cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Broken Communication

ahmad2
Associate II
Posted on January 31, 2016 at 10:19

Hello,

I am currently evaluating the EVALSTPM34 Smart Metering IC so that a decision can be made about including it in a smart home management system.

Here is the STPM34 IC datasheet for reference:

https://my.st.com//public/STe2ecommunities/mcu/Lists/STM32Discovery/www.st.com/web/en/resource/technical/document/datasheet/DM00111861.pdf

check sections 8.5 and 8.6 (pages 65 to 71) for relevant SPI interface information

The design will include a dual core spear processor managing up to 5 STPM34 ICs over SPI using one core and uploading the data simultaneously to a gateway using the other core.

For practical purposes, the SPI interface is being tested using the STM32F407 Discovery board as I have multiples of those lying around for rapid prototyping.

Unfortunately, all attempts to get the SPI interface to produce rational data was in vain.

The only bright side is I am getting consistent, meaningless, but consistent results for every read address.

Major issues can be summarized quickly as follows:

1) The STPM34 tends to send incorrect CRC values for an arbitrary address reads

for example:

addresses 0X04, 0X06 result in an incorrect CRC value (always same data and same CRC value, there is no cross talk involved, data verified using scope)

address 0X08 always results in a CORRECT CRC value  (always same data and same CRC value, there is no cross talk involved,  data verified using scope)

CRC verification was performed using SPI CRC hardware unit of the STM32F047 and using Software function both producing the same results

2)Disabling the CRC byte requires writing a valid 5 Byte transaction 0X24, 0X24, 0X07, 0X00 followed by a CRC of 0X15

The STPM34 doesnt recognize this as a valid transaction and consequently the CRC byte cannot be disabled

3) Disregarding the CRC issues which should only render write operations impossible, all read operations do result in data, however even after a complete power shutdown and restart of the IC,

all data received have nothing to do with default values. This has been tested, with exact similar results on 2 different EVALSTPM34 boards

For your reference here is the initialization code for the SPI interface to verify correct configuration:

void init_SPI(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

SPI_InitTypeDef SPI_InitStruct;

RCC_AHB1PeriphClockCmd(SPI_GPIO_Clock , ENABLE);

RCC_AHB1PeriphClockCmd(SPI_CRC_Clock , ENABLE);

GPIO_InitStruct.GPIO_Pin = SPI_MOSI_Pin | SPI_MISO_Pin | SPI_SCL_Pin;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(SPI_Port, &GPIO_InitStruct);

GPIO_PinAFConfig(SPI_Port, SPI_MOSI_PinSource, SPI_AF);

GPIO_PinAFConfig(SPI_Port, SPI_MISO_PinSource, SPI_AF);

GPIO_PinAFConfig(SPI_Port, SPI_SCL_PinsSource , SPI_AF);

RCC_APB1PeriphClockCmd(SPI_BUS_Clock , ENABLE);

SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStruct.SPI_Mode = SPI_Mode_Master;    

SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;       

SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;     

SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;

SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;

SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStruct.SPI_CRCPolynomial = 263; //--->X8 + X2+X1+X0

SPI_Init(SPIController, &SPI_InitStruct);

SPI_CalculateCRC(SPIController, ENABLE);

SPI_Cmd(SPIController, ENABLE);

}

If possible, can anyone please provide an example of working code that would demonstrate a singe successful read - write - read (reflecting the data change during the write)operation using the std peripheral library for any of the stm32f4 series.

That way I could  be able to verify that the design is valid.

Thank you very much and please let me know if any further case material is required to solve this issue.

#stm32f407 #spi #stpm34 #error #discovery #crc #stm32f4
6 REPLIES 6
Posted on January 31, 2016 at 19:15

Really no support available here for the meter IC, you should perhaps contact a local FAE.

Can you provide some complete byte sequences for the DATA+CRC that you are seeing, and that are supposedly incorrect, and also correct ones if you have them.

I think the 8th bit of the CRC poly is implicit, you'd write this as 7 rather than 263

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ahmad2
Associate II
Posted on February 01, 2016 at 11:26

Thank you very much Clive for taking interest in this and helping me out, I knew you will like you always help out here.

Please find attached the data required.

Quick words on how the data was generated:

Communication works in Transactions. A single transaction is 4 Bytes + CRC.

Byte 1: Address of 32-Bit Register to read in the following transaction

Byte 2: Address of 16-Bit Register to write

Byte 3: LSB Data to write

Byte 4: MSB Data to write

CRC: CRC-8 of the above 4 Bytes (X8+X2+X1+X0)

Note : If Byte_2 = 0XFF, then no data needs to be written and Bytes 3 and 4 are disregarded

So to read any Address, Master Sends 2 Transactions

Address, 0XFF, 0XFF, 0XFF, CRC

followed by dummy transaction to generate clock

0XFF, 0XFF, 0XFF, 0XFF, 0XDE -->CRC-8 for (FF FF FF FF)

Here is the function to calculate the CRC values of 4 bytes

uint8_t CRC_8(uint8_t Read ,uint8_t Write, uint8_t LSB, uint8_t MSB)

{

const uint8_t Word [4] = {Read,Write,LSB,MSB};

const uint8_t *data =&Word[0];

unsigned crc = 0;

int i, j;

for (j = 4; j; j--, data++) {

crc ^= (*data << 8);

for(i = 8; i; i--) {

if (crc & 0x8000)

crc ^= (0x1070 << 3);

crc <<= 1;

}

}

return (uint8_t)(crc >> 8);

}

I am using software for CRC to be completely sure that the error is not due to misconfig and since the STM32F4 is not the target platform in mind I wont bother to correctly config the SPI CRC hardware unit since the implementation is rather strange.

Thank you very much and awaiting your feed back

________________

Attachments :

Data.txt : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HznF&d=%2Fa%2F0X0000000bQf%2FZdbyf87JlU74sAcmfcOGRO1PKG9e8.uZou745oo2pyI&asPdf=false
Posted on February 01, 2016 at 22:43

You have the receive phase set up incorrectly

---|row: 03|Address: 06|Sent: 06 FF FF FF + CRC: 7B|Received: 80 7C 1F 80 + CRC:03|ExpectedCRC:B1|Default: 00 00 00 00---|row: 04|Address: 08|Sent: 08 FF FF FF + CRC: BF|Received: 13 81 93 87 + CRC:FC|ExpectedCRC:7F|Default: 00 3F F8 00

If I shift the bits here left once the CRC math works

//  unsigned char test2[] = { 0x80,0x7C,0x1F,0x80 }; // 0x03

  unsigned char test2[] = { 0x00,0xF8,0x3F,0x00 }; // 0x07  (0x03 << 1) + 1

//  unsigned char test3[] = { 0x13,0x81,0x93,0x87 }; // 0xFC

  unsigned char test3[] = { 0x27,0x03,0x27,0x0F }; // 0xF9  (0xFC << 1) + 1

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ahmad2
Associate II
Posted on February 03, 2016 at 07:24

Thanks alot Clive !! Spot On as usual !! Its embarrassing that I messed up the config like this (happens when you copy and paste around alot) anyway its all working now no problem.

Since your familiar with the case now, you saw the data set size, now each read is about 60 bytes per channel. I will have 5 channels so MCU will collect 300 bytes per sample. Thats fine, however the real problem is that the sampling rate is 7.81KHz, which means from the total 5 channels I have 2.34Mega Bytes collected per second. Collecting the data using SPI shouldnt be a problem for a Spear or even an STM32F469. From that point the MCU must flush the data to a gateway (data concentrator). This data concentrator will be be running with full Linux OS and probably the application will be in Java for easy database integration and charting and reporting and what not ...

First problem:

I am not aware of any MCU offered by ST, or others for that matter, that has (2.34 X 2) MegaBytes of Ram that would allow me to hold the data and flush every second using DMA, which means that the gateway will be interrupted quite frequently (something tells me the JVM will crash from the amount of interrupts it will receive form the MCU)

Second what interface would you recommend for sending the data from MCU to Gateway, I havent tried configuring the MCU as SPI Slave before, USB device implementations on the STM32F4 series are very heavy ... no way can sample like that AND transfer that amount of data at same time

Let me know what you think

Thanks alot !!

Cheers!

Posted on February 03, 2016 at 20:21

Yes, well ONE second is an awful long time from the micro-processors perspective.

The STM32 could do a lot of management work on a 1KHz (1ms) ticker.

If you must hold this much data, then an SDRAM based F427/9 would be able to hold it. Otherwise you need to think of ways to decimate, or compress the data. That might be by having a ''Key Frame'' of data every second, followed by delta measurements identifying what has changed, and the ability to code different ranges. ie an 8-bit byte using 7-bits of data, and a bit flagging if there is another byte to follow.

You'd have to make a determination about how frequently the JVM could manage data (10Hz, 20Hz, or whatever), or have a very large buffer to hold data streaming from your micro.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Nilesh Patil
Associate
Posted on December 13, 2017 at 11:50

Hi, I used UART protocol and it works fine for me.

1) UART Mode - Transfer Direction Setting -> MSB First, Baud Rate - 9600

2) Eg-We are Supposed to Transmit '04_03_CD_AB' Frame

3) Reverse all bits of '04_03_CD_AB', It will be '20_C0_B3_D5'

4) Calculate CRC for '20_C0_B3_D5'. The CRC is 0x16

5) Now Reverse 0x16, It will be 0x68.

6) Now Transmit '04_03_CD_AB_68'

7) Send 1 more frame (dummy frame) to get read results.