SPI3 for thermocouple works ONE time on stm32f4 discovery!?!
Posted: Tue Mar 11, 2014 1:39 pm
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);
}
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);
}