dsPid33
src/com.c
Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Defines