Passing SPI data from C to CPP Teensy 3.5

Status
Not open for further replies.

jeff0778

Member
I am struggling at the moment to integrate some 3rd party code into a project I’m working on. The 3rd parties code is written in C and my main code is CPP. I’m struggling with the pointer references and I’ve still a lot to learn regarding this.
I am running the code on a Teensy 3.5 board and linking up to the 3rd party’s product via SPI. I’m using Platform IO within Visual Studio Code.
In the 3rd party code they have packaged all the data up for me and it should be a simple case of just clocking the bytes in & out over the SPI bus. The area I’m struggling with is they are using void pointers to the Tx & Rx data blocks. I’m also not sure where or how to write the received data back to the pointer.

I've attached some code below at my initial attempts but welcome any assistance anyone could offer.
Main.cpp
HTML:
SPISettings SPIconfig(1000000, MSBFIRST, SPI_MODE0);

extern "C" void TNSY_SPI_TransmitReceive(uint8_t *dataTx, uint8_t *dataRx, uint16_t len)  {
   Serial.print("TNSY_SPI_TransmitReceive: ");
   SPI.beginTransaction(SPIconfig);
   digitalWrite(SLAVESELECT,LOW);
   delayMicroseconds(1);
   for (uint16_t i = 0; i < len; i++)  {
      *dataRx = SPI.transfer(*dataTx);       // send the data, while storing the received data
      dataTx++;                              // increment the pointer to the next value
      dataRx++;                              // increment the poitner to the next space for RXdata
      }
   digitalWrite(SLAVESELECT,HIGH);
   delayMicroseconds(1);
   SPI.endTransaction();  
}

3rd Party's C
HTML:
static SpiDataReceivedCbfType pnDataReadyCbf;
void SpiRegDataReceived(SpiDataReceivedCbfType pnDataReceived  )
{
   pnDataReadyCbf = pnDataReceived;
}

void SpiSendReceive( void* pxSendDataBuffer, void* pxReceiveDataBuffer, UINT16 iLength )
{
   TNSY_SPI_TransmitReceive(pxSendDataBuffer, pxReceiveDataBuffer, iLength);
   pnDataReadyCbf();
}
 
Others can maybe give you more exact answers to this...

But void* just means it is a pointer to something... So often times with functions like this, I will then cast it to something like uint8_t* to process.

This casting could be done either on a function call, or internal to a function...

Example like:
Code:
void transfer_buffer(void* buf, int count) {
    uint8_t * buf_out = (uint8_t*)buf;
    while (could--) {
       SPI.transfer(*buf_out++);
    }
}
Note: I would not do the above as SPI has a transfer function where I can pass in buffer and count...

With the above usual caveats.. As void* could be pointer to anything. If you are expecting to send or receive data in a certain format, line 16 bit integers or 32 bit integers. Not all processors represent the data in the same format (order of bytes), so you may need to understand the actual formats and potentially process the data, to get it into proper format for Teensy...
 
Others can maybe give you more exact answers to this...

But void* just means it is a pointer to something... So often times with functions like this, I will then cast it to something like uint8_t* to process.

This casting could be done either on a function call, or internal to a function...

Example like:
Code:
void transfer_buffer(void* buf, int count) {
    uint8_t * buf_out = (uint8_t*)buf;
    while (could--) {
       SPI.transfer(*buf_out++);
    }
}
Note: I would not do the above as SPI has a transfer function where I can pass in buffer and count...

With the above usual caveats.. As void* could be pointer to anything. If you are expecting to send or receive data in a certain format, line 16 bit integers or 32 bit integers. Not all processors represent the data in the same format (order of bytes), so you may need to understand the actual formats and potentially process the data, to get it into proper format for Teensy...
And you also can get into problems if you use an unaligned pointer to load up multiple bytes. As I recall there are a few bytes in the Teensy 3.2 address range where doing an int load just does not work.

And there is also the issue on the Teensy 4.0 which of the two memory banks are used, and whether you have to flush the cache for devices like SPI to see it.
 
ok, so i should type cast the void pointer as i pass it my function in main that should help ? i've checked and it all looks like uint8_t data types anyway.

I was wondering if I'm using the pointer correctly in my TNSY_SPI_TransmitReceive() and is this the best way to collect the incoming data from the spi ?
 
Status
Not open for further replies.
Back
Top