AnsweredAssumed Answered

I2C TXDR doesnt send the data on SDA. STM32F3 Discovery.

Question asked by s.daniel on Jul 3, 2016
Latest reply on Jul 13, 2016 by ForumSTM32.ForumSTM3
Sample program to get accelerometer data.
01.#include "stm32f3xx.h"                  // Device header
02. 
03.void initSystem()
04.{
05.    // LSM303DLHC wiring: SCL to PB6, SDA to PB7.
06.    // Enable port B timing and set pins to alternate function mode. No pull-up/pull-down.
07.    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
08.    GPIOB->MODER |= GPIO_MODER_MODER6_1|GPIO_MODER_MODER7_1;
09.    GPIOB->OTYPER |= GPIO_OTYPER_OT_6|GPIO_OTYPER_OT_7;
10.    GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7 );
11.    GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 |GPIO_OSPEEDER_OSPEEDR7;
12.    // Select AF4 (0100=0x4) to toggle I2C_SCL function on pin PB6 and I2C_SDA on pin PB7.
13.    GPIOB->AFR[0] |= (0x4 << GPIO_AFRL_AFRL6_Pos);
14.    GPIOB->AFR[0] |= (0x4 << GPIO_AFRL_AFRL7_Pos);
15.     
16.    // Enable I2C peripheral clock.
17.    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
18.    // Set up TIMINGR (CubeMX).
19.    I2C1->TIMINGR = 0x00501E26;
20.    // Peripheral Enable.
21.  I2C1->CR1 |= I2C_CR1_PE;
22.}
23. 
24.// Variable to store the data.
25.uint32_t buffer[5];
26.// Counter.
27.uint32_t i = 5;
28. 
29.int main()
30.{
31.    initSystem();
32.     
33.    // Set up CR2 register for data writing.
34.    I2C1->CR2 |= (I2C_CR2_NBYTES & 1);      // 1 byte to transfer (NBYTES).
35.    I2C1->CR2 &= ~I2C_CR2_RD_WRN;       // Write. Set 0 in RD_WRN bit for transfer direction in master mode.
36.    I2C1->CR2 |= 0x19 << 1;                 // Accelerometer address (without r/w bit).
37.    I2C1->CR2 |= I2C_CR2_START;         // Set START bit. Master sends start condition, slave address and R/W bit.
38.    while ((I2C1->ISR & I2C_ISR_TC) == 0);  // Wait for transfer complete.
39.    I2C1->TXDR = 0x28;                  // Put data (inernal registry address) into TXDR.
40.    while ((I2C1->ISR & I2C_ISR_TXIS) == 0);    // Wait for TXDR is empty and ready for the new data.
41.     
42.    // Set up CR2 register for data reading and set START bit.
43.    I2C1->CR2 = I2C_CR2_AUTOEND | (I2C_CR2_NBYTES & 5) | I2C_CR2_RD_WRN | 0x19 << 1;
44.    I2C1->CR2 |= I2C_CR2_START;
45.    // Read the data.
46.    while (i-- > 0)
47.    {
48.        while((I2C1->ISR & I2C_ISR_RXNE) == 0);     // Wait for recieve data register is ready.
49.        buffer [i] = I2C1->RXDR;                    // Copy the data from recieve data register.
50.    }
51. 
52.    while(1)
53.    {
54.         
55.    }
56.}
The program execution can't pass line 40. The line 39 should transmit an internal register address of the accelerometer. The data remain in the TXDR.

How can I check if ACK from the slave device (LSM303DLHC) is recieved?

Outcomes