Martin Johnson / accelerometer_test

Dependencies:   STM32F3-Discovery-minimal

Revision:
1:c92d1851a036
Parent:
0:ed38888a34c2
Child:
2:742027e49b6f
--- a/main.c	Sun May 22 23:34:31 2016 +0000
+++ b/main.c	Wed May 02 01:56:42 2018 +0000
@@ -1,50 +1,83 @@
 
 #include <stm32f3_discovery.h>
-#include "stm32f3_discovery_lsm303dlhc.h"
+#include <stm32f3_discovery_lsm303dlhc.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 AccelerometerConfig(void)
-{
-  LSM303DLHCMag_InitTypeDef LSM303DLHC_InitStructure;
-  LSM303DLHCAcc_InitTypeDef LSM303DLHCAcc_InitStructure;
-  LSM303DLHCAcc_FilterConfigTypeDef LSM303DLHCFilter_InitStructure;
-  
-  /* Configure MEMS magnetometer main parameters: temp, working mode, full Scale and Data rate */
-  LSM303DLHC_InitStructure.Temperature_Sensor = LSM303DLHC_TEMPSENSOR_DISABLE;
-  LSM303DLHC_InitStructure.MagOutput_DataRate =LSM303DLHC_ODR_30_HZ ;
-  LSM303DLHC_InitStructure.MagFull_Scale = LSM303DLHC_FS_8_1_GA;
-  LSM303DLHC_InitStructure.Working_Mode = LSM303DLHC_CONTINUOS_CONVERSION;
-  LSM303DLHC_MagInit(&LSM303DLHC_InitStructure);
-  
-   /* Fill the accelerometer structure */
-  LSM303DLHCAcc_InitStructure.Power_Mode = LSM303DLHC_NORMAL_MODE;
-  LSM303DLHCAcc_InitStructure.AccOutput_DataRate = LSM303DLHC_ODR_50_HZ;
-  LSM303DLHCAcc_InitStructure.Axes_Enable= LSM303DLHC_AXES_ENABLE;
-  LSM303DLHCAcc_InitStructure.AccFull_Scale = LSM303DLHC_FULLSCALE_2G;
-  LSM303DLHCAcc_InitStructure.BlockData_Update = LSM303DLHC_BlockUpdate_Continous;
-  LSM303DLHCAcc_InitStructure.Endianness=LSM303DLHC_BLE_LSB;
-  LSM303DLHCAcc_InitStructure.High_Resolution=LSM303DLHC_HR_ENABLE;
-  /* Configure the accelerometer main parameters */
-  LSM303DLHC_AccInit(&LSM303DLHCAcc_InitStructure);
-  
-  /* Fill the accelerometer LPF structure */
-  LSM303DLHCFilter_InitStructure.HighPassFilter_Mode_Selection =LSM303DLHC_HPM_NORMAL_MODE;
-  LSM303DLHCFilter_InitStructure.HighPassFilter_CutOff_Frequency = LSM303DLHC_HPFCF_16;
-  LSM303DLHCFilter_InitStructure.HighPassFilter_AOI1 = LSM303DLHC_HPF_AOI1_DISABLE;
-  LSM303DLHCFilter_InitStructure.HighPassFilter_AOI2 = LSM303DLHC_HPF_AOI2_DISABLE;
+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;
+}
 
-  /* Configure the accelerometer LPF main parameters */
-  LSM303DLHC_AccFilterConfig(&LSM303DLHCFilter_InitStructure);
+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 ReadAccelerometer(int16_t * data)
+void i2cInit() {
+  RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
+  // configure GPIOPB6 and 7
+  RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
+  GPIOB->AFR[0] = (GPIOC->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)
 {
-  uint8_t buffer[6];
-  
-  LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, buffer, 6);
-  
-  for(int i=0; i<3; i++) {
-	data[i]=((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i])/16;
-  }
+  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, 6);
+	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_H_M, (uint8_t *)data+1, 6);
+	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_L_M, (uint8_t *)data+2, 6);
+	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_H_M, (uint8_t *)data+3, 6);
+	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_L_M, (uint8_t *)data+4, 6);
+	i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_H_M, (uint8_t *)data+5, 6);
+}
+
+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;
@@ -64,17 +97,21 @@
 int main(void) {
     
     SysTick_Config((SystemCoreClock / 1000));
-    RCC->AHBENR |= RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOA;    
+    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
 
-	AccelerometerConfig();
-	int16_t acc[3];
+	MemsConfig();
+	int16_t acc[3],mag[3],temp;
     int b=0;
-    int TH=200;
+    int TH=200*16;
     while(1) {
     	
     	ReadAccelerometer(acc);
+    	ReadMagnetometer(mag);
+    	temp=ReadTemperature();
+    	printf("Acc: %d %d %d\n",acc[0]/16,acc[1]/16,acc[2]/16);
+    	printf("Mag: %d %d %d %d\n",mag[0],mag[1],mag[2],temp);
     	GPIOE->BSRR=b<<(8+16);
     	b=0;
     	if(acc[1]<-TH) {