From 28062b510835655b26fc387db7e9db770621586d Mon Sep 17 00:00:00 2001 From: "Frederic.Pierson" Date: Sat, 12 Oct 2019 12:38:23 +0200 Subject: [PATCH] stm32/accel: Add support for KXTJ3. --- ports/stm32/accel.c | 76 ++++++++++++++++++++++++++++++++++++++++---- ports/stm32/modpyb.c | 2 +- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/ports/stm32/accel.c b/ports/stm32/accel.c index b4916b505..634ed0a75 100644 --- a/ports/stm32/accel.c +++ b/ports/stm32/accel.c @@ -33,21 +33,30 @@ #include "i2c.h" #include "accel.h" -#if MICROPY_HW_HAS_MMA7660 +#if MICROPY_HW_HAS_MMA7660 || MICROPY_HW_HAS_KXTJ3 /// \moduleref pyb /// \class Accel - accelerometer control /// -/// Accel is an object that controls the accelerometer. Example usage: +/// Accel is an object that controls the MMA7660 or the KXTJ3 accelerometer +/// depending on one/two constant in mpconfigboard.h file of board project : +/// #define MICROPY_HW_HAS_MMA7660 (1) +/// #define MICROPY_HW_HAS_KXTJ3 (0) // not mandatory if equal to 0 +/// +/// Example usage: /// /// accel = pyb.Accel() /// for i in range(10): /// print(accel.x(), accel.y(), accel.z()) /// -/// Raw values are between -32 and 31. +/// Raw values are between -32 and 31 for -/+ 1.5G acceleration for MMA7660. +/// Raw values are between -128 and 127 for -/+ 8G acceleration for KXTJ3. + #define I2C_TIMEOUT_MS (50) +#if MICROPY_HW_HAS_MMA7660 + #define ACCEL_ADDR (76) #define ACCEL_REG_X (0) #define ACCEL_REG_Y (1) @@ -56,16 +65,36 @@ #define ACCEL_REG_MODE (7) #define ACCEL_AXIS_SIGNED_VALUE(i) (((i) & 0x3f) | ((i) & 0x20 ? (~0x1f) : 0)) +#elif MICROPY_HW_HAS_KXTJ3 + +#define ACCEL_ADDR (0x0f) +#define ACCEL_REG_DCST_RESP (0x0c) +#define ACCEL_REG_WHO_AM_I (0x0f) +#define ACCEL_REG_X (0x07) // XOUT_H +#define ACCEL_REG_Y (0x09) // YOUT_H +#define ACCEL_REG_Z (0x0B) // ZOUT_H +#define ACCEL_REG_CTRL_REG1 (0x1B) +#define ACCEL_REG_CTRL_REG2 (0x1d) +#define ACCEL_REG_CTRL_REG2 (0x1d) +#define ACCEL_REG_DATA_CTRL_REG (0x21) +#define ACCEL_AXIS_SIGNED_VALUE(i) (((i) & 0x7f) | ((i) & 0x80 ? (~0x7f) : 0)) + +#endif + void accel_init(void) { + #if MICROPY_HW_HAS_MMA7660 // PB5 is connected to AVDD; pull high to enable MMA accel device mp_hal_pin_low(MICROPY_HW_MMA_AVDD_PIN); // turn off AVDD mp_hal_pin_output(MICROPY_HW_MMA_AVDD_PIN); + #endif } STATIC void accel_start(void) { // start the I2C bus in master mode i2c_init(I2C1, MICROPY_HW_I2C1_SCL, MICROPY_HW_I2C1_SDA, 400000, I2C_TIMEOUT_MS); + #if MICROPY_HW_HAS_MMA7660 + // turn off AVDD, wait 30ms, turn on AVDD, wait 30ms again mp_hal_pin_low(MICROPY_HW_MMA_AVDD_PIN); // turn off mp_hal_delay_ms(30); @@ -90,6 +119,27 @@ STATIC void accel_start(void) { // wait for MMA to become active mp_hal_delay_ms(30); + + #elif MICROPY_HW_HAS_KXTJ3 + + // readout WHO_AM_I register to check KXTJ3 device presence + uint8_t data[2] = { ACCEL_REG_WHO_AM_I }; + i2c_writeto(I2C1, ACCEL_ADDR, data, 1, false); + i2c_readfrom(I2C1, ACCEL_ADDR, data, 1, true); + if (data[0] != 0x35) { + mp_raise_msg(&mp_type_OSError, "accelerometer not found"); + } + + // set operating mode (default: 8 bits, range +/-8G) + data[0] = ACCEL_REG_CTRL_REG1; + data[1] = 0x90; + i2c_writeto(I2C1, ACCEL_ADDR, data, 2, true); + // set dat output rates to 200Hz (LPF roll-over 10ms), idd=35uA + data[0] = ACCEL_REG_DATA_CTRL_REG; + data[1] = 0x04; + i2c_writeto(I2C1, ACCEL_ADDR, data, 2, true); + + #endif } /******************************************************************************/ @@ -158,10 +208,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_accel_z_obj, pyb_accel_z); /// \method tilt() /// Get the tilt register. STATIC mp_obj_t pyb_accel_tilt(mp_obj_t self_in) { + #if MICROPY_HW_HAS_MMA7660 uint8_t data[1] = { ACCEL_REG_TILT }; i2c_writeto(I2C1, ACCEL_ADDR, data, 1, false); i2c_readfrom(I2C1, ACCEL_ADDR, data, 1, true); return mp_obj_new_int(data[0]); + #elif MICROPY_HW_HAS_KXTJ3 + /// No tilt like register with KXTJ3 accelerometer + return 0; + #endif } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_accel_tilt_obj, pyb_accel_tilt); @@ -172,13 +227,20 @@ STATIC mp_obj_t pyb_accel_filtered_xyz(mp_obj_t self_in) { memmove(self->buf, self->buf + NUM_AXIS, NUM_AXIS * (FILT_DEPTH - 1) * sizeof(int16_t)); - uint8_t data[NUM_AXIS] = { ACCEL_REG_X }; + #if MICROPY_HW_HAS_MMA7660 + const size_t DATA_SIZE = NUM_AXIS; + const size_t DATA_STRIDE = 1; + #elif MICROPY_HW_HAS_KXTJ3 + const size_t DATA_SIZE = 5; + const size_t DATA_STRIDE = 2; + #endif + uint8_t data[DATA_SIZE]; data[0] = ACCEL_REG_X; i2c_writeto(I2C1, ACCEL_ADDR, data, 1, false); - i2c_readfrom(I2C1, ACCEL_ADDR, data, 3, true); + i2c_readfrom(I2C1, ACCEL_ADDR, data, DATA_SIZE, true); mp_obj_t tuple[NUM_AXIS]; for (int i = 0; i < NUM_AXIS; i++) { - self->buf[NUM_AXIS * (FILT_DEPTH - 1) + i] = ACCEL_AXIS_SIGNED_VALUE(data[i]); + self->buf[NUM_AXIS * (FILT_DEPTH - 1) + i] = ACCEL_AXIS_SIGNED_VALUE(data[i * DATA_STRIDE]); int32_t val = 0; for (int j = 0; j < FILT_DEPTH; j++) { val += self->buf[i + NUM_AXIS * j]; @@ -225,4 +287,4 @@ const mp_obj_type_t pyb_accel_type = { .locals_dict = (mp_obj_dict_t*)&pyb_accel_locals_dict, }; -#endif // MICROPY_HW_HAS_MMA7660 +#endif // MICROPY_HW_HAS_MMA7660 || MICROPY_HW_HAS_KXTJ3 diff --git a/ports/stm32/modpyb.c b/ports/stm32/modpyb.c index 1a1f567a5..71d784923 100644 --- a/ports/stm32/modpyb.c +++ b/ports/stm32/modpyb.c @@ -248,7 +248,7 @@ STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pyb_dac_type) }, #endif -#if MICROPY_HW_HAS_MMA7660 +#if MICROPY_HW_HAS_MMA7660 || MICROPY_HW_HAS_KXTJ3 { MP_ROM_QSTR(MP_QSTR_Accel), MP_ROM_PTR(&pyb_accel_type) }, #endif