rt-thread/components/net/freemodbus/modbus/port/portserial.c

143 lines
3.3 KiB
C

/*
* File : portserial.c
* This file is part of freemodbus in RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-04-04 yi.qiu first version
*/
#include <rtthread.h>
#include "port.h"
#include "serial.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#define UART1 ((struct uartport *)&U1BASE)
/* ----------------------- static functions ---------------------------------*/
static void rt_serial1_handler(int vector);
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
extern rt_uint32_t PCLK;
/* ----------------------- Start implementation -----------------------------*/
void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
if( xRxEnable )
{
INTSUBMSK &= ~(BIT_SUB_RXD1);
}
else
{
INTSUBMSK |= (BIT_SUB_RXD1);
}
if( xTxEnable )
{
INTSUBMSK &= ~(BIT_SUB_TXD1);
prvvUARTTxReadyISR();
}
else
{
INTSUBMSK |= (BIT_SUB_TXD1);
}
}
void vMBPortClose( void )
{
/* null */
}
BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
int i;
/* FIFO enable, Tx/Rx FIFO clear */
UART1->ufcon = 0x0;
/* disable the flow control */
UART1->umcon = 0x0;
/* Normal,No parity,1 stop,8 bit */
UART1->ulcon = 0x3;
/*
* tx=level,rx=edge,disable timeout int.,enable rx error int.
* normal,interrupt or polling
*/
UART1->ucon = 0x245;
/* Set uart0 bps */
UART1->ubrd = (rt_int32_t)(PCLK / (ulBaudRate * 16)) - 1;
for (i = 0; i < 100; i++);
SUBSRCPND |= BIT_SUB_RXD1;
SUBSRCPND |= BIT_SUB_TXD1;
rt_hw_interrupt_install(INTUART1, rt_serial1_handler, RT_NULL);
rt_hw_interrupt_umask(INTUART1);
return TRUE;
}
BOOL xMBPortSerialPutByte( CHAR ucByte )
{
/* wait for room in the transmit FIFO */
while(!(USTAT1 & USTAT_TXB_EMPTY));
UTXH1 = (UCHAR)ucByte;
return TRUE;
}
BOOL xMBPortSerialGetByte( CHAR * pucByte )
{
while (!(USTAT1 & USTAT_RCV_READY));
*pucByte = URXH1;
return TRUE;
}
static void rt_serial1_handler(int vector)
{
if (SUBSRCPND & BIT_SUB_RXD1)
{
SUBSRCPND |= BIT_SUB_RXD1;
prvvUARTRxISR();
}
else if (SUBSRCPND & BIT_SUB_TXD1)
{
SUBSRCPND |= BIT_SUB_TXD1;
prvvUARTTxReadyISR();
}
}
/*
* Create an interrupt handler for the transmit buffer empty interrupt
* (or an equivalent) for your target processor. This function should then
* call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
* a new character can be sent. The protocol stack will then call
* xMBPortSerialPutByte( ) to send the character.
*/
static void prvvUARTTxReadyISR( void )
{
pxMBFrameCBTransmitterEmpty( );
}
/*
* Create an interrupt handler for the receive interrupt for your target
* processor. This function should then call pxMBFrameCBByteReceived( ). The
* protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
* character.
*/
static void prvvUARTRxISR( void )
{
pxMBFrameCBByteReceived( );
}