Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of football_project by
Revision 5:1b9734e68327, committed 2015-04-17
- 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
--- /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
