[BSP] Add RT_DEVICE_CTRL_BLK_GETGEOME command handling in device control of LPC176x bsp
This commit is contained in:
parent
7f45ac18bc
commit
a5119d696c
|
@ -36,9 +36,11 @@ static bool LPC17xx_SD_WaitForReady (void)
|
|||
uint32_t timeout = 400000;
|
||||
|
||||
LPC17xx_SPI_SendByte(0xFF);
|
||||
do {
|
||||
do
|
||||
{
|
||||
res = LPC17xx_SPI_RecvByte();
|
||||
} while ((res != 0xFF) && timeout--);
|
||||
}
|
||||
while ((res != 0xFF) && timeout--);
|
||||
|
||||
return (res == 0xFF ? true : false);
|
||||
}
|
||||
|
@ -54,7 +56,8 @@ static bool LPC17xx_SD_Init (void)
|
|||
LPC17xx_SPI_Init();
|
||||
|
||||
/* At least 74 clock cycles are required prior to starting bus communication */
|
||||
for (i = 0; i < 80; i++) { /* 80 dummy clocks */
|
||||
for (i = 0; i < 80; i++) /* 80 dummy clocks */
|
||||
{
|
||||
LPC17xx_SPI_SendByte(0xFF);
|
||||
}
|
||||
|
||||
|
@ -62,22 +65,32 @@ static bool LPC17xx_SD_Init (void)
|
|||
if (LPC17xx_SD_SendCmd(GO_IDLE_STATE, 0) == 0x1)
|
||||
{
|
||||
timeout = 50000;
|
||||
if (LPC17xx_SD_SendCmd(CMD8, 0x1AA) == 1) { /* SDHC */
|
||||
if (LPC17xx_SD_SendCmd(CMD8, 0x1AA) == 1) /* SDHC */
|
||||
{
|
||||
/* Get trailing return value of R7 resp */
|
||||
for (i = 0; i < 4; i++) ocr[i] = LPC17xx_SPI_RecvByte();
|
||||
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
|
||||
if (ocr[2] == 0x01 && ocr[3] == 0xAA) /* The card can work at vdd range of 2.7-3.6V */
|
||||
{
|
||||
/* Wait for leaving idle state (ACMD41 with HCS bit) */
|
||||
while (timeout-- && LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 1UL << 30));
|
||||
/* Check CCS bit in the OCR */
|
||||
if (timeout && LPC17xx_SD_SendCmd(READ_OCR, 0) == 0) {
|
||||
if (timeout && LPC17xx_SD_SendCmd(READ_OCR, 0) == 0)
|
||||
{
|
||||
for (i = 0; i < 4; i++) ocr[i] = LPC17xx_SPI_RecvByte();
|
||||
ct = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
|
||||
}
|
||||
} else { /* SDSC or MMC */
|
||||
if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1) {
|
||||
ct = CT_SD1; cmd = SD_SEND_OP_COND; /* SDSC */
|
||||
} else {
|
||||
ct = CT_MMC; cmd = SEND_OP_COND; /* MMC */
|
||||
}
|
||||
else /* SDSC or MMC */
|
||||
{
|
||||
if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1)
|
||||
{
|
||||
ct = CT_SD1;
|
||||
cmd = SD_SEND_OP_COND; /* SDSC */
|
||||
}
|
||||
else
|
||||
{
|
||||
ct = CT_MMC;
|
||||
cmd = SEND_OP_COND; /* MMC */
|
||||
}
|
||||
/* Wait for leaving idle state */
|
||||
while (timeout-- && LPC17xx_SD_SendCmd(cmd, 0));
|
||||
|
@ -86,11 +99,17 @@ static bool LPC17xx_SD_Init (void)
|
|||
ct = CT_NONE;
|
||||
}
|
||||
}
|
||||
else { /* SDSC or MMC */
|
||||
if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1) {
|
||||
ct = CT_SD1; cmd = SD_SEND_OP_COND; /* SDSC */
|
||||
} else {
|
||||
ct = CT_MMC; cmd = SEND_OP_COND; /* MMC */
|
||||
else /* SDSC or MMC */
|
||||
{
|
||||
if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1)
|
||||
{
|
||||
ct = CT_SD1;
|
||||
cmd = SD_SEND_OP_COND; /* SDSC */
|
||||
}
|
||||
else
|
||||
{
|
||||
ct = CT_MMC;
|
||||
cmd = SEND_OP_COND; /* MMC */
|
||||
}
|
||||
/* Wait for leaving idle state */
|
||||
while (timeout-- && LPC17xx_SD_SendCmd(cmd, 0));
|
||||
|
@ -102,14 +121,20 @@ static bool LPC17xx_SD_Init (void)
|
|||
CardType = ct;
|
||||
LPC17xx_SPI_Release();
|
||||
|
||||
if (ct) { /* Initialization succeeded */
|
||||
if (ct) /* Initialization succeeded */
|
||||
{
|
||||
ret = true;
|
||||
if ( ct == CT_MMC ) {
|
||||
LPC17xx_SPI_SetSpeed(SPI_SPEED_20MHz);
|
||||
} else {
|
||||
if (ct == CT_MMC)
|
||||
{
|
||||
LPC17xx_SPI_SetSpeed(SPI_SPEED_20MHz);
|
||||
}
|
||||
} else { /* Initialization failed */
|
||||
else
|
||||
{
|
||||
LPC17xx_SPI_SetSpeed(SPI_SPEED_20MHz);
|
||||
}
|
||||
}
|
||||
else /* Initialization failed */
|
||||
{
|
||||
LPC17xx_SPI_Select();
|
||||
LPC17xx_SD_WaitForReady();
|
||||
LPC17xx_SPI_DeInit();
|
||||
|
@ -128,7 +153,8 @@ static uint8_t LPC17xx_SD_SendCmd (uint8_t cmd, uint32_t arg)
|
|||
{
|
||||
uint32_t r1, n;
|
||||
|
||||
if (cmd & 0x80) { /* ACMD<n> is the command sequence of CMD55-CMD<n> */
|
||||
if (cmd & 0x80) /* ACMD<n> is the command sequence of CMD55-CMD<n> */
|
||||
{
|
||||
cmd &= 0x7F;
|
||||
r1 = LPC17xx_SD_SendCmd(APP_CMD, 0); /* CMD55 */
|
||||
if (r1 > 1) return r1; /* cmd send failed */
|
||||
|
@ -154,9 +180,11 @@ static uint8_t LPC17xx_SD_SendCmd (uint8_t cmd, uint32_t arg)
|
|||
if (cmd == STOP_TRAN) LPC17xx_SPI_RecvByte(); /* Skip a stuff byte when stop reading */
|
||||
|
||||
n = 10; /* Wait for a valid response in timeout of 10 attempts */
|
||||
do {
|
||||
do
|
||||
{
|
||||
r1 = LPC17xx_SPI_RecvByte();
|
||||
} while ((r1 & 0x80) && --n);
|
||||
}
|
||||
while ((r1 & 0x80) && --n);
|
||||
|
||||
return (r1); /* Return with the response value */
|
||||
}
|
||||
|
@ -171,16 +199,22 @@ static bool LPC17xx_SD_ReadSector (uint32_t sector, uint8_t *buff, uint32_t coun
|
|||
/* Convert to byte address if needed */
|
||||
if (!(CardType & CT_BLOCK)) sector *= SD_SECTOR_SIZE;
|
||||
|
||||
if (count == 1) { /* Single block read */
|
||||
if (count == 1) /* Single block read */
|
||||
{
|
||||
if ((LPC17xx_SD_SendCmd(READ_BLOCK, sector) == 0)
|
||||
&& LPC17xx_SD_ReadDataBlock(buff, SD_SECTOR_SIZE))
|
||||
count = 0;
|
||||
} else { /* Multiple block read */
|
||||
if (LPC17xx_SD_SendCmd(READ_MULT_BLOCK, sector) == 0) {
|
||||
do {
|
||||
}
|
||||
else /* Multiple block read */
|
||||
{
|
||||
if (LPC17xx_SD_SendCmd(READ_MULT_BLOCK, sector) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!LPC17xx_SD_ReadDataBlock(buff, SD_SECTOR_SIZE)) break;
|
||||
buff += SD_SECTOR_SIZE;
|
||||
} while (--count);
|
||||
}
|
||||
while (--count);
|
||||
LPC17xx_SD_SendCmd(STOP_TRAN, 0); /* STOP_TRANSMISSION */
|
||||
}
|
||||
}
|
||||
|
@ -200,20 +234,24 @@ static bool LPC17xx_SD_ReadDataBlock ( uint8_t *buff, uint32_t cnt)
|
|||
uint32_t timeout;
|
||||
|
||||
timeout = 20000;
|
||||
do { /* Wait for data packet in timeout of 100ms */
|
||||
do /* Wait for data packet in timeout of 100ms */
|
||||
{
|
||||
token = LPC17xx_SPI_RecvByte();
|
||||
} while ((token == 0xFF) && timeout--);
|
||||
}
|
||||
while ((token == 0xFF) && timeout--);
|
||||
if (token != 0xFE) return false; /* If not valid data token, return with error */
|
||||
|
||||
#if USE_FIFO
|
||||
LPC17xx_SPI_RecvBlock_FIFO(buff, cnt);
|
||||
#else
|
||||
do { /* Receive the data block into buffer */
|
||||
do /* Receive the data block into buffer */
|
||||
{
|
||||
*buff++ = LPC17xx_SPI_RecvByte();
|
||||
*buff++ = LPC17xx_SPI_RecvByte();
|
||||
*buff++ = LPC17xx_SPI_RecvByte();
|
||||
*buff++ = LPC17xx_SPI_RecvByte();
|
||||
} while (cnt -= 4);
|
||||
}
|
||||
while (cnt -= 4);
|
||||
#endif /* USE_FIFO */
|
||||
LPC17xx_SPI_RecvByte(); /* Discard CRC */
|
||||
LPC17xx_SPI_RecvByte();
|
||||
|
@ -230,17 +268,23 @@ static bool LPC17xx_SD_WriteSector (uint32_t sector, const uint8_t *buff, uint32
|
|||
{
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
|
||||
|
||||
if (count == 1) { /* Single block write */
|
||||
if (count == 1) /* Single block write */
|
||||
{
|
||||
if ((LPC17xx_SD_SendCmd(WRITE_BLOCK, sector) == 0)
|
||||
&& LPC17xx_SD_WirteDataBlock(buff, TOKEN_SINGLE_BLOCK))
|
||||
count = 0;
|
||||
} else { /* Multiple block write */
|
||||
}
|
||||
else /* Multiple block write */
|
||||
{
|
||||
if (CardType & CT_SDC) LPC17xx_SD_SendCmd(SET_WR_BLK_ERASE_COUNT, count);
|
||||
if (LPC17xx_SD_SendCmd(WRITE_MULT_BLOCK, sector) == 0) {
|
||||
do {
|
||||
if (LPC17xx_SD_SendCmd(WRITE_MULT_BLOCK, sector) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!LPC17xx_SD_WirteDataBlock(buff, TOKEN_MULTI_BLOCK)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
}
|
||||
while (--count);
|
||||
#if 1
|
||||
if (!LPC17xx_SD_WirteDataBlock(0, TOKEN_STOP_TRAN)) /* STOP_TRAN token */
|
||||
count = 1;
|
||||
|
@ -268,12 +312,14 @@ static bool LPC17xx_SD_WirteDataBlock (const uint8_t *buff, uint8_t token)
|
|||
|
||||
LPC17xx_SPI_SendByte(token); /* send data token first*/
|
||||
|
||||
if (token != TOKEN_STOP_TRAN) {
|
||||
if (token != TOKEN_STOP_TRAN)
|
||||
{
|
||||
#if USE_FIFO
|
||||
LPC17xx_SPI_SendBlock_FIFO(buff);
|
||||
#else
|
||||
/* Send data. */
|
||||
for (i = 512/4; i ; i--) {
|
||||
for (i = 512 / 4; i ; i--)
|
||||
{
|
||||
LPC17xx_SPI_SendByte(*buff++);
|
||||
LPC17xx_SPI_SendByte(*buff++);
|
||||
LPC17xx_SPI_SendByte(*buff++);
|
||||
|
@ -319,10 +365,13 @@ static bool LPC17xx_SD_ReadCfg (SDCFG *cfg)
|
|||
cfg -> sectorsize = SD_SECTOR_SIZE;
|
||||
|
||||
/* Get number of sectors on the disk (DWORD) */
|
||||
if ((cfg->csd[0] >> 6) == 1) { /* SDC ver 2.00 */
|
||||
if ((cfg->csd[0] >> 6) == 1) /* SDC ver 2.00 */
|
||||
{
|
||||
csize = cfg->csd[9] + ((uint16_t)cfg->csd[8] << 8) + 1;
|
||||
cfg -> sectorcnt = (uint32_t)csize << 10;
|
||||
} else { /* SDC ver 1.XX or MMC*/
|
||||
}
|
||||
else /* SDC ver 1.XX or MMC*/
|
||||
{
|
||||
n = (cfg->csd[5] & 15) + ((cfg->csd[10] & 128) >> 7) + ((cfg->csd[9] & 3) << 1) + 2; // 19
|
||||
csize = (cfg->csd[8] >> 6) + ((uint16_t)cfg->csd[7] << 2) + ((uint16_t)(cfg->csd[6] & 3) << 10) + 1; // 3752
|
||||
cfg -> sectorcnt = (uint32_t)csize << (n - 9); // 3842048
|
||||
|
@ -331,20 +380,29 @@ static bool LPC17xx_SD_ReadCfg (SDCFG *cfg)
|
|||
cfg->size = cfg -> sectorcnt * cfg -> sectorsize; // 512*3842048=1967128576Byte (1.83GB)
|
||||
|
||||
/* Get erase block size in unit of sector (DWORD) */
|
||||
if (CardType & CT_SD2) { /* SDC ver 2.00 */
|
||||
if (LPC17xx_SD_SendCmd(SD_STATUS /*ACMD13*/, 0) == 0) { /* Read SD status */
|
||||
if (CardType & CT_SD2) /* SDC ver 2.00 */
|
||||
{
|
||||
if (LPC17xx_SD_SendCmd(SD_STATUS /*ACMD13*/, 0) == 0) /* Read SD status */
|
||||
{
|
||||
LPC17xx_SPI_RecvByte();
|
||||
if (LPC17xx_SD_ReadDataBlock(csd, 16)) { /* Read partial block */
|
||||
if (LPC17xx_SD_ReadDataBlock(csd, 16)) /* Read partial block */
|
||||
{
|
||||
for (n = 64 - 16; n; n--) LPC17xx_SPI_RecvByte(); /* Purge trailing data */
|
||||
cfg->blocksize = 16UL << (csd[10] >> 4);
|
||||
retv = true;
|
||||
}
|
||||
}
|
||||
} else { /* SDC ver 1.XX or MMC */
|
||||
if ((LPC17xx_SD_SendCmd(SEND_CSD, 0) == 0) && LPC17xx_SD_ReadDataBlock(csd, 16)) { /* Read CSD */
|
||||
if (CardType & CT_SD1) { /* SDC ver 1.XX */
|
||||
}
|
||||
else /* SDC ver 1.XX or MMC */
|
||||
{
|
||||
if ((LPC17xx_SD_SendCmd(SEND_CSD, 0) == 0) && LPC17xx_SD_ReadDataBlock(csd, 16)) /* Read CSD */
|
||||
{
|
||||
if (CardType & CT_SD1) /* SDC ver 1.XX */
|
||||
{
|
||||
cfg->blocksize = (((csd[10] & 63) << 1) + ((uint16_t)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
|
||||
} else { /* MMC */
|
||||
}
|
||||
else /* MMC */
|
||||
{
|
||||
// cfg->blocksize = ((uint16_t)((buf[10] & 124) >> 2) + 1) * (((buf[11] & 3) << 3) + ((buf[11] & 224) >> 5) + 1);
|
||||
cfg->blocksize = ((uint16_t)((cfg->csd[10] & 124) >> 2) + 1) * (((cfg->csd[10] & 3) << 3) + ((cfg->csd[11] & 224) >> 5) + 1);
|
||||
}
|
||||
|
@ -352,7 +410,8 @@ static bool LPC17xx_SD_ReadCfg (SDCFG *cfg)
|
|||
}
|
||||
}
|
||||
|
||||
x: LPC17xx_SPI_Release();
|
||||
x:
|
||||
LPC17xx_SPI_Release();
|
||||
return (retv);
|
||||
}
|
||||
|
||||
|
@ -397,6 +456,18 @@ static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buf
|
|||
|
||||
static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||
{
|
||||
if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
|
||||
{
|
||||
struct rt_device_blk_geometry *geometry;
|
||||
|
||||
geometry = (struct rt_device_blk_geometry *)args;
|
||||
if (geometry == RT_NULL) return -RT_ERROR;
|
||||
|
||||
geometry->bytes_per_sector = SDCfg.sectorsize;
|
||||
geometry->block_size = SDCfg.blocksize;
|
||||
geometry->sector_count = SDCfg.sectorcnt;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
#define CT_BLOCK 0x08
|
||||
|
||||
/* MMC device configuration */
|
||||
typedef struct tagSDCFG{
|
||||
typedef struct tagSDCFG
|
||||
{
|
||||
uint32_t sernum; // serial number
|
||||
uint32_t size; // size=sectorsize*sectorcnt
|
||||
uint32_t sectorcnt; //
|
||||
|
|
Loading…
Reference in New Issue