/* * 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 #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( ); }