不含stm32 底层的代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MyStm32Code/device/Src/wk2114.c

939 lines
32 KiB

2 years ago
/**
* @file wk2114.c
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief WK2114串口拓展驱动
* @version 1.0
* @date 2023-01-04
*
* @copyright ESEA (c) 2020
*
*/
#include <string.h>
#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<<i);
}
}
return wk2114_write_reg(wk2114,WK2114_G_REG_GENA,reg);
}
/**
* @brief 使
*
* @param wk2114 struct wk2114结构指针
* @return int :0 :
*/
int wk2114_flush_gier(WK2114_TypeDef *wk2114)
{
uint8_t reg;
int i;
reg=0;
for(i=0;i<4;i++){
if(wk2114->sub_uart[i]!=NULL){
reg|=(1<<i);
}
}
return wk2114_write_reg(wk2114,WK2114_G_REG_GIER,reg);
}
/**
* @brief
* @note \ref wk2114_init()
* @param wk2114 struct wk2114结构指针
* @param party
* @param stop_bits
* @return int :0 :
*/
int wk2114_set_uart(WK2114_TypeDef *wk2114,enum wk2114_uart_parity party,enum wk2114_uart_stop_bits stop_bits)
{
return(wk2114_write_reg(wk2114,WK2114_G_REG_GMUT,party|stop_bits));
}
/**
* @brief
* @note \ref wk2114_sub_uart_init() ,
* @param sub_uart
* @param buad
* @param party
* @param stop_bits
* @return int :0 :
*/
int wk2114_set_sub_uart(WK2114_Sub_Uart_TypeDef*sub_uart,uint32_t buad,enum wk2114_uart_parity party,enum wk2114_uart_stop_bits stop_bits)
{
uint32_t tmp;
uint16_t buad_div;
tmp=sub_uart->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<<sub_uart->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);
}