Martin Johnson / accelerometer_test_minimal

Dependencies:   STM32F3-Discovery-minimal

Fork of accelerometer_test by Martin Johnson

main.c

Committer:
MartinJohnson
Date:
2019-04-03
Revision:
4:e38891a2d67c
Parent:
2:742027e49b6f

File content as of revision 4:e38891a2d67c:


#include <stm32f3_discovery.h>
#include <stm32f3_discovery_lsm303dlhc.h>
#include <stdio.h>
#include <math.h>

#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)

void i2cWrite(int address, int reg, int val) {
	while(I2C1->ISR & I2C_ISR_BUSY);
	I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_RELOAD | I2C_CR2_START | (1<<16) | address;
	while(!(I2C1->ISR & I2C_ISR_TXIS));
	I2C1->TXDR = reg;
	while(!(I2C1->ISR & I2C_ISR_TCR));
	I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_AUTOEND | (1<<16) | address;
	while(!(I2C1->ISR & I2C_ISR_TXIS));
	I2C1->TXDR = val;
	while(!(I2C1->ISR & I2C_ISR_STOPF));
	I2C1->ICR = I2C_ICR_STOPCF;
}

void i2cRead(int address, int reg, uint8_t *data, int nbytes) {
	while(I2C1->ISR & I2C_ISR_BUSY);
	I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_START | (1<<16) | address;
	while(!(I2C1->ISR & I2C_ISR_TXIS));
	if(nbytes>1) reg |= 0x80;
	I2C1->TXDR=  reg;
	while(!(I2C1->ISR & I2C_ISR_TC));
	I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_RD_WRN | (nbytes<<16) | address;
	while(nbytes--) {
		while(!(I2C1->ISR & I2C_ISR_RXNE));
		*data++ = I2C1->RXDR;
	}
	while(!(I2C1->ISR & I2C_ISR_STOPF));
	I2C1->ICR = I2C_ICR_STOPCF;
}

void i2cInit() {
  RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  // configure GPIOPB6 and 7
  RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
  GPIOB->AFR[0] = (GPIOB->AFR[0] & 0x00ffffff) | 0x44000000; // alt funcs for GPIOB6 and 7 are 4
  GPIOB->OSPEEDR |= 0xf000; // speed high
  GPIOB->OTYPER &= ~0xc0; // output type pp
  GPIOB->MODER = (GPIOB->MODER & ~0xf000) | 0xa000; // mode af (10)
  GPIOB->PUPDR = (GPIOB->PUPDR & ~0xf000) | 0xa000; // pull down (10)

  I2C1->TIMINGR = 0x00902025;
  I2C1->CR1 |= I2C_CR1_PE;

}

void MemsConfig(void)
{
  i2cInit();
  i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG1_A, LSM303DLHC_NORMAL_MODE | LSM303DLHC_ODR_50_HZ | LSM303DLHC_AXES_ENABLE);
  i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG4_A, LSM303DLHC_FULLSCALE_2G | LSM303DLHC_BlockUpdate_Continous | LSM303DLHC_BLE_LSB | LSM303DLHC_HR_ENABLE);
  i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG2_A, LSM303DLHC_HPM_NORMAL_MODE | LSM303DLHC_HPFCF_16 | LSM303DLHC_HPF_AOI1_DISABLE | LSM303DLHC_HPF_AOI2_DISABLE);
 
  i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_CRA_REG_M, LSM303DLHC_TEMPSENSOR_ENABLE | LSM303DLHC_ODR_30_HZ);
  i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_CRB_REG_M, LSM303DLHC_FS_8_1_GA);
  i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_MR_REG_M, LSM303DLHC_CONTINUOS_CONVERSION);
}

void ReadAccelerometer(int16_t * data) {  
	i2cRead(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, (uint8_t *)data, 6);
}

void ReadMagnetometer(int16_t * data) {
	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_L_M, (uint8_t *)data, 1);
	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_H_M, (uint8_t *)data+1, 1);
	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_L_M, (uint8_t *)data+2, 1);
	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_H_M, (uint8_t *)data+3, 1);
	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_L_M, (uint8_t *)data+4, 1);
	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_H_M, (uint8_t *)data+5, 1);
}

int ReadTemperature() {
	int t=0;
	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_TEMP_OUT_L_M, (uint8_t *)&t, 1);
	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_TEMP_OUT_H_M, (uint8_t *)&t+1, 1);
	return t/64;
}

volatile  unsigned	sysTiming;
volatile  unsigned  sysTicks = 0;

__attribute__ ((section ("ccmram"))) void SysTick_Handler(void) {
        sysTicks++;
        if (sysTiming > 0) --sysTiming; 
}

void sysDelayMs(unsigned dly) {
	sysTiming = dly;
	while (sysTiming > 0) __wfi();

}

int main(void) {
    SysTick_Config((SystemCoreClock / 1000));
    RCC->AHBENR |= RCC_AHBENR_GPIOEEN | RCC_AHBENR_GPIOAEN;    
    GPIOE->MODER = (GPIOE->MODER&0xffff) | 0x55550000; // output mode for PE8-15
	GPIOA->MODER = (GPIOA->MODER&0xfffffffc)  ; // input mode for PA0

	MemsConfig();
	int16_t acc[3],mag[3],temp;
    int b = 0;
    int TH = 200*16;
    while(1) {
    	ReadAccelerometer(acc);
    	ReadMagnetometer(mag);
    	float heading = atan2(mag[1], mag[0]);
        heading = heading * 180 / 3.14159265359f;
        if (heading < 0) heading += 360;
    	temp=ReadTemperature();
    	printf("Acc: %d %d %d\n", acc[0]/16, acc[1]/16, acc[2]/16);
    	printf("Mag: %d %d %d %d %f\n", mag[0], mag[1], mag[2], temp, heading);
    	GPIOE->BSRR = b<<(8+16);
    	b = 0;
    	if(acc[1] < -TH) {
    		 if(acc[0] < -TH) b = 1<<4;
    		 	else if(acc[0] > TH) b = 1<<2;
    		 		else b = 1<<3;
    	} else {
    		if(acc[1] > TH) {
	    		 if(acc[0] < -TH) b = 1<<6;
	    		 	else if(acc[0] > TH) b = 1<<0;
    			 		else b = 1<<7;
    		} else {
    			if(acc[0] < -TH) b = 1<<5;
	    		 	else if(acc[0] > TH) b = 1<<1;
    		}
    	}
    	GPIOE->BSRR = b<<8;
    	while(GPIOA->IDR&1);
    	sysDelayMs(100);
    }
}