Merge pull request #383 from paparazzi/fix_stm32_spi

fixes for STM32 SPI transactions:
can handle zero input or output lengths now, max1168 works again...
This commit is contained in:
Felix Ruess
2013-03-02 12:01:28 -08:00
11 changed files with 547 additions and 515 deletions
@@ -33,17 +33,19 @@
<subsystem name="stabilization" type="euler"/>
<subsystem name="ahrs" type="int_cmpl_quat"/>
<subsystem name="ins"/>
<define name="HMC5843_USE_INT"/>
<define name="PRINT_CONFIG"/>
</firmware>
<firmware name="lisa_test_progs">
<define name="PRINT_CONFIG"/>
<target name="test_led" board="lisa_l_1.1"/>
<target name="test_uart" board="lisa_l_1.1"/>
<target name="test_servos" board="lisa_l_1.1"/>
<target name="test_telemetry" board="lisa_l_1.1"/>
<target name="test_baro" board="lisa_l_1.1"/>
<target name="test_imu_b2_2" board="lisa_l_1.1"/>
<target name="test_imu_b2_nomag" board="lisa_l_1.1"/>
<target name="test_imu_b2" board="lisa_l_1.1"/>
<target name="test_imu_b2_2" board="lisa_l_1.1"/>
<target name="test_rc_spektrum" board="lisa_l_1.1"/>
<target name="test_rc_ppm" board="lisa_l_1.1"/>
<target name="test_adc" board="lisa_l_1.1"/>
+3 -4
View File
@@ -361,10 +361,10 @@ test_imu_b2.srcs += $(IMU_B2_SRCS)
#
IMU_B2_2_CFLAGS = -DIMU_B2_VERSION_1_2
# mag stuff
IMU_B2_2_CFLAGS += -DUSE_I2C2
IMU_B2_2_CFLAGS += -DIMU_B2_I2C_DEV=i2c2 -DUSE_I2C2
IMU_B2_2_SRCS = mcu_periph/i2c.c $(SRC_ARCH)/mcu_periph/i2c_arch.c
IMU_B2_2_CFLAGS += -DIMU_B2_MAG_TYPE=IMU_B2_MAG_HMC5843
IMU_B2_2_SRCS += peripherals/hmc5843.c $(SRC_ARCH)/peripherals/hmc5843_arch.c
IMU_B2_2_CFLAGS += -DIMU_B2_MAG_TYPE=IMU_B2_MAG_HMC58XX
IMU_B2_2_SRCS += peripherals/hmc58xx.c
test_imu_b2_2.ARCHDIR = $(ARCH)
test_imu_b2_2.srcs = test/subsystems/test_imu.c
@@ -498,7 +498,6 @@ test_hmc5843.srcs += lisa/test/lisa_test_hmc5843.c
test_hmc5843.CFLAGS += -DUSE_I2C2
test_hmc5843.srcs += mcu_periph/i2c.c $(SRC_ARCH)/mcu_periph/i2c_arch.c
#
# test ITG3200
#
File diff suppressed because it is too large Load Diff
@@ -90,13 +90,13 @@ static inline void main_periodic_task( void ) {
if (acc_status != CONFIGURED) {
/* set data rate to 800Hz */
write_to_reg(ADXL345_REG_BW_RATE, 0x0D);
/* switch to measurememnt mode */
write_to_reg(ADXL345_REG_POWER_CTL, 1<<3);
/* enable data ready interrupt */
write_to_reg(ADXL345_REG_INT_ENABLE, 1<<7);
/* Enable full res and interrupt active low */
write_to_reg(ADXL345_REG_DATA_FORMAT, 1<<3|1<<5);
/* reads data once to bring interrupt line up */
/* switch to measurememnt mode */
write_to_reg(ADXL345_REG_POWER_CTL, 1<<3);
read_data();
acc_status = CONFIGURED;
}
@@ -114,9 +114,6 @@ static inline void main_event_task( void ) {
}
if (acc_status >= CONFIGURED && acc_data_available) {
acc_data_available = FALSE;
//int16_t ax = dma_rx_buf[1] | (dma_rx_buf[2]<<8);
//int16_t ay = dma_rx_buf[3] | (dma_rx_buf[4]<<8);
//int16_t az = dma_rx_buf[5] | (dma_rx_buf[6]<<8);
int16_t ax = Int16FromBuf(dma_rx_buf, 1);
int16_t ay = Int16FromBuf(dma_rx_buf, 3);
int16_t az = Int16FromBuf(dma_rx_buf, 5);
@@ -128,7 +125,8 @@ static inline void main_event_task( void ) {
}
static void write_to_reg(uint8_t addr, uint8_t val) {
//adxl345_spi_trans.output_length = 2;
adxl345_spi_trans.output_length = 2;
adxl345_spi_trans.input_length = 0;
dma_tx_buf[0] = addr;
dma_tx_buf[1] = val;
spi_submit(&(ADXL345_SPI_DEV), &adxl345_spi_trans);
@@ -137,7 +135,8 @@ static void write_to_reg(uint8_t addr, uint8_t val) {
}
static void read_data(void) {
//adxl345_spi_trans.output_length = 1;
adxl345_spi_trans.output_length = 1;
adxl345_spi_trans.input_length = 7;
dma_tx_buf[0] = (1<<7|1<<6|ADXL345_REG_DATA_X0);
spi_submit(&(ADXL345_SPI_DEV), &adxl345_spi_trans);
}
+2 -5
View File
@@ -135,12 +135,9 @@ typedef void (*SPICallback)( struct spi_transaction *trans );
* - The input/output buffers needs to be created separately
* - Take care of pointing input_buf/ouput_buf correctly
* - input_length and output_length can be different, the larger number
* of the two specifies the toal number of exchanged bytes,
* of the two specifies the toal number of exchanged words,
* - if input_length is larger than output length,
* 0 is sent for the remaining bytes
* WARNING: For STM32 only, the output_buf size MUST be greater than or equal
* to the input_buf size. This is only required in the event any transaction
* has (0 < output_length < input_length).
* 0 is sent for the remaining words
*/
struct spi_transaction {
volatile uint8_t* input_buf; ///< pointer to receive buffer for DMA
+3 -3
View File
@@ -36,9 +36,9 @@
enum Adxl345ConfStatus {
ADXL_CONF_UNINIT = 0,
ADXL_CONF_RATE = 1,
ADXL_CONF_POWER = 2,
ADXL_CONF_INT = 3,
ADXL_CONF_FORMAT = 4,
ADXL_CONF_INT = 2,
ADXL_CONF_FORMAT = 3,
ADXL_CONF_ENABLE = 4,
ADXL_CONF_DONE = 5
};
+5 -5
View File
@@ -64,11 +64,6 @@ static void adxl345_i2c_send_config(struct Adxl345_I2c *adxl)
adxl345_i2c_tx_reg(adxl, ADXL345_REG_BW_RATE, adxl->config.rate);
adxl->init_status++;
break;
case ADXL_CONF_POWER:
/* enable measurement, is in standby after power up */
adxl345_i2c_tx_reg(adxl, ADXL345_REG_POWER_CTL, (0x1<<3));
adxl->init_status++;
break;
case ADXL_CONF_INT:
adxl345_i2c_tx_reg(adxl, ADXL345_REG_INT_ENABLE, adxl->config.drdy_int_enable);
adxl->init_status++;
@@ -77,6 +72,11 @@ static void adxl345_i2c_send_config(struct Adxl345_I2c *adxl)
adxl345_i2c_tx_reg(adxl, ADXL345_REG_DATA_FORMAT, ADXL345_DATA_FORMAT);
adxl->init_status++;
break;
case ADXL_CONF_ENABLE:
/* enable measurement, is in standby after power up */
adxl345_i2c_tx_reg(adxl, ADXL345_REG_POWER_CTL, (0x1<<3));
adxl->init_status++;
break;
case ADXL_CONF_DONE:
adxl->initialized = TRUE;
adxl->i2c_trans.status = I2CTransDone;
+9 -9
View File
@@ -67,8 +67,8 @@ void adxl345_spi_init(struct Adxl345_Spi *adxl, struct spi_periph *spi_p, uint8_
static void adxl345_spi_write_to_reg(struct Adxl345_Spi *adxl, uint8_t _reg, uint8_t _val) {
//adxl->spi_trans.output_length = 2;
//adxl->spi_trans.input_length = 0;
adxl->spi_trans.output_length = 2;
adxl->spi_trans.input_length = 0;
adxl->tx_buf[0] = _reg;
adxl->tx_buf[1] = _val;
spi_submit(adxl->spi_p, &(adxl->spi_trans));
@@ -82,11 +82,6 @@ static void adxl345_spi_send_config(struct Adxl345_Spi *adxl)
adxl345_spi_write_to_reg(adxl, ADXL345_REG_BW_RATE, adxl->config.rate);
adxl->init_status++;
break;
case ADXL_CONF_POWER:
/* enable measurement, is in standby after power up */
adxl345_spi_write_to_reg(adxl, ADXL345_REG_POWER_CTL, (0x1<<3));
adxl->init_status++;
break;
case ADXL_CONF_INT:
adxl345_spi_write_to_reg(adxl, ADXL345_REG_INT_ENABLE, (adxl->config.drdy_int_enable << 7));
adxl->init_status++;
@@ -95,6 +90,11 @@ static void adxl345_spi_send_config(struct Adxl345_Spi *adxl)
adxl345_spi_write_to_reg(adxl, ADXL345_REG_DATA_FORMAT, adxl345_data_format(&adxl->config));
adxl->init_status++;
break;
case ADXL_CONF_ENABLE:
/* enable measurement, is in standby after power up */
adxl345_spi_write_to_reg(adxl, ADXL345_REG_POWER_CTL, (0x1<<3));
adxl->init_status++;
break;
case ADXL_CONF_DONE:
adxl->initialized = TRUE;
adxl->spi_trans.status = SPITransDone;
@@ -117,8 +117,8 @@ void adxl345_spi_start_configure(struct Adxl345_Spi *adxl)
void adxl345_spi_read(struct Adxl345_Spi *adxl)
{
if (adxl->initialized && adxl->spi_trans.status == SPITransDone) {
//adxl->spi_trans.output_length = 1;
//adxl->spi_trans.input_length = 7;
adxl->spi_trans.output_length = 1;
adxl->spi_trans.input_length = 7;
/* set read bit and multiple byte bit, then address */
adxl->tx_buf[0] = (1<<7|1<<6|ADXL345_REG_DATA_X0);
spi_submit(adxl->spi_p, &(adxl->spi_trans));
+1 -10
View File
@@ -93,7 +93,6 @@ void max1168_read( void ) {
spi_submit(&(MAX1168_SPI_DEV),&max1168_read_trans);
max1168_status = MAX1168_SENDING_REQ;
}
void max1168_event( void ) {
@@ -111,15 +110,7 @@ void max1168_event( void ) {
// handle reading transaction
if (max1168_read_trans.status == SPITransSuccess) {
if (max1168_status == MAX1168_READING_RES) {
// store values
//max1168_values[0] = max1168_read_trans.input_buf[0];
//max1168_values[1] = max1168_read_trans.input_buf[1];
//max1168_values[2] = max1168_read_trans.input_buf[2];
//max1168_values[3] = max1168_read_trans.input_buf[3];
//max1168_values[4] = max1168_read_trans.input_buf[4];
//max1168_values[5] = max1168_read_trans.input_buf[5];
//max1168_values[6] = max1168_read_trans.input_buf[6];
//max1168_values[7] = max1168_read_trans.input_buf[7];
// result was already written to max1168_values by DMA
max1168_status = MAX1168_DATA_AVAILABLE;
max1168_read_trans.status = SPITransDone;
}
+7 -4
View File
@@ -24,12 +24,17 @@
* @file subsystems/imu/imu_b2.c
*
* Driver for the Booz2 IMUs.
*
* Analog gyros and accelerometers are read via MAX1168 16-bit SPI ADC.
* Depending on version, different I2C or SPI magnetometers are used.
*/
#include "subsystems/imu.h"
struct ImuBooz2 imu_b2;
PRINT_CONFIG_VAR(IMU_B2_MAG_TYPE)
void imu_impl_init(void) {
max1168_init();
@@ -53,11 +58,9 @@ void imu_periodic(void) {
// read mag
#if defined IMU_B2_MAG_TYPE && IMU_B2_MAG_TYPE == IMU_B2_MAG_MS2100
ms2100_periodic(&ms2100);
#endif
#if defined IMU_B2_MAG_TYPE && IMU_B2_MAG_TYPE == IMU_B2_MAG_AMI601
#elif defined IMU_B2_MAG_TYPE && IMU_B2_MAG_TYPE == IMU_B2_MAG_AMI601
RunOnceEvery(10, { ami601_read(); });
#endif
#if defined IMU_B2_MAG_TYPE && IMU_B2_MAG_TYPE == IMU_B2_MAG_HMC58XX
#elif defined IMU_B2_MAG_TYPE && IMU_B2_MAG_TYPE == IMU_B2_MAG_HMC58XX
RunOnceEvery(5, hmc58xx_periodic(&imu_b2.mag_hmc));
#endif
+4 -5
View File
@@ -41,7 +41,7 @@ static inline void main_init( void );
static inline void main_periodic_task( void );
static inline void main_event_task( void );
static inline void on_gyro_accel_event(void);
static inline void on_gyro_event(void);
static inline void on_accel_event(void);
static inline void on_mag_event(void);
@@ -69,7 +69,7 @@ static inline void main_init( void ) {
static inline void led_toggle ( void ) {
#ifdef BOARD_LISA_L
LED_TOGGLE(3);
LED_TOGGLE(7);
#endif
}
@@ -109,8 +109,7 @@ static inline void main_periodic_task( void ) {
static inline void main_event_task( void ) {
ImuEvent(on_gyro_accel_event, on_accel_event, on_mag_event);
ImuEvent(on_gyro_event, on_accel_event, on_mag_event);
}
@@ -135,7 +134,7 @@ static inline void on_accel_event(void) {
}
}
static inline void on_gyro_accel_event(void) {
static inline void on_gyro_event(void) {
ImuScaleGyro(imu);
RunOnceEvery(50, LED_TOGGLE(2));