3 years, 1 month ago.

SPI dialog with AS5047D

Hi all.

Here is my problem : I try to communicate using SPI between a Nucleo F446RE and a AS5047D (absolute position encoder).

It works pretty well with ABI signals but I try to use SPI for test purpose (I must check that SPI is fully functionnal on the component).

the AS5047D is configured for a 16bits Big Endian Mode 1 communication. But I don't see how to set Big Endian communication on SPI as a word is stored as Little endian in my Nucleo.

Thanks to those that will take time to answer my question.

I don't know about the specifics here, but sometimes you are stuck with a particular byte order on a communication channel. A workaround is to use a union for byte access to a larger word which allows you to reshuffle things as they go out or come in.

    typedef struct bytes_16 {
        uint8_t b0;
        uint8_t b1;
    } bytes_16;

    typedef union {
        uint16_t data;
        bytes_16 bytes;
    } data_packed;

    data_packed data1;
    data_packed data2;

    data2.data = 0xFF00;

    data1.bytes.b0 = data2.bytes.b1;
    data1.bytes.b1 = data2.bytes.b0;

    printf("\r\ndata1 = %d",data1.data);

At this point data1.data will equal 0x00FF

posted by Graham S. 07 Jun 2017

Thank you for that, but in one byte no structure is able to swap bit order... Even bit field... I realy need to know how to set Endianess in SPI.

posted by H A 07 Jun 2017

Looking at SPI_API.h I saw that mode integrate both CPOL, CPHA and shift direction without any more info... Any Ideas ?

Either I've found a :

extract of spi.h from mbed lib

#define SPI_FIRSTBIT_MSB                ((uint32_t)0x00000000U)
#define SPI_FIRSTBIT_LSB                SPI_CR1_LSBFIRST

How I may use it to set my data direction ?

Looking at SCK / MOSI / MISO with a scope I see : SS Falling down a 16 periods clock + 1x16 bits frame (0xFFFF) then before SS goes high another 16 periods clock + 16 bits frame (0x0000) And then SS goes high.

But my code says :

extract of my code

SS = 0;
SPIG_angle = SPIG.write (SPI_READ_ANGLE);
SS = 1;

where SPIG is an instance of SPI and SPI_READ_ANGLE is defined as 0xFFFF (I've tried to put a 0xFFFFU directly but it change nothing).

So where does the second frame came from as my SPI is define as 16 bits wide ?

Holly God ! I really beleive that SPI library is a crap...

posted by H A 07 Jun 2017

1 Answer

7 months, 2 weeks ago.


There are two ways to communicate with the sensor. The application can split 16 bit command to 2 x byte command and combine the 2 byte answer to one 16 bit lenght variable. The other way is to set SPI to use 16 bits. It might work (Endian is correct) or not. format (int bits, int mode=0) where bits can be 4 -16 / spi.write.

First one could be something like this: uint16_t SPI_operation(uint16_t command16) { uint8_t command[2]; uint8_t answer[2]; uint16_t answer16; command[0] = (uint8_t)(command16>>8); command[1] = (uint8_t)(command16 & 0x00ff); spi.write(command[0]); spi.write(command[1]); answer[0] = spi.write(0x00); answer[0] = spi.write(0x00); answer16 = answer[0]; answer16 = (answer16<<8) + answer[1]; return answer16; }

In general look at https://os.mbed.com/docs/mbed-os/v5.14/apis/spi.html#spi-hello-world

Regards, Pekka

Thank you for your answer, but I've already found an answer to my last question : There was a mistake in STM32 lib. I've solve it (it's in an other thread by me). And for Endianess, I've created a fonction that swap bit order... It's stupid as microcontroler can be easily configure to do it itself, but it was faster than looking in the whole SPI API lib... But I'm still building a mbed lib for the AS5047D.

posted by H A 26 Nov 2019