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

📄 serial.c

📁 关于 modbus tcp 的一些源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * FreeModbus Libary: STR71/lwIP Port serial driver.
 * Copyright (C) 2006 Christian Walter <wolti@sil.at>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * File: $Id: serial.c,v 1.4 2006/09/04 20:38:50 wolti Exp $
 */


/* ----------------------- Platform includes --------------------------------*/
#include "uart.h"
#include "eic.h"
#include "gpio.h"

/* ----------------------- lwIP includes ------------------------------------*/
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/sio.h"
#include "lwip/err.h"

/* ----------------------- FreeRTOS includes --------------------------------*/
#include "task.h"
#include "semphr.h"

/* ----------------------- Project includes ---------------------------------*/
#include "serial.h"

/* ----------------------- Defines ------------------------------------------*/
#define UART0_DEV               ( UART0 )
#define UART0_RX_PORT           ( GPIO0 )
#define UART0_RX_PIN            ( 8 )
#define UART0_TX_PORT           ( GPIO0 )
#define UART0_TX_PIN            ( 9 )
#define UART0_IRQ_CH            ( UART0_IRQChannel )
#define UART0_IRQ_PRIORITY      ( 1 )

#define UART1_DEV               ( UART1 )
#define UART1_RX_PORT           ( GPIO0 )
#define UART1_RX_PIN            ( 10 )
#define UART1_TX_PORT           ( GPIO0 )
#define UART1_TX_PIN            ( 11 )
#define UART1_IRQ_CH            ( UART1_IRQChannel )
#define UART1_IRQ_PRIORITY      ( 1 )

#define UART_DEVICES_MAX        ( 2 )

#define DEFAULT_BAUDRATE        ( 38400 )
#define DEFAULT_DATABITS        ( 8 )
#define DEFAULT_STOPBITS        ( 1 )
#define DEFAULT_PARITY          ( SIO_PAR_NONE )

#define DEFAULT_TX_BUFSIZE      ( 64 )
#define DEFAULT_RX_BUFSIZE      ( 64 )

#define DEFAULT_READTIMEOUT_MS  ( 10 )

#define SIO_RESET_STATE( dev )    do { \
        ( dev )->ready = 0; \
        ( dev )->abort = 0; \
        ( dev )->UARTx = NULL; \
        ( dev )->rx_buf_rdpos = ( dev )->rx_buf_wrpos = 0; \
        ( dev )->rx_sem = SYS_SEM_NULL; \
        ( dev )->tx_buf_rdpos = ( dev )->tx_buf_wrpos = 0; \
        ( dev )->tx_sem = SYS_SEM_NULL; \
    } while( 0 )

#define MS_TO_TICKS( ms )           \
    ( portTickType )( ( portTickType ) ( ms ) / portTICK_RATE_MS )

/* ----------------------- Type definitions ---------------------------------*/
typedef struct
{
    u8_t            ready;
    u8_t            abort;

    u8_t            rx_buf[DEFAULT_RX_BUFSIZE];
    u8_t            rx_buf_rdpos;
    u8_t            rx_buf_wrpos;
    u8_t            rx_buf_cnt;
    xSemaphoreHandle rx_sem;

    u8_t            tx_buf[DEFAULT_TX_BUFSIZE];
    u8_t            tx_buf_rdpos;
    u8_t            tx_buf_wrpos;
    u8_t            tx_buf_cnt;
    xSemaphoreHandle tx_sem;
    UART_TypeDef   *UARTx;
} serdev_t;

/* ----------------------- Prototypes ---------------------------------------*/
void            sio_uart0_irq( void ) __attribute__ ( ( naked ) );
void            sio_uart1_irq( void ) __attribute__ ( ( naked ) );

/* ----------------------- Static functions ---------------------------------*/

static err_t    sio_open_low_level( u8_t devnr, serdev_t * dev );
static err_t    sio_close_low_level( u8_t devnr, serdev_t * dev );

/* ----------------------- Static variables ---------------------------------*/
static u8_t     initialized = FALSE;
static volatile serdev_t devices[UART_DEVICES_MAX];

/* ----------------------- Start implementation -----------------------------*/

err_t
sio_open_low_level( u8_t devnr, serdev_t * dev )
{
    err_t           error = ERR_OK;

    if( devnr == 0 )
    {
        /* Return value. */
        dev->UARTx = UART0;

        /* Reset the UART. */
        UART_Init( dev->UARTx );

        /* Configure the GPIO pints for the UART device. */
        GPIO_Config( UART0_TX_PORT, 1 << UART0_TX_PIN, GPIO_AF_PP );
        GPIO_Config( UART0_RX_PORT, 1 << UART0_RX_PIN, GPIO_IN_TRI_CMOS );

        /* Configure the IEC for the UART interrupts. */
        EIC_IRQChannelPriorityConfig( UART0_IRQ_CH, UART0_IRQ_PRIORITY );
        EIC_IRQChannelConfig( UART0_IRQ_CH, ENABLE );
    }
    else if( devnr == 1 )
    {
        /* Return value. */
        dev->UARTx = UART1;

        /* Reset the UART. */
        UART_Init( dev->UARTx );

        /* Configure the GPIO pints for the UART device. */
        GPIO_Config( UART1_TX_PORT, 1 << UART1_TX_PIN, GPIO_AF_PP );
        GPIO_Config( UART1_RX_PORT, 1 << UART1_RX_PIN, GPIO_IN_TRI_TTL );

        /* Configure the EIC for the UART interrupts. */
        EIC_IRQChannelPriorityConfig( UART1_IRQ_CH, UART1_IRQ_PRIORITY );
        EIC_IRQChannelConfig( UART1_IRQ_CH, ENABLE );
    }
    else
    {
        error = ERR_IF;
    }
    return error;
}

err_t
sio_close_low_level( u8_t devnr, serdev_t * dev )
{
    err_t           error = ERR_OK;

    if( devnr == 0 )
    {
        UART_Init( dev->UARTx );

        /* Disable the GPIO pints for the UART device. */
        GPIO_Config( UART0_TX_PORT, 1 << UART1_TX_PIN, GPIO_IN_TRI_TTL );
        GPIO_Config( UART0_RX_PORT, 1 << UART1_RX_PIN, GPIO_IN_TRI_TTL );

        /* Disable the UART interrupts in the EIC. */
        EIC_IRQChannelConfig( UART0_IRQ_CH, DISABLE );
    }
    else if( devnr == 1 )
    {
        UART_Init( dev->UARTx );

        /* Disable the GPIO pints for the UART device. */
        GPIO_Config( UART1_TX_PORT, 1 << UART1_TX_PIN, GPIO_IN_TRI_TTL );
        GPIO_Config( UART1_RX_PORT, 1 << UART1_RX_PIN, GPIO_IN_TRI_TTL );

        /* Disable the UART interrupts in the EIC. */
        EIC_IRQChannelConfig( UART1_IRQ_CH, DISABLE );
    }
    else
    {
        error = ERR_IF;
    }
    return error;
}

err_t
sio_close( serdev_t * dev )
{
    int             i;
    err_t           error = ERR_VAL;

    for( i = 0; i < UART_DEVICES_MAX; i++ )
    {
        if( &devices[i] == dev )
        {
            break;
        }
    }
    if( i < UART_DEVICES_MAX )
    {
        vPortEnterCritical(  );
        error = sio_close_low_level( i, dev );
        vPortExitCritical(  );

        if( dev->tx_sem != ( xSemaphoreHandle ) 0 )
        {
            vQueueDelete( dev->tx_sem );
        }
        if( dev->rx_sem != ( xSemaphoreHandle ) 0 )
        {
            vQueueDelete( dev->tx_sem );
        }
        SIO_RESET_STATE( dev );
    }

    return error;
}

sio_fd_t
sio_open_new( u8_t devnr, u32_t baudrate, u8_t databits, sio_stop_t stopbits, sio_parity_t parity )
{
    int             i;
    err_t           error = ERR_OK;
    serdev_t       *dev;
    UARTParity_TypeDef eUARTParity = UART_NO_PARITY;
    UARTMode_TypeDef eUARTMode = UARTM_8D;
    UARTStopBits_TypeDef eUARTStopBits;

    if( !initialized )
    {
        for( i = 0; i < UART_DEVICES_MAX; i++ )
        {
            SIO_RESET_STATE( &devices[i] );
        }
        initialized = 1;
    }

    /* Check if devicename is valid and not in use. */
    if( ( devnr < UART_DEVICES_MAX ) && ( devices[devnr].ready == 0 ) )
    {
        dev = ( serdev_t * ) & devices[devnr];

        switch ( parity )
        {
        case SIO_PAR_EVEN:
            eUARTParity = UART_EVEN_PARITY;
            break;
        case SIO_PAR_ODD:
            eUARTParity = UART_ODD_PARITY;
            break;
        case SIO_PAR_NONE:
            eUARTParity = UART_NO_PARITY;
            break;
        default:
            error = ERR_VAL;
        }

        switch ( databits )
        {
        case 7:
            if( parity != SIO_PAR_NONE )
            {
                eUARTMode = UARTM_7D_P;
            }
            break;
        case 8:
            eUARTMode = parity == SIO_PAR_NONE ? UARTM_8D : UARTM_8D_P;
            break;
        default:
            error = ERR_VAL;
        }

        switch ( stopbits )
        {
        case SIO_STOP_0_5:
            eUARTStopBits = UART_0_5_StopBits;
            break;
        case SIO_STOP_1:
            eUARTStopBits = UART_1_StopBits;
            break;
        case SIO_STOP_1_5:
            eUARTStopBits = UART_1_5_StopBits;
            break;
        case SIO_STOP_2:
            eUARTStopBits = UART_2_StopBits;
            break;
        default:
            error = ERR_VAL;
        }

        if( error == ERR_OK )
        {
            SIO_RESET_STATE( dev );

            vSemaphoreCreateBinary( dev->rx_sem );
            vSemaphoreCreateBinary( dev->tx_sem );

            vPortEnterCritical(  );
            if( ( error = sio_open_low_level( devnr, dev ) ) != ERR_OK )
            {
                /* Hardware interface does not exist. */
            }
            else if( dev->tx_sem == ( xSemaphoreHandle ) 0 )
            {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -