*************************************************************************** */
-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
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}
+
{ 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,
};
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];
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);
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 */
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;
+
+
}