From f78d9b1a721bbe56b9049f33a8ec610f811011e5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 20 Mar 2014 23:33:30 +0000 Subject: [PATCH] stmhal: Add accelerometer driver; fix bug with LFN. --- stmhal/Makefile | 3 +- stmhal/accel.c | 137 +++++++++++++++++++++++++++++++++++++++++++++ stmhal/accel.h | 11 ++++ stmhal/import.c | 9 +-- stmhal/led.c | 8 +++ stmhal/led.h | 1 + stmhal/main.c | 37 ++++-------- stmhal/pybmodule.c | 8 +-- 8 files changed, 179 insertions(+), 35 deletions(-) create mode 100644 stmhal/accel.c create mode 100644 stmhal/accel.h diff --git a/stmhal/Makefile b/stmhal/Makefile index 9f3e365a19..a1a5a1db68 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -84,9 +84,9 @@ SRC_C = \ sdcard.c \ diskio.c \ lcd.c \ + accel.c \ # servo.c \ -# accel.c \ # timer.c \ # audio.c \ # i2c.c \ @@ -104,6 +104,7 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\ stm32f4xx_hal_flash.c \ stm32f4xx_hal_flash_ex.c \ stm32f4xx_hal_gpio.c \ + stm32f4xx_hal_i2c.c \ stm32f4xx_hal_pcd.c \ stm32f4xx_hal_rcc.c \ stm32f4xx_hal_rcc_ex.c \ diff --git a/stmhal/accel.c b/stmhal/accel.c new file mode 100644 index 0000000000..f380242bf6 --- /dev/null +++ b/stmhal/accel.c @@ -0,0 +1,137 @@ +#include +#include + +#include + +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "runtime.h" +#include "accel.h" + +#define MMA_ADDR (0x98) +#define MMA_REG_MODE (7) + +STATIC I2C_HandleTypeDef I2cHandle; + +void accel_init(void) { + GPIO_InitTypeDef GPIO_InitStructure; + + // PB5 is connected to AVDD; pull high to enable MMA accel device + GPIOB->BSRRH = GPIO_PIN_5; // turn off AVDD + GPIO_InitStructure.Pin = GPIO_PIN_5; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Speed = GPIO_SPEED_LOW; + GPIO_InitStructure.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + + // wait 20ms, then turn on AVDD, then wait 20ms again + HAL_Delay(20); + GPIOB->BSRRL = GPIO_PIN_5; + HAL_Delay(20); + + // PB6=SCL, PB7=SDA + GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; + GPIO_InitStructure.Speed = GPIO_SPEED_FAST; + GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines + GPIO_InitStructure.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + + // enable the I2C1 clock + __I2C1_CLK_ENABLE(); + + // set up the I2C1 device + memset(&I2cHandle, 0, sizeof(I2C_HandleTypeDef)); + I2cHandle.Instance = I2C1; + I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + I2cHandle.Init.ClockSpeed = 400000; + I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED; + I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_16_9; + I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED; + I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED; + I2cHandle.Init.OwnAddress1 = 0xfe; // unused + I2cHandle.Init.OwnAddress2 = 0xfe; // unused + + if (HAL_I2C_Init(&I2cHandle) != HAL_OK) { + // init error + printf("accel_init: HAL_I2C_Init failed\n"); + return; + } + + HAL_StatusTypeDef status; + + //printf("IsDeviceReady\n"); + for (int i = 0; i < 10; i++) { + status = HAL_I2C_IsDeviceReady(&I2cHandle, MMA_ADDR, 10, 200); + //printf(" got %d\n", status); + if (status == HAL_OK) { + break; + } + } + + //printf("MemWrite\n"); + uint8_t data[1]; + data[0] = 1; // active mode + status = HAL_I2C_Mem_Write(&I2cHandle, MMA_ADDR, MMA_REG_MODE, I2C_MEMADD_SIZE_8BIT, data, 1, 200); + //printf(" got %d\n", status); +} + +/******************************************************************************/ +/* Micro Python bindings */ + +int accel_buf[12]; + +mp_obj_t pyb_accel_read(void) { + for (int i = 0; i <= 6; i += 3) { + accel_buf[0 + i] = accel_buf[0 + i + 3]; + accel_buf[1 + i] = accel_buf[1 + i + 3]; + accel_buf[2 + i] = accel_buf[2 + i + 3]; + } + + uint8_t data_[4]; + HAL_I2C_Mem_Read(&I2cHandle, MMA_ADDR, 0, I2C_MEMADD_SIZE_8BIT, data_, 4, 200); + accel_buf[9] = data_[0] & 0x3f; if (accel_buf[9] & 0x20) accel_buf[9] |= ~0x1f; + accel_buf[10] = data_[1] & 0x3f; if (accel_buf[10] & 0x20) accel_buf[10] |= ~0x1f; + accel_buf[11] = data_[2] & 0x3f; if (accel_buf[11] & 0x20) accel_buf[11] |= ~0x1f; + int jolt_info = data_[3]; + + mp_obj_t data[4]; + data[0] = mp_obj_new_int(accel_buf[0] + accel_buf[3] + accel_buf[6] + accel_buf[9]); + data[1] = mp_obj_new_int(accel_buf[1] + accel_buf[4] + accel_buf[7] + accel_buf[10]); + data[2] = mp_obj_new_int(accel_buf[2] + accel_buf[5] + accel_buf[8] + accel_buf[11]); + data[3] = mp_obj_new_int(jolt_info); + + return rt_build_tuple(4, data); +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_accel_read_obj, pyb_accel_read); + +/* +mp_obj_t pyb_accel_read_all(void) { + mp_obj_t data[11]; + accel_start(MMA_ADDR, 1); + accel_send_byte(0); + accel_restart(MMA_ADDR, 0); + for (int i = 0; i <= 9; i++) { + data[i] = mp_obj_new_int(accel_read_ack()); + } + data[10] = mp_obj_new_int(accel_read_nack()); + + return rt_build_tuple(11, data); +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_accel_read_all_obj, pyb_accel_read_all); + +mp_obj_t pyb_accel_write_mode(mp_obj_t o_int, mp_obj_t o_mode) { + accel_start(MMA_ADDR, 1); + accel_send_byte(6); // start at int + accel_send_byte(mp_obj_get_int(o_int)); + accel_send_byte(mp_obj_get_int(o_mode)); + accel_stop(); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_2(pyb_accel_write_mode_obj, pyb_accel_write_mode); +*/ diff --git a/stmhal/accel.h b/stmhal/accel.h new file mode 100644 index 0000000000..c2320f1a4e --- /dev/null +++ b/stmhal/accel.h @@ -0,0 +1,11 @@ +void accel_init(void); +void accel_restart(uint8_t addr, int write); +void accel_start(uint8_t addr, int write); +void accel_send_byte(uint8_t data); +uint8_t accel_read_ack(void); +uint8_t accel_read_nack(void); +void accel_stop(void); + +MP_DECLARE_CONST_FUN_OBJ(pyb_accel_read_obj); +MP_DECLARE_CONST_FUN_OBJ(pyb_accel_read_all_obj); +MP_DECLARE_CONST_FUN_OBJ(pyb_accel_write_mode_obj); diff --git a/stmhal/import.c b/stmhal/import.c index f2fd3b3dee..c977dcf2ec 100644 --- a/stmhal/import.c +++ b/stmhal/import.c @@ -1,16 +1,18 @@ +#include #include #include "misc.h" #include "mpconfig.h" #include "qstr.h" #include "lexer.h" -#if 0 #include "ff.h" -#endif mp_import_stat_t mp_import_stat(const char *path) { -#if 0 FILINFO fno; +#if _USE_LFN + fno.lfname = NULL; + fno.lfsize = 0; +#endif FRESULT res = f_stat(path, &fno); if (res == FR_OK) { if ((fno.fattrib & AM_DIR) != 0) { @@ -19,6 +21,5 @@ mp_import_stat_t mp_import_stat(const char *path) { return MP_IMPORT_STAT_FILE; } } -#endif return MP_IMPORT_STAT_NO_EXIST; } diff --git a/stmhal/led.c b/stmhal/led.c index 677c151b33..80c1e145f1 100644 --- a/stmhal/led.c +++ b/stmhal/led.c @@ -73,6 +73,14 @@ void led_toggle(pyb_led_t led) { } } +void led_debug(int n, int delay) { + led_state(1, n & 1); + led_state(2, n & 2); + led_state(3, n & 4); + led_state(4, n & 8); + HAL_Delay(delay); +} + /******************************************************************************/ /* Micro Python bindings */ diff --git a/stmhal/led.h b/stmhal/led.h index 44c68d4ebe..b3762271c1 100644 --- a/stmhal/led.h +++ b/stmhal/led.h @@ -19,5 +19,6 @@ typedef enum { void led_init(void); void led_state(pyb_led_t led, int state); void led_toggle(pyb_led_t led); +void led_debug(int value, int delay); MP_DECLARE_CONST_FUN_OBJ(pyb_Led_obj); diff --git a/stmhal/main.c b/stmhal/main.c index d77733429b..522ebfa6b1 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -33,9 +33,9 @@ #include "sdcard.h" #include "ff.h" #include "lcd.h" +#include "accel.h" #if 0 #include "servo.h" -#include "accel.h" #include "timer.h" #include "pybwlan.h" #include "pin.h" @@ -170,22 +170,6 @@ int main(void) { // enable the CCM RAM __CCMDATARAMEN_CLK_ENABLE(); - // some test code to flash LEDs - led_init(); - - led_state(0, 1); - led_state(1, 0); - led_state(2, 1); - -#if 0 - for (;;) { - HAL_Delay(500); - led_state(1, 1); - HAL_Delay(500); - led_state(1, 0); - } -#endif - #if 0 #if defined(NETDUINO_PLUS_2) { @@ -348,6 +332,11 @@ soft_reset: // make sure we have a /boot.py { FILINFO fno; +#if _USE_LFN + fno.lfname = NULL; + fno.lfsize = 0; +#endif + led_debug(0, 500); FRESULT res = f_stat("0:/boot.py", &fno); if (res == FR_OK) { if (fno.fattrib & AM_DIR) { @@ -382,15 +371,6 @@ soft_reset: flash_error(4); } - if (first_soft_reset) { -#if 0 -#if MICROPY_HW_HAS_MMA7660 - // MMA accel: init and reset address to zero - accel_init(); -#endif -#endif - } - // turn boot-up LED off led_state(PYB_LED_GREEN, 0); @@ -419,6 +399,11 @@ soft_reset: pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC); #endif +#if MICROPY_HW_HAS_MMA7660 + // MMA accel: init and reset + accel_init(); +#endif + // run main script { vstr_t *vstr = vstr_new(); diff --git a/stmhal/pybmodule.c b/stmhal/pybmodule.c index b6b269b065..3db23dc6de 100644 --- a/stmhal/pybmodule.c +++ b/stmhal/pybmodule.c @@ -21,10 +21,10 @@ #include "usart.h" #include "storage.h" #include "sdcard.h" +#include "accel.h" #if 0 #include "servo.h" #include "usb.h" -#include "accel.h" #include "i2c.h" #include "adc.h" #include "audio.h" @@ -256,13 +256,13 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sdcard_obj }, #endif -#if 0 #if MICROPY_HW_HAS_MMA7660 { MP_OBJ_NEW_QSTR(MP_QSTR_accel), (mp_obj_t)&pyb_accel_read_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_accel_read), (mp_obj_t)&pyb_accel_read_all_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_accel_mode), (mp_obj_t)&pyb_accel_write_mode_obj }, + //{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_read), (mp_obj_t)&pyb_accel_read_all_obj }, + //{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_mode), (mp_obj_t)&pyb_accel_write_mode_obj }, #endif +#if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj }, #endif { MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_Led_obj },