LoRaWAN demo application using grove peripherals generating Cayenne LPP

Dependencies:   lorawan1v1

radio chip selection

Radio chip driver is not included, because two options are available.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.

Grove peripherals -> Cayenne demo

Read LoRaWAN-1.1 page for configuration instructions.

This project adds support for Murata discovery board, in addition to LoRa shields on NUCLEO boards.

Use with sx1272 shield with grove peripherals connected:

D8 D9: ButtonRX TXA3 A4: TempSense
D6 D7:SCL SDA : LEDA1 A2: Pot

Button

Sends two different payload types: short press (under 1 sec)
long press: held down > 1 sec.

serial console keys

115200bps, 8N1
Enter key not used
Keys '0' to '3': cayenne channel number
'0': pot (rotary sensor)
'1': temperature
'2': digital out
'3': analog out

DevEUI configuration

For use on networks which force you to use DevEUI defined by network, comment out HardwareIDtoDevEUI().
HardwareIDtoDevEUI() obtains DevEUI from the CPU unique hardware serial number. However, some networks may force you to use their DevEUI value.

Revision:
0:62e456e60083
Child:
9:1a94f4a5e716
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialDisplay.cpp	Wed Feb 28 14:06:17 2018 -0800
@@ -0,0 +1,518 @@
+/*
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2015 Semtech
+
+Description: VT100 serial display management
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#include "board.h"
+
+#include "SerialDisplay.h"
+#include "LoRaMacString.h"
+
+#ifdef ENABLE_VT100
+VT100 vt( USBTX, USBRX );
+
+void SerialPrintCheckBox( bool activated, uint8_t color )
+{
+    if( activated == true )
+    {
+        vt.SetAttribute( VT100::ATTR_OFF, color, color );
+    }
+    else
+    {
+        vt.SetAttribute( VT100::ATTR_OFF );
+    }
+    vt.printf( " " );
+    vt.SetAttribute( VT100::ATTR_OFF );
+}
+
+#ifdef LORAWAN_JOIN_EUI
+void SerialDisplayUpdateActivationMode( bool otaa )
+{
+    vt.SetCursorPos( 4, 17 );   // TODO
+    SerialPrintCheckBox( otaa, VT100::WHITE );
+}
+
+void SerialDisplayUpdateEui( uint8_t line, const uint8_t *eui )
+{
+    vt.SetCursorPos( line, 27 );
+    for( uint8_t i = 0; i < 8; i++ )
+    {
+        vt.printf( "%02x ", eui[i] );
+    }
+    vt.SetCursorPos( line, 50 );
+    vt.printf( "]" );
+}
+#endif /* LORAWAN_JOIN_EUI */
+
+void SerialDisplayUpdateKey( uint8_t line, const uint8_t *key )
+{
+    vt.SetCursorPos( line, 29 );
+    for( uint8_t i = 0; i < 16; i++ )
+    {
+        vt.printf( "%02x ", key[i] );
+    }
+    vt.SetCursorPos( line, 76 );
+    vt.printf( "]" );
+}
+
+void SerialDisplayUpdateNwkId( uint8_t id )
+{
+    vt.SetCursorPos( ROW_NwkId, 27 );
+    vt.printf( "%03d", id );
+}
+
+void SerialDisplayUpdateDevAddr( uint32_t addr )
+{
+    vt.SetCursorPos( ROW_DevAddr, 27 );
+    vt.printf( "%02X %02X %02X %02X", ( addr >> 24 ) & 0xFF, ( addr >> 16 ) & 0xFF, ( addr >> 8 ) & 0xFF, addr & 0xFF );
+}
+
+void SerialDisplayUpdateFrameType( bool confirmed )
+{
+    vt.SetCursorPos( ROW_FrameType, 17 );
+    SerialPrintCheckBox( confirmed, VT100::WHITE );
+    vt.SetCursorPos( ROW_FrameType, 32 );
+    SerialPrintCheckBox( !confirmed, VT100::WHITE );
+}
+
+void SerialDisplayUpdateAdr( bool adr )
+{
+    vt.SetCursorPos( ROW_ADR, 27 );
+    if( adr == true )
+    {
+        vt.printf( " ON" );
+    }
+    else
+    {
+        vt.printf( "OFF" );
+    }
+}
+
+void SerialDisplayUpdateDutyCycle( bool dutyCycle )
+{
+    vt.SetCursorPos( ROW_DUTY, 27 );
+    if( dutyCycle == true )
+    {
+        vt.printf( " ON" );
+    }
+    else
+    {
+        vt.printf( "OFF" );
+    }
+}
+
+void SerialDisplayUpdatePublicNetwork( bool network )
+{
+    vt.SetCursorPos( ROW_PUBLIC, 17 );
+    SerialPrintCheckBox( network, VT100::WHITE );
+    vt.SetCursorPos( ROW_PUBLIC, 30 );
+    SerialPrintCheckBox( !network, VT100::WHITE );
+}
+
+#ifdef LORAWAN_JOIN_EUI
+void SerialDisplayUpdateNetworkIsJoined( bool state )
+{
+    vt.SetCursorPos( ROW_JOINED, 17 );
+    SerialPrintCheckBox( !state, VT100::RED );
+    vt.SetCursorPos( ROW_JOINED, 30 );
+    SerialPrintCheckBox( state, VT100::GREEN );
+}
+#endif /* LORAWAN_JOIN_EUI */
+
+/*void SerialDisplayUpdateLedState( uint8_t id, uint8_t state )
+{
+    switch( id )
+    {
+        case 1:
+            vt.SetCursorPos( 22, 17 );
+            SerialPrintCheckBox( state, VT100::RED );
+            break;
+        case 2:
+            vt.SetCursorPos( 22, 31 );
+            SerialPrintCheckBox( state, VT100::GREEN );
+            break;
+        case 3:
+            vt.SetCursorPos( 22, 45 );
+            SerialPrintCheckBox( state, VT100::BLUE );
+            break;
+    }
+}*/
+
+void SerialDisplayUpdateData( uint8_t line, const uint8_t *buffer, uint8_t size )
+{
+    if( size != 0 )
+    {
+        vt.SetCursorPos( line, 27 );
+        for( uint8_t i = 0; i < size; i++ )
+        {
+            vt.printf( "%02X ", buffer[i] );
+            if( ( ( i + 1 ) % 16 ) == 0 )
+            {
+                line++;
+                vt.SetCursorPos( line, 27 );
+            }
+        }
+        for( uint8_t i = size; i < 64; i++ )
+        {
+            vt.printf( "__ " );
+            if( ( ( i + 1 ) % 16 ) == 0 )
+            {
+                line++;
+                vt.SetCursorPos( line, 27 );
+            }
+        }
+        vt.SetCursorPos( line - 1, 74 );
+        vt.printf( "]" );
+    }
+    else
+    {
+        vt.SetCursorPos( line, 27 );
+        for( uint8_t i = 0; i < 64; i++ )
+        {
+            vt.printf( "__ " );
+            if( ( ( i + 1 ) % 16 ) == 0 )
+            {
+                line++;
+                vt.SetCursorPos( line, 27 );
+            }
+        }
+        vt.SetCursorPos( line - 1, 74 );
+        vt.printf( "]" );
+    }
+}
+
+void SerialDisplayUpdateUplinkAcked( bool state )
+{
+    vt.SetCursorPos( ROW_UPLINK_ACKED, 36 );
+    SerialPrintCheckBox( state, VT100::GREEN );
+}
+
+//void SerialDisplayUpdateUplink( bool acked, uint8_t datarate, uint32_t counter, uint8_t port, uint8_t *buffer, uint8_t bufferSize, LoRaMacEventInfoStatus_t s)
+void SerialDisplayUplink(uint8_t fport, const uint8_t* buffer, uint8_t bufferSize )
+{
+    vt.SetCursorPos( ROW_DOWNLINK_RSSI, 32 );
+    vt.printf( "     ");
+    vt.SetCursorPos( ROW_DOWNLINK_SNR, 32 );
+    vt.printf( "     ");
+
+    // Port
+    vt.SetCursorPos( ROW_UPLINK_PORT, 34 );
+    vt.printf( "%3u", fport );
+    // Data
+    SerialDisplayUpdateData( ROW_UPLINK_PAYLOAD, buffer, bufferSize );
+}
+
+void SerialDisplayMcpsConfirm( const McpsConfirm_t* mc)
+{
+    char str[48];
+    static uint8_t lastStrLen = 0;
+    // Acked
+    SerialDisplayUpdateUplinkAcked(mc->AckReceived);
+    LoRaMacEventInfoStatus_to_string(mc->Status, str);
+    vt.printf("]  %s", str);
+    for (unsigned n = 0; n < lastStrLen; n++)
+        vt.putc(' ' );
+    lastStrLen = strlen(str);
+    // Datarate
+    vt.SetCursorPos( ROW_UPLINK_DR, 33 );
+    vt.printf( "DR%u", mc->Datarate);
+    // Counter
+    vt.SetCursorPos( ROW_UPLINK_FCNT, 27 );
+    vt.printf( "%10" PRIu32, mc->UpLinkCounter);
+}
+
+void SerialDisplayMcpsIndication()
+{
+}
+
+void SerialDisplayUpdateDonwlinkRxData( bool state )
+{
+    vt.SetCursorPos( ROW_DOWNLINK_SNR, 4 );
+    SerialPrintCheckBox( state, VT100::GREEN );
+}
+
+void SerialDisplayMcpsIndication(const McpsIndication_t* mi)
+{
+    int8_t Snr;
+
+    vt.SetCursorPos( ROW_DOWNLINK_RSSI, 32 );
+    vt.printf( "%5d", mi->Rssi );
+
+    if (mi->Snr & 0x80) { // The SNR sign bit is 1
+        // Invert and divide by 4
+        Snr = ( ( ~mi->Snr + 1 ) & 0xFF ) >> 2;
+        Snr = -Snr;
+    } else {
+        // Divide by 4
+        Snr = ( mi->Snr & 0xFF ) >> 2;
+    }
+    vt.SetCursorPos( ROW_DOWNLINK_SNR, 32 );
+    vt.printf( "%5d", Snr );
+
+    vt.SetCursorPos( ROW_DOWNLINK_FCNT, 27 );
+    vt.printf( "%10" PRIu32, mi->receivedFCntDown);
+
+    SerialDisplayUpdateDonwlinkRxData(mi->RxData);
+    vt.SetCursorPos( ROW_DOWNLINK_FPORT, 34 );
+    if (mi->RxData) {
+        vt.printf( "%3u", mi->Port);
+        SerialDisplayUpdateData( ROW_DOWNLINK_PAYLOAD, mi->Buffer, mi->BufferSize );
+    } else {
+        vt.printf("   ");
+        SerialDisplayUpdateData( ROW_DOWNLINK_PAYLOAD, NULL, 0 );
+    }
+    /*if (mcpsIndication->RxData) {
+        LoRaMacDownlinkStatus.Port = mcpsIndication->Port;
+        LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
+        LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
+    } else
+        LoRaMacDownlinkStatus.Buffer = NULL;*/
+}
+
+#if 0
+void SerialDisplayUpdateDownlink( int16_t rssi, int8_t snr, uint32_t counter, uint8_t port, uint8_t *buffer, uint8_t bufferSize )
+{
+    // Rx data
+    SerialDisplayUpdateDonwlinkRxData( buffer != NULL );
+    // RSSI
+    vt.SetCursorPos( ROW_DOWNLINK_RSSI, 32 );
+    vt.printf( "%5d", rssi );
+    // SNR
+    vt.SetCursorPos( ROW_DOWNLINK_SNR, 32 );
+    vt.printf( "%5d", snr );
+    // Counter
+    vt.SetCursorPos( ROW_DOWNLINK_FCNT, 27 );
+    vt.printf( "%10" PRIu32, counter );
+    if( buffer != NULL )
+    {
+        // Port
+        vt.SetCursorPos( ROW_DOWNLINK_FPORT, 34 );
+        vt.printf( "%3u", port );
+        // Data
+        SerialDisplayUpdateData( ROW_DOWNLINK_PAYLOAD, buffer, bufferSize );
+    }
+    else
+    {
+        // Port
+        vt.SetCursorPos( ROW_DOWNLINK_FPORT, 34 );
+        vt.printf( "   " );
+        // Data
+        SerialDisplayUpdateData( ROW_DOWNLINK_PAYLOAD, NULL, 0 );
+    }
+}
+#endif /* if 0 */
+
+void SerialDisplayDrawFirstLine( void )
+{
+    vt.PutBoxDrawingChar( 'l' );
+    for( int8_t i = 0; i <= 77; i++ )
+    {
+        vt.PutBoxDrawingChar( 'q' );
+    }
+    vt.PutBoxDrawingChar( 'k' );
+    vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawTitle( const char* title )
+{
+    vt.PutBoxDrawingChar( 'x' );
+    vt.printf( "%s", title );
+    vt.PutBoxDrawingChar( 'x' );
+    vt.printf( "\r\n" );
+}
+void SerialDisplayDrawTopSeparator( void )
+{
+    vt.PutBoxDrawingChar( 't' );
+    for( int8_t i = 0; i <= 11; i++ )
+    {
+        vt.PutBoxDrawingChar( 'q' );
+    }
+    vt.PutBoxDrawingChar( 'w' );
+    for( int8_t i = 0; i <= 64; i++ )
+    {
+        vt.PutBoxDrawingChar( 'q' );
+    }
+    vt.PutBoxDrawingChar( 'u' );
+    vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawColSeparator( void )
+{
+    vt.PutBoxDrawingChar( 'x' );
+    for( int8_t i = 0; i <= 11; i++ )
+    {
+        vt.PutBoxDrawingChar( ' ' );
+    }
+    vt.PutBoxDrawingChar( 't' );
+    for( int8_t i = 0; i <= 64; i++ )
+    {
+        vt.PutBoxDrawingChar( 'q' );
+    }
+    vt.PutBoxDrawingChar( 'u' );
+    vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawSeparator( void )
+{
+    vt.PutBoxDrawingChar( 't' );
+    for( int8_t i = 0; i <= 11; i++ )
+    {
+        vt.PutBoxDrawingChar( 'q' );
+    }
+    vt.PutBoxDrawingChar( 'n' );
+    for( int8_t i = 0; i <= 64; i++ )
+    {
+        vt.PutBoxDrawingChar( 'q' );
+    }
+    vt.PutBoxDrawingChar( 'u' );
+    vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawLine( const char* firstCol, const char* secondCol )
+{
+    vt.PutBoxDrawingChar( 'x' );
+    vt.printf( "%s", firstCol );
+    vt.PutBoxDrawingChar( 'x' );
+    vt.printf( "%s", secondCol );
+    vt.PutBoxDrawingChar( 'x' );
+    vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawBottomLine( void )
+{
+    vt.PutBoxDrawingChar( 'm' );
+    for( int8_t i = 0; i <= 11; i++ )
+    {
+        vt.PutBoxDrawingChar( 'q' );
+    }
+    vt.PutBoxDrawingChar( 'v' );
+    for( int8_t i = 0; i <= 64; i++ )
+    {
+        vt.PutBoxDrawingChar( 'q' );
+    }
+    vt.PutBoxDrawingChar( 'j' );
+    vt.printf( "\r\n" );
+}
+
+void SerialDisplayInit( void )
+{
+    vt.ClearScreen( 2 );
+    vt.SetCursorMode( false );
+    vt.SetCursorPos( 0, 0 );
+    
+    // "+-----------------------------------------------------------------------------+" );
+    SerialDisplayDrawFirstLine( );
+    // "¦                      LoRaWAN Demonstration Application                      ¦" );
+    SerialDisplayDrawTitle( "                      LoRaWAN Demonstration Application                       " );
+    // "+------------+----------------------------------------------------------------¦" );
+    SerialDisplayDrawTopSeparator( );
+#ifdef LORAWAN_JOIN_EUI
+    // "¦ Activation ¦ [ ]Over The Air                                                ¦" );
+    SerialDisplayDrawLine( " Activation ", " [ ]Over The Air                                                 " );
+    // "¦            ¦ DevEui    [__ __ __ __ __ __ __ __]                            ¦" );
+    SerialDisplayDrawLine( "            ", " DevEui    [__ __ __ __ __ __ __ __]                             " );
+    // "¦            ¦ JoinEui   [__ __ __ __ __ __ __ __]                            ¦" );
+    SerialDisplayDrawLine( "            ", " JoinEui   [__ __ __ __ __ __ __ __]                             " );
+    // "¦            ¦ NwkKey  [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]      ¦" );
+    SerialDisplayDrawLine( "            ", " NwkKey      [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]   " );
+#ifdef OPTNEG
+    SerialDisplayDrawLine( "            ", " AppKey      [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]   " );
+#endif
+    // "¦            +----------------------------------------------------------------¦" );
+    SerialDisplayDrawColSeparator( );
+#endif /* LORAWAN_JOIN_EUI */
+    // "¦            ¦ [x]Personalisation                                             ¦" );
+    SerialDisplayDrawLine( "            ", " [ ]Personalisation                                              " );
+    // "¦            ¦ NwkId     [___]                                                ¦" );
+    SerialDisplayDrawLine( "            ", " NwkId     [___]                                                 " );
+    // "¦            ¦ DevAddr   [__ __ __ __]                                        ¦" );
+    SerialDisplayDrawLine( "            ", " DevAddr   [__ __ __ __]                                         " );
+#ifdef OPTNEG
+    SerialDisplayDrawLine( "            ", " FNwkSIntKey [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]   ");
+    SerialDisplayDrawLine( "            ", " SNwkSIntKey [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]   ");
+    SerialDisplayDrawLine( "            ", " NwkSEncKey  [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]   ");
+#else
+    // "¦            ¦ NwkSKey   [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]    ¦" );
+    SerialDisplayDrawLine( "            ", " NwkSKey     [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]   ");
+#endif
+    // "¦            ¦ AppSKey   [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]    ¦" );
+    SerialDisplayDrawLine( "            ", " AppSKey     [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]   ");
+    // "+------------+----------------------------------------------------------------¦" );
+    SerialDisplayDrawSeparator( );
+    // "¦ MAC params ¦ [ ]Confirmed / [ ]Unconfirmed                                  ¦" );
+    SerialDisplayDrawLine( " MAC params ", " [ ]Confirmed / [ ]Unconfirmed                                   " );
+    // "¦            ¦ ADR       [   ]                                                ¦" );
+    SerialDisplayDrawLine( "            ", " ADR       [   ]                                                 " );
+    // "¦            ¦ Duty cycle[   ]                                                ¦" );
+    SerialDisplayDrawLine( "            ", " Duty cycle[   ]                                                 " );
+    // "+------------+----------------------------------------------------------------¦" );
+    SerialDisplayDrawSeparator( );
+    // "¦ Network    ¦ [ ]Public  / [ ]Private                                        ¦" );
+    SerialDisplayDrawLine( " Network    ", " [ ]Public  / [ ]Private                                         " );
+#ifdef LORAWAN_JOIN_EUI
+    // "¦            ¦ [ ]Joining / [ ]Joined                                         ¦" );
+    SerialDisplayDrawLine( "            ", " [ ]Joining / [ ]Joined                                          " );
+#endif /* LORAWAN_JOIN_EUI */
+    // "+------------+----------------------------------------------------------------¦" );
+    SerialDisplayDrawSeparator( );
+    // "¦ Uplink     ¦ Acked              [ ]                                         ¦" );
+    SerialDisplayDrawLine( " Uplink     ", " Acked              [ ]                                          " );
+    // "¦            ¦ Datarate        [    ]                                         ¦" );
+    SerialDisplayDrawLine( "            ", " Datarate        [    ]                                          " );
+    // "¦            ¦ Counter   [          ]                                         ¦" );
+    SerialDisplayDrawLine( "            ", " Counter   [          ]                                          " );
+    // "¦            ¦ Port             [   ]                                         ¦" );
+    SerialDisplayDrawLine( "            ", " Port             [   ]                                          " );
+    // "¦            ¦ Data      [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __     ¦" );
+    SerialDisplayDrawLine( "            ", " Data      [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __      " );
+    // "¦            ¦            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __     ¦" );
+    SerialDisplayDrawLine( "            ", "            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __      " );
+    // "¦            ¦            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __     ¦" );
+    SerialDisplayDrawLine( "            ", "            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __      " );
+    // "¦            ¦            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __     ¦" );
+    SerialDisplayDrawLine( "            ", "            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __      " );
+    // "+------------+----------------------------------------------------------------¦" );
+    SerialDisplayDrawSeparator( );
+    // "¦ Downlink   ¦ RSSI           [     ] dBm                                     ¦" );
+    SerialDisplayDrawLine( " Downlink   ", " RSSI           [     ] dBm                                      " );
+    // "¦ [ ]Data    ¦ SNR      [     ] dB                                            ¦" );
+    SerialDisplayDrawLine( " [ ]Data    ", " SNR            [     ] dB                                       " );
+    // "¦            ¦ Counter  [          ]                                          ¦" );
+    // "¦            ¦ Counter   [          ]                                         ¦" );
+    SerialDisplayDrawLine( "            ", " Counter   [          ]                                          " );
+    // "¦            ¦ Port             [   ]                                         ¦" );
+    SerialDisplayDrawLine( "            ", " Port             [   ]                                          " );
+    // "¦            ¦ Data      [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __     ¦" );
+    SerialDisplayDrawLine( "            ", " Data      [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __      " );
+    // "¦            ¦            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __     ¦" );
+    SerialDisplayDrawLine( "            ", "            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __      " );
+    // "¦            ¦            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __     ¦" );
+    SerialDisplayDrawLine( "            ", "            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __      " );
+    // "¦            ¦            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __     ¦" );
+    SerialDisplayDrawLine( "            ", "            __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __      " );
+    // "+------------+----------------------------------------------------------------+" );
+    SerialDisplayDrawBottomLine( );
+    vt.printf( "To refresh screen please hit 'r' key.\r\n" );
+}
+
+bool SerialDisplayReadable( void )
+{
+    return vt.Readable( );
+}
+
+uint8_t SerialDisplayGetChar( void )
+{
+    return vt.GetChar( );
+}
+
+#endif /* ENABLE_VT100 */
+