cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103C8 CMSIS SPI

DAlat.1
Associate II

I'm using SMT32F103C8 and I want to comunicate with MPU9250, I do not have any other SPI devices . Only MPU9250.

I set 72MHz for SMT32F103C8. here is my initialization and read/write functions.

void    SPI_init()
{ 
     RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
     RCC->APB2ENR |= RCC_APB2ENR_SPI1EN | RCC_APB2ENR_IOPAEN;
 
     GPIOA->CRL &= ~(GPIO_CRL_CNF5 | GPIO_CRL_MODE5 |
                GPIO_CRL_CNF6 | GPIO_CRL_MODE6 |
                GPIO_CRL_CNF7 | GPIO_CRL_MODE7);
 
      // setup SCK PA5 pin, Mode(11b), Cnf(10b)
     GPIOA->CRL |= (GPIO_CRL_MODE5 | GPIO_CRL_CNF5_1);
 
     // setup MOSI PA7 pin, Mode(11b), Cnf(10b)
     GPIOA->CRL |= (GPIO_CRL_MODE7 | GPIO_CRL_CNF7_1);
 
     // setup MISO PA6 pin, Mode(00b), Cnf(01b)
     GPIOA->CRL |= GPIO_CRL_CNF6_0;
 
     // setup SS
     GPIOA->CRL   |=  GPIO_CRL_MODE4;
     GPIOA->CRL   &= ~GPIO_CRL_CNF4;
 
     SPI1->CR1     = 0x0000;
     SPI1->CR2     = 0x0000;
 
     // set SPI 8bit
     SPI1->CR1 &= ~SPI_CR1_DFF;
 
     // set MSB first
     SPI1->CR1 &= ~SPI_CR1_LSBFIRST;
     SPI1->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI;
     SPI1->CR1 |= SPI_CR1_BR_0| SPI_CR1_BR_2;
     SPI1->CR1 |= SPI_CR1_MSTR; 
 
     SPI1->CR1 |= SPI_CR1_CPHA;
     SPI1->CR1 |= SPI_CR1_CPOL;
 
     // enable SPI
     SPI1->CR1 |= SPI_CR1_SPE;
}
 
 
uint8_t SPI_ReadWrite8(const uint8_t &data)
{
     while(!(SPI1 -> SR & SPI_SR_TXE));
 
     *(volatile uint8_t *)&SPI1->DR = data;
 
     while (!(SPI1 -> SR & SPI_SR_RXNE));
 
     while(SPI1->SR & SPI_SR_BSY){}
 
     return *(volatile uint8_t *)&SPI1-> DR;
}

So what is my problem. If I want to read some register , for example 0x75(WHO_AM_I) then

ReadWrite8(0x1B|0x80);   // 0x80 means that 7th bit is 1 i.e Read mode for MPU9250.
data = ReadWrite8(0x00); // send dummy byte

it gives me 0x71 value and everything is ok, BUT if I want to write into another register , then reading is not working. In other words, ONLY Reading works. For example:

// low
GPIOA->BSRR = GPIO_BSRR_BR4;
 
ReadWrite8(0x1B); // GYRSCOPE configure register
ReadWrite8(0x18); // set GYRO_FS_SEL bits
 
data = ReadWrite8(0x1B|0x80); // READ GYRSCOPE configure register
data = ReadWrite8(0x00);
 
// high
GPIOA->BSRR = GPIO_BSRR_BS4;

I'm getting 0x00. Please tell me what I'm doing wrong.?

3 REPLIES 3
Eleon BORLINI
ST Employee

Hi @DAlat.1​ , let me add microcontroller topics since this is an MCU-related question. You are able to read registers (did you try to read the DATAOUT registers and check if they are varying?) but you cannot write on them, right? You should check: first, while sending the write SPI command did you correctly set the MSB bit SPI of Address format (p. 33 of the sensor datasheet)?; secondly, if the register you are trying to write are RW or Read only?

Please note however that MPU9250 is an Invensense (not STMicroelectronics) part number, so that sensor could have issues. Regards

Yes I set MSB bit correctly, MSB | 0x80 i.e READ MODE as MPU9250 says. Second , it is read/write register, so I can write and read .

So you correctly set the R/W bit but you are not able to write in a register in SPI mode, right? And you try to write a register and you get back 00h? Which SPI mode did you set (and is 8 or 16 bits)? I don't have much knowledge on MPU9250 sensor (Invensense), but you should check the pattern analyzer waveforms and try to find any mistake... Regards