UART処理

802.15.4 MAC API を使用する場合の UART の使用方法を以下に記述します。

UARTの概要についてはこちらを参照ください。

UART処理は、UARTペリフェラルへの入力と出力、割り込み処理、FIFOキューによる処理となっています。主要処理は、以下のソースコードに含まれており、そのまま利用できます。必要に応じて uart.c を書き換えることが有ります(パリティの設定など)。

このソースコードは UART0, UART1 を同時に扱えるようになっています。

基本的な使用方法

# include "serial.h"
# include "fprintf.h"

// UARTのポートの指定
#define UART_PORT E_AHI_UART_0

// ボーレートの設定(DivとCbpによる)
//#define UARTBAUD (0x80000000 | 104             ) //   9600bps
//#define UARTBAUD (0x80000000 |  52             ) //  19200bps
//#define UARTBAUD (0x80000000 |  26             ) //  38400bps
//#define UARTBAUD (0x80000000 |  23 | (11 << 16)) //  57600bps
//#define UARTBAUD (0x80000000 |  13             ) //  76800bps
  #define UARTBAUD (0x80000000 |  10 | (13 << 16)) // 115200bps
//#define UARTBAUD (0x80000000 |   5 | (13 << 16)) // 230400bps
//#define UARTBAUD (0x80000000 |   4             ) // 250000bps

// FIFOキューや出力用の定義
tsFILE sUartStream;
tsSerialPortSetup sUartPort;

// 初期化関数(UART利用前に呼び出しておく。vAHI_Init()の後)
void vSerialInit(void) {
    static uint8 au8SerialTxBuffer[96]; // 送信FIFOバッファサイズ(必要に応じで調整する)
    static uint8 au8SerialRxBuffer[32]; // 受信FIFOバッファサイズ(必要に応じで調整する)

    sUartPort.pu8SerialRxQueueBuffer = au8SerialRxBuffer;
    sUartPort.pu8SerialTxQueueBuffer = au8SerialTxBuffer;
    sUartPort.u32BaudRate = UART_BAUD;
    sUartPort.u16AHI_UART_RTS_LOW = 0xffff;
    sUartPort.u16AHI_UART_RTS_HIGH = 0xffff;
    sUartPort.u16SerialRxQueueSize = sizeof(au8SerialRxBuffer);
    sUartPort.u16SerialTxQueueSize = sizeof(au8SerialTxBuffer);
    sUartPort.u8SerialPort = UART_PORT;
    sUartPort.u8RX_FIFO_LEVEL = E_AHI_UART_FIFO_LEVEL_1;
    SERIAL_vInit(&sUartPort);

    sUartStream.bPutChar = SERIAL_bTxChar;
    sUartStream.u8Device = UART_PORT;
}

// 出力
    vfPrintf(&sUartStream, "\r\nHELLO WORLD!");

// 入力(イベント処理ループ内でキューをチェックする)
void vMain() {
    while(1) {
        // メインループ内
        vProcessEventQueues();
        vHandleSerialInput();
        vAHI_CpuDoze();
    }
}
    
void vHandleSerialInput(void)
{
    // handle UART command
    while (!SERIAL_bRxQueueEmpty(sUartPort.u8SerialPort)) {
        // FIFOキューから1バイトずつ取り出して処理する。
        
        int16 i16Char;

        i16Char = SERIAL_i16RxChar(sUartPort.u8SerialPort);
        
        vfPutc(&sUartStream, '[');
        vfPutc(&sUartStream, i16Char);
        vfPutc(&sUartStream, ']');
        
        switch(i16Char) {
            case 'h': case 'H':
                vfPrintf(&sUartStream, "\r\nHELP MESSAGE HERE!");
                break;
            default:
                vfPrintf(&sUartStream, "\r\nUnknown Character[%c]", i16Char);
                break;
        }
    }
    
// 出力待ち
//   au8SerialTxBuffer[] のサイズを超えると出力が欠損します。
//   これを防ぐためには、UART 出力完了待ちを行います。

// UART wait
#define WAIT_UART_OUTPUT(P) \
    while ((!SERIAL_bTxQueueEmpty(P)) || \
           ((u8AHI_UartReadLineStatus(P) & E_AHI_UART_LS_THRE) == 0) || \
           ((u8AHI_UartReadLineStatus(P) & E_AHI_UART_LS_TEMT) == 0))

...
    vfPrintf(&sUartStream, "\r\nLONG LONG LONG LONG LONG LONG MESSAGE HERE.");
    WAIT_UART_OUTPUT(sUartStream.u8Device);
    vfPrintf(&sUartStream, "\r\nLONG LONG LONG LONG LONG LONG MESSAGE HERE.");
    WAIT_UART_OUTPUT(sUartStream.u8Device);

より詳細な設定

UARTのより細かい設定を行いたい場合(パリティの変更、フロー制御など)は、uart.c を参考にしてください。vAHI_UartSetRTSCTS(), vAHI_UartSetControl() 以外は設定を変える必要はありません。

※ 他のコードを編集した場合、動作については予測が出来ない場合も有ります。

///// uart.c
// 
PUBLIC void UART_vInit(uint8 u8UARTNum,
                       void (*pfRxFn)(uint8,uint8),
                       void (*pfTxRdy)(uint8),
                       uint32 u32BaudRate,
                       uint8 u8RX_FIFO_LEVEL)
{

    asUARTS[u8UARTNum].pfRxFn = pfRxFn;
    asUARTS[u8UARTNum].pfTxRdy = pfTxRdy;
    asUARTS[u8UARTNum].u8RX_FIFO_LEVEL = u8RX_FIFO_LEVEL;

    /* Enable UART 0 */
    vAHI_UartEnable(u8UARTNum);

    vAHI_UartReset(u8UARTNum, TRUE, TRUE);
    vAHI_UartReset(u8UARTNum, FALSE, FALSE);

    if (u8UARTNum == E_AHI_UART_0){
        asUARTS[u8UARTNum].u32StartAddress = UART0_START_ADR;
        vAHI_Uart0RegisterCallback(UART_vHandleUartInterrupt);
    }
    else{
        asUARTS[u8UARTNum].u32StartAddress = UART1_START_ADR;
        vAHI_Uart1RegisterCallback(UART_vHandleUartInterrupt);
    }

    if (u32BaudRate &0x80000000) {
        /* MSB を設定した時は divisor と cpb による設定を行う */
        u32BaudRate &= 0x7FFFFFF;
        vAHI_UartSetBaudDivisor(u8UARTNum, u32BaudRate & 0xFFFF);
        vAHI_UartSetClocksPerBit(u8UARTNum, (u32BaudRate >> 16) & 0xFF);
    } else {
        /* 数値によるボーレート設定 */
        UART_vSetBaudRate(u8UARTNum,u32BaudRate);

    }

    // ハードフローの設定
    //vAHI_UartSetRTSCTS(u8UARTNum, FALSE);

    // パリティの設定
    vAHI_UartSetControl(u8UARTNum,
            UART_PARITY_TYPE,
            UART_PARITY_ENABLE,
            UART_BITLEN,
            UART_STOPBITS,
            FALSE); /* [I SP001222_P1 279] */

    vAHI_UartSetInterrupt(u8UARTNum, FALSE, FALSE, FALSE, TRUE,
            asUARTS[u8UARTNum].u8RX_FIFO_LEVEL);    // No TX ints!
}

UART0/1両方使う場合

UARTポートを2ヶ使用する場合は、以下を参考にしてください。

// UARTのポートの指定
#define UART_PORT0 E_AHI_UART_0
#define UART_PORT1 E_AHI_UART_1

// ボーレートの設定(DivとCbpによる)
#define UARTBAUD0 (0x80000000 |  52             ) //  19200bps
#define UARTBAUD1 (0x80000000 |  26             ) //  38400bps

// FIFOキューや出力用の定義
tsFILE sUartStream0, sUartStream1;
tsSerialPortSetup sUartPort0, sUartPort1;

// 初期化関数
void vSerialInit(void) {
    /* Create the debug port transmit and receive queues */
    static uint8 au8SerialTxBuffer0[96]; // 送信FIFOバッファサイズ(必要に応じで調整する)
    static uint8 au8SerialRxBuffer0[32]; // 受信FIFOバッファサイズ(必要に応じで調整する)

    static uint8 au8SerialTxBuffer1[96]; // 送信FIFOバッファサイズ(必要に応じで調整する)
    static uint8 au8SerialRxBuffer1[32]; // 受信FIFOバッファサイズ(必要に応じで調整する)

    /* Initialise the serial port to be used for debug output */
    sUartPort0.pu8SerialRxQueueBuffer = au8SerialRxBuffer0;
    sUartPort0.pu8SerialTxQueueBuffer = au8SerialTxBuffer0;
    sUartPort0.u32BaudRate = UART_BAUD0;
    sUartPort0.u16AHI_UART_RTS_LOW = 0xffff;
    sUartPort0.u16AHI_UART_RTS_HIGH = 0xffff;
    sUartPort0.u16SerialRxQueueSize = sizeof(au8SerialRxBuffer0);
    sUartPort0.u16SerialTxQueueSize = sizeof(au8SerialTxBuffer0);
    sUartPort0.u8SerialPort = UART_PORT0;
    sUartPort0.u8RX_FIFO_LEVEL = E_AHI_UART_FIFO_LEVEL_1;
    SERIAL_vInit(&sUartPort0);

    sUartStream0.bPutChar = SERIAL_bTxChar;
    sUartStream0.u8Device = UART_PORT0;
    
    /* Initialise the serial port to be used for debug output */
    sUartPort1.pu8SerialRxQueueBuffer = au8SerialRxBuffer1;
    sUartPort1.pu8SerialTxQueueBuffer = au8SerialTxBuffer1;
    sUartPort1.u32BaudRate = UART_BAUD1;
    sUartPort1.u16AHI_UART_RTS_LOW = 0xffff;
    sUartPort1.u16AHI_UART_RTS_HIGH = 0xffff;
    sUartPort1.u16SerialRxQueueSize = sizeof(au8SerialRxBuffer1);
    sUartPort1.u16SerialTxQueueSize = sizeof(au8SerialTxBuffer1);
    sUartPort1.u8SerialPort = UART_PORT1;
    sUartPort1.u8RX_FIFO_LEVEL = E_AHI_UART_FIFO_LEVEL_1;
    SERIAL_vInit(&sUartPort1);

    sUartStream1.bPutChar = SERIAL_bTxChar;
    sUartStream1.u8Device = UART_PORT1;
}

...
    while (!SERIAL_bRxQueueEmpty(sUartPort0.u8SerialPort)) {
        // UART1のFIFOキューから1バイトずつ取り出して処理する。
        
        int16 i16Char;

        i16Char = SERIAL_i16RxChar(sUartPort0.u8SerialPort);
             // 処理:UART1に出力。UART0には何も出力しない
             vfPrintf(&sUartStream1, "[%c]", i16Char);
        }
    }

    while (!SERIAL_bRxQueueEmpty(sUartPort1.u8SerialPort)) {
        // UART1のFIFOキューから1バイトずつ取り出して処理する。
        
        int16 i16Char;

        i16Char = SERIAL_i16RxChar(sUartPort1.u8SerialPort);
             // 処理:UART1に出力。
             vfPrintf(&sUartStream1, "<%c>", i16Char);
        }
    }
TWELITE
TWELITE
DIP
DIP
UART
UART
CUE
CUE
ARIA
ARIA
PAL
PAL
STICK
STICK
spot
SPOT
R3
R3
STARTER KIT
STARTER KIT
アンテナ
アンテナ
製品一覧
製品一覧

モノをつなぐ無線

モノをつなぐ無線
モノの無線
導入事例
導入事例
選び方
選び方
小型
小型
省電力
省電力
多数接続
多数接続
コントロール
コントロール
モニタリング
モニタリング
ソフトウエア
ソフトウエア
親機
親機
中継機
中継機
子機
子機
始め方
始め方

評価開発環境

STAGE
STAGE
STAGE APP
STAGE APP
interactive
アプリ設定
アプリ書換
アプリ書換
プログラミング
プログラミング