/* * Routines to access hardware * * Copyright (c) 2015 Realtek Semiconductor Corp. * * This module is a confidential and proprietary property of RealTek and * possession or use of this module requires written permission of RealTek. */ #include "FreeRTOS.h" #include "task.h" #include "diag.h" #include "main.h" #include "spdio_api.h" /** * @brief Main program. * @param None * @retval None */ #define EX_SPDIO_STACKSIZE 2048 #define EX_SPDIO_TX_BD_NUM 24 //n*2, 2 bd for one transaction #define EX_SPDIO_RX_BD_NUM 20 #define EX_SPDIO_RX_BUFSZ (SPDIO_RX_BUFSZ_ALIGN(2048+24)) //n*64, must be rounded to 64, extra 24 bytes for spdio header info struct spdio_t spdio_dev; /* * param: pdata, package */ char ex_spdio_tx(u8 *pdata, u16 size, u8 type){ static int loop_cnt = 0; struct spdio_buf_t *tx_buf = (struct spdio_buf_t *)malloc(sizeof(struct spdio_buf_t)); memset((u8 *)tx_buf, 0, sizeof(struct spdio_buf_t)); if(!tx_buf) return FAIL; tx_buf->buf_allocated = (u32)malloc(size + SPDIO_DMA_ALIGN_4); if(!tx_buf->buf_allocated) { free((u8 *)tx_buf); return FAIL; } tx_buf->size_allocated = size + SPDIO_DMA_ALIGN_4; tx_buf->buf_addr = (u32)N_BYTE_ALIGMENT((u32)(tx_buf->buf_allocated), SPDIO_DMA_ALIGN_4); // copy data memcpy((void*)tx_buf->buf_addr, pdata, size); tx_buf->buf_size = size; tx_buf->type = SPDIO_RX_DATA_USER; // you can define your own data type in spdio_rx_data_t and spdio_tx_data_t printf("loopback package, size = %d (cnt = %d) heap=%d\n", size, ++loop_cnt, xPortGetFreeHeapSize()); // loopback spdio_tx(&spdio_dev, tx_buf); return SUCCESS; } /*spdio rx done callback (HOST->Device), manage your package and buffer*/ char ex_spdio_rx_done_cb(void *priv, void *pbuf, u8 *pdata, u16 size, u8 type){ struct spdio_t *obj = (struct spdio_t *)priv; struct spdio_buf_t* rx_buf = (struct spdio_buf_t*)pbuf; // handle package received ex_spdio_tx(pdata, size, type); // manage rx_buf here free((char *)rx_buf->buf_allocated); // assign new buffer for SPDIO RX rx_buf->buf_allocated = (u32)malloc(obj->rx_bd_bufsz + SPDIO_DMA_ALIGN_4); rx_buf->size_allocated = obj->rx_bd_bufsz + SPDIO_DMA_ALIGN_4; // this buffer must be 4 byte alignment rx_buf->buf_addr = (u32)N_BYTE_ALIGMENT((u32)(rx_buf->buf_allocated), SPDIO_DMA_ALIGN_4); return SUCCESS; } /*spdio tx done callback(Device->HOST), manage buffer*/ // this API will be called after package have been moved to HOST char ex_spdio_tx_done_cb(void *priv, void *pbuf){ struct spdio_buf_t* tx_buf = (struct spdio_buf_t*)pbuf; free((u8 *)tx_buf->buf_allocated); free((u8 *)tx_buf); return SUCCESS; } void ex_spdio_thread(void* param){ int i; spdio_dev.priv = NULL; spdio_dev.rx_bd_num = EX_SPDIO_RX_BD_NUM; spdio_dev.tx_bd_num = EX_SPDIO_TX_BD_NUM; spdio_dev.rx_bd_bufsz = EX_SPDIO_RX_BUFSZ; spdio_dev.rx_buf = (struct spdio_buf_t *)malloc(spdio_dev.rx_bd_num*sizeof(struct spdio_buf_t)); if(!spdio_dev.rx_buf){ printf("malloc failed for spdio buffer structure!\n"); return; } for(i=0;i