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