|
- /*******************************************************************************
- * *
- * Copyright 2010 Rheinmetall Canada Inc. *
- * *
- * No part of this document may be reproduced, stored in *
- * a retrieval system, or transmitted, in any form or by any means, *
- * electronic, mechanical, photocopying, recording, or otherwise, *
- * without the prior written permission of Rheinmetall Canada Inc. *
- * *
- *******************************************************************************/
- /*
- Description:
- This is a template file for standard C code file.
-
- */
-
- /* ************************************************************************** */
- /* ¤Revision:
- 000 20100616 JFM,
- Original version.
-
- ### YYYYMMDD Initial, Bug Identification
- Change description.
- */
-
- /* ************************************************************************** */
- /* Includes */
- #include "define.h"
- #include "Uart.h"
- #include "Internaluart.h"
- #include <stdio.h>
- #include <string.h>
- //#include "Watchdog.h"
-
- #ifndef NO_EXTERNAL_UART
- #include "sc16IS740Driver.h"
- #endif
-
- #include "digitalio.h"
- //#include "DriveProtocol.h"
- #include "terminal.h"
- #include "SIM7080GInterface.h"
-
-
-
- /* ************************************************************************** */
- /* Local variables */
-
- stUartData astUartData[MAX_UART_HANDLE];
-
- const char *gUartStrings[MAX_UART_HANDLE] = { "LORA" //UART_1
- ,"LTE", //UART_5
- // ,"CONSOLE" //UART_3
- };
-
- /* ************************************************************************** */
- /* Private function prototypes */
- //void _mon_putc(char c); //override from stdio to redirect stdout on uart 3B
- //void _mon_write (const char * s, unsigned int count);
-
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- void InitUart(void)
- {
- int i;
-
- InternalUartInit();
- //InitSC16S740();
-
- memset(&astUartData,0,sizeof(astUartData));
-
- for(i = 0; i < MAX_UART_HANDLE; i++)
- {
- astUartData[i].iDataPending = 0; //This flag is 0 when : TxPtr == RxPtr OR Uart is transmitting.
- astUartData[i].pcTxInPtr = &astUartData[i].acTxCircularBuffer[0];
- astUartData[i].pcTxOutPtr = &astUartData[i].acTxCircularBuffer[0];
- //memset(&astUartData[i].acTxCircularBuffer[0],0xDE,UART_MAX_TX_BUFF_SIZE);
-
- astUartData[i].pcRxInDataPtr = astUartData[i].pcRxOutDataPtr = &astUartData[i].acRxCircularBuffer[0];
- astUartData[i].iNbRxFIFOPendingBytes = 0;
- }
-
-
- //This is a physical mapping of the UARTS.
- //DO NOT CHANGE assignments unless hardware changed !
- //
- astUartData[UART_1].iIsInternal = 1;
- astUartData[UART_1].iPhysicalUartPort = INTERNAL_UART_PORT_2; // (232)
-
- astUartData[UART_2].iIsInternal = 1;
- astUartData[UART_2].iPhysicalUartPort = INTERNAL_UART_PORT_5; // (232)
-
- #ifndef NO_EXTERNAL_UART
- astUartData[UART_3].iIsInternal = 0;
- astUartData[UART_3].iPhysicalUartPort = EXT_UART_1; // (SPI - 232 daughter board)
- #endif
-
- setbuf(stdout,NULL); //to use printf without \r
- fflush(stdout);
-
- UartOpenComPort(NETWORK_UART_PORT,9600,UART_ONE_STOP_BIT,UART_NO_PARITY); //Open LoRa module port
- UartOpenComPort(LTE_IF_UART_PORT,115200,UART_ONE_STOP_BIT,UART_NO_PARITY); //Open LTE module port
- #ifdef USE_PRINTF
- //UartOpenComPort(CONSOLE_UART_PORT,115200,UART_ONE_STOP_BIT,UART_NO_PARITY); //Open console port
-
- #endif
-
- }
-
- //-----------------------------------------------------------------------------
-
- int UartResetPort(int p_iUartHandle)
- {
- if(p_iUartHandle > MAX_UART_HANDLE)
- return 0;
-
- //reset the port data structures...
- astUartData[p_iUartHandle].iDataPending = 0; //This flag is 0 when : TxPtr == RxPtr OR Uart is transmitting.
- astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
- astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
- astUartData[p_iUartHandle].pcRxInDataPtr = astUartData[p_iUartHandle].pcRxOutDataPtr = &astUartData[p_iUartHandle].acRxCircularBuffer[0];
- astUartData[p_iUartHandle].iNbRxFIFOPendingBytes = 0;
-
- if(astUartData[UART_1].iIsInternal == 1)
- {
- switch(astUartData[p_iUartHandle].iPhysicalUartPort)
- {
- case INTERNAL_UART_PORT_1:
- {
- ResetUart1();
- break;
- }
- case INTERNAL_UART_PORT_2:
- {
- ResetUart2();
- break;
- }
- case INTERNAL_UART_PORT_5:
- {
- ResetUart5();
- break;
- }
-
- default:
- break;
- }
- }
- else
- {
- #ifndef NO_EXTERNAL_UART
- switch(astUartData[p_iUartHandle].iPhysicalUartPort)
- {
- case EXT_UART_1:
- {
- break;
- }
- default:
- break;
- }
- #endif
- }
-
- return 1;
- }
-
- //-----------------------------------------------------------------------------
- int UartOpenComPort(int p_iUartHandle, int p_iBaudRate, int p_iNbStopBits, int p_iParityEnable)
- {
- int iStopbits,iParity,iRet;
- if(p_iUartHandle >= MAX_UART_HANDLE || p_iUartHandle < 0)
- return UART_INVALID_HANDLE;
-
- if(astUartData[p_iUartHandle].iIsInternal == 1)
- {
- switch(p_iNbStopBits)
- {
- case UART_ONE_STOP_BIT:
- case UART_ONE_HALF_STOP_BIT: //1½ stop bits doesn't exist for internal uart
- {
- iStopbits = INT_UART_ONE_STOP_BIT;
- break;
- }
- case UART_TWO_STOP_BITS:
- {
- iStopbits = INT_UART_TWO_STOP_BITS;
- break;
- }
- }
-
- switch(p_iParityEnable)
- {
- case UART_NO_PARITY:
- {
- iParity = INT_UART_NO_PARITY;
- break;
- }
- case UART_EVEN_PARITY:
- {
- iParity = INT_UART_EVEN_PARITY;
- break;
- }
- case UART_ODD_PARTIY:
- {
- iParity = INT_UART_ODD_PARITY;
- break;
- }
- }
-
- iRet = OpenInternalPort(astUartData[p_iUartHandle].iPhysicalUartPort,
- p_iUartHandle,
- &astUartData[p_iUartHandle].acTxCircularBuffer[0],
- &astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1],
- p_iBaudRate,
- iStopbits,
- iParity);
- }
- #ifndef NO_EXTERNAL_UART
- else
- {
- switch(p_iNbStopBits)
- {
- case UART_ONE_STOP_BIT:
- {
- iStopbits = ONE_STOP_BIT;
- break;
- }
- case UART_ONE_HALF_STOP_BIT: //1½ stop bits doesn't exist for internal uart
- {
- iStopbits = ONE_HALF_STOP_BIT;
- break;
- }
- case UART_TWO_STOP_BITS:
- {
- iStopbits = TWO_STOP_BITS;
- break;
- }
- }
-
- switch(p_iParityEnable)
- {
- case UART_NO_PARITY:
- {
- iParity = NO_PARITY;
- break;
- }
- case UART_EVEN_PARITY:
- {
- iParity = EVEN_PARITY;
- break;
- }
- case UART_ODD_PARTIY:
- {
- iParity = ODD_PARITY;
- break;
- }
- }
-
- iRet = OpenExternalPort(astUartData[p_iUartHandle].iPhysicalUartPort,
- p_iUartHandle,
- &astUartData[p_iUartHandle].acTxCircularBuffer[0],
- &astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1],
- p_iBaudRate,
- iStopbits,
- iParity);
- }
- #endif
-
- return iRet;
- }
-
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- //All the uart callback function assignment must be done here !!!
- //This must be changed if hardware changes or if port assignment is changed !!!
- //
- int UartReceiveData(int p_iUartHandle, char *p_pcBuffer, int p_iSize)
- {
- int i;
- stUartData *p_stUartDatPtr = &astUartData[p_iUartHandle];
-
- if(p_iUartHandle < 0 && p_iUartHandle >= MAX_UART_HANDLE)
- {
- //TODO: Flag a logic error !
- return 0;
- }
-
- for(i = 0; i < p_iSize; i++)
- {
- *p_stUartDatPtr->pcRxInDataPtr++ = *p_pcBuffer++;
- if(p_stUartDatPtr->pcRxInDataPtr > &p_stUartDatPtr->acRxCircularBuffer[UART_MAX_RX_BUFF_SIZE-1])
- {
- p_stUartDatPtr->pcRxInDataPtr = &p_stUartDatPtr->acRxCircularBuffer[0]; //wrap pointer
- // printf("Wrap\n");
- }
- }
- p_stUartDatPtr->iNbRxFIFOPendingBytes += p_iSize;
-
- if(p_stUartDatPtr->iNbRxFIFOPendingBytes >= UART_MAX_RX_BUFF_SIZE)
- PRINTF("RX FIFO Overflow\n");
-
-
- /* switch(p_iUartHandle)
- {
- case UART_0:
- {
- break;
- }
- case UART_1:
- {
- break;
- }
- case UART_2:
- {
- break;
- }
- case UART_3:
- {
- break;
- }
- case UART_4:
- {
- break;
- }
- case UART_5:
- {
- break;
- }
- } */
- return 1;
- }
-
- int UartGetPendingDataSize(int iUartHandle)
- {
- stUartData *p_stUartDatPtr = &astUartData[iUartHandle];
-
- if(p_stUartDatPtr->pcRxInDataPtr == p_stUartDatPtr->pcRxOutDataPtr)
- {
- return 0;
- }
- else if(p_stUartDatPtr->pcRxOutDataPtr < p_stUartDatPtr->pcRxInDataPtr)
- {
- return(p_stUartDatPtr->pcRxInDataPtr - p_stUartDatPtr->pcRxOutDataPtr);
- }
- else
- {
- int size = &p_stUartDatPtr->acRxCircularBuffer[UART_MAX_RX_BUFF_SIZE-1] - p_stUartDatPtr->pcRxOutDataPtr;
- size += p_stUartDatPtr->pcRxInDataPtr - &p_stUartDatPtr->acRxCircularBuffer[0];
- return size;
- }
- }
-
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- int UartTransmitData(int p_iUartHandle, char *p_pcBuffer, int p_iSize)
- {
- int iRet = 0;
-
- // Case where OutPtr < InPtr
- // * = Available space
- //
- //Top ---->|---------------|
- // | * |
- //OutPtr ->| |
- // | |
- // | (p_pcBuffer) | //Available size = (OutPtr - Top) + (Bottom - InPtr)
- // | |
- //InPtr -->| |
- // | * |
- // | * |
- //Bottom ->|---------------|
-
-
- // Case where OutPtr > InPtr
- // * = Available space
- //
- //Top ---->|---------------|
- // | |
- //InPtr -->| |
- // | * |
- // | * | //available size = OutPtr - InPtr
- // | * |
- //OutPtr ->| |
- // | (p_pcBuffer) |
- // | |
- //Bottom ->|---------------|
-
-
- //Check if data buffer fits in remaining circular buffer space
- if(astUartData[p_iUartHandle].pcTxOutPtr < astUartData[p_iUartHandle].pcTxInPtr)
- {
- //Calculate remaining buffer space and check if it's enough to fit requested data buffer
- if(p_iSize > ((astUartData[p_iUartHandle].pcTxOutPtr - &astUartData[p_iUartHandle].acTxCircularBuffer[0]) + //Outptr - Top
- (&astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1] - astUartData[p_iUartHandle].pcTxInPtr))) //Bottom - Inptr
- {
- //Drop remaining packets, flush buffer
- astUartData[p_iUartHandle].iDataPending = 0;
- astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
- astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
- return UART_BUFFER_FULL;
- }
- }
- else if(astUartData[p_iUartHandle].pcTxInPtr < astUartData[p_iUartHandle].pcTxOutPtr)
- {
- //Calculate remaining buffer space and check if it's enough to fit requested data buffer
- if(p_iSize > (astUartData[p_iUartHandle].pcTxOutPtr - astUartData[p_iUartHandle].pcTxInPtr))
- {
- //Drop remaining packets, flush buffer
- astUartData[p_iUartHandle].iDataPending = 0; //Force data pending flag to flush buffer
- astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
- astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
- return UART_BUFFER_FULL;
- }
- }
- else //OutPtr = InPtr
- {
- if(p_iSize > UART_MAX_TX_BUFF_SIZE - 1) //message is too big to fit in buffer !!!
- {
- //Drop remaining packets, flush buffer
- astUartData[p_iUartHandle].iDataPending = 0; //Force data pending flag to flush buffer
- astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
- astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
-
- return UART_BUFFER_FULL;
- }
- }
-
- int i;
-
-
- for(i = 0; i < p_iSize; i++)
- {
- *astUartData[p_iUartHandle].pcTxInPtr++ = *p_pcBuffer++; //fill circular buffer
-
- if(astUartData[p_iUartHandle].pcTxInPtr > &astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1]) //check for wrapping
- {
- astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
- }
- }
-
- //Now flag pending data for transmission.
- astUartData[p_iUartHandle].iDataPending = 1; //The data send will start on next Main loop processing
-
-
- return iRet;
- }
-
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- //Some data has been entirely sent
- //Move output pointer
- //
- int DataSentNotification(int p_iUartHandle,int DataSize)
- {
- //Check wrapping.
- if(astUartData[p_iUartHandle].pcTxOutPtr + DataSize < &astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE])
- {
- astUartData[p_iUartHandle].pcTxOutPtr += DataSize;
- }
- else //Pointer must wrap
- {
-
- //Top ------>|---------------|
- // | * |
- //Final Pos->| | // Final Pos = Top + *
- // | |
- // | (buffer) | // DataSize = & + *
- // | | // & = Bottom - OutPtr
- //OutPtr --->| | // * = DataSize - &
- // | & | // FinalPos = Top + (DataSize - (Bottom - OutPtr))
- // | & |
- //Bottom --->|---------------|
-
- // if(p_iUartHandle != PRINTF_UART_PORT)
- // printf("Out wrap\r");
-
- DataSize -= (&astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE] - astUartData[p_iUartHandle].pcTxOutPtr); //p_iSize - (Bottom - OutPtr)
-
- astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0] + DataSize; //Top + new p_iSize
-
-
- }
-
- //Check if data is pending in buffer
- if(astUartData[p_iUartHandle].pcTxOutPtr != astUartData[p_iUartHandle].pcTxInPtr)
- {
- astUartData[p_iUartHandle].iDataPending = 1;
- }
- else
- {
- astUartData[p_iUartHandle].iDataPending = 0;
- // LORA_MODULE_TX_LED_PIN = LED_OFF;
- }
-
- return UART_OK;
- }
-
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- //Called by main loop. Check if any uart has data pending to be sent
- //
- int UartTick(void)
- {
- int i = 0;
- int iRet;
- int p_iSize;
- char aTempBuffer[UART_MAX_RX_BUFF_SIZE];
-
- TickInternalUart();
-
- //Send...
-
- for(i = 0; i < MAX_UART_HANDLE; i++)
- {
- if(astUartData[i].iDataPending)
- {
- char *pcTxInPtr = astUartData[i].pcTxInPtr;
- //Check remaining data size.
- if(astUartData[i].pcTxOutPtr < pcTxInPtr)
- {
- p_iSize = pcTxInPtr - astUartData[i].pcTxOutPtr;
- }
- else
- {
- p_iSize = ((&astUartData[i].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE] - astUartData[i].pcTxOutPtr) +
- (pcTxInPtr - &astUartData[i].acTxCircularBuffer[0]));
- }
-
- if(astUartData[i].iIsInternal) //Uart handle mapped to PIC internal uart
- {
- astUartData[i].iDataPending = 0;
- iRet = SendInternalUartData(astUartData[i].pcTxOutPtr,
- p_iSize,
- astUartData[i].iPhysicalUartPort,
- &astUartData[i].acTxCircularBuffer[0],
- &astUartData[i].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1]);
- }
-
- #ifndef NO_EXTERNAL_UART
- else //mapped to external uart
- {
- astUartData[i].iDataPending = 0;
- iRet = SendExternalUartData(astUartData[i].iPhysicalUartPort, astUartData[i].pcTxOutPtr, p_iSize,&astUartData[i].acTxCircularBuffer[0], &astUartData[i].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1]);
- }
- #endif
-
- //TODO: manage return values
- switch(iRet)
- {
- case UART_OK:
- {
- break;
- }
- case UART_PORT_BUSY:
- case UART_BUFFER_FULL:
- {
- astUartData[i].iDataPending = 1;
- break;
- }
- case UART_PORT_NOT_OPENED:
- {
- break;
- }
- }
- }
-
-
- //Receive...
-
- // int iNbPendingData = astUartData[i].iNbRxFIFOPendingBytes; //JFM 2012-09-05
- int iNbPendingData = UartGetPendingDataSize(i);
- if(iNbPendingData > 0)
- {
- int byte;
- for(byte = 0; byte < iNbPendingData; byte++)
- {
- aTempBuffer[byte] = *astUartData[i].pcRxOutDataPtr++;
- if(astUartData[i].pcRxOutDataPtr > &astUartData[i].acRxCircularBuffer[UART_MAX_RX_BUFF_SIZE-1])
- astUartData[i].pcRxOutDataPtr = &astUartData[i].acRxCircularBuffer[0]; //wrap pointer
- }
- astUartData[i].iNbRxFIFOPendingBytes -= iNbPendingData;
-
- switch(i)
- {
- // case DRIVE_UART_PORT:
- // {
- // //printf("drive rx\n");
- // DriveProtocolRxData(aTempBuffer,iNbPendingData);
- // break;
- // }
- // case CU_UART_PORT:
- // {
- // CUProtocolRxData(aTempBuffer,iNbPendingData); // HCAM 20120918
- // break;
- // }
- case NETWORK_UART_PORT:
- {
- //HEARTBEAT_LED_1_TOGGLE_REG = HEARTBEAT_LED_1_TOGGLE_MASK;
- //UartTransmitData(CONSOLE_UART_PORT, aTempBuffer, iNbPendingData);//echo received character
- int i = 0;
- for(i = 0; i< iNbPendingData; i++)
- {
- ProtocolAnalyzeNewData(aTempBuffer[i]);
- //RxTerminalData(aTempBuffer[i]);
- }
- break;
- }
- case LTE_IF_UART_PORT:
- {
- int i = 0;
- for(i = 0; i< iNbPendingData; i++)
- {
- // LTE_MODULE_RX_LED_PIN = ~LTE_MODULE_RX_LED_PIN;
- LTEModuleNewData(aTempBuffer[i]);
- //ProtocolAnalyzeNewData(aTempBuffer[i]);
- //RxTerminalData(aTempBuffer[i]);
- }
- break;
- }
- }
- }
- }
-
- return UART_OK;
- }
- //-----------------------------------------------------------------------------
- //
- // This function is used in the case of a large amount of data to be sent or received
- // in a process without going back to main loop.
-
- void UartBlockAndTick(unsigned int TickCount)
- {
- int i;
-
- // KickWatchdog();
- for(i = 0; i < TickCount; i++)
- {
- UartTick();
- }
- // KickWatchdog();
- }
- //-----------------------------------------------------------------------------
-
- //-----------------------------------------------------------------------------
- //
- // This function is used in the case of a large amount of data to be sent or received
- // in a process without going back to main loop.
- int UartBlockUntillBufEmpty(int iUartHandle)
- {
- if(iUartHandle >= MAX_UART_HANDLE)
- return 0;
-
- // KickWatchdog();
- while(astUartData[iUartHandle].iDataPending)
- {
- UartTick();
- }
- // KickWatchdog();
- return 1;
-
- }
- //-----------------------------------------------------------------------------
-
- //-----------------------------------------------------------------------------
- //Overload the stdio character output routine to redirect printfs
- //
- //void _mon_putc(char c)
- //{
- // KickWatchdog();
-
- // U2TXREG = c;
- // while (U2STAbits.TRMT==0);
-
-
- //#ifdef USE_BLOCKING_PRINTF
- // switch(CONSOLE_UART_PORT)
- // {
- // case UART_1: //(422) Uart 1B
- // {
- // if(U1MODEbits.ON == 1)
- // {
- // U1TXREG = c;
- // while (U1STAbits.TRMT==0);
- // }
- // break;
- // }
- // case UART_2: //(422) Uart 2A
- // {
- // if(U2MODEbits.ON == 1)
- // {
- // U2TXREG = c;
- // while (U2STAbits.TRMT==0);
- // }
- // break;
- // }
-
- // }
- //#else
- // UartTransmitData(PRINTF_UART_PORT, &c, 1);
- //#endif
- // UartTransmitData(CONSOLE_UART_PORT, &c, 1);
- // Nop();
-
- // KickWatchdog();
- //}
-
- /*
- void _mon_write (const char * s, unsigned int count)
- {
- #ifdef USE_BLOCKING_PRINTF
- int i;
- for(i = 0; i < count; i++)
- _mon_putc(*s++);
- #else
- UartTransmitData(UART_10, s, count);
- #endif
- }*/
-
- //EOF
|