I can't get the SPI on my STM32f3 discovery board (Datasheet) to work with gyroscope sensor (I3G4250D) on the register level. I know I'm sending data since I'm in full duplex and receiving dummy bytes from sensor using 16 bit data packing but when I try to receive using 8 bit access to DR register I get inconsistent values from sensor, sometimes returning one byte 0xff and other times returning 2 bytes 0xffff (at least I think that's what's happening) but no real values from from the sensor register I want to read. I think this has to do with automatic packing of STM32 SPI on my chip but I think I am addressing that by accessing DR register with uint8_t* but it doesn't seem to work. I also want to ask that when I compare the SPI protocol on sensor (datasheet page 24) and STM32 datasheet (page 729) I infer that both CPOL (clock polarity) and CPHA (clock phase) bits in STM32 SPI should be set but I seem to be able to at least send data with or without these bits set...
Here is my SPI Initialization function which includes trying to read bytes at the end of it and a write a byte to sensor register function:
void SPI_Init() {
/* Peripheral Clock Enable */
RCC->AHBENR |= RCC_AHBENR_GPIOEEN|RCC_AHBENR_GPIOAEN;
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
/* GPIO Configuration */
GPIOA->MODER |= GPIO_MODER_MODER5_1|GPIO_MODER_MODER6_1|GPIO_MODER_MODER7_1; //Alternate function
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5|GPIO_OSPEEDER_OSPEEDR6|GPIO_OSPEEDER_OSPEEDR7; //High speed
GPIOA->AFR[0] |= 0x00500000|0x05000000|0x50000000; //AF for SCK,MISO,MOSI
GPIOE->MODER |= GPIO_MODER_MODER3_0; //Port E for NSS Pin
GPIOE->MODER |= GPIO_MODER_MODER3_0;
/* SPI Configuration */
SPI1->CR2 |= SPI_CR2_FRXTH|SPI_CR2_RXDMAEN; //Enable DMA but DMA is not used
// not sure if I need this?|SPI_CR1_CPOL|SPI_CR1_CPHA;
SPI1->CR1 |= SPI_CR1_BR_1|SPI_CR1_SSM|SPI_CR1_SSI|SPI_CR1_MSTR|SPI_CR1_SPE; //big endian, SPI@6MH, since using software set SPI_CR1_SSI to high for master mode
/* Slave Device Initialization */
SPI_WriteByte(CTRL_REG1_G,0x9f);
SPI_WriteByte(CTRL_REG4_G,0x10);
SPI_WriteByte(CTRL_REG5_G,0x10);
//receive test
uint8_t test =0xff;
uint8_t* spiDrPtr = (__IO uint8_t*)&SPI1->DR;
*spiDrPtr = 0x80|CTRL_REG1_G;
while(!(SPI1->SR & SPI_SR_TXE)){}
//SPI1->CR2 &= ~(SPI_CR2_FRXTH); //this is done in HAL not sure why though
*spiDrPtr = test; //Send dummy
while(!(SPI1->SR & SPI_SR_RXNE)){}
test = *spiDrPtr;
}
static void SPI_WriteByte(uint8_t regAdd, uint8_t data) {
uint8_t arr[2] = {regAdd,data}; //16 bit data packing
SPI1->DR = *((uint16_t*)arr);
}
Any suggestions?