cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7: SPI problem with SPI_RXDR

Fabian3
Associate

I am using the STM32H725RE (68-pin package).
My goal is to have full duplex SPI communication with a 16 bit shift register using the stm32h7 as the SPI master (with no dma controller).
I am using the SPI3 with the following pin (12MHz)
PA15 (SPI3_nCS), PC10 (SPI3_SCK), PC11 (SPI3_MISO) and PC12 (SPI3_MOSI).

With the following code it is already possible to write the data successfully and the shift register also sends the data correctly to the MISO wire. (as you can see in the logic analyser screenshot)

But I have problems reading the receive buffer, the flags are set correctly (RXP is set correctly), but when I read the RXDR I only read the data 0xFFFF, although other data should be read as shown in the logic analyser screenshot?

Fabian3_1-1738063907629.png

#include <stm32h7xx.h>
#include "stm32h725xx.h"
 
 
#define pSpiSR SPI3
 
static void initSPI3() {
 
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // SPI1 Peripherie Enable (FLASH)
// PA15 (SPI3_nCS)
GPIOA->MODER &= ~(GPIO_MODER_MODE15);
GPIOA->MODER |= (GPIO_MODER_MODE15_1); // Alternate function mode
GPIOA->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED15_Pos); // very high speed
GPIOA->OTYPER &= ~GPIO_OTYPER_OT15; // Push-pull
GPIOA->AFR[1] |=  ((6 & 0x000F) << ((15-8)*4)); // set Alternate function 6;
// PC10 (SPI3_SCK), PC11 (SPI3_MISO), PC12 (SPI3_MOSI)
GPIOC->MODER &= ~(GPIO_MODER_MODE10 | GPIO_MODER_MODE11 | GPIO_MODER_MODE12);
GPIOC->MODER |= (GPIO_MODER_MODE10_1 | GPIO_MODER_MODE11_1 | GPIO_MODER_MODE12_1); // Alternate function mode
GPIOC->OSPEEDR |= ((3 << GPIO_OSPEEDR_OSPEED10_Pos) | (3 << GPIO_OSPEEDR_OSPEED11_Pos) | (3 << GPIO_OSPEEDR_OSPEED12_Pos)); // very high speed
GPIOC->OTYPER &= ~(GPIO_OTYPER_OT10 | GPIO_OTYPER_OT11 | GPIO_OTYPER_OT12); // Push-pull
GPIOC->AFR[1] |=  ((6 & 0x000F) << ((10-8)*4)); // set   Alternate function 6;
GPIOC->AFR[1] |=  ((6 & 0x000F) << ((11-8)*4)); // set   Alternate function 6;
GPIOC->AFR[1] |=  ((6 & 0x000F) << ((12-8)*4)); // set   Alternate function 6;
    // 1. deactivate the SPI
    SPI3->CR1 = 0;       // SPI deactivate
    SPI3->CR2 = 0x0;
    SPI3->I2SCFGR = 0;   // I2S-mode deactivate
 
    // 2. configuration of CFG1
    SPI3->CFG1 = SPI_CFG1_MBR_1 | (0x0F << SPI_CFG1_DSIZE_Pos) //;               //frame size 16bit
    | (0x00 << SPI_CFG1_FTHLV_Pos);
 
    // 3. configuration of CFG2
    SPI3->CFG2 = SPI_CFG2_MASTER               // master-mode
               | SPI_CFG2_AFCNTR               // automatic chip-select
               | SPI_CFG2_SSOE;                // SS-Pin activate
 
    // 4. deactivate interupts
    SPI3->IER = 0;
}
 
static void spiStart(SPI_TypeDef *pSpi)
{
pSpi->CR2 = 0x1;
pSpi->CR1 |= SPI_CR1_SPE; //Enable SPI
pSpi->CR1 |= SPI_CR1_SPE | SPI_CR1_CSTART; //Master transfer start
 
}
 
void static spiStop(SPI_TypeDef *pSpi)
{
pSpi->CR1 = 0; //master transfer stop
pSpi->IFCR = 0xFFFFFFFF;
}
 
static unsigned long spiTrns16(SPI_TypeDef *pSpi, uint16_t dataOut) {
    uint16_t dataIn;
    volatile uint16_t *pHw = (volatile uint16_t *)&pSpi->TXDR;
    volatile uint16_t *pRxHw = (volatile uint16_t *)&pSpi->RXDR;
 
    // clear Read Register
    while (pSpi->SR & SPI_SR_RXP) {
        (void)*pRxHw;  
    }
 
    // send data
    *pHw = dataOut;
 
    // wait until data are received (RXP-Flag)
    while (!(pSpi->SR & SPI_SR_RXP));
    
    pSpi->IFCR = 0xFFFFFFFF; //reset interrupt flags
    
    // read data
    dataIn = *pRxHw;
 
    return dataIn;
}
 
 
static uint16_t spiShiftRegister(uint16_t sendSR){
uint16_t readSR;
 
spiStart(pSpiSR);
readSR = spiTrns16(pSpiSR, sendSR);
spiStop(pSpiSR);
 
return(readSR);
}
// mainFunction
int main(void) {
    // SPI3 init
    initSPI3();
 
    // Variablen für den SPI-Datenaustausch
    uint16_t dataToSend = 0x0AAA;
    uint16_t receivedData;
 
    while (1) {
        receivedData = spiShiftRegister(pSpiSR, dataToSend)
    }
 
    return 0;
}

 

2 REPLIES 2
Uwe Bonnes
Principal III

Did you check with a scope that RX really is available at the pin? Did you check for other hardware errors/misshaps?

I am using a logic analyser and I have seen that data is also being sent on the miso line, see screenshot in the main post.