⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 This network protcol stack,it is very strong and powerful!
💻 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 + -