Andriy Makukha
/
football_project_wo_output
football_project_wo_output
Fork of football_project by
Diff: main.cpp
- 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 = ☎ - + 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.