123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2021-03-18 Carl the first version
- */
- #include "drv_sdctrl.h"
- #include "ft_sdctrl_hw.h"
- #include "ft_sdctrl.h"
- #include "ft_debug.h"
- #include "ft_types.h"
- #include "ft_generic_timer.h"
- #include <drivers/mmcsd_core.h>
- #include "interrupt.h"
- #include "rtconfig.h"
- #include "ft_cache.h"
- #ifdef BSP_USING_SDC
- #define LOG_TAG "drv.sdmmc"
- #include <drv_log.h>
- #define RTHW_SDCTRL_LOCK(_sdctrl) rt_mutex_take(&_sdctrl->mutex, RT_WAITING_FOREVER)
- #define RTHW_SDCTRL_UNLOCK(_sdctrl) rt_mutex_release(&_sdctrl->mutex);
- struct mmcsd_pkg
- {
- struct rt_mmcsd_cmd *cmd;
- void *buff;
- rt_uint32_t flag;
- };
- typedef struct
- {
- FtsdCtrl_t ft_sdctrl;
- struct rt_mmcsd_host *host;
- struct rt_event event;
- struct rt_mutex mutex;
- struct mmcsd_pkg *pkg;
- } ft_sdctrl_class_t;
- ft_sdctrl_class_t sdctrl_class;
- rt_align(SDCTR_ALIGN_LEN)
- static rt_uint8_t cache_buf[SDCTR_BUFF_SIZE];
- static void rthw_sdctrl_send_command(ft_sdctrl_class_t *class_p, struct mmcsd_pkg *pkg);
- static void demo_dump_sdc(void)
- {
- Ft_DumpHexWord((const rt_uint32_t *)(0x28207C00), 256);
- }
- MSH_CMD_EXPORT_ALIAS(demo_dump_sdc, dump_sdc, output all dump_sdc);
- static void rthw_sdctrl_delay(u32 delayCnt)
- {
- Ft_GenericTimer_UsDelay(delayCnt);
- }
- static u32 rthw_sdctrl_rasp2type(u32 rasp)
- {
- switch (rasp)
- {
- case RESP_NONE:
- return FTSDCTRL_CMD_RES_NONE;
- case RESP_R2:
- return FTSDCTRL_CMD_RES_LONG;
- default:
- return FTSDCTRL_CMD_RES_SHORT;
- }
- return FTSDCTRL_CMD_RES_SHORT;
- }
- static void rthw_sdctrl_transfer_by_dma(ft_sdctrl_class_t *class_p, struct mmcsd_pkg *pkg)
- {
- struct rt_mmcsd_data *data;
- struct rt_mmcsd_cmd *cmd;
- u32 rasp;
- u32 *buff;
- FtsdCtrl_t *ft_sdctrl_p;
- if ((RT_NULL == class_p))
- {
- LOG_E("rthw_sdctrl_transfer_by_dma invalid class_p");
- return;
- }
- ft_sdctrl_p = &class_p->ft_sdctrl;
- if ((RT_NULL == pkg))
- {
- LOG_E("rthw_sdctrl_transfer_by_dma invalid args");
- return;
- }
- data = pkg->cmd->data;
- if (RT_NULL == data)
- {
- LOG_E("rthw_sdctrl_transfer_by_dma invalid args");
- return;
- }
- buff = pkg->buff;
- if (RT_NULL == buff)
- {
- LOG_E("rthw_sdctrl_transfer_by_dma invalid args");
- return;
- }
- cmd = pkg->cmd;
- rasp = resp_type(pkg->cmd);
- rasp = rthw_sdctrl_rasp2type(rasp);
- if (data->flags & DATA_DIR_WRITE)
- {
- #ifdef BSP_SDC_DEBUG_PRINT
- rt_kprintf("DATA_DIR_WRITE %x \r\n", cmd->arg);
- #endif
- FCache_cpuDcacheClean(buff, data->blks * data->blksize);
- /* data, card, blk: card : data + blk */
- FSdCtrl_WriteData(ft_sdctrl_p, (UINTPTR)buff, cmd->arg, data->blks);
- cmd->err = FSdCtrl_WaitCmdEnd(ft_sdctrl_p, (pFtsdCtrl_delayTimer_t)rthw_sdctrl_delay, rasp, cmd->resp);
- #ifdef BSP_SDC_DEBUG_PRINT
- for (int i = 0; i < 4; i++)
- {
- rt_kprintf("cmdRsp[%d] %x \r\n", i, cmd->resp[i]);
- }
- Ft_DumpHexWord(buff, 256);
- #endif
- FSdCtrl_WaitWriteDataEnd(ft_sdctrl_p, (pFtsdCtrl_delayTimer_t)rthw_sdctrl_delay, data->blks);
- FCache_cpuDcacheInvalidate(buff, data->blks * data->blksize);
- }
- else if (data->flags & DATA_DIR_READ)
- {
- #ifdef BSP_SDC_DEBUG_PRINT
- rt_kprintf("DATA_DIR_READ %x \r\n", cmd->arg);
- #endif
- if ((cmd->flags & CMD_ADTC) && (data->blksize < 512))
- {
- #ifdef BSP_SDC_DEBUG_PRINT
- LOG_E("CMD_ADTC \r\n");
- #endif
- FSdCtrl_DoACmd(ft_sdctrl_p, cmd->cmd_code, rasp, cmd->arg);
- rt_thread_mdelay(10);
- }
- FCache_cpuDcacheInvalidate(buff, data->blks * data->blksize);
- FSdCtrl_ReadData(ft_sdctrl_p, (UINTPTR)buff, cmd->arg, data->blks);
- cmd->err = FSdCtrl_WaitCmdEnd(ft_sdctrl_p, (pFtsdCtrl_delayTimer_t)rthw_sdctrl_delay, rasp, cmd->resp);
- #ifdef BSP_SDC_DEBUG_PRINT
- for (int i = 0; i < 4; i++)
- {
- rt_kprintf("cmdRsp[%d] %x \r\n", i, cmd->resp[i]);
- }
- #endif
- FSdCtrl_WaitReadDataEnd(ft_sdctrl_p, (pFtsdCtrl_delayTimer_t)rthw_sdctrl_delay, data->blks);
- FCache_cpuDcacheClean(buff, data->blks * data->blksize);
- #ifdef BSP_SDC_DEBUG_PRINT
- Ft_DumpHexWord(buff, data->blks * data->blksize);
- #endif
- }
- }
- static void rthw_sdctrl_docmd(ft_sdctrl_class_t *class_p, struct mmcsd_pkg *pkg)
- {
- struct rt_mmcsd_cmd *cmd;
- u32 rasp;
- FtsdCtrl_t *ft_sdctrl_p;
- if ((RT_NULL == class_p))
- {
- LOG_E("rthw_sdctrl_docmd invalid class_p");
- return;
- }
- ft_sdctrl_p = &class_p->ft_sdctrl;
- if ((RT_NULL == pkg))
- {
- LOG_E("rthw_sdctrl_docmd invalid args");
- return;
- }
- cmd = pkg->cmd;
- rasp = resp_type(pkg->cmd);
- rasp = rthw_sdctrl_rasp2type(rasp);
- FSdCtrl_DoCmd(ft_sdctrl_p, pkg->cmd->cmd_code, rasp, cmd->arg);
- cmd->err = FSdCtrl_WaitCmdEnd(ft_sdctrl_p, (pFtsdCtrl_delayTimer_t)rthw_sdctrl_delay, rasp, cmd->resp);
- #ifdef BSP_SDC_DEBUG_PRINT
- for (int i = 0; i < 4; i++)
- {
- rt_kprintf("cmdRsp[%d] %x \r\n", i, cmd->resp[i]);
- }
- #endif
- }
- static void rthw_sdctrl_send_command(ft_sdctrl_class_t *class_p, struct mmcsd_pkg *pkg)
- {
- struct rt_mmcsd_cmd *cmd = pkg->cmd;
- struct rt_mmcsd_data *data = cmd->data;
- /* save pkg */
- class_p->pkg = pkg;
- /* config data reg */
- if (data != RT_NULL && data->blks)
- {
- /* transfer config */
- rthw_sdctrl_transfer_by_dma(class_p, pkg);
- }
- else
- {
- rthw_sdctrl_docmd(class_p, pkg);
- }
- }
- /**
- * @brief This function send sdio request.
- * @param host rt_mmcsd_host
- * @param req request
- * @retval None
- */
- static void rthw_sdctrl_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
- {
- struct mmcsd_pkg pkg;
- ft_sdctrl_class_t *class_p = host->private_data;
- struct rt_mmcsd_data *data;
- RTHW_SDCTRL_LOCK(class_p);
- if (req->cmd != RT_NULL)
- {
- rt_memset(&pkg, 0, sizeof(pkg));
- data = req->cmd->data;
- pkg.cmd = req->cmd;
- if (pkg.cmd->cmd_code == 5 || pkg.cmd->cmd_code == 1)
- {
- rt_kprintf("cmd_code is not vaild %x \r\n", pkg.cmd->cmd_code);
- pkg.cmd->err = RT_EINVAL;
- goto _exit;
- }
- #ifdef BSP_SDC_DEBUG_PRINT
- struct rt_mmcsd_cmd *cmd;
- cmd = req->cmd;
- LOG_E("CMD:%d ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d",
- cmd->cmd_code,
- cmd->arg,
- resp_type(cmd) == RESP_NONE ? "NONE" : "",
- resp_type(cmd) == RESP_R1 ? "R1" : "",
- resp_type(cmd) == RESP_R1B ? "R1B" : "",
- resp_type(cmd) == RESP_R2 ? "R2" : "",
- resp_type(cmd) == RESP_R3 ? "R3" : "",
- resp_type(cmd) == RESP_R4 ? "R4" : "",
- resp_type(cmd) == RESP_R5 ? "R5" : "",
- resp_type(cmd) == RESP_R6 ? "R6" : "",
- resp_type(cmd) == RESP_R7 ? "R7" : "",
- data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
- data ? data->blks * data->blksize : 0,
- data ? data->blksize : 0);
- #endif
- if (data != RT_NULL)
- {
- rt_uint32_t size = data->blks * data->blksize;
- RT_ASSERT(size <= SDCTR_BUFF_SIZE);
- pkg.buff = data->buf;
- if ((rt_uint32_t)data->buf & (SDCTR_ALIGN_LEN - 1))
- {
- pkg.buff = cache_buf;
- if (data->flags & DATA_DIR_WRITE)
- {
- rt_memcpy(cache_buf, data->buf, size);
- }
- }
- }
- rthw_sdctrl_send_command(class_p, &pkg);
- if ((data != RT_NULL) && (data->flags & DATA_DIR_READ) && ((rt_uint32_t)data->buf & (SDCTR_ALIGN_LEN - 1)))
- {
- rt_memcpy(data->buf, cache_buf, data->blksize * data->blks);
- }
- }
- if (req->stop != RT_NULL)
- {
- rt_memset(&pkg, 0, sizeof(pkg));
- pkg.cmd = req->stop;
- rthw_sdctrl_send_command(class_p, &pkg);
- }
- _exit:
- RTHW_SDCTRL_UNLOCK(class_p);
- mmcsd_req_complete(class_p->host);
- }
- static void rthw_sdctrl_clk_divider(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
- {
- ft_sdctrl_class_t *class_p = host->private_data;
- FtsdCtrl_t *sd_ctrl = &(class_p->ft_sdctrl);
- /* bus mode is pull push */
- FSdCtrl_ClkFreqSetup(sd_ctrl, io_cfg->clock);
- return;
- }
- static void rthw_sdctrl_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
- {
- ft_sdctrl_class_t *class_p = host->private_data;
- RTHW_SDCTRL_LOCK(class_p);
- /* calculate and set clk divider */
- rthw_sdctrl_clk_divider(host, io_cfg);
- RTHW_SDCTRL_UNLOCK(class_p);
- }
- rt_int32_t rthw_sdctrl_detect(struct rt_mmcsd_host *host)
- {
- ft_sdctrl_class_t *class_p = host->private_data;
- return FSdCtrl_CardDetect(&class_p->ft_sdctrl);
- }
- static const struct rt_mmcsd_host_ops ops =
- {
- rthw_sdctrl_request,
- rthw_sdctrl_iocfg,
- rthw_sdctrl_detect,
- RT_NULL,
- };
- void rthw_sdctrl_nomarl_callback(void *args)
- {
- FtsdCtrl_t *pFtsdCtrl = (FtsdCtrl_t *)args;
- rt_uint32_t status;
- ft_sdctrl_class_t *class_p;
- if (RT_NULL == pFtsdCtrl)
- {
- return;
- }
- class_p = rt_container_of(pFtsdCtrl, ft_sdctrl_class_t, ft_sdctrl);
- status = FSdCtrl_GetNormalIrqStatus(pFtsdCtrl);
- if (status & NORMAL_INT_STATUS_CR)
- {
- rt_event_send(&class_p->event, SDCTR_CARD_REMOVE_FLG);
- }
- else if (status & NORMAL_INT_STATUS_CC)
- {
- rt_event_send(&class_p->event, SDCTR_CMD_IS_COMPLETE_FLG);
- }
- else if (status & NORMAL_INT_STATUS_EI)
- {
- rt_event_send(&class_p->event, SDCTR_CMD_IS_ERROR_FLG);
- }
- return;
- }
- void rthw_sdctrl_dma_callback(void *args)
- {
- FtsdCtrl_t *pFtsdCtrl = (FtsdCtrl_t *)args;
- rt_uint32_t status;
- ft_sdctrl_class_t *class_p;
- if (RT_NULL == pFtsdCtrl)
- {
- return;
- }
- class_p = rt_container_of(pFtsdCtrl, ft_sdctrl_class_t, ft_sdctrl);
- status = FSdCtrl_GetDataIrqStatus(pFtsdCtrl);
- if (status & BD_ISR_REG_TRS)
- {
- /* send write complete event */
- rt_event_send(&class_p->event, SDCTR_WRITE_IS_COMPLETE_FLG);
- }
- if (status & BD_ISR_REG_RESPE)
- {
- /* send read complete event */
- rt_event_send(&class_p->event, SDCTR_READ_IS_COMPLETE_FLG);
- }
- if (status & BD_ISR_REG_DAIS)
- {
- /* send dma errror event */
- rt_event_send(&class_p->event, SDCTR_DMA_IS_ERROR_FLG);
- }
- }
- void rthw_sdctrl_error_callback(void *args)
- {
- FtsdCtrl_t *pFtsdCtrl = (FtsdCtrl_t *)args;
- rt_uint32_t status;
- ft_sdctrl_class_t *class_p;
- if (RT_NULL == pFtsdCtrl)
- {
- return;
- }
- class_p = rt_container_of(pFtsdCtrl, ft_sdctrl_class_t, ft_sdctrl);
- status = FSdCtrl_GetErrorIrqStatus(pFtsdCtrl);
- if (status & SDCTR_CMD_TIMEOUT_FLG)
- {
- rt_event_send(&class_p->event, SDCTR_CMD_TIMEOUT_FLG);
- }
- if (status & ERROR_INT_EN_CNR)
- {
- rt_event_send(&class_p->event, SDCTR_CMD_RECEIVE_IS_ERROR_FLG);
- }
- if (status & ERROR_INT_EN_CCRCE)
- {
- rt_event_send(&class_p->event, SDCTR_CMD_CRC_IS_ERROR_FLG);
- }
- }
- void rthw_sdctrl_normal_irq(int vector, void *param)
- {
- FtsdCtrl_t *pFtsdCtrl = (FtsdCtrl_t *)param;
- FSdCtrl_NormalIrq(pFtsdCtrl);
- }
- void rthw_sdctrl_dma_irq(int vector, void *param)
- {
- FtsdCtrl_t *pFtsdCtrl = (FtsdCtrl_t *)param;
- FSdCtrl_DmaIrq(pFtsdCtrl);
- }
- void rthw_sdctrl_err_irq(int vector, void *param)
- {
- FtsdCtrl_t *pFtsdCtrl = (FtsdCtrl_t *)param;
- FSdCtrl_ErrIrq(pFtsdCtrl);
- }
- ft_error_t rthw_sdctrl_cmd_wait(FtsdCtrl_t *pFtsdCtrl)
- {
- rt_uint32_t status;
- ft_sdctrl_class_t *class_p;
- if (RT_NULL == pFtsdCtrl)
- {
- return FTSDC_INVALID_PARAM;
- }
- class_p = rt_container_of(pFtsdCtrl, ft_sdctrl_class_t, ft_sdctrl);
- if (rt_event_recv(&class_p->event, SDCTR_CMD_IS_COMPLETE_FLG | SDCTR_CMD_IS_ERROR_FLG | SDCTR_CMD_CRC_IS_ERROR_FLG, RT_EVENT_FLAG_CLEAR | RT_EVENT_FLAG_OR,
- rt_tick_from_millisecond(50000), &status) != RT_EOK)
- {
- /* wait cmd completed timeout */
- LOG_E("wait cmd completed timeout");
- return FTSDC_TIMEOUT;
- }
- if (SDCTR_CMD_IS_COMPLETE_FLG == (status & SDCTR_CMD_IS_COMPLETE_FLG))
- {
- return FTSDC_SUCCESS;
- }
- else
- {
- LOG_E("wait cmd is error %x ", status);
- return FTSDC_FAILURE;
- }
- }
- ft_error_t rthw_sdctrl_read_wait(FtsdCtrl_t *pFtsdCtrl)
- {
- rt_uint32_t status;
- ft_sdctrl_class_t *class_p;
- if (RT_NULL == pFtsdCtrl)
- {
- return FTSDC_INVALID_PARAM;
- }
- class_p = rt_container_of(pFtsdCtrl, ft_sdctrl_class_t, ft_sdctrl);
- if (rt_event_recv(&class_p->event, SDCTR_READ_IS_COMPLETE_FLG | SDCTR_CMD_RECEIVE_IS_ERROR_FLG,
- RT_EVENT_FLAG_CLEAR | RT_EVENT_FLAG_OR,
- rt_tick_from_millisecond(50000), &status) != RT_EOK)
- {
- /* wait read completed timeout */
- LOG_E("wait read completed timeout");
- return FTSDC_TIMEOUT;
- }
- if (SDCTR_READ_IS_COMPLETE_FLG == (status & SDCTR_READ_IS_COMPLETE_FLG))
- {
- return FTSDC_SUCCESS;
- }
- else
- {
- LOG_E("wait read is error %x ", status);
- return FTSDC_FAILURE;
- }
- }
- ft_error_t rthw_sdctrl_write_wait(FtsdCtrl_t *pFtsdCtrl)
- {
- rt_uint32_t status;
- ft_sdctrl_class_t *class_p;
- if (RT_NULL == pFtsdCtrl)
- {
- return FTSDC_INVALID_PARAM;
- }
- class_p = rt_container_of(pFtsdCtrl, ft_sdctrl_class_t, ft_sdctrl);
- if (rt_event_recv(&class_p->event, SDCTR_WRITE_IS_COMPLETE_FLG, RT_EVENT_FLAG_CLEAR | RT_EVENT_FLAG_OR,
- rt_tick_from_millisecond(50000), &status) != RT_EOK)
- {
- /* wait write completed timeout */
- LOG_E("wait write completed timeout");
- return FTSDC_TIMEOUT;
- }
- if (SDCTR_WRITE_IS_COMPLETE_FLG == (status & SDCTR_WRITE_IS_COMPLETE_FLG))
- {
- return FTSDC_SUCCESS;
- }
- else
- {
- LOG_E("wait write is error %x ", status);
- return FTSDC_FAILURE;
- }
- }
- static rt_err_t rthw_sdctrl_create(ft_sdctrl_class_t *class_p)
- {
- struct rt_mmcsd_host *host;
- host = mmcsd_alloc_host();
- if (host == RT_NULL)
- {
- LOG_E("L:%d F:%s mmcsd alloc host fail");
- return RT_ENOMEM;
- }
- class_p->ft_sdctrl.config = *(FSdCtrl_Config_t *)FSdCtrl_LookupConfig(0);
- rt_event_init(&class_p->event, "sdctrl", RT_IPC_FLAG_FIFO);
- rt_mutex_init(&class_p->mutex, "sdctrl", RT_IPC_FLAG_PRIO);
- class_p->host = host;
- host->ops = &ops;
- /* range of sd work speed */
- host->freq_min = 400 * 1000;
- host->freq_max = 48 * 1000000;
- host->valid_ocr = 0X00FFFF80; /* The voltage range supported is 1.65v-3.6v */
- host->flags = MMCSD_BUSWIDTH_4;
- host->private_data = class_p;
- /* ready to change */
- return RT_EOK;
- }
- int rthw_sdctrl_init(void)
- {
- FtsdCtrl_t *ft_sdctrl_p;
- #ifdef BSP_SDC_USE_IRQ
- FSdCtrl_Config_t *config_p;
- FSdCtrl_NormalIrqSelect_t normalIrqFlgs = 0;
- #endif
- rt_kprintf("rthw_sdctrl_init \r\n");
- RT_ASSERT(rthw_sdctrl_create(&sdctrl_class) == RT_EOK);
- ft_sdctrl_p = &sdctrl_class.ft_sdctrl;
- FSdCtrl_Reset(ft_sdctrl_p, (pFtsdCtrl_delayTimer_t)rthw_sdctrl_delay);
- FsdCtrl_Init(ft_sdctrl_p);
- #ifdef BSP_SDC_USE_IRQ
- config_p = &ft_sdctrl_p->config;
- #ifdef BSP_SDC_IRQ_CARD_REMOVE
- normalIrqFlgs |= NORMAL_IRQ_CR;
- #endif
- normalIrqFlgs |= NORMAL_IRQ_CC;
- /* register handler、irq enable bit and wait callback */
- FSdCtrl_SetHandler(ft_sdctrl_p, FTSDCTRL_CMDIRQID, rthw_sdctrl_nomarl_callback, ft_sdctrl_p);
- FSdCtrl_NormalIrqSet(ft_sdctrl_p, normalIrqFlgs);
- FSdCtrl_CmdWaitRegister(ft_sdctrl_p, rthw_sdctrl_cmd_wait);
- FSdCtrl_SetHandler(ft_sdctrl_p, FTSDCTRL_DMADATAIRQID, rthw_sdctrl_dma_callback, ft_sdctrl_p);
- FSdCtrl_BdIrqSet(ft_sdctrl_p, BD_IRQ_TRS | BD_IRQ_RESPE);
- FSdCtrl_WriteWaitRegister(ft_sdctrl_p, rthw_sdctrl_write_wait);
- FSdCtrl_ReadWaitRegister(ft_sdctrl_p, rthw_sdctrl_read_wait);
- config_p->workMode = FTSDCTRL_CMD_IRQ_MASK | FTSDCTRL_DATA_WRITE_IRQ_MASK | FTSDCTRL_DATA_READ_IRQ_MASK;
- #else
- #endif
- /* install normal irq */
- rt_hw_interrupt_install(ft_sdctrl_p->config.normalIrqNum, rthw_sdctrl_normal_irq,
- &sdctrl_class.ft_sdctrl, "normalIrq");
- rt_hw_interrupt_umask(ft_sdctrl_p->config.normalIrqNum);
- rt_hw_interrupt_install(ft_sdctrl_p->config.dmaIrqNum, rthw_sdctrl_dma_irq,
- &sdctrl_class.ft_sdctrl, "dmaIrq");
- rt_hw_interrupt_umask(ft_sdctrl_p->config.dmaIrqNum);
- return 0;
- }
- INIT_DEVICE_EXPORT(rthw_sdctrl_init);
- void ft2004_mmcsd_change(void)
- {
- mmcsd_change(sdctrl_class.host);
- }
- rt_bool_t ft2004_card_status(void)
- {
- return FSdCtrl_CardDetect(&sdctrl_class.ft_sdctrl);
- }
- rt_err_t ft2004_card_remove_check(rt_int32_t timeout, rt_uint32_t *status)
- {
- return rt_event_recv(&sdctrl_class.event, SDCTR_CARD_REMOVE_FLG, RT_EVENT_FLAG_CLEAR | RT_EVENT_FLAG_OR,
- timeout, status);
- }
- void ft2004_sdctrl_reset(void)
- {
- FSdCtrl_Reset(&sdctrl_class.ft_sdctrl, (pFtsdCtrl_delayTimer_t)rthw_sdctrl_delay);
- FsdCtrl_Init(&sdctrl_class.ft_sdctrl);
- #ifdef BSP_SDC_USE_IRQ
- FSdCtrl_NormalIrqSet(&sdctrl_class.ft_sdctrl, NORMAL_IRQ_CC | NORMAL_IRQ_CR | NORMAL_IRQ_EI);
- FSdCtrl_BdIrqSet(&sdctrl_class.ft_sdctrl, BD_IRQ_TRS | BD_IRQ_RESPE);
- #endif
- }
- #endif
|