AKM Development Platform. This is the D7.014 version.

Dependencies:   AK09970 AK099XX AK7401 AK7451 AK8963X AK9750 AK9752 AkmSensor BLE_API I2CNano MCP342x SerialNano SpiNano TCA9554A mbed nRF51822

Fork of AKDP by Masahiko Fukasawa

Revision:
12:522a22a23f8a
Parent:
11:53e52f5f1051
Child:
14:76205d28fea2
diff -r 53e52f5f1051 -r 522a22a23f8a main.cpp
--- a/main.cpp	Thu Jun 16 18:37:41 2016 +0000
+++ b/main.cpp	Fri Jul 08 22:28:13 2016 +0000
@@ -4,6 +4,7 @@
 #include "ble/BLE.h"
 #include "ble/services/UARTService.h"
 #include "SerialNano.h"
+#include "akmsensor.h"
 #include "akmsensormanager.h"
 #include "debug.h"
 #include "tca9554a.h"
@@ -18,7 +19,8 @@
 #define CR                              '\r'
 #define LF                              '\n'
 
-#define DEVICE_NAME                     "AKDP Rev002"
+#define DEVICE_NAME                     "AKDP Rev.D7.003"
+
 
 BLE                 ble;
 UARTService*        uartService;
@@ -29,6 +31,8 @@
 #endif
 
 AkmSensorManager*   manager;
+uint8_t id;
+uint8_t subId;
 
 void WrittenHandler(const GattWriteCallbackParams *Handler)
 {   
@@ -100,43 +104,7 @@
     ble.gap().startAdvertising();
 } 
 
-int main(void)
-{   
-    // USB serial
-    serial.baud(115200);
-            
-    // serial port RX event
-    serial.attach(&usbUartCallback);
-
-#ifdef DEBUG    
-    Debug::setSerial(&serial);
-    MSG("#Debug Mode.\n");
-#endif
-
-#ifdef REV_D
-    /* Rev.D */
-    {
-        MSG("#I2C GPIO Expander.\n");
-        const int TIME_FOR_OE_MS = 100;
-        const TCA9554A::Port PORT_OE_LVS1 = TCA9554A::PORT_7;
-        const TCA9554A::Port PORT_OE_LVS2 = TCA9554A::PORT_6;
-        I2C i2c(I2C_SDA, I2C_SCL);
-        TCA9554A tca9554a(&i2c, TCA9554A::SLAVE_ADDRESS_38H);
-        // Initializes TCA9554A (I2C GPIO Expander)
-        tca9554a.configurePort(PORT_OE_LVS1, TCA9554A::DIR_OUTPUT);
-        tca9554a.configurePort(PORT_OE_LVS2, TCA9554A::DIR_OUTPUT);
-        // Makes sure that the OE is low first.
-//        tca9554a.setPortLevel(PORT_OE_LVS1, TCA9554A::LOW);
-//        tca9554a.setPortLevel(PORT_OE_LVS2, TCA9554A::LOW);
-        wait_ms(TIME_FOR_OE_MS);
-        // Sets the OE pins high.
-        tca9554a.setPortLevel(PORT_OE_LVS1, TCA9554A::HIGH);
-        tca9554a.setPortLevel(PORT_OE_LVS2, TCA9554A::HIGH);
-        MSG("#Start main loop.\n");
-//        manager->releaseTWI();
-    }
-#endif    
-    
+void bleSetup(){
     ble.init();
     // setup advertising 
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
@@ -149,19 +117,188 @@
     ble.gap().onDisconnection(disconnectionCallback);
     ble.gattServer().onDataWritten(WrittenHandler);  
     
-    // 40ms; in multiples of 0.625ms. 
-    ble.gap().setAdvertisingInterval(64);
+    // 100ms; in multiples of 0.625ms. 
+    ble.gap().setAdvertisingInterval(100);
     ble.gap().startAdvertising(); 
+}
 
+
+#ifdef REV_D
+int16_t getAdcData(MCP342X *mcp3428, MCP342X::AdcChannel ch, MCP342X::SampleSetting s) {
+    const int WAIT_ADC_MS = 1;
+
+    // Configure channel and trigger.
+    mcp3428->setChannel(ch);
+    mcp3428->setSampleSetting(s);
+    mcp3428->trigger();
+
+    // polling data (!blocking)
+    MCP342X::Data data;
+    do {
+        wait_ms(WAIT_ADC_MS);
+        mcp3428->getData(&data);
+    } while(data.st == MCP342X::DATA_NOT_UPDATED);
+    
+    return data.value;
+}
+#endif
+
+uint8_t getId(PinName pin, uint8_t bits)
+{
+#ifndef REV_D
+    /* Rev.C */
+    AnalogIn id(pin);
+    MSG("#Voltage=%5.2f[V]\n",id*3.0);
+    double s = id + 1.0/(double)(pow(2.0,bits+1));
+    uint8_t value = (uint8_t)(s*pow(2.0,bits));
+#else
+    /* Rev.D */
+    MSG("#GetID\n");
+    
+    I2C i2c(I2C_SDA, I2C_SCL);
+    // ADC
+    MCP342X mcp342x(&i2c, MCP342X::SLAVE_ADDRESS_6EH);
+    mcp342x.setConversionMode(MCP342X::ONE_SHOT);
+    MCP342X::AdcChannel ch;
+    if (pin == ANALOG_SENSOR_ID) {
+        ch = MCP342X::ADC_CH1;
+    } else { // pin == ANALOG_SENSOR_ID_SUB
+        ch = MCP342X::ADC_CH2;
+    }
+    int16_t val = getAdcData(&mcp342x, ch, MCP342X::SAMPLE_240HZ_12BIT);
+    MSG("#12bit ADC Val = %d.\n", val);
+    
+    const int16_t VAL_MAX = 3000-2048;   // Corresponds to 3V
+    const int16_t VAL_MIN = -2048;       // Corresponds to 0V
+    
+    uint8_t value = (uint8_t)((val - VAL_MIN)/(float)(VAL_MAX - VAL_MIN) * (1 << bits) + 0.5);
+    MSG("#ID = %d.\n", value);
+
+#endif    
+    return value;
+}
+
+
+void releaseTWI(){
+    NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+    NRF_TWI0->POWER  = 0;
+    NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+    NRF_TWI1->POWER  = 0;
+}
+
+void initAkdpBoard(){
+
+    // CSN High
+    DigitalOut _cs = DigitalOut(SPI_CS);
+    _cs.write(1);
+//    DigitalOut _so = DigitalOut(SPI_MISO);
+//    _so.write(1);
+//    DigitalOut _si = DigitalOut(SPI_MOSI);
+//    _si.write(1);
+//    DigitalOut _sck = DigitalOut(SPI_SCK);
+//    _sck.write(1);
+    
+    MSG("#I2C GPIO Expander.\n");
+    const int TIME_FOR_OE_MS = 100;
+    const TCA9554A::Port PORT_OE_LVS1   = TCA9554A::PORT_7;
+    const TCA9554A::Port PORT_OE_LVS2   = TCA9554A::PORT_6;
+    const TCA9554A::Port PORT_SPIN      = TCA9554A::PORT_5;
+    const TCA9554A::Port PORT_RSV_RSTN  = TCA9554A::PORT_0;
+    
+    I2C i2c(I2C_SDA, I2C_SCL);
+    TCA9554A tca9554a(&i2c, TCA9554A::SLAVE_ADDRESS_38H);
+    
+    // Initializes TCA9554A (I2C GPIO Expander)
+    tca9554a.configurePort(PORT_OE_LVS1, TCA9554A::DIR_OUTPUT);
+    tca9554a.configurePort(PORT_OE_LVS2, TCA9554A::DIR_OUTPUT);
+    tca9554a.configurePort(PORT_SPIN, TCA9554A::DIR_OUTPUT);
+    tca9554a.configurePort(PORT_RSV_RSTN, TCA9554A::DIR_OUTPUT);
+    
+    //  enable 5V level shifter
+    tca9554a.setPortLevel(PORT_OE_LVS1, TCA9554A::HIGH);
+    tca9554a.setPortLevel(PORT_OE_LVS2, TCA9554A::HIGH);
+    tca9554a.setPortLevel(PORT_RSV_RSTN, TCA9554A::HIGH);
+    tca9554a.setPortLevel(PORT_SPIN, TCA9554A::HIGH);
+
+    wait_ms(TIME_FOR_OE_MS);
+    
+    //  disable 1.8V level shifter to read ID
+    tca9554a.setPortLevel(PORT_OE_LVS1, TCA9554A::LOW);
+    MSG("#LVS1 Low.\n");
+    
+    wait_ms(TIME_FOR_OE_MS);
+    
+    //  read ID and subId from ADC
+    id = getId(ANALOG_SENSOR_ID,4);
+    uint8_t subid_bitlen = 4;
+    if(id == AkmSensor::AKM_PRIMARY_ID_AKD_SPI || id == AkmSensor::AKM_PRIMARY_ID_AKD_I2C){
+        MSG("#5 bit sub ID.\n");
+        subid_bitlen = 5;
+    }
+    subId = getId(ANALOG_SENSOR_ID_SUB,subid_bitlen);
+
+    //  enable 1.8V level shifter
+    tca9554a.setPortLevel(PORT_OE_LVS1, TCA9554A::HIGH);
+    MSG("#LVS1 High.\n");
+
+    wait_ms(TIME_FOR_OE_MS);
+
+    // RSTN control
+    if(id == AkmSensor::AKM_PRIMARY_ID_AKD_SPI || id == AkmSensor::AKM_PRIMARY_ID_AKD_I2C){
+        tca9554a.setPortLevel(PORT_RSV_RSTN, TCA9554A::LOW);
+        wait_ms(TIME_FOR_OE_MS);
+        tca9554a.setPortLevel(PORT_RSV_RSTN, TCA9554A::HIGH);                
+        MSG("#Detect AKD, RSTN control.\n");
+    }
+
+    // SPI disable/enable
+    if( id == AkmSensor::AKM_PRIMARY_ID_AKD_SPI || id == AkmSensor::AKM_PRIMARY_ID_ANGLE_SENSOR ){
+        tca9554a.setPortLevel(PORT_SPIN, TCA9554A::LOW);
+        // Disable 5.0V level shifter in order to ADC doesn't respond.
+        tca9554a.setPortLevel(PORT_OE_LVS2, TCA9554A::LOW);
+        MSG("#Detect SPI, set SPIN low.\n");
+    }
+    else{
+        tca9554a.setPortLevel(PORT_SPIN, TCA9554A::HIGH);
+        tca9554a.setPortLevel(PORT_OE_LVS2, TCA9554A::HIGH);
+    }
+
+    wait_ms(TIME_FOR_OE_MS);
+    
+    releaseTWI();
+}
+
+
+
+int main(void)
+{   
+    // USB serial
+    serial.baud(115200);
+    
+    // serial port RX event
+    serial.attach(&usbUartCallback);
+    
+#ifdef DEBUG
+    Debug::setSerial(&serial);
+    MSG("#Debug Mode.\n");
+#endif
+    
+    // initialize AKDP board
+    initAkdpBoard();
+
+    // ble initialize
+    bleSetup();
+    
     // BLE UART service
     uartService = new UARTService(ble);
-
+    
     // create sensor manager
     manager = new AkmSensorManager(&serial, uartService);
-    if( manager->init() == AkmSensorManager::ERROR){
+    
+    if( manager->init(id, subId) == AkmSensorManager::ERROR){
         MSG("#Error: sensor is NULL\n");
     }
-    
+
     MSG("#Connecting...\n");
     
     // main loop