SPI3 for thermocouple works ONE time on stm32f4 discovery!?!

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

ljfischer
Posts: 19
Joined: Sat Jan 04, 2014 5:03 am

SPI3 for thermocouple works ONE time on stm32f4 discovery!?!

Post by ljfischer »

Using the stm32f4 discovery board, Im enabling all three SPI xfaces: SPI1=mems, SPI2&3 are connected to offboard max31855 thermocouple chips. I initially used SPI2 for one chip and got it working perfectly from sample code. Configure and start spi2 at init time. Never stop it. Just select and unselect it to read. I tried to do the same thing for SPI3, but found it only worked ONCE, and then would return 0s on the receive. I have found that it works consistently if I start/stop it every time I try to read it (I no longer start it at init time). The code to read both SPIs is the same. Obviously, the pins are different.

One clue(?): I found that I had to change the palmode for the SPI3 NSS pin - I had to remove the pushpull bit setting or I was getting bad data back.

Im trying to figure out how to debug this - stepping thru the spi_receive code didnt give me anything obvious. Any ideas? Init code is below.
Ugly debug oriented read code is below that (no flames about reading in single bytes - Im debugging :) )

static const SPIConfig spi2cfg = { NULL,
/* HW dependent part.*/
SPI_GPIO2, 12, 0 };

static const SPIConfig spi3cfg = { NULL,
/* HW dependent part.
* Slave select is on pin 15 of GPIOA
*/
SPI3_CS_GPIO, SPI3_CS_PIN, 0 };

spiStart(&SPID2, &spi2cfg);
palSetPad(SPI_GPIO2, SPI2_CS_PIN);
palSetPadMode(SPI_GPIO2, SPI2_CS_PIN, PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST); /* NSS. */
palSetPadMode(SPI_GPIO2, SPI2_SCK_PIN, PAL_MODE_ALTERNATE(5) |
PAL_STM32_OSPEED_HIGHEST); /* SCK. */
palSetPadMode(SPI_GPIO2, SPI2_MISO_PIN, PAL_MODE_ALTERNATE(5)); /* MISO. */
palSetPadMode(SPI_GPIO2, SPI2_MOSI_PIN, PAL_MODE_ALTERNATE(5) |
PAL_STM32_OSPEED_HIGHEST); /* MOSI. */

// init the thermocouple SPI driver. this is a max31855 chip
/*
* Initializes the SPI driver 3. The SPI3 signals are routed as follow:
* P - NSS. to pin 6 of 31855
* P - SCK. to pin 5 of 31855
* P - MISO. Master In Slave Out to pin 7 of 31855
* P - MOSI. - not connected to 31855
* red lead of thermocouple to pin 3 of 31855
* blue lead of thermocouple to pin 2 of 31855
*
*/
palSetPadMode(SPI3_CS_GPIO, SPI3_CS_PIN,
PAL_STM32_OSPEED_HIGHEST | PAL_MODE_ALTERNATE(6) ); /* NSS. */
palSetPad(SPI3_CS_GPIO, SPI3_CS_PIN);
palSetPadMode(SPI_GPIO3, SPI3_SCK_PIN, PAL_MODE_ALTERNATE(6) |
PAL_STM32_OSPEED_HIGHEST); /* SCK. */
palSetPadMode(SPI_GPIO3, SPI3_MISO_PIN, PAL_MODE_ALTERNATE(6)); /* MISO. */
palSetPadMode(SPI_GPIO3, SPI3_MOSI_PIN, PAL_MODE_ALTERNATE(6) |
PAL_STM32_OSPEED_HIGHEST); /* MOSI. */

// spiStart(&SPID3, &spi3cfg);

void readThermoCouple3(void)
{
static int8_t buf[4];
char c;
/* Read thermocouple data over SPI3.*/
spiStart(&SPID3, &spi3cfg);

spiSelect(&SPID3);


spiReceive(&SPID3, 1, buf); // 4th byte
c=buf[0];
headTemp=c; // 3rd byte of temp
headTemp=headTemp<<4;
// chprintf(chp,"%02X ",buf[0]); //delay


spiReceive(&SPID3, 1, buf); // 3rd byte
c=buf[0];
// chprintf(chp,"%02X ",buf[0]); //delay
spiFault=c;
spiFault&=1; // only want the low bit;
c=c>>4;
headTemp+=c;

spiReceive(&SPID3, 1, buf); // 2nd byte
c=buf[0];
spiIntTemp=c;
// chprintf(chp,"%02X ",buf[0]); //delay

spiReceive(&SPID3, 1, buf); // low byte
c=buf[0];
spiData=c;
spiData&=7;
// chprintf(chp,"%02X\r\n",buf[0]); //delay

spiUnselect(&SPID3);
spiStop(&SPID3);

}
fred
Posts: 20
Joined: Wed Feb 27, 2013 4:32 pm

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by fred »

Hi,

it would appear that you're running SPI3 at full clock (last value in spi3cfg is 0). Just glanced the MAX31855 datasheet and it seems to state max clock of 5MHz.

If I remember correctly, SPI3 runs on a half-clock compared to SPI1 & SPI2, so take that into account.

Edit:
check out viewtopic.php?f=2&t=933
You'd need
#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018)

and add that as your spi3cfg value:

static const SPIConfig spi3cfg = { NULL,
/* HW dependent part.
* Slave select is on pin 15 of GPIOA
*/
SPI3_CS_GPIO, SPI3_CS_PIN, SPI_BaudRatePrescaler_16 };
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by Giovanni »

Hi,

Note that the SPI driver uses the CS pin in GPIO mode so you have to program it as an output GPIO defaulted to state 1. It is possible this is related to your problem.

Giovanni
ljfischer
Posts: 19
Joined: Sat Jan 04, 2014 5:03 am

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by ljfischer »

Thanks for the fast replies. I tried adjusting the speed:
SPI3_CS_GPIO, SPI3_CS_PIN, SPI_BaudRatePrescaler_16};

and tried both output types - No good.
Any recommendations on *how* to debug this?
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by Giovanni »

Hi,

Usually a logic analyzer, even a cheap one, can help in those cases. The SPI driver itself has been used countless times, problems there are not very likely.

Giovanni
ljfischer
Posts: 19
Joined: Sat Jan 04, 2014 5:03 am

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by ljfischer »

Oh - I dont doubt the driver. Just trying to figure out how to attack this. I will single step with a scope - no LA...

Thanks
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by Giovanni »

The scope is not useful like a LA, consider getting a cheap one like the ZeroPlus I have at home.

Giovanni
ljfischer
Posts: 19
Joined: Sat Jan 04, 2014 5:03 am

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by ljfischer »

I dont *need* to solve this, as I have a workaround hack. But I dont like hacks, so Im thinking hard about the LA.

I want to make sure I didnt misinterpret your comment about programming the cs pin as GPIO. I tried programming the PALMODE for CS on SPI3 as both PAL_MODE_OUTPUT_PUSHPULL, and PAL_MODE_OUTPUT_OPENDRAIN. Is that what you meant?

Again - this works if I do an spistart/stop every time before/after I select/unselect (my hack). I also have the identical HW on SPI2, which works reliably. And I have swapped HW just to make sure. I also tried a few other, slower clk speeds for the SPI3. No Joy. So there is something silly Im missing.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by Giovanni »

The appropriate mode is PAL_MODE_OUTPUT_PUSHPULL.

Your hack should not be necessary, you are probably just hiding the real problem there.

Giovanni
fred
Posts: 20
Joined: Wed Feb 27, 2013 4:32 pm

Re: SPI3 for thermocouple works ONE time on stm32f4 discover

Post by fred »

Did you remap the SCK pin for SPI3?

From the ref manual page 856:

Since some SPI1 and SPI3/I2S3 pins may be mapped onto some pins used by the JTAG interface (SPI1_NSS onto JTDI, SPI3_NSS/I2S3_WS onto JTDI and SPI3_SCK/I2S3_CK onto JTDO), you may either:
– map SPI/I2S onto other pins
– disable the JTAG and use the SWD interface prior to configuring the pins listed as SPI I/Os (when debugging the application) or
– disable both JTAG/SWD interfaces (for standalone applications).
For more information on the configuration of the JTAG/SWD interface pins, please refer to Section 8.3.2: I/O pin multiplexer and mapping .


My solution is posted here, it's an AFIO remap, but you need to check the STM32F4 Ref to verify whether it's the same.
Post Reply