nRF51822 serves as the bridge between BLE central and MCU, which makes cental able to fetch photos from serial camera.

Dependencies:   BLE_API mbed nRF51822

Fork of nRF51822_blinky by RedBearLab

Committer:
stormysun513
Date:
Sun May 22 14:29:58 2016 +0000
Revision:
21:4753996b0bcb
Parent:
20:f6e313950373
Saperate turn on and off command into different packet headers

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stormysun513 12:7060e287bdae 1 #ifndef DEVICE_SERIAL_FC
stormysun513 12:7060e287bdae 2 #define DEVICE_SERIAL_FC 1
stormysun513 12:7060e287bdae 3 #endif
stormysun513 14:f62d55b7dead 4
stormysun513 13:65c9b7d667f6 5 #define APPLICATION_TIMEOUT
stormysun513 16:5552833a3401 6 #define LOW_POWER_CONSTRAINT
stormysun513 12:7060e287bdae 7
dan 0:7dec7e9ac085 8 #include "mbed.h"
stormysun513 12:7060e287bdae 9 #include "ble/BLE.h"
stormysun513 12:7060e287bdae 10 #include "ble/Gap.h"
stormysun513 12:7060e287bdae 11 #include "ringBuffer.h"
stormysun513 11:b3929de96933 12 #include "application.h"
stormysun513 11:b3929de96933 13
stormysun513 21:4753996b0bcb 14 #define DEVICE_NAME "ket_045"
stormysun513 21:4753996b0bcb 15 #define CODE_VERSION 8
stormysun513 14:f62d55b7dead 16
stormysun513 12:7060e287bdae 17 #define SDA_PIN P0_8
stormysun513 12:7060e287bdae 18 #define SCL_PIN P0_9
stormysun513 12:7060e287bdae 19 #define UARTTX_PIN P0_18
stormysun513 12:7060e287bdae 20 #define UARTRX_PIN P0_17
stormysun513 12:7060e287bdae 21 #define POWER_LED_PIN P0_11
stormysun513 12:7060e287bdae 22 #define INSERTION_LED_PIN P0_10
stormysun513 12:7060e287bdae 23 #define ANI_BATTERY_VOLTAGE_PIN P0_2
stormysun513 12:7060e287bdae 24 #define ANI_USB_CHARGE_PIN P0_3
stormysun513 12:7060e287bdae 25 #define BTN_POWER_ON_PIN P0_4
stormysun513 12:7060e287bdae 26 #define ANI_SALIVA_VOLTAGE_PIN P0_5
stormysun513 14:f62d55b7dead 27 #define STM32_ENABLE_PIN P0_12
stormysun513 12:7060e287bdae 28 #define CHECK_BUTTON_TIMES 2
stormysun513 12:7060e287bdae 29 #define CHECK_BUTTON_VOLTAGE_LEVEL 0.05f
stormysun513 12:7060e287bdae 30
stormysun513 14:f62d55b7dead 31 #ifdef LOW_POWER_CONSTRAINT
stormysun513 20:f6e313950373 32 #define LOW_POWER_THERS 103 // changed 5/21
stormysun513 14:f62d55b7dead 33 #define LOW_POWER_THERS_MARGIN 2
stormysun513 14:f62d55b7dead 34 #define MAXIMUM_LOW_POWER_COUNTER 30
stormysun513 14:f62d55b7dead 35 #endif
stormysun513 14:f62d55b7dead 36
stormysun513 11:b3929de96933 37 #define UART_BAUDRATE 14400
stormysun513 11:b3929de96933 38 #define MINIMUM_TICKER_PERIOD 2500
stormysun513 12:7060e287bdae 39
stormysun513 12:7060e287bdae 40 #define BLE_UUID_TXRX_SERVICE 0x0000 /**< The UUID of the Nordic UART Service. */
stormysun513 12:7060e287bdae 41 #define BLE_UUID_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */
stormysun513 12:7060e287bdae 42 #define BLE_UUIDS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */
stormysun513 12:7060e287bdae 43
stormysun513 12:7060e287bdae 44 #define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 //Lowest mimimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms.
stormysun513 12:7060e287bdae 45 #define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 //Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s.
stormysun513 12:7060e287bdae 46 #define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 //Highest slave latency permitted, in connection events.
stormysun513 12:7060e287bdae 47 #define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A //Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms.
stormysun513 12:7060e287bdae 48 #define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 //Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s.
stormysun513 12:7060e287bdae 49
stormysun513 11:b3929de96933 50 #define BLE_BUF_LEN 20
stormysun513 12:7060e287bdae 51 #define BLE_RETRANSMISSION_BUF 18
stormysun513 16:5552833a3401 52 #define MONITORING_PAYLOAD 5
stormysun513 12:7060e287bdae 53 #define SINGLE_UINT16_PAYLOAD 3
stormysun513 12:7060e287bdae 54 #define UART_DATA_PACKET_PAYLOAD 1
stormysun513 12:7060e287bdae 55 #define UART_PACKET_SIZE 111
stormysun513 12:7060e287bdae 56
stormysun513 12:7060e287bdae 57 typedef enum {
stormysun513 12:7060e287bdae 58 SYS_POWERSAVING = 0,
stormysun513 12:7060e287bdae 59 SYS_RELAXING_BUTTON,
stormysun513 12:7060e287bdae 60 SYS_LOCKING_BUTTON
stormysun513 12:7060e287bdae 61 }SystemStateTypeDef;
stormysun513 12:7060e287bdae 62
stormysun513 12:7060e287bdae 63 typedef enum {
stormysun513 12:7060e287bdae 64 BTN_IDLE = 0,
stormysun513 12:7060e287bdae 65 BTN_CHANGE_ANALOG,
stormysun513 12:7060e287bdae 66 BTN_CHECK_LONG_PRESS
stormysun513 12:7060e287bdae 67 }ButtonStateTypeDef;
stormysun513 12:7060e287bdae 68
stormysun513 12:7060e287bdae 69 typedef enum {
stormysun513 12:7060e287bdae 70 STM32_IDLE = 0, //Cannot receive any byte from UARTRX
stormysun513 12:7060e287bdae 71 STM32_CHECK_HEADER, //Check incoming header and forward to the client
stormysun513 12:7060e287bdae 72 STM32_IMAGE_FORWARDING //Forward image data to the client
stormysun513 12:7060e287bdae 73 }STM32StateTypeDef;
stormysun513 12:7060e287bdae 74
stormysun513 12:7060e287bdae 75 typedef enum {
stormysun513 12:7060e287bdae 76 SYS_HEADER_IMAGE_INFO = 0,
stormysun513 12:7060e287bdae 77 SYS_HEADER_SALIVA_VOLTAGE, // Not used (for debug purpose)
stormysun513 16:5552833a3401 78 SYS_HEADER_MONITORING, // Not used (for debug purpose)
stormysun513 12:7060e287bdae 79 SYS_HEADER_IMAGE_PACKET,
stormysun513 16:5552833a3401 80 SYS_HEADER_DEVICE_INFO,
stormysun513 12:7060e287bdae 81 SYS_HEADER_NO_SPECIFIC
stormysun513 12:7060e287bdae 82 }HeaderTypeDef;
stormysun513 12:7060e287bdae 83
stormysun513 12:7060e287bdae 84 typedef enum {
stormysun513 12:7060e287bdae 85 UARTRX_CHECK_FIRST_PREAMBLE = 0,
stormysun513 12:7060e287bdae 86 UARTRX_CHECK_SECOND_PREAMBLE,
stormysun513 12:7060e287bdae 87 UARTRX_TRANSFERING_DATA
stormysun513 12:7060e287bdae 88 }UARTRxStateTypeDef;
stormysun513 12:7060e287bdae 89
stormysun513 12:7060e287bdae 90 typedef enum {
stormysun513 21:4753996b0bcb 91 BLE_TURNON_MONITORING = 0, // Enable/Disable device monitoring
stormysun513 16:5552833a3401 92 BLE_CHANGE_CASSETTE_ID, // Write ID to saliva cassette
stormysun513 12:7060e287bdae 93 BLE_REQUEST_SALIVA_VOLTAGE, // Turn on saliva sampling periodically
stormysun513 12:7060e287bdae 94 BLE_REQUEST_IMAGE_INFO, // Request image header
stormysun513 12:7060e287bdae 95 BLE_REQUEST_IMAGE_BY_INDEX, // Request image data by uart packet IDs
stormysun513 12:7060e287bdae 96 BLE_END_IMAGE_TRANSFER, // Directly terminate image transferring
stormysun513 12:7060e287bdae 97 BLE_DEREQUEST_SALIVA_VOLTAGE, // Turn off saliva sampling periodically
stormysun513 12:7060e287bdae 98 BLE_SHUTDOWN, // Shutdown device
stormysun513 12:7060e287bdae 99 BLE_UNLOCK_BUTTON, // Unlock Button
stormysun513 14:f62d55b7dead 100 BLE_UART_DEBUG, // Reserved for debug Value: 0x09
stormysun513 21:4753996b0bcb 101 BLE_REQUEST_DEVICE_INFO, // Request code version
stormysun513 21:4753996b0bcb 102 BLE_CLOSE_MONITORING
stormysun513 12:7060e287bdae 103 }BLECommandTypeDef;
stormysun513 12:7060e287bdae 104
stormysun513 12:7060e287bdae 105 /* BLE Callback functions */
stormysun513 12:7060e287bdae 106 void bleInitCompleteCB(struct BLE::InitializationCompleteCallbackContext *context);
stormysun513 12:7060e287bdae 107 void bleOnConnectionCB(const Gap::ConnectionCallbackParams_t *p_conn_param);
stormysun513 12:7060e287bdae 108 void bleDisconnectionCB(const Gap::DisconnectionCallbackParams_t *params);
stormysun513 12:7060e287bdae 109 void bleCharacteristicWrittenCB(const GattWriteCallbackParams *Handler);
stormysun513 12:7060e287bdae 110 void bleReduceConnInterval(void);
dan 0:7dec7e9ac085 111
stormysun513 11:b3929de96933 112 void timerPeriodicalCB(void);
stormysun513 14:f62d55b7dead 113 void timerFlashPowerLed(void);
stormysun513 14:f62d55b7dead 114 void timerFlashInsertionLed(void);
stormysun513 12:7060e287bdae 115 void timerCheckBuffer(void);
stormysun513 12:7060e287bdae 116 void timerRoutineTasks(void);
stormysun513 12:7060e287bdae 117
stormysun513 12:7060e287bdae 118 void uartTxTransmit(uint8_t* buf, uint16_t length);
stormysun513 12:7060e287bdae 119 void uartRxCB(void);
stormysun513 11:b3929de96933 120
stormysun513 12:7060e287bdae 121 void buttonInterruptServiceRoutine(void);
stormysun513 12:7060e287bdae 122 void buttonCheckLongPress(uint8_t counter);
stormysun513 12:7060e287bdae 123 void buttonLongPressVerified(void);
stormysun513 12:7060e287bdae 124 void changeButtonPinToAnalogIn(void);
stormysun513 12:7060e287bdae 125 void changeButtonPinToInterrupt(void);
stormysun513 12:7060e287bdae 126 void shutdownDevice(void);
stormysun513 12:7060e287bdae 127
stormysun513 12:7060e287bdae 128 void resetSTM32StateType(void);
stormysun513 12:7060e287bdae 129 void requestSalivaVoltage(void);
stormysun513 12:7060e287bdae 130 void requestForImagePacket(uint16_t packetId);
stormysun513 12:7060e287bdae 131
stormysun513 12:7060e287bdae 132 BLE ble;
stormysun513 12:7060e287bdae 133 Gap::Handle_t mHandle = 0;
stormysun513 11:b3929de96933 134 Ticker ticker;
stormysun513 12:7060e287bdae 135 Serial pc(UARTTX_PIN, UARTRX_PIN);
stormysun513 12:7060e287bdae 136 I2C *pI2C = NULL;
stormysun513 12:7060e287bdae 137 DigitalOut ledPower(POWER_LED_PIN); //P0_11
stormysun513 12:7060e287bdae 138 DigitalOut *pLedInsertion = NULL; //P0_10 Must be changed
stormysun513 14:f62d55b7dead 139 DigitalOut uartEnable(STM32_ENABLE_PIN); //P0_12
stormysun513 12:7060e287bdae 140 InterruptIn *pButton = NULL; //P0_4
stormysun513 12:7060e287bdae 141 AnalogIn *pButtonAnalogIn = NULL; //P0_4
stormysun513 12:7060e287bdae 142 AnalogIn aniSalivaVolt(ANI_SALIVA_VOLTAGE_PIN); //P0_5
stormysun513 12:7060e287bdae 143 AnalogIn aniUSBChargeVolt(ANI_USB_CHARGE_PIN);
stormysun513 12:7060e287bdae 144 AnalogIn aniBatterVolt(ANI_BATTERY_VOLTAGE_PIN); //P0_2
stormysun513 12:7060e287bdae 145
stormysun513 16:5552833a3401 146 static const uint16_t codeVersion = CODE_VERSION;
stormysun513 15:c099dd509203 147
stormysun513 12:7060e287bdae 148 /* State variables for application status, UARTRX data parsing status,
stormysun513 12:7060e287bdae 149 waiting header type and main loop trigger */
stormysun513 12:7060e287bdae 150 static SystemStateTypeDef systemState = SYS_RELAXING_BUTTON;
stormysun513 12:7060e287bdae 151 static ButtonStateTypeDef buttonState = BTN_IDLE;
stormysun513 12:7060e287bdae 152 static STM32StateTypeDef stm32State = STM32_IDLE;
stormysun513 12:7060e287bdae 153 static UARTRxStateTypeDef uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 16:5552833a3401 154 static HeaderTypeDef waitHeader = SYS_HEADER_NO_SPECIFIC;
stormysun513 12:7060e287bdae 155
stormysun513 12:7060e287bdae 156 /* Variables to handle data transferring. */
stormysun513 12:7060e287bdae 157 static uint8_t packetNum = 0;
stormysun513 12:7060e287bdae 158 static uint8_t lastPacketSize = 0;
stormysun513 12:7060e287bdae 159 static uint8_t currentPacketIndex = 0;
stormysun513 12:7060e287bdae 160 static uint8_t targetPayload = 0;
stormysun513 12:7060e287bdae 161 static uint8_t alreadyTransferred = 0;
stormysun513 12:7060e287bdae 162 static uint8_t waitCamera = 0;
stormysun513 12:7060e287bdae 163 static const uint8_t MAX_WAIT_TARGET_PAYLOAD = 2;
stormysun513 12:7060e287bdae 164 static bool isRetransmit = false;
stormysun513 12:7060e287bdae 165 static uint8_t retransmitIndex = 0;
stormysun513 12:7060e287bdae 166 static uint8_t retransmitSize = 0;
stormysun513 12:7060e287bdae 167 static bool setImgPktPayloadByID = false;
stormysun513 12:7060e287bdae 168 static bool directForward = false;
stormysun513 11:b3929de96933 169
stormysun513 12:7060e287bdae 170 static bool isCheckBuf = false;
stormysun513 12:7060e287bdae 171 static bool isRoutine = false;
stormysun513 15:c099dd509203 172 static bool isInserted = false;
stormysun513 12:7060e287bdae 173 static bool isEnterMainLoop = false;
stormysun513 16:5552833a3401 174 static bool isMonitoring = false;
stormysun513 12:7060e287bdae 175 static bool salivaPeriodically = false;
stormysun513 12:7060e287bdae 176
stormysun513 12:7060e287bdae 177 static uint8_t checkButtonCounter = 0;
stormysun513 12:7060e287bdae 178
stormysun513 14:f62d55b7dead 179 #ifdef LOW_POWER_CONSTRAINT
stormysun513 14:f62d55b7dead 180 static bool isLowPower = false;
stormysun513 14:f62d55b7dead 181 static uint8_t lowPowerCounter = 0;
stormysun513 14:f62d55b7dead 182 #endif
stormysun513 14:f62d55b7dead 183
stormysun513 12:7060e287bdae 184 #ifdef APPLICATION_TIMEOUT
stormysun513 12:7060e287bdae 185 static uint16_t disConnIdleCnt = 0;
stormysun513 12:7060e287bdae 186 static uint16_t connIdleCnt = 0;
stormysun513 14:f62d55b7dead 187 static const uint16_t MAX_DISCONN_IDLE = 300;
stormysun513 14:f62d55b7dead 188 static const uint16_t MAX_CONN_IDLE = 300;
stormysun513 12:7060e287bdae 189 #endif
stormysun513 11:b3929de96933 190
stormysun513 12:7060e287bdae 191 static RingBuffer ringBuffer;
stormysun513 12:7060e287bdae 192 static const uint8_t preamble[] = {0xFF, 0x7F};
stormysun513 12:7060e287bdae 193 uint8_t uartTxPayload[BLE_BUF_LEN] = {0,};
stormysun513 12:7060e287bdae 194 uint8_t uartRxPayload[BLE_BUF_LEN] = {0,};
stormysun513 12:7060e287bdae 195 uint8_t retransmitIndices[BLE_RETRANSMISSION_BUF] = {0,};
stormysun513 12:7060e287bdae 196
stormysun513 12:7060e287bdae 197 // The Nordic UART Service
stormysun513 12:7060e287bdae 198 static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
stormysun513 12:7060e287bdae 199 static const uint8_t uart_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
stormysun513 12:7060e287bdae 200 static const uint8_t uart_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
stormysun513 12:7060e287bdae 201 static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
stormysun513 12:7060e287bdae 202
stormysun513 12:7060e287bdae 203 /* GATTs */
stormysun513 12:7060e287bdae 204 GattCharacteristic txCharacteristic (uart_tx_uuid, uartTxPayload, 1, BLE_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
stormysun513 12:7060e287bdae 205 GattCharacteristic rxCharacteristic (uart_rx_uuid, uartRxPayload, 1, BLE_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
stormysun513 12:7060e287bdae 206 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
stormysun513 12:7060e287bdae 207 GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
dan 0:7dec7e9ac085 208
RedBearLab 10:9e24f9f4ac47 209 int main()
RedBearLab 10:9e24f9f4ac47 210 {
stormysun513 12:7060e287bdae 211 pc.baud(UART_BAUDRATE);
stormysun513 12:7060e287bdae 212 pc.attach(uartRxCB , pc.RxIrq);
stormysun513 12:7060e287bdae 213 pc.set_flow_control(pc.Disabled);
stormysun513 12:7060e287bdae 214 RingBuffer_init(&ringBuffer);
stormysun513 14:f62d55b7dead 215 uartEnable = 1;
stormysun513 12:7060e287bdae 216
stormysun513 12:7060e287bdae 217 pI2C = new I2C(SDA_PIN, SCL_PIN);
stormysun513 12:7060e287bdae 218 pLedInsertion = new DigitalOut(INSERTION_LED_PIN);
stormysun513 14:f62d55b7dead 219 pLedInsertion->write(1);
stormysun513 14:f62d55b7dead 220 ledPower = 0;
stormysun513 12:7060e287bdae 221
stormysun513 11:b3929de96933 222 ticker.attach_us(timerPeriodicalCB, MINIMUM_TICKER_PERIOD);
stormysun513 12:7060e287bdae 223 pButton = new InterruptIn(BTN_POWER_ON_PIN);
stormysun513 12:7060e287bdae 224 pButton->fall(buttonInterruptServiceRoutine);
stormysun513 12:7060e287bdae 225
stormysun513 12:7060e287bdae 226 ble.init(bleInitCompleteCB);
stormysun513 12:7060e287bdae 227 ble.onConnection(bleOnConnectionCB);
stormysun513 12:7060e287bdae 228 ble.onDisconnection(bleDisconnectionCB);
stormysun513 12:7060e287bdae 229 ble.onDataWritten(bleCharacteristicWrittenCB);
stormysun513 14:f62d55b7dead 230
stormysun513 14:f62d55b7dead 231 // Adjust interrupt priority
stormysun513 12:7060e287bdae 232 // NVIC_SetPriority(RADIO_IRQn, 0);
stormysun513 12:7060e287bdae 233 // NVIC_SetPriority(UART0_IRQn, 1);
stormysun513 12:7060e287bdae 234 // NVIC_SetPriority(RTC1_IRQn, 2);
stormysun513 12:7060e287bdae 235
stormysun513 12:7060e287bdae 236 // setup advertising // Restricted to 31 bytes
stormysun513 12:7060e287bdae 237 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
stormysun513 12:7060e287bdae 238 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
stormysun513 12:7060e287bdae 239 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)"BLETest", sizeof("BLETest") - 1);
stormysun513 12:7060e287bdae 240 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
stormysun513 12:7060e287bdae 241 ble.gap().setDeviceName("BLETest");
stormysun513 12:7060e287bdae 242
stormysun513 14:f62d55b7dead 243 ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME) - 1);
stormysun513 12:7060e287bdae 244 ble.setAdvertisingInterval(160); // 100ms; in multiples of 0.625ms.
stormysun513 12:7060e287bdae 245 ble.addService(uartService);
stormysun513 12:7060e287bdae 246
stormysun513 12:7060e287bdae 247 ble.startAdvertising();
stormysun513 11:b3929de96933 248
stormysun513 11:b3929de96933 249 while(true){
stormysun513 12:7060e287bdae 250
stormysun513 14:f62d55b7dead 251 #ifdef LOW_POWER_CONSTRAINT
stormysun513 14:f62d55b7dead 252 if(lowPowerCounter > MAXIMUM_LOW_POWER_COUNTER){
stormysun513 14:f62d55b7dead 253 shutdownDevice();
stormysun513 14:f62d55b7dead 254 }
stormysun513 14:f62d55b7dead 255 #endif
stormysun513 14:f62d55b7dead 256
stormysun513 12:7060e287bdae 257 #ifdef APPLICATION_TIMEOUT
stormysun513 12:7060e287bdae 258 if(disConnIdleCnt >= MAX_DISCONN_IDLE && systemState == SYS_RELAXING_BUTTON){
stormysun513 12:7060e287bdae 259 shutdownDevice();
stormysun513 12:7060e287bdae 260 }
stormysun513 12:7060e287bdae 261 else if(connIdleCnt >= MAX_CONN_IDLE){
stormysun513 13:65c9b7d667f6 262 if(mHandle != 0)
stormysun513 13:65c9b7d667f6 263 ble.disconnect(mHandle, Gap::CONNECTION_TIMEOUT);
stormysun513 12:7060e287bdae 264 systemState = SYS_RELAXING_BUTTON;
stormysun513 12:7060e287bdae 265 }
stormysun513 12:7060e287bdae 266 #endif
stormysun513 12:7060e287bdae 267
stormysun513 12:7060e287bdae 268 switch (systemState) {
stormysun513 12:7060e287bdae 269 case SYS_POWERSAVING:
stormysun513 12:7060e287bdae 270 case SYS_RELAXING_BUTTON:
stormysun513 12:7060e287bdae 271 switch (buttonState) {
stormysun513 12:7060e287bdae 272 case BTN_CHANGE_ANALOG:
stormysun513 12:7060e287bdae 273 changeButtonPinToAnalogIn();
stormysun513 12:7060e287bdae 274 break;
stormysun513 12:7060e287bdae 275 case BTN_CHECK_LONG_PRESS:
stormysun513 12:7060e287bdae 276 buttonCheckLongPress(checkButtonCounter);
stormysun513 12:7060e287bdae 277 break;
stormysun513 12:7060e287bdae 278 case BTN_IDLE:
stormysun513 12:7060e287bdae 279 default:
stormysun513 12:7060e287bdae 280 break;
stormysun513 12:7060e287bdae 281 }
stormysun513 12:7060e287bdae 282 break;
stormysun513 12:7060e287bdae 283 case SYS_LOCKING_BUTTON:
stormysun513 12:7060e287bdae 284 buttonState = BTN_IDLE;
stormysun513 12:7060e287bdae 285 break;
stormysun513 12:7060e287bdae 286 }
stormysun513 12:7060e287bdae 287
stormysun513 12:7060e287bdae 288 if(isCheckBuf){
stormysun513 12:7060e287bdae 289 isCheckBuf = false;
stormysun513 12:7060e287bdae 290 timerCheckBuffer();
stormysun513 12:7060e287bdae 291 }
stormysun513 12:7060e287bdae 292
stormysun513 12:7060e287bdae 293 if(isRoutine){
stormysun513 12:7060e287bdae 294 isRoutine = false;
stormysun513 12:7060e287bdae 295 timerRoutineTasks();
stormysun513 12:7060e287bdae 296 }
stormysun513 12:7060e287bdae 297
stormysun513 12:7060e287bdae 298 if( isEnterMainLoop ){
stormysun513 12:7060e287bdae 299 switch (stm32State){
stormysun513 16:5552833a3401 300 case STM32_IMAGE_FORWARDING:
stormysun513 16:5552833a3401 301 {
stormysun513 12:7060e287bdae 302 if (setImgPktPayloadByID == false){
stormysun513 12:7060e287bdae 303 uint8_t check = 0;
stormysun513 12:7060e287bdae 304 RingBuffer_read(&ringBuffer, &check, 1);
stormysun513 12:7060e287bdae 305 HeaderTypeDef header = static_cast<HeaderTypeDef>(check);
stormysun513 12:7060e287bdae 306 if (header == SYS_HEADER_IMAGE_PACKET){
stormysun513 12:7060e287bdae 307 if (currentPacketIndex != (packetNum-1))
stormysun513 12:7060e287bdae 308 targetPayload = UART_PACKET_SIZE + 3;
stormysun513 12:7060e287bdae 309 else
stormysun513 12:7060e287bdae 310 targetPayload = lastPacketSize + 3;
stormysun513 12:7060e287bdae 311
stormysun513 12:7060e287bdae 312 alreadyTransferred = 0;
stormysun513 12:7060e287bdae 313 setImgPktPayloadByID = true;
stormysun513 12:7060e287bdae 314 waitCamera = 0;
stormysun513 12:7060e287bdae 315 }
stormysun513 12:7060e287bdae 316 }
stormysun513 12:7060e287bdae 317 else {
stormysun513 12:7060e287bdae 318 uint16_t numBytes = RingBuffer_availableDataAmount(&ringBuffer);
stormysun513 12:7060e287bdae 319 while((numBytes >= (BLE_BUF_LEN-1)) || (directForward == true)){
stormysun513 12:7060e287bdae 320 waitCamera = 0;
stormysun513 12:7060e287bdae 321 uint16_t diff = numBytes;
stormysun513 12:7060e287bdae 322 if(diff > (BLE_BUF_LEN-1))
stormysun513 12:7060e287bdae 323 diff = (BLE_BUF_LEN-1);
stormysun513 12:7060e287bdae 324 uartRxPayload[0] = static_cast<uint8_t>(SYS_HEADER_IMAGE_PACKET);
stormysun513 12:7060e287bdae 325
stormysun513 12:7060e287bdae 326 RingBuffer_read(&ringBuffer, uartRxPayload+1, diff);
stormysun513 12:7060e287bdae 327
stormysun513 12:7060e287bdae 328 if(mHandle != 0){
stormysun513 12:7060e287bdae 329 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), uartRxPayload, diff+1);
stormysun513 12:7060e287bdae 330 alreadyTransferred += diff;
stormysun513 12:7060e287bdae 331 numBytes -= diff;
stormysun513 12:7060e287bdae 332 }
stormysun513 12:7060e287bdae 333
stormysun513 12:7060e287bdae 334 if(directForward == true || alreadyTransferred >= targetPayload){
stormysun513 12:7060e287bdae 335 __disable_irq(); // Disable Interrupts
stormysun513 12:7060e287bdae 336 setImgPktPayloadByID = false;
stormysun513 12:7060e287bdae 337 __enable_irq();
stormysun513 12:7060e287bdae 338 directForward = false;
stormysun513 12:7060e287bdae 339 RingBuffer_init(&ringBuffer);
stormysun513 12:7060e287bdae 340
stormysun513 12:7060e287bdae 341 if(isRetransmit == false){
stormysun513 12:7060e287bdae 342 currentPacketIndex++;
stormysun513 12:7060e287bdae 343 }
stormysun513 12:7060e287bdae 344 else{
stormysun513 12:7060e287bdae 345 retransmitIndex++;
stormysun513 12:7060e287bdae 346 if(retransmitIndex >= retransmitSize){
stormysun513 12:7060e287bdae 347 retransmitSize = 0;
stormysun513 12:7060e287bdae 348 resetSTM32StateType();
stormysun513 12:7060e287bdae 349 break;
stormysun513 12:7060e287bdae 350 }
stormysun513 12:7060e287bdae 351 else{
stormysun513 12:7060e287bdae 352 currentPacketIndex = retransmitIndices[retransmitIndex];
stormysun513 12:7060e287bdae 353 }
stormysun513 12:7060e287bdae 354 }
stormysun513 12:7060e287bdae 355
stormysun513 12:7060e287bdae 356 if(currentPacketIndex == packetNum && isRetransmit == false){
stormysun513 12:7060e287bdae 357 /* TODO retransmission */
stormysun513 12:7060e287bdae 358 isRetransmit = true;
stormysun513 12:7060e287bdae 359 if(retransmitSize > 0){
stormysun513 12:7060e287bdae 360 uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 12:7060e287bdae 361 retransmitIndex = 0;
stormysun513 12:7060e287bdae 362 currentPacketIndex = retransmitIndices[retransmitIndex];
stormysun513 12:7060e287bdae 363 requestForImagePacket(currentPacketIndex);
stormysun513 12:7060e287bdae 364 }
stormysun513 12:7060e287bdae 365 else{
stormysun513 12:7060e287bdae 366 resetSTM32StateType();
stormysun513 12:7060e287bdae 367 }
stormysun513 12:7060e287bdae 368 }
stormysun513 12:7060e287bdae 369 else{
stormysun513 12:7060e287bdae 370 uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 12:7060e287bdae 371 requestForImagePacket(currentPacketIndex);
stormysun513 12:7060e287bdae 372 }
stormysun513 12:7060e287bdae 373 break;
stormysun513 12:7060e287bdae 374 }
stormysun513 12:7060e287bdae 375 }
stormysun513 12:7060e287bdae 376 }
stormysun513 12:7060e287bdae 377 break;
stormysun513 12:7060e287bdae 378 }
stormysun513 16:5552833a3401 379 case STM32_CHECK_HEADER:
stormysun513 16:5552833a3401 380 {
stormysun513 12:7060e287bdae 381 uint8_t buf[BLE_BUF_LEN] = {0,};
stormysun513 12:7060e287bdae 382 HeaderTypeDef header;
stormysun513 12:7060e287bdae 383 switch (waitHeader) {
stormysun513 12:7060e287bdae 384 /* Image info */
stormysun513 12:7060e287bdae 385 case SYS_HEADER_IMAGE_INFO:
stormysun513 16:5552833a3401 386 {
stormysun513 12:7060e287bdae 387 RingBuffer_read(&ringBuffer, buf, 1);
stormysun513 12:7060e287bdae 388 header = static_cast<HeaderTypeDef>(buf[0]);
stormysun513 12:7060e287bdae 389 if (header == SYS_HEADER_IMAGE_INFO){
stormysun513 12:7060e287bdae 390 RingBuffer_read(&ringBuffer, buf+1, SINGLE_UINT16_PAYLOAD-1);
stormysun513 12:7060e287bdae 391 if(mHandle != 0)
stormysun513 12:7060e287bdae 392 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, SINGLE_UINT16_PAYLOAD);
stormysun513 12:7060e287bdae 393
stormysun513 12:7060e287bdae 394 uint16_t totalDataLength = buf[1]*256 + buf[2];
stormysun513 12:7060e287bdae 395 packetNum = totalDataLength/UART_PACKET_SIZE;
stormysun513 12:7060e287bdae 396 lastPacketSize = totalDataLength%UART_PACKET_SIZE;
stormysun513 12:7060e287bdae 397 if(totalDataLength%UART_PACKET_SIZE != 0)
stormysun513 12:7060e287bdae 398 packetNum++;
stormysun513 12:7060e287bdae 399 else
stormysun513 12:7060e287bdae 400 lastPacketSize = UART_PACKET_SIZE;
stormysun513 12:7060e287bdae 401
stormysun513 12:7060e287bdae 402 currentPacketIndex = 0;
stormysun513 12:7060e287bdae 403 resetSTM32StateType();
stormysun513 12:7060e287bdae 404 }
stormysun513 12:7060e287bdae 405 break;
stormysun513 16:5552833a3401 406 }
stormysun513 12:7060e287bdae 407 case SYS_HEADER_SALIVA_VOLTAGE:
stormysun513 16:5552833a3401 408 // {
stormysun513 16:5552833a3401 409 // RingBuffer_read(&ringBuffer, buf, 1);
stormysun513 16:5552833a3401 410 // header = static_cast<HeaderTypeDef>(buf[0]);
stormysun513 16:5552833a3401 411 // if (header == SYS_HEADER_SALIVA_VOLTAGE){
stormysun513 16:5552833a3401 412 // RingBuffer_read(&ringBuffer, buf+1, SINGLE_UINT16_PAYLOAD-1);
stormysun513 16:5552833a3401 413 // if(mHandle != 0)
stormysun513 16:5552833a3401 414 // ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, SINGLE_UINT16_PAYLOAD);
stormysun513 16:5552833a3401 415 //
stormysun513 16:5552833a3401 416 // stm32State = STM32_CHECK_HEADER;
stormysun513 16:5552833a3401 417 // uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 16:5552833a3401 418 // }
stormysun513 16:5552833a3401 419 // break;
stormysun513 16:5552833a3401 420 // }
stormysun513 12:7060e287bdae 421 case SYS_HEADER_NO_SPECIFIC:
stormysun513 12:7060e287bdae 422 default:
stormysun513 12:7060e287bdae 423 break;
stormysun513 12:7060e287bdae 424 }
stormysun513 12:7060e287bdae 425 break;
stormysun513 12:7060e287bdae 426 }
stormysun513 12:7060e287bdae 427 case STM32_IDLE:
stormysun513 12:7060e287bdae 428 default:
stormysun513 12:7060e287bdae 429 break;
stormysun513 12:7060e287bdae 430 }
stormysun513 12:7060e287bdae 431 isEnterMainLoop = false;
stormysun513 12:7060e287bdae 432 }
stormysun513 12:7060e287bdae 433 ble.waitForEvent();
stevep 4:81cea7a352b0 434 }
dan 0:7dec7e9ac085 435 }
stormysun513 11:b3929de96933 436
stormysun513 12:7060e287bdae 437 void bleInitCompleteCB(struct BLE::InitializationCompleteCallbackContext *context){
stormysun513 12:7060e287bdae 438 if (context->error != BLE_ERROR_NONE)
stormysun513 12:7060e287bdae 439 return;
stormysun513 12:7060e287bdae 440
stormysun513 12:7060e287bdae 441 if (context->ble.getInstanceID() == BLE::DEFAULT_INSTANCE){
stormysun513 12:7060e287bdae 442 /* use the BLE instance */
stormysun513 12:7060e287bdae 443 return;
stormysun513 12:7060e287bdae 444 }
stormysun513 12:7060e287bdae 445 }
stormysun513 12:7060e287bdae 446
stormysun513 12:7060e287bdae 447 void bleOnConnectionCB(const Gap::ConnectionCallbackParams_t *p_conn_param){
stormysun513 12:7060e287bdae 448 mHandle = p_conn_param->handle;
stormysun513 12:7060e287bdae 449 #ifdef APPLICATION_TIMEOUT
stormysun513 12:7060e287bdae 450 connIdleCnt = 0;
stormysun513 12:7060e287bdae 451 #endif
stormysun513 12:7060e287bdae 452 bleReduceConnInterval();
stormysun513 12:7060e287bdae 453 }
stormysun513 12:7060e287bdae 454
stormysun513 12:7060e287bdae 455 void bleDisconnectionCB(const Gap::DisconnectionCallbackParams_t *params){
stormysun513 12:7060e287bdae 456 mHandle = 0;
stormysun513 12:7060e287bdae 457 if(systemState != SYS_POWERSAVING){
stormysun513 12:7060e287bdae 458 #ifdef APPLICATION_TIMEOUT
stormysun513 12:7060e287bdae 459 disConnIdleCnt = 0;
stormysun513 12:7060e287bdae 460 #endif
stormysun513 12:7060e287bdae 461 ble.startAdvertising();
stormysun513 12:7060e287bdae 462 }
stormysun513 12:7060e287bdae 463 }
stormysun513 12:7060e287bdae 464
stormysun513 12:7060e287bdae 465 void bleCharacteristicWrittenCB(const GattWriteCallbackParams *Handler){
stormysun513 12:7060e287bdae 466 uint16_t bleBytesRead;
stormysun513 12:7060e287bdae 467 if (Handler->handle == txCharacteristic.getValueAttribute().getHandle())
stormysun513 12:7060e287bdae 468 {
stormysun513 12:7060e287bdae 469 #ifdef APPLICATION_TIMEOUT
stormysun513 12:7060e287bdae 470 connIdleCnt = 0;
stormysun513 12:7060e287bdae 471 #endif
stormysun513 12:7060e287bdae 472 ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), uartTxPayload, &bleBytesRead);
stormysun513 12:7060e287bdae 473 if(bleBytesRead == 0)
stormysun513 12:7060e287bdae 474 return;
stormysun513 12:7060e287bdae 475
stormysun513 12:7060e287bdae 476 BLECommandTypeDef command = static_cast<BLECommandTypeDef>(uartTxPayload[0]);
stormysun513 12:7060e287bdae 477 bool isUARTCommand = false;
stormysun513 12:7060e287bdae 478 switch(command){
stormysun513 21:4753996b0bcb 479 case BLE_TURNON_MONITORING:
stormysun513 21:4753996b0bcb 480 isMonitoring = true;
stormysun513 21:4753996b0bcb 481 break;
stormysun513 21:4753996b0bcb 482 case BLE_CLOSE_MONITORING:
stormysun513 21:4753996b0bcb 483 isMonitoring = false;
stormysun513 12:7060e287bdae 484 break;
stormysun513 12:7060e287bdae 485 case BLE_REQUEST_SALIVA_VOLTAGE:
stormysun513 12:7060e287bdae 486 waitHeader = SYS_HEADER_SALIVA_VOLTAGE;
stormysun513 12:7060e287bdae 487 salivaPeriodically = true;
stormysun513 12:7060e287bdae 488 systemState = SYS_LOCKING_BUTTON; // Lock Begin
stormysun513 12:7060e287bdae 489 break;
stormysun513 12:7060e287bdae 490 case BLE_DEREQUEST_SALIVA_VOLTAGE:
stormysun513 12:7060e287bdae 491 salivaPeriodically = false;
stormysun513 12:7060e287bdae 492 break;
stormysun513 12:7060e287bdae 493 case BLE_REQUEST_IMAGE_INFO:
stormysun513 12:7060e287bdae 494 waitHeader = SYS_HEADER_IMAGE_INFO;
stormysun513 12:7060e287bdae 495 isUARTCommand = true;
stormysun513 12:7060e287bdae 496 salivaPeriodically = false;
stormysun513 12:7060e287bdae 497 break;
stormysun513 12:7060e287bdae 498 case BLE_END_IMAGE_TRANSFER:
stormysun513 12:7060e287bdae 499 isRetransmit = false;
stormysun513 12:7060e287bdae 500 packetNum = 0;
stormysun513 12:7060e287bdae 501 resetSTM32StateType();
stormysun513 12:7060e287bdae 502 break;
stormysun513 12:7060e287bdae 503 case BLE_SHUTDOWN:
stormysun513 12:7060e287bdae 504 changeButtonPinToInterrupt();
stormysun513 12:7060e287bdae 505 shutdownDevice();
stormysun513 12:7060e287bdae 506 break;
stormysun513 12:7060e287bdae 507 case BLE_UNLOCK_BUTTON:
stormysun513 19:03d39b923919 508 {
stormysun513 12:7060e287bdae 509 systemState = SYS_RELAXING_BUTTON;
stormysun513 19:03d39b923919 510 buttonState = BTN_IDLE;
stormysun513 12:7060e287bdae 511 break;
stormysun513 19:03d39b923919 512 }
stormysun513 16:5552833a3401 513 case BLE_UART_DEBUG:
stormysun513 16:5552833a3401 514 {
stormysun513 12:7060e287bdae 515 uint8_t debugHeader = 0xF1;
stormysun513 12:7060e287bdae 516 uartTxTransmit(&debugHeader, 1);
stormysun513 12:7060e287bdae 517 break;
stormysun513 12:7060e287bdae 518 }
stormysun513 12:7060e287bdae 519 case BLE_REQUEST_IMAGE_BY_INDEX:
stormysun513 12:7060e287bdae 520 if(bleBytesRead >= 2){
stormysun513 12:7060e287bdae 521 uint8_t check = uartTxPayload[1];
stormysun513 12:7060e287bdae 522 if(check == 0){
stormysun513 12:7060e287bdae 523 if(packetNum > 0){
stormysun513 12:7060e287bdae 524 setImgPktPayloadByID = false;
stormysun513 12:7060e287bdae 525 directForward = false;
stormysun513 12:7060e287bdae 526 RingBuffer_init(&ringBuffer);
stormysun513 12:7060e287bdae 527 currentPacketIndex = 0;
stormysun513 12:7060e287bdae 528 isRetransmit = false;
stormysun513 12:7060e287bdae 529 retransmitSize = 0;
stormysun513 12:7060e287bdae 530 stm32State = STM32_IMAGE_FORWARDING;
stormysun513 12:7060e287bdae 531 uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 12:7060e287bdae 532 requestForImagePacket(currentPacketIndex);
stormysun513 12:7060e287bdae 533 }
stormysun513 12:7060e287bdae 534 }
stormysun513 12:7060e287bdae 535 else if(check <= 18){
stormysun513 12:7060e287bdae 536 if(bleBytesRead < check+2)
stormysun513 12:7060e287bdae 537 break;
stormysun513 12:7060e287bdae 538 retransmitSize = check;
stormysun513 12:7060e287bdae 539 memcpy(retransmitIndices, uartTxPayload+2, retransmitSize);
stormysun513 12:7060e287bdae 540 if(isRetransmit == true){
stormysun513 12:7060e287bdae 541 stm32State = STM32_IMAGE_FORWARDING;
stormysun513 12:7060e287bdae 542 uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 12:7060e287bdae 543 retransmitIndex = 0;
stormysun513 12:7060e287bdae 544 currentPacketIndex = retransmitIndices[retransmitIndex];
stormysun513 12:7060e287bdae 545 requestForImagePacket(currentPacketIndex);
stormysun513 12:7060e287bdae 546 }
stormysun513 12:7060e287bdae 547 else{
stormysun513 12:7060e287bdae 548 uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 12:7060e287bdae 549 requestForImagePacket(currentPacketIndex);
stormysun513 12:7060e287bdae 550 }
stormysun513 12:7060e287bdae 551 }
stormysun513 12:7060e287bdae 552 else{
stormysun513 12:7060e287bdae 553 /* Invalid check number */
stormysun513 12:7060e287bdae 554 }
stormysun513 12:7060e287bdae 555 }
stormysun513 12:7060e287bdae 556 break;
stormysun513 16:5552833a3401 557 case BLE_CHANGE_CASSETTE_ID:
stormysun513 12:7060e287bdae 558 if(bleBytesRead >= 3)
stormysun513 12:7060e287bdae 559 writeAT24EEPROMBuffer(*pI2C, 0, (char*)uartTxPayload+1, 2);
stormysun513 12:7060e287bdae 560 break;
stormysun513 16:5552833a3401 561 case BLE_REQUEST_DEVICE_INFO:
stormysun513 16:5552833a3401 562 {
stormysun513 16:5552833a3401 563 uint8_t buf[SINGLE_UINT16_PAYLOAD] = {0,};
stormysun513 16:5552833a3401 564 buf[0] = SYS_HEADER_DEVICE_INFO;
stormysun513 16:5552833a3401 565 buf[1] = (codeVersion >> 8) & 0xFF;
stormysun513 16:5552833a3401 566 buf[2] = codeVersion & 0xFF;
stormysun513 16:5552833a3401 567 if(mHandle != 0)
stormysun513 16:5552833a3401 568 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, SINGLE_UINT16_PAYLOAD);
stormysun513 16:5552833a3401 569
stormysun513 16:5552833a3401 570 break;
stormysun513 16:5552833a3401 571 }
stormysun513 12:7060e287bdae 572 default:
stormysun513 12:7060e287bdae 573 break;
stormysun513 12:7060e287bdae 574 }
stormysun513 12:7060e287bdae 575 if(isUARTCommand){
stormysun513 12:7060e287bdae 576 stm32State = STM32_CHECK_HEADER;
stormysun513 12:7060e287bdae 577 uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 12:7060e287bdae 578 uartTxTransmit(uartTxPayload, 1);
stormysun513 12:7060e287bdae 579 }
stormysun513 12:7060e287bdae 580 }
stormysun513 12:7060e287bdae 581 }
stormysun513 12:7060e287bdae 582
stormysun513 12:7060e287bdae 583 void bleReduceConnInterval(void){
stormysun513 12:7060e287bdae 584 Gap::ConnectionParams_t bleGapConnParamInitStruct;
stormysun513 12:7060e287bdae 585 bleGapConnParamInitStruct.minConnectionInterval = BLE_GAP_CP_MIN_CONN_INTVL_MIN; /*Minimum Connection Interval in 1.25 ms*/
stormysun513 12:7060e287bdae 586 bleGapConnParamInitStruct.maxConnectionInterval = BLE_GAP_CP_MIN_CONN_INTVL_MIN; /*Minimum Connection Interval in 1.25 ms*/
stormysun513 12:7060e287bdae 587 bleGapConnParamInitStruct.slaveLatency = 0; /*Slave Latency in number of connection events*/
stormysun513 12:7060e287bdae 588 bleGapConnParamInitStruct.connectionSupervisionTimeout = BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN; /*Connection Supervision Timeout in 10 ms*/
stormysun513 12:7060e287bdae 589
stormysun513 12:7060e287bdae 590 ble.gap().updateConnectionParams(mHandle, &bleGapConnParamInitStruct);
stormysun513 12:7060e287bdae 591 }
stormysun513 12:7060e287bdae 592
stormysun513 11:b3929de96933 593 void timerPeriodicalCB(void){
stormysun513 11:b3929de96933 594 static uint32_t time = 0;
stormysun513 11:b3929de96933 595 time++;
stormysun513 11:b3929de96933 596
stormysun513 11:b3929de96933 597 if ( time % 100 == 2 ) { // 250ms
stormysun513 12:7060e287bdae 598 if(buttonState == BTN_CHECK_LONG_PRESS)
stormysun513 12:7060e287bdae 599 checkButtonCounter++;
stormysun513 11:b3929de96933 600 }
stormysun513 11:b3929de96933 601
stormysun513 12:7060e287bdae 602 if(systemState != SYS_POWERSAVING){
stormysun513 12:7060e287bdae 603 if ( time % 3 == 1 ) { // 7.5ms
stormysun513 12:7060e287bdae 604 isCheckBuf = true;
stormysun513 12:7060e287bdae 605 }
stormysun513 12:7060e287bdae 606
stormysun513 14:f62d55b7dead 607 // if ( time % 50 == 2 ) { // 250ms
stormysun513 14:f62d55b7dead 608 // if(isInserted)
stormysun513 14:f62d55b7dead 609 // timerFlashPowerLed();
stormysun513 14:f62d55b7dead 610 // }
stormysun513 12:7060e287bdae 611
stormysun513 12:7060e287bdae 612 if ( time % 200 == 3 ) { // 500ms
stormysun513 14:f62d55b7dead 613 #ifdef LOW_POWER_CONSTRAINT
stormysun513 14:f62d55b7dead 614 if(isLowPower){
stormysun513 14:f62d55b7dead 615 timerFlashPowerLed();
stormysun513 14:f62d55b7dead 616 lowPowerCounter++;
stormysun513 14:f62d55b7dead 617 }
stormysun513 14:f62d55b7dead 618 #endif
stormysun513 15:c099dd509203 619
stormysun513 19:03d39b923919 620 if(isInserted && systemState == SYS_LOCKING_BUTTON){
stormysun513 19:03d39b923919 621 timerFlashInsertionLed();
stormysun513 20:f6e313950373 622 }
stormysun513 12:7060e287bdae 623 }
stormysun513 12:7060e287bdae 624
stormysun513 12:7060e287bdae 625 if ( time % 400 == 4 ) { // 1s
stormysun513 12:7060e287bdae 626 isRoutine = true;
stormysun513 12:7060e287bdae 627 #ifdef APPLICATION_TIMEOUT
stormysun513 13:65c9b7d667f6 628 if(mHandle == 0)
stormysun513 12:7060e287bdae 629 disConnIdleCnt++;
stormysun513 12:7060e287bdae 630 else
stormysun513 12:7060e287bdae 631 connIdleCnt++;
stormysun513 12:7060e287bdae 632 #endif
stormysun513 12:7060e287bdae 633 }
stormysun513 12:7060e287bdae 634
stormysun513 12:7060e287bdae 635 if ( time % 800 == 5 ) {
stormysun513 12:7060e287bdae 636 if(salivaPeriodically == true)
stormysun513 12:7060e287bdae 637 requestSalivaVoltage();
stormysun513 12:7060e287bdae 638 }
stormysun513 11:b3929de96933 639 }
stormysun513 11:b3929de96933 640 }
stormysun513 11:b3929de96933 641
stormysun513 14:f62d55b7dead 642 void timerFlashPowerLed(void){
stormysun513 12:7060e287bdae 643 ledPower = !ledPower;
stormysun513 11:b3929de96933 644 }
stormysun513 11:b3929de96933 645
stormysun513 14:f62d55b7dead 646 void timerFlashInsertionLed(void){
stormysun513 14:f62d55b7dead 647 int tmp = pLedInsertion->read();
stormysun513 14:f62d55b7dead 648 pLedInsertion->write(!tmp);
stormysun513 14:f62d55b7dead 649 }
stormysun513 14:f62d55b7dead 650
stormysun513 12:7060e287bdae 651 void timerRoutineTasks(void){
stormysun513 11:b3929de96933 652 uint8_t buf[BLE_BUF_LEN] = {0,};
stormysun513 16:5552833a3401 653 buf[0] = SYS_HEADER_MONITORING;
stormysun513 12:7060e287bdae 654 bool result = readAT24EEPROMBuffer(*pI2C, 0, (char*)buf+1, 2);
stormysun513 11:b3929de96933 655
stormysun513 11:b3929de96933 656 if(result == false){
stormysun513 14:f62d55b7dead 657 pLedInsertion->write(1);
stormysun513 15:c099dd509203 658 isInserted = false;
stormysun513 11:b3929de96933 659 buf[1] = 0xFF;
stormysun513 11:b3929de96933 660 buf[2] = 0xFF;
stormysun513 19:03d39b923919 661
stormysun513 19:03d39b923919 662 // If no ID detected, system will unlock button automatically. 5/17
stormysun513 19:03d39b923919 663 if(systemState == SYS_LOCKING_BUTTON){
stormysun513 19:03d39b923919 664 systemState = SYS_RELAXING_BUTTON;
stormysun513 19:03d39b923919 665 buttonState = BTN_IDLE;
stormysun513 19:03d39b923919 666 }
stormysun513 11:b3929de96933 667 }
stormysun513 11:b3929de96933 668 else{
stormysun513 15:c099dd509203 669 isInserted = true;
stormysun513 15:c099dd509203 670 if(systemState != SYS_LOCKING_BUTTON){
stormysun513 15:c099dd509203 671 pLedInsertion->write(0);
stormysun513 15:c099dd509203 672 }
stormysun513 15:c099dd509203 673
stormysun513 14:f62d55b7dead 674 if(systemState == SYS_POWERSAVING){
stormysun513 14:f62d55b7dead 675 pLedInsertion->write(1);
stormysun513 14:f62d55b7dead 676 }
stormysun513 12:7060e287bdae 677 }
stormysun513 12:7060e287bdae 678
stormysun513 12:7060e287bdae 679 float fvalue = (float)aniBatterVolt.read()*3.3*100;
stormysun513 12:7060e287bdae 680 uint16_t ivalue = (uint16_t)fvalue;
stormysun513 12:7060e287bdae 681 buf[3] = (ivalue >> 8) & 0xFF;
stormysun513 12:7060e287bdae 682 buf[4] = ivalue & 0xFF;
stormysun513 12:7060e287bdae 683
stormysun513 14:f62d55b7dead 684 #ifdef LOW_POWER_CONSTRAINT
stormysun513 14:f62d55b7dead 685 if(!isLowPower && ivalue < (LOW_POWER_THERS-LOW_POWER_THERS_MARGIN)){
stormysun513 14:f62d55b7dead 686 isLowPower = true;
stormysun513 14:f62d55b7dead 687 lowPowerCounter = 0;
stormysun513 14:f62d55b7dead 688 }
stormysun513 14:f62d55b7dead 689 else if(isLowPower && ivalue > (LOW_POWER_THERS+LOW_POWER_THERS_MARGIN)){
stormysun513 14:f62d55b7dead 690 isLowPower = false;
stormysun513 14:f62d55b7dead 691 }
stormysun513 14:f62d55b7dead 692 #endif
stormysun513 14:f62d55b7dead 693
stormysun513 16:5552833a3401 694 if(mHandle != 0 && isMonitoring == true){
stormysun513 16:5552833a3401 695 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, MONITORING_PAYLOAD);
stormysun513 12:7060e287bdae 696 }
stormysun513 12:7060e287bdae 697 }
stormysun513 12:7060e287bdae 698
stormysun513 12:7060e287bdae 699 void uartTxTransmit(uint8_t* buf, uint16_t length){
stormysun513 12:7060e287bdae 700 uint16_t index;
stormysun513 12:7060e287bdae 701 pc.putc(preamble[0]);
stormysun513 12:7060e287bdae 702 pc.putc(preamble[1]);
stormysun513 12:7060e287bdae 703 for(index = 0; index < length; index++)
stormysun513 12:7060e287bdae 704 {
stormysun513 12:7060e287bdae 705 pc.putc(buf[index]);
stormysun513 12:7060e287bdae 706 }
stormysun513 12:7060e287bdae 707 }
stormysun513 12:7060e287bdae 708
stormysun513 12:7060e287bdae 709 // UARTRX Callback function
stormysun513 12:7060e287bdae 710 void uartRxCB(void){
stormysun513 12:7060e287bdae 711 while(pc.readable())
stormysun513 12:7060e287bdae 712 {
stormysun513 12:7060e287bdae 713 uint8_t byteIn = pc.getc();
stormysun513 12:7060e287bdae 714 if(stm32State == STM32_IDLE)
stormysun513 12:7060e287bdae 715 continue;
stormysun513 12:7060e287bdae 716
stormysun513 12:7060e287bdae 717 if(uartRxState == UARTRX_TRANSFERING_DATA){
stormysun513 12:7060e287bdae 718 RingBuffer_writebyte(&ringBuffer, byteIn);
stormysun513 12:7060e287bdae 719 }
stormysun513 12:7060e287bdae 720 else if(uartRxState == UARTRX_CHECK_FIRST_PREAMBLE && byteIn == preamble[0]){
stormysun513 12:7060e287bdae 721 uartRxState = UARTRX_CHECK_SECOND_PREAMBLE;
stormysun513 12:7060e287bdae 722 }
stormysun513 12:7060e287bdae 723 else if(uartRxState == UARTRX_CHECK_SECOND_PREAMBLE && byteIn == preamble[1]){
stormysun513 12:7060e287bdae 724 uartRxState = UARTRX_TRANSFERING_DATA;
stormysun513 12:7060e287bdae 725 }
stormysun513 12:7060e287bdae 726 }
stormysun513 12:7060e287bdae 727 }
stormysun513 12:7060e287bdae 728
stormysun513 12:7060e287bdae 729 void buttonInterruptServiceRoutine(void){
stormysun513 12:7060e287bdae 730 if(buttonState == BTN_IDLE)
stormysun513 12:7060e287bdae 731 buttonState = BTN_CHANGE_ANALOG;
stormysun513 12:7060e287bdae 732
stormysun513 12:7060e287bdae 733 if(systemState == SYS_POWERSAVING)
stormysun513 12:7060e287bdae 734 ticker.attach_us(timerPeriodicalCB, MINIMUM_TICKER_PERIOD);
stormysun513 12:7060e287bdae 735 }
stormysun513 12:7060e287bdae 736
stormysun513 12:7060e287bdae 737 void buttonCheckLongPress(uint8_t counter){
stormysun513 12:7060e287bdae 738 if(counter < CHECK_BUTTON_TIMES){
stormysun513 12:7060e287bdae 739 if(pButtonAnalogIn != NULL && (float)pButtonAnalogIn->read() < CHECK_BUTTON_VOLTAGE_LEVEL){
stormysun513 12:7060e287bdae 740 return;
stormysun513 12:7060e287bdae 741 }
stormysun513 12:7060e287bdae 742 else if(systemState == SYS_POWERSAVING){
stormysun513 12:7060e287bdae 743 ticker.detach();
stormysun513 12:7060e287bdae 744 }
stormysun513 12:7060e287bdae 745 }
stormysun513 12:7060e287bdae 746 else{
stormysun513 12:7060e287bdae 747 buttonLongPressVerified();
stormysun513 12:7060e287bdae 748 }
stormysun513 12:7060e287bdae 749 changeButtonPinToInterrupt();
stormysun513 12:7060e287bdae 750 }
stormysun513 12:7060e287bdae 751
stormysun513 12:7060e287bdae 752 void buttonLongPressVerified(void){
stormysun513 12:7060e287bdae 753 checkButtonCounter = 0;
stormysun513 12:7060e287bdae 754 if(systemState == SYS_POWERSAVING){
stormysun513 12:7060e287bdae 755 systemState = SYS_RELAXING_BUTTON;
stormysun513 12:7060e287bdae 756 ble.startAdvertising();
stormysun513 12:7060e287bdae 757 #ifdef APPLICATION_TIMEOUT
stormysun513 12:7060e287bdae 758 disConnIdleCnt = 0;
stormysun513 12:7060e287bdae 759 #endif
stormysun513 12:7060e287bdae 760 ticker.attach_us(timerPeriodicalCB, MINIMUM_TICKER_PERIOD);
stormysun513 14:f62d55b7dead 761 ledPower = 0;
stormysun513 14:f62d55b7dead 762 uartEnable = 1;
stormysun513 12:7060e287bdae 763 resetSTM32StateType();
stormysun513 12:7060e287bdae 764 }
stormysun513 12:7060e287bdae 765 else if(systemState == SYS_RELAXING_BUTTON){
stormysun513 12:7060e287bdae 766 shutdownDevice();
stormysun513 12:7060e287bdae 767 }
stormysun513 12:7060e287bdae 768 }
stormysun513 12:7060e287bdae 769
stormysun513 12:7060e287bdae 770 void changeButtonPinToAnalogIn(void){
stormysun513 12:7060e287bdae 771 pButton->fall(NULL);
stormysun513 12:7060e287bdae 772 delete pButton;
stormysun513 12:7060e287bdae 773 checkButtonCounter = 0;
stormysun513 12:7060e287bdae 774 pButtonAnalogIn = new AnalogIn(BTN_POWER_ON_PIN);
stormysun513 12:7060e287bdae 775 buttonState = BTN_CHECK_LONG_PRESS;
stormysun513 12:7060e287bdae 776 }
stormysun513 12:7060e287bdae 777
stormysun513 12:7060e287bdae 778 void changeButtonPinToInterrupt(void){
stormysun513 12:7060e287bdae 779 delete pButtonAnalogIn;
stormysun513 12:7060e287bdae 780 pButton = new InterruptIn(BTN_POWER_ON_PIN);
stormysun513 12:7060e287bdae 781 pButton->fall(buttonInterruptServiceRoutine);
stormysun513 12:7060e287bdae 782 float dummy = (float)pButtonAnalogIn->read();
stormysun513 12:7060e287bdae 783 buttonState = BTN_IDLE;
stormysun513 11:b3929de96933 784 }
stormysun513 12:7060e287bdae 785
stormysun513 12:7060e287bdae 786 void shutdownDevice(void){
stormysun513 12:7060e287bdae 787 systemState = SYS_POWERSAVING;
stormysun513 13:65c9b7d667f6 788 if(mHandle != 0)
stormysun513 13:65c9b7d667f6 789 ble.disconnect(mHandle, Gap::REMOTE_USER_TERMINATED_CONNECTION);
stormysun513 14:f62d55b7dead 790 pLedInsertion->write(1);
stormysun513 13:65c9b7d667f6 791 ticker.detach();
stormysun513 12:7060e287bdae 792 ble.gap().stopAdvertising();
stormysun513 12:7060e287bdae 793 ledPower = 1;
stormysun513 14:f62d55b7dead 794 uartEnable = 0;
stormysun513 18:d146cee0a80e 795 isMonitoring = false;
stormysun513 18:d146cee0a80e 796 salivaPeriodically = false;
stormysun513 17:0c7951915608 797 #ifdef LOW_POWER_CONSTRAINT
stormysun513 17:0c7951915608 798 lowPowerCounter = 0;
stormysun513 17:0c7951915608 799 #endif
stormysun513 12:7060e287bdae 800 deepsleep();
stormysun513 12:7060e287bdae 801 }
stormysun513 12:7060e287bdae 802
stormysun513 12:7060e287bdae 803 void resetSTM32StateType(void){
stormysun513 12:7060e287bdae 804 stm32State = STM32_IDLE;
stormysun513 12:7060e287bdae 805 uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 12:7060e287bdae 806 waitHeader = SYS_HEADER_NO_SPECIFIC;
stormysun513 12:7060e287bdae 807 }
stormysun513 12:7060e287bdae 808
stormysun513 12:7060e287bdae 809 void requestSalivaVoltage(void){
stormysun513 12:7060e287bdae 810 uint8_t buf[BLE_BUF_LEN] = {0,};
stormysun513 12:7060e287bdae 811 float fvalue = aniSalivaVolt.read()*3.3*100;
stormysun513 12:7060e287bdae 812 uint16_t ivalue = (uint16_t)fvalue;
stormysun513 12:7060e287bdae 813
stormysun513 12:7060e287bdae 814 buf[0] = SYS_HEADER_SALIVA_VOLTAGE;
stormysun513 12:7060e287bdae 815 buf[1] = (ivalue >> 8) & 0xFF;
stormysun513 12:7060e287bdae 816 buf[2] = ivalue & 0xFF;
stormysun513 12:7060e287bdae 817
stormysun513 16:5552833a3401 818 if(mHandle != 0)
stormysun513 12:7060e287bdae 819 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, SINGLE_UINT16_PAYLOAD);
stormysun513 12:7060e287bdae 820 }
stormysun513 12:7060e287bdae 821
stormysun513 12:7060e287bdae 822 void timerCheckBuffer(void){
stormysun513 12:7060e287bdae 823 uint16_t numBytes = RingBuffer_availableDataAmount(&ringBuffer);
stormysun513 12:7060e287bdae 824 switch (stm32State) {
stormysun513 12:7060e287bdae 825 case STM32_CHECK_HEADER:{
stormysun513 12:7060e287bdae 826 if (numBytes >= SINGLE_UINT16_PAYLOAD){
stormysun513 12:7060e287bdae 827 isEnterMainLoop = true;
stormysun513 12:7060e287bdae 828 }
stormysun513 12:7060e287bdae 829 break;
stormysun513 12:7060e287bdae 830 }
stormysun513 19:03d39b923919 831 case STM32_IMAGE_FORWARDING:
stormysun513 19:03d39b923919 832 {
stormysun513 12:7060e287bdae 833 if(setImgPktPayloadByID == false){
stormysun513 12:7060e287bdae 834 if(numBytes >= UART_DATA_PACKET_PAYLOAD){
stormysun513 12:7060e287bdae 835 isEnterMainLoop = true;
stormysun513 12:7060e287bdae 836 }
stormysun513 12:7060e287bdae 837 else{
stormysun513 12:7060e287bdae 838 if (waitCamera > MAX_WAIT_TARGET_PAYLOAD){
stormysun513 12:7060e287bdae 839 setImgPktPayloadByID = false;
stormysun513 12:7060e287bdae 840 directForward = false;
stormysun513 12:7060e287bdae 841 RingBuffer_init(&ringBuffer);
stormysun513 12:7060e287bdae 842 requestForImagePacket(currentPacketIndex);
stormysun513 12:7060e287bdae 843 waitCamera = 0;
stormysun513 12:7060e287bdae 844 }
stormysun513 12:7060e287bdae 845 }
stormysun513 12:7060e287bdae 846 }
stormysun513 12:7060e287bdae 847 else {
stormysun513 12:7060e287bdae 848 if((targetPayload-alreadyTransferred) <= (BLE_BUF_LEN-1)){
stormysun513 12:7060e287bdae 849 if(numBytes+alreadyTransferred == targetPayload)
stormysun513 12:7060e287bdae 850 directForward = true;
stormysun513 12:7060e287bdae 851 }
stormysun513 12:7060e287bdae 852
stormysun513 12:7060e287bdae 853 if (numBytes > 0){
stormysun513 12:7060e287bdae 854 isEnterMainLoop = true;
stormysun513 12:7060e287bdae 855 }
stormysun513 12:7060e287bdae 856
stormysun513 12:7060e287bdae 857 else if (waitCamera > MAX_WAIT_TARGET_PAYLOAD){
stormysun513 12:7060e287bdae 858 uartRxState = UARTRX_CHECK_FIRST_PREAMBLE;
stormysun513 12:7060e287bdae 859 requestForImagePacket(currentPacketIndex);
stormysun513 12:7060e287bdae 860 waitCamera = 0;
stormysun513 12:7060e287bdae 861 }
stormysun513 12:7060e287bdae 862
stormysun513 12:7060e287bdae 863 }
stormysun513 12:7060e287bdae 864 break;
stormysun513 12:7060e287bdae 865 }
stormysun513 12:7060e287bdae 866 default:
stormysun513 12:7060e287bdae 867 break;
stormysun513 12:7060e287bdae 868 }
stormysun513 12:7060e287bdae 869 }
stormysun513 12:7060e287bdae 870
stormysun513 12:7060e287bdae 871 void requestForImagePacket(uint16_t packetId){
stormysun513 12:7060e287bdae 872 uint8_t tempBuf[3];
stormysun513 12:7060e287bdae 873 tempBuf[0] = static_cast<uint8_t>(BLE_REQUEST_IMAGE_BY_INDEX);
stormysun513 12:7060e287bdae 874 tempBuf[1] = (packetId >> 8) & 0xFF;
stormysun513 12:7060e287bdae 875 tempBuf[2] = packetId & 0xFF;
stormysun513 12:7060e287bdae 876 uartTxTransmit(tempBuf, 3);
stormysun513 12:7060e287bdae 877 }
stormysun513 12:7060e287bdae 878
stormysun513 12:7060e287bdae 879 void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) {
stormysun513 12:7060e287bdae 880 FlowControl flow_type = (FlowControl)type;
stormysun513 12:7060e287bdae 881 switch(type) {
stormysun513 12:7060e287bdae 882 case RTS:
stormysun513 12:7060e287bdae 883 serial_set_flow_control(&_serial, flow_type, flow1, NC);
stormysun513 12:7060e287bdae 884 break;
stormysun513 12:7060e287bdae 885
stormysun513 12:7060e287bdae 886 case CTS:
stormysun513 12:7060e287bdae 887 serial_set_flow_control(&_serial, flow_type, NC, flow1);
stormysun513 12:7060e287bdae 888 break;
stormysun513 12:7060e287bdae 889
stormysun513 12:7060e287bdae 890 case RTSCTS:
stormysun513 12:7060e287bdae 891 case Disabled:
stormysun513 12:7060e287bdae 892 serial_set_flow_control(&_serial, flow_type, flow1, flow2);
stormysun513 12:7060e287bdae 893 break;
stormysun513 12:7060e287bdae 894
stormysun513 12:7060e287bdae 895 default:
stormysun513 12:7060e287bdae 896 break;
stormysun513 12:7060e287bdae 897 }
stormysun513 12:7060e287bdae 898 }