dsPid33
|
00001 /* //////////////////////////////////////////////////////////////////////////// 00002 ** It contains all functions related to communication 00003 ** 00004 ** Detailed description are on file "descrEng.txt" 00005 ** numbers between brackets, eg.: [1] , are the references to the specific 00006 ** decription into the file 00008 00009 // standard includes 00010 #include "dsPID33_common.h" 00011 #include "com.h" 00012 00013 // DMA buffers 00014 unsigned char UartTxBuff[MAX_TX_BUFF] __attribute__((space(dma),aligned(128))); 00015 unsigned char Uart2TxBuff[MAX_TX2_BUFF] __attribute__((space(dma),aligned(128))); 00016 00017 void UsartSetting(void) 00018 { 00019 /*---------------------------------------------------------------------------*/ 00020 /* USART1 [6] */ 00021 /*---------------------------------------------------------------------------*/ 00022 float BaudRate; 00023 float BRG; 00024 /* Baud Rate = Fcy / ( 4 * (UxBRG + 1) ) with BRGH = 1 00025 value for the U1BRG register rounded to closest integer (+0.5) 00026 */ 00027 BaudRate = 57600; // desired baud rate 00028 BRG = (FCY/(4*(BaudRate)))-0.5; 00029 00030 /*...............................................................DMA UART TX */ 00031 // Associate DMA Channel 6 with UART Tx 00032 DMA6REQ = 0x000c; // Select UART1 Transmitter 00033 DMA6PAD = (volatile unsigned int) &U1TXREG; 00034 00035 DMA6CONbits.SIZE = 1; // Transfer bytes 00036 DMA6CONbits.DIR = 1; // Transfer data from RAM to UART 00037 DMA6CONbits.HALF = 0; // Interrupt when all of the data has been moved 00038 DMA6CONbits.AMODE = 0; // Register Indirect with Post-Increment 00039 DMA6CONbits.MODE = 1; // One-Shot mode 00040 00041 //DMA6CNT = 31; // # of DMA requests 00042 00043 // Associate one buffer with Channel 6 for one-shot operation 00044 DMA6STA = __builtin_dmaoffset(UartTxBuff); 00045 00046 // Enable DMA Interrupts 00047 IFS4bits.DMA6IF = 0; // Clear DMA Interrupt Flag 00048 IEC4bits.DMA6IE = 1; // Enable DMA interrupt 00049 /*...............................................................DMA UART TX */ 00050 00051 /*.....................................................................USART */ 00052 U1MODEbits.STSEL = 0; // 1-stop bit 00053 U1MODEbits.PDSEL = 0; // No Parity, 8-data bits 00054 U1MODEbits.ABAUD = 0; // Autobaud Disabled 00055 U1MODEbits.RTSMD = 1; // No flow control 00056 U1MODEbits.BRGH = 1; // Hi speed 00057 U1BRG = BRG; // BAUD Rate Setting 00058 00059 // Configure UART for DMA transfers 00060 U1STAbits.UTXISEL0 = 0; // Interrupt after one Tx character is transmitted 00061 U1STAbits.UTXISEL1 = 0; 00062 U1STAbits.URXISEL = 0; // Interrupt after one RX character is received 00063 00064 // Enable UART Rx and Tx 00065 U1MODEbits.UARTEN = 1; // Enable UART 00066 U1STAbits.UTXEN = 1; // Enable UART Tx 00067 IEC4bits.U1EIE = 0; 00068 _U1RXIF = 0; // Reset RX interrupt flag 00069 _U1RXIE = 1; // Enable RX interrupt 00070 00071 UartRxStatus = 0; 00072 ChkSum=0; 00073 00074 /*.....................................................................USART */ 00075 } 00076 00077 void Usart2Setting(void) 00078 { 00079 /*---------------------------------------------------------------------------*/ 00080 /* USART2 [6z] */ 00081 /*---------------------------------------------------------------------------*/ 00082 float BaudRate2; 00083 float BRG2; 00084 00085 /* Baud Rate = Fcy / ( 4 * (UxBRG + 1) ) with BRGH = 1 00086 value for the U2BRG register rounded to closest integer (+0.5) 00087 */ 00088 BaudRate2 = 115200; // desired baud rate 00089 BRG2 = (FCY/(4*(BaudRate2)))-0.5; 00090 00091 /*..............................................................DMA UART2 TX */ 00092 // Associate DMA Channel 5 with UART2 Tx 00093 DMA5REQ = 0x003f; // Select UART2 Transmitter 00094 DMA5PAD = (volatile unsigned int) &U2TXREG; 00095 00096 DMA5CONbits.SIZE = 1; // Transfer bytes 00097 DMA5CONbits.DIR = 1; // Transfer data from RAM to UART 00098 DMA5CONbits.HALF = 0; // Interrupt when all of the data has been moved 00099 DMA5CONbits.AMODE = 0; // Register Indirect with Post-Increment 00100 DMA5CONbits.MODE = 1; // One-Shot mode 00101 00102 //DMA5CNT = 31; // # of DMA requests 00103 00104 // Associate one buffer with Channel 5 for one-shot operation 00105 DMA5STA = __builtin_dmaoffset(Uart2TxBuff); 00106 00107 // Enable DMA Interrupts 00108 IFS3bits.DMA5IF = 0; // Clear DMA Interrupt Flag 00109 IEC3bits.DMA5IE = 1; // Enable DMA interrupt 00110 /*..............................................................DMA UART2 TX */ 00111 00112 /*....................................................................USART2 */ 00113 U2MODEbits.STSEL = 0; // 1-stop bit 00114 U2MODEbits.PDSEL = 0; // No Parity, 8-data bits 00115 U2MODEbits.ABAUD = 0; // Autobaud Disabled 00116 U2MODEbits.RTSMD = 1; // No flow control 00117 U2MODEbits.BRGH = 1; // Hi speed 00118 U2BRG = BRG2; // BAUD Rate Setting 00119 00120 // Configure UART2 for DMA transfers 00121 U2STAbits.UTXISEL0 = 0; // Interrupt after one Tx character is transmitted 00122 U2STAbits.UTXISEL1 = 0; 00123 U2STAbits.URXISEL = 0; // Interrupt after one RX character is received 00124 00125 // Enable UART2 Rx and Tx 00126 U2MODEbits.UARTEN = 1; // Enable UART 00127 U2STAbits.UTXEN = 1; // Enable UART Tx 00128 IEC4bits.U2EIE = 0; 00129 _U2RXIF = 0; // Reset RX interrupt flag 00130 _U2RXIE = 1; // Enable RX interrupt 00131 00132 Uart2RxStatus = 0; 00133 ChkSum2=0; 00134 00135 /*.....................................................................USART */ 00136 } 00137 00138 void TxParameters(char TxCmd,int TxCmdLen, int Port) // [18] 00139 { 00140 int TxCount; 00141 unsigned int UartTxBuffSize=0; 00142 00143 if (Port==0) 00144 { 00145 UartTxBuff[0] = '@'; // Header 00146 UartTxBuff[1] = Id; // Id 00147 UartTxBuff[2] = TxCmd; // Cmd 00148 UartTxBuff[3] = TxCmdLen +1; // CmdLen 00149 for (TxCount = 0; TxCount < TxCmdLen; TxCount ++) 00150 { 00151 UartTxBuff[TxCount + 4] = UartTmpBuff[TxCount][Port]; 00152 } 00153 UartTxBuff[TxCount + 4] = UartChkSum(UartTxBuff,TxCount + 4); 00154 UartTxBuffSize = TxCount + 5; 00155 00156 DMA6CNT = UartTxBuffSize-1; // # of DMA requests 00157 DMA6CONbits.CHEN = 1; // Re-enable DMA Channel 00158 DMA6REQbits.FORCE = 1; // Manual mode: Kick-start the first transfer 00159 } 00160 else 00161 { 00162 Uart2TxBuff[0] = '@'; // Header 00163 Uart2TxBuff[1] = Id; // Id 00164 Uart2TxBuff[2] = TxCmd; // Cmd 00165 Uart2TxBuff[3] = TxCmdLen +1; // CmdLen 00166 for (TxCount = 0; TxCount < TxCmdLen; TxCount ++) 00167 { 00168 Uart2TxBuff[TxCount + 4] = UartTmpBuff[TxCount][Port]; 00169 } 00170 Uart2TxBuff[TxCount + 4] = UartChkSum(Uart2TxBuff,TxCount + 4); 00171 UartTxBuffSize = TxCount + 5; 00172 00173 DMA5CNT = UartTxBuffSize-1; // # of DMA requests 00174 DMA5CONbits.CHEN = 1; // Re-enable DMA Channel 00175 DMA5REQbits.FORCE = 1; // Manual mode: Kick-start the first transfer 00176 } 00177 } 00178 00179 void UartRx(void) // [6b] 00180 { 00181 if (UartRxStatus < 0) // if error, RX is terminated 00182 { 00183 UartRxError(UartRxStatus,0); 00184 } 00185 else // otherwise it analyzes status 00186 { 00187 switch (UartRxStatus) 00188 { 00189 case 0: // idle 00190 if (UartRxBuff[UartRxPtrOut][0] == HEADER) 00191 { 00192 UartRxStatus = 1; // next status 00193 UartRxPtrStart = UartRxPtrOut; 00194 ChkSum = ChkSum + UartRxBuff[UartRxPtrOut][0]; 00195 UartRxPtrOut ++; // next byte 00196 } 00197 else // out of command sequence -> error 00198 { 00199 UartRxError(-5,0); 00200 } 00201 break; 00202 00203 case 1: // header received 00204 if(UartRxBuff[UartRxPtrOut][0]==Id||UartRxBuff[UartRxPtrOut][0]==0) 00205 {// command addressed to this board or broadcast 00206 // Id received and recognized 00207 RX_ID_FLAG = 1; // it has to decode the command 00208 UartRxStatus = 2; // next status 00209 } 00210 else if (UartRxBuff[UartRxPtrOut][0] == 'z') // 00211 { 00212 UartRxStatus=99; // enables command parser 00213 UartRxCmd[0]=UartRxBuff[UartRxPtrOut][0]; 00214 } 00215 else 00216 { 00217 // Id received but NOT recognized 00218 RX_ID_FLAG = 0; // receives but does not decode the command 00219 UartRxStatus = 2; // next status 00220 } 00221 ChkSum = ChkSum + UartRxBuff[UartRxPtrOut][0]; 00222 UartRxPtrOut ++; // next byte 00223 break; 00224 00225 case 2: // command received 00226 UartRxStatus = 3; // next status 00227 UartRxCmd[0]=UartRxBuff[UartRxPtrOut][0]; 00228 ChkSum = ChkSum + UartRxBuff[UartRxPtrOut][0]; 00229 UartRxPtrOut ++; // next byte 00230 break; 00231 00232 case 3: // command length received 00233 // calculating end pointer of command string 00234 UartRxPtrEnd=UartRxBuff[UartRxPtrOut][0]+RX_HEADER_LEN+ 00235 UartRxPtrStart; 00236 if (UartRxPtrEnd >= MAX_RX_BUFF)UartRxPtrEnd -= MAX_RX_BUFF; 00237 if (UartRxPtrEnd >= MAX_RX_BUFF) // still bigger? 00238 { 00239 UartRxError(-11,0); // queue overflow 00240 } 00241 else 00242 { 00243 UartRxStatus = 4; // next status 00244 ChkSum = ChkSum + UartRxBuff[UartRxPtrOut][0]; 00245 UartRxPtrData=UartRxPtrOut;// pointer to last header byte 00246 UartRxPtrOut ++; // next byte 00247 } 00248 break; 00249 00250 case 4: // waiting for command end 00251 if (UartRxPtrOut == UartRxPtrEnd) 00252 { 00253 if (ChkSum == UartRxBuff[UartRxPtrOut][0])// checksum OK? 00254 { 00255 if (RX_ID_FLAG) // if right Id 00256 { 00257 UartRxStatus=99;// enables command parser 00258 UartRxPtrOut ++; // next byte 00259 } 00260 else 00261 { 00262 UartRxStatus=0; // end of command receive 00263 UartRxPtrOut ++; // next byte 00264 } 00265 } 00266 else 00267 { 00268 UartRxError(-1,0); // checksum error 00269 } 00270 ChkSum=0; 00271 } 00272 else 00273 { 00274 ChkSum = ChkSum + UartRxBuff[UartRxPtrOut][0]; 00275 UartRxPtrOut ++; // next byte 00276 } 00277 break; 00278 00279 default:// error: not a known status 00280 UartRxError(-6,0); 00281 break; 00282 } // switch end 00283 } // if end 00284 00285 if (UartRxPtrOut >= MAX_RX_BUFF) UartRxPtrOut=0;//reset circular queue [6d] 00286 } 00287 00288 void Uart2Rx(void) // [6zb] 00289 { 00290 if (Uart2RxStatus < 0) // if error, RX is terminated 00291 { 00292 UartRxError(Uart2RxStatus,1); 00293 } 00294 else // otherwise it analyzes status 00295 { 00296 switch (Uart2RxStatus) 00297 { 00298 case 0: // idle 00299 if (UartRxBuff[Uart2RxPtrOut][1] == HEADER) 00300 { 00301 Uart2RxStatus = 1; // next status 00302 Uart2RxPtrStart = Uart2RxPtrOut; 00303 ChkSum2 = ChkSum2 + UartRxBuff[Uart2RxPtrOut][1]; 00304 Uart2RxPtrOut ++; // next byte 00305 } 00306 else // out of command sequence -> error 00307 { 00308 UartRxError(-105,1); 00309 } 00310 break; 00311 00312 case 1: // header received 00313 if(UartRxBuff[Uart2RxPtrOut][1]==Id || 00314 UartRxBuff[Uart2RxPtrOut][1]==0) 00315 {// command addressed to this board or broadcast 00316 // Id received and recognized 00317 RX2_ID_FLAG = 1; // it has to decode the command 00318 Uart2RxStatus = 2; // next status 00319 } 00320 else if (UartRxBuff[Uart2RxPtrOut][1] == 'z') // 00321 { 00322 Uart2RxStatus=99; // enables command parser 00323 UartRxCmd[1]=UartRxBuff[Uart2RxPtrOut][1]; 00324 } 00325 else 00326 { 00327 // Id received but NOT recognized 00328 RX2_ID_FLAG = 0; // receives but does not decode the command 00329 Uart2RxStatus = 2; // next status 00330 } 00331 ChkSum2 = ChkSum2 + UartRxBuff[Uart2RxPtrOut][1]; 00332 Uart2RxPtrOut ++; // next byte 00333 break; 00334 00335 case 2: // command received 00336 Uart2RxStatus = 3; // next status 00337 UartRxCmd[1]=UartRxBuff[Uart2RxPtrOut][1]; 00338 ChkSum2 = ChkSum2 + UartRxBuff[Uart2RxPtrOut][1]; 00339 Uart2RxPtrOut ++; // next byte 00340 break; 00341 00342 case 3: // command length received 00343 // calculating end pointer of command string 00344 Uart2RxPtrEnd=UartRxBuff[Uart2RxPtrOut][1]+RX_HEADER_LEN+ 00345 Uart2RxPtrStart; 00346 if (Uart2RxPtrEnd >= MAX_RX_BUFF)Uart2RxPtrEnd -= MAX_RX_BUFF; 00347 if (Uart2RxPtrEnd >= MAX_RX_BUFF) // still bigger? 00348 { 00349 UartRxError(-111,1); // queue overflow 00350 } 00351 else 00352 { 00353 Uart2RxStatus = 4; // next status 00354 ChkSum2 = ChkSum2 + UartRxBuff[Uart2RxPtrOut][1]; 00355 Uart2RxPtrData=Uart2RxPtrOut;// pointer to last header byte 00356 Uart2RxPtrOut ++; // next byte 00357 } 00358 break; 00359 00360 case 4: // waiting for command end 00361 if (Uart2RxPtrOut == Uart2RxPtrEnd) 00362 { 00363 if (ChkSum2 == UartRxBuff[Uart2RxPtrOut][1])// checksum OK? 00364 { 00365 if (RX2_ID_FLAG) // if right Id 00366 { 00367 Uart2RxStatus=99;// enables command parser 00368 Uart2RxPtrOut ++; // next byte 00369 } 00370 else 00371 { 00372 Uart2RxStatus=0; // end of command receive 00373 Uart2RxPtrOut ++; // next byte 00374 } 00375 } 00376 else 00377 { 00378 UartRxError(-101,1); // checksum error 00379 } 00380 ChkSum2=0; 00381 } 00382 else 00383 { 00384 ChkSum2 = ChkSum2 + UartRxBuff[Uart2RxPtrOut][1]; 00385 Uart2RxPtrOut ++; // next byte 00386 } 00387 break; 00388 00389 default:// error: not a known status 00390 UartRxError(-106,1); 00391 break; 00392 } // switch end 00393 } // if end 00394 00395 //reset circular queue [6zd] 00396 if (Uart2RxPtrOut >= MAX_RX_BUFF) Uart2RxPtrOut=0; 00397 } 00398 00399 unsigned char UartChkSum (unsigned char *Buff,unsigned int BuffSize) // [17] 00400 { 00401 unsigned char ChkSum=0; // checksum 00402 int ChkIndx; 00403 for (ChkIndx = 0; ChkIndx < BuffSize; ChkIndx ++) 00404 { 00405 ChkSum = ChkSum + Buff[ChkIndx]; 00406 } 00407 00408 return (ChkSum); 00409 } 00410 00411 void UartRxError(int Err, int Port) // RX error occured 00412 { 00413 BlinkPeriod = ERR_BLINK_PER;// LED1 blinking period (ms) 00414 BlinkOn = ERR_BLINK_ON; // LED1 on time (ms) 00415 Blink = 0; 00416 00417 if (Port==0) 00418 { 00419 UartRxPtrOut=0; // flush circular queue 00420 UartRxPtrIn=0; 00421 UartRxPtrEnd=0; 00422 UartRxStatus=0; 00423 ChkSum=0; 00424 while (U1STAbits.URXDA) // flush USART RX buffer 00425 { 00426 ReadUART1(); 00427 } 00428 } 00429 else 00430 { 00431 Uart2RxPtrOut=0; // flush circular queue 00432 Uart2RxPtrIn=0; 00433 Uart2RxPtrEnd=0; 00434 Uart2RxStatus=0; 00435 ChkSum2=0; 00436 while (U2STAbits.URXDA) // flush USART RX buffer 00437 { 00438 ReadUART2(); 00439 } 00440 } 00441 00442 // **debug** 00443 ErrNo[abs(Err)]++; // error log 00444 // **debug** 00445 ErrCode=Err; // store the last Error Code 00446 } 00447 00448 unsigned char IncrCircPtr(int Port) // [6d] 00449 { 00450 if (Port==0) 00451 { 00452 TmpPtr ++; // next byte 00453 if (TmpPtr >= MAX_RX_BUFF) TmpPtr=0; //reset circular queue 00454 return TmpPtr; 00455 } 00456 else 00457 { 00458 TmpPtr2 ++; // next byte 00459 if (TmpPtr2 >= MAX_RX_BUFF) TmpPtr2=0; //reset circular queue 00460 return TmpPtr2; 00461 } 00462 } 00463 00464 /*---------------------------------------------------------------------------*/ 00465 /* Interrupt Service Routines */ 00466 /*---------------------------------------------------------------------------*/ 00467 00468 void _ISR_PSV _U1RXInterrupt(void) // UART RX [6b] 00469 { 00470 _U1RXIF = 0; // interrupt flag reset 00471 ClrWdt(); // [1] 00472 // UART errors or still parsing command ? 00473 if (!OVERRUN_ERROR && !FRAME_ERROR && UartRxStatus!=99) 00474 { 00475 UartRxBuff[UartRxPtrIn][0] = ReadUART1(); // fills RX queue 00476 UartRxPtrIn ++; // next byte 00477 if (UartRxPtrIn>=MAX_RX_BUFF) UartRxPtrIn=0;//reset circ queue[6d] 00478 } 00479 else 00480 { 00481 // indicates the error kind [6b] 00482 if (OVERRUN_ERROR) 00483 { 00484 UartRxStatus = -4; 00485 OVERRUN_ERROR = 0; // error reset & flush RX buffer 00486 } 00487 if (FRAME_ERROR) UartRxStatus = -3; 00488 if (UartRxStatus==99) UartRxStatus = -9; 00489 UartRxPtrIn ++; // start RX routine to analyze error 00490 if (UartRxPtrIn>=MAX_RX_BUFF) UartRxPtrIn=0;//reset circ queue[6d] 00491 } 00492 } 00493 00494 void _ISR_PSV _U2RXInterrupt(void) // UART2 RX [6zb] 00495 { 00496 _U2RXIF = 0; // interrupt flag reset 00497 ClrWdt(); // [1] 00498 // UART2 errors or still parsing command ? 00499 if (!OVERRUN_ERROR2 && !FRAME_ERROR2 && Uart2RxStatus!=99) 00500 { 00501 UartRxBuff[Uart2RxPtrIn][1] = ReadUART2(); // fills RX queue 00502 Uart2RxPtrIn ++; // next byte 00503 if (Uart2RxPtrIn>=MAX_RX_BUFF) Uart2RxPtrIn=0;//reset circ queue[6zd] 00504 } 00505 else 00506 { 00507 // indicates the error kind [6zb] 00508 if (OVERRUN_ERROR2) 00509 { 00510 Uart2RxStatus = -4; 00511 OVERRUN_ERROR2 = 0; // error reset & flush RX buffer 00512 } 00513 if (FRAME_ERROR2) Uart2RxStatus = -3; 00514 if (Uart2RxStatus==99) Uart2RxStatus = -9; 00515 Uart2RxPtrIn ++; // start RX routine to analyze error 00516 if (Uart2RxPtrIn>=MAX_RX_BUFF) Uart2RxPtrIn=0;//reset circ queue[6zd] 00517 } 00518 }