144 lines
3.3 KiB
C
144 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) == 0);
|
||
|
|
||
|
*pucByte = URXB1;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static void rt_serial1_handler(int vector)
|
||
|
{
|
||
|
|
||
|
if (SUBSRCPND & BIT_SUB_RXD1)
|
||
|
{
|
||
|
SUBSRCPND |= BIT_SUB_RXD1;
|
||
|
prvvUARTRxISR();
|
||
|
}
|
||
|
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( );
|
||
|
}
|