Created
April 21, 2022 22:25
-
-
Save Roman-Port/ad1e30d6e3578738f8c7891152b94ed2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
#include <sys/unistd.h> | |
#include <sys/stat.h> | |
#include "esp_vfs_fat.h" | |
#include "sdmmc_cmd.h" | |
#include "driver/sdmmc_host.h" | |
#include <driver/i2s.h> | |
static const char *TAG = "example"; | |
// General | |
#define MOUNT_POINT "/sdcard" | |
#define MICROSECONDS_PER_SECOND 1000000 | |
#define SECTOR_COUNT 64 | |
//#define IQ_MODE | |
#ifdef IQ_MODE | |
/* IQ Baseband Mode (ground=red, 23=orange, 18=green, 5=blue) */ | |
#define SAMPLE_RATE (325000 * 2) | |
#define BITS_PER_SAMPLE 16 | |
#define FIXED_MCLK 20800000 | |
#define COMM_FMT I2S_COMM_FORMAT_STAND_I2S | |
#define USE_APLL true | |
/* END IQ Baseband Mode */ | |
#else | |
/* HD Mode (ground=blue, 23=orange, 18=yellow, 5=green) */ | |
#define SAMPLE_RATE 44100 | |
#define BITS_PER_SAMPLE 32 | |
#define FIXED_MCLK 0 | |
#define COMM_FMT I2S_COMM_FORMAT_STAND_I2S | |
#define USE_APLL false | |
/* END HD Mode */ | |
#endif | |
int64_t configure_port(i2s_port_t port, int dmaChunkSize) { | |
//Set up I2S | |
i2s_config_t i2s_config = { | |
.mode = (i2s_mode_t)(I2S_MODE_SLAVE | I2S_MODE_RX), | |
.sample_rate = SAMPLE_RATE, | |
.bits_per_sample = BITS_PER_SAMPLE, | |
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, | |
.communication_format = COMM_FMT, | |
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // Interrupt level 1, default 0 | |
.dma_buf_count = 32, | |
.dma_buf_len = dmaChunkSize, | |
.use_apll = USE_APLL, | |
.tx_desc_auto_clear = false, | |
.fixed_mclk = FIXED_MCLK, | |
.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT | |
}; | |
i2s_driver_install(port, &i2s_config, 0, NULL); | |
//Set up pins | |
i2s_pin_config_t pin_config = { | |
.bck_io_num = 18, | |
.ws_io_num = 5, | |
.data_out_num = I2S_PIN_NO_CHANGE, | |
.data_in_num = 23 | |
}; | |
i2s_set_pin(port, &pin_config); | |
//Calculate data rate | |
return SAMPLE_RATE * (BITS_PER_SAMPLE / 8) * 2; | |
} | |
void app_main(void) | |
{ | |
//Initialize SD card driver | |
if (sdmmc_host_init() != ESP_OK) { | |
printf("Failed to initialize SD card driver.\n"); | |
return; | |
} | |
//Initialize slot | |
sdmmc_slot_config_t slot = SDMMC_SLOT_CONFIG_DEFAULT(); | |
slot.width = 4; | |
slot.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP; | |
if (sdmmc_host_init_slot(1, &slot) != ESP_OK) { | |
printf("Failed to initialize SD card slot.\n"); | |
return; | |
} | |
//Open card | |
printf("Opening SD card...\n"); | |
sdmmc_host_t host = SDMMC_HOST_DEFAULT(); | |
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED; | |
sdmmc_card_t card; | |
if (sdmmc_card_init(&host, &card) != ESP_OK) { | |
printf("Failed to open SD card! Rebooting...\n"); | |
vTaskDelay(1000 / portTICK_PERIOD_MS); | |
esp_restart(); | |
} | |
//Get info | |
sdmmc_card_print_info(stdout, &card); | |
printf("Sector size: %i\n", card.csd.sector_size); | |
//Set up ports | |
int64_t targetByteRate = configure_port(I2S_NUM_0, card.csd.sector_size); | |
//Allocate sector buffer | |
size_t bufferSize = SECTOR_COUNT * card.csd.sector_size; | |
void* buffer = malloc(bufferSize); | |
if (buffer == 0) { | |
printf("Failed to allocate buffer!\n"); | |
return; | |
} | |
//Enter loop | |
size_t read; | |
int sector = 0; | |
int64_t start = esp_timer_get_time(); | |
int64_t end = esp_timer_get_time(); | |
while (true) { | |
//Read | |
i2s_read(I2S_NUM_0, buffer, bufferSize, &read, 300);//portMAX_DELAY | |
if (read == 0) | |
printf("WARN: No data is being read from I2S!\n"); | |
//Write | |
end = esp_timer_get_time(); | |
if (sdmmc_write_sectors(&card, buffer, sector, SECTOR_COUNT) != ESP_OK) { | |
printf("Failed to write sectors to SD card! Aborting...\n"); | |
break; | |
} | |
//Advance | |
sector += SECTOR_COUNT; | |
} | |
//Print info | |
int64_t written = sector * card.csd.sector_size; | |
double speed = written / ((end - start) / 1000000.0); | |
ESP_LOGI(TAG, "FINISHED WRITING. Wrote %i sectors (%lli bytes) at %f bytes/sec (%f%% of target)", sector, written, (float)speed, (float)((speed / targetByteRate) * 100.0)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
(ps, there's a memory leak since I forgot to free the buffer)