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
Diff: main.cpp
- 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