LIS3DH & BLE broadcast example for VTT Node V3 & mbed

Dependencies:   BLE_API TMP_nrf51 mbed nRF51822

Committer:
jejuho
Date:
Tue Dec 08 11:58:59 2015 +0000
Revision:
0:de3e4a57ebe0
Child:
1:bd7fd35251ab
Works OK.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jejuho 0:de3e4a57ebe0 1 #include "mbed.h"
jejuho 0:de3e4a57ebe0 2 #include "ble/BLE.h"
jejuho 0:de3e4a57ebe0 3
jejuho 0:de3e4a57ebe0 4 #define USE_DFU
jejuho 0:de3e4a57ebe0 5
jejuho 0:de3e4a57ebe0 6 #ifdef USE_DFU
jejuho 0:de3e4a57ebe0 7 #include "DFUService.h"
jejuho 0:de3e4a57ebe0 8 #endif
jejuho 0:de3e4a57ebe0 9
jejuho 0:de3e4a57ebe0 10 #include "AT45.h"
jejuho 0:de3e4a57ebe0 11 #include "LIS3DH.h"
jejuho 0:de3e4a57ebe0 12
jejuho 0:de3e4a57ebe0 13 //interrupt /gpio configuration
jejuho 0:de3e4a57ebe0 14 #include "nrf_gpio.h"
jejuho 0:de3e4a57ebe0 15 #include "nrf_gpiote.h"
jejuho 0:de3e4a57ebe0 16 #include "nrf_soc.h"
jejuho 0:de3e4a57ebe0 17
jejuho 0:de3e4a57ebe0 18 //SPI stuff
jejuho 0:de3e4a57ebe0 19 #define MOSI p8
jejuho 0:de3e4a57ebe0 20 #define MISO p9
jejuho 0:de3e4a57ebe0 21 #define SCLK p7
jejuho 0:de3e4a57ebe0 22 #define CS p2
jejuho 0:de3e4a57ebe0 23
jejuho 0:de3e4a57ebe0 24 //#include "app_error.h"
jejuho 0:de3e4a57ebe0 25 //void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) { }
jejuho 0:de3e4a57ebe0 26
jejuho 0:de3e4a57ebe0 27 //const static char DEVICE_NAME[] = "BAc0N";
jejuho 0:de3e4a57ebe0 28 //static const uint16_t uuid16_list[] = {GattService::UUID_STREAMING_SERVICE};
jejuho 0:de3e4a57ebe0 29
jejuho 0:de3e4a57ebe0 30 BLE ble;
jejuho 0:de3e4a57ebe0 31
jejuho 0:de3e4a57ebe0 32 static LIS3DH lis(MOSI, MISO, CS, SCLK);
jejuho 0:de3e4a57ebe0 33
jejuho 0:de3e4a57ebe0 34 #define LED_0 p20
jejuho 0:de3e4a57ebe0 35 #define LED_1 p23
jejuho 0:de3e4a57ebe0 36 //#define LED_2 p24
jejuho 0:de3e4a57ebe0 37 DigitalOut myled1(LED_0);
jejuho 0:de3e4a57ebe0 38 DigitalOut myled2(LED_1);
jejuho 0:de3e4a57ebe0 39 //DigitalOut myled3(LED_2);
jejuho 0:de3e4a57ebe0 40
jejuho 0:de3e4a57ebe0 41 //#define UART_TX p17
jejuho 0:de3e4a57ebe0 42 //#define UART_RX p18
jejuho 0:de3e4a57ebe0 43 //Serial pc(UART_TX, UART_RX); // tx, rx
jejuho 0:de3e4a57ebe0 44
jejuho 0:de3e4a57ebe0 45
jejuho 0:de3e4a57ebe0 46 /** @brief Function for initializing the GPIO Tasks/Events peripheral.
jejuho 0:de3e4a57ebe0 47 */
jejuho 0:de3e4a57ebe0 48 static void gpiote_init(void)
jejuho 0:de3e4a57ebe0 49 {
jejuho 0:de3e4a57ebe0 50 // Configure accelerometer interrupt pin
jejuho 0:de3e4a57ebe0 51 nrf_gpio_cfg_input(3, NRF_GPIO_PIN_PULLDOWN);
jejuho 0:de3e4a57ebe0 52 //nrf_gpio_cfg_input(4, NRF_GPIO_PIN_PULLDOWN);
jejuho 0:de3e4a57ebe0 53
jejuho 0:de3e4a57ebe0 54 // Configure GPIOTE channel 0 to generate event when MOTION_INTERRUPT_PIN_NUMBER goes from Low to High
jejuho 0:de3e4a57ebe0 55 nrf_gpiote_event_config(0, 3, NRF_GPIOTE_POLARITY_LOTOHI); //accelerometer int1
jejuho 0:de3e4a57ebe0 56 //nrf_gpiote_event_config(1, 4, NRF_GPIOTE_POLARITY_LOTOHI); //accelerometer int2
jejuho 0:de3e4a57ebe0 57
jejuho 0:de3e4a57ebe0 58 // Enable interrupt for NRF_GPIOTE->EVENTS_IN[0] event
jejuho 0:de3e4a57ebe0 59 NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Msk;
jejuho 0:de3e4a57ebe0 60 //NRF_GPIOTE->INTENSET |= GPIOTE_INTENSET_IN1_Msk;
jejuho 0:de3e4a57ebe0 61 }
jejuho 0:de3e4a57ebe0 62
jejuho 0:de3e4a57ebe0 63 extern "C"
jejuho 0:de3e4a57ebe0 64 void GPIOTE_IRQHandler(void)
jejuho 0:de3e4a57ebe0 65 {
jejuho 0:de3e4a57ebe0 66 // Event causing the interrupt must be cleared
jejuho 0:de3e4a57ebe0 67 NRF_GPIOTE->EVENTS_IN[0] = 0;
jejuho 0:de3e4a57ebe0 68 //NRF_GPIOTE->EVENTS_IN[1] = 0;
jejuho 0:de3e4a57ebe0 69 lis.LIS3DH_ResetInt1Latch();
jejuho 0:de3e4a57ebe0 70
jejuho 0:de3e4a57ebe0 71 myled1 = !myled1;
jejuho 0:de3e4a57ebe0 72 myled2 = !myled2;
jejuho 0:de3e4a57ebe0 73 }
jejuho 0:de3e4a57ebe0 74
jejuho 0:de3e4a57ebe0 75 void disconnect_input_buffers()
jejuho 0:de3e4a57ebe0 76 {
jejuho 0:de3e4a57ebe0 77 for(uint8_t i = 0; i < 3; i++)
jejuho 0:de3e4a57ebe0 78 {
jejuho 0:de3e4a57ebe0 79 NRF_GPIO->PIN_CNF[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
jejuho 0:de3e4a57ebe0 80 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
jejuho 0:de3e4a57ebe0 81 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
jejuho 0:de3e4a57ebe0 82 | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
jejuho 0:de3e4a57ebe0 83 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
jejuho 0:de3e4a57ebe0 84 }
jejuho 0:de3e4a57ebe0 85 //Omit accelerometer interrupt pins (3&4)
jejuho 0:de3e4a57ebe0 86 for(uint8_t i = 5; i < 21; i++)
jejuho 0:de3e4a57ebe0 87 {
jejuho 0:de3e4a57ebe0 88 NRF_GPIO->PIN_CNF[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
jejuho 0:de3e4a57ebe0 89 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
jejuho 0:de3e4a57ebe0 90 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
jejuho 0:de3e4a57ebe0 91 | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
jejuho 0:de3e4a57ebe0 92 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
jejuho 0:de3e4a57ebe0 93 }
jejuho 0:de3e4a57ebe0 94 //Omit I2C pins (21 & 22)
jejuho 0:de3e4a57ebe0 95 for(uint8_t i = 23; i < 31; i++)
jejuho 0:de3e4a57ebe0 96 {
jejuho 0:de3e4a57ebe0 97 NRF_GPIO->PIN_CNF[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
jejuho 0:de3e4a57ebe0 98 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
jejuho 0:de3e4a57ebe0 99 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
jejuho 0:de3e4a57ebe0 100 | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
jejuho 0:de3e4a57ebe0 101 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
jejuho 0:de3e4a57ebe0 102 }
jejuho 0:de3e4a57ebe0 103 }
jejuho 0:de3e4a57ebe0 104
jejuho 0:de3e4a57ebe0 105 __packed struct ApplicationData_t {
jejuho 0:de3e4a57ebe0 106 uint16_t applicationSpecificId; /* An ID used to identify temperature value in the manufacture specific AD data field */
jejuho 0:de3e4a57ebe0 107 //TMP_nrf51::tmpSensorValue_t tmpSensorValue; /* User defined application data */
jejuho 0:de3e4a57ebe0 108 int8_t accel_temp;
jejuho 0:de3e4a57ebe0 109 //uint16_t lis;
jejuho 0:de3e4a57ebe0 110 AxesRaw_t accel_raw;
jejuho 0:de3e4a57ebe0 111 };
jejuho 0:de3e4a57ebe0 112
jejuho 0:de3e4a57ebe0 113 void setupApplicationData(ApplicationData_t &appData)
jejuho 0:de3e4a57ebe0 114 {
jejuho 0:de3e4a57ebe0 115 static const uint16_t APP_SPECIFIC_ID_TEST = 0xFEFE;
jejuho 0:de3e4a57ebe0 116 appData.applicationSpecificId = APP_SPECIFIC_ID_TEST;
jejuho 0:de3e4a57ebe0 117 //appData.tmpSensorValue = tempSensor.get();
jejuho 0:de3e4a57ebe0 118 lis.LIS3DH_GetAccAxesRaw(&appData.accel_raw);
jejuho 0:de3e4a57ebe0 119 lis.LIS3DH_GetTempRaw(&appData.accel_temp);
jejuho 0:de3e4a57ebe0 120 //uint8_t asdf;
jejuho 0:de3e4a57ebe0 121 //lis.LIS3DH_GetWHO_AM_I(&asdf);
jejuho 0:de3e4a57ebe0 122 //uint8_t val = 100;
jejuho 0:de3e4a57ebe0 123 //appData.lis = (asdf << 8) | val;
jejuho 0:de3e4a57ebe0 124
jejuho 0:de3e4a57ebe0 125 //appData.lis = lis.whoami();
jejuho 0:de3e4a57ebe0 126 }
jejuho 0:de3e4a57ebe0 127
jejuho 0:de3e4a57ebe0 128 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
jejuho 0:de3e4a57ebe0 129 {
jejuho 0:de3e4a57ebe0 130 ble.gap().startAdvertising();
jejuho 0:de3e4a57ebe0 131 }
jejuho 0:de3e4a57ebe0 132
jejuho 0:de3e4a57ebe0 133 void senseCallback(void)
jejuho 0:de3e4a57ebe0 134 {
jejuho 0:de3e4a57ebe0 135 ApplicationData_t appData;
jejuho 0:de3e4a57ebe0 136 setupApplicationData(appData);
jejuho 0:de3e4a57ebe0 137 ble.gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));
jejuho 0:de3e4a57ebe0 138 }
jejuho 0:de3e4a57ebe0 139
jejuho 0:de3e4a57ebe0 140 int main()
jejuho 0:de3e4a57ebe0 141 {
jejuho 0:de3e4a57ebe0 142
jejuho 0:de3e4a57ebe0 143 //LEDS off
jejuho 0:de3e4a57ebe0 144 myled1 = 0;
jejuho 0:de3e4a57ebe0 145 myled2 = 0;
jejuho 0:de3e4a57ebe0 146 //myled3 = 0;
jejuho 0:de3e4a57ebe0 147
jejuho 0:de3e4a57ebe0 148 //Without this setup CS lines of AT45 & LIS3DH are in conflict, causing huge current consumption
jejuho 0:de3e4a57ebe0 149 //i.e. both are connected to same SPI interface at the same time
jejuho 0:de3e4a57ebe0 150 #if defined(TARGET_NRF51822_NODE_V3_OTA) || defined(TARGET_NRF51822_NODE_V3) || defined(TARGET_NRF51822_NODE_V3_BOOT)
jejuho 0:de3e4a57ebe0 151 DigitalOut LIS_CS_0(CS);
jejuho 0:de3e4a57ebe0 152 LIS_CS_0 = 1; //not selected
jejuho 0:de3e4a57ebe0 153
jejuho 0:de3e4a57ebe0 154 DigitalOut AT_CS(p5);
jejuho 0:de3e4a57ebe0 155 DigitalOut AT_RS(p6);
jejuho 0:de3e4a57ebe0 156
jejuho 0:de3e4a57ebe0 157 AT_CS = 1; //not selected
jejuho 0:de3e4a57ebe0 158 AT_RS = 0; //asserted == reset state
jejuho 0:de3e4a57ebe0 159 wait_ms(100);
jejuho 0:de3e4a57ebe0 160 AT_RS = 1;
jejuho 0:de3e4a57ebe0 161 #endif
jejuho 0:de3e4a57ebe0 162
jejuho 0:de3e4a57ebe0 163 //Initialize SPI interface
jejuho 0:de3e4a57ebe0 164 SPI spi(MOSI, MISO, SCLK); // mosi, miso, sclk
jejuho 0:de3e4a57ebe0 165 spi.format(8,3);
jejuho 0:de3e4a57ebe0 166 spi.frequency(8000000);
jejuho 0:de3e4a57ebe0 167 //setup AT45 dataflash to powersaving mode
jejuho 0:de3e4a57ebe0 168 AT45* flash = new AT45(spi, p5);
jejuho 0:de3e4a57ebe0 169 flash->ultra_deep_power_down(true);
jejuho 0:de3e4a57ebe0 170
jejuho 0:de3e4a57ebe0 171 //Accelerometer interrupt pin configuration
jejuho 0:de3e4a57ebe0 172 gpiote_init();
jejuho 0:de3e4a57ebe0 173
jejuho 0:de3e4a57ebe0 174 //Disconnect input buffers to save power
jejuho 0:de3e4a57ebe0 175 //disabled for testing
jejuho 0:de3e4a57ebe0 176 //disconnect_input_buffers();
jejuho 0:de3e4a57ebe0 177
jejuho 0:de3e4a57ebe0 178 //Initialize LIS3DH driver
jejuho 0:de3e4a57ebe0 179 lis.InitLIS3DH(LIS3DH_NORMAL, LIS3DH_ODR_100Hz, LIS3DH_FULLSCALE_2); //Init Acc-sensor
jejuho 0:de3e4a57ebe0 180 //lis.LIS3DH_SetTemperature(MEMS_ENABLE);
jejuho 0:de3e4a57ebe0 181 //lis.LIS3DH_SetADCAux(MEMS_ENABLE);
jejuho 0:de3e4a57ebe0 182 //lis.LIS3DH_SetBDU(MEMS_ENABLE);
jejuho 0:de3e4a57ebe0 183 //enable threshold to generate interrupt
jejuho 0:de3e4a57ebe0 184 lis.SetLIS3DHActivityDetection(3, LIS3DH_INT_MODE_6D_POSITION, 1);
jejuho 0:de3e4a57ebe0 185 //disable...
jejuho 0:de3e4a57ebe0 186 //lis.SetLIS3DHActivityDetection(20, LIS3DH_INT_MODE_OR, 0);
jejuho 0:de3e4a57ebe0 187
jejuho 0:de3e4a57ebe0 188 // Enable GPIOTE interrupt in Nested Vector Interrupt Controller.
jejuho 0:de3e4a57ebe0 189 NVIC_ClearPendingIRQ(GPIOTE_IRQn);
jejuho 0:de3e4a57ebe0 190 NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Set << GPIOTE_INTENSET_PORT_Pos;
jejuho 0:de3e4a57ebe0 191 NVIC_SetPriority(GPIOTE_IRQn, 1);
jejuho 0:de3e4a57ebe0 192 NVIC_EnableIRQ(GPIOTE_IRQn);
jejuho 0:de3e4a57ebe0 193 //sd_nvic_EnableIRQ(GPIOTE_IRQn);
jejuho 0:de3e4a57ebe0 194
jejuho 0:de3e4a57ebe0 195 //osDelay(osWaitForever);
jejuho 0:de3e4a57ebe0 196 //Was Getting 13.2uA with these settings (flash deep power down).
jejuho 0:de3e4a57ebe0 197 //With ultra deep power down 7.8uA... rose back to ~11uA??? Seems to fluctuate. Now getting 9.4... IO issue?
jejuho 0:de3e4a57ebe0 198 //Now getting 5.4uA
jejuho 0:de3e4a57ebe0 199
jejuho 0:de3e4a57ebe0 200 //device current
jejuho 0:de3e4a57ebe0 201 //3.8uA idle (SYSTEM-ON base current with 32 kB RAM enabled.). Executing code from flash memory 4.1uA. From ram 2.4uA
jejuho 0:de3e4a57ebe0 202 //32.768 kHz crystal oscillator 0.4uA / 32.768 kHz RC oscillator (32k RCOSC) 1.1uA (kumpi on?)
jejuho 0:de3e4a57ebe0 203 //RTC Timer (LFCLK source) 0.1uA
jejuho 0:de3e4a57ebe0 204 //==3.8 + (0.4) + 0.1uA + 5*0.1 (digitalout active) = 4.8uA
jejuho 0:de3e4a57ebe0 205
jejuho 0:de3e4a57ebe0 206 //(watchdog) 0.1uA
jejuho 0:de3e4a57ebe0 207 //GPIO as input = 22uA (Run current with 1 or more GPIOTE active channels in Input mode.)
jejuho 0:de3e4a57ebe0 208 //as output 0.1A (Run current with 1 or more GPIOTE active channels in Output mode)
jejuho 0:de3e4a57ebe0 209
jejuho 0:de3e4a57ebe0 210 //Peripherals current
jejuho 0:de3e4a57ebe0 211 //BMP 180 0.1uA standby, 5uA standard mode, 7uA high resolution mode
jejuho 0:de3e4a57ebe0 212 //LIS3DH 0.5uA standby mode, varies a lot in measurement mode
jejuho 0:de3e4a57ebe0 213 //Si7021 0.06uA standby mode, 150uA active
jejuho 0:de3e4a57ebe0 214 //AT45 Ultra deep power down 0,4uA, deep power down 5uA. Standby 25uA. 11mA active
jejuho 0:de3e4a57ebe0 215 //== 0.1uA + 0.5uA + 0.06uA + 0.4uA = 1.06uA
jejuho 0:de3e4a57ebe0 216
jejuho 0:de3e4a57ebe0 217 //total should be ~5.86 (or 5.46 depending on whether oscillator is included in system idle current)
jejuho 0:de3e4a57ebe0 218
jejuho 0:de3e4a57ebe0 219 //Initialize BLE stuff
jejuho 0:de3e4a57ebe0 220 ble.init();
jejuho 0:de3e4a57ebe0 221 ble.gap().onDisconnection(disconnectionCallback);
jejuho 0:de3e4a57ebe0 222
jejuho 0:de3e4a57ebe0 223 #ifdef USE_DFU
jejuho 0:de3e4a57ebe0 224 DFUService dfu(ble);
jejuho 0:de3e4a57ebe0 225 #endif
jejuho 0:de3e4a57ebe0 226
jejuho 0:de3e4a57ebe0 227 /* Setup advertising. */
jejuho 0:de3e4a57ebe0 228 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
jejuho 0:de3e4a57ebe0 229 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
jejuho 0:de3e4a57ebe0 230 ApplicationData_t appData;
jejuho 0:de3e4a57ebe0 231 setupApplicationData(appData);
jejuho 0:de3e4a57ebe0 232 //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
jejuho 0:de3e4a57ebe0 233 //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
jejuho 0:de3e4a57ebe0 234 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));
jejuho 0:de3e4a57ebe0 235
jejuho 0:de3e4a57ebe0 236 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jejuho 0:de3e4a57ebe0 237 //ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
jejuho 0:de3e4a57ebe0 238 ble.gap().setAdvertisingInterval(100); /* 1000ms. */
jejuho 0:de3e4a57ebe0 239 ble.gap().startAdvertising();
jejuho 0:de3e4a57ebe0 240
jejuho 0:de3e4a57ebe0 241 Ticker ticker;
jejuho 0:de3e4a57ebe0 242 ticker.attach(senseCallback, 0.1);
jejuho 0:de3e4a57ebe0 243
jejuho 0:de3e4a57ebe0 244 ///Could have main loop here doing something
jejuho 0:de3e4a57ebe0 245 while(true) {
jejuho 0:de3e4a57ebe0 246 ble.waitForEvent();
jejuho 0:de3e4a57ebe0 247 }
jejuho 0:de3e4a57ebe0 248 }
jejuho 0:de3e4a57ebe0 249