Serial Communication between OpenMV and TI board

Hello,

I am trying to send SERIAL data from OpneMV H7 to TI 3220 SF launchpad.

I have this simple code in OpenMV, where I an sending the number 5 as a test
from pyb import SPI
spi = SPI(2, SPI.MASTER, baudrate=115200, polarity=1, phase=0, crc=0x7)
spi.send(b’5’)

In CCCT (TI IDE) the code snippet is included below

#define SPI_MSG_LENGTH  (30)
#define SLAVE_MSG       ("Hello from slave, msg#: ")

#define MAX_LOOP        (10)
unsigned char slaveRxBuffer[SPI_MSG_LENGTH];
unsigned char slaveTxBuffer[SPI_MSG_LENGTH];

/* Semaphore to block slave until transfer is complete */
sem_t slaveSem;

static Display_Handle display;
void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction)
{
    sem_post(&slaveSem);
}

       LOG_INFO("Starting SPI Code\r\n");
    // BEGIN SPI SLAVE CODE
       SPI_Handle      slaveSpi;
       SPI_Params      spiParams;
       SPI_Transaction transaction;
       uint32_t        i;
       bool            transferOK;
       int32_t         status;
          GPIO_setConfig(CONFIG_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
          GPIO_setConfig(CONFIG_SPI_MASTER_READY, GPIO_CFG_INPUT);
          LOG_INFO("setconfig done\r\n");
          GPIO_write(CONFIG_SPI_SLAVE_READY, 1);
          while (GPIO_read(CONFIG_SPI_MASTER_READY) == 0) {}

          status = sem_init(&slaveSem, 0, 0);
          if (status != 0) {
              //Display_printf(display, 0, 0, "Error creating slaveSem\n");
              LOG_INFO("Error creating slaveSem\r\n");
              while(1);
          }

          while (GPIO_read(CONFIG_SPI_MASTER_READY)) {}

          LOG_INFO("SPI is ready to receive messages\r\n");

          SPI_Params_init(&spiParams);
          spiParams.frameFormat = SPI_POL0_PHA1;
          spiParams.mode = SPI_SLAVE;
          spiParams.transferCallbackFxn = transferCompleteFxn;
          spiParams.transferMode = SPI_MODE_CALLBACK;
          slaveSpi = SPI_open(CONFIG_SPI_SLAVE, &spiParams);
          if (slaveSpi == NULL) {
              //Display_printf(display, 0, 0, "Error initializing slave SPI\n");
              LOG_INFO("Error initializing slave SPI\r\n")
              while (1);
          }
          else {
              //Display_printf(display, 0, 0, "Slave SPI initialized\n");
              LOG_INFO("Slave SPI initialized\r\n")
          }

          /* Copy message to transmit buffer */
          strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH);

The challenge I am facing is that the code does not come out of this loop
while (GPIO_read(CONFIG_SPI_MASTER_READY)) {}
The statement below does not get executed:
LOG_INFO(“SPI is ready to receive messages\r\n”);
This seem to imply that the serial data is not coming from OpenMV to TI board.

The pins that are connected in between two boards are:
OpenMV:
P0 (MOSI)
P1 (MISO)
P2 (SLCK)
P3 (SS)

TI board
MOSI (P7)
MISO (P6)
CLK (P5)
SS (P8)

Thanks,
Ravi

You have to manually control the SS signal on the OpenMV Cam. SPI2 just controls the MOSI/MISO/SCLK.

Thanks @kwagyeman . Much appreciated. My new code in OpenMV is
spi = SPI(2, SPI.MASTER, baudrate=115200, polarity=0, phase=0)
cs.low()
spi.send(b’5’)
cs.high()

When the TI board code runs, the initial part works well In the end there is this statement where we are waiting for completion of message.
sem_wait(&slaveSem);
LOG_INFO(“SEM wait done\r\n”);

This statement does not get executed. The code snippet is given below. Any suggestions on what could be going wrong. Does it mean that the wiring is correct, and connection is established correctly. Many Thanks for the help.

LOG_INFO("before GPIO set config %s\r\n", SSID_NAME);

GPIO_setConfig(CONFIG_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_setConfig(CONFIG_SPI_MASTER_READY, GPIO_CFG_INPUT);

LOG_INFO("GPIO Config done\r\n");

/*
 * Handshake - Set CONFIG_SPI_SLAVE_READY high to indicate slave is ready
 * to run.  Wait for CONFIG_SPI_MASTER_READY to be high.
 */
GPIO_write(CONFIG_SPI_SLAVE_READY, 1);
while (GPIO_read(CONFIG_SPI_MASTER_READY) == 0) {}
LOG_INFO("Received handshake from Master.\r\n");

status = sem_init(&slaveSem, 0, 0);
if (status != 0) {
    Display_printf(display, 0, 0, "Error creating slaveSem\n");

    while(1);
}
LOG_INFO("Sem init done\r\n");

while (GPIO_read(CONFIG_SPI_MASTER_READY)) {}

LOG_INFO("Ready to receive messages\r\n");

/*
 * Open SPI as slave in callback mode; callback mode is used to allow us to
 * configure the transfer & then set CONFIG_SPI_SLAVE_READY high.
 */
SPI_Params_init(&spiParams);
spiParams.frameFormat = SPI_POL0_PHA1;
spiParams.mode = SPI_SLAVE;
spiParams.transferCallbackFxn = transferCompleteFxn;
spiParams.transferMode = SPI_MODE_CALLBACK;
slaveSpi = SPI_open(CONFIG_SPI_SLAVE, &spiParams);

if (slaveSpi == NULL) {
    LOG_INFO("Error initializing slave SPI\r\n");
    Display_printf(display, 0, 0, "Error initializing slave SPI\n");
    while (1);
}
else {
    LOG_INFO("Slave SPI initialized\r\n");
    Display_printf(display, 0, 0, "Slave SPI initialized\n");
}

/* Copy message to transmit buffer */
strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH);

for (i = 0; i < MAX_LOOP; i++) {
    /* Initialize slave SPI transaction structure */
    transaction.count = SPI_MSG_LENGTH;
    transaction.txBuf = NULL;
    transaction.rxBuf = (void *) slaveRxBuffer;

    /* Toggle on user LED, indicating a SPI transfer is in progress */
    GPIO_toggle(CONFIG_GPIO_LED_1);

    /*
     * Setup SPI transfer; CONFIG_SPI_SLAVE_READY will be set to notify
     * master the slave is ready.
     */
    transferOK = SPI_transfer(slaveSpi, &transaction);
    if (transferOK) {
        LOG_INFO("Inside transfer OK\r\n");
        LOG_INFO("Slave received %s\r\n",slaveRxBuffer);

        GPIO_write(CONFIG_SPI_SLAVE_READY, 0);

        LOG_INFO("GPIo write done\r\n");

        /* Wait until transfer has completed */
        sem_wait(&slaveSem);
   //THE NEXT STATEMENT DOES NOT GET PRINTED
        LOG_INFO("SEM wait done\r\n");

        /*
         * Drive CONFIG_SPI_SLAVE_READY high to indicate slave is not ready
         * for another transfer yet.
         */
        GPIO_write(CONFIG_SPI_SLAVE_READY, 1);


        Display_printf(display, 0, 0, "Slave received: %s", slaveRxBuffer);
        LOG_INFO("Slave received\r\n");


    }
    else {
        Display_printf(display, 0, 0, "Unsuccessful slave SPI transfer");
        LOG_INFO("Unsuccessful slave SPI transfer\r\n");
    }
}

SPI_close(slaveSpi);

/* Example complete - set pins to a known state */
GPIO_setConfig(CONFIG_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_write(CONFIG_SPI_SLAVE_READY, 0);

Hi, it looks like you set the SPI settings on the TI board different from the OpenMV Cam.

But, if you have a logic analyzer you can quickly check the link and see what’s happening on it. Or with an oscope. I think your TI code is wrong.

Thanks @kwagyeman
I checked the connections. The clock was set on TI board to P3 instead of P5. So the new pins are
MOSI P07 (TI) … P0 (OpenMV)
MISO P06 (TI) … P1
SCLK P05 (TI) … P2
SS P08 (TI) … P3

And Gnd

I added a statement spiParams.bitRate = 115200; in TI code, and changed the phase to 1 in OpenMV:
spi = SPI(2, SPI.MASTER, baudrate=115200, polarity=0, phase=1)

The new TI code is included below. The problem remains the same, TransferComplete callback does not get called in the TI code. So the data sent by Master is not received by the Slave (TI board).

status = sem_init(&slaveSem, 0, 0);
if (status != 0) {
while(1);
}
LOG_INFO(“Sem init done\r\n”);

SPI_Params_init(&spiParams);
spiParams.bitRate = 115200;
spiParams.frameFormat = SPI_POL0_PHA1;
spiParams.mode = SPI_SLAVE;
spiParams.transferCallbackFxn = transferCompleteFxn;
spiParams.transferMode = SPI_MODE_CALLBACK;
slaveSpi = SPI_open(CONFIG_SPI_SLAVE, &spiParams);

if (slaveSpi == NULL) {
LOG_INFO(“Error initializing slave SPI\r\n”);
while (1);
}
else {
LOG_INFO(“Slave SPI initialized\r\n”);
}

/* Copy message to transmit buffer */
strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH);

for (i = 0; i < MAX_LOOP; i++) {
/* Initialize slave SPI transaction structure */
transaction.count = SPI_MSG_LENGTH;
transaction.txBuf = NULL;
transaction.rxBuf = (void *) slaveRxBuffer;

/* Toggle on user LED, indicating a SPI transfer is in progress */
GPIO_toggle(CONFIG_GPIO_LED_1);

transferOK = SPI_transfer(slaveSpi, &transaction);
if (transferOK) {
    LOG_INFO("Inside transfer OK\r\n");
    LOG_INFO("Slave received %s\r\n",transaction.rxBuf);

    /* Wait until transfer has completed */
   sem_wait(&slaveSem);
   LOG_INFO("SEM wait done\r\n");

    GPIO_write(CONFIG_SPI_SLAVE_READY, 1);


    LOG_INFO("Slave received\r\n");

}
else {
LOG_INFO(“Unsuccessful slave SPI transfer\r\n”);
}
}

Hi man,

So, I’m not going to debug your code dumps. Please ask a specific question about something you are confused about. I am here to help. But, mostly clarification. Not to read code for a system I’ve never used. To be clear, I cannot tell you if your TI code is right.

This does not appear to be an OpenMV issue. OpenMV code is straightforward. Something with my TI setup. The callback function does not get called.