/** * @file wk2114.c * @author Chen Jihang (embedded@eseaoptics.com) * @brief WK2114串口拓展驱动 * @version 1.0 * @date 2023-01-04 * * @copyright ESEA (c) 2020 * */ #include #include "wk2114.h" // #include "critical_section.h" #include "usart.h" #include "elog.h" static uint8_t init_buf=0x55; UART_HandleTypeDef *pWK2114Uart = &huart2; #define WK2114_Uart_IRQHandler USART2_IRQHandler WK2114_TypeDef *wk2114; osMessageQueueId_t wk2114CmdQueueHandle; osMessageQueueId_t wk2114SndQueueHandle; // osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); // osMessageQueueGet(TestQueueHandle,osWaitForever); // osStatus_t osMessageQueueGet ( osMessageQueueId_t mq_id, void WK2114_Uart_IRQHandler(void) { uint16_t count = 0; uint16_t data_length = 0; if (__HAL_UART_GET_FLAG(pWK2114Uart, UART_FLAG_TC) != RESET) { log_i("WK2114 ..huart TC callback ..."); wk2114->flag&=~WK2114_G_FLAG_MASK_SENDING; pWK2114Uart->gState = HAL_UART_STATE_READY; __HAL_UART_CLEAR_FLAG(pWK2114Uart, UART_FLAG_TC); } if (__HAL_UART_GET_FLAG(pWK2114Uart, UART_FLAG_IDLE) != RESET) { log_i("WK2114 ..huart IDLE ..."); // count = __HAL_DMA_GET_COUNTER( pWK2114Uart->hdmarx ); // data_length = Ramses_Rcv_Buf_Size - count; // if ( data_length > 0 ) // { // // log_i("Ramses_ IDLE.. data_length %d", data_length); // // Ramses_copy( wk2114, data_length ); // // log_i("Oscar_. IDLE..res %02X %d %02X", oscar->uarthelper ->receive_buf[0], oscar->uarthelper ->receive_buf[2], oscar->uarthelper ->receive_buf[data_length-1]); // } __HAL_UART_CLEAR_IDLEFLAG( pWK2114Uart ); } } int WK2114_Init( ) { log_i( "..... init......... %d " , wk2114->flag); wk2114 = (WK2114_TypeDef *)malloc(sizeof(WK2114_TypeDef)); wk2114->send_class = pWK2114Uart; wk2114->send_fun = HAL_UART_Transmit_DMA; // 命令队列 uint8_t cmd_buf[64][2] , 消息类型 2个uint8_t wk2114->cmd_queue = osMessageQueueNew( 8, sizeof(wk2114->cmd_queue_msg), NULL); if (wk2114->cmd_queue ==NULL) return -1; wk2114->flag = 0; wk2114->dev_clock_hz = WK2114_CLOCK_HZ; for(size_t i=0;i<4;i++){ wk2114->sub_uart[0]=NULL; } if( wk2114_set_baud(wk2114)<0) { return NULL; } log_i( "..... init.. 2....... %d " , wk2114->flag); return 0; } /** * @brief 内部函数 检查发送队列中的指令并发送到串口 * @note 请确保调用时上次发送的数据已经发送完毕 * @param wk2114 struct wk2114结构指针 * @return int >=0:成功 <0:失败 */ int wk2114_send(WK2114_TypeDef *wk2114) { log_i( "..... send.......... %d " , wk2114->flag); int p_de; uint8_t cmd; volatile uint8_t size; WK2114_Sub_Uart_TypeDef *p_sub_uart; if((wk2114->flag&WK2114_G_FLAG_MASK_BUSY)!=0){ // busy,exit return 0; } log_i( "..... send 22 ..... " ); if((wk2114->flag&WK2114_G_FLAG_MASK_SENDING)!=0){ // sending ,exit return 0; } // p_de=queue_get_de_index(&wk2114->cmd_queue); // 取队列消息,即cmd_buf数组索引 log_i( ".....get wk2114->cmd_queue_msg....111...... " ); osMessageQueueGet( wk2114->cmd_queue ,wk2114->cmd_queue_msg, sizeof(wk2114->cmd_queue_msg) ,osWaitForever); log_i( ".....get wk2114->cmd_queue_msg.......... " ); // if(p_de<0){ // wk2114->flag&=~WK2114_G_FLAG_MASK_INTER; // return 0; // } wk2114->flag|=WK2114_G_FLAG_MASK_SENDING; cmd=wk2114->cmd_queue_msg[0]; // first byte if( WK2114_CMD_IS_REG(cmd) ){ // 若为命令 if(WK2114_CMD_IS_READ(cmd)){ // 读命令 1byte 0+1 size=0; wk2114->flag|=WK2114_G_FLAG_MASK_BUSY; wk2114->send_buf[0]=cmd; } else{ // 写命令 2byte 1+1 size=1; wk2114->send_buf[0]=cmd; wk2114->send_buf[1]=wk2114->cmd_queue_msg[1]; if( WK2114_CMD_GET_ADDR(cmd)==WK2114_S_REG_SPAGE ){ if(wk2114->cmd_queue_msg[1]==0){ wk2114->sub_uart[WK2114_CMD_GET_SUB_UART(cmd)]->flag&=~WK2114_S_UART_FLAG_MASK_PAGE_D; } else{ wk2114->sub_uart[WK2114_CMD_GET_SUB_UART(cmd)]->flag|=WK2114_S_UART_FLAG_MASK_PAGE_D; } } } // queue_dequeue(&wk2114->cmd_queue,NULL); // 出队 // osMessageQueueGet(wk2114->cmd_queue ); } else{ // 若为数据,子串口发送 p_sub_uart=wk2114->sub_uart[WK2114_CMD_GET_SUB_UART(cmd)]; if(p_sub_uart==NULL){ return -3; } if(WK2114_CMD_IS_READ(cmd)){ // read 1byte 0+1 wk2114->flag|=WK2114_G_FLAG_MASK_BUSY; size=0; if(wk2114->cmd_queue_msg[1] < 16){ // 判断数据量 wk2114->send_buf[0]=(cmd&0xf0)+wk2114->cmd_queue_msg[1]; // queue_dequeue(&wk2114->cmd_queue,NULL); } else{ wk2114->send_buf[0]=cmd|0x0f; wk2114->cmd_queue_msg[1]-=16; } } else{ // write if(wk2114->cmd_queue_msg[1] < 16){ // 判断数据量 size=wk2114->cmd_queue_msg[1]+1; wk2114->send_buf[0]=(cmd&0xf0)+size-1; memcpy(&wk2114->send_buf[1],p_sub_uart->send_buf,size-1); // 发送子串口的send_buf ?? size size-1 // queue_dequeue(&wk2114->cmd_queue,NULL); p_sub_uart->send_buf=NULL; } else{ size=16; wk2114->send_buf[0]=cmd|0x0f; memcpy(&wk2114->send_buf[1],p_sub_uart->send_buf,size); p_sub_uart->send_buf+=16; wk2114->cmd_queue_msg[1]-=16; } } } return wk2114->send_fun(wk2114->send_class,wk2114->send_buf,size+1); } /** * @brief 内部函数 发送读寄存器指令 * * @param wk2114 struct wk2114结构指针 * @param reg_addr 寄存器地址 * @return int 0:成功 负数:失败 */ int wk2114_read_reg(WK2114_TypeDef *wk2114,uint8_t reg_addr) { int p_en; int count; int descriptor; uint8_t sub_uart; if( WK2114_REG_IS_GLOBAL(reg_addr) ){ if(wk2114->cmd!=0){ return -3; } wk2114->cmd = 0xff; } else{ sub_uart=WK2114_CMD_GET_SUB_UART(reg_addr); if(wk2114->sub_uart[sub_uart]->cmd!=0){ return -3; } wk2114->sub_uart[sub_uart]->cmd=0xff; } // descriptor=critical_section_enter(); // if(descriptor<0){ // return -2; // } __disable_irq(); count=queue_isempty(&wk2114->cmd_queue); // p_en=queue_get_en_index(&wk2114->cmd_queue); // if(p_en<0){ // // critical_section_exit(descriptor); // return -2; // } wk2114->cmd_queue_msg[0]=((WK2114_CMD_READ_REG<<6)+reg_addr); wk2114->cmd_queue_msg[1]=0x00; // queue_enqueue(&wk2114->cmd_queue,0); osMessageQueuePut( wk2114->cmd_queue, (void *) wk2114->cmd_queue_msg, 0, osWaitForever ); // critical_section_exit(descriptor); __enable_irq(); if(count){ wk2114_send(wk2114); } return 0; } /** * @brief 内部函数 发送写寄存器指令 * * @param wk2114 struct wk2114结构指针 * @param reg_addr 寄存器地址 * @param reg 要写入的值 * @return int 0:成功 负数:失败 */ int wk2114_write_reg(WK2114_TypeDef *wk2114,uint8_t reg_addr,uint8_t reg) { log_i( "..... wk2114_write_reg .. reg_addr %d reg %d ", reg_addr, reg); int p_en; int count; // int descriptor; // descriptor=critical_section_enter(); // if(descriptor<0){ // return -2; // } __disable_irq(); // isempty=queue_isempty(&wk2114->cmd_queue); count = osMessageQueueGetCount(wk2114->cmd_queue); log_i( "..... wk2114_write_reg .. count %d wk2114->flag %d ", count, wk2114->flag); // p_en = queue_get_en_index(&wk2114->cmd_queue); // p_en = count; // if(p_en<0){ // critical_section_exit(descriptor); // __enable_irq(); // return -2; // } wk2114->cmd_queue_msg[0] = ( (WK2114_CMD_WRITE_REG<<6)+reg_addr); wk2114->cmd_queue_msg[1] = reg; // queue_enqueue(&wk2114->cmd_queue,0); // queue_enqueue 入队 osMessageQueuePut( wk2114->cmd_queue, (void *) wk2114->cmd_queue_msg, 0, osWaitForever ); // critical_section_exit(descriptor); __enable_irq(); // if(count){ // log_i( "..... wk2114 send begin .. " ); // wk2114_send(wk2114); // } wk2114_send(wk2114); return 0; } /** * @brief 内部函数 发送读取FIFO的命令 * * @param wk2114 struct wk2114结构指针 * @param sub_uart 要读取FIFO的子串口地址 * @param size 要读取的长度-1 * @return int 0:成功 负数:失败 */ int wk2114_read_fifo(WK2114_TypeDef *wk2114,enum wk2114_s_uart sub_uart,uint8_t size) { int p_en; int isempty; int descriptor; if(wk2114->sub_uart[sub_uart]==NULL){ return -1; } descriptor=critical_section_enter(); if(descriptor<0){ return -2; } isempty=queue_isempty(&wk2114->cmd_queue); p_en=queue_get_en_index(&wk2114->cmd_queue); if(p_en<0){ critical_section_exit(descriptor); return -2; } wk2114->cmd_buf[p_en][0]=((WK2114_CMD_READ_FIFO<<6)+(sub_uart<<4)); wk2114->cmd_buf[p_en][1]=size; queue_enqueue(&wk2114->cmd_queue,0); critical_section_exit(descriptor); if(isempty){ wk2114_send(wk2114); } return 0; } /** * @brief 内部函数 发送写入FIFO的命令 * * @param wk2114 struct wk2114结构指针 * @param sub_uart 子串口地址 * @param buf 要发送的数据缓冲区 * @param size 要发送的长度-1 * @return int 0:成功 负数:失败 */ int wk2114_write_fifo(WK2114_TypeDef *wk2114,enum wk2114_s_uart sub_uart,uint8_t *buf,uint8_t size) { int p_en; int isempty; int descriptor; if(wk2114->sub_uart[sub_uart]==NULL){ return -1; } if(wk2114->sub_uart[sub_uart]->send_buf!=NULL){ return -2; } descriptor=critical_section_enter(); if(descriptor<0){ return -2; } isempty=queue_isempty(&wk2114->cmd_queue); p_en=queue_get_en_index(&wk2114->cmd_queue); if(p_en<0){ return -2; } wk2114->cmd_buf[p_en][0]=((WK2114_CMD_WRITE_FIFO<<6)+(sub_uart<<4)); wk2114->cmd_buf[p_en][1]=size; wk2114->sub_uart[sub_uart]->send_buf=buf; queue_enqueue(&wk2114->cmd_queue,0); critical_section_exit(descriptor); if(isempty){ wk2114_send(wk2114); } return 0; } /** * @brief 设置主串口波特率 * @note 此函数会被 \ref wk2114_init() 函数间接调用,一般不需要手动调用 * @note 调用此函数前请对wk2114执行硬件复位 * @param wk2114 struct wk2114结构指针 * @return int >=0:成功 <0:失败 */ int wk2114_set_baud(WK2114_TypeDef *wk2114) { wk2114->flag|=WK2114_G_FLAG_MASK_SENDING; return wk2114->send_fun(wk2114->send_class,&init_buf,1); } /** * @brief 内部函数 设置子串口寄存器页 * * @param sub_uart 子串口结构 * @param page 页 0/1 * @return int 0:成功 负数:失败 */ int wk2114_sub_uart_set_page(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t page) { int ret; if(page>1){ return -1; } if(((sub_uart->flag&WK2114_S_UART_FLAG_MASK_PAGE)!=0)==page){ return 0; } ret=wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_SPAGE),page); if(ret<0){ return ret; } if(page==1){ sub_uart->flag|=WK2114_S_UART_FLAG_MASK_PAGE; } else{ sub_uart->flag&=~WK2114_S_UART_FLAG_MASK_PAGE; } return 0; } /** * @brief 内部函数 根据已经注册的子串口刷新子串口时钟使能 * * @param wk2114 struct wk2114结构指针 * @return int 成功:0 失败:负值 */ int wk2114_flush_gena(WK2114_TypeDef *wk2114) { log_i( "..... wk2114_flush_gena .. "); uint8_t reg; int i; reg=0; for(i=0;i<4;i++){ if(wk2114->sub_uart[i]!=NULL && (wk2114->sub_uart[i]->flag&WK2114_S_UART_FLAG_MASK_ENABLE)!=0){ reg|=(1<sub_uart[i]!=NULL){ reg|=(1<wk2114->dev_clock_hz*100/16/buad; if(tmp<10){ return -1; } buad_div=tmp/100-1; if(wk2114_sub_uart_set_page(sub_uart,1)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_BUAD1),buad_div>>8)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_BUAD0),buad_div&0xff)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_PRES),(tmp/10)%10)<0){ return -2; } if(wk2114_sub_uart_set_page(sub_uart,0)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_LCR),party|stop_bits)<0){ return -2; } return 0; } /** * @brief 内部函数 设置子串口中断使能 * * @param sub_uart 子串口结构 * @param inter_flag 宏定义 WK2114_S_REG_SIFR_MASK_XXX 的任意结合 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_set_inter(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t inter_flag) { if(wk2114_sub_uart_set_page(sub_uart,0)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_SIER),inter_flag)<0){ return -2; } return 0; } /** * @brief 设置子串口的模式 * @note 此函数会被 \ref wk2114_sub_uart_init() 间接调用 一般不需要手动调用 * @param sub_uart 子串口结构 * @param mode 模式 WK2114_SUB_UART_MODE_MASK_XXX 的任意结合 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_set_mode(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t mode) { if(wk2114_sub_uart_set_page(sub_uart,0)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_SCR),mode)<0){ return -2; } return 0; } /** * @brief 内部函数 设置子串口FIFO触点 * * @param sub_uart 子串口结构 * @param tx_trigger 发送FIFO触点 * @param rx_trigger 接收FIFO触点 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_set_fifo_trigger(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t tx_trigger,uint8_t rx_trigger) { if(wk2114_sub_uart_set_page(sub_uart,1)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_TFTL),tx_trigger)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_RFTL),rx_trigger)<0){ return -2; } return 0; } /** * @brief 设置子串口FIFO模式 * @note 此函数被 \ref wk2114_sub_uart_init() 间接调用 一般不需要手动调用 * @param sub_uart 子串口结构 * @param mode 模式 WK2114_SUB_UART_FIFO_MODE_MASK_XXX 的任意结合 * @return int */ int wk2114_sub_uart_set_fifo_mode(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t mode) { if(wk2114_sub_uart_set_page(sub_uart,0)<0){ return -2; } if(wk2114_write_reg(sub_uart->wk2114,WK2114_BUILD_SUB_REG(sub_uart->uart_index,WK2114_S_REG_FCR),mode)<0){ return -2; } return 0; } /** * @brief 开启子串口时钟 * * @param sub_uart 子串口 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_enable(WK2114_Sub_Uart_TypeDef*sub_uart) { log_i( "..... wk2114_sub_uart_enable .. "); sub_uart->flag|=WK2114_S_UART_FLAG_MASK_ENABLE; return wk2114_flush_gena(sub_uart->wk2114); } /** * @brief 关闭子串口时钟 * * @param sub_uart 子串口结构 * @return int 成功;0 失败:负值 */ int wk2114_sub_uart_disable(WK2114_Sub_Uart_TypeDef*sub_uart) { sub_uart->flag&=~WK2114_S_UART_FLAG_MASK_ENABLE; return wk2114_flush_gena(sub_uart->wk2114); } /** * @brief 重置子串口 * * @param sub_uart 子串口结构 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_reset(WK2114_Sub_Uart_TypeDef*sub_uart) { return wk2114_write_reg(sub_uart->wk2114,WK2114_G_REG_GRST,1<uart_index); } /** * @brief 通过子串口向外发送数据 * @note buf参数指向的缓冲区在发送完成之前不能改变 * @param sub_uart 子串口结构 * @param buf 要发送的数据缓冲区 * @param size 要发送的长度 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_send(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t *buf,uint32_t size) { int p_en; int isimpty; int descriptor; descriptor=critical_section_enter(); if(descriptor<0){ return -2; } isimpty=queue_isempty(&sub_uart->send_queue); p_en=queue_get_en_index(&sub_uart->send_queue); if(p_en<0){ critical_section_exit(descriptor); return -2; } sub_uart->send_record[p_en].p_data=buf; sub_uart->send_record[p_en].size=size; queue_enqueue(&sub_uart->send_queue,0); critical_section_exit(descriptor); if(isimpty){ return wk2114_sub_uart_set_inter(sub_uart,WK2114_S_REG_SIFR_MASK_RFTRIG_INT|WK2114_S_REG_SIFR_MASK_RXOVT_INT|WK2114_S_REG_SIFR_MASK_TFTRIG_INT|WK2114_S_REG_SIFR_MASK_TFEMPTY_INT|WK2114_S_REG_SIFR_MASK_FERR_INT); } return 0; } /** * @brief 判断子串口是否忙 * * @param sub_uart 子串口结构 * @return int -1:出错 0:不忙 1:忙 */ int wk2114_sub_uart_isbusy(WK2114_Sub_Uart_TypeDef*sub_uart) { if(sub_uart==NULL){ return -1; } return !queue_isempty(&sub_uart->send_queue)||sub_uart->send_buf!=NULL; } /** * @brief wk2114初始化 * * @param wk2114 WK2114_TypeDef 结构指针 * @param dev_clock_hz wk2114的时钟源频率 * @param send_class 发送函数的第一个参数 * @param send_fun 发送函数 * @return struct wk2114* 成功:wk2114 失败:NULL */ // WK2114_TypeDef * wk2114_init(WK2114_TypeDef *wk2114,uint32_t dev_clock_hz,void *send_class,wk2114_send_fun send_fun) // { // int i; // if(wk2114==NULL || send_class==NULL || send_fun==NULL || dev_clock_hz>32000000 || dev_clock_hz<1000000){ // return NULL; // } // if(queue_init(&wk2114->cmd_queue,NULL,64)==NULL){ // return NULL; // } // wk2114->send_class=send_class; // wk2114->send_fun=send_fun; // wk2114->flag=0; // wk2114->dev_clock_hz=dev_clock_hz; // for(i=0;i<4;i++){ // wk2114->sub_uart[0]=NULL; // } // if(wk2114_set_baud(wk2114)<0){ // return NULL; // }; // return wk2114; // } /** * @brief 注册子串口 * * @param wk2114 WK2114_TypeDef 结构指针 * @param sub_uart 子串口结构 * @param uart_addr 子串口地址 * @param recv_buf 接收缓冲区 * @param recv_buf_size 接收缓冲区大小 >=16 * @param recv_class 接收回调函数的第一个参数 * @param recv_fun 接收回调函数 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_register(WK2114_TypeDef *wk2114,WK2114_Sub_Uart_TypeDef*sub_uart,enum wk2114_s_uart uart_addr,uint8_t *recv_buf,uint32_t recv_buf_size,void *recv_class,wk2114_sub_uart_recv_fun recv_fun) { log_i( ".....wk2114_sub_uart_register.. " ); // if(wk2114==NULL || sub_uart==NULL || recv_class==NULL || recv_fun==NULL || uart_addr<0 || uart_addr>=4 || recv_buf==NULL || recv_buf_size<16){ // return -1; // } // // TODO // sub_uart->send_queue = osMessageQueueNew(8, sizeof(struct wk2114_send_record) ,NULL); // if (sub_uart->send_queue ==NULL) return -2; // // if(queue_init(&sub_uart->send_queue,NULL,8)==NULL){ // // return -2; // // } // if(wk2114->sub_uart[uart_addr]!=NULL){ // return -3; // } // sub_uart->recv_class=recv_class; // sub_uart->recv_fun=recv_fun; // sub_uart->recv_buf=recv_buf; // sub_uart->recv_buf_size=recv_buf_size; // sub_uart->recv_buf_p=0; // sub_uart->wk2114=wk2114; // sub_uart->flag=0; // sub_uart->cmd=0; // sub_uart->reg=0; // sub_uart->uart_index=uart_addr; // sub_uart->send_buf_p=0; // sub_uart->send_buf=NULL; // wk2114->sub_uart[uart_addr]=sub_uart; // log_i( ".....wk2114_sub_uart_register.. wk2114->flag %d " , wk2114->flag); return 0; }/** * @brief 更改子串口接收回调函数 * * @param sub_uart 子串口结构 * @param recv_class 接受回调函数的第一个参数 * @param recv_fun 接收回调函数 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_chenge_recv_fun(WK2114_Sub_Uart_TypeDef*sub_uart,void *recv_class,wk2114_sub_uart_recv_fun recv_fun) { if(sub_uart==NULL || recv_class==NULL || recv_fun==NULL){ return -1; } sub_uart->recv_class=recv_class; sub_uart->recv_fun=recv_fun; return 0; } /** * @brief 子串口初始化 * * @param sub_uart 子串口结构 * @param buad 波特率 * @param mode 模式 WK2114_SUB_UART_MODE_MASK_XXX 的任意结合 * @param fifo_mode FIFO模式 WK2114_SUB_UART_FIFO_MODE_MASK_XXX 的任意结合 * @param party 校验 * @param stop_bits 停止位 * @return int 成功:0 失败:负值 */ int wk2114_sub_uart_init(WK2114_Sub_Uart_TypeDef*sub_uart,uint32_t buad,uint8_t mode,uint8_t fifo_mode,enum wk2114_uart_parity party,enum wk2114_uart_stop_bits stop_bits) { log_i( "wk2114_sub_uart_init .. %d " , wk2114->flag); if(wk2114_sub_uart_enable(sub_uart)<0){ return -1; } // if(wk2114_sub_uart_reset(sub_uart)<0){ // return -1; // } // if(wk2114_flush_gier(sub_uart->wk2114)<0){ // return -1; // } // if(wk2114_set_sub_uart(sub_uart,buad,party,stop_bits)<0){ // return -1; // } // if(wk2114_sub_uart_set_fifo_trigger(sub_uart,128,128)<0){ // return -1; // } // if(wk2114_sub_uart_set_inter(sub_uart,WK2114_S_REG_SIFR_MASK_RFTRIG_INT|WK2114_S_REG_SIFR_MASK_RXOVT_INT|WK2114_S_REG_SIFR_MASK_FERR_INT)<0){ // return -1; // } // if(wk2114_sub_uart_set_fifo_mode(sub_uart,fifo_mode)<0){ // return -1; // } // if(wk2114_sub_uart_set_mode(sub_uart,mode)<0){ // return -1; // } return 0; } /** * @brief 内部函数 接收寄存器回调 * * @param wk2114 WK2114_TypeDef 结构指针 */ void wk2114_reg_recv_callback(WK2114_TypeDef *wk2114) { int i; int p_de; if(WK2114_CMD_GET_ADDR(wk2114->cmd)==WK2114_G_REG_GIFR){ wk2114->cmd=0; if((wk2114->reg&WK2114_G_REG_GIFR_MASK_UT1INT)!=0 && wk2114->sub_uart[WK2114_S_UART_1]!=NULL){ wk2114_read_reg(wk2114,WK2114_BUILD_SUB_REG(WK2114_S_UART_1,WK2114_S_REG_SIFR)); } if((wk2114->reg&WK2114_G_REG_GIFR_MASK_UT2INT)!=0 && wk2114->sub_uart[WK2114_S_UART_2]!=NULL){ wk2114_read_reg(wk2114,WK2114_BUILD_SUB_REG(WK2114_S_UART_2,WK2114_S_REG_SIFR)); } if((wk2114->reg&WK2114_G_REG_GIFR_MASK_UT3INT)!=0 && wk2114->sub_uart[WK2114_S_UART_3]!=NULL){ wk2114_read_reg(wk2114,WK2114_BUILD_SUB_REG(WK2114_S_UART_3,WK2114_S_REG_SIFR)); } if((wk2114->reg&WK2114_G_REG_GIFR_MASK_UT4INT)!=0 && wk2114->sub_uart[WK2114_S_UART_4]!=NULL){ wk2114_read_reg(wk2114,WK2114_BUILD_SUB_REG(WK2114_S_UART_4,WK2114_S_REG_SIFR)); } return; } for(i=0;i<4;i++){ if(wk2114->sub_uart[i]!=NULL && (wk2114->sub_uart[i]->flag&WK2114_S_UART_FLAG_MASK_PAGE_D)==0){ if(WK2114_CMD_GET_ADDR(wk2114->sub_uart[i]->cmd)==WK2114_BUILD_SUB_REG(i,WK2114_S_REG_SIFR)){ wk2114->sub_uart[i]->cmd=0; if((wk2114->sub_uart[i]->reg&WK2114_S_REG_SIFR_MASK_RXOVT_INT)!=0){ wk2114->sub_uart[i]->flag|=WK2114_S_UART_FLAG_MASK_IDLE; wk2114_read_reg(wk2114,WK2114_BUILD_SUB_REG(i,WK2114_S_REG_RFCNT)); } else if((wk2114->sub_uart[i]->reg&WK2114_S_REG_SIFR_MASK_RFTRIG_INT)!=0){ wk2114_read_fifo(wk2114,i,126); } if((wk2114->sub_uart[i]->reg&WK2114_S_REG_SIFR_MASK_TFEMPTY_INT)!=0 && wk2114->sub_uart[i]->send_buf_p==0xffffffff){ // 发送FIFO触点空中断 发送下一个字符串 wk2114->sub_uart[i]->send_buf_p=0; p_de=queue_get_de_index(&wk2114->sub_uart[i]->send_queue); if(p_de>=0){ if(wk2114->sub_uart[i]->send_record[p_de].size-wk2114->sub_uart[i]->send_buf_p <= 256){ wk2114_write_fifo(wk2114,i,&wk2114->sub_uart[i]->send_record[p_de].p_data[wk2114->sub_uart[i]->send_buf_p],wk2114->sub_uart[i]->send_record[p_de].size-wk2114->sub_uart[i]->send_buf_p-1); wk2114->sub_uart[i]->send_buf_p=0xffffffff; queue_dequeue(&wk2114->sub_uart[i]->send_queue,NULL); } else{ wk2114_write_fifo(wk2114,i,&wk2114->sub_uart[i]->send_record[p_de].p_data[wk2114->sub_uart[i]->send_buf_p],255); wk2114_sub_uart_set_inter(wk2114->sub_uart[i],WK2114_S_REG_SIFR_MASK_RFTRIG_INT|WK2114_S_REG_SIFR_MASK_RXOVT_INT|WK2114_S_REG_SIFR_MASK_TFTRIG_INT|WK2114_S_REG_SIFR_MASK_TFEMPTY_INT|WK2114_S_REG_SIFR_MASK_FERR_INT); wk2114->sub_uart[i]->send_buf_p+=256; } } else{ wk2114_sub_uart_set_inter(wk2114->sub_uart[i],WK2114_S_REG_SIFR_MASK_RFTRIG_INT|WK2114_S_REG_SIFR_MASK_RXOVT_INT|WK2114_S_REG_SIFR_MASK_FERR_INT); } } else if((wk2114->sub_uart[i]->reg&WK2114_S_REG_SIFR_MASK_TFTRIG_INT)!=0){ // 发送FIFO触点中断 发送同一个字符串 p_de=queue_get_de_index(&wk2114->sub_uart[i]->send_queue); if(p_de>=0){ if(wk2114->sub_uart[i]->send_buf_p >= wk2114->sub_uart[i]->send_record[p_de].size){ wk2114_sub_uart_set_inter(wk2114->sub_uart[i],WK2114_S_REG_SIFR_MASK_RFTRIG_INT|WK2114_S_REG_SIFR_MASK_RXOVT_INT|WK2114_S_REG_SIFR_MASK_TFEMPTY_INT|WK2114_S_REG_SIFR_MASK_FERR_INT); wk2114->sub_uart[i]->send_buf_p=0xffffffff; return; } if(wk2114->sub_uart[i]->send_record[p_de].size-wk2114->sub_uart[i]->send_buf_p <= 128){ wk2114_write_fifo(wk2114,i,&wk2114->sub_uart[i]->send_record[p_de].p_data[wk2114->sub_uart[i]->send_buf_p],wk2114->sub_uart[i]->send_record[p_de].size-wk2114->sub_uart[i]->send_buf_p-1); wk2114->sub_uart[i]->send_buf_p=0xffffffff; wk2114_sub_uart_set_inter(wk2114->sub_uart[i],WK2114_S_REG_SIFR_MASK_RFTRIG_INT|WK2114_S_REG_SIFR_MASK_RXOVT_INT|WK2114_S_REG_SIFR_MASK_TFEMPTY_INT|WK2114_S_REG_SIFR_MASK_FERR_INT); queue_dequeue(&wk2114->sub_uart[i]->send_queue,NULL); } else{ wk2114_write_fifo(wk2114,i,&wk2114->sub_uart[i]->send_record[p_de].p_data[wk2114->sub_uart[i]->send_buf_p],127); wk2114->sub_uart[i]->send_buf_p+=128; } } else{ wk2114_sub_uart_set_inter(wk2114->sub_uart[i],WK2114_S_REG_SIFR_MASK_RFTRIG_INT|WK2114_S_REG_SIFR_MASK_RXOVT_INT|WK2114_S_REG_SIFR_MASK_FERR_INT); } } if((wk2114->sub_uart[i]->reg&WK2114_S_REG_SIFR_MASK_FERR_INT)!=0){ wk2114_read_reg(wk2114,WK2114_BUILD_SUB_REG(i,WK2114_S_REG_LSR)); } } else if(WK2114_CMD_GET_ADDR(wk2114->sub_uart[i]->cmd)==WK2114_BUILD_SUB_REG(i,WK2114_S_REG_RFCNT)){ wk2114->sub_uart[i]->cmd=0; wk2114_read_fifo(wk2114,i,wk2114->sub_uart[i]->reg-1); } else if(WK2114_CMD_GET_ADDR(wk2114->sub_uart[i]->cmd)==WK2114_BUILD_SUB_REG(i,WK2114_S_REG_LSR)){ wk2114->sub_uart[i]->cmd=0; wk2114_read_reg(wk2114,WK2114_BUILD_SUB_REG(i,WK2114_S_REG_FSR)); } else if(WK2114_CMD_GET_ADDR(wk2114->sub_uart[i]->cmd)==WK2114_BUILD_SUB_REG(i,WK2114_S_REG_FSR)){ wk2114->sub_uart[i]->cmd=0; } } } return; } /** * @brief wk2114接收回调 * * @param wk2114 WK2114_TypeDef 结构指针 * @param buf 接收到的数据缓冲区 * @param size 接收到的数据长度 */ void wk2114_recv_callback(WK2114_TypeDef *wk2114,uint8_t *buf,uint32_t size) { int p_de; uint8_t cmd; uint8_t cmd_size; uint8_t sub_uart; WK2114_Sub_Uart_TypeDef*p_sub_uart; cmd=wk2114->send_buf[0]; wk2114->send_buf[0]=0; cmd_size=WK2114_CMD_GET_SIZE(cmd); sub_uart=WK2114_CMD_GET_SUB_UART(cmd); p_sub_uart=wk2114->sub_uart[sub_uart]; if(WK2114_CMD_IS_WRITE(cmd)){ return; } if(WK2114_CMD_IS_REG(cmd)){ // 读寄存器 if(size!=1){ return; } if(WK2114_REG_IS_GLOBAL(cmd_size)){ // 全局寄存器 if(wk2114->cmd!=0xff){ return; } wk2114->cmd=cmd; wk2114->reg=buf[0]; } else{ // 子串口寄存器 if(p_sub_uart==NULL || wk2114->sub_uart[sub_uart]->cmd!=0xff){ return; } p_sub_uart->cmd=cmd; p_sub_uart->reg=buf[0]; } wk2114->flag&=~WK2114_G_FLAG_MASK_BUSY; wk2114_reg_recv_callback(wk2114); return; } if(size!=cmd_size){ return; } if(p_sub_uart->recv_buf_size-p_sub_uart->recv_buf_p < size){ cmd_size=p_sub_uart->recv_buf_size-p_sub_uart->recv_buf_p; } memcpy(&p_sub_uart->recv_buf[p_sub_uart->recv_buf_p],buf,cmd_size); p_sub_uart->recv_buf_p+=cmd_size; p_de=queue_get_de_index(&wk2114->cmd_queue); if((p_de<0 || (wk2114->cmd_buf[p_de][0]&0xf0)!=(cmd&0xf0)) && (p_sub_uart->flag&WK2114_S_UART_FLAG_MASK_IDLE)==1){ // 接收超时 p_sub_uart->flag&=~WK2114_S_UART_FLAG_MASK_IDLE; p_sub_uart->recv_fun(p_sub_uart->recv_class,p_sub_uart->recv_buf,p_sub_uart->recv_buf_p); p_sub_uart->recv_buf_p=0; } else if(p_sub_uart->recv_buf_p==p_sub_uart->recv_buf_size) // 缓冲区满 { p_sub_uart->recv_fun(p_sub_uart->recv_class,p_sub_uart->recv_buf,p_sub_uart->recv_buf_p); p_sub_uart->recv_buf_p=size-cmd_size; memcpy(p_sub_uart->recv_buf,&buf[cmd_size],p_sub_uart->recv_buf_p); } wk2114->flag&=~WK2114_G_FLAG_MASK_BUSY; } /** * @brief wk2114中断回调 * @note 不要将此函数放入中断中或比其他回调函数优先级更改的任务中 * @param wk2114 WK2114_TypeDef 结构指针 */ void wk2114_inter_callback(WK2114_TypeDef *wk2114) { if((wk2114->flag&WK2114_G_FLAG_MASK_INTER)!=0){ return; } wk2114->flag|=WK2114_G_FLAG_MASK_INTER; wk2114_read_reg(wk2114,WK2114_G_REG_GIFR); } /** * @brief wk2114发送完成回调 * * @param wk2114 WK2114_TypeDef 结构指针 */ void wk2114_send_completed_callback(WK2114_TypeDef *wk2114) { wk2114->flag&=~WK2114_G_FLAG_MASK_SENDING; wk2114_send(wk2114); }