📄 drvuart0.c
字号:
#include "includes.h"
#include "device.h"
#include "funcint.h"
#include "event.h"
#include "devuart0.h"
extern OS_MEM *pMemSml;
extern OS_MEM *pMemLge;
extern INT8U rom ModuleMod;
INT16U uart0_init(void);
INT16U uart0_open(void);
INT16U uart0_ioctl(INT8U cmd, INT24U arg);
INT16U uart0_write(INT8U rom *wrpte, INT16U length);
void Func_Transmit_ISR(void);
void Func_INT2_ISR(void);
void Func_TMR0_ISR(void);
INT16U intCurTxNum;
INT8U chrCOMBusy;
INT8U CurRxNum;
INT8U rom * pCurRxTail;
INT8U rom * pCurRxHead;
INT8U rom * pCurTxHead;
INT8U erri;
INT8U rom *pMemT;
INT8U rom *pMemT2;
INT16U intTemp1;
INT8U rom * ptrTemp2;
INT8U ComCurStt;
#pragma romdata EXTRAM
//Transmit queue
INT8U rom * rom pTxQ[64];
OS_MEM rom * rom TxTypeQ[64];
INT16U rom TxLenQ[64];
INT8U rom TxQHead;
INT8U rom TxQTail;
#pragma romdata CCODE
DEV_HEADER DEV_UART0 = {
DEV_ID_UART0, /*device ID */
{'C','M','0'}, /*device name*/
DEVP_CHAR, /*device Type*/
uart0_init, /*device init function*/
FNull_1, /*device clear function*/
uart0_open, /*device open function*/
FNull_1, /*device close function*/
uart0_ioctl, /*device ioctl function*/
uart0_write, /*device write function*/
FNull_1 /*device read function*/
};
#pragma code MYCODE
INT16U uart0_init(void){
//INTCON3bits.INT2E = 1; //enable INT2 for receive
T0CON = 0b00000010; //Timer0 is used for receiver time out
isr_set(INT_TX0, Func_Transmit_ISR);
isr_set(INT_EINT2,Func_INT2_ISR);
isr_set(INT_TMR0,Func_TMR0_ISR);
}
INT16U uart0_open(void){
INT8U err;
TxQHead = 0;
TxQTail = 0;
chrCOMBusy = FALSE;
do{
pCurRxTail = OSMemGet(pMemLge, &err);
}while(err != OS_NO_ERR);
CurRxNum = 0;
pCurRxHead = pCurRxTail;
TXSTAbits.TX9 = 0; //select 8bit per byte
RCSTAbits.RX9 = 0;
TXSTAbits.TXEN = 1; //enable transmit
TXSTAbits.SYNC = 0; //asynchronous mode
TXSTAbits.BRGH = 1; //high baud rate
RCSTAbits.SPEN = 1; //enable serial port
RCSTAbits.CREN = 1; //enable continous receive
SPBRG = 1;//22; //select baud rate
IPR1bits.RCIP = 1; //set RX high priority
IPR1bits.TXIP = 0; //set TX low priority
PIE1bits.RCIE = 0; //close interrupt, it will be open in tskHardware
PIE1bits.TXIE = 0;
INTCON3bits.INT2E = 1; //enable INT2 for receive
PIE1bits.RCIE = 1;
}
INT16U uart0_ioctl(INT8U cmd, INT24U arg){
switch (cmd){
case UART_SETMEMTYP:
if(((TxQTail+1) & 0x3f) != TxQHead){
TxTypeQ[TxQTail] = (OS_MEM rom *) arg;
return(0);
}
else return(1);
break;
case UART_CLRBUF:
intCurTxNum = 0;
pCurTxHead = (INT8U rom *)0;
PIE1bits.TXIE = 0;
chrCOMBusy = FALSE;
CurRxNum = 0;
pCurRxTail = pCurRxHead;
break;
}
}
INT16U uart0_write(INT8U rom *wrptr, INT16U length){
if(((TxQTail+1) & 0x3f) != TxQHead){
pTxQ[TxQTail] = wrptr;
TxLenQ[TxQTail] = length;
TxQTail++;
TxQTail &= 0x3f;
}
OS_ENTER_CRITICAL();
if(chrCOMBusy == FALSE){
OS_EXIT_CRITICAL();
intCurTxNum = TxLenQ[TxQHead];
pCurTxHead = pTxQ[TxQHead];
chrCOMBusy = TRUE;
PIE1bits.TXIE = 1;
}
OS_EXIT_CRITICAL();
}
void Func_Transmit_ISR(void){
unsigned char i;
RCSTAbits.OERR = 0;
RCSTAbits.FERR = 0;
if(PIR1bits.TXIF){//May be the TX is not enabled
if (intCurTxNum != 0){
TXREG = *pCurTxHead++;
intCurTxNum --;
}
else{
PIE1bits.TXIE = 0; //Close transmit interrupt
chrCOMBusy = FALSE;
if(TxQHead != TxQTail){
OSMemPut(TxTypeQ[TxQHead],pTxQ[TxQHead]);
TxQHead++;
TxQHead &= 0x3f;
if(TxQTail != TxQHead){
intCurTxNum = TxLenQ[TxQHead];
pCurTxHead = pTxQ[TxQHead];
chrCOMBusy = TRUE;
PIE1bits.TXIE = 1;
}
}
}
}
PIR1bits.TXIF = 0;
}
void Func_INT2_ISR(void){
INTCON3bits.INT2F = 0;
INTCONbits.GIEH = 0;
if(CurRxNum != 0){
INTCONbits.GIEH = 1;
pMemT = OSMemGet(pMemLge, &erri);
if(erri != OS_NO_ERR) {
INTCONbits.GIEH = 0;
CurRxNum = 0;
pCurRxTail = pCurRxHead;
INTCONbits.GIEH = 1;
return;
}
pMemT2 = OSMemGet(pMemSml, &erri);
if(erri != OS_NO_ERR) {
INTCONbits.GIEH = 0;
CurRxNum = 0;
pCurRxTail = pCurRxHead;
INTCONbits.GIEH = 1;
return;
}
INTCONbits.GIEH = 0;
intTemp1 = CurRxNum;
ptrTemp2 = pCurRxHead;
CurRxNum = 0;
pCurRxTail = pMemT;
pCurRxHead = pMemT;
INTCONbits.GIEH = 1;
//make the message and send it
if(ComCurStt == S_DEBUG){
((MSG_HEAD *)pMemT2)->Msg_ID = MSG_DEBUG_RECEIVE;
}
else{
((MSG_HEAD *)pMemT2)->Msg_ID = MSG_MODULE_RECEIVE;
}
((MSG_HEAD *)pMemT2)->Origin = peventHardware;
((MSG_HEAD *)pMemT2)->pmemME = pMemSml;
((MSG_HEAD *)pMemT2)->Attached = TRUE;
((MSG_HEAD *)pMemT2)->LenOfAttach = intTemp1;
((MSG_HEAD *)pMemT2)->pMem = ptrTemp2;
((MSG_HEAD *)pMemT2)->pmemATT = pMemLge;
((MSG_HEAD *)pMemT2)->LenOfBody = 0;
if(ComCurStt == S_DEBUG){
OSQPost(peventDEBUG, pMemT2);
}
else{
if(ModuleMod == MOD_DATA)
OSQPost(peventPPPReceiver, pMemT2);
else
OSQPost(peventWICResp, pMemT2);
}
//for test
}
INTCONbits.GIEH = 1;
}
void Func_TMR0_ISR(void){
INTCONbits.TMR0IE = 0;
INTCONbits.TMR0IF = 0;
T0CONbits.TMR0ON = 0;
INTCONbits.GIEH = 0;
if(CurRxNum) INTCON3bits.INT2F = 1;
INTCONbits.GIEH = 1;
}
//Serial port receive ISR, called from high priority interrupt.
//contains two parts, one for receive and one for time out.
//the data received is handled by the INT2 ISR in the low
//priority ISR
void Func_Receive_ISR(void){
if(PIR1bits.RCIF){
PIR1bits.RCIF = 0;
*pCurRxTail++ = RCREG;
CurRxNum ++;
TMR0H = RXTIMEOUTH;
TMR0L = RXTIMEOUTL;
T0CONbits.TMR0ON = 1;
INTCONbits.TMR0IE = 1;
if(CurRxNum >= RXTHREHOLD) INTCON3bits.INT2F = 1;
}
RCSTAbits.OERR = 0;
RCSTAbits.FERR = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -