Martin Johnson / accelerometer_test_minimal

Dependencies:   STM32F3-Discovery-minimal

Fork of accelerometer_test by Martin Johnson

Committer:
MartinJohnson
Date:
Wed Apr 03 22:00:45 2019 +0000
Revision:
4:e38891a2d67c
Parent:
2:742027e49b6f
Tidy up formatting

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MartinJohnson 0:ed38888a34c2 1
MartinJohnson 0:ed38888a34c2 2 #include <stm32f3_discovery.h>
MartinJohnson 1:c92d1851a036 3 #include <stm32f3_discovery_lsm303dlhc.h>
MartinJohnson 2:742027e49b6f 4 #include <stdio.h>
MartinJohnson 2:742027e49b6f 5 #include <math.h>
MartinJohnson 1:c92d1851a036 6
MartinJohnson 1:c92d1851a036 7 #define I2C_CR2_CLEAR_MASK ~(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)
MartinJohnson 0:ed38888a34c2 8
MartinJohnson 1:c92d1851a036 9 void i2cWrite(int address, int reg, int val) {
MartinJohnson 1:c92d1851a036 10 while(I2C1->ISR & I2C_ISR_BUSY);
MartinJohnson 1:c92d1851a036 11 I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_RELOAD | I2C_CR2_START | (1<<16) | address;
MartinJohnson 1:c92d1851a036 12 while(!(I2C1->ISR & I2C_ISR_TXIS));
MartinJohnson 4:e38891a2d67c 13 I2C1->TXDR = reg;
MartinJohnson 1:c92d1851a036 14 while(!(I2C1->ISR & I2C_ISR_TCR));
MartinJohnson 1:c92d1851a036 15 I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_AUTOEND | (1<<16) | address;
MartinJohnson 1:c92d1851a036 16 while(!(I2C1->ISR & I2C_ISR_TXIS));
MartinJohnson 4:e38891a2d67c 17 I2C1->TXDR = val;
MartinJohnson 1:c92d1851a036 18 while(!(I2C1->ISR & I2C_ISR_STOPF));
MartinJohnson 1:c92d1851a036 19 I2C1->ICR = I2C_ICR_STOPCF;
MartinJohnson 1:c92d1851a036 20 }
MartinJohnson 0:ed38888a34c2 21
MartinJohnson 1:c92d1851a036 22 void i2cRead(int address, int reg, uint8_t *data, int nbytes) {
MartinJohnson 1:c92d1851a036 23 while(I2C1->ISR & I2C_ISR_BUSY);
MartinJohnson 1:c92d1851a036 24 I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_START | (1<<16) | address;
MartinJohnson 1:c92d1851a036 25 while(!(I2C1->ISR & I2C_ISR_TXIS));
MartinJohnson 1:c92d1851a036 26 if(nbytes>1) reg |= 0x80;
MartinJohnson 4:e38891a2d67c 27 I2C1->TXDR= reg;
MartinJohnson 1:c92d1851a036 28 while(!(I2C1->ISR & I2C_ISR_TC));
MartinJohnson 1:c92d1851a036 29 I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_RD_WRN | (nbytes<<16) | address;
MartinJohnson 1:c92d1851a036 30 while(nbytes--) {
MartinJohnson 1:c92d1851a036 31 while(!(I2C1->ISR & I2C_ISR_RXNE));
MartinJohnson 4:e38891a2d67c 32 *data++ = I2C1->RXDR;
MartinJohnson 1:c92d1851a036 33 }
MartinJohnson 1:c92d1851a036 34 while(!(I2C1->ISR & I2C_ISR_STOPF));
MartinJohnson 1:c92d1851a036 35 I2C1->ICR = I2C_ICR_STOPCF;
MartinJohnson 0:ed38888a34c2 36 }
MartinJohnson 0:ed38888a34c2 37
MartinJohnson 1:c92d1851a036 38 void i2cInit() {
MartinJohnson 1:c92d1851a036 39 RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
MartinJohnson 1:c92d1851a036 40 // configure GPIOPB6 and 7
MartinJohnson 1:c92d1851a036 41 RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
MartinJohnson 2:742027e49b6f 42 GPIOB->AFR[0] = (GPIOB->AFR[0] & 0x00ffffff) | 0x44000000; // alt funcs for GPIOB6 and 7 are 4
MartinJohnson 1:c92d1851a036 43 GPIOB->OSPEEDR |= 0xf000; // speed high
MartinJohnson 1:c92d1851a036 44 GPIOB->OTYPER &= ~0xc0; // output type pp
MartinJohnson 1:c92d1851a036 45 GPIOB->MODER = (GPIOB->MODER & ~0xf000) | 0xa000; // mode af (10)
MartinJohnson 1:c92d1851a036 46 GPIOB->PUPDR = (GPIOB->PUPDR & ~0xf000) | 0xa000; // pull down (10)
MartinJohnson 1:c92d1851a036 47
MartinJohnson 1:c92d1851a036 48 I2C1->TIMINGR = 0x00902025;
MartinJohnson 1:c92d1851a036 49 I2C1->CR1 |= I2C_CR1_PE;
MartinJohnson 1:c92d1851a036 50
MartinJohnson 1:c92d1851a036 51 }
MartinJohnson 1:c92d1851a036 52
MartinJohnson 1:c92d1851a036 53 void MemsConfig(void)
MartinJohnson 0:ed38888a34c2 54 {
MartinJohnson 1:c92d1851a036 55 i2cInit();
MartinJohnson 4:e38891a2d67c 56 i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG1_A, LSM303DLHC_NORMAL_MODE | LSM303DLHC_ODR_50_HZ | LSM303DLHC_AXES_ENABLE);
MartinJohnson 4:e38891a2d67c 57 i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG4_A, LSM303DLHC_FULLSCALE_2G | LSM303DLHC_BlockUpdate_Continous | LSM303DLHC_BLE_LSB | LSM303DLHC_HR_ENABLE);
MartinJohnson 4:e38891a2d67c 58 i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG2_A, LSM303DLHC_HPM_NORMAL_MODE | LSM303DLHC_HPFCF_16 | LSM303DLHC_HPF_AOI1_DISABLE | LSM303DLHC_HPF_AOI2_DISABLE);
MartinJohnson 1:c92d1851a036 59
MartinJohnson 1:c92d1851a036 60 i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_CRA_REG_M, LSM303DLHC_TEMPSENSOR_ENABLE | LSM303DLHC_ODR_30_HZ);
MartinJohnson 1:c92d1851a036 61 i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_CRB_REG_M, LSM303DLHC_FS_8_1_GA);
MartinJohnson 4:e38891a2d67c 62 i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_MR_REG_M, LSM303DLHC_CONTINUOS_CONVERSION);
MartinJohnson 1:c92d1851a036 63 }
MartinJohnson 1:c92d1851a036 64
MartinJohnson 1:c92d1851a036 65 void ReadAccelerometer(int16_t * data) {
MartinJohnson 1:c92d1851a036 66 i2cRead(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, (uint8_t *)data, 6);
MartinJohnson 1:c92d1851a036 67 }
MartinJohnson 1:c92d1851a036 68
MartinJohnson 1:c92d1851a036 69 void ReadMagnetometer(int16_t * data) {
MartinJohnson 2:742027e49b6f 70 i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_L_M, (uint8_t *)data, 1);
MartinJohnson 2:742027e49b6f 71 i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_H_M, (uint8_t *)data+1, 1);
MartinJohnson 2:742027e49b6f 72 i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_L_M, (uint8_t *)data+2, 1);
MartinJohnson 2:742027e49b6f 73 i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_H_M, (uint8_t *)data+3, 1);
MartinJohnson 2:742027e49b6f 74 i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_L_M, (uint8_t *)data+4, 1);
MartinJohnson 2:742027e49b6f 75 i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_H_M, (uint8_t *)data+5, 1);
MartinJohnson 1:c92d1851a036 76 }
MartinJohnson 1:c92d1851a036 77
MartinJohnson 1:c92d1851a036 78 int ReadTemperature() {
MartinJohnson 1:c92d1851a036 79 int t=0;
MartinJohnson 4:e38891a2d67c 80 i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_TEMP_OUT_L_M, (uint8_t *)&t, 1);
MartinJohnson 4:e38891a2d67c 81 i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_TEMP_OUT_H_M, (uint8_t *)&t+1, 1);
MartinJohnson 1:c92d1851a036 82 return t/64;
MartinJohnson 0:ed38888a34c2 83 }
MartinJohnson 0:ed38888a34c2 84
MartinJohnson 0:ed38888a34c2 85 volatile unsigned sysTiming;
MartinJohnson 0:ed38888a34c2 86 volatile unsigned sysTicks = 0;
MartinJohnson 0:ed38888a34c2 87
MartinJohnson 4:e38891a2d67c 88 __attribute__ ((section ("ccmram"))) void SysTick_Handler(void) {
MartinJohnson 0:ed38888a34c2 89 sysTicks++;
MartinJohnson 0:ed38888a34c2 90 if (sysTiming > 0) --sysTiming;
MartinJohnson 0:ed38888a34c2 91 }
MartinJohnson 0:ed38888a34c2 92
MartinJohnson 0:ed38888a34c2 93 void sysDelayMs(unsigned dly) {
MartinJohnson 0:ed38888a34c2 94 sysTiming = dly;
MartinJohnson 0:ed38888a34c2 95 while (sysTiming > 0) __wfi();
MartinJohnson 0:ed38888a34c2 96
MartinJohnson 0:ed38888a34c2 97 }
MartinJohnson 0:ed38888a34c2 98
MartinJohnson 0:ed38888a34c2 99 int main(void) {
MartinJohnson 0:ed38888a34c2 100 SysTick_Config((SystemCoreClock / 1000));
MartinJohnson 1:c92d1851a036 101 RCC->AHBENR |= RCC_AHBENR_GPIOEEN | RCC_AHBENR_GPIOAEN;
MartinJohnson 0:ed38888a34c2 102 GPIOE->MODER = (GPIOE->MODER&0xffff) | 0x55550000; // output mode for PE8-15
MartinJohnson 0:ed38888a34c2 103 GPIOA->MODER = (GPIOA->MODER&0xfffffffc) ; // input mode for PA0
MartinJohnson 0:ed38888a34c2 104
MartinJohnson 1:c92d1851a036 105 MemsConfig();
MartinJohnson 1:c92d1851a036 106 int16_t acc[3],mag[3],temp;
MartinJohnson 4:e38891a2d67c 107 int b = 0;
MartinJohnson 4:e38891a2d67c 108 int TH = 200*16;
MartinJohnson 0:ed38888a34c2 109 while(1) {
MartinJohnson 0:ed38888a34c2 110 ReadAccelerometer(acc);
MartinJohnson 1:c92d1851a036 111 ReadMagnetometer(mag);
MartinJohnson 2:742027e49b6f 112 float heading = atan2(mag[1], mag[0]);
MartinJohnson 4:e38891a2d67c 113 heading = heading * 180 / 3.14159265359f;
MartinJohnson 4:e38891a2d67c 114 if (heading < 0) heading += 360;
MartinJohnson 1:c92d1851a036 115 temp=ReadTemperature();
MartinJohnson 4:e38891a2d67c 116 printf("Acc: %d %d %d\n", acc[0]/16, acc[1]/16, acc[2]/16);
MartinJohnson 4:e38891a2d67c 117 printf("Mag: %d %d %d %d %f\n", mag[0], mag[1], mag[2], temp, heading);
MartinJohnson 4:e38891a2d67c 118 GPIOE->BSRR = b<<(8+16);
MartinJohnson 4:e38891a2d67c 119 b = 0;
MartinJohnson 4:e38891a2d67c 120 if(acc[1] < -TH) {
MartinJohnson 4:e38891a2d67c 121 if(acc[0] < -TH) b = 1<<4;
MartinJohnson 4:e38891a2d67c 122 else if(acc[0] > TH) b = 1<<2;
MartinJohnson 4:e38891a2d67c 123 else b = 1<<3;
MartinJohnson 0:ed38888a34c2 124 } else {
MartinJohnson 4:e38891a2d67c 125 if(acc[1] > TH) {
MartinJohnson 4:e38891a2d67c 126 if(acc[0] < -TH) b = 1<<6;
MartinJohnson 4:e38891a2d67c 127 else if(acc[0] > TH) b = 1<<0;
MartinJohnson 4:e38891a2d67c 128 else b = 1<<7;
MartinJohnson 0:ed38888a34c2 129 } else {
MartinJohnson 4:e38891a2d67c 130 if(acc[0] < -TH) b = 1<<5;
MartinJohnson 4:e38891a2d67c 131 else if(acc[0] > TH) b = 1<<1;
MartinJohnson 0:ed38888a34c2 132 }
MartinJohnson 0:ed38888a34c2 133 }
MartinJohnson 4:e38891a2d67c 134 GPIOE->BSRR = b<<8;
MartinJohnson 0:ed38888a34c2 135 while(GPIOA->IDR&1);
MartinJohnson 0:ed38888a34c2 136 sysDelayMs(100);
MartinJohnson 0:ed38888a34c2 137 }
MartinJohnson 0:ed38888a34c2 138 }
MartinJohnson 0:ed38888a34c2 139