123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- #include "driver/slc_register.h"
- #include "driver/sdio_slv.h"
- #include "ets_sys.h"
- #include "osapi.h"
- #include "os_type.h"
- #include "user_interface.h"
- #include "mem.h"
- #define SDIO_TOKEN_SIZE 0
- #define RX_BUFFER_SIZE 512
- #define RX_BUFFER_NUM 4
- #define TX_BUFFER_SIZE 512
- #define SLC_INTEREST_EVENT (SLC_TX_EOF_INT_ENA | SLC_RX_EOF_INT_ENA | SLC_RX_UDF_INT_ENA | SLC_TX_DSCR_ERR_INT_ENA)
- #define TRIG_TOHOST_INT() SET_PERI_REG_MASK(SLC_INTVEC_TOHOST , BIT0);\
-
- struct sdio_queue
- {
- uint32 blocksize:12;
- uint32 datalen:12;
- uint32 unused:5;
- uint32 sub_sof:1;
- uint32 eof:1;
- uint32 owner:1;
- uint32 buf_ptr;
- uint32 next_link_ptr;
- };
- struct sdio_slave_status_element
- {
- uint32 wr_busy:1;
- uint32 rd_empty :1;
- uint32 comm_cnt :3;
- uint32 intr_no :3;
- uint32 rx_length:16;
- uint32 res:8;
- };
- union sdio_slave_status
- {
- struct sdio_slave_status_element elm_value;
- uint32 word_value;
- };
- uint8 tx_buffer[TX_BUFFER_SIZE];
- uint32 data_len = 0;
- struct sdio_list {
- uint8 buffer[RX_BUFFER_SIZE + SDIO_TOKEN_SIZE];
- uint8* tail;
- struct sdio_list* next;
- };
- static sdio_recv_data_callback_t sdio_recv_data_callback_ptr = NULL;
- struct sdio_list* pHead_ToSend;
- struct sdio_list* pTail_ToSend;
- struct sdio_list* pHead_Sended;
- struct sdio_list* pTail_Sended;
- os_event_t * sdioQueue;
- struct sdio_queue rx_que,tx_que;
- static bool has_read = 0;
- static void sdio_slave_isr(void *para);
- static void tx_buff_handle_done(void);
- static void rx_buff_read_done(void);
- static void tx_buff_write_done(void);
- static void sdio_try_to_load(void);
- static void sdio_read_done_process(void);
- void sdio_slave_init(void)
- {
- uint32 regval = 0;
- union sdio_slave_status sdio_sta;
- ETS_SDIO_INTR_DISABLE();
-
- SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST|SLC_TXLINK_RST);
- CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST|SLC_TXLINK_RST);
- os_printf("RX&TX link reset!\n");
-
- SET_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_RX_EOF_MODE | SLC_RX_FILL_MODE);
-
- WRITE_PERI_REG(SLC_HOST_INTR_CLR, 0xffffffff);
-
- SET_PERI_REG_MASK(SLC_HOST_INTR_ENA , SLC_HOST_TOHOST_BIT0_INT_ENA);
-
- has_read = TRUE;
- pHead_ToSend = NULL;
- int loop = RX_BUFFER_NUM;
- struct sdio_list* p = NULL;
- while(loop--) {
- if(pHead_Sended == NULL) {
- pHead_Sended = (struct sdio_list*)os_malloc(sizeof(struct sdio_list));
- p = pHead_Sended;
- } else {
- p->next = (struct sdio_list*)os_malloc(sizeof(struct sdio_list));
- p = p->next;
- }
-
- p->tail = p->buffer + SDIO_TOKEN_SIZE;
- p->next = NULL;
- }
- pTail_Sended = p;
-
- rx_que.blocksize = RX_BUFFER_SIZE;
- rx_que.datalen=0;
- rx_que.eof=1;
- rx_que.owner=1;
- rx_que.sub_sof=0;
- rx_que.unused=0;
- rx_que.buf_ptr=(uint32)pHead_Sended->buffer;
- rx_que.next_link_ptr=0;
-
- tx_que.blocksize=TX_BUFFER_SIZE;
- tx_que.datalen=0;
- tx_que.eof=0;
- tx_que.owner=1;
- tx_que.sub_sof=0;
- tx_que.unused=0;
- tx_que.buf_ptr=(uint32)tx_buffer;
- tx_que.next_link_ptr=0;
-
- CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK);
- regval= ((uint32)&rx_que);
- SET_PERI_REG_MASK(SLC_RX_LINK, regval&SLC_RXLINK_DESCADDR_MASK);
- CLEAR_PERI_REG_MASK(SLC_TX_LINK,SLC_TXLINK_DESCADDR_MASK);
- regval= ((uint32)&tx_que);
- SET_PERI_REG_MASK(SLC_TX_LINK, regval&SLC_TXLINK_DESCADDR_MASK);
- #if (SDIO_TOKEN_SIZE == 0)
- SET_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_TOKEN_NO_REPLACE);
- #endif
-
- sdio_sta.elm_value.comm_cnt=7;
- sdio_sta.elm_value.intr_no=INIT_STAGE;
- sdio_sta.elm_value.wr_busy=0;
- sdio_sta.elm_value.rd_empty=1;
- sdio_sta.elm_value.rx_length=0;
- sdio_sta.elm_value.res=0;
- SET_PERI_REG_MASK(SLC_TX_LINK, SLC_TXLINK_START);
- WRITE_PERI_REG(SLC_HOST_CONF_W2, sdio_sta.word_value);
-
- ETS_SDIO_INTR_ATTACH(sdio_slave_isr, NULL);
-
- WRITE_PERI_REG(SLC_INT_ENA, SLC_INTEREST_EVENT);
-
- WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);
-
- ETS_SDIO_INTR_ENABLE();
- }
- static void sdio_slave_isr(void *para)
- {
- uint32 slc_intr_status,postval;
- static uint8 state =0;
- uint16 rx_len,i;
- uint32* pword;
- union sdio_slave_status sdio_sta;
- slc_intr_status = READ_PERI_REG(SLC_INT_STATUS);
- if (slc_intr_status == 0)
- {
-
- return;
- }
-
- WRITE_PERI_REG(SLC_INT_CLR, slc_intr_status);
-
-
-
- if (slc_intr_status & SLC_RX_EOF_INT_ENA)
- {
-
- rx_buff_read_done();
-
-
- sdio_read_done_process();
- }
-
- if (slc_intr_status & SLC_TX_EOF_INT_ENA)
- {
-
- tx_buff_write_done();
-
-
-
- if(sdio_recv_data_callback_ptr) {
- sdio_recv_data_callback_ptr((uint8*)tx_que.buf_ptr,tx_que.datalen);
- }
- tx_buff_handle_done();
- TRIG_TOHOST_INT();
-
- }
-
- if(slc_intr_status & SLC_RX_UDF_INT_ENA)
- {
- }
-
- if(slc_intr_status & SLC_TX_DSCR_ERR_INT_ENA)
- {
- }
- slc_intr_status = READ_PERI_REG(SLC_INT_STATUS);
- if(slc_intr_status)
- {
- WRITE_PERI_REG(SLC_INT_CLR, slc_intr_status);
- os_printf("slc_intr_status:0x%08x\r\n",slc_intr_status);
- }
- }
- static void rx_buff_read_done(void)
- {
- union sdio_slave_status sdio_sta;
-
- sdio_sta.word_value=READ_PERI_REG(SLC_HOST_CONF_W2);
- sdio_sta.elm_value.comm_cnt++;
- sdio_sta.elm_value.rd_empty=1;
- sdio_sta.elm_value.rx_length=0;
- sdio_sta.elm_value.intr_no &= (~RX_AVAILIBLE);
- WRITE_PERI_REG(SLC_HOST_CONF_W2, sdio_sta.word_value);
-
- }
- static void tx_buff_write_done(void)
- {
- union sdio_slave_status sdio_sta;
-
- sdio_sta.word_value=READ_PERI_REG(SLC_HOST_CONF_W2);
- sdio_sta.elm_value.comm_cnt++;
- sdio_sta.elm_value.wr_busy=1;
- sdio_sta.elm_value.intr_no &= (~TX_AVAILIBLE);
- WRITE_PERI_REG(SLC_HOST_CONF_W2, sdio_sta.word_value);
- }
- static void tx_buff_handle_done(void)
- {
- union sdio_slave_status sdio_sta;
-
- tx_que.blocksize=TX_BUFFER_SIZE;
- tx_que.datalen=0;
- tx_que.eof=0;
- tx_que.owner=1;
-
- sdio_sta.word_value=READ_PERI_REG(SLC_HOST_CONF_W2);
- sdio_sta.elm_value.wr_busy=0;
- sdio_sta.elm_value.intr_no |= TX_AVAILIBLE;
- SET_PERI_REG_MASK(SLC_TX_LINK, SLC_TXLINK_START);
- WRITE_PERI_REG(SLC_HOST_CONF_W2, sdio_sta.word_value);
-
- }
- static int32 rx_buff_load_done(uint16 rx_len)
- {
- union sdio_slave_status sdio_sta;
- if(rx_len == 0) {
- return 0;
- }
- if(rx_len > rx_que.blocksize)
- {
- rx_len = rx_que.blocksize;
- }
-
-
- rx_que.blocksize=RX_BUFFER_SIZE;
- rx_que.datalen=rx_len + SDIO_TOKEN_SIZE;
- rx_que.eof=1;
- rx_que.owner=1;
-
-
-
- sdio_sta.word_value=READ_PERI_REG(SLC_HOST_CONF_W2);
- sdio_sta.elm_value.rd_empty=0;
- sdio_sta.elm_value.intr_no |= RX_AVAILIBLE;
- sdio_sta.elm_value.rx_length=rx_len;
- SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START);
- WRITE_PERI_REG(SLC_HOST_CONF_W2, sdio_sta.word_value);
-
-
-
- return rx_len;
- }
- int32 ICACHE_FLASH_ATTR sdio_load_data(const uint8* data,uint32 len)
- {
- int32 data_len = 0;
- if (pHead_Sended == NULL) {
- os_printf("no buf\r\n");
- return 0;
- }
- int32 left_len = 0;
-
- while(len)
- {
- left_len = RX_BUFFER_SIZE + SDIO_TOKEN_SIZE - (uint32)(pHead_Sended->tail - pHead_Sended->buffer);
- if(len < left_len)
- {
- os_memcpy(pHead_Sended->tail,data,len);
- pHead_Sended->tail += len;
- len = 0;
- data_len += len;
-
- }
- else
- {
- os_memcpy(pHead_Sended->tail,data,left_len);
- pHead_Sended->tail += left_len;
- len -= left_len;
- data += left_len;
- data_len += left_len;
- if(pHead_ToSend == NULL) {
- pTail_ToSend = pHead_Sended;
- pHead_ToSend = pTail_ToSend;
- } else {
- pTail_ToSend->next = pHead_Sended;
- pTail_ToSend = pTail_ToSend->next;
- }
- pHead_Sended = pHead_Sended->next;
-
- pTail_ToSend->next = NULL;
- if(pHead_Sended == NULL)
- {
- os_printf("buf full\r\n");
- break;
- }
-
- }
- }
-
-
- if(pHead_ToSend == NULL) {
- pTail_ToSend = pHead_Sended;
- pHead_ToSend = pTail_ToSend;
- pHead_Sended = pHead_Sended->next;
- pTail_ToSend->next = NULL;
-
- sdio_try_to_load();
- }
- return data_len;
- }
- static void sdio_try_to_load(void)
- {
- if((has_read == TRUE) && (pHead_ToSend != NULL))
- {
- rx_que.buf_ptr = (uint32)pHead_ToSend->buffer;
- rx_buff_load_done(pHead_ToSend->tail- pHead_ToSend->buffer - SDIO_TOKEN_SIZE);
-
- has_read = FALSE;
-
- TRIG_TOHOST_INT();
- }
- }
- static void sdio_read_done_process(void)
- {
- has_read = TRUE;
-
- pHead_ToSend->tail = pHead_ToSend->buffer + SDIO_TOKEN_SIZE;
- if(pHead_Sended) {
- pTail_Sended->next = pHead_ToSend;
- pTail_Sended = pTail_Sended->next;
- }else {
- pTail_Sended = pHead_ToSend;
- pHead_Sended = pTail_Sended;
- }
- pHead_ToSend = pHead_ToSend->next;
- pTail_Sended->next = NULL;
-
- if(pHead_ToSend) {
- rx_que.buf_ptr = (uint32)pHead_ToSend->buffer;
- rx_buff_load_done(pHead_ToSend->tail - pHead_ToSend->buffer - SDIO_TOKEN_SIZE);
- has_read = FALSE;
-
-
- } else if ((pHead_Sended != NULL) && (pHead_Sended->buffer != (pHead_Sended->tail- SDIO_TOKEN_SIZE))) {
- pHead_ToSend = pHead_Sended;
- pTail_ToSend = pHead_ToSend;
- pHead_Sended = pHead_Sended->next;
- pTail_ToSend->next = NULL;
-
- rx_que.buf_ptr = (uint32)pHead_ToSend->buffer;
- rx_buff_load_done(pHead_ToSend->tail- pHead_ToSend->buffer - SDIO_TOKEN_SIZE);
- has_read = FALSE;
-
-
- }
- TRIG_TOHOST_INT();
- }
- bool sdio_register_recv_cb(sdio_recv_data_callback_t cb)
- {
- sdio_recv_data_callback_ptr = cb;
-
- return TRUE;
- }
|