diff --git a/include/ADXL345_accel.h b/include/ADXL345_accel.h new file mode 100644 index 0000000000000000000000000000000000000000..f2e2ebcf40b7b8a2d06db8bafed3447f219e800a --- /dev/null +++ b/include/ADXL345_accel.h @@ -0,0 +1,15 @@ +#ifndef ADXL345_ACCEL_H +#define ADXL345_ACCEL_H + +#include "stm32f4xx.h" + +// public functions +void imu_accel_get_config(void); +void imu_accel_start(void); +void imu_accel_stop(void); +void imu_accel_get_data(void); +void imu_accel_set_config(void); +uint8_t imu_accel_detect(void); +void imu_accel_process_data(void); + +#endif diff --git a/include/HMC5843_compass.h b/include/HMC5843_compass.h new file mode 100644 index 0000000000000000000000000000000000000000..eac9ddab5bad5c68687fe636c6849ca9821b8da2 --- /dev/null +++ b/include/HMC5843_compass.h @@ -0,0 +1,15 @@ +#ifndef _HMC5843_compass_h +#define _HMC5843_compass_h + +#include "stm32f4xx.h" + +uint8_t imu_compass_detect(void); +void imu_compass_get_config(void); +void imu_compass_start(void); +void imu_compass_stop(void); +void imu_compass_get_data(void); +void imu_compass_set_config(void); +void imu_compass_process_data(void); + + +#endif diff --git a/include/ITG3200_gyro.h b/include/ITG3200_gyro.h new file mode 100644 index 0000000000000000000000000000000000000000..f2efc4c83c57a110346374a9d6cab61a758a483f --- /dev/null +++ b/include/ITG3200_gyro.h @@ -0,0 +1,15 @@ +#ifndef _ITG3200_GYRO_H +#define _ITG3200_GYRO_H + +#include "stm32f4xx.h" + +// public functions +uint8_t imu_gyro_detect(void); +void imu_gyro_get_config(void); +void imu_gyro_start(void); +void imu_gyro_stop(void); +void imu_gyro_get_data(void); +void imu_gyro_set_config(void); +void imu_gyro_process_data(void); + +#endif diff --git a/include/imu_9dof_dma.h b/include/imu_9dof_dma.h index 8163d5341d33605b433b0cf5c608e8ac3fbff6fc..41db3c0d74587c695e0ae1e224e3718172f5aecc 100644 --- a/include/imu_9dof_dma.h +++ b/include/imu_9dof_dma.h @@ -3,49 +3,9 @@ #include "stm32f4xx.h" -// accelerometer configuration data -#define ACCEL_RATE_3200HZ 0x0F -#define ACCEL_RATE_1600HZ 0x0E -#define ACCEL_RATE_800HZ 0x0D -#define ACCEL_RATE_400HZ 0x0C -#define ACCEL_RATE_200HZ 0x0B -#define ACCEL_RATE_100HZ 0x0A -#define ACCEL_RATE_50HZ 0x09 -#define ACCEL_RATE_25HZ 0x08 -#define ACCEL_RATE_12_5HZ 0x07 -#define ACCEL_RATE_6_25HZ 0x06 - -#define ACCEL_ENABLE_LINK 0x20 -#define ACCEL_ENABLE_AUTOSLEEP 0x10 -#define ACCEL_ENABLE_MEASURE 0x08 -#define ACCEL_ENABLE_SLEEP 0x04 -#define ACCEL_SLEEP_8HZ 0x00 -#define ACCEL_SLEEP_4HZ 0x01 -#define ACCEL_SLEEP_2HZ 0x02 -#define ACCEL_SLEEP_1HZ 0x03 - -#define ACCEL_ENABLE_FULL_RES 0x08 -#define ACCEL_JUSTIFY_LEFT 0x04 -#define ACCEL_JUSTIFY_RIGHT 0x00 -#define ACCEL_RANGE_2G 0x00 -#define ACCEL_RANGE_4G 0x01 -#define ACCEL_RANGE_8G 0x02 -#define ACCEL_RANGE_16G 0x03 - -#define ACCEL_FIFO_BYPASS 0x00 -#define ACCEL_FIFO_BUFFER 0x40 -#define ACCEL_FIFO_STREAM 0x80 -#define ACCEL_FIFO_TRIGGER 0xC0 - // general IMU public functions void imu_init(void); void imu_start(void); void imu_stop(void); -// gyroscope public functions -uint8_t imu_gyro_detect(void); - -// compass public functions -uint8_t imu_compass_detect(void); - #endif diff --git a/include/imu_int.h b/include/imu_int.h new file mode 100644 index 0000000000000000000000000000000000000000..9dc552e2a819ea55f78399fb0242d2db4f632fdd --- /dev/null +++ b/include/imu_int.h @@ -0,0 +1,67 @@ +#ifndef _IMU_INT_H +#define _IMU_INT_H + +#define I2C_IMU_DMA DMA1 +#define I2C_IMU_DMA_CHANNEL DMA_Channel_3 +#define I2C_IMU_DR_ADDRESS ((uint32_t)I2C3+0x10) +#define I2C_IMU_DMA_STREAM_TX DMA1_Stream4 +#define I2C_IMU_DMA_STREAM_RX DMA1_Stream2 +#define I2C_IMU_TX_DMA_TCFLAG DMA_FLAG_TCIF4 +#define I2C_IMU_TX_DMA_FEIFLAG DMA_FLAG_FEIF4 +#define I2C_IMU_TX_DMA_DMEIFLAG DMA_FLAG_DMEIF4 +#define I2C_IMU_TX_DMA_TEIFLAG DMA_FLAG_TEIF4 +#define I2C_IMU_TX_DMA_HTIFLAG DMA_FLAG_HTIF4 +#define I2C_IMU_RX_DMA_TCFLAG DMA_FLAG_TCIF2 +#define I2C_IMU_RX_DMA_FEIFLAG DMA_FLAG_FEIF2 +#define I2C_IMU_RX_DMA_DMEIFLAG DMA_FLAG_DMEIF2 +#define I2C_IMU_RX_DMA_TEIFLAG DMA_FLAG_TEIF2 +#define I2C_IMU_RX_DMA_HTIFLAG DMA_FLAG_HTIF2 +#define DMA_IMU_CLK RCC_AHB1Periph_DMA1 + +#define I2C_IMU_TX_DMA_IRQn DMA1_Stream4_IRQn +#define I2C_IMU_RX_DMA_IRQn DMA1_Stream2_IRQn +#define I2C_IMU_TX_DMA_IRQHandler DMA1_Stream4_IRQHandler +#define I2C_IMU_RX_DMA_IRQHandler DMA1_Stream2_IRQHandler + +#define I2C_IMU I2C3 +#define I2C_IMU_CLK RCC_APB1Periph_I2C3 +#define I2C_IMU_SDA_GPIO_CLK RCC_AHB1Periph_GPIOC +#define I2C_IMU_SDA_PIN GPIO_Pin_9 +#define I2C_IMU_SDA_GPIO_PORT GPIOC +#define I2C_IMU_SDA_SOURCE GPIO_PinSource9 +#define I2C_IMU_SDA_AF GPIO_AF_I2C3 + +#define I2C_IMU_SCL_GPIO_CLK RCC_AHB1Periph_GPIOA +#define I2C_IMU_SCL_PIN GPIO_Pin_8 +#define I2C_IMU_SCL_GPIO_PORT GPIOA +#define I2C_IMU_SCL_SOURCE GPIO_PinSource8 +#define I2C_IMU_SCL_AF GPIO_AF_I2C3 + +#define I2C_IMU_EV_IRQn I2C3_EV_IRQn +#define I2C_IMU_ER_IRQn I2C3_ER_IRQn +#define I2C_IMU_EV_IRQHandler I2C3_EV_IRQHandler +#define I2C_IMU_ER_IRQHandler I2C3_ER_IRQHandler + +#define IMU_TIMER TIM4 +#define IMU_TIMER_IRQn TIM4_IRQn +#define IMU_TIMER_IRQHandler TIM4_IRQHandler +#define IMU_TIMER_CLK RCC_APB1Periph_TIM4 + +typedef enum {I2C_OP_DONE,I2C_WR_OP,I2C_RD_OP_CMD,I2C_RD_OP_DATA} i2c_op_t; +typedef enum {IMU_GET_ACCEL,IMU_GET_GYRO,IMU_GET_COMPASS} imu_state_t; + +// I2C private variables +extern volatile uint8_t i2c_error; +extern volatile i2c_op_t i2c_op; +extern uint8_t i2c_rd_addr; +extern uint8_t i2c_wr_addr; +extern uint8_t i2c_data_out[32]; +// dma initialization structures; +extern DMA_InitTypeDef IMU_DMA_TX_InitStructure; +extern DMA_InitTypeDef IMU_DMA_RX_InitStructure; + +// private functions +void imu_wait_op_done(void); +uint8_t imu_is_op_done(void); + +#endif diff --git a/include/ram.h b/include/ram.h index d9378534607db8f8b1d861a65a4822f0e6199b3b..5705338913943b95afa0279dddc9ca9a74fbcd5b 100644 --- a/include/ram.h +++ b/include/ram.h @@ -123,9 +123,10 @@ typedef enum { BIOLOID_IMU_COMPASS_Y_H = 0x7D, BIOLOID_IMU_COMPASS_Z_L = 0x7E, BIOLOID_IMU_COMPASS_Z_H = 0x7F, - BIOLOID_ACTION_PAGE = 0x80, - BIOLOID_ACTION_CONTROL = 0x81, - BIOLOID_ACTION_SATUTUS = 0x82 + BIOLOID_IMU_TEMP = 0x80, + BIOLOID_ACTION_PAGE = 0x81, + BIOLOID_ACTION_CONTROL = 0x82, + BIOLOID_ACTION_SATUTUS = 0x83 } bioloid_registers; #define RAM_SIZE 256 diff --git a/src/ADXL345_accel.c b/src/ADXL345_accel.c new file mode 100644 index 0000000000000000000000000000000000000000..1251cb34ddc635a46a4ddf88976b078338de7af2 --- /dev/null +++ b/src/ADXL345_accel.c @@ -0,0 +1,220 @@ +#include "ADXL345_accel.h" +#include "imu_int.h" +#include "ram.h" + +// accelerometer registers +#define ACCEL_THRESH_TAP 0x1D +#define ACCEL_OFSX 0x1E +#define ACCEL_OFSY 0x1F +#define ACCEL_OFSZ 0x20 +#define ACCEL_DUR 0x21 +#define ACCEL_LATENT 0x22 +#define ACCEL_WINDOW 0x23 +#define ACCEL_THRESH_ACT 0x24 +#define ACCEL_THRESH_INACT 0x25 +#define ACCEL_TIME_INACT 0x26 +#define ACCEL_ACT_INACT_CTL 0x27 +#define ACCEL_THRESH_FF 0x28 +#define ACCEL_TIME_FF 0x29 +#define ACCEL_TAP_AXES 0x2A +#define ACCEL_ACT_TAP_STATUS 0x2B +#define ACCEL_BW_RATE 0x2C +#define ACCEL_POWER_CTL 0x2D +#define ACCEL_INT_ENABLE 0x2E +#define ACCEL_INT_MAP 0x2F +#define ACCEL_INT_SOURCE 0x30 +#define ACCEL_DATA_FORMAT 0x31 + +// accelerometer configuration data +#define ACCEL_RATE_3200HZ 0x0F +#define ACCEL_RATE_1600HZ 0x0E +#define ACCEL_RATE_800HZ 0x0D +#define ACCEL_RATE_400HZ 0x0C +#define ACCEL_RATE_200HZ 0x0B +#define ACCEL_RATE_100HZ 0x0A +#define ACCEL_RATE_50HZ 0x09 +#define ACCEL_RATE_25HZ 0x08 +#define ACCEL_RATE_12_5HZ 0x07 +#define ACCEL_RATE_6_25HZ 0x06 + +#define ACCEL_ENABLE_LINK 0x20 +#define ACCEL_ENABLE_AUTOSLEEP 0x10 +#define ACCEL_ENABLE_MEASURE 0x08 +#define ACCEL_ENABLE_SLEEP 0x04 +#define ACCEL_SLEEP_8HZ 0x00 +#define ACCEL_SLEEP_4HZ 0x01 +#define ACCEL_SLEEP_2HZ 0x02 +#define ACCEL_SLEEP_1HZ 0x03 + +#define ACCEL_ENABLE_FULL_RES 0x08 +#define ACCEL_JUSTIFY_LEFT 0x04 +#define ACCEL_JUSTIFY_RIGHT 0x00 +#define ACCEL_RANGE_2G 0x00 +#define ACCEL_RANGE_4G 0x01 +#define ACCEL_RANGE_8G 0x02 +#define ACCEL_RANGE_16G 0x03 + +#define ACCEL_FIFO_BYPASS 0x00 +#define ACCEL_FIFO_BUFFER 0x40 +#define ACCEL_FIFO_STREAM 0x80 +#define ACCEL_FIFO_TRIGGER 0xC0 + +// private variables +// accelerometer data and configuration +const uint8_t accel_id_reg=0x00; +const uint8_t accel_id=0xE5; +const uint8_t accel_id_len=0x01; +const uint8_t accel_conf_reg=0x1D; +const uint8_t accel_conf_len=0x15; +const uint8_t accel_data_reg=0x32; +const uint8_t accel_data_len=0x06; +const uint8_t accel_fifo_reg=0x38; +const uint8_t accel_fifo_len=0x01; +const uint8_t accel_status_reg=0x39; +const uint8_t accel_status_len=0x01; +const uint8_t accel_rd_addr=0xA6; +const uint8_t accel_wr_addr=0xA7; +uint8_t i2c_accel_conf[21]; +uint8_t i2c_accel_fifo_conf; +uint8_t i2c_accel_data[6]; +uint8_t i2c_accel_status; + +// public accelerometer functions +void imu_accel_get_config(void) +{ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=accel_conf_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_accel_conf; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&accel_conf_reg; + + i2c_rd_addr=accel_rd_addr; + i2c_wr_addr=accel_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_accel_start(void) +{ + // enter measure mode + i2c_accel_conf[ACCEL_POWER_CTL-ACCEL_THRESH_TAP]|=ACCEL_ENABLE_MEASURE; + i2c_data_out[0]=ACCEL_POWER_CTL; + i2c_data_out[1]=i2c_accel_conf[ACCEL_POWER_CTL-ACCEL_THRESH_TAP]; + // write the fifo configuration + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=2; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=accel_rd_addr; + i2c_wr_addr=accel_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_accel_stop(void) +{ + // enter measure mode + i2c_accel_conf[ACCEL_POWER_CTL-ACCEL_THRESH_TAP]&=~ACCEL_ENABLE_MEASURE; + i2c_data_out[0]=ACCEL_POWER_CTL; + i2c_data_out[1]=i2c_accel_conf[ACCEL_POWER_CTL-ACCEL_THRESH_TAP]; + // write the fifo configuration + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=2; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=accel_rd_addr; + i2c_wr_addr=accel_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_accel_get_data(void) +{ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=accel_data_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_accel_data; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&accel_data_reg; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=accel_rd_addr; + i2c_wr_addr=accel_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); +} + +void imu_accel_set_config(void) +{ + uint8_t i; + + // set the configuration + i2c_accel_conf[ACCEL_BW_RATE-ACCEL_THRESH_TAP]|=ACCEL_RATE_100HZ; + i2c_accel_conf[ACCEL_DATA_FORMAT-ACCEL_THRESH_TAP]&=0xF0; + i2c_accel_conf[ACCEL_DATA_FORMAT-ACCEL_THRESH_TAP]|=ACCEL_RANGE_8G;// +/-8g range + i2c_accel_conf[ACCEL_DATA_FORMAT-ACCEL_THRESH_TAP]|=ACCEL_JUSTIFY_RIGHT;// justify right + i2c_accel_conf[ACCEL_DATA_FORMAT-ACCEL_THRESH_TAP]|=ACCEL_ENABLE_FULL_RES;// enable full resolution according to the range + // write the configuration + for(i=0;i<accel_conf_len;i++) + i2c_data_out[i+1]=i2c_accel_conf[i]; + i2c_data_out[0]=accel_conf_reg; + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=accel_conf_len+1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=accel_rd_addr; + i2c_wr_addr=accel_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); + + // set the fifo configuration + i2c_accel_fifo_conf=ACCEL_FIFO_STREAM; + i2c_data_out[0]=accel_fifo_reg; + i2c_data_out[1]=i2c_accel_fifo_conf; + // write the fifo configuration + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=accel_fifo_len+1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=accel_rd_addr; + i2c_wr_addr=accel_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +uint8_t imu_accel_detect(void) +{ + i2c_accel_data[0]=0x00; + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=accel_id_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_accel_data; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&accel_id_reg; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=accel_rd_addr; + i2c_wr_addr=accel_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); + if(i2c_accel_data[0]==accel_id) + { + imu_accel_get_config(); + imu_accel_set_config(); + return 0x01; + } + else + return 0x00; +} + +void imu_accel_process_data(void) +{ + uint8_t i; + int16_t value; + + for(i=0;i<3;i++) + { + value=((int16_t)(i2c_accel_data[i*2]+(i2c_accel_data[i*2+1]<<8)))<<2; + ram_data[BIOLOID_IMU_ACCEL_X_L+i*2]=value&0xFF; + ram_data[BIOLOID_IMU_ACCEL_X_H+i*2]=(value>>8); + } +} + diff --git a/src/HMC5843_compass.c b/src/HMC5843_compass.c new file mode 100644 index 0000000000000000000000000000000000000000..da5b65fec74851b58e62bd8fa847df0ee61b324b --- /dev/null +++ b/src/HMC5843_compass.c @@ -0,0 +1,181 @@ +#include "HMC5843_compass.h" +#include "imu_int.h" +#include "ram.h" + +// compass registers +#define COMPASS_CONF_A 0x00 +#define COMPASS_CONF_B 0x01 +#define COMPASS_MODE 0x02 +#define COMPASS_STATUS 0x09 +#define COMPASS_IDA 0x0A +#define COMPASS_IDB 0x0B +#define COMPASS_IDC 0x0C + +// configuration values +#define COMPASS_DATA_RATE_0_5 0x00 +#define COMPASS_DATA_RATE_1 0x04 +#define COMPASS_DATA_RATE_2 0x08 +#define COMPASS_DATA_RATE_5 0x0C +#define COMPASS_DATA_RATE_10 0x10 +#define COMPASS_DATA_RATE_20 0x14 +#define COMPASS_DATA_RATE_50 0x18 + +#define COMPASS_NO_BIAS 0x00 +#define COMPASS_POS_BIAS 0x01 +#define COMPASS_NEG_BIAS 0x02 + +#define COMPASS_FS_0_7 0x00 +#define COMPASS_FS_1 0x20 +#define COMPASS_FS_1_5 0x40 +#define COMPASS_FS_2 0x60 +#define COMPASS_FS_3_2 0x80 +#define COMPASS_FS_3_8 0xA0 +#define COMPASS_FS_4_5 0xC0 +#define COMPASS_FS_6_5 0xE0 + +#define COMPASS_CONT_MODE 0x00 +#define COMPASS_SINGLE_MODE 0x01 +#define COMPASS_IDLE_MODE 0x02 +#define COMPASS_SLEEP_MODE 0x03 + +// compass data adn configuration +const uint8_t compass_id_reg=0x0A; +const uint8_t compass_id[3]={'H','4','3'}; +const uint8_t compass_id_len=0x03; +const uint8_t compass_conf_reg=0x00; +const uint8_t compass_conf_len=0x03; +const uint8_t compass_data_reg=0x03; +const uint8_t compass_data_len=0x06; +const uint8_t compass_status_reg=0x09; +const uint8_t compass_status_len=0x01; +const uint8_t compass_rd_addr=0x3D; +const uint8_t compass_wr_addr=0x3C; +uint8_t i2c_compass_conf[3]; +uint8_t i2c_compass_data[6]; + +// compass public functions +uint8_t imu_compass_detect(void) +{ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=compass_id_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_compass_data; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&compass_id_reg; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_compass_data[0]=0x00; + i2c_compass_data[1]=0x00; + i2c_compass_data[2]=0x00; + i2c_rd_addr=compass_rd_addr; + i2c_wr_addr=compass_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + + imu_wait_op_done(); + if(i2c_compass_data[0]==compass_id[0] && i2c_compass_data[1]==compass_id[1] && i2c_compass_data[2]==compass_id[2]) + { + imu_compass_get_config(); + imu_compass_set_config(); + return 0x01; + } + else + return 0x00; +} + +void imu_compass_get_config(void) +{ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=compass_conf_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_compass_conf; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&compass_conf_reg; + i2c_rd_addr=compass_rd_addr; + i2c_wr_addr=compass_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_compass_start(void) +{ + // enter measure mode + i2c_compass_conf[COMPASS_MODE-COMPASS_CONF_A]=COMPASS_CONT_MODE; + i2c_data_out[0]=COMPASS_MODE; + i2c_data_out[1]=i2c_compass_conf[COMPASS_MODE-COMPASS_CONF_A]; + // write the fifo configuration + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=2; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=compass_rd_addr; + i2c_wr_addr=compass_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_compass_stop(void) +{ + // enter measure mode + i2c_compass_conf[COMPASS_MODE-COMPASS_CONF_A]=COMPASS_SLEEP_MODE; + i2c_data_out[0]=COMPASS_MODE; + i2c_data_out[1]=i2c_compass_conf[COMPASS_MODE-COMPASS_CONF_A]; + // write the fifo configuration + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=2; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=compass_rd_addr; + i2c_wr_addr=compass_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_compass_get_data(void) +{ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=compass_data_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_compass_data; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&compass_data_reg; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=compass_rd_addr; + i2c_wr_addr=compass_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); +} + +void imu_compass_set_config(void) +{ + uint8_t i; + + // set the configuration + i2c_compass_conf[COMPASS_CONF_A-COMPASS_CONF_A]=COMPASS_DATA_RATE_50 | COMPASS_NO_BIAS; + i2c_compass_conf[COMPASS_CONF_B-COMPASS_CONF_A]=COMPASS_FS_1; + i2c_compass_conf[COMPASS_MODE-COMPASS_CONF_A]=COMPASS_SLEEP_MODE; + // write the configuration + for(i=0;i<compass_conf_len;i++) + i2c_data_out[i+1]=i2c_compass_conf[i]; + i2c_data_out[0]=compass_conf_reg; + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=compass_conf_len+1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=compass_rd_addr; + i2c_wr_addr=compass_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_compass_process_data(void) +{ + uint8_t i; + int16_t value; + + for(i=0;i<3;i++) + { + value=(((int16_t)(i2c_compass_data[i*2]+(i2c_compass_data[i*2+1]<<8)))<<4)/1300; + ram_data[BIOLOID_IMU_COMPASS_X_L+i*2]=value&0xFF; + ram_data[BIOLOID_IMU_COMPASS_X_H+i*2]=(value>>8); + } +} + + diff --git a/src/ITG3200_gyro.c b/src/ITG3200_gyro.c new file mode 100644 index 0000000000000000000000000000000000000000..241c3ae6f291d6a46fb92e140fd565b485fb45dd --- /dev/null +++ b/src/ITG3200_gyro.c @@ -0,0 +1,219 @@ +#include "ITG3200_gyro.h" +#include "imu_int.h" +#include "ram.h" + +// gyroscope registers +#define GYRO_SMPL_DIV 0x15 +#define GYRO_CONFIG 0x16 +#define GYRO_INT_CONFIG 0x17 +#define GYRO_STATUS 0x1A +#define GYRO_POWER_MGM 0x3E + +// configuration data +#define GYRO_FS_2000 0x18 +#define GYRO_BW_256 0x00 +#define GYRO_BW_188 0x01 +#define GYRO_BW_98 0x02 +#define GYRO_BW_42 0x03 +#define GYRO_BW_20 0x04 +#define GYRO_BW_10 0x05 +#define GYRO_BW_5 0x06 + +#define GYRO_INT_ACTIVE_LOW 0x80 +#define GYRO_INT_ACTIVE_HIGH 0x00 +#define GYRO_INT_OPEN_DRAIN 0x40 +#define GYRO_INT_PUSH_PULL 0x00 +#define GYRO_INT_LATCH 0x20 +#define GYRO_INT_PULSE 0x00 +#define GYRO_INT_CLEAR_RD_ANY 0x10 +#define GYRO_INT_CLEAR_RD_STATUS 0x00 +#define GYRO_INT_DEVICE_READY 0x04 +#define GYRO_INT_DATA_READY 0x01 + +#define GYRO_INT_DEVICE_READY_FLAG 0x04 +#define GYRO_INT_DATA_READY_FLAG 0x01 + +#define GYRO_RESET 0x80 +#define GYRO_SLEEP_MODE 0x40 +#define GYRO_STBY_X 0x20 +#define GYRO_STBY_Y 0x10 +#define GYRO_STBY_Z 0x08 +#define GYRO_CLK_INT 0x00 +#define GYRO_CLK_PLL_X 0x01 +#define GYRO_CLK_PLL_Y 0x02 +#define GYRO_CLK_PLL_Z 0x03 +#define GYRO_CLK_PLL_32768 0x04 +#define GYRO_CLK_PLL_19_2M 0x05 + +// gyroscope data and configuration +const uint8_t gyro_id_reg=0x00; +const uint8_t gyro_id=0x68; +const uint8_t gyro_id_len=0x01; +const uint8_t gyro_conf_reg=0x15; +const uint8_t gyro_conf_len=0x03; +const uint8_t gyro_status_reg=0x1A; +const uint8_t gyro_status_len=0x01; +const uint8_t gyro_data_reg=0x1B; +const uint8_t gyro_data_len=0x08; +const uint8_t gyro_power_reg=0x3E; +const uint8_t gyro_power_len=0x01; +const uint8_t gyro_rd_addr=0xD0; +const uint8_t gyro_wr_addr=0xD1; +uint8_t i2c_gyro_conf[3]; +uint8_t i2c_gyro_data[8]; +uint8_t i2c_gyro_power_mgm; +uint8_t i2c_gyro_status; + +// gyroscope private functions +uint8_t imu_gyro_detect(void) +{ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=gyro_id_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_gyro_data; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&gyro_id_reg; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_gyro_data[0]=0x00; + i2c_rd_addr=gyro_rd_addr; + i2c_wr_addr=gyro_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + + imu_wait_op_done(); + if((i2c_gyro_data[0]&0x7E)==gyro_id) + { + imu_gyro_get_config(); + imu_gyro_set_config(); + return 0x01; + } + else + return 0x00; +} + +void imu_gyro_get_config(void) +{ + /* read the configuration */ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=gyro_conf_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_gyro_conf; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&gyro_conf_reg; + i2c_rd_addr=gyro_rd_addr; + i2c_wr_addr=gyro_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); + + /* read trhe power management */ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=gyro_power_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_gyro_power_mgm; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&gyro_power_reg; + i2c_rd_addr=gyro_rd_addr; + i2c_wr_addr=gyro_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_gyro_start(void) +{ + // enter measure mode + i2c_gyro_power_mgm&=~(GYRO_SLEEP_MODE | GYRO_STBY_X | GYRO_STBY_Y | GYRO_STBY_Z); + i2c_data_out[0]=GYRO_POWER_MGM; + i2c_data_out[1]=i2c_gyro_power_mgm; + // write the fifo configuration + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=2; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=gyro_rd_addr; + i2c_wr_addr=gyro_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_gyro_stop(void) +{ + // enter measure mode + i2c_gyro_power_mgm|=(GYRO_SLEEP_MODE | GYRO_STBY_X | GYRO_STBY_Y | GYRO_STBY_Z); + i2c_data_out[0]=GYRO_POWER_MGM; + i2c_data_out[1]=i2c_gyro_power_mgm; + // write the fifo configuration + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=2; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=gyro_rd_addr; + i2c_wr_addr=gyro_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_gyro_get_data(void) +{ + i2c_op=I2C_RD_OP_CMD; + IMU_DMA_RX_InitStructure.DMA_BufferSize=gyro_data_len; + IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_gyro_data; + DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); + IMU_DMA_TX_InitStructure.DMA_BufferSize=1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&gyro_data_reg; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=gyro_rd_addr; + i2c_wr_addr=gyro_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); +} + +void imu_gyro_set_config(void) +{ + uint8_t i; + + // set the configuration + i2c_gyro_conf[GYRO_SMPL_DIV-GYRO_SMPL_DIV]=9;// 100 Hz + i2c_gyro_conf[GYRO_CONFIG-GYRO_SMPL_DIV]=GYRO_FS_2000 | GYRO_BW_188; + i2c_gyro_conf[GYRO_INT_CONFIG-GYRO_SMPL_DIV]=0x00;// no interrupts enabled + // write the configuration + for(i=0;i<gyro_conf_len;i++) + i2c_data_out[i+1]=i2c_gyro_conf[i]; + i2c_data_out[0]=gyro_conf_reg; + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=gyro_conf_len+1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=gyro_rd_addr; + i2c_wr_addr=gyro_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); + + // set the fifo configuration + i2c_gyro_power_mgm|=GYRO_CLK_INT; + i2c_data_out[0]=gyro_power_reg; + i2c_data_out[1]=i2c_gyro_power_mgm; + // write the fifo configuration + i2c_op=I2C_WR_OP; + IMU_DMA_TX_InitStructure.DMA_BufferSize=gyro_power_len+1; + IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; + DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); + i2c_rd_addr=gyro_rd_addr; + i2c_wr_addr=gyro_wr_addr; + I2C_GenerateSTART(I2C_IMU, ENABLE); + imu_wait_op_done(); +} + +void imu_gyro_process_data(void) +{ + uint8_t i; + int16_t value; + + // process temperature + ram_data[BIOLOID_IMU_TEMP]=((((int16_t)(i2c_gyro_data[1]+(i2c_gyro_data[0]<<8)))-13200)/280)+35; + // process gyro data + for(i=0;i<3;i++) + { + value=(((int16_t)(i2c_gyro_data[i*2+3]+(i2c_gyro_data[i*2+2]<<8)))*7)/115;// format 12|4 + ram_data[BIOLOID_IMU_GYRO_X_L+i*2]=value&0xFF; + ram_data[BIOLOID_IMU_GYRO_X_H+i*2]=(value>>8); + } +} + diff --git a/src/bioloid_stm32.c b/src/bioloid_stm32.c index 6035dfd64006ca2a50b25fec47e4221522593ff0..d7f18f8c03243b2ad02bb87b1e2cf2ca5220c3e3 100644 --- a/src/bioloid_stm32.c +++ b/src/bioloid_stm32.c @@ -147,7 +147,7 @@ int32_t main(void) EE_ReadVariable(RETURN_LEVEL_OFFSET,&eeprom_data); dyn_slave_set_return_level((uint8_t)eeprom_data); /* initialize the IMU */ -// imu_init(); + imu_init(); // initialize the Analog to digital converter // adc_init(); // initialize motion manager diff --git a/src/imu_9dof_dma.c b/src/imu_9dof_dma.c index 5099fb129579d5e3f38ca383feb9e8b7872df831..6f166fa72645bbb4bc1af2657b6690dcd7b6f935 100644 --- a/src/imu_9dof_dma.c +++ b/src/imu_9dof_dma.c @@ -1,128 +1,16 @@ #include "imu_9dof_dma.h" +#include "imu_int.h" +#include "ADXL345_accel.h" +#include "ITG3200_gyro.h" +#include "HMC5843_compass.h" #include "ram.h" -#define I2C_IMU_DMA DMA1 -#define I2C_IMU_DMA_CHANNEL DMA_Channel_3 -#define I2C_IMU_DR_ADDRESS ((uint32_t)I2C3+0x10) -#define I2C_IMU_DMA_STREAM_TX DMA1_Stream4 -#define I2C_IMU_DMA_STREAM_RX DMA1_Stream2 -#define I2C_IMU_TX_DMA_TCFLAG DMA_FLAG_TCIF4 -#define I2C_IMU_TX_DMA_FEIFLAG DMA_FLAG_FEIF4 -#define I2C_IMU_TX_DMA_DMEIFLAG DMA_FLAG_DMEIF4 -#define I2C_IMU_TX_DMA_TEIFLAG DMA_FLAG_TEIF4 -#define I2C_IMU_TX_DMA_HTIFLAG DMA_FLAG_HTIF4 -#define I2C_IMU_RX_DMA_TCFLAG DMA_FLAG_TCIF2 -#define I2C_IMU_RX_DMA_FEIFLAG DMA_FLAG_FEIF2 -#define I2C_IMU_RX_DMA_DMEIFLAG DMA_FLAG_DMEIF2 -#define I2C_IMU_RX_DMA_TEIFLAG DMA_FLAG_TEIF2 -#define I2C_IMU_RX_DMA_HTIFLAG DMA_FLAG_HTIF2 -#define DMA_IMU_CLK RCC_AHB1Periph_DMA1 - -#define I2C_IMU_TX_DMA_IRQn DMA1_Stream4_IRQn -#define I2C_IMU_RX_DMA_IRQn DMA1_Stream2_IRQn -#define I2C_IMU_TX_DMA_IRQHandler DMA1_Stream4_IRQHandler -#define I2C_IMU_RX_DMA_IRQHandler DMA1_Stream2_IRQHandler - -#define I2C_IMU I2C3 -#define I2C_IMU_CLK RCC_APB1Periph_I2C3 -#define I2C_IMU_SDA_GPIO_CLK RCC_AHB1Periph_GPIOC -#define I2C_IMU_SDA_PIN GPIO_Pin_9 -#define I2C_IMU_SDA_GPIO_PORT GPIOC -#define I2C_IMU_SDA_SOURCE GPIO_PinSource9 -#define I2C_IMU_SDA_AF GPIO_AF_I2C3 - -#define I2C_IMU_SCL_GPIO_CLK RCC_AHB1Periph_GPIOA -#define I2C_IMU_SCL_PIN GPIO_Pin_8 -#define I2C_IMU_SCL_GPIO_PORT GPIOA -#define I2C_IMU_SCL_SOURCE GPIO_PinSource8 -#define I2C_IMU_SCL_AF GPIO_AF_I2C3 - -#define I2C_IMU_EV_IRQn I2C3_EV_IRQn -#define I2C_IMU_ER_IRQn I2C3_ER_IRQn -#define I2C_IMU_EV_IRQHandler I2C3_EV_IRQHandler -#define I2C_IMU_ER_IRQHandler I2C3_ER_IRQHandler - -#define IMU_TIMER TIM4 -#define IMU_TIMER_IRQn TIM4_IRQn -#define IMU_TIMER_IRQHandler TIM4_IRQHandler -#define IMU_TIMER_CLK RCC_APB1Periph_TIM4 - -// accelerometer registers -#define ACCEL_THRESH_TAP 0x1D -#define ACCEL_OFSX 0x1E -#define ACCEL_OFSY 0x1F -#define ACCEL_OFSZ 0x20 -#define ACCEL_DUR 0x21 -#define ACCEL_LATENT 0x22 -#define ACCEL_WINDOW 0x23 -#define ACCEL_THRESH_ACT 0x24 -#define ACCEL_THRESH_INACT 0x25 -#define ACCEL_TIME_INACT 0x26 -#define ACCEL_ACT_INACT_CTL 0x27 -#define ACCEL_THRESH_FF 0x28 -#define ACCEL_TIME_FF 0x29 -#define ACCEL_TAP_AXES 0x2A -#define ACCEL_ACT_TAP_STATUS 0x2B -#define ACCEL_BW_RATE 0x2C -#define ACCEL_POWER_CTL 0x2D -#define ACCEL_INT_ENABLE 0x2E -#define ACCEL_INT_MAP 0x2F -#define ACCEL_INT_SOURCE 0x30 -#define ACCEL_DATA_FORMAT 0x31 - - -typedef enum {I2C_OP_DONE,I2C_WR_OP,I2C_RD_OP_CMD,I2C_RD_OP_DATA} i2c_op_t; -typedef enum {IMU_GET_ACCEL,IMU_GET_GYRO,IMU_GET_COMPASS} imu_state_t; - -// private variables // I2C private variables volatile uint8_t i2c_error; volatile i2c_op_t i2c_op; uint8_t i2c_rd_addr; uint8_t i2c_wr_addr; uint8_t i2c_data_out[32]; -// accelerometer data and configuration -const uint8_t accel_id_reg=0x00; -const uint8_t accel_id=0xE5; -const uint8_t accel_id_len=0x01; -const uint8_t accel_conf_reg=0x1D; -const uint8_t accel_conf_len=0x15; -const uint8_t accel_data_reg=0x32; -const uint8_t accel_data_len=0x06; -const uint8_t accel_fifo_reg=0x38; -const uint8_t accel_fifo_len=0x01; -const uint8_t accel_status_reg=0x39; -const uint8_t accel_status_len=0x01; -const uint8_t accel_rd_addr=0xA6; -const uint8_t accel_wr_addr=0xA7; -uint8_t i2c_accel_conf[21]; -uint8_t i2c_accel_fifo_conf; -uint8_t i2c_accel_data[6]; -uint8_t i2c_accel_status; -// gyroscope data and configuration -const uint8_t gyro_id_reg=0x00; -const uint8_t gyro_id=0x68; -const uint8_t gyro_id_len=0x01; -const uint8_t gyro_conf_reg=0x15; -const uint8_t gyro_conf_len=0x03; -const uint8_t gyro_data_reg=0x1B; -const uint8_t gyro_data_len=0x08; -const uint8_t gyro_rd_addr=0xD0; -const uint8_t gyro_wr_addr=0xD1; -uint8_t i2c_gyro_conf[4]; -uint8_t i2c_gyro_data[8]; -// compass data adn configuration -const uint8_t compass_id_reg=0x0A; -const uint8_t compass_id[3]={'H','4','3'}; -const uint8_t compass_id_len=0x03; -const uint8_t compass_conf_reg=0x00; -const uint8_t compass_conf_len=0x03; -const uint8_t compass_data_reg=0x03; -const uint8_t compass_data_len=0x06; -const uint8_t compass_rd_addr=0x3D; -const uint8_t compass_wr_addr=0x3C; -uint8_t i2c_compass_conf[4]; -uint8_t i2c_compass_data[6]; // dma initialization structures; DMA_InitTypeDef IMU_DMA_TX_InitStructure; DMA_InitTypeDef IMU_DMA_RX_InitStructure; @@ -141,145 +29,6 @@ uint8_t imu_is_op_done(void) return 0x00; } -// private accelerometer functions -void imu_accel_get_config(void) -{ - i2c_op=I2C_RD_OP_CMD; - IMU_DMA_RX_InitStructure.DMA_BufferSize=accel_conf_len; - IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_accel_conf; - DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); - IMU_DMA_TX_InitStructure.DMA_BufferSize=1; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&accel_conf_reg; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_rd_addr=accel_rd_addr; - i2c_wr_addr=accel_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); - imu_wait_op_done(); -} - -void imu_accel_start(void) -{ - // enter measure mode - i2c_accel_conf[ACCEL_POWER_CTL-ACCEL_THRESH_TAP]|=ACCEL_ENABLE_MEASURE; - i2c_data_out[0]=ACCEL_POWER_CTL; - i2c_data_out[1]=i2c_accel_conf[ACCEL_POWER_CTL-ACCEL_THRESH_TAP]; - // write the fifo configuration - i2c_op=I2C_WR_OP; - IMU_DMA_TX_InitStructure.DMA_BufferSize=2; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_rd_addr=accel_rd_addr; - i2c_wr_addr=accel_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); - imu_wait_op_done(); -} - -void imu_accel_stop(void) -{ - // enter measure mode - i2c_accel_conf[ACCEL_POWER_CTL-ACCEL_THRESH_TAP]&=~ACCEL_ENABLE_MEASURE; - i2c_data_out[0]=ACCEL_POWER_CTL; - i2c_data_out[1]=i2c_accel_conf[ACCEL_POWER_CTL-ACCEL_THRESH_TAP]; - // write the fifo configuration - i2c_op=I2C_WR_OP; - IMU_DMA_TX_InitStructure.DMA_BufferSize=2; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_rd_addr=accel_rd_addr; - i2c_wr_addr=accel_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); - imu_wait_op_done(); -} - -void imu_accel_get_data(void) -{ - i2c_op=I2C_RD_OP_CMD; - IMU_DMA_RX_InitStructure.DMA_BufferSize=accel_data_len; - IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_accel_data; - DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); - IMU_DMA_TX_InitStructure.DMA_BufferSize=1; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&accel_data_reg; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_rd_addr=accel_rd_addr; - i2c_wr_addr=accel_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); -} - -void imu_accel_set_config(void) -{ - uint8_t i; - - // set the configuration - i2c_accel_conf[ACCEL_BW_RATE-ACCEL_THRESH_TAP]|=ACCEL_RATE_100HZ; - i2c_accel_conf[ACCEL_DATA_FORMAT-ACCEL_THRESH_TAP]&=0xF0; - i2c_accel_conf[ACCEL_DATA_FORMAT-ACCEL_THRESH_TAP]|=ACCEL_RANGE_8G;// +/-8g range - i2c_accel_conf[ACCEL_DATA_FORMAT-ACCEL_THRESH_TAP]|=ACCEL_JUSTIFY_RIGHT;// justify right - i2c_accel_conf[ACCEL_DATA_FORMAT-ACCEL_THRESH_TAP]|=ACCEL_ENABLE_FULL_RES;// enable full resolution according to the range - // write the configuration - for(i=0;i<accel_conf_len;i++) - i2c_data_out[i+1]=i2c_accel_conf[i]; - i2c_data_out[0]=accel_conf_reg; - i2c_op=I2C_WR_OP; - IMU_DMA_TX_InitStructure.DMA_BufferSize=accel_conf_len+1; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_rd_addr=accel_rd_addr; - i2c_wr_addr=accel_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); - imu_wait_op_done(); - - // set the fifo configuration - i2c_accel_fifo_conf=ACCEL_FIFO_STREAM; - i2c_data_out[0]=accel_fifo_reg; - i2c_data_out[1]=i2c_accel_fifo_conf; - // write the fifo configuration - i2c_op=I2C_WR_OP; - IMU_DMA_TX_InitStructure.DMA_BufferSize=accel_fifo_len+1; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_data_out; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_rd_addr=accel_rd_addr; - i2c_wr_addr=accel_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); - imu_wait_op_done(); -} - -uint8_t imu_accel_detect(void) -{ - i2c_accel_data[0]=0x00; - i2c_op=I2C_RD_OP_CMD; - IMU_DMA_RX_InitStructure.DMA_BufferSize=accel_id_len; - IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)i2c_accel_data; - DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); - IMU_DMA_TX_InitStructure.DMA_BufferSize=1; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&accel_id_reg; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_rd_addr=accel_rd_addr; - i2c_wr_addr=accel_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); - imu_wait_op_done(); - if(i2c_accel_data[0]==accel_id) - { - imu_accel_get_config(); - imu_accel_set_config(); - return 0x01; - } - else - return 0x00; -} - -void imu_accel_process_data(void) -{ - uint8_t i; - int16_t value; - - for(i=0;i<3;i++) - { - value=((int16_t)(i2c_accel_data[i*2]+(i2c_accel_data[i*2+1]<<8)))<<2; - ram_data[BIOLOID_IMU_ACCEL_X_L+i*2]=value&0xFF; - ram_data[BIOLOID_IMU_ACCEL_X_H+i*2]=(value>>8); - } -} - // interrupt handlers void IMU_TIMER_IRQHandler(void) { @@ -296,12 +45,16 @@ void IMU_TIMER_IRQHandler(void) switch(state) { case IMU_GET_ACCEL: imu_accel_get_data(); + imu_compass_process_data(); state=IMU_GET_GYRO; break; - case IMU_GET_GYRO: imu_accel_process_data(); + case IMU_GET_GYRO: imu_gyro_get_data(); + imu_accel_process_data(); state=IMU_GET_COMPASS; break; - case IMU_GET_COMPASS: state=IMU_GET_ACCEL; + case IMU_GET_COMPASS: imu_compass_get_data(); + imu_gyro_process_data(); + state=IMU_GET_ACCEL; break; } } @@ -390,52 +143,6 @@ void I2C_IMU_RX_DMA_IRQHandler(void) i2c_op=I2C_OP_DONE; } -// gyroscope public functions -uint8_t imu_gyro_detect(void) -{ - i2c_op=I2C_RD_OP_CMD; - IMU_DMA_RX_InitStructure.DMA_BufferSize=gyro_id_len; - IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_gyro_data; - DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); - IMU_DMA_TX_InitStructure.DMA_BufferSize=1; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&gyro_id_reg; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_gyro_data[0]=0x00; - i2c_rd_addr=gyro_rd_addr; - i2c_wr_addr=gyro_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); - - imu_wait_op_done(); - if((i2c_gyro_data[0]&0x7E)==gyro_id) - return 0x01; - else - return 0x00; -} - -// compass public functions -uint8_t imu_compass_detect(void) -{ - i2c_op=I2C_RD_OP_CMD; - IMU_DMA_RX_InitStructure.DMA_BufferSize=compass_id_len; - IMU_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)i2c_compass_data; - DMA_Init(I2C_IMU_DMA_STREAM_RX,&IMU_DMA_RX_InitStructure); - IMU_DMA_TX_InitStructure.DMA_BufferSize=1; - IMU_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&compass_id_reg; - DMA_Init(I2C_IMU_DMA_STREAM_TX,&IMU_DMA_TX_InitStructure); - i2c_compass_data[0]=0x00; - i2c_compass_data[1]=0x00; - i2c_compass_data[2]=0x00; - i2c_rd_addr=compass_rd_addr; - i2c_wr_addr=compass_wr_addr; - I2C_GenerateSTART(I2C_IMU, ENABLE); - - imu_wait_op_done(); - if(i2c_compass_data[0]==compass_id[0] && i2c_compass_data[1]==compass_id[1] && i2c_compass_data[2]==compass_id[2]) - return 0x01; - else - return 0x00; -} - // public functions void imu_init(void) { @@ -595,6 +302,8 @@ void imu_start(void) { // start the accelerometer imu_accel_start(); + imu_gyro_start(); + imu_compass_start(); // start the timer to get the imu data TIM_Cmd(IMU_TIMER, ENABLE); @@ -611,6 +320,8 @@ void imu_stop(void) // stop the accelerometer imu_accel_stop(); + imu_gyro_stop(); + imu_compass_stop(); ram_clear_bit(BIOLOID_IMU_STATUS,0); }