UART repeater for FRDM-KL25

Dependencies:   USBDevice mbed

UART repeater for FRDM-KL25

main.cpp

Committer:
ohneta
Date:
2015-06-22
Revision:
0:26f0a25e8be6

File content as of revision 0:26f0a25e8be6:

//---------------------------------------------------------
/**
 * FRDM-KL25Z用
 * UART -> USB Serial変換
 *
 * UART : UART1
 *
 * モード認識ポート : D0、D1、D2、D3
 *   GND接続でON
 *
 * UART入力モード
 *   D0=OFF, D1=OFF : スルー
 *   D0=ON,  D1=OFF : CR(0x0D, \r)を改行と認識する
 *   D0=OFF, D1=ON  : LF(0x0A, \n)を改行と認識する
 *   D0=ON,  D1=ON  : CRとLFの両方とも改行と認識する
 *
 * USB Serial出力モード
 *   D2=OFF, D3=OFF : スルー
 *   D2=ON,  D3=OFF : 改行ををCR(0x0D, \r)として出力する
 *   D2=OFF, D3=ON  : 改行ををLF(0x0A, \n)として出力する
 *   D2=ON,  D3=ON  : 改行ををCR+LF(0x0D+0x0A, \r\n)として出力する
 *
 * 備考
 *   USB Serialからの入力はスルー
 *   モード認識ポートの利用の利便性を考えてそれぞれのポートの隣のポートを意図的にGNDにしてある。
 */
//---------------------------------------------------------

#include "mbed.h"
#include "USBSerial.h"

enum newline_mode {
    nlmode_none = 0x00,    // 処理しない
    nlmode_cr   = 0x01,    // CRを出力
    nlmode_lf   = 0x02,    // LFを出力
    nlmode_crlf = 0x03,    // CR+LFを出力
};

//---------------------------------------------------------
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);

DigitalOut nlInModeGnd0(PTC7);
DigitalOut nlInModeGnd1(PTC0);
DigitalOut nlOutModeGnd0(PTC3);
DigitalOut nlOutModeGnd1(PTC4);

DigitalIn nlInModePin0(D0);
DigitalIn nlInModePin1(D1);
DigitalIn nlOutModePin0(D2);
DigitalIn nlOutModePin1(D3);


int inMode  = nlmode_none;
int outMode = nlmode_none;

USBSerial pc;
Serial uart(D14, D15);      // tx, rx
Ticker flipper;

//---------------------------------------------------------
/**
 *
 */
void flip()
{
    myled3 = !myled3;
}

//---------------------------------------------------------
/**
 *
 */
void checkNlMode()
{
    int inModePin0  = !nlInModePin0;
    int inModePin1  = !nlInModePin1;
    int outModePin0 = !nlOutModePin0;
    int outModePin1 = !nlOutModePin1;

    inMode  = (inModePin1 << 1) | inModePin0;
    outMode = (outModePin1 << 1) | outModePin0;

#if 0
    static char* modeString[] = { "nlmode_none", "nlmode_cr", "nlmode_lf", "nlmode_crlf" };
    pc.printf("[MODE: %x %x %x %x] => %s %s", inModePin0, inModePin1, outModePin0, outModePin1, modeString[inMode], modeString[outMode]);
    pc.printf("\r\n");
    wait(0.1);
#endif
}

//---------------------------------------------------------
//---------------------------------------------------------
/**
 *
 */
int main()
{
    myled1 = 1; myled2 = 1; myled3 = 1; wait(0.1);
    myled1 = 0; myled2 = 0; myled3 = 0; wait(0.1);
    myled1 = 1; myled2 = 1; myled3 = 1; wait(0.2);
    myled1 = 0; myled2 = 0; myled3 = 0; wait(0.2);
    myled1 = 1; myled2 = 1; myled3 = 1; wait(0.3);
    myled1 = 0; myled2 = 0; myled3 = 0; wait(0.3);
    myled1 = 1; myled2 = 1; myled3 = 1; wait(0.4);
    myled1 = 0; myled2 = 0; myled3 = 0; wait(0.4);

    nlInModeGnd0 = 0;
    nlInModeGnd1 = 0;
    nlOutModeGnd0 = 0;
    nlOutModeGnd1 = 0;

    flipper.attach(&flip, 0.5);
    wait(2);
    pc.printf("** serial repeater **\r\n");
    pc.printf("----------------\r\n");

    bool nlFlag = false;
    while(1) {
        checkNlMode();
        nlFlag = false;

        if (pc.available() > 0) {
            int c = pc.getc();
            uart.putc(c);
            myled1 = !myled1;
        }

        if(uart.readable()) {
            int c = uart.getc();

            if ((inMode == nlmode_cr) && (c == '\r')) {
                nlFlag = true;
            }
            if ((inMode == nlmode_lf) && (c == '\n')) {
                nlFlag = true;
            }
            // inModeには nlmode_crlfは存在しない -> cr/lfの両方を処理する

            if (nlFlag) {
                if (outMode == nlmode_cr) {
                    pc.putc('\r');  // CR
                } else if (outMode == nlmode_lf) {
                    pc.putc('\n');  // LF
                } else if (outMode == nlmode_crlf) {
                    pc.putc('\r');  // CR
                    pc.putc('\n');  // LF
                }
            } else {
                pc.putc(c);
            }
            myled2 = !myled2;
        }

    }
}
//---------------------------------------------------------