2019-01-24 01:25 AM
My code to write directly to registers for I2C communication between Lis3dh accelerometer and STM32L053R8T6 is not working. Only CMSIS drivers are used. Could you give some suggestions. [I am looking to learn the basics of STM32 and have tried HAL drivers already]
#include "stm32l0xx.h"
#include "stdio.h"
/* accelerometer definitions*/
#define lis3dh_address 0x19 //0x18 if sd0 connected to ground //0x19 if sd0 connected to power supply
#define who_am_i 0x0F
/*STM32 definitions*/
#define buffersize 1
uint32_t I2C2_RX_Data[buffersize];
uint8_t I2C_Read_Reg(uint8_t Device,uint8_t Register);
int main(void)
{
//LSI clock
RCC->CSR = RCC_CSR_LSION;
while((RCC->CSR & RCC_CSR_LSIRDY)!=RCC_CSR_LSIRDY); //check the stablity of the low speed oscillator
RCC->IOPENR |= RCC_IOPENR_GPIOBEN; //IO port B clock enable bit This bit is set and cleared by software.
/* (1) PU for I2C signals */
/* (2) open drain for I2C signals */
/* (3) AF5 for I2C signals */
/* (4) Select AF mode (10) on PB13 and PB14 */
GPIOB->PUPDR |= (GPIOB->PUPDR & ~(GPIO_PUPDR_PUPD13 | GPIO_PUPDR_PUPD14)) \
| (GPIO_PUPDR_PUPD13_0 | GPIO_PUPDR_PUPD14_0); /* (1) */
GPIOB->OTYPER |= GPIO_OTYPER_OT_13 | GPIO_OTYPER_OT_14; /* (2) */
GPIOB->OSPEEDR |= 2<<26 | 2<<28;
GPIOB->AFR[1] |= 5<<20 | 5<<24;
GPIOB->MODER |= (GPIOB->MODER & ~(GPIO_MODER_MODE13 | GPIO_MODER_MODE14)) | (GPIO_MODER_MODE13_1 | GPIO_MODER_MODE14_1);
I2C_Read_Reg(lis3dh_address,who_am_i);
// printf("receive interrupt %d, receive output",a);
}
uint8_t I2C_Read_Reg(uint8_t Device,uint8_t Register)
{
/*3. I2C configured in master mode to transmit*/
I2C2->CR2|= (0x2FF67FF & 0x00); //Reset CR2 Register
I2C2->TIMINGR |= 0x10420F13;
RCC->APB1ENR|=RCC_APB1ENR_I2C2EN;
I2C2->CR1 |= I2C_CR1_PE;
while((I2C2->ISR & I2C_ISR_BUSY) == I2C_ISR_BUSY){};
I2C2->CR2 |= ~I2C_CR2_ADD10|(Device<<1)|~I2C_CR2_RD_WRN|(1<<16);
I2C2->CR2 |= I2C_CR2_START;
NVIC_SetPriority(I2C2_IRQn, 0); // Set priority for I2C2_IRQn
NVIC_EnableIRQ(I2C2_IRQn); // Enable I2C2_IRQn
if((I2C2->ISR & I2C_ISR_TXE) == (I2C_ISR_TXE))
{
I2C2->TXDR = Register;
I2C2->CR2 |= I2C_CR2_START;
}
//read mode for Device
I2C2->CR1 |=I2C_CR1_PE|I2C_CR1_RXIE;
I2C2->CR2 |= (0x2FF67FF)|(Device<<1|(1<<16)|I2C_CR2_RD_WRN);
while((I2C2->ISR & I2C_ISR_BUSY) != I2C_ISR_BUSY){};
I2C2->CR2 |= ~I2C_CR2_START;
while((I2C2->ISR & I2C_ISR_RXNE) != I2C_ISR_RXNE){};
{
I2C2_RX_Data[buffersize-1]=I2C2->RXDR;
}
return(*I2C2_RX_Data);
}
2019-01-24 10:05 AM
Plan B: Use my shared SW GPIO I2C Master example.
2019-01-25 12:39 AM
Well sounds like a good plan ! Thank you. But I have the i2c working using HAL and LL functions. I want to program it register wise, to get more understanding and small code.