📄 uart.c
字号:
/************************************************************************************
* Includes the UART interface.
*
* Author(s): Allan Poulsen, Jakob Koed
*
* (c) Copyright 2004, Freescale Semiconductor, Inc. All rights reserved.
*
* Freescale Confidential Proprietary
* Digianswer Confidential
*
* No part of this document must be reproduced in any form - including copied,
* transcribed, printed or by any electronic means - without specific written
* permission from Freescale.
*
* Last Inspected:
* Last Tested:
*
* Source Safe revision history (Do not edit manually)
* $Date: 10-03-04 11:20 $
* $Author: Allan1 $
* $Revision: 28 $
* $Workfile: Uart.c $
************************************************************************************/
#include "DigiType.h"
#include "gb60_io.h"
#include "Uart.h"
#include "NV_Data.h"
/************************************************************************************
*************************************************************************************
* Private macros
*************************************************************************************
************************************************************************************/
/************************************************************************************
*************************************************************************************
* Private prototypes
*************************************************************************************
************************************************************************************/
void SCI_Init(void);
/************************************************************************************
*************************************************************************************
* Private type definitions
*************************************************************************************
************************************************************************************/
/************************************************************************************
*************************************************************************************
* Public memory declarations
*************************************************************************************
************************************************************************************/
uint8_t SCI_RxBuf[RXBUFFERLEN], SCI_TxBuf[TXBUFFERLEN];
uint8_t SCI_HeadRxBuf=0, SCI_TailRxBuf=0, SCI_HeadTxBuf=0, SCI_TailTxBuf=0;
/************************************************************************************
*************************************************************************************
* Private memory declarations
*************************************************************************************
************************************************************************************/
static uint8_t UartRxTimer, generalTimer;
/************************************************************************************
*************************************************************************************
* Public functions
*************************************************************************************
************************************************************************************/
void Uart_Init(void)
{
UartRxTimer = 0;
generalTimer = 0;
// Init SCI hardware
SCI_Init();
}
//-----------------------------------------------------------------------------------
void Uart_PutInTxCirc(uint8_t txByte)
{
SCI_TxBuf[SCI_HeadTxBuf] = txByte;
SCI_HeadTxBuf = (SCI_HeadTxBuf+1) & (RXBUFFERLEN-1);
}
//-----------------------------------------------------------------------------------
uint8_t Uart_GetFromRxCirc(void)
{
uint8_t returnValue;
returnValue = SCI_RxBuf[SCI_TailRxBuf]; // Read the data, increment the pointer
SCI_TailRxBuf = (SCI_TailRxBuf+1) & (RXBUFFERLEN-1);
return(returnValue);
}
//-----------------------------------------------------------------------------------
uint8_t Uart_ReadFromRxCirc(uint8_t index)
{
uint8_t i;
i = SCI_RxBuf[(SCI_TailRxBuf+index) & (RXBUFFERLEN-1)];
return(i); // return the data
}
//-----------------------------------------------------------------------------------
uint8_t Uart_Poll(uint8_t * pBuffer)
{
uint8_t i;
uint8_t bytesInBuffer;
// Check for fast exit
if ( SCI_HeadRxBuf == SCI_TailRxBuf )
return 0; // No bytes in SerialRx, therefore just exit
// Calculate the number of bytes in the rx buffer
bytesInBuffer = SCI_HeadRxBuf - SCI_TailRxBuf;
#if RXBUFFERLEN < 256
if (bytesInBuffer > RXBUFFERLEN)
bytesInBuffer += RXBUFFERLEN; // Unsigned calculation
#endif
// Check if a full packet is in the RX buffer or a timeout has occured
if ( (bytesInBuffer < FULLPACKETLENGTH) && (UartRxTimer < 50) )
return 0; // No full packet and no timeout, therefore just return
// At this point we have a Timeout or Full Packet, therefore return the data
// ...At this point, we have confirmed that (at least) one complete packet is waiting in the Rx buffer...
if (bytesInBuffer > FULLPACKETLENGTH)
bytesInBuffer = FULLPACKETLENGTH; // Ensures we don't send more than the maximum number of bytes allowed
// Copy the bytes from the Serial RX buffer to the buffer used in the transmission
for ( i=0; i<bytesInBuffer; i++ ) {
*(pBuffer++) = Uart_GetFromRxCirc();
}
return bytesInBuffer; // True indicates new data ready
}
//-----------------------------------------------------------------------------------
void Uart_Tx(uint8_t * pData, uint8_t length)
{
uint8_t i;
uint8_t space;
// Check for room in Tx buffer
space = SCI_TailTxBuf - SCI_HeadTxBuf - 1;
#if TXBUFFERLEN < 256
if ( space > TXBUFFERLEN)
space += TXBUFFERLEN; // Unsigned calculation
#endif
// Write data payload until no space left
for (i = 0; i <length; )
{
if(i < space)
{
Uart_PutInTxCirc(*pData++);
i++;
}
else
{
while(SCI_TailTxBuf != SCI_HeadTxBuf) {}
space = TXBUFFERLEN-1;
}
}
SCIXC2 |= 0x80; // enable transmit interrupt
}
//-----------------------------------------------------------------------------------
uint8_t Timer_Get(void)
{
return generalTimer;
}
void Timer_Reset(void)
{
generalTimer = 0;
}
#ifdef ENABLE_UART_PRINT
void Uart_Print(uint8_t * pString)
{
uint16_t i;
uint16_t space;
// Check for room in Tx buffer
space = SCI_TailTxBuf - SCI_HeadTxBuf - 1;
if ( space > TXBUFFERLEN) space += TXBUFFERLEN; // Unsigned calculation
// Write data payload until '\0' encountered or no space left
for (i = 0; (*pString != '\0'); ) {
if(i < space)
{
if(*pString == '\n' )
Uart_PutInTxCirc('\r');
if(*pString != '\r' )
Uart_PutInTxCirc(*pString++);
i++;
}
else
{
while(SCI_TailTxBuf != SCI_HeadTxBuf) {}
space = TXBUFFERLEN-1;
}
}
SCIXC2 |= 0x80; // enable transmit interrupt
}
//-----------------------------------------------------------------------------------
/* Convert a 4 bit HEX number to the equivalent ASCII char.
E.g. 0x05 is converted to '5'.*/
uint8_t HexToAscii(uint8_t hex)
{
hex &= 0x0F;
return hex + (uint8_t)((hex <= 9) ? '0' : ('A'-10));
}
void Uart_PrintHex(uint8_t *hex, uint8_t len, uint8_t flags)
{
uint8_t i=0, hexString[2];
if(! (flags & gPrtHexBigEndian_c))
hex = hex + (len-1);
while(len)
{
hexString[1] = HexToAscii( *hex );
hexString[0] = HexToAscii((*hex)>>4);
Uart_Print(hexString);
if(flags & gPrtHexCommas_c)
Uart_Print(",");
hex = hex + (flags & gPrtHexBigEndian_c ? 1 : -1);
len--;
}
if(flags & gPrtHexNewLine_c)
Uart_Print("\n");
}
#endif // ENABLE_UART_PRINT
/************************************************************************************
*************************************************************************************
* Low level Init, Rx & Tx drivers
*************************************************************************************
************************************************************************************/
/************************************************************************************
* Function: sci_init
*
* Description: Initialize SCI interface on HCS08
*
* Return value:
* None
************************************************************************************/
void SCI_Init(void)
{
/* for 16MHz bus clk, the baudrate difference between
* COM and SCI is listed below:
*
* COM SCI diff SCIBD
* -------------------------------
* 38400 38461 61 26 +0,2%
* 57600 58823 1223 17 +2,1%
* 115200 111111 4089 9 -3,5%
* 128000 125000 3000 8
* 256000 250000 6000 4
*
* Abel 2.0 default CLKO out 32,78 KHz
* Abel output = (16000000/488) = 32786.9 Hz
* CPU clock = 512 * (16000000/488) = 16787000 Hz
* BUS clock = 256 * (16000000/488) = 8393443 Hz
* therefore, 38400 is highest baudrate that can be used.
*
* Abel 2.0 default CLKO out 62,5 KHz
* Abel output = (16000000/256) = 62500 Hz
* CPU clock = 64* (4/1) * (16000000/256) = 16000000 Hz
* BUS clock = CPU clock/2 = 8000000 Hz
* therefore, 38400 is highest baudrate that can be used. */
// Defines in Uart.h
#ifdef __SYSTEM_BUS_CLOCK_32_78
// Abel 2.0 CLKO out = 32,78 KHz - enable
SCIXBDH = 0x00;
SCIXBDL = 0x1b; // 8393443/(27*16) = 19429 baud = +1,2%
#endif __SYSTEM_BUS_CLOCK_32_78
#ifdef __SYSTEM_BUS_CLOCK_62_5
// Abel 2.0 CLKO out = 62,5 KHz - enable
SCIXBDH = 0x00;
SCIXBDL = 0x1a; // 8000000/(26*16) = 19231 baud = +0,16%
#endif __SYSTEM_BUS_CLOCK_62_5
#ifdef __USE_BAUD_RATE_FROM_NV_RAM
// Use baud rate value from NV RAM
SCIXBDH = NV_RAM_ptr->NV_SCI1BDH;
SCIXBDL = NV_RAM_ptr->NV_SCI1BDL;
#endif __USE_BAUD_RATE_FROM_NV_RAM
/* LOOPS SCIWAIT RSRC M WAKE ILT PE PT */
SCIXC1 = 0x00; // 8 data, no parity
/* TIE TCIE RIE ILIE TE RE RWU SBK */
/* 1 0 1 0 1 1 0 0 */
SCIXC2 = 0x2C; // TIE = 0, RIE = 1, TE = 1, RE= 1, 0, 0,
// SCIXC2 = 0x0C; // TIE = 0, RIE = 0, TE = 1, RE= 1, 0, 0,
// SCIXC2 = 0x8C; // TIE = 1, RIE = 0, TE = 1, RE= 1, 0, 0,
// SCIXC2 = 0xAC; // TIE = 1, RIE = 1, TE = 1, RE= 1, 0, 0,
SCIXC3 = 0x00;
// Initialize timer for ensuring that small data packets are transmitted:
// bit6 = 1 -> Overflow interrupt enabled. Use BUSCLK and prescale with factor 0.
TPM1SC = 0x48;
return;
}
/************************************************************************************
* Function: SCIX_tx_int
*
* Description: SCI interrupt routine for transmission.
*
* Return value:
* None
************************************************************************************/
interrupt void SCIX_tx_ISR(void)
{
uint8_t dummy;
if (SCI_HeadTxBuf == SCI_TailTxBuf)
{
SCIXC2 &= ~0x80; // Disable transmit interrupt
}
else
{
dummy = SCIXS1; //allow next write to TX register
SCIXD = SCI_TxBuf[SCI_TailTxBuf];
SCI_TailTxBuf = (SCI_TailTxBuf+1) & (TXBUFFERLEN-1);
}
}
/************************************************************************************
* Function: SCIX_rx_int
*
* Description: SCI interrupt routine for receiving.
*
* Return value:
* None
************************************************************************************/
interrupt void SCIX_rx_ISR(void)
{
uint8_t dummy;
// Receive register full and no errors ?
if ( (SCIXS1 & 0x20) != 0x0 )
{ // SCIS1:5 (RDRF) = 0: Data register empty, 1: full. SCIS1:0-4 Error flags
SCI_RxBuf[SCI_HeadRxBuf] = SCIXD; // Read the data, increment the pointer
SCI_HeadRxBuf = (SCI_HeadRxBuf+1) & (RXBUFFERLEN-1);
}
else
{
dummy = SCIXD; // Dummy read because the error flags are only cleared when the data register is read
}
}
/***********************************************************************************/
/************************************************************************************
* Function: UART_TIMER_ISR
*
* Description:.
*
* Return value:
* None
************************************************************************************/
interrupt void UART_TIMER_ISR(void)
{
TPM1SC &= 0x7F; // Read, Clear bit 7, Write
UartRxTimer++; // Counted upwards on a regular basis, reset everytime a byte is received in the uart interrupt
generalTimer++; // Counted upwards on a regular basis. Never reset, will wrap around.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -