123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- #include "hal_ble_uart0.h"
- #include "system.h"
- #include "bsp_time.h"
- #include "app_uart.h"
- #include "nrf_gpio.h"
- /************************ 函数声明 ***********************************/
- //extern void UART0_send_buff(uint8_t *p,uint16_t len);
- void UART0_Tx_Process(void);
- /************************ 变量 ***********************************/
- /********************** 环形缓存区 *************************/
- static const int RxLen = 1024;
- static volatile unsigned char RxBuf[RxLen];
- static volatile unsigned char* RxW=RxBuf;
- static volatile unsigned char* RxR=RxBuf;
- void UART0_Push(unsigned char* p,int len)
- {
- volatile unsigned char *W=RxW; //这里要与上面指针相同
- if(len<=0) return;
- for(int i=0;i<len;i++){
- W=RxW+1; if(W>=RxBuf+RxLen) W=RxBuf; //取下一位置(到顶转到底)
- if(W!=RxR){*RxW=*(p+i); RxW=W;}
- else break;
- }
- }
- static unsigned int CheckLen(void) //检查RX接收了多少数据
- {
- unsigned int Len; //short
- volatile unsigned char *W=RxW; volatile unsigned char *R=RxR;
- if(W>=R)Len=W-R;else Len=(W+RxLen)-R; //这样正确(中途中断改变也变不了结果)
- return Len;
- }
- //static unsigned char ReadByte(void) //读RX中数锯,地指加一,和丢弃
- //{
- // unsigned char R=*RxR; //读数
- // if(RxR!=RxW){ if(RxR+1>=(RxBuf+RxLen))RxR =RxBuf; else RxR++;}//下标
- // return R;
- //}
- static unsigned char CheckByte(unsigned short n) //看RX中数锯,地指不变,
- {
- volatile unsigned char *R=RxR+n;
- if(R>=(RxBuf+RxLen))R-=RxLen;
- return *R;
- }
- static void Discard(unsigned short n) //丢弃RX数据几位
- {
- while(n){ n--;
- if(RxR==RxW) return;
- if(RxR+1>=RxBuf+RxLen){RxR=RxBuf;} else RxR++; //下标
- }
- }
- //********************* 接收 **********************//
- #define UART0_RX_CMD_LEN 256
- static UART0_Rx_t mUART0_Rx[UART0_NUM_OF_R];
- static unsigned char cmdDatBuf[UART0_RX_CMD_LEN]; //存放一条完整命令
- static unsigned int rxNum = 0;
- int UART0_Rx_Regist(unsigned char cmd,UART0_Callback cb) //注册
- {
- if(rxNum>=UART0_NUM_OF_R) return -1;
- mUART0_Rx[rxNum].cb = cb;
- mUART0_Rx[rxNum].cmd = cmd;
- mUART0_Rx[rxNum].pDat = cmdDatBuf;
- rxNum++;
- return 0;
- }
- //********************* 接收协议 **********************//
- //协议(1位头+ 1位长度+ 1位长度反码+ 1命令+ N数据+ 1效验)
- static void Protocol(unsigned char len) //协议处理
- {
- #if DEBUG_UART0
- SEGGER_RTT_printf(0,"Rx_UART0(%d):",CheckByte(1)); for(int i=0;i<len;i++){SEGGER_RTT_printf(0,"%02X ",CheckByte(i));} SEGGER_RTT_printf(0,"\r\n");
- #endif
- uint8_t cmd = CheckByte(3);
- if(len<5) return;
- for(int j=0;j<rxNum;j++){
- if(mUART0_Rx[j].cmd==cmd&&mUART0_Rx[j].cb){
- for(int i=0;i<len-5;i++) mUART0_Rx[j].pDat[i] = CheckByte(i+4);
- mUART0_Rx[j].datLen = len-5;
- mUART0_Rx[j].cb((UART0_Rx_t*)&mUART0_Rx[j]);
- break;
- }
- }
- }
- //协议(1位头+ 1位长度+ 1位长度反码+ 1命令+ N数据+ 1效验)
- void UART0_Rx_Process(void)
- {
- static unsigned char R=0;
- static unsigned char L=0;
- //接收缓存有数据,就全部处理
- while(1){
- switch( R ){
- case 0: if( CheckLen()<3 )return; else{
- if(CheckByte(0)!=0xAA){ Discard(1);}
- else{unsigned char LF=CheckByte(2);LF=~LF; L=CheckByte(1); if((LF==L)&&(L>=5)){ R++;}else { Discard(1);}}
- } break;
- // 多收数据 7 = 3位头+ 1位长度负数+ 1位长度+ 2效验
- case 1: if( CheckLen()<L) { return; }else{ //SEGGER_RTT_printf(0,"Rx:"); for(int i=0;i<L;i++){SEGGER_RTT_printf(0,"%02X ",CheckByte(i));} SEGGER_RTT_printf(0,"\r\n");
- unsigned char i,ver=0;
- for(i=0;i<L-1;i++){ ver += CheckByte(i); }
- if(CheckByte(L-1)==ver){ Protocol(L);Discard(L);//丢弃整条命令
- } else Discard(1);
- R=0;
- } break;
- default: R=0;break; }
- }
- }
- //********************* 发送协议 **********************//
- void UART0_SendChar(unsigned char ch)//发送一位数锯
- {
- NRF_UART0->TXD = (unsigned int)ch;
- while(NRF_UART0->EVENTS_TXDRDY == 0x0UL);
- NRF_UART0->EVENTS_TXDRDY = 0x0UL;
- }
- void UART0_SendBuff(unsigned char *p,int L)//发送缓存
- {
- unsigned int len = L;
- while (len>0){len--;
- UART0_SendChar(*p++);
- }
- }
- void UART0_SendStr(char *p)//发送字符串
- {
- while (*p){
- UART0_SendChar(*p++);
- }
- }
- //协议(1位头+ 1位长度+ 1位长度反码+ 1命令+ N数据+ 1效验)
- void UART0_Send(unsigned char cmd,unsigned char *pDat,unsigned char datLen) //协议发送
- {
- unsigned char buf[255];
- unsigned char ver=0;
- unsigned char i,L=0,Len=datLen+5;
-
- buf[L]=0xAA; ver+=buf[L++]; // 头
- buf[L]=Len; ver+=buf[L++]; //1位长度
- buf[L]=~Len; ver+=buf[L++]; // 1位长度反码
- buf[L]=cmd; ver+=buf[L++]; //1命令
- for(i=0;i<datLen; i++){ buf[L]=pDat[i];ver+=buf[L++];} //数据
- buf[L++]=ver; //效验
- #if DEBUG_UART0
- SEGGER_RTT_printf(0,"Tx_UART0:"); for(int i=0;i<L;i++){SEGGER_RTT_printf(0,"%02X ",buf[i]);} SEGGER_RTT_printf(0,"\r\n");
- #endif
- // UART0_send_buff(buf,L); //压入发送缓存
- for(i=0;i<L;i++) UART0_SendChar(buf[i]);
- }
- static UART0_Tx_t* head_handle = 0;
- void UART0_Tx_Send(UART0_Tx_t* handle,unsigned char cmd,unsigned char *pDat,unsigned char datLen)
- {
- UART0_Tx_t* target = head_handle;
- if(handle){
- handle->cmd = cmd;
- handle->pDat = pDat;
- handle->datLen = datLen;
- handle->tcnt = handle->t;
- if(handle->n>0) handle->ncnt = handle->n-1;
- else handle->ncnt = 0;
- handle->holdon = 1;
- while(target){ //检查是否已经存在
- if(target==handle){
- return;
- }
- target = target->next ;
- }
- handle->next = head_handle;
- head_handle = handle;
- }
- UART0_Send(cmd,pDat,datLen);
- }
- void UART0_Tx_Clear(UART0_Tx_t* handle)
- {
- UART0_Tx_t** curr;
- for(curr=&head_handle;*curr;){
- UART0_Tx_t* entry = *curr;
- if(entry==handle){
- handle->holdon = 0;
- *curr = entry->next;
- }else{
- curr = &entry->next;
- }
- }
- }
- void UART0_Tx_Process(void)
- {
- UART0_Tx_t* target;
- uint8_t holdon = 0;
- for(target=head_handle; target; target=target->next) {
- if(target->tcnt>0){target->tcnt--;
- if(target->tcnt==0){
- if(target->ncnt>0){target->ncnt--;
- target->tcnt = target->t;
- UART0_Send(target->cmd,target->pDat,target->datLen);
- }else{
- UART0_Tx_Clear(target);
- if(target->cb){
- target->cb(target);
- }
- }
- }
- }
- holdon |= target->holdon;
- }
- Process_SetHoldOn(UART0_Tx_Process,holdon);
- }
- //void uart_event_handle(app_uart_evt_t * p_event)
- //{
- // unsigned char byte;
- // switch (p_event->evt_type)
- // {
- // /**@snippet [Handling data from UART] */
- // case APP_UART_DATA_READY:
- // app_uart_get(&byte);
- // UART0_Push(&byte,1);
- // break;
- // /**@snippet [Handling data from UART] */
- // case APP_UART_COMMUNICATION_ERROR:
- // //APP_ERROR_HANDLER(p_event->data.error_communication);
- // break;
- // case APP_UART_FIFO_ERROR:
- // //APP_ERROR_HANDLER(p_event->data.error_code);
- // break;
- // default:
- // break;
- // }
- //}
- //*****************************************************************//
- void UARTE0_UART0_IRQHandler(void)
- {
- volatile unsigned char *W=RxW; //这里要与上面指针相同
- if(NRF_UART0->EVENTS_RXDRDY!=0){NRF_UART0->EVENTS_RXDRDY=0;
- uint8_t ch = NRF_UART0->RXD;
- // SEGGER_RTT_printf(0," %02X\n",ch);
- W=RxW+1; if(W>=RxBuf+RxLen) W=RxBuf; //取下一位置(到顶转到底)
- if(W!=RxR){*RxW=ch; RxW=W;}
- }
- if(NRF_UART0->EVENTS_RXTO!=0){NRF_UART0->EVENTS_RXTO=0;
- //SEGGER_RTT_printf(0,"EVENTS_RXTO\n");
- }
- if(NRF_UART0->EVENTS_CTS!=0){NRF_UART0->EVENTS_CTS=0;
- //SEGGER_RTT_printf(0,"EVENTS_CTS\n");
- }
- if(NRF_UART0->EVENTS_NCTS!=0){NRF_UART0->EVENTS_NCTS=0;
- //SEGGER_RTT_printf(0,"EVENTS_NCTS\n");
- }
- if(NRF_UART0->EVENTS_TXDRDY!=0){//NRF_UART0->EVENTS_TXDRDY=0;
- //SEGGER_RTT_printf(0,"EVENTS_TXDRDY\n");
- }
- if(NRF_UART0->EVENTS_ERROR!=0){NRF_UART0->EVENTS_ERROR=0;
- //SEGGER_RTT_printf(0,"EVENTS_ERROR=%d\n",NRF_UART0->EVENTS_ERROR);
- }
- }
- uint32_t get_baud(uint32_t baud)
- {
- switch(baud){
- case 1200: return UART_BAUDRATE_BAUDRATE_Baud1200;
- case 2400: return UART_BAUDRATE_BAUDRATE_Baud2400;
- case 4800: return UART_BAUDRATE_BAUDRATE_Baud4800;
- case 9600: return UART_BAUDRATE_BAUDRATE_Baud9600;
- case 14400: return UART_BAUDRATE_BAUDRATE_Baud14400;
- case 19200: return UART_BAUDRATE_BAUDRATE_Baud19200;
- case 28800: return UART_BAUDRATE_BAUDRATE_Baud28800;
- case 31250: return UART_BAUDRATE_BAUDRATE_Baud31250;
- case 38400: return UART_BAUDRATE_BAUDRATE_Baud38400;
- case 56000: return UART_BAUDRATE_BAUDRATE_Baud56000;
- case 57600: return UART_BAUDRATE_BAUDRATE_Baud57600;
- case 76800: return UART_BAUDRATE_BAUDRATE_Baud76800;
- case 115200: return UART_BAUDRATE_BAUDRATE_Baud115200;
- case 230400: return UART_BAUDRATE_BAUDRATE_Baud230400;
- case 250000: return UART_BAUDRATE_BAUDRATE_Baud250000;
- case 460800: return UART_BAUDRATE_BAUDRATE_Baud460800;
- case 921600: return UART_BAUDRATE_BAUDRATE_Baud921600;
- case 1000000: return UART_BAUDRATE_BAUDRATE_Baud1M;
- default: return UART_BAUDRATE_BAUDRATE_Baud115200;
- }
- }
- void UART0_Init(uint32_t baud)
- {
- NRF_UART0->INTENCLR = UART_INTENCLR_CTS_Msk | UART_INTENCLR_RXTO_Msk | UART_INTENCLR_NCTS_Msk | UART_INTENCLR_ERROR_Msk;
- NRF_UART0->INTENSET = UART_INTENSET_RXDRDY_Enabled << UART_INTENSET_RXDRDY_Pos;
- NRF_UART0->PSELTXD = PIN_TXD_BLE;
- NRF_UART0->PSELRXD = PIN_RXD_BLE;
-
- NRF_UART0->BAUDRATE = get_baud(baud);
- NRF_UART0->ENABLE |= UART_ENABLE_ENABLE_Enabled;
- NRF_UART0->TASKS_STARTTX = 0XFFFFFFFF;
- NRF_UART0->TASKS_STARTRX = 0XFFFFFFFF;
- NVIC_SetPriority(UARTE0_UART0_IRQn, 7);
- NVIC_EnableIRQ(UARTE0_UART0_IRQn);
- NRF_UART0->EVENTS_TXDRDY = 0x0UL;
- }
- void UART0_unInit(void)
- {
- NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Disabled;
- NRF_UART0->INTENCLR = UART_INTENCLR_RXDRDY_Msk | UART_INTENCLR_TXDRDY_Msk | UART_INTENCLR_RXTO_Msk | UART_INTENCLR_ERROR_Msk;
- NVIC_DisableIRQ(UARTE0_UART0_IRQn);
- NVIC_ClearPendingIRQ(UARTE0_UART0_IRQn);
- }
- static void cb_uarteWakeup(uint32_t t)
- {
- UART0_Init(38400);
- }
- static void cb_uarteSleep(uint32_t t)
- {
- UART0_unInit();
- }
- void UART0_Initialize(void)
- {
- UART0_Init(38400);
- Process_Start(0,UART0_Rx_Process);
- Process_Start(10,UART0_Tx_Process);
-
- Wakeup_Regist(cb_uarteWakeup);
- Sleep_Regist(cb_uarteSleep);
- }
|