Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Passing SPI data from C to CPP Teensy 3.5

  1. #1
    Junior Member
    Join Date
    Dec 2019
    Posts
    5

    Passing SPI data from C to CPP Teensy 3.5

    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 Code:
    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 Code:
    static SpiDataReceivedCbfType pnDataReadyCbf;
    void SpiRegDataReceived(SpiDataReceivedCbfType pnDataReceived  )
    {
       pnDataReadyCbf = pnDataReceived;
    }
    
    void SpiSendReceive( void* pxSendDataBuffer, void* pxReceiveDataBuffer, UINT16 iLength )
    {
       TNSY_SPI_TransmitReceive(pxSendDataBuffer, pxReceiveDataBuffer, iLength);
       pnDataReadyCbf();
    }

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,083
    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...

  3. #3
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,481
    Quote Originally Posted by KurtE View Post
    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.

  4. #4
    Junior Member
    Join Date
    Dec 2019
    Posts
    5
    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 ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •