fix nrf51822 i2c & spi conflict

Dependencies:   BLE_API eMPL_MPU6050 nRF51822

Fork of Seeed_Tiny_BLE_Flash by Darren Huang

Files at this revision

API Documentation at this revision

Comitter:
yihui
Date:
Sat Feb 07 08:13:51 2015 +0000
Child:
1:fc2f9d636751
Commit message:
initial

Changed in this revision

BLE_API.lib Show annotated file Show diff for this revision Revisions of this file
battery.h Show annotated file Show diff for this revision Revisions of this file
eMPL_MPU6050.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF51822.lib Show annotated file Show diff for this revision Revisions of this file
tiny_ble.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BLE_API.lib	Sat Feb 07 08:13:51 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#1407d2f1ce3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/battery.h	Sat Feb 07 08:13:51 2015 +0000
@@ -0,0 +1,43 @@
+
+
+#ifndef __BATTERY_H__
+#define __BATTERY_H__
+
+#include "mbed.h"
+
+class Battery {
+public:
+    Battery(PinName pin) {
+        uint32_t n = (uint32_t) pin;
+        channel = 1 << (1 + n);
+    }
+    
+    float read() {
+        uint32_t pre_enable_register = NRF_ADC->ENABLE;
+        uint32_t pre_config_register = NRF_ADC->CONFIG;
+        
+        
+        NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
+        NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
+                          (ADC_CONFIG_INPSEL_AnalogInputNoPrescaling << ADC_CONFIG_INPSEL_Pos) |
+                          (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
+                          (channel << ADC_CONFIG_PSEL_Pos) |
+                          (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+                          
+        NRF_ADC->TASKS_START = 1;
+        while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {
+        } 
+        
+        uint16_t value = NRF_ADC->RESULT;
+        
+        NRF_ADC->ENABLE = pre_enable_register;
+        NRF_ADC->CONFIG = pre_config_register;
+        
+        return (float)value * (1.0f / (float)0x3FF) * 1.2 * 12.2 / 2.2;    
+    }
+    
+private:
+    uint32_t channel;
+};
+
+#endif // __BATTERY_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eMPL_MPU6050.lib	Sat Feb 07 08:13:51 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/Seeed/code/eMPL_MPU6050/#1b6dab73c06b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Feb 07 08:13:51 2015 +0000
@@ -0,0 +1,301 @@
+
+#include "mbed.h"
+#include "mbed_i2c.h"
+#include "inv_mpu.h"
+#include "inv_mpu_dmp_motion_driver.h"
+
+#include "BLEDevice.h"
+#include "DFUService.h"
+#include "UARTService.h"
+
+
+#define LOG(...)    { pc.printf(__VA_ARGS__); }
+
+#define LED_GREEN   p21
+#define LED_RED     p22
+#define LED_BLUE    p23
+#define BUTTON_PIN  p17
+#define BATTERY_PIN p1
+
+#define MPU6050_SDA p12
+#define MPU6050_SCL p13
+
+#define UART_TX     p9
+#define UART_RX     p11
+#define UART_CTS    p8
+#define UART_RTS    p10
+
+/* Starting sampling rate. */
+#define DEFAULT_MPU_HZ  (100)
+
+DigitalOut blue(LED_BLUE);
+DigitalOut green(LED_GREEN);
+DigitalOut red(LED_RED);
+
+InterruptIn button(BUTTON_PIN);
+AnalogIn    battery(BATTERY_PIN);
+Serial pc(UART_TX, UART_RX);
+
+InterruptIn motion_probe(p14);
+
+BLEDevice  ble;
+UARTService *uartServicePtr;
+
+volatile bool bleIsConnected = false;
+volatile uint8_t tick_event = 0;
+volatile uint8_t motion_event = 0;
+static signed char board_orientation[9] = {
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 1
+};
+
+
+void check_i2c_bus(void);
+unsigned short inv_orientation_matrix_to_scalar( const signed char *mtx);
+
+void connectionCallback(Gap::Handle_t handle, Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, const Gap::ConnectionParams_t *params)
+{
+    LOG("Connected!\n");
+    bleIsConnected = true;
+}
+
+void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
+{
+    LOG("Disconnected!\n");
+    LOG("Restarting the advertising process\n");
+    ble.startAdvertising();
+    bleIsConnected = false;
+}
+
+void tick(void)
+{
+    green = !green;
+}
+
+void detect(void)
+{
+    LOG("Button pressed\n");
+    
+    blue = !blue;
+}
+
+void motion_interrupt_handle(void)
+{
+    motion_event = 1;
+}
+
+void tap_cb(unsigned char direction, unsigned char count)
+{
+    LOG("Tap motion detected\n");
+}
+
+void android_orient_cb(unsigned char orientation)
+{
+    LOG("Oriention changed\n");
+}
+
+
+int main(void)
+{
+    blue  = 1;
+    green = 1;
+    red   = 1;
+
+    pc.baud(115200);
+    LOG("---- Seeed Tiny BLE ----\n");
+    
+    Ticker ticker;
+    ticker.attach(tick, 3);
+
+    button.fall(detect);
+
+    LOG("Initialising the nRF51822\n");
+    ble.init();
+    ble.onDisconnection(disconnectionCallback);
+    ble.onConnection(connectionCallback);
+
+
+    /* setup advertising */
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
+    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
+                                     (const uint8_t *)"smurfs", sizeof("smurfs"));
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
+                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
+    DFUService dfu(ble);                                 
+    UARTService uartService(ble);
+    uartServicePtr = &uartService;
+    //uartService.retargetStdout();
+
+    ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
+    ble.startAdvertising();
+    
+    check_i2c_bus();
+   
+    mbed_i2c_init(MPU6050_SDA, MPU6050_SCL);
+    motion_probe.fall(motion_interrupt_handle);
+    
+
+    if (mpu_init(0)) {
+//         LOG("failed to initialize mpu6050\r\n");
+    }
+    
+    /* Get/set hardware configuration. Start gyro. */
+    /* Wake up all sensors. */
+    mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL);
+    /* Push both gyro and accel data into the FIFO. */
+    mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL);
+    mpu_set_sample_rate(DEFAULT_MPU_HZ);
+    
+    /* Read back configuration in case it was set improperly. */
+    unsigned char accel_fsr;
+    unsigned short gyro_rate, gyro_fsr;
+    mpu_get_sample_rate(&gyro_rate);
+    mpu_get_gyro_fsr(&gyro_fsr);
+    mpu_get_accel_fsr(&accel_fsr);
+    
+    dmp_load_motion_driver_firmware();
+    dmp_set_orientation(
+        inv_orientation_matrix_to_scalar(board_orientation));
+    dmp_register_tap_cb(tap_cb);
+    dmp_register_android_orient_cb(android_orient_cb);
+    
+    uint16_t dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
+                       DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
+                       DMP_FEATURE_GYRO_CAL;
+    dmp_enable_feature(dmp_features);
+    dmp_set_fifo_rate(DEFAULT_MPU_HZ);
+    mpu_set_dmp_state(1);
+    
+//     dmp_set_interrupt_mode(DMP_INT_GESTURE);
+    dmp_set_tap_thresh(TAP_XYZ, 50);
+
+    while (true) {
+        if (motion_event) {
+            motion_event = 0;
+            
+            unsigned long sensor_timestamp;
+            short gyro[3], accel[3], sensors;
+            long quat[4];
+            unsigned char more = 1;
+            
+            while (more) {
+                /* This function gets new data from the FIFO when the DMP is in
+                 * use. The FIFO can contain any combination of gyro, accel,
+                 * quaternion, and gesture data. The sensors parameter tells the
+                 * caller which data fields were actually populated with new data.
+                 * For example, if sensors == (INV_XYZ_GYRO | INV_WXYZ_QUAT), then
+                 * the FIFO isn't being filled with accel data.
+                 * The driver parses the gesture data to determine if a gesture
+                 * event has occurred; on an event, the application will be notified
+                 * via a callback (assuming that a callback function was properly
+                 * registered). The more parameter is non-zero if there are
+                 * leftover packets in the FIFO.
+                 */
+                dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,
+                              &more);
+                /* Gyro and accel data are written to the FIFO by the DMP in chip
+                 * frame and hardware units. This behavior is convenient because it
+                 * keeps the gyro and accel outputs of dmp_read_fifo and
+                 * mpu_read_fifo consistent.
+                 */
+                if (sensors & INV_XYZ_GYRO) {
+                    // LOG("GYRO: %d, %d, %d\n", gyro[0], gyro[1], gyro[2]);
+                }
+                if (sensors & INV_XYZ_ACCEL) {
+                    // LOG("ACC: %d, %d, %d\n", accel[0], accel[1], accel[2]);
+                }
+                
+                /* Unlike gyro and accel, quaternions are written to the FIFO in
+                 * the body frame, q30. The orientation is set by the scalar passed
+                 * to dmp_set_orientation during initialization.
+                 */
+                if (sensors & INV_WXYZ_QUAT) {
+                    // LOG("QUAT: %ld, %ld, %ld, %ld\n", quat[0], quat[1], quat[2], quat[3]);
+                }
+            }
+        } else {
+            ble.waitForEvent();
+        }
+    }
+}
+
+void check_i2c_bus(void)
+{
+    
+    DigitalInOut scl(MPU6050_SCL);
+    DigitalInOut sda(MPU6050_SDA);
+    
+    scl.input();
+    sda.input();
+    int scl_level = scl;
+    int sda_level = sda;
+    if (scl_level == 0 || sda_level == 0) {
+        printf("scl: %d, sda: %d, i2c bus is not released\r\n", scl_level, sda_level);
+        
+        scl.output();
+        for (int i = 0; i < 8; i++) {
+            scl = 0;
+            wait_us(10);
+            scl = 1;
+            wait_us(10);
+        }
+    }
+    
+    scl.input();
+    
+    scl_level = scl;
+    sda_level = sda;
+    if (scl_level == 0 || sda_level == 0) {
+        printf("scl: %d, sda: %d, i2c bus is still not released\r\n", scl_level, sda_level);
+    }
+}
+
+/* These next two functions converts the orientation matrix (see
+ * gyro_orientation) to a scalar representation for use by the DMP.
+ * NOTE: These functions are borrowed from Invensense's MPL.
+ */
+static inline unsigned short inv_row_2_scale(const signed char *row)
+{
+    unsigned short b;
+
+    if (row[0] > 0)
+        b = 0;
+    else if (row[0] < 0)
+        b = 4;
+    else if (row[1] > 0)
+        b = 1;
+    else if (row[1] < 0)
+        b = 5;
+    else if (row[2] > 0)
+        b = 2;
+    else if (row[2] < 0)
+        b = 6;
+    else
+        b = 7;      // error
+    return b;
+}
+
+unsigned short inv_orientation_matrix_to_scalar(
+    const signed char *mtx)
+{
+    unsigned short scalar;
+
+    /*
+       XYZ  010_001_000 Identity Matrix
+       XZY  001_010_000
+       YXZ  010_000_001
+       YZX  000_010_001
+       ZXY  001_000_010
+       ZYX  000_001_010
+     */
+
+    scalar = inv_row_2_scale(mtx);
+    scalar |= inv_row_2_scale(mtx + 3) << 3;
+    scalar |= inv_row_2_scale(mtx + 6) << 6;
+
+
+    return scalar;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Feb 07 08:13:51 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e188a91d3eaa
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51822.lib	Sat Feb 07 08:13:51 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#0e7a9efee6d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tiny_ble.h	Sat Feb 07 08:13:51 2015 +0000
@@ -0,0 +1,19 @@
+
+#ifndef __TINY_BLE_H__
+#define __TINY_BLE_H__
+
+#define LED_GREEN   p21
+#define LED_RED     p22
+#define LED_BLUE    p23
+#define BUTTON_PIN  p17
+#define BATTERY_PIN p1
+
+#define MPU6050_SDA p12
+#define MPU6050_SCL p13
+
+#define UART_TX     p9
+#define UART_RX     p11
+#define UART_CTS    p8
+#define UART_RTS    p10
+
+#endif // __TINY_BLE_H__