rt-thread/bsp/phytium/libraries/standalone/drivers/mmc/fsdio/fsdio.h

241 lines
9.9 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright : (C) 2022 Phytium Information Technology, Inc.
* All Rights Reserved.
*
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
* either version 1.0 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Phytium Public License for more details.
*
*
* FilePath: fsdio.h
* Date: 2022-05-26 16:20:52
* LastEditTime: 2022-05-26 16:20:53
* Description:  This file is for sdio user interface definition
*
* Modify History:
* Ver   Who        Date         Changes
* ----- ------     --------    --------------------------------------
* 1.0 zhugengyu 2021/12/2 init
* 1.1 zhugengyu 2022/6/6 modify according to tech manual.
* 1.2 zhugengyu 2022/7/15 adopt to e2000
* 1.3 zhugengyu 2022/11/23 fix multi-block rw issues
*/
#ifndef FSDIO_H
#define FSDIO_H
/***************************** Include Files *********************************/
#include "ftypes.h"
#include "ferror_code.h"
#include "fkernel.h"
#ifdef __cplusplus
extern "C"
{
#endif
/************************** Constant Definitions *****************************/
/* SDIO driver error code */
#define FSDIO_SUCCESS FT_SUCCESS
#define FSDIO_ERR_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 1)
#define FSDIO_ERR_NOT_INIT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 2)
#define FSDIO_ERR_SHORT_BUF FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 3)
#define FSDIO_ERR_NOT_SUPPORT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 4)
#define FSDIO_ERR_INVALID_STATE FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 5)
#define FSDIO_ERR_TRANS_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 6)
#define FSDIO_ERR_CMD_TIMEOUT FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 7)
#define FSDIO_ERR_NO_CARD FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 8)
#define FSDIO_ERR_BUSY FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 9)
#define FSDIO_ERR_DMA_BUF_UNALIGN FT_MAKE_ERRCODE(ErrModBsp, ErrBspMmc, 10)
typedef enum
{
FSDIO_IDMA_TRANS_MODE, /* DMA trans mode */
FSDIO_PIO_TRANS_MODE, /* NO-DMA trans by read/write Fifo */
} FSdioTransMode; /* SDIO trans mode */
typedef enum
{
FSDIO_GENERAL_INTR, /* interrupt status belongs to controller */
FSDIO_IDMA_INTR, /* interrupt status belongs to DMA */
} FSdioIntrType; /* SDIO interrupt status type */
typedef enum
{
FSDIO_SD_3_3V_VOLTAGE = 0, /* 3.3v */
FSDIO_SD_1_8V_VOLTAGE /* 1.8v */
} FSdioVoltageType; /* SDIO card voltage type */
typedef enum
{
FSDIO_EVT_CARD_DETECTED = 0, /* card detected event */
FSDIO_EVT_CMD_DONE, /* cmd transfer finish event */
FSDIO_EVT_DATA_DONE, /* cmd with data transfer finish event */
FSDIO_EVT_ERR_OCCURE, /* error occurred in transfer */
FSDIO_NUM_OF_EVT
} FSdioEvtType; /* SDIO event type */
#define FSDIO_SD_400KHZ 400000U
#define FSDIO_SD_25_MHZ 25000000U
#define FSDIO_SD_50_MHZ 50000000U
/**************************** Type Definitions *******************************/
typedef struct _FSdio FSdio;
typedef void (*FSdioRelaxHandler)(void);
typedef void (*FSdioEvtHandler)(FSdio *const instance_p, void *args, u32 status, u32 dmac_status);
typedef struct
{
u32 attribute; /* ds0 */
#define FSDIO_IDMAC_DES0_DIC BIT(1)/* 内部描述表不触发TI/RI中断 */
#define FSDIO_IDMAC_DES0_LD BIT(2)/* 数据的最后一个描述符 */
#define FSDIO_IDMAC_DES0_FD BIT(3)/* 数据的第一个描述符 */
#define FSDIO_IDMAC_DES0_CH BIT(4)/* 链接下一个描述符地址 */
#define FSDIO_IDMAC_DES0_ER BIT(5)/* 链表已经到达最后一个链表 */
#define FSDIO_IDMAC_DES0_CES BIT(30)/* RINTSTS寄存器错误汇总 */
#define FSDIO_IDMAC_DES0_OWN BIT(31)/* 描述符关联DMA完成传输后该位置置0 */
u32 non1; /* ds1 --> unused */
u32 len; /* ds2 bit[25:13] buffer2 sizebit[12:0] buffer1 size*/
#define FSDIO_IDMAC_DES2_BUF1_MASK GENMASK(12, 0)
#define FSDIO_IDMAC_DES2_BUF1_SIZE(x) (FSDIO_IDMAC_DES2_BUF1_MASK & (x))
#define FSDIO_IDMAC_DES2_BUF2_MASK GENMASK(25, 13)
#define FSDIO_IDMAC_DES2_BUF2_SIZE(x) (FSDIO_IDMAC_DES2_BUF2_MASK & (x << 13))
u32 non2; /* ds3 --> unused */
u32 addr_lo; /* ds4 Lower 32-bits of Buffer Address Pointer 1 --> buffer 1 */
u32 addr_hi; /* ds5 Upper 32-bits of Buffer Address Pointer 1 */
u32 desc_lo; /* ds6 Lower 32-bits of Next Descriptor Address --> buffer 2 */
u32 desc_hi; /* ds7 Upper 32-bits of Next Descriptor Address */
} __attribute__((packed)) __attribute((aligned(4))) FSdioIDmaDesc; /* SDIO DMA descriptr */
typedef struct
{
volatile FSdioIDmaDesc *first_desc; /* first descriptor in the list */
volatile uintptr first_desc_p;
u32 desc_num; /* num of descriptors in the list */
} FSdioIDmaDescList; /* SDIO DMA descriptors list */
typedef struct
{
u8 *buf; /* trans buffer */
uintptr buf_p;
u32 blksz; /* card block size */
u32 blkcnt; /* num of block in trans */
u32 datalen; /* bytes in trans */
} FSdioData; /* SDIO trans data */
typedef struct
{
u32 cmdidx; /* command index */
u32 cmdarg; /* command argument */
u32 response[4]; /* command response buffer */
u32 flag; /* command flags */
#define FSDIO_CMD_FLAG_NEED_INIT BIT(1) /* need initialization */
#define FSDIO_CMD_FLAG_EXP_RESP BIT(2) /* need reply */
#define FSDIO_CMD_FLAG_EXP_LONG_RESP BIT(3) /* need 136 bits long reply */
#define FSDIO_CMD_FLAG_NEED_RESP_CRC BIT(4) /* need CRC */
#define FSDIO_CMD_FLAG_EXP_DATA BIT(5) /* need trans data */
#define FSDIO_CMD_FLAG_WRITE_DATA BIT(6) /* need trans data to write card */
#define FSDIO_CMD_FLAG_READ_DATA BIT(7) /* need trans data to read card */
#define FSDIO_CMD_FLAG_NEED_AUTO_STOP BIT(8) /* need auto stop after command */
#define FSDIO_CMD_FLAG_ADTC BIT(9) /* need ADTC */
#define FSDIO_CMD_FLAG_SWITCH_VOLTAGE BIT(10) /* need switch voltage */
FSdioData *data_p; /* SDIO trans data */
volatile boolean success; /* TRUE: comand and data transfer success */
} FSdioCmdData; /* SDIO trans command and data */
typedef struct
{
u32 instance_id; /* Device instance id */
uintptr base_addr; /* Device base address */
u32 irq_num; /* Interrupt num */
FSdioTransMode trans_mode; /* Trans mode, PIO/DMA */
FSdioVoltageType voltage; /* Card voltage type */
boolean non_removable; /* No removeable media, e.g eMMC */
boolean filp_resp_byte_order; /* Some SD protocol implmentation may not do byte-order filp */
} FSdioConfig; /* SDIO intance configuration */
typedef struct _FSdio
{
FSdioConfig config; /* Current active configs */
u32 is_ready; /* Device is initialized and ready */
FSdioIDmaDescList desc_list; /* DMA descriptor list, valid in DMA trans mode */
FSdioEvtHandler evt_handlers[FSDIO_NUM_OF_EVT]; /* call-backs for interrupt event */
void *evt_args[FSDIO_NUM_OF_EVT]; /* arguments for event call-backs */
FSdioRelaxHandler relax_handler;
u32 prev_cmd; /* record previous command code */
} FSdio; /* SDIO intance */
/************************** Variable Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/* Get the device instance default configure */
const FSdioConfig *FSdioLookupConfig(u32 instance_id);
/* initialization SDIO controller instance */
FError FSdioCfgInitialize(FSdio *const instance_p, const FSdioConfig *cofig_p);
/* deinitialization SDIO controller instance */
void FSdioDeInitialize(FSdio *const instance_p);
/* Setup DMA descriptor for SDIO controller instance */
FError FSdioSetIDMAList(FSdio *const instance_p, volatile FSdioIDmaDesc *desc, u32 desc_num);
/* Set the Card clock freqency */
FError FSdioSetClkFreq(FSdio *const instance_p, u32 input_clk_hz);
/* Get the real Card clock freqency */
u32 FSdioGetClkFreq(FSdio *const instance_p);
/* Start command and data transfer in DMA mode */
FError FSdioDMATransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p);
/* Wait DMA transfer finished by poll */
FError FSdioPollWaitDMAEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p);
/* Start command and data transfer in PIO mode */
FError FSdioPIOTransfer(FSdio *const instance_p, FSdioCmdData *const cmd_data_p);
/* Wait PIO transfer finished by poll */
FError FSdioPollWaitPIOEnd(FSdio *const instance_p, FSdioCmdData *const cmd_data_p);
/* Get cmd response and received data after wait poll status or interrupt signal */
FError FSdioGetCmdResponse(FSdio *const instance_p, FSdioCmdData *const cmd_data_p);
/* Get SDIO controller interrupt mask */
u32 FSdioGetInterruptMask(FSdio *const instance_p, FSdioIntrType intr_type);
/* Enable/Disable SDIO controller interrupt */
void FSdioSetInterruptMask(FSdio *const instance_p, FSdioIntrType type, u32 set_mask, boolean enable);
/* Interrupt handler for SDIO instance */
void FSdioInterruptHandler(s32 vector, void *param);
/* Reset controller from error state */
FError FSdioRestart(FSdio *const instance_p);
/* Register event call-back function as handler for interrupt events */
void FSdioRegisterEvtHandler(FSdio *const instance_p, FSdioEvtType evt, FSdioEvtHandler handler, void *handler_arg);
/* Register sleep call-back function */
void FSdioRegisterRelaxHandler(FSdio *const instance_p, FSdioRelaxHandler relax_handler);
/* Dump all register value of SDIO instance */
void FSdioDumpRegister(uintptr base_addr);
/* Dump command and data info */
void FSdioDumpCmdInfo(FSdioCmdData *const cmd_data);
#ifdef __cplusplus
}
#endif
#endif