芯片CSI驱动开发

概述

CSI驱动有规范的实现流程,以UART为例进行说明,驱动包含以下几个部分: 1、初始化/去初始化 2、配置 3、同步输入输出 4、异步输入输出

统一的设备和中断管理

如下图,描述设备初始化和中断处理流程。

UART驱动编写

初始化

获取基地址和中断号

通过target_get接口获取设备基地址和中断号,保存到csi_uart_t控制块中。

target_get接口的获取方式详见“芯片设备信息描述”章节

csi_error_t csi_uart_init(csi_uart_t *uart, uint32_t idx)
{
    //...
    ret = target_get(DEV_DW_UART_TAG, idx, &uart->dev);
    //...
}

初始化设备硬件

初始化UART FIFO等。

csi_error_t csi_uart_init(csi_uart_t *uart, uint32_t idx)
{
    //...
    dw_uart_fifo_init(uart_base);
    //...
}

配置

UART 需要实现配置 baudrate、format、flowctrl。

csi_error_t csi_uart_baud(csi_uart_t *uart, uint32_t baud);

csi_error_t csi_uart_format(csi_uart_t *uart,  csi_uart_data_bits_t data_bits,
                            csi_uart_parity_t parity, csi_uart_stop_bits_t stop_bits);

csi_error_t csi_uart_flowctrl(csi_uart_t *uart,  csi_uart_flowctrl_t flowctrl);

同步输入输出

同步输入输出通过轮询的方式实现,实现send/receive接口。

uint32_t csi_uart_send(csi_uart_t *uart, const void *data, uint32_t size, uint32_t timeout);

uint32_t csi_uart_receive(csi_uart_t *uart, void *data, uint32_t size, uint32_t timeout);

异步输出输出

异步接口包含中断方式和DMA方式,send/receive接口统一。

默认状态下csi_uart_send_async是通过中断方式,用户调用了LINK DMA接口则变成DMA方式 实现send_async/receive_async接口。

csi_error_t csi_uart_send_async(csi_uart_t *uart, const void *data, uint32_t size);

csi_error_t csi_uart_receive_async(csi_uart_t *uart, void *data, uint32_t size);

注册回调函数

CSI 接口的使用者不需要实现中断处理函数,只需要通过回调函数来接收中断事件。 驱动需要实现csi_uart_attach_callback接口供用户注册。

csi_error_t csi_uart_attach_callback(csi_uart_t *uart, void *callback, void *arg);

void        csi_uart_detach_callback(csi_uart_t *uart);

中断

中断处理函数

UART中断处理函数,把数据接收到csi_uart_t rx_data中;把csi_uart_t tx_data的数据发送出去。

中断处理函数通过csi_irq_attach注册到g_irq_table中。g_irq_table中通过中断号存放csi_dev_t结构体变量。

void dw_uart_irq_handler(void *arg);

DMA

默认的,csi_uart_send_async使用中断方式发送;只有调用了csi_uart_link_dma后,才会启用DMA方式发送。

csi_error_t csi_uart_link_dma(csi_uart_t *uart, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma);

芯片设备信息描述

设备信息统一描述在devices.c文件中。设备初始化接口csi_xxx_init会通过target_get接口获取设备的基地址,中断号和设备号信息。示例如下,也可参考dummy芯片中的devices.c

const csi_perip_info_t g_soc_info[] = {
    {DW_UART0_BASE,            DW_UART0_IRQn,            0,    DEV_DW_UART_TAG},
    {DW_UART1_BASE,            DW_UART1_IRQn,            1,    DEV_DW_UART_TAG},
    {DW_TIMER0_BASE,           DW_TIMER0_IRQn,           0,    DEV_DW_TIMER_TAG},
    {DW_TIMER1_BASE,           DW_TIMER1_IRQn,           1,    DEV_DW_TIMER_TAG},
    {DW_TIMER2_BASE,           DW_TIMER2_IRQn,           2,    DEV_DW_TIMER_TAG},
    {DW_TIMER3_BASE,           DW_TIMER3_IRQn,           3,    DEV_DW_TIMER_TAG},
    {0, 0, 0, 0}
};
typedef struct {
    unsigned long    reg_base;        //设备基地址
    uint8_t          irq_num;         //中断号
    uint8_t          idx;             //设备号,若UART0,则idx=0
    uint16_t         dev_tag;         //设备TAG,该设备类型的唯一标志符,如DEV_DW_UART_TAG
} csi_perip_info_t;

results matching ""

    No results matching ""