From: Nathael Pajani Date: Mon, 7 Nov 2022 17:00:28 +0000 (+0100) Subject: Updated uSD access example. X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=91723f0aff3d8c668fedc0944f2294258f00511a;p=soft%2Flpc122x%2Fexamples Updated uSD access example. --- diff --git a/usd_card/README b/usd_card/README index d891332..a7c035b 100644 --- a/usd_card/README +++ b/usd_card/README @@ -20,10 +20,10 @@ Copyright 2017 Nathael Pajani *************************************************************************** */ -This example reads data from the first 16 bytes of the first four bolcs of -the SD card to collect a message to be displayed, and then stores temperature -data on the SD, with one sample on each successive block, starting on the -fifth block. +This example reads data from the first block(s) (first 512 bytes of the uSD +card) to collect an "hello" message to be displayed, and then stores +temperature data on the SD, with one sample on each successive block, starting +on the next block. This demonstrates basic usage of the SD, but is very inefective for recent SD cards (SDHC and SDXC) as they have fixed 512 bytes blocks : this will @@ -34,13 +34,12 @@ SD card. In order to write the "hello" messages to the SD card, use something like this (adapt to the SD device name) : SDDEV="/dev/sdc" -echo "This message is not much usefull, and gonna get split." > /tmp/msg -for i in $(seq 0 3) ; do - dd if=/tmp/msg of=$SDDEV ibs=16 obs=512 count=1 skip=$i seek=$i -done +echo "This message is not much usefull, find a better one" > ${SDDEV} -In order to display data from the SD, you can use hexdump : +In order to display data from the SD, you can use hexdump (-n is here to + avoid dumping full SD card content on terminal) : SDDEV="/dev/sdc" -hexdump -n 6000 -C $SDDEV +hexdump -n 6000 -C ${SDDEV} + diff --git a/usd_card/main.c b/usd_card/main.c index 79d984d..170c3fe 100644 --- a/usd_card/main.c +++ b/usd_card/main.c @@ -72,7 +72,22 @@ const struct pio_config common_pins[] = { { LPC_SSP0_MOSI_PIO_0_17, LPC_IO_DIGITAL }, { LPC_SSP0_MISO_PIO_0_16, LPC_IO_DIGITAL }, /* GPIO */ - { LPC_GPIO_1_6, LPC_IO_DIGITAL }, /* uSD Card SPI Chip Select */ + { LPC_GPIO_0_15, LPC_IO_DIGITAL }, /* uSD Card SPI Chip Select */ + ARRAY_LAST_PIO, +}; + +const struct pio_config mmc_spi_pins[] = { + /* SPI : uSD card */ + { LPC_SSP0_SCLK_PIO_0_14, LPC_IO_DIGITAL }, + { LPC_SSP0_MOSI_PIO_0_17, LPC_IO_DIGITAL }, + { LPC_SSP0_MISO_PIO_0_16, LPC_IO_DIGITAL }, + ARRAY_LAST_PIO, +}; + +const struct pio_config mmc_init_pins[] = { + { LPC_GPIO_0_14, LPC_IO_DIGITAL }, + { LPC_GPIO_0_17, LPC_IO_DIGITAL }, + { LPC_GPIO_0_16, LPC_IO_DIGITAL }, ARRAY_LAST_PIO, }; @@ -105,10 +120,15 @@ void temp_config(int uart_num) struct sdmmc_card micro_sd = { .ssp_bus_num = SSP_BUS_0, .card_type = MMC_CARDTYPE_UNKNOWN, - .block_size = 16, + .block_size = 64, .chip_select = LPC_GPIO_0_15, + .sclk = LPC_GPIO_0_14, + .mosi = LPC_GPIO_0_17, + .miso = LPC_GPIO_0_16, + .pin_cfg_mode_spi = (struct pio_config*)mmc_spi_pins, + .pin_cfg_mode_gpio = (struct pio_config*)mmc_init_pins, }; -#define MMC_BUF_SIZE 64 +#define MMC_BUF_SIZE 512 uint8_t mmc_data[MMC_BUF_SIZE]; @@ -140,37 +160,44 @@ void fault_info(const char* name, uint32_t len) while (1); } - - /***************************************************************************** */ int main(void) { int ret = 0; + uint8_t step = 0, loop = 0, retries = 10; + uint32_t block_num = 0; system_init(); uart_on(UART0, 115200, NULL); i2c_on(I2C0, I2C_CLK_100KHz, I2C_MASTER); - ssp_master_on(0, LPC_SSP_FRAME_SPI, 8, 4*1000*1000); + ssp_master_on(SSP_BUS_0, LPC_SSP_FRAME_SPI, 8, 4*1000*1000); /* TMP101 sensor config */ temp_config(UART0); /* microSD card init */ + /* Get SD card to SPI mode */ + ret = sdmmc_reset(µ_sd); + uprintf(UART0, "uSD reset ret: %d\n", ret); + /* Init card, try it up to 10 times */ do { - ret = sdmmc_init(µ_sd); - if (ret == 0) { - msleep(10); - ret = sdmmc_init_wait_card_ready(µ_sd); - if (ret == 0) { - ret = sdmmc_init_end(µ_sd); - } + ret = sdmmc_init_single(µ_sd, &step, &retries); + uprintf(UART0, "uSD init (%d): step: %d, retries: %d, ret: %d, type: %d, bs: %d\n", + loop, step, retries, ret, micro_sd.card_type, micro_sd.block_size); + if (ret != 0) { + msleep(250); } - uprintf(UART0, "uSD init: %d, type: %d, bs: %d\n", ret, micro_sd.card_type, micro_sd.block_size); - } while (ret != 0); + loop++; + } while ((ret != 0) && (loop < 10)); + + /* Read first block */ memset(mmc_data, 0, MMC_BUF_SIZE); - ret = sdmmc_read_block(µ_sd, 0, mmc_data); - ret = sdmmc_read_block(µ_sd, 1, (mmc_data + 16)); - ret = sdmmc_read_block(µ_sd, 2, (mmc_data + 32)); - ret = sdmmc_read_block(µ_sd, 3, (mmc_data + 48)); + ret = sdmmc_read_block(µ_sd, block_num++, mmc_data); + if (micro_sd.block_size < MMC_BUF_SIZE) { + uint16_t idx = micro_sd.block_size; + while ((idx + micro_sd.block_size) < MMC_BUF_SIZE) { + ret = sdmmc_read_block(µ_sd, block_num++, (mmc_data + idx)); + } + } uprintf(UART0, "uSD read: %s\n", mmc_data); msleep(50); @@ -178,9 +205,10 @@ int main(void) while (1) { int tmp101_deci_degrees = 0; int abs_deci = 0; - static int block_num = 4; /* Do not write too many times, one data every 20s is more than enough for a test */ + /* Start with the delay so it's possible to perform read test only with same test code simply + * by reseting before the write step */ msleep(20 * 1000); /* Get internal temperature */ @@ -196,17 +224,29 @@ int main(void) abs_deci = tmp101_deci_degrees; } - /* Write temp to uSD */ + /* Write temperature to uSD */ memset(mmc_data, 0, MMC_BUF_SIZE); mmc_data[0] = tmp101_deci_degrees / 10; mmc_data[1] = abs_deci % 10; ret = sdmmc_write_block(µ_sd, block_num++, mmc_data); uprintf(UART0, "Wrote data on block %d: ret=%d\n", (block_num - 1), ret); + if (ret == -EBUSY) { + uprintf(UART0, "Busy ?\n"); + uint8_t cnt = 10; + do { + /* Wait for sd to get ready */ + msleep(10); + ret = sdmmc_wait_write_end(µ_sd); + } while ((ret != 0) && (cnt-- > 0)); + uprintf(UART0, "Still busy ? cnt: %d, ret=%d\n", cnt, ret); + } /* Display */ uprintf(UART0, "Internal Temp : % 4d.%02d\n", (tmp101_deci_degrees / 10), (abs_deci % 10)); } return 0; + + }