football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Revision:
18:affef3a7db2a
Parent:
17:d8b901d791fd
Child:
19:afcbb425b3cf
--- a/main.cpp	Tue Nov 03 07:05:15 2015 +0000
+++ b/main.cpp	Sun Nov 29 13:52:53 2015 +0000
@@ -34,6 +34,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <cstdarg>
+#include <cstdio>
 
 #include "mbed.h"
 // #include "rtos.h"
@@ -46,6 +48,8 @@
 #include "MTSSerialFlowControl.h"
 #include "PhoneAppIO.h"
 
+#include "TA.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. */
 
@@ -61,7 +65,7 @@
 void setup();
 void getRadioInput(char *ibuffer, int size);
 
-Timer tmr;
+static Timer tmr;
 
 unsigned long millis()
 {
@@ -85,23 +89,23 @@
 }
 
 // DigitalOut rts( RTS_PIN_NUMBER );
-DigitalIn cts( CTS_PIN_NUMBER, PullDown );  // We'll use as a mode switch for serial data source.  TODO
+//DigitalIn cts( CTS_PIN_NUMBER, PullDown );  // We'll use as a mode switch for serial data source.  TODO
 
 // Check if we should swap serial Rx/Tx for early rev of "Little Brain"
-DigitalIn trSwp( P0_30, PullUp );
+//DigitalIn trSwp( P0_30, PullUp );
 
 // Wait to settle.
 int foo = (wait( 0.1 ), 0);
 
 // Not using "LED" or "LED1" because target NRF51822 for FOTA uses different pins.
-DigitalOut led0( P0_19, 1 );                  // BLE Nano      Low =On
-DigitalOut led1( P0_3,  0 );                  // TA Baseboard  High=On  (OK on Nano: Alt RxD)
+static DigitalOut led0( P0_19, 1 );                  // BLE Nano      Low =On
+static DigitalOut led1( P0_3,  0 );                  // TA Baseboard  High=On  (OK on Nano: Alt RxD)
 // DigitalOut led1( (trSwp ? P0_4 : P0_3), 0 );  // TA Baseboard  High=On  (And don't use P0_4 on Nano)
 
 // App timer, app scheduler, and pstorage are already setup by bootloader.
 
-BLEDevice  ble;
-
+static BLEDevice  ble;
+//int trSwp = 0;
 
 // Note:  From the datasheet:
 //  PSELRXD, PSELRTS, PSELTRTS and PSELTXD must only be configured when the UART is disabled.
@@ -119,7 +123,7 @@
 //  internal buffer--Rx servicing usually is fast enough not to need hw flow control, so it's okay.
 //
 // mts::MTSSerialFlowControl pcfc( (trSwp ? USBRX : USBTX), (trSwp ? USBTX : USBRX), RTS_PIN_NUMBER, CTS_PIN_NUMBER, 384, 2688 );
-mts::MTSSerial pcfc( (trSwp ? USBRX : USBTX), (trSwp ? USBTX : USBRX), 256, 1280, RTS_PIN_NUMBER, NC );  // 256, 2560
+//mts::MTSSerial pcfc( USBTX, USBRX, 256, 1280, RTS_PIN_NUMBER, NC );  // 256, 2560
 
 uint8_t txPayload[TXRX_BUF_LEN] = { 0 };
 
@@ -128,32 +132,36 @@
 Gap::address_t   macAddr;
 Gap::addr_type_t *pAdType;
 
+// Buffer for holding data from the phone
+// to the device
+static char phoneToDev[200] = {0};
 
-// const uint8_t DevInfoServiceUUID_rev[] =
-// {
-//     (uint8_t)(GattService::UUID_DEVICE_INFORMATION_SERVICE & 0xFF), (uint8_t)(GattService::UUID_DEVICE_INFORMATION_SERVICE >> 8)
-// };
+// Current position in the buffer
+static int phoneToDevPos = 0; 
 
 UARTService *uartServicePtr;
 PhoneAppIO  *phoneP;
 
+extern TA ta;
+
+extern void radio_init();
+extern void radio_loop();
+
+// True when connected to a phone
 bool connected = false;
 
 void connectionCallback( Gap::Handle_t, Gap::addr_type_t peerAddrType,
                          const Gap::address_t peerAddr, const Gap::ConnectionParams_t *connParams )
 {
     connected = true;
-
-    DEBUG( "Connected!\n\r" );
 }
 
 void disconnectionCallback( Gap::Handle_t handle, Gap::DisconnectionReason_t reason )
 {
     connected = false;
 
-    DEBUG( "Disconnected!\n\r" );
-    DEBUG( "Restarting the advertising process\n\r" );
     ble.startAdvertising();
+    ta.post_color(0);
 }
 
 bool updateCharacteristic( GattAttribute::Handle_t handle, const uint8_t *data, uint16_t bytesRead )
@@ -163,7 +171,7 @@
     if( (err == BLE_ERROR_BUFFER_OVERFLOW) ||
         (err == BLE_ERROR_PARAM_OUT_OF_RANGE ) )
     {
-        pcfc.printf( "\r\nBLE %d!  ", err );
+       // pcfc.printf( "\r\nBLE %d!  ", err );
 
     } else if ( err == BLE_STACK_BUSY )
       {
@@ -173,35 +181,60 @@
     return  (err != BLE_ERROR_NONE);
 }
 
-void writeToPhone(char *data)
+/* Writes the string given to the phone.
+ *
+ * @param *data - the string to send.
+ */
+static void writeToPhoneImpl(char *data)
 {
-    pcfc.write(data, strlen(data));
     if (phoneP != NULL)
     {
-        //phoneP->puts(data);
+       for (int i = 0; i < strlen(data); ++i)
+       {
+            phoneP->putchar(data[i]);
             
+            // If we don't call maybeHandleWrite all hell breaks loose and 
+            // the app crashes. :(
+            if (i != 0 && i % 10 == 0)
+            { 
+                int counter = 0;
+                while(phoneP->maybeHandleWrite() == 0 && ++counter < 20)
+                { 
+                    wait_us(1);
+                }
+            }
+        }
+        
+        phoneP->maybeHandleWrite();
     }
 }
 
+static char wtp_buff[150] = {0};
+extern "C" void writeToPhone(char *format, ...)
+{
+    va_list arg;
+    va_start(arg, format );
+    
+    vsnprintf(wtp_buff, sizeof(wtp_buff), format, arg);
+    
+    writeToPhoneImpl(wtp_buff);    
+    va_end(arg);
+}
+
 void onDataWritten( const GattCharacteristicWriteCBParams *params )
 {
     if( phoneP != NULL )
     {
         uint16_t bytesRead = phoneP->maybeHandleRead( params );  // Also writes to txPayload
+        
         if( 0 != bytesRead )
         {
-            DEBUG( "received %u bytes\n\r", bytesRead );
-            getRadioInput((char*)txPayload, bytesRead );
-            // Also write to serial port...
-//            pcfc.printf( "From app: " );
-            pcfc.write( (char *)txPayload, bytesRead );
-//            pcfc.printf( "\r\n" );
-
+            memcpy(phoneToDev+phoneToDevPos, txPayload, bytesRead);
+            phoneToDevPos += bytesRead;
+            
             return;
         }
     }
-
-    // Other Characteristics here.
 }
 
 void onDataSent( unsigned count )
@@ -210,27 +243,7 @@
 
 void toPhoneChk( void )
 {
-//    if( 0 != rts.read() )  pcfc.puts( "\r\n!RTS disengaged.\r\n" );  // When not using HWFC.
 
-    if( phoneP != NULL )
-    {
-        char ch;
-        // Get any data from serial port buffer--Full lines if avail--Last line after >= 20 chars.
-        for( int cnt=1; 0 != pcfc.atomicRead( ch ); cnt++ )
-        {
-            if( 0 > phoneP->putchar( ch ) )
-            {
-                pcfc.printf( " * " );
-                break;
-            }
-            if( (cnt >= 20) && ('\n' == ch) )  break;
-        }
-        // Write to outgoing characteristic if anything is pending.
-        if( 0 != phoneP->maybeHandleWrite() )
-        {
-            // pcfc.printf( "ToPhoneHandler \r\n" );
-        }
-    }
 }
 
 
@@ -308,7 +321,7 @@
         } else
           {
               // Load operation failed.
-              pcfc.printf( "\r\nWarn: pstorage load operation error: %x\r\n", result );
+              //pcfc.printf( "\r\nWarn: pstorage load operation error: %x\r\n", result );
           }
         break;       
       case PSTORAGE_UPDATE_OP_CODE:
@@ -321,7 +334,7 @@
         } else
           {
               // Store operation failed.
-              pcfc.printf( "\r\nWarn: pstorage store operation error: %x\r\n", result );
+              //pcfc.printf( "\r\nWarn: pstorage store operation error: %x\r\n", result );
           }
         // Source memory can now be reused or freed.
         break;
@@ -334,11 +347,9 @@
         } else
           {
               // Clear operation failed.
-              pcfc.printf( "\r\nWarn: pstorage clear operation error: %x\r\n", result );
+              //pcfc.printf( "\r\nWarn: pstorage clear operation error: %x\r\n", result );
           }
         break;
-      default:
-        pcfc.printf( "\r\nWarn: pstorage unknown op: %x  error: %x\r\n", op_code, result );
     }
 }
 static uint32_t pstorage_setup()
@@ -355,8 +366,8 @@
 
 void periodicCallback( void )
 {
-    //led0 = !led0;
-    //led1 = !led1;
+    led0 = !led0;
+    led1 = !led1;
 //    rts  = !rts;
 }
 
@@ -375,18 +386,11 @@
 
 int main( void )
 {
-    // NVIC_SetVector( UART0_IRQn, (uint32_t)My_UART0_IRQHandler );  // TODO maybe try before instantiating pcfc.
-
     Ticker ticker;
-    ticker.attach( periodicCallback, .01 );
-    // Thread thread( led_thread );
-
-    pcfc.baud( 57600 );
-
-    DEBUG( "Initialising the nRF51822\n\r" );
-
+    ticker.attach( periodicCallback, 0.1 );
 
     ble.init();
+    
     ble.onConnection( connectionCallback );
     ble.onDisconnection( disconnectionCallback );
     ble.onDataWritten( onDataWritten );
@@ -395,48 +399,22 @@
     /* setup advertising */
     ble.accumulateAdvertisingPayload( GapAdvertisingData::BREDR_NOT_SUPPORTED |
                                       GapAdvertisingData::LE_GENERAL_DISCOVERABLE );
+                                      
     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 );
-#if LOOPBACK_MODE
-    pcfc.printf( "\r\nIn BLE Loopback mode.\r\n" );
-#endif
-
     uint32_t p_count;
     uint32_t pstorageErr = pstorage_init();  // This needs to be called, even though apparently called in bootloader--Check other stuff.
     pstorage_access_status_get( &p_count );
-//    pcfc.printf( "\r\nInitial pstorage count: %d\r\n", p_count );
-
-    if( NRF_SUCCESS != pstorageErr )  pcfc.printf( "\r\nWarn: pstorage init error: %x\r\n", pstorageErr );
-      else
-      {
-          pstorageErr = pstorage_setup();
-          if( NRF_SUCCESS != pstorageErr )  pcfc.printf( "\r\nWarn: pstorage setup error: %x\r\n", pstorageErr );
-            else
-            {                
-                pstorageErr = pstorage_read_test();
-                if( NRF_SUCCESS != pstorageErr )  pcfc.printf( "\r\nWarn: pstorage read attempt error: %x\r\n", pstorageErr );
-                  else
-                  {
-                      // In this test setup, we use the load callback to signal start to clear,
-                      //  then we use the clear callback to signal start to write.
-                  }
-            }
-      }
 
     ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LOCAL_NAME,
                                       (const uint8_t *)deviceName, strlen(deviceName) );
     ble.accumulateAdvertisingPayload( GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS,
                                       (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed) );
 
-// Necessary?
-//    ble.accumulateScanResponse( GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
-//                                      (const uint8_t *)DevInfoServiceUUID_rev, sizeof(DevInfoServiceUUID_rev) );
 
     ble.setAdvertisingInterval( Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( 200 ) );
     ble.startAdvertising();
@@ -448,62 +426,42 @@
      * handover control to a resident bootloader. */
     DFUService dfu( ble );
 
-    UARTService uartService( ble );
+    UARTService uartService ( ble );
     uartServicePtr = &uartService;
 
-    PhoneAppIO phone( ble, uartService.getRXCharacteristicHandle(),
-                           uartService.getTXCharacteristicHandle() );
-    phone.loopbackMode = LOOPBACK_MODE;
-    phoneP = &phone;
-
+    PhoneAppIO *phone = new PhoneAppIO(ble, 
+                                       uartServicePtr->getRXCharacteristicHandle(),
+                                       uartServicePtr->getTXCharacteristicHandle() );
+                           
+    phone->loopbackMode = LOOPBACK_MODE;
+    phoneP = phone;
+    
+    DigitalOut *buzzPin = new DigitalOut(p20);
+    *buzzPin = 1;
     setup();
-
+    //radio_init();
     tmr.start();
-
+    
     // Main Loop
     while( true)
     {
         ble.waitForEvent();
-    
-        toPhoneChk();  // Write any pending data to phone.
-
-        while( 0 <= phone.getchar() );  // Eat input.
-
-//        if( !(loop % 50) )  phone.printf( "Post: %d\r\n", tmr.read_ms() );
-
+        
+        if (phoneToDevPos > 0)
+        {
+            getRadioInput(phoneToDev, phoneToDevPos ); 
+            phoneToDevPos = 0;   
+        }
+        
         loop();
-
-        app_sched_execute();  // Attempt to get pstorage enqueued cmd callbacks.
-
-        // Update persistent storage if ready...
-        if( data_loaded )
+        //radio_loop();
+        
+        if (connected)
         {
-            data_loaded = false;
-
-            boot_cnt_data++;
-            pcfc.printf( "\r\nApp boot #%d\r\n", boot_cnt_data );
+            phoneP->maybeHandleWrite(); 
+        }
 
-            pstorageErr = pstorage_clear_test();
-//            pcfc.printf( "pstorage clear command sent.\r\n" );
-            if( NRF_SUCCESS != pstorageErr )  pcfc.printf( "\r\nWarn: pstorage clear attempt error: %x\r\n", pstorageErr );
- 
-        } else if( data_cleared )
-          {
-              data_cleared  = false;
-
-//              pcfc.printf( "\r\npstorage clear operation successful.\r\n" );
-
-              pstorageErr = pstorage_write_test();
-//              pcfc.printf( "pstorage write command sent.\r\n" );
-              if( NRF_SUCCESS != pstorageErr )  pcfc.printf( "\r\nWarn: pstorage write attempt error: %x\r\n", pstorageErr );
-
-          } else if( data_stored )
-            {
-                data_stored = false;
-
-//                pcfc.printf( "\r\npstorage store operation successful.\r\n" );
-            }
-
+        while( 0 <= phone->getchar() );  // Eat input.
     }
 }
 
@@ -519,7 +477,7 @@
 void $Sub$$app_error_handler( uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name )
 {
     // nrf_gpio_pin_set( ASSERT_LED_PIN_NO );
-    led1 = 1;
+    //led1 = 1;
 
     // This call can be used for debug purposes during application development.
     // @note CAUTION: Activating this code will write the stack to flash on an error.