Updated uSD access example.
authorNathael Pajani <nathael.pajani@ed3l.fr>
Mon, 7 Nov 2022 17:00:28 +0000 (18:00 +0100)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 16:14:24 +0000 (17:14 +0100)
usd_card/README
usd_card/main.c

index d891332..a7c035b 100644 (file)
@@ -20,10 +20,10 @@ Copyright 2017 Nathael Pajani <nathael.pajani@ed3l.fr>
  *************************************************************************** */
 
 
-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}
+
 
 
index 79d984d..170c3fe 100644 (file)
@@ -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(&micro_sd);
+       uprintf(UART0, "uSD reset ret: %d\n", ret);
+       /* Init card, try it up to 10 times */
        do {
-               ret = sdmmc_init(&micro_sd);
-               if (ret == 0) {
-                       msleep(10);
-                       ret = sdmmc_init_wait_card_ready(&micro_sd);
-                       if (ret == 0) {
-                               ret = sdmmc_init_end(&micro_sd);
-                       }
+               ret = sdmmc_init_single(&micro_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(&micro_sd, 0, mmc_data);
-       ret = sdmmc_read_block(&micro_sd, 1, (mmc_data + 16));
-       ret = sdmmc_read_block(&micro_sd, 2, (mmc_data + 32));
-       ret = sdmmc_read_block(&micro_sd, 3, (mmc_data + 48));
+       ret = sdmmc_read_block(&micro_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(&micro_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(&micro_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(&micro_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;
+
+
 }