diff --git a/common/app_info.h b/common/app_info.h index efee1c0e..2ab5b79c 100644 --- a/common/app_info.h +++ b/common/app_info.h @@ -3,10 +3,10 @@ * A place to put all common defines */ //make sure the FW_VERSION_STRING fits in MorpheusCommand.top_version (16 bytes) -#define FW_VERSION_STRING "1.7.1" +#define FW_VERSION_STRING "1.7.2" //pill only -#define FIRMWARE_VERSION_8BIT (0x47) +#define FIRMWARE_VERSION_8BIT (0x48) #define BLE_SIG_COMPANY_ID 1002 diff --git a/common/imu_data.h b/common/imu_data.h index cc7d3edc..f1980820 100644 --- a/common/imu_data.h +++ b/common/imu_data.h @@ -17,6 +17,7 @@ enum imu_hz { IMU_HZ_1 = 1, IMU_HZ_10 = 2, IMU_HZ_25 = 3, + IMU_HZ_400 = 7, }; enum imu_accel_range { diff --git a/drivers/imu.c b/drivers/imu.c index 3866e2f2..8cbf5dc2 100644 --- a/drivers/imu.c +++ b/drivers/imu.c @@ -166,6 +166,10 @@ inline void imu_enable_all_axis() _register_write(REG_CTRL_1, reg | (AXIS_ENABLE)); } +void imu_clear_tap_interrupt(void){ + uint8_t int_source; + _register_read(REG_CLICK_SRC, &int_source); +} inline uint8_t imu_clear_interrupt_status() { @@ -174,7 +178,7 @@ inline uint8_t imu_clear_interrupt_status() _register_read(REG_INT1_SRC, &int_source); imu_reset_hp_filter(); - PRINTF("INT CLR %x\n", int_source); + PRINTF("INT CLR %x\r\n", int_source); return int_source; } @@ -472,8 +476,28 @@ int32_t imu_init_simple(enum SPI_Channel channel, APP_ASSERT(0); return -1; } + + imu_reset(); + _register_write(REG_CTRL_4, BLOCKDATA_UPDATE);//80 + return 0; +} + +int32_t imu_tap_enable(void){ + imu_enable_all_axis(); + imu_set_accel_freq(IMU_HZ_400); + _register_write(REG_CTRL_3, INT1_CLICK); + _register_write(REG_CTRL_5, (LATCH_INTERRUPT1)); + _register_write(REG_CTRL_6, INT_ACTIVE_LOW ); + + _register_write(REG_CLICK_CFG, 0x3F);//all directions clickable + _register_write(REG_CLICK_SRC, CLICK_SRC_DCLICK | CLICK_SRC_STAP); + _register_write(REG_CLICK_THR, 0x06); + _register_write(REG_TIME_LIMIT, 0x04); + _register_write(REG_TIME_LATENCY, 0x24); + _register_write(REG_TIME_WINDOW, 0x7F); + return 0; } int32_t imu_init_low_power(enum SPI_Channel channel, enum SPI_Mode mode, uint8_t miso, uint8_t mosi, uint8_t sclk, diff --git a/drivers/imu.h b/drivers/imu.h index b8048ae8..72693573 100644 --- a/drivers/imu.h +++ b/drivers/imu.h @@ -110,3 +110,5 @@ int32_t imu_init_simple(enum SPI_Channel channel, enum SPI_Mode mode, uint8_t miso, uint8_t mosi, uint8_t sclk, uint8_t nCS); +int32_t imu_tap_enable(void); +void imu_clear_tap_interrupt(void); diff --git a/drivers/lis2dh_registers.h b/drivers/lis2dh_registers.h index 7d38a7d1..458156a1 100644 --- a/drivers/lis2dh_registers.h +++ b/drivers/lis2dh_registers.h @@ -125,6 +125,22 @@ enum IMU_Reg_Bits { INT1_X_HIGH = 0x2, INT1_X_LOW = 0x1, + //REG_CLICK_CFG + CLICK_CFG_ZD = 0x20, + CLICK_CFG_ZS = 0x10, + CLICK_CFG_YD = 0x08, + CLICK_CFG_YS = 0x04, + CLICK_CFG_XD = 0x02, + CLICK_CFG_XS = 0x01, + + //REG_CLICK_SRC + CLICK_SRC_IA = 0x40, + CLICK_SRC_DCLICK = 0x20, + CLICK_SRC_STAP = 0x10, + CLICK_SRC_SIGN = 0x08, + CLICK_SRC_Z = 0x04, + CLICK_SRC_Y = 0x02, + CLICK_SRC_X = 0x01, //INT1_SRC //... we will just look for not zero... // reading this one will clear the interrupt in latched mode diff --git a/morpheus/app.h b/morpheus/app.h index 6f0be29f..d58953d6 100644 --- a/morpheus/app.h +++ b/morpheus/app.h @@ -10,7 +10,7 @@ enum { APP_TIMER_PRESCALER = 255, //overflow every 36 hours - APP_TIMER_MAX_TIMERS = 6, + APP_TIMER_MAX_TIMERS = 7, APP_TIMER_OP_QUEUE_SIZE = 2, }; diff --git a/morpheus/message_ble.c b/morpheus/message_ble.c index fea495e7..0ef5d3de 100644 --- a/morpheus/message_ble.c +++ b/morpheus/message_ble.c @@ -709,6 +709,9 @@ static void _pair_morpheus(MorpheusCommand* command) MSG_Base_ReleaseDataAtomic(command->accountId.arg); } +bool is_boot_completed(void){ + return self.boot_state == BOOT_COMPLETED; +} bool morpheus_ble_route_protobuf_to_cc3200(MorpheusCommand* command) { diff --git a/morpheus/message_ble.h b/morpheus/message_ble.h index 7a8d2da2..965e5977 100644 --- a/morpheus/message_ble.h +++ b/morpheus/message_ble.h @@ -32,4 +32,4 @@ MSG_Status message_ble_pill_pairing_begin(MSG_Data_t* account_id_page); MSG_Status message_ble_remove_pill(MSG_Data_t* pill_id_page); void message_ble_reset(); void message_ble_on_protobuf_command(MSG_Data_t* data_page, MorpheusCommand* command); - +bool is_boot_completed(void); diff --git a/morpheus/message_imu.c b/morpheus/message_imu.c index 40eb3b7c..8e55b5f9 100644 --- a/morpheus/message_imu.c +++ b/morpheus/message_imu.c @@ -4,6 +4,11 @@ #include #include #include "imu.h" +#include +#include +#include "message_sspi.h" +#include +#include "platform.h" static const MSG_Central_t * parent; static MSG_Base_t base; static char * name = "IMU"; @@ -15,9 +20,69 @@ static MSG_Status _flush(void){ return SUCCESS; } +#ifdef PLATFORM_HAS_ACCEL_SPI +static uint8_t flipped = 0; +static app_timer_id_t _flip_timer; +static app_gpiote_user_id_t _gpiote_user; +static void _imu_gpiote_process(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low) +{ + imu_clear_tap_interrupt(); + if(!is_boot_completed()){ + return; + } + PRINTS("Tap\r\n"); + MSG_Data_t * data = MSG_Base_AllocateStringAtomic("tap"); + if(data){ + parent->dispatch( (MSG_Address_t){IMU, 0}, + (MSG_Address_t){SSPI,MSG_SSPI_TEXT}, + data); + MSG_Base_ReleaseDataAtomic(data); + } + parent->dispatch( (MSG_Address_t){IMU, 0}, + (MSG_Address_t){IMU,0}, + NULL); +} +static void _on_flip_timer(void* context){ + int16_t xyz[3] = {0}; + imu_accel_reg_read(xyz); + /* + *PRINTF("x:%d y:%d z:%d\r\n", xyz[0], xyz[1], xyz[2]); + */ + if(!is_boot_completed()){ + return; + } + if(xyz[2] > 1000 && !flipped){ + PRINTF("flipped"); + MSG_Data_t * data = MSG_Base_AllocateStringAtomic("flipped 1"); + if(data){ + parent->dispatch( (MSG_Address_t){IMU, 0}, + (MSG_Address_t){SSPI,MSG_SSPI_TEXT}, + data); + MSG_Base_ReleaseDataAtomic(data); + } + flipped = 1; + }else if(xyz[2] < -1000 && flipped){ + PRINTF("normal"); + MSG_Data_t * data = MSG_Base_AllocateStringAtomic("flipped 0"); + if(data){ + parent->dispatch( (MSG_Address_t){IMU, 0}, + (MSG_Address_t){SSPI,MSG_SSPI_TEXT}, + data); + MSG_Base_ReleaseDataAtomic(data); + } + flipped = 0; + } +} +#endif static MSG_Status _init(void){ #ifdef PLATFORM_HAS_ACCEL_SPI - if(0 == imu_init_simple(SPI_Channel_0, SPI_Mode3, ACCEL_MISO, ACCEL_MOSI, ACCEL_SCLK, ACCEL_nCS)){ + if( 0 == imu_init_simple(SPI_Channel_0, SPI_Mode3, ACCEL_MISO, ACCEL_MOSI, ACCEL_SCLK, ACCEL_nCS) + && 0 == imu_tap_enable() + ){ + APP_OK(app_gpiote_user_enable(_gpiote_user)); + imu_clear_interrupt_status(); + imu_clear_tap_interrupt(); + app_timer_start(_flip_timer, 250, NULL); return SUCCESS; }else{ return FAIL; @@ -37,5 +102,11 @@ MSG_Base_t * MSG_IMU_Init(const MSG_Central_t * central){ base.send = _send; base.type = IMU; base.typestr = name; +#ifdef PLATFORM_HAS_ACCEL_SPI + nrf_gpio_cfg_input(ACCEL_INT, NRF_GPIO_PIN_NOPULL); + APP_OK(app_gpiote_user_register(&_gpiote_user, 0, 1 << ACCEL_INT, _imu_gpiote_process)); + APP_OK(app_gpiote_user_disable(_gpiote_user)); + APP_OK(app_timer_create(&_flip_timer, APP_TIMER_MODE_REPEATED, _on_flip_timer)); +#endif return &base; }