Andriy Makukha / Mbed 2 deprecated football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Files at this revision

API Documentation at this revision

Comitter:
AntonLS
Date:
Fri Apr 17 04:20:07 2015 +0000
Parent:
4:17b8edf264c3
Child:
6:ef758ac3c928
Commit message:
Waits for BLE ready on characteristic update.

Changed in this revision

PhoneAppIO.cpp Show annotated file Show diff for this revision Revisions of this file
PhoneAppIO.h Show annotated file Show diff for this revision Revisions of this file
io/MTSSerial.cpp Show annotated file Show diff for this revision Revisions of this file
io/MySerial.cpp Show annotated file Show diff for this revision Revisions of this file
io/MySerial.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
utils/Vars.h Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PhoneAppIO.cpp	Fri Apr 17 04:20:07 2015 +0000
@@ -0,0 +1,63 @@
+/*
+ *  Buffered IO of pending CharacteristicWrites meant to Nofify
+ *   the phone/tablet application.   ALS  20150416
+ *
+ */
+
+#include "PhoneAppIO.h"
+
+PhoneAppIO::PhoneAppIO( BLEDevice *ble, int txBufferSize, int rxBufferSize )
+            : mts::MTSBufferedIO( txBufferSize, rxBufferSize )
+{
+    PhoneAppIO::ble = ble;
+    data            = NULL;
+    bytesRead       = 0;
+}
+
+PhoneAppIO::~PhoneAppIO()
+{
+}
+
+
+void PhoneAppIO::toPhoneBuf( uint8_t *data, uint16_t bytesRead )
+{
+    PhoneAppIO::data      = data;
+    PhoneAppIO::bytesRead = bytesRead;
+    handleRead();
+}
+
+void PhoneAppIO::handleRead()
+{
+    int charsToBuf = rxBuffer.write( (char *)data, bytesRead );
+    if( charsToBuf != bytesRead )
+    {
+        printf( "[ERROR] ToPhoneCharacteristic Data Lost, tried %d, got %d\r\n", bytesRead, charsToBuf );
+    }
+}
+
+void PhoneAppIO::handleWrite()
+{
+    /** This method should be used to transfer
+    * data from the internal write buffer (txBuffer) to the physical interface.
+    * Note that this function is called everytime new data is written to the
+    * txBuffer though one of the write calls.
+    */
+
+    while( txBuffer.size() != 0 )
+    {
+        if( 1 /* ble. writeable() */ )
+        {
+            char byte;
+            if( txBuffer.read( byte ) == 1 )
+            {
+                // Write Characteristic
+            }
+
+        } else
+          {
+              return;
+          }
+    }
+}
+
+/* EOF */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PhoneAppIO.h	Fri Apr 17 04:20:07 2015 +0000
@@ -0,0 +1,88 @@
+/*
+ *  Buffered IO of pending CharacteristicWrites meant to Nofify
+ *   the phone/tablet application.   ALS  20150416
+ *
+ */
+
+#ifndef PHONEAPPIO_H
+#define PHONEAPPIO_H
+
+#include "mbed.h"
+#include "BLEDevice.h"
+#include <cstdarg>
+#include "MTSBufferedIO.h"
+
+#define STRING_STACK_LIMIT    120
+
+// namespace moo
+// {
+
+class PhoneAppIO : public mts::MTSBufferedIO
+{
+  public:
+    PhoneAppIO( BLEDevice *ble, int txBufferSize=1280, int rxBufferSize=1280 );
+
+    /** Destructs an MTSSerial object and frees all related resources, including
+    * internal buffers.
+    */
+    ~PhoneAppIO();
+
+    /** Write a string to the buffer
+     *
+     * @param str The string to write
+     *
+     * @returns 0 if the write succeeds, EOF for error
+     */
+    int puts( const char *str )
+    {
+        return  write( str, strlen( str ) );
+    }
+
+    int printf( const char *format, ... )
+    {
+        va_list arg;
+        va_start( arg, format );
+
+        int len = PhoneAppIO::vprintf( format, arg );
+
+        va_end( arg );
+
+        return  len;
+    }
+    int vprintf( const char *format, va_list arg )
+    {
+        int len = vsnprintf( NULL, 0, format, arg );
+        if( len < STRING_STACK_LIMIT )
+        {
+            char temp[STRING_STACK_LIMIT];
+            vsprintf( temp, format, arg );
+            puts( temp );
+
+        } else
+          {
+              char *temp = new char[len + 1];
+              vsprintf( temp, format, arg );
+              puts( temp );
+              delete[] temp;
+          }
+
+        return  len;
+    }
+
+  void toPhoneBuf( uint8_t *data, uint16_t bytesRead );
+
+  protected:
+    BLEDevice  *ble;
+    uint8_t    *data;
+    uint16_t   bytesRead;
+
+  private:
+    virtual void handleWrite(); // Method for handling data to be written
+    virtual void handleRead();  // Method for handling data to be read
+};
+
+// }
+
+#endif /* PHONEAPPIO_H */
+
+/* EOF */
--- a/io/MTSSerial.cpp	Thu Apr 16 17:10:19 2015 +0000
+++ b/io/MTSSerial.cpp	Fri Apr 17 04:20:07 2015 +0000
@@ -48,7 +48,8 @@
 {
     char byte = serial.getc();
     if(rxBuffer.write(byte) != 1) {
-        printf("[ERROR] Serial Rx Byte Dropped [%c][0x%02X]\r\n", byte, byte);
+    //  printf("[ERROR] Serial Rx Byte Dropped [%c][0x%02X]\r\n", byte, byte);
+        printf( "\r\n!  " );
     }
 }
 
--- a/io/MySerial.cpp	Thu Apr 16 17:10:19 2015 +0000
+++ b/io/MySerial.cpp	Fri Apr 17 04:20:07 2015 +0000
@@ -27,6 +27,9 @@
 {
     my_serial_init( &_my_serial, tx, rx, rts, cts, _my_baud );
     serial_irq_handler( &_my_serial, _irq_handler, (uint32_t)this );
+
+    // For uart errors
+    attach( this, &MySerialBase::error_handler, (Serial::IrqType)ErrIrq );
 }
 void MySerialBase::baud( int baudrate )
 {
@@ -45,16 +48,17 @@
 {
     return  serial_writable( &_my_serial );
 }
-void MySerialBase::attach( void (*fptr)(void), SerialBase::IrqType type )
+void MySerialBase::attach( void (*fptr)(void), Serial::IrqType type )
 {
     if( fptr )
     {
         _my_irq[type].attach( fptr );
-        serial_irq_set( &_my_serial, (SerialIrq)type, 1 );
+        my_serial_irq_set( &_my_serial, (IrqType)type, 1 );
+
     } else
-    {
-        serial_irq_set( &_my_serial, (SerialIrq)type, 0 );
-    }
+      {
+          my_serial_irq_set( &_my_serial, (IrqType)type, 0 );
+      }
 }
 void MySerialBase::my_serial_init( serial_t *obj, PinName tx, PinName rx, PinName rts, PinName cts, int baudrate )
 {
@@ -116,11 +120,76 @@
         memcpy(&stdio_uart, obj, sizeof(serial_t));
     }
 }
+// Replacement for serial_irq_set() in serial_api.c so we can grab uart errors.
+void MySerialBase::my_serial_irq_set( serial_t *obj, IrqType irq, uint32_t enable )
+{
+    IRQn_Type irq_n = (IRQn_Type)0;
+
+    switch( (int)obj->uart )
+    {
+      case UART_0:
+        irq_n = UART0_IRQn;
+        break;
+    }
+
+    if( enable )
+    {
+        switch( irq )
+        {
+          case RxIrq:
+            obj->uart->INTEN |= (UART_INTENSET_RXDRDY_Msk);
+            break;
+          case TxIrq:
+            obj->uart->INTEN |= (UART_INTENSET_TXDRDY_Msk);
+            break;
+          case ErrIrq:
+            obj->uart->INTEN |= (UART_INTENSET_ERROR_Msk);
+            break;
+        }
+        NVIC_SetPriority( irq_n, 3 );
+        NVIC_EnableIRQ( irq_n );
+
+    } else
+      { // disable
+          // masked writes to INTENSET dont disable and masked writes to
+          //  INTENCLR seemed to clear the entire register, not bits.
+          //  Added INTEN to memory map and seems to allow set and clearing of specific bits as desired
+          switch( irq )
+          {
+            case RxIrq:
+              obj->uart->INTEN &= ~(UART_INTENCLR_RXDRDY_Msk);
+              break;
+            case TxIrq:
+              obj->uart->INTEN &= ~(UART_INTENCLR_TXDRDY_Msk);
+              break;
+            case ErrIrq:
+              obj->uart->INTEN &= ~(UART_INTENCLR_ERROR_Msk);
+              break;
+          }
+
+          if( 0 == obj->uart->INTENCLR )
+          {
+              NVIC_DisableIRQ( irq_n );
+          }
+      }
+}
 void MySerialBase::_irq_handler( uint32_t id, SerialIrq irq_type )
 {
     MySerialBase *handler = (MySerialBase*)id;
     handler->_my_irq[irq_type].call();
 }
+void MySerialBase::error_handler()
+{
+    puts( "\r\nUART ERR!  " );
+
+    if( (UART_ERRORSRC_OVERRUN_Present << UART_ERRORSRC_OVERRUN_Pos) == (UART_ERRORSRC_OVERRUN_Msk & _my_serial.uart->ERRORSRC) )
+    {
+        puts( "\r\n[ERR: OVERRUN]\r\n" );
+
+        // Clear the error
+        _my_serial.uart->ERRORSRC = (UART_ERRORSRC_OVERRUN_Clear << UART_ERRORSRC_OVERRUN_Pos);
+    }
+}
 int MySerialBase::_base_getc()
 {
     return  serial_getc( &_my_serial );
--- a/io/MySerial.h	Thu Apr 16 17:10:19 2015 +0000
+++ b/io/MySerial.h	Fri Apr 17 04:20:07 2015 +0000
@@ -28,6 +28,14 @@
 class MySerialBase
 {
   public:
+
+    enum IrqType
+    {
+        RxIrq = 0,
+        TxIrq,
+        ErrIrq
+    };
+
     /** Set the baud rate of the serial port
      *
      *  @param baudrate The baudrate of the serial port (default = 9600).
@@ -61,23 +69,23 @@
     /** Attach a function to call whenever a serial interrupt is generated
      *
      *  @param fptr A pointer to a void function, or 0 to set as none
-     *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+     *  @param type Which serial interrupt to attach the member function to (MySerial::RxIrq for receive, TxIrq for transmit buffer empty)
      */
-    void attach( void (*fptr)(void), SerialBase::IrqType type=SerialBase::RxIrq );
+    void attach( void (*fptr)(void), Serial::IrqType type=Serial::RxIrq );
 
     /** Attach a member function to call whenever a serial interrupt is generated
      *
      *  @param tptr pointer to the object to call the member function on
      *  @param mptr pointer to the member function to be called
-     *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+     *  @param type Which serial interrupt to attach the member function to (MySerial::RxIrq for receive, TxIrq for transmit buffer empty)
      */
     template<typename T>
-    void attach( T* tptr, void (T::*mptr)(void), SerialBase::IrqType type=SerialBase::RxIrq )
+    void attach( T* tptr, void (T::*mptr)(void), Serial::IrqType type=Serial::RxIrq )
     {
         if( (mptr != NULL) && (tptr != NULL) )
         {
             _my_irq[type].attach( tptr, mptr );
-            serial_irq_set( &_my_serial, (SerialIrq)type, 1 );
+            my_serial_irq_set( &_my_serial, (IrqType)type, 1 );
         }
     }
 
@@ -95,11 +103,15 @@
 
     void my_serial_init( serial_t *obj, PinName tx, PinName rx, PinName rts, PinName cts, int baudrate );
 
+    void my_serial_irq_set( serial_t *obj, IrqType irq, uint32_t enable );
+
+    void error_handler();
+
     int _base_getc();
     int _base_putc( int c );
 
     serial_t        _my_serial;
-    FunctionPointer _my_irq[2];
+    FunctionPointer _my_irq[4];
     int             _my_baud;
 };
 
--- a/main.cpp	Thu Apr 16 17:10:19 2015 +0000
+++ b/main.cpp	Fri Apr 17 04:20:07 2015 +0000
@@ -27,11 +27,12 @@
 #include "DeviceInformationService.h"
 
 #include "MTSSerialFlowControl.h"
+#include "PhoneAppIO.h"
 
 #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
                                * it will have an impact on code-size and power consumption. */
 
-#define LOOPBACK_MODE         // Loopback mode
+// #define LOOPBACK_MODE         // Loopback mode
 
 #if NEED_CONSOLE_OUTPUT
 #define DEBUG(...) { printf(__VA_ARGS__); }
@@ -41,6 +42,7 @@
 
 BLEDevice  ble;
 
+
 #define TXRX_BUF_LEN  20
 
 extern "C"
@@ -59,8 +61,8 @@
 //  Since MTSSerial now uses hardware flow control by default, MTSSerialFlowControl isn't needed
 //  unless the hardware doesn't have hardware flow control capability or sw is always fast enough.
 //
-// mts::MTSSerialFlowControl pcfc( USBTX, USBRX, RTS_PIN_NUMBER, CTS_PIN_NUMBER, 1280, 1280 );
-mts::MTSSerial pcfc( USBTX, USBRX, 1280, 1280 );
+// mts::MTSSerialFlowControl pcfc( USBTX, USBRX, RTS_PIN_NUMBER, CTS_PIN_NUMBER, 1536, 1536 );
+mts::MTSSerial pcfc( USBTX, USBRX, 384, 2688 );
 
 uint8_t txPayload[TXRX_BUF_LEN] = { 0 };
 
@@ -72,7 +74,10 @@
 DigitalOut rts( RTS_PIN_NUMBER );
 
 
-const char *deviceName = "TAF00";
+char deviceName[6];  // "TAF00";
+Gap::address_t   macAddr;
+Gap::addr_type_t *pAdType;
+
 
 const uint8_t DevInfoServiceUUID_rev[] =
 { 
@@ -81,6 +86,9 @@
 
 UARTService *uartServicePtr;
 
+// PhoneAppIO toPhone( &ble );
+
+
 void disconnectionCallback( Gap::Handle_t handle, Gap::DisconnectionReason_t reason )
 {
     DEBUG( "Disconnected!\n\r" );
@@ -88,6 +96,24 @@
     ble.startAdvertising();
 }
 
+bool updateCharacteristic( GattAttribute::Handle_t handle, const uint8_t *data, uint16_t bytesRead )
+{
+    ble_error_t err;
+
+//    toPhone.toPhoneBuf( (uint8_t *)data, bytesRead );
+
+    err = ble.updateCharacteristicValue( handle, data, bytesRead );
+
+    if( (err == BLE_ERROR_BUFFER_OVERFLOW) ||
+        (err == BLE_STACK_BUSY)            || 
+        (err == BLE_ERROR_PARAM_OUT_OF_RANGE ) )
+        {
+            // pcfc.printf( "\r\nBLE %d!  ", err );
+        }
+
+    return  (err != BLE_ERROR_NONE);
+}
+
 void onDataWritten( const GattCharacteristicWriteCBParams *params )
 {
     if( (uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle()) )
@@ -99,11 +125,12 @@
 
 #ifdef LOOPBACK_MODE
         // Loopback data from Central.
-        ble.updateCharacteristicValue( uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead );  // Notifies.
+        updateCharacteristic( uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead );  // Notifies.
 #endif
 
+        ble.readCharacteristicValue( uartServicePtr->getTXCharacteristicHandle(), buf, &bytesRead );
+
         // Also write to serial port...
-        ble.readCharacteristicValue( uartServicePtr->getTXCharacteristicHandle(), buf, &bytesRead );
         memset( txPayload, 0, TXRX_BUF_LEN );
         memcpy( txPayload, buf, TXRX_BUF_LEN );
 //        pcfc.printf( "From app: " );
@@ -112,11 +139,10 @@
     }
 }
 
-// bool notReady;
+bool bleWasntReady;
 
 void onDataSent( unsigned count )
 {
-//    notReady = false;
 }
 
 void periodicCallback( void )
@@ -127,24 +153,24 @@
 
 void uartCB( void )
 {
-//    if( notReady )  return;
-
     if( 0 != rts.read() )  pcfc.puts( "\r\n!RTS disengaged.\r\n" );  // Can we read rts when in HW fc mode?
 
-
     // Set line from serial port to RX characteristic (From cone)
     while( pcfc.readable() )
     {
-        char ch;
-        pcfc.read( ch );
-        rx_buf[rx_len++] = ch;
-        if( rx_len>=20 || rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\r' )
+        if( !bleWasntReady )
         {
-//            notReady = true;
+            char ch;
+            pcfc.read( ch );
+            rx_buf[rx_len++] = ch;
+        }
+        if( bleWasntReady || rx_len>=20 || rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\r' )
+        {
+            bleWasntReady = updateCharacteristic( uartServicePtr->getRXCharacteristicHandle(), rx_buf, rx_len );  // Notifies.
 
-            ble.updateCharacteristicValue( uartServicePtr->getRXCharacteristicHandle(), rx_buf, rx_len );  // Notifies.
 //            pcfc.printf( "RecHandler \r\n" );
-            rx_len = 0;
+
+            if( !bleWasntReady )  rx_len = 0;
             break;
         }
     }
@@ -160,11 +186,6 @@
     pcfc.baud( 57600 );
     pcfc.rxClear();
     // pc.attach( uartCB, pc.RxIrq );
-    pcfc.printf( "\r\nNano nano!\r\n" );
-#ifdef LOOPBACK_MODE
-    pcfc.printf( "\r\nIn BLE Loopback mode.\r\n" );
-#endif
-
 
     DEBUG( "Initialising the nRF51822\n\r" );
 
@@ -177,6 +198,16 @@
     /* setup advertising */
     ble.accumulateAdvertisingPayload( GapAdvertisingData::BREDR_NOT_SUPPORTED );
     ble.setAdvertisingType( GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED );
+
+    // Get MAC addr so we can create a device name using it.
+    ble.getAddress( pAdType, macAddr );
+    sprintf( deviceName, "T%02X%02X", macAddr[1], macAddr[0] );
+
+    pcfc.printf( "\r\nNano nano!   I am \"%s\"\r\n", deviceName );
+#ifdef LOOPBACK_MODE
+    pcfc.printf( "\r\nIn BLE Loopback mode.\r\n" );
+#endif
+
     ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LOCAL_NAME,
                                       (const uint8_t *)deviceName, strlen(deviceName) );
     ble.accumulateAdvertisingPayload( GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS,
--- a/utils/Vars.h	Thu Apr 16 17:10:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/* Universal Socket Modem Interface Library
-* Copyright (c) 2013 Multi-Tech Systems
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#ifndef VARS_H
-#define VARS_H
-
-#include <string>
-
-namespace mts
-{
-
-#ifndef MAX
-#define MAX(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
-#endif
-
-#ifndef MIN
-#define MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
-#endif
-
-
-/// An enumeration for common responses.
-enum Code {
-    MTS_SUCCESS, MTS_ERROR, MTS_FAILURE, MTS_NO_RESPONSE
-};
-
-/** A static method for getting a string representation for the Code
-* enumeration.
-*
-* @param code a Code enumeration.
-* @returns the enumeration name as a string.
-*/
-static std::string getCodeNames(Code code)
-{
-    switch(code) {
-        case MTS_SUCCESS:
-            return "SUCCESS";
-        case MTS_ERROR:
-            return "ERROR";
-        case MTS_NO_RESPONSE:
-            return "NO_RESPONSE";
-        case MTS_FAILURE:
-            return "FAILURE";
-        default:
-            return "UNKNOWN ENUM";
-    }
-}
-
-const unsigned int PINGDELAY = 3; //Time to wait on each ping for a response before timimg out (seconds)
-const unsigned int PINGNUM = 4; //Number of pings to try on ping command
-
-//Special Payload Characters
-const char ETX    = 0x03;  //Ends socket connection
-const char DLE    = 0x10;  //Escapes ETX and DLE within Payload
-const char CR     = 0x0D;
-const char NL     = 0x0A;
-const char CTRL_Z = 0x1A;
-
-
-/** This class holds several enum types and other static variables
-* that are used throughout the rest of the SDK.
-*/
-class Vars
-{
-public:
-    /// Enumeration for different cellular radio types.
-    enum Radio {NA, E1, G2, EV2, H4, EV3, H5};
-
-    enum RelationalOperator {GREATER, LESS, EQUAL, GREATER_EQUAL, LESS_EQUAL};
-};
-
-}
-
-//Test Commit!!!
-
-#endif /* VARS_H */
\ No newline at end of file