diff options
| author | Bernard Xiong <[email protected]> | 2018-03-04 17:37:16 +0800 |
|---|---|---|
| committer | Bernard Xiong <[email protected]> | 2018-03-04 17:37:16 +0800 |
| commit | f6a7136226cd225a76dcdc7d19450ea3bfb51859 (patch) | |
| tree | ab64d53571a93eb267a66e1d57e700054fc691c0 | |
| parent | 8203b6004b9e82a58ec733b4dd2e70e110cef5da (diff) | |
[BSP] Update sdcard driver in mini4020
| -rw-r--r-- | bsp/mini4020/drivers/sdcard.c | 1043 | ||||
| -rw-r--r-- | bsp/mini4020/drivers/sdcard.h | 56 |
2 files changed, 550 insertions, 549 deletions
diff --git a/bsp/mini4020/drivers/sdcard.c b/bsp/mini4020/drivers/sdcard.c index 77983c36b9..78c1306a0d 100644 --- a/bsp/mini4020/drivers/sdcard.c +++ b/bsp/mini4020/drivers/sdcard.c @@ -14,15 +14,14 @@ * 2010-10-13 Wangmeng Added sep4020 support */ -#include "sdcard.h" -//#include <dfs_config.h> +#include <rtthread.h> -volatile rt_int32_t RCA; +#include "sdcard.h" #ifdef RT_USING_DFS +volatile rt_int32_t RCA; /* RT-Thread Device Driver Interface */ -#include <rtthread.h> #include <dfs_fs.h> /*GLOBAL SD DEVICE PONITER*/ @@ -41,30 +40,32 @@ static rt_uint8_t gsec_buf[SECTOR_SIZE]; */ static void sd_pwr(int sd_ctl) { - if (sd_ctl) - { - *(RP)GPIO_PORTA_SEL |= 0x0200; - *(RP)GPIO_PORTA_DIR &= (~0x0200); - *(RP)GPIO_PORTA_DATA |= 0x0200; - } - else - { - - *(RP)GPIO_PORTA_SEL |= 0x0200; - *(RP)GPIO_PORTA_DIR &= (~0x0200); - *(RP)GPIO_PORTA_DATA &= (~0x0200); - } + if (sd_ctl) + { + *(RP)GPIO_PORTA_SEL |= 0x0200; + *(RP)GPIO_PORTA_DIR &= (~0x0200); + *(RP)GPIO_PORTA_DATA |= 0x0200; + } + else + { + + *(RP)GPIO_PORTA_SEL |= 0x0200; + *(RP)GPIO_PORTA_DIR &= (~0x0200); + *(RP)GPIO_PORTA_DATA &= (~0x0200); + } } /*a nop operation to delay*/ -static void delay (U32 j) -{ - U32 i; - - for (i=0;i<j;i++) - {}; +static void delay(U32 j) +{ + U32 i; + for (i = 0; i < j; i++) + { + /* nothing */ + } } + /* * Send the command to set the data transfer mode * @param cmd:the command to sent @@ -74,129 +75,127 @@ static void delay (U32 j) * @param num:number of blocks * @param mask:sdc interrupt mask */ -static rt_err_t cmd_data(U16 cmd,U32 arg,U16 mode,U16 blk_len,U16 num,U16 mask) +static rt_err_t cmd_data(U16 cmd, U32 arg, U16 mode, U16 blk_len, U16 num, U16 mask) { U32 i; - #ifdef USE_TIMEOUT - U32 to = 10000; - #endif - - *(RP)SDC_CLOCK_CONTROL = 0Xff00; //����SDʱ�ӣ�512��Ƶ,�ر�SD ʱ�� - *(RP)SDC_CLOCK_CONTROL = 0Xff04; //��SDʱ�ӣ�512��Ƶ,����SD ʱ�� - *(RP)SDC_INTERRUPT_STATUS_MASK = mask; //�ж�״̬���μĴ�����ֵ - - *(RP)SDC_TRANSFER_MODE = mode; //����ģʽѡ��Ĵ�����ֵ - - *(RP)SDC_BLOCK_SIZE = blk_len; //���ݿ鳤�ȼĴ�����ֵ - *(RP)SDC_BLOCK_COUNT = num; //���ݿ���Ŀ�Ĵ�����ֵ - *(RP)SDC_ARGUMENT = arg; //��������Ĵ�����ֵ - *(RP)SDC_COMMAND = cmd; //������ƼĴ�����ֵ - - delay(10); - +#ifdef USE_TIMEOUT + U32 to = 10000; +#endif + + *(RP)SDC_CLOCK_CONTROL = 0Xff00; + *(RP)SDC_CLOCK_CONTROL = 0Xff04; + *(RP)SDC_INTERRUPT_STATUS_MASK = mask; + + *(RP)SDC_TRANSFER_MODE = mode; + + *(RP)SDC_BLOCK_SIZE = blk_len; + *(RP)SDC_BLOCK_COUNT = num; + *(RP)SDC_ARGUMENT = arg; + *(RP)SDC_COMMAND = cmd; + + delay(10); + i = *(RP)SDC_INTERRUPT_STATUS & 0x1000; - - while(i != 0x1000) //�жϣ��Ƿ��������ϣ������յ���Ӧ + + while (i != 0x1000) { - i = *(RP)SDC_INTERRUPT_STATUS & 0x1000; - #ifdef USE_TIMEOUT - to --; - if(!to) - { - EOUT("%s TIMEOUT\n",__FUNCTION__); - return RT_ETIMEOUT; - } - #endif + i = *(RP)SDC_INTERRUPT_STATUS & 0x1000; +#ifdef USE_TIMEOUT + to --; + if (!to) + { + EOUT("%s TIMEOUT\n", __FUNCTION__); + return RT_ETIMEOUT; + } +#endif } delay(160); - #ifdef USE_TIMEOUT - //DBOUT("cmd_data TO is %d\n",to); - #endif - - return *(RP)SDC_RESPONSE0; //�����������Ϣ + return *(RP)SDC_RESPONSE0; } -static rt_err_t cmd_response(U16 Cmd,U32 Arg,U16 TransMode,U16 BlkLen,U16 Nob,U16 IntMask) +static rt_err_t cmd_response(U16 Cmd, U32 Arg, U16 TransMode, U16 BlkLen, U16 Nob, U16 IntMask) { - U32 i; - #ifdef USE_TIMEOUT - U32 to = 50000; - #endif - - *(RP)SDC_CLOCK_CONTROL=0Xff00; //����SDʱ�� - - *(RP)SDC_CLOCK_CONTROL=0Xff04; //��SDʱ�� - - - *(RP)SDC_INTERRUPT_STATUS_MASK=IntMask; //�ж�״̬���μĴ�����ֵ - *(RP)SDC_TRANSFER_MODE=TransMode; //����ģʽѡ��Ĵ�����ֵ - *(RP)SDC_BLOCK_SIZE=BlkLen; //���ݿ鳤�ȼĴ�����ֵ - *(RP)SDC_BLOCK_COUNT=Nob; //���ݿ���Ŀ�Ĵ�����ֵ - *(RP)SDC_ARGUMENT=Arg; //��������Ĵ�����ֵ - *(RP)SDC_COMMAND=Cmd; //������ƼĴ�����ֵ - - delay(10); - + U32 i; +#ifdef USE_TIMEOUT + U32 to = 50000; +#endif + + *(RP)SDC_CLOCK_CONTROL = 0Xff00; + + *(RP)SDC_CLOCK_CONTROL = 0Xff04; + + + *(RP)SDC_INTERRUPT_STATUS_MASK = IntMask; + *(RP)SDC_TRANSFER_MODE = TransMode; + *(RP)SDC_BLOCK_SIZE = BlkLen; + *(RP)SDC_BLOCK_COUNT = Nob; + *(RP)SDC_ARGUMENT = Arg; + *(RP)SDC_COMMAND = Cmd; + + delay(10); + i = *(RP)SDC_INTERRUPT_STATUS & 0x1040; - - while(i != 0x1040) //�жϣ��������ϣ������յ���Ӧ�����ݴ�����ϡ��������Ƿ��Ѿ�����ɡ� + + while (i != 0x1040) { - i = *(RP)SDC_INTERRUPT_STATUS & 0x1040; - #ifdef USE_TIMEOUT - to--; - if(!to) - { - EOUT("%s Timeout\n",__FUNCTION__); - return RT_ETIMEOUT; - } - #endif + i = *(RP)SDC_INTERRUPT_STATUS & 0x1040; +#ifdef USE_TIMEOUT + to--; + if (!to) + { + EOUT("%s Timeout\n", __FUNCTION__); + return RT_ETIMEOUT; + } +#endif } - - //DBOUT("cmd_response TO is %d\n",to); + + //DBOUT("cmd_response TO is %d\n",to); delay(100); - - return RT_EOK; //�����������Ϣ + + return RT_EOK; } -static rt_err_t cmd_wait(U16 Cmd,U32 Arg,U16 IntMask ) + +static rt_err_t cmd_wait(U16 Cmd, U32 Arg, U16 IntMask) { int i; - #ifdef USE_TIMEOUT - U32 to=200000; - #endif +#ifdef USE_TIMEOUT + U32 to = 200000; +#endif + + *(RP)SDC_CLOCK_CONTROL = 0Xff00; + + *(RP)SDC_CLOCK_CONTROL = 0Xff04; + + *(RP)SDC_COMMAND = Cmd; + + *(RP)SDC_INTERRUPT_STATUS_MASK = IntMask; + + *(RP)SDC_ARGUMENT = Arg; - *(RP)SDC_CLOCK_CONTROL=0Xff00; //����SDʱ�� - - *(RP)SDC_CLOCK_CONTROL=0Xff04; //��SDʱ�� - - *(RP)SDC_COMMAND=Cmd; //������ƼĴ�����ֵ - - *(RP)SDC_INTERRUPT_STATUS_MASK=IntMask; //�ж�״̬���μĴ�����ֵ - - *(RP)SDC_ARGUMENT=Arg; //��������Ĵ�����ֵ - i = *(RP)SDC_INTERRUPT_STATUS & 0x1000; - - while(i != 0x1000) //�жϣ��Ƿ��������ϣ������յ���Ӧ + + while (i != 0x1000) { - i = *(RP)SDC_INTERRUPT_STATUS & 0x1000; - #ifdef USE_TIMEOUT - to--; - if(!to) - { - EOUT("%s Timeout\n",__FUNCTION__); - return RT_ETIMEOUT; - } - #endif + i = *(RP)SDC_INTERRUPT_STATUS & 0x1000; +#ifdef USE_TIMEOUT + to--; + if (!to) + { + EOUT("%s Timeout\n", __FUNCTION__); + return RT_ETIMEOUT; + } +#endif } - //DBOUT("cmd_wait TO is %d\n",to); + //DBOUT("cmd_wait TO is %d\n",to); delay(10); - - return RT_EOK; //�����������Ϣ�Լ���ֵ1 + + return RT_EOK; } + /** * This function will set a hook function, which will be invoked when a memory * block is allocated from heap memory. @@ -205,59 +204,56 @@ static rt_err_t cmd_wait(U16 Cmd,U32 Arg,U16 IntMask ) */ static rt_err_t sd_init(void) { - rt_err_t err; - #ifdef USE_TIMEOUT - rt_uint32_t to=1000; - #endif - sd_pwr(1); - - *(RP)SDC_SOFTWARE_RESET=0x0; //��������λ,����д0�ǽ���reset + rt_err_t err; +#ifdef USE_TIMEOUT + rt_uint32_t to = 1000; +#endif + sd_pwr(1); + + *(RP)SDC_SOFTWARE_RESET = 0x0; delay(200); - *(RP)SDC_SOFTWARE_RESET=0x1; //����������λ + *(RP)SDC_SOFTWARE_RESET = 0x1; delay(200); - - cmd_wait(0x08,0x0,0xfff); //CMD0�������ʹ�� - - do + + cmd_wait(0x08, 0x0, 0xfff); + + do { - err = cmd_wait(0x6ea,0x0,0xfff); //CMD55,���л���ACMD���� + err = cmd_wait(0x6ea, 0x0, 0xfff); + +#ifdef USE_TIMEOUT + if (err != RT_EOK) + { + EOUT("cmd_wait err in %s\n", __FUNCTION__); + return RT_ETIMEOUT; + } +#endif - #ifdef USE_TIMEOUT - if(err != RT_EOK) - { - EOUT("cmd_wait err in %s\n",__FUNCTION__); - return RT_ETIMEOUT; - } - #endif - - delay(3); - err = cmd_wait(0x52a,0x80ff8000,0xfff); //ACMD41����SD��������������ȴ�SD������ȷ���յ����� - if(err != RT_EOK) - { - EOUT("cmd_wait err in %s\n",__FUNCTION__); - return RT_ETIMEOUT; - } - #ifdef USE_TIMEOUT - to--; - if(!to) - { - EOUT("%s timeout\n",__FUNCTION__); - return RT_ETIMEOUT; - } - #endif - - }while(*(RP)SDC_RESPONSE0<0X80008000); + delay(3); + err = cmd_wait(0x52a, 0x80ff8000, 0xfff); + if (err != RT_EOK) + { + EOUT("cmd_wait err in %s\n", __FUNCTION__); + return RT_ETIMEOUT; + } +#ifdef USE_TIMEOUT + to--; + if (!to) + { + EOUT("%s timeout\n", __FUNCTION__); + return RT_ETIMEOUT; + } +#endif - #ifdef USE_TIMEOUT - //DBOUT("%s TO is %d\n",__FUNCTION__,to); - #endif + } + while (*(RP)SDC_RESPONSE0 < 0X80008000); - cmd_data(0x49,0X0,0X0,0x0,0x0,0Xfff);//CMD2������CID - cmd_data(0x6a,0X0,0X0,0x0,0x0,0Xfff);//CMD3��ѯ�ʿ�Ƭ�����µ���ص�ַ - RCA = *(RP)SDC_RESPONSE0; - cmd_data(0xea,RCA,0X0,0x0,0x0,0Xfff);//CMD7������ѡ���Ե���ز��� + cmd_data(0x49, 0X0, 0X0, 0x0, 0x0, 0Xfff); + cmd_data(0x6a, 0X0, 0X0, 0x0, 0x0, 0Xfff); + RCA = *(RP)SDC_RESPONSE0; + cmd_data(0xea, RCA, 0X0, 0x0, 0x0, 0Xfff); - return RT_EOK; + return RT_EOK; } /** @@ -266,108 +262,107 @@ static rt_err_t sd_init(void) * * @param hook the hook function */ -static rt_err_t sd_readblock(rt_uint32_t address, rt_uint8_t* buf) +static rt_err_t sd_readblock(rt_uint32_t address, rt_uint8_t *buf) { - U32 complete,i; - rt_uint8_t temp; - rt_err_t err; - RT_UNUSED rt_uint32_t discard; - #ifdef USE_TIMEOUT - rt_uint32_t to = 10; - #endif + U32 complete, i; + rt_uint8_t temp; + rt_err_t err; + RT_UNUSED rt_uint32_t discard; +#ifdef USE_TIMEOUT + rt_uint32_t to = 10; +#endif + //rt_kprintf("in readblock:%x\n",address); + //Clear all the errors & interrups + *(RP)DMAC_INTINTERRCLR |= 0x1; + *(RP)DMAC_INTINTERRCLR &= ~0x1; + *(RP)DMAC_INTTCCLEAR |= 0x1; + *(RP)DMAC_INTTCCLEAR &= ~0x1; - //rt_kprintf("in readblock:%x\n",address); - //Clear all the errors & interrups - *(RP)DMAC_INTINTERRCLR |= 0x1; - *(RP)DMAC_INTINTERRCLR &= ~0x1; - *(RP)DMAC_INTTCCLEAR |= 0x1; - *(RP)DMAC_INTTCCLEAR &= ~0x1; + /*Clear read fifo*/ + *(RP)(SDC_INTERRUPT_STATUS_MASK) = ~(0x1 << 9); //don't mask fifo empty + while ((*(RP)SDC_INTERRUPT_STATUS) & 0x200 != 0x200) + discard = *(RP)SDC_READ_BUFER_ACCESS; - /*Clear read fifo*/ - *(RP)(SDC_INTERRUPT_STATUS_MASK) = ~(0x1<<9); //don't mask fifo empty - while((*(RP)SDC_INTERRUPT_STATUS)&0x200 != 0x200) - discard = *(RP)SDC_READ_BUFER_ACCESS; + /*DMAC2,word,size=0x80*/ + *(RP)DMAC_C2SRCADDR = SDC_READ_BUFER_ACCESS; + *(RP)DMAC_C2DESTADDR = (rt_uint32_t)buf; + *(RP)DMAC_C2CONTROL = 0x20249b; + *(RP)DMAC_C2CONFIGURATION = 0x38d; - /*DMAC2,word,size=0x80*/ - *(RP)DMAC_C2SRCADDR = SDC_READ_BUFER_ACCESS; - *(RP)DMAC_C2DESTADDR = (rt_uint32_t)buf; - *(RP)DMAC_C2CONTROL =0x20249b; - *(RP)DMAC_C2CONFIGURATION = 0x38d; + err = cmd_wait(0x6ea, RCA, 0xfff); + if (err != RT_EOK) + { + rt_set_errno(err); + return err; + } - err = cmd_wait(0x6ea,RCA,0xfff); - if(err != RT_EOK) - { - rt_set_errno(err); - return err; - } + err = cmd_wait(0xca, 0x2, 0xfff); + if (err != RT_EOK) + { + rt_set_errno(err); + return err; + } + + err = cmd_response(0x22e, address, 0X1, 0x0200, 0x1, 0Xfff); //CMD17 4bit mode + if (err != RT_EOK) + { + rt_set_errno(err); + return err; + } - err = cmd_wait(0xca,0x2,0xfff); - if(err != RT_EOK) - { - rt_set_errno(err); - return err; - } - - err = cmd_response(0x22e,address,0X1,0x0200,0x1,0Xfff); //CMD17 4bit mode - if(err != RT_EOK) - { - rt_set_errno(err); - return err; - } - complete = *(RP)SDC_INTERRUPT_STATUS; - - /*CRC*/ - if((complete |0xfffffffd) !=0xfffffffd) + + /*CRC*/ + if ((complete | 0xfffffffd) != 0xfffffffd) { - rt_kprintf("CRC ERROR!!!\n"); - complete = *(RP)SDC_INTERRUPT_STATUS; + rt_kprintf("CRC ERROR!!!\n"); + complete = *(RP)SDC_INTERRUPT_STATUS; } - while(((*(RP)( DMAC_INTTCSTATUS)) & 0x4) != 0x4 ) - { - delay(10); - #ifdef USE_TIMEOUT - to--; - if(!to) - { - EOUT("%s TIMEOUT\n",__FUNCTION__); - return RT_ETIMEOUT; - } - #endif - } - #ifdef USE_TIMEOUT - //DBOUT("%s timeout is %d\n",__FUNCTION__,to); - #endif - /*for the buf is big-endian we must reverse it*/ - for(i = 0;i<0x80;i++) - { - temp = buf[0]; - buf[0] = buf[3]; - buf[3] = temp; + while (((*(RP)(DMAC_INTTCSTATUS)) & 0x4) != 0x4) + { + delay(10); +#ifdef USE_TIMEOUT + to--; + if (!to) + { + EOUT("%s TIMEOUT\n", __FUNCTION__); + return RT_ETIMEOUT; + } +#endif + } +#ifdef USE_TIMEOUT + //DBOUT("%s timeout is %d\n",__FUNCTION__,to); +#endif + /*for the buf is big-endian we must reverse it*/ + for (i = 0; i < 0x80; i++) + { + temp = buf[0]; + buf[0] = buf[3]; + buf[3] = temp; - temp = buf[1]; - buf[1] = buf[2]; - buf[2] = temp; + temp = buf[1]; + buf[1] = buf[2]; + buf[2] = temp; - buf += 4; - } + buf += 4; + } - return RT_EOK; + return RT_EOK; } -static rt_uint8_t sd_readmultiblock(rt_uint32_t address, rt_uint8_t* buf,rt_uint32_t size) +static rt_uint8_t sd_readmultiblock(rt_uint32_t address, rt_uint8_t *buf, rt_uint32_t size) { - rt_int32_t index; - rt_uint8_t status=RT_EOK; - - for(index = 0;index < size;index++) - { - status = sd_readblock(address+index*SECTOR_SIZE,buf+index*SECTOR_SIZE); - if(status!=RT_EOK) - break; - } - return status; + rt_int32_t index; + rt_uint8_t status = RT_EOK; + + for (index = 0; index < size; index++) + { + status = sd_readblock(address + index * SECTOR_SIZE, buf + index * SECTOR_SIZE); + if (status != RT_EOK) + break; + } + return status; } /** @@ -376,91 +371,90 @@ static rt_uint8_t sd_readmultiblock(rt_uint32_t address, rt_uint8_t* buf,rt_uint * * @param hook the hook function */ -static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t* buf) +static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t *buf) { - U32 complete; - rt_uint8_t temp; - rt_uint8_t *ptr = buf; - rt_err_t err; - #ifdef USE_TIMEOUT - rt_uint32_t to = 10; - #endif + U32 complete; + rt_uint8_t temp; + rt_uint8_t *ptr = buf; + rt_err_t err; +#ifdef USE_TIMEOUT + rt_uint32_t to = 10; +#endif + + int i; + + rt_kprintf("in writeblock:%x\n", address); + + /*for the buf is big-endian we must reverse it*/ + for (i = 0; i < 0x80; i++) + { + temp = ptr[0]; + ptr[0] = ptr[3]; + ptr[3] = temp; - int i; + temp = ptr[1]; + ptr[1] = ptr[2]; + ptr[2] = temp; - rt_kprintf("in writeblock:%x\n",address); + ptr += 4; + } + //Clear all the errors & interrups + *(RP)DMAC_INTINTERRCLR |= 0x1; + *(RP)DMAC_INTINTERRCLR &= ~0x1; + *(RP)DMAC_INTTCCLEAR |= 0x1; + *(RP)DMAC_INTTCCLEAR &= ~0x1; + + *(RP)DMAC_C2SRCADDR = (U32)buf; + *(RP)DMAC_C2DESTADDR = SDC_WRITE_BUFER_ACCESS; + *(RP)DMAC_C2CONTROL = 0x20149b; + *(RP)DMAC_C2CONFIGURATION = 0x380b; - /*for the buf is big-endian we must reverse it*/ - for(i = 0;i<0x80;i++) - { - temp = ptr[0]; - ptr[0] = ptr[3]; - ptr[3] = temp; - temp = ptr[1]; - ptr[1] = ptr[2]; - ptr[2] = temp; + err = cmd_wait(0x6ea, RCA, 0xfff); + if (err != RT_EOK) + { + rt_set_errno(err); + return err; + } - ptr += 4; - } - //Clear all the errors & interrups - *(RP)DMAC_INTINTERRCLR |= 0x1; - *(RP)DMAC_INTINTERRCLR &= ~0x1; - *(RP)DMAC_INTTCCLEAR |= 0x1; - *(RP)DMAC_INTTCCLEAR &= ~0x1; + err = cmd_wait(0xca, 0x2, 0xfff); + if (err != RT_EOK) + { + rt_set_errno(err); + return err; + } - //***********************����DMA2������λд************************* - *(RP)DMAC_C2SRCADDR = (U32)buf; //DMAC��2Դ��ַ��Ϊ0x30200000 - *(RP)DMAC_C2DESTADDR = SDC_WRITE_BUFER_ACCESS; //DMAC��2Ŀ�ĵ�ַ��Ϊ����FIFO�ĵ�ַ - *(RP)DMAC_C2CONTROL = 0x20149b; //����ߴ�0x080,Դ��ַ����Ŀ�ĵ�ַ�����ӣ��������32bit���������Ŀ4 - *(RP)DMAC_C2CONFIGURATION = 0x380b; //�����δ����жϣ����δ����жϣ�ͨ��ʹ�ܣ��������ͣ��洢�������� - - - err = cmd_wait(0x6ea,RCA,0xfff); //CMD55�����л���ACMD���� - if(err != RT_EOK) - { - rt_set_errno(err); - return err; - } + err = cmd_response(0x30e, address, 0X3, 0x0200, 0x1, 0Xfff); //CMD24 1bit mode + if (err != RT_EOK) + { + rt_set_errno(err); + return err; + } - err = cmd_wait(0xca,0x2,0xfff); //ACMD6�����������߿��ȣ�48 λ�̷����������ݴ��� - if(err != RT_EOK) - { - rt_set_errno(err); - return err; - } - - err = cmd_response(0x30e,address,0X3,0x0200,0x1,0Xfff); //CMD24 1bit mode - if(err != RT_EOK) - { - rt_set_errno(err); - return err; - } - complete = *(RP)SDC_INTERRUPT_STATUS; - - if((complete |0xfffffffe) !=0xfffffffe) //��Ӧ��ʱ���� + + if ((complete | 0xfffffffe) != 0xfffffffe) { - //printf("CRC ERROR"); - complete = *(RP)SDC_INTERRUPT_STATUS; - } - - while(((*(RP)( DMAC_INTTCSTATUS)) & 0x4) != 0x4 ) - { - delay(10); - #ifdef USE_TIMEOUT - to--; - if(!to) - { - EOUT("%s TIMEOUT\n",__FUNCTION__); - } - #endif - } - #ifdef USE_TIMEOUT - //DBOUT("%s timeout is %d\n",__FUNCTION__,to); - #endif + //printf("CRC ERROR"); + complete = *(RP)SDC_INTERRUPT_STATUS; + } - return RT_EOK; + while (((*(RP)(DMAC_INTTCSTATUS)) & 0x4) != 0x4) + { + delay(10); +#ifdef USE_TIMEOUT + to--; + if (!to) + { + EOUT("%s TIMEOUT\n", __FUNCTION__); + } +#endif + } +#ifdef USE_TIMEOUT + //DBOUT("%s timeout is %d\n",__FUNCTION__,to); +#endif + + return RT_EOK; } @@ -472,7 +466,7 @@ static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t* buf) */ static rt_err_t rt_sdcard_init(rt_device_t dev) { - return 0; + return 0; } /** @@ -483,7 +477,7 @@ static rt_err_t rt_sdcard_init(rt_device_t dev) */ static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag) { - return 0; + return 0; } /** @@ -494,7 +488,7 @@ static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag) */ static rt_err_t rt_sdcard_close(rt_device_t dev) { - return 0; + return 0; } /** @@ -505,8 +499,8 @@ static rt_err_t rt_sdcard_close(rt_device_t dev) */ static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args) { - rt_kprintf("cmd = %d\n",cmd); - RT_ASSERT(dev != RT_NULL); + rt_kprintf("cmd = %d\n", cmd); + RT_ASSERT(dev != RT_NULL); if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) { @@ -517,10 +511,10 @@ static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args) geometry->bytes_per_sector = 512; geometry->block_size = 0x200000; - //if (CardType == SDIO_HIGH_CAPACITY_SD_CARD) - // geometry->sector_count = (SDCardInfo.SD_csd.DeviceSize + 1) * 1024; - //else - geometry->sector_count = 0x200000;//SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize; + //if (CardType == SDIO_HIGH_CAPACITY_SD_CARD) + // geometry->sector_count = (SDCardInfo.SD_csd.DeviceSize + 1) * 1024; + //else + geometry->sector_count = 0x200000;//SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize; } return RT_EOK; @@ -532,47 +526,55 @@ static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args) * * @param hook the hook function */ -static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) { - rt_uint32_t retry = 3; - rt_uint8_t status; - rt_uint32_t index; + rt_uint32_t retry = 3; + rt_uint8_t status; + rt_uint32_t index; + + struct dfs_partition *part; + + if (dev == RT_NULL) + { + rt_set_errno(-DFS_STATUS_EINVAL); + return 0; + } - ///*take the semaphore - struct dfs_partition *part = (struct dfs_partition *)dev->user_data; - rt_sem_take(part->lock, RT_WAITING_FOREVER); - while(retry--) + part = (struct dfs_partition *)dev->user_data; + // take the semaphore + rt_sem_take(part->lock, RT_WAITING_FOREVER); + while (retry--) { - if (((rt_uint32_t)buffer % 4 != 0) || - ((rt_uint32_t)buffer > 0x20080000)) - { - for(index = 0;index < size;index++) - { - status = sd_readblock((part->offset + pos) * SECTOR_SIZE,ptr_sddev->sec_buf); - if(status != RT_EOK) - break; - - rt_memcpy((rt_uint8_t *)buffer + (index * SECTOR_SIZE),ptr_sddev->sec_buf,SECTOR_SIZE); - } - } - else - { - for(index = 0;index<size;index++) - { - status = sd_readblock((pos) * SECTOR_SIZE,(rt_uint8_t*)buffer + index * SECTOR_SIZE); - if(status != RT_EOK) - break; - } - } + if (((rt_uint32_t)buffer % 4 != 0) || + ((rt_uint32_t)buffer > 0x20080000)) + { + for (index = 0; index < size; index++) + { + status = sd_readblock((part->offset + pos) * SECTOR_SIZE, ptr_sddev->sec_buf); + if (status != RT_EOK) + break; - } - rt_sem_release(part->lock); + rt_memcpy((rt_uint8_t *)buffer + (index * SECTOR_SIZE), ptr_sddev->sec_buf, SECTOR_SIZE); + } + } + else + { + for (index = 0; index < size; index++) + { + status = sd_readblock((pos) * SECTOR_SIZE, (rt_uint8_t *)buffer + index * SECTOR_SIZE); + if (status != RT_EOK) + break; + } + } - if (status == RT_EOK) - return size; + } + rt_sem_release(part->lock); + + if (status == RT_EOK) + return size; - rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer); - return 0; + rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer); + return 0; } @@ -582,63 +584,64 @@ static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_ * * @param hook the hook function */ -static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +static rt_size_t rt_sdcard_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) { - int i; - rt_uint8_t status; + int i; + rt_uint8_t status; + struct dfs_partition *part; - struct dfs_partition *part = (struct dfs_partition *)dev->user_data; + if (dev == RT_NULL) + { + rt_set_errno(-DFS_STATUS_EINVAL); + return 0; + } - if ( dev == RT_NULL ) - { - rt_set_errno(-DFS_STATUS_EINVAL); - return 0; - } + part = (struct dfs_partition *)dev->user_data; - rt_sem_take(part->lock, RT_WAITING_FOREVER); + rt_sem_take(part->lock, RT_WAITING_FOREVER); if (((rt_uint32_t)buffer % 4 != 0) || - ((rt_uint32_t)buffer > 0x20080000)) - { - rt_uint32_t index; + ((rt_uint32_t)buffer > 0x20080000)) + { + rt_uint32_t index; - for(index=0;index<size;index++) - { - rt_memcpy(ptr_sddev->sec_buf, ((rt_uint8_t*)buffer + index * SECTOR_SIZE), SECTOR_SIZE); - status = sd_writeblock((part->offset + index + pos)*SECTOR_SIZE,ptr_sddev->sec_buf); - } - } - else - { + for (index = 0; index < size; index++) + { + rt_memcpy(ptr_sddev->sec_buf, ((rt_uint8_t *)buffer + index * SECTOR_SIZE), SECTOR_SIZE); + status = sd_writeblock((part->offset + index + pos) * SECTOR_SIZE, ptr_sddev->sec_buf); + } + } + else + { - for(i=0;i<size;i++) - { - status = sd_writeblock((part->offset + i + pos)*SECTOR_SIZE, - (rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE)); - if (status != RT_EOK) break; - } - } + for (i = 0; i < size; i++) + { + status = sd_writeblock((part->offset + i + pos) * SECTOR_SIZE, + (rt_uint8_t *)((rt_uint8_t *)buffer + i * SECTOR_SIZE)); + if (status != RT_EOK) break; + } + } - rt_sem_release(part->lock); + rt_sem_release(part->lock); - if (status == RT_EOK) - return size; + if (status == RT_EOK) + return size; - rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer); - return 0; + rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer); + return 0; } rt_err_t rt_hw_sdcard_exit() { - if(ptr_sddev->device != RT_NULL) - rt_free(ptr_sddev->device); - if(ptr_sddev->part != RT_NULL) - rt_free(ptr_sddev->part); - if(ptr_sddev != RT_NULL) - rt_free(ptr_sddev); + if (ptr_sddev->device != RT_NULL) + rt_free(ptr_sddev->device); + if (ptr_sddev->part != RT_NULL) + rt_free(ptr_sddev->part); + if (ptr_sddev != RT_NULL) + rt_free(ptr_sddev); - return RT_EOK; + return RT_EOK; } /** @@ -648,143 +651,141 @@ rt_err_t rt_hw_sdcard_exit() */ rt_err_t rt_hw_sdcard_init() { - /*For test*/ - rt_err_t err; - rt_int32_t i; + /*For test*/ + rt_err_t err; + rt_int32_t i; - char dname[4]; - char sname[8]; + char dname[4]; + char sname[8]; - /*Initialize structure*/ + /*Initialize structure*/ - ptr_sddev = (struct sd_device*)rt_malloc(sizeof(struct sd_device)); - if(ptr_sddev == RT_NULL) - { - EOUT("Failed to allocate sdcard device structure\n"); - return RT_ENOMEM; - } - - /*sdcard intialize*/ - err = sd_init(); - if(err != RT_EOK) - goto FAIL2; + ptr_sddev = (struct sd_device *)rt_malloc(sizeof(struct sd_device)); + if (ptr_sddev == RT_NULL) + { + EOUT("Failed to allocate sdcard device structure\n"); + return RT_ENOMEM; + } - /*set sector buffer*/ - ptr_sddev->sec_buf = gsec_buf; - ptr_sddev->buf_size = SECTOR_SIZE; - ptr_sddev->sdc = (struct sd_c*)SD_BASE; + /*sdcard intialize*/ + err = sd_init(); + if (err != RT_EOK) + goto FAIL2; - //DBOUT("allocate partition sector buffer OK!"); + /*set sector buffer*/ + ptr_sddev->sec_buf = gsec_buf; + ptr_sddev->buf_size = SECTOR_SIZE; + ptr_sddev->sdc = (struct sd_c *)SD_BASE; - err = sd_readblock(0,ptr_sddev->sec_buf); - if(err != RT_EOK) - { - EOUT("read first block error\n"); - goto FAIL2; - } + //DBOUT("allocate partition sector buffer OK!"); - /*sdcard driver initialize*/ - ptr_sddev->part = (struct dfs_partition*)rt_malloc(4 * sizeof(struct dfs_partition)); - if(ptr_sddev->part == RT_NULL) - { - EOUT("allocate partition failed\n"); - err = RT_ENOMEM; - goto FAIL2; - } + err = sd_readblock(0, ptr_sddev->sec_buf); + if (err != RT_EOK) + { + EOUT("read first block error\n"); + goto FAIL2; + } - /*alloc device buffer*/ - ptr_sddev->device = (struct rt_device*)rt_malloc(4 * sizeof(struct rt_device)); - if(ptr_sddev->device == RT_NULL) - { - EOUT("allocate device failed\n"); - err = RT_ENOMEM; - goto FAIL1; - } + /*sdcard driver initialize*/ + ptr_sddev->part = (struct dfs_partition *)rt_malloc(4 * sizeof(struct dfs_partition)); + if (ptr_sddev->part == RT_NULL) + { + EOUT("allocate partition failed\n"); + err = RT_ENOMEM; + goto FAIL2; + } - ptr_sddev->part_num = 0; + /*alloc device buffer*/ + ptr_sddev->device = (struct rt_device *)rt_malloc(4 * sizeof(struct rt_device)); + if (ptr_sddev->device == RT_NULL) + { + EOUT("allocate device failed\n"); + err = RT_ENOMEM; + goto FAIL1; + } - err = sd_readblock(0,ptr_sddev->sec_buf); + ptr_sddev->part_num = 0; - if(err != RT_EOK) - { - EOUT("Read block 0 to initialize ERROR\n"); - goto FAIL1; - } + err = sd_readblock(0, ptr_sddev->sec_buf); - for(i=0; i<4; i++) - { - /* get the first partition */ - err = dfs_filesystem_get_partition(&(ptr_sddev->part[i]), ptr_sddev->sec_buf, i); - if (err == RT_EOK) - { - rt_snprintf(dname, 4, "sd%d", i); - rt_snprintf(sname, 8, "sem_sd%d", i); - ptr_sddev->part[i].lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + if (err != RT_EOK) + { + EOUT("Read block 0 to initialize ERROR\n"); + goto FAIL1; + } - /* register sdcard device */ - ptr_sddev->device[i].init = rt_sdcard_init; - ptr_sddev->device[i].open = rt_sdcard_open; - ptr_sddev->device[i].close = rt_sdcard_close; - ptr_sddev->device[i].read = rt_sdcard_read; - ptr_sddev->device[i].write = rt_sdcard_write; - ptr_sddev->device[i].control = rt_sdcard_control; - ptr_sddev->device[i].user_data= &ptr_sddev->part[i]; + for (i = 0; i < 4; i++) + { + /* get the first partition */ + err = dfs_filesystem_get_partition(&(ptr_sddev->part[i]), ptr_sddev->sec_buf, i); + if (err == RT_EOK) + { + rt_snprintf(dname, 4, "sd%d", i); + rt_snprintf(sname, 8, "sem_sd%d", i); + ptr_sddev->part[i].lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); - err = rt_device_register(&ptr_sddev->device[i], dname, - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + /* register sdcard device */ + ptr_sddev->device[i].init = rt_sdcard_init; + ptr_sddev->device[i].open = rt_sdcard_open; + ptr_sddev->device[i].close = rt_sdcard_close; + ptr_sddev->device[i].read = rt_sdcard_read; + ptr_sddev->device[i].write = rt_sdcard_write; + ptr_sddev->device[i].control = rt_sdcard_control; + ptr_sddev->device[i].user_data = &ptr_sddev->part[i]; - if(err == RT_EOK) - ptr_sddev->part_num++; - } - else - { - if(i == 0) - { - /* there is no partition table */ - ptr_sddev->part[0].offset = 0; - ptr_sddev->part[0].size = 0; - ptr_sddev->part[0].lock = rt_sem_create("sem_sd0", 1, RT_IPC_FLAG_FIFO); + err = rt_device_register(&ptr_sddev->device[i], dname, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); - /* register sdcard device */ - ptr_sddev->device[0].init = rt_sdcard_init; - ptr_sddev->device[0].open = rt_sdcard_open; - ptr_sddev->device[0].close = rt_sdcard_close; - ptr_sddev->device[0].read = rt_sdcard_read; - ptr_sddev->device[0].write = rt_sdcard_write; - ptr_sddev->device[0].control = rt_sdcard_control; - ptr_sddev->device[0].user_data= &ptr_sddev->part[0]; + if (err == RT_EOK) + ptr_sddev->part_num++; + } + else + { + if (i == 0) + { + /* there is no partition table */ + ptr_sddev->part[0].offset = 0; + ptr_sddev->part[0].size = 0; + ptr_sddev->part[0].lock = rt_sem_create("sem_sd0", 1, RT_IPC_FLAG_FIFO); - err = rt_device_register(&ptr_sddev->device[0], "sd0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + /* register sdcard device */ + ptr_sddev->device[0].init = rt_sdcard_init; + ptr_sddev->device[0].open = rt_sdcard_open; + ptr_sddev->device[0].close = rt_sdcard_close; + ptr_sddev->device[0].read = rt_sdcard_read; + ptr_sddev->device[0].write = rt_sdcard_write; + ptr_sddev->device[0].control = rt_sdcard_control; + ptr_sddev->device[0].user_data = &ptr_sddev->part[0]; - if(err == RT_EOK) - ptr_sddev->part_num++; + err = rt_device_register(&ptr_sddev->device[0], "sd0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); - break; - } - } - } + if (err == RT_EOK) + ptr_sddev->part_num++; - if(ptr_sddev->part_num == 0) - goto FAIL0; - - return err; + break; + } + } + } - FAIL0: - rt_free(ptr_sddev->device); - ptr_sddev->device = RT_NULL; + if (ptr_sddev->part_num == 0) + goto FAIL0; - FAIL1: - rt_free(ptr_sddev->part); - ptr_sddev->part = RT_NULL; + return err; - FAIL2: - rt_free(ptr_sddev); - ptr_sddev = RT_NULL; +FAIL0: + rt_free(ptr_sddev->device); + ptr_sddev->device = RT_NULL; - return err; +FAIL1: + rt_free(ptr_sddev->part); + ptr_sddev->part = RT_NULL; +FAIL2: + rt_free(ptr_sddev); + ptr_sddev = RT_NULL; + return err; } #endif diff --git a/bsp/mini4020/drivers/sdcard.h b/bsp/mini4020/drivers/sdcard.h index ce19f8f48c..c8a4acf1a1 100644 --- a/bsp/mini4020/drivers/sdcard.h +++ b/bsp/mini4020/drivers/sdcard.h @@ -17,43 +17,43 @@ #include <rtthread.h> #ifdef RT_USING_DFS - + #include <sep4020.h> -#define INICLK 300000 -#define SDCLK 24000000 //PCLK=49.392MHz -#define MMCCLK 15000000 //PCLK=49.392MHz +#define INICLK 300000 +#define SDCLK 24000000 //PCLK=49.392MHz +#define MMCCLK 15000000 //PCLK=49.392MHz /*struct of the SDC*/ -struct sd_c +struct sd_c { - __IO rt_uint32_t clk_ctl; - __IO rt_uint32_t soft_rst; - __IO rt_uint32_t arg; - __IO rt_uint32_t cmd; - __IO rt_uint32_t blk_sz; - __IO rt_uint32_t blk_cnt; - __IO rt_uint32_t trans_mode; - __O rt_uint32_t response0; - __O rt_uint32_t response1; - __O rt_uint32_t response2; - __O rt_uint32_t response3; - __IO rt_uint32_t rd_to_ctl; - __IO rt_uint32_t int_stat; - __IO rt_uint32_t int_stat_mask; - __O rt_uint32_t rx_fifo; - __I rt_uint32_t tx_fifo; + __IO rt_uint32_t clk_ctl; + __IO rt_uint32_t soft_rst; + __IO rt_uint32_t arg; + __IO rt_uint32_t cmd; + __IO rt_uint32_t blk_sz; + __IO rt_uint32_t blk_cnt; + __IO rt_uint32_t trans_mode; + __O rt_uint32_t response0; + __O rt_uint32_t response1; + __O rt_uint32_t response2; + __O rt_uint32_t response3; + __IO rt_uint32_t rd_to_ctl; + __IO rt_uint32_t int_stat; + __IO rt_uint32_t int_stat_mask; + __O rt_uint32_t rx_fifo; + __I rt_uint32_t tx_fifo; }; /*sdcard driver structure*/ -struct sd_device +struct sd_device { - struct rt_device *device; /*rt_device*/ - struct sd_c *sdc; /*SDCARD register*/ - struct dfs_partition *part; /*dfs partitions*/ - rt_uint8_t *sec_buf; /*sdcard buffer*/ - rt_uint32_t part_num; /*partiont numbers*/ - rt_uint32_t buf_size; /*buffer size*/ + struct rt_device *device; /*rt_device*/ + struct sd_c *sdc; /*SDCARD register*/ + struct dfs_partition *part; /*dfs partitions*/ + rt_uint8_t *sec_buf; /*sdcard buffer*/ + rt_uint32_t part_num; /*partiont numbers*/ + rt_uint32_t buf_size; /*buffer size*/ }; #endif |
