cancel
Showing results for 
Search instead for 
Did you mean: 

SPI on STM32F4 Discovery and STM32F429

linhnd89
Associate II
Posted on September 10, 2015 at 12:45

Please help me for this situation.

I am using both STM32F4 DISCOVERY and CORE STM32F429 board from

http://waveshare.com/

I use SPI standard driver to read ADS1292 chip from TI but I have a tricky problem.

SPI2 was used to read data from ADS1292, the code works fine with STM32F4 DISCOVERY but when I change to STM32F429 it doesn't work.

I already checked all registers of SPI2, they were same on both boards.

In the code, I also used SPI1 to read data from another chip (AFE4400) and it works fine on STM32F4 Discovery and stm32f429.

Could you help me please!

Thanks in advance
9 REPLIES 9
Posted on September 10, 2015 at 13:06

>

it doesn't work.

Please elaborate.

> I already checked all registers of SPI2, they were same on both boards.

Did you check the related GPIO registers? And clock to SPI2 in RCC?

JW

linhnd89
Associate II
Posted on September 10, 2015 at 13:43

Thank you Jan,

''It doesn't work'' means the value that I received from ADS1292 is all 0.

The value of CR1 register of SPI2 are all 0x0365 in both F4Discovery and F429.

And all GPIOs are the same and I also used exactly same code (main.c file) with both F4Discovery and F429. The code worked well with F4 Discovery.

Posted on September 10, 2015 at 14:15

Observe the SPI pins by an oscilloscope. Do you see the clocks? And do you see the data?

JW
Posted on September 10, 2015 at 18:40

''It doesn't work'' means the value that I received from ADS1292 is all 0.

Ok, so let's look critically at the GPIO configuration, the pins used, the clocks enabled, and the correct AF mux selected.

Show the code that initialized the SPI, and talks to the chip, that's not working. It saves a whole lot of wild guessing. Assume we have ZERO insight into YOUR design.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on September 10, 2015 at 22:38

> Ok, so let's look critically at the GPIO configuration, the pins used, the clocks enabled, and the correct AF mux selected.

Ah...

>> And all GPIOs are the same and I also used exactly same code (main.c file) with both F4Discovery and F429.

I did not check, but Clive is right - while mapping of peripherals to pins will be mostly the same to achieve the proclaimed pin compatibility, the mapping of peripherals onto AFs may be different between the 40x and 42x/43x.

JW

linhnd89
Associate II
Posted on September 11, 2015 at 04:27

Thank you clive1 and Jan. Here is SPI initialized code:

void
SPI_Config()
{
GPIO_InitTypeDef GPIO_InitTypeDefStruct;
SPI_InitTypeDef SPI_InitTypeDefStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE , ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC , ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_6;
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitTypeDefStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitTypeDefStruct);
GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitTypeDefStruct);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_SPI2);
GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7 |GPIO_Pin_8|GPIO_Pin_9; 
// AFE: CS | RESET_Z | PWD_Z
// ADS: START| RESET_Z
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOE, &GPIO_InitTypeDefStruct);
GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_3; 
//AFE_DRDY
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOE, &GPIO_InitTypeDefStruct);
GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_4; 
//ADS_DRDY
GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOE, &GPIO_InitTypeDefStruct);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_InitTypeDefStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitTypeDefStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitTypeDefStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitTypeDefStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitTypeDefStruct.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitTypeDefStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_InitTypeDefStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI1, &SPI_InitTypeDefStruct);
SPI_InitTypeDefStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitTypeDefStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitTypeDefStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitTypeDefStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitTypeDefStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitTypeDefStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
SPI_InitTypeDefStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI2, &SPI_InitTypeDefStruct);
SPI_Cmd(SPI1, ENABLE);
SPI_Cmd(SPI2, ENABLE);
GPIO_SetBits(GPIOE, GPIO_Pin_6); 
//AFE_CS= 1
GPIO_SetBits(GPIOE, GPIO_Pin_7); 
//AFE_RESET_Z = 1
GPIO_SetBits(GPIOE, GPIO_Pin_5); 
//AFE_PWD_Z = 1
GPIO_SetBits(GPIOE, GPIO_Pin_8); 
//ADS START= 1
GPIO_SetBits(GPIOE, GPIO_Pin_9); 
//ADS RESET= 1

and here is function to read ADS1292:

/**
* @brief Check SPI busy status
*/
#define SPI_IS_BUSY(SPIx) (((SPIx)->SR & (SPI_SR_TXE | SPI_SR_RXNE)) == 0 || ((SPIx)->SR & SPI_SR_BSY))
/**
* @brief SPI wait till end
*/
#define SPI_WAIT(SPIx) while (SPI_IS_BUSY(SPIx))
/**
* @brief Checks if SPI is enabled
*/
#define SPI_CHECK_ENABLED(SPIx) if (!((SPIx)->CR1 & SPI_CR1_SPE)) {return;}
void
TM_SPI_SendMulti(SPI_TypeDef* SPIx, uint8_t* dataOut, uint8_t* dataIn, uint32_t count) {
uint32_t i;
/* Check if SPI is enabled */
SPI_CHECK_ENABLED(SPIx);
/* Wait for previous transmissions to complete if DMA TX enabled for SPI */
SPI_WAIT(SPIx);
for
(i = 0; i < count; i++) {
/* Fill output buffer with data */
SPIx->DR = dataOut[i];
/* Wait for SPI to end everything */
SPI_WAIT(SPIx);
/* Read data register */
dataIn[i] = SPIx->DR;
}
}
void
TM_SPI_WriteMulti(SPI_TypeDef* SPIx, uint8_t* dataOut, uint32_t count) {
uint32_t i; 
/* Check if SPI is enabled */
SPI_CHECK_ENABLED(SPIx);
/* Wait for previous transmissions to complete if DMA TX enabled for SPI */
SPI_WAIT(SPIx);
for
(i = 0; i < count; i++) {
/* Fill output buffer with data */
SPIx->DR = dataOut[i];
/* Wait for SPI to end everything */
SPI_WAIT(SPIx);
/* Read data register */
(
void
)SPIx->DR;
}
}
void
ADS_CmdWrite(uint8_t opcmd) 
//Write command to ADS1292
{
uint8_t opbuf;
opbuf = opcmd;
TM_SPI_WriteMulti(SPI2, &opbuf, 1);
}
void
EEGRegDataWrite(uint8_t startindex, uint8_t wrdata) 
//Write data to register in ADS1292
{
uint8_t wbuf[3];
wbuf[0]= startindex | 0x40; 
//write
wbuf[1]= 0x00;
wbuf[2] = wrdata;
TM_SPI_WriteMulti(SPI2, wbuf, 3);
}
uint8_t EEGRegDataRead(uint8_t startIndex) 
//Read data from register in ADS1292
{
uint8_t wbuf[2];
uint8_t rdbuf;
wbuf[0]= startIndex | 0x20; 
//write
wbuf[1]= 0x00;
TM_SPI_WriteMulti(SPI2, wbuf, 2);
TM_SPI_ReadMulti(SPI2, &rdbuf,0xFF, 1);
return
rdbuf;
}

and I put it in the main function:

int
main(
void
){
SystemInit();
RCC_HSEConfig(RCC_HSE_ON);
//Wait for clock to stabilize
while
(!RCC_WaitForHSEStartUp());
SPI_Config();
//Reset procedure for ADS1299
GPIO_SetBits(GPIOE, GPIO_Pin_9; 
//RESET pin = 1 (no reset)
GPIO_ResetBits(GPIOE, GPIO_Pin_9); 
//RESET pin = 0 (reset)
//delay
for
(count =0; count < 1680000; count++);
GPIO_SetBits(GPIOE, GPIO_Pin_9); 
//ADS_1292 RESET pin goes High
//delay for stability 
for
(count =0; count < 16800000; count++);
ADS_CmdWrite(EEG_SDATAC_OPC); 
//write STOP command to ADS1292
test = EEGRegDataRead(0x00); 
//Test reading ID register of ADS1292
EEGRegDataWrite(EEG_WREG_CONFIG2,0xA0); 
//Write value 0xA0 to EEG_WREG_CONFIG2 register
test_1 = EEGRegDataRead(EEG_WREG_CONFIG2); 
//Test reading EEG_WREG_CONFIG2 register of ADS1292
}

and in the project I configured STM32F429 to get 168 Mhz clock. This main function is run on bothF4 Discovery and F429 board. The tricky thing is that SPI2 works on F4 Discovery (return right value for registers) but not in F429 board.I also use SPI1 to communicate with another IC and it works well on both F4 Discovery and F4 Thank you so much
Posted on September 11, 2015 at 09:17

Observe the SPI pins by an oscilloscope. Do you see the clocks? And do you see the data?

JW

0690X0000060MnJQAU.gif

rumlyen
Associate II
Posted on December 26, 2015 at 17:31

Hello Nguyen,

Have you succeeded at the end with the ADS1292 ? I have the ADS1292R to interface. I request to know how have you solved the issue.

Thank you.

dechawat
Associate II
Posted on December 27, 2015 at 13:44

Have you tried to change the another SPI2 and ADS control pin?

On Core429i board, PC2 is used for USB P2 and PE7, PE8 and PE9 is used for external ram.