cancel
Showing results for 
Search instead for 
Did you mean: 

Manipulating MCU SPI Interface to Access a Nonstandard SPI

TOne.1
Associate II

HI There,

I want to access multiple SPI slaves at the same time.

They all share the same CLK , the same MOSI pin and the same CS.

Therefore, I wrote two code sections which basically should do the same.

They kind of work, but they both have the same Problem. SPI1 the Master works fine. The Slave on SPI2 Only delivers 1111 1111 1111 1111 only 1s. Dos anybody knows in detail what's wrong?

Code section One according to https://www.analog.com/media/en/analog-dialogue/raqs/raq-issue-172.pdf

__HAL_SPI_ENABLE(&hspi1);

__HAL_SPI_ENABLE(&hspi2);

int SPI4_CNVNum = 1;

int SPI4_CNVCount = 0;

while (SPI4_CNVCount < SPI4_CNVNum)

{

 int SPI4_WordCount = 0;

 int SPI4_CNVWordNum = size;

 int Buf_Idn = 0;

 HAL_GPIO_WritePin(csMuxAdc_GPIO_Port, csMuxAdc_Pin, GPIO_PIN_RESET);

 //AD7606B conversion start

 // wait for conversion finish, BUSY goes from high to low. Polling or interrupt mode

 while (hspi1.State == HAL_SPI_STATE_BUSY) {;}

 while (SPI4_WordCount < SPI4_CNVWordNum)// code number to read per conversion cycle

    {

    while ((__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_TXE)) != SET);

    *(__IO uint8_t *)&hspi1.Instance->DR = buf1[Buf_Idn];//Transmit Data from Master

    while (__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_RXNE) != SET);

    //delayxus(1);// need half SCLK cycle delay for slow SCLK rate < 10MHz

    buf2[Buf_Idn] = *(__IO uint16_t *)&hspi1.Instance->DR;//Receive Data from master

    while (__HAL_SPI_GET_FLAG(&hspi2, SPI_FLAG_RXNE) != SET);

    buf4[Buf_Idn] = *(__IO uint16_t *)&hspi2.Instance->DR;//Receive Data from Slave

    Buf_Idn++;

    SPI4_WordCount ++;

    }

 HAL_GPIO_WritePin(csMuxAdc_GPIO_Port, csMuxAdc_Pin, GPIO_PIN_SET);

 SPI4_CNVCount++;

 SPI4_WordCount = 0;

}//while (SPI4_CNVCount < SPI4_CNVNum)

__HAL_SPI_DISABLE(&hspi1);

__HAL_SPI_DISABLE(&hspi2);

buf3 = 0;

buf3 |= buf2[2];

buf3 <<= 8;

buf3 |= buf2[3];

buf3 = 0b0000111111111111 & buf3;

Vin_1 = buf3 * (5 / pow(2,12));

memset(buf2, 0, sizeof(buf2));

buf3 = 0;

buf3 |= buf4[2];

buf3 <<= 8;

buf3 |= buf4[3];

buf3 = 0b0000111111111111 & buf3;

Vin_2 = buf3 * (5 / pow(2,12));

memset(buf4, 0, sizeof(buf2));

8 REPLIES 8
TOne.1
Associate II

I also analyzed the Physical SPI interface this seems to work Fine.

TOne.1
Associate II

0693W000005BJiEQAW.png

TDK
Guru

> The Slave on SPI2 Only delivers 1111 1111 1111 1111 only 1s.

From your last plot, it doesn't appear that either interface is sending only 1s. I see 0s and 1s in both MOSI and both MISO signals. Can you clarify what the problem actually is?

If you feel a post has answered your question, please click "Accept as Solution".
TOne.1
Associate II

I want to measure a voltage with ADC. The Last 12 Bits in the Plot are the measured voltage. So both ADC get the same Analog reference Voltage and Test voltage. So the communication should give the same values back. At least almost noise in the last bits is ok. but at the moment the SPI1(Master) Interface delivers the right voltage 1000 0001 1010 which is 2.531V. The SPI2 should deliver the same sequence and in the plot the IC does deliver the same sequence of bits. But when I run my code the " buf4[Buf_Idn] = *(__IO uint16_t *)&hspi2.Instance->DR;" call delivers 1111 1111 1111 so where does this difference come from.

Bad MISO path/solder joint on the pin? Measure directly on pin.

Incorrectly initialized MISO in GPIO? Sounds unlikely as that typically results in stuck at 0, but to be sure, read it and check the relevant GPIO registers.

JW

TOne.1
Associate II

I am measuring directly on the MISO pin of the MCU on both Channels (SPI1 and SPI2).

My hardware Configuration looks like This:

 hspi1.Instance = SPI1;

 hspi1.Init.Mode = SPI_MODE_MASTER;

 hspi1.Init.Direction = SPI_DIRECTION_2LINES;

 hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

 hspi1.Init.NSS = SPI_NSS_SOFT;

 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;

 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

 hspi1.Init.CRCPolynomial = 10;

 if (HAL_SPI_Init(&hspi1) != HAL_OK)

 {

   Error_Handler();

 }

 hspi2.Instance = SPI2;

 hspi2.Init.Mode = SPI_MODE_SLAVE;

 hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;

 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;

 hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;

 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;

 hspi2.Init.NSS = SPI_NSS_HARD_INPUT;

 hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;

 hspi2.Init.TIMode = SPI_TIMODE_DISABLE;

 hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

 hspi2.Init.CRCPolynomial = 10;

 if (HAL_SPI_Init(&hspi2) != HAL_OK)

 {

   Error_Handler();

 }

TDK
Guru

>  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

> buf4[Buf_Idn] = *(__IO uint16_t *)&hspi2.Instance->DR;

If you're using 8 data bits, shouldn't this be reading 8 bits instead of 16?

buf4[Buf_Idn] = *(__IO uint8_t *)&hspi2.Instance->DR;

You should be initializing hspi2.Init.BaudRatePrescaler to SPI_BAUDRATEPRESCALER_16 or less, but you're not.

Could also be incorrect GPIO settings, as noted.

If you feel a post has answered your question, please click "Accept as Solution".
TOne.1
Associate II

I Found My problem I swapped MISO and MOSI at the SPI2 Port because it is a slave but it should appear as a Master in this Communication.