CCS/LAUNCHXL-CC1352P: SPI in callback mode spi_transfer getting stuck

Intellectual 450 points

Replies: 1

Views: 26

Part Number: LAUNCHXL-CC1352P

Tool/software: Code Composer Studio

Hello,

I want to move to a callback-based SPI transfer. I've been using the blocking mode successfully with my CC1352P1 interfaced with an ENC28j60. I followed the spislave example which uses the callback mode.

A few things I wanted to clarify - will I be able to use the SPI module from different threads/tasks if I use the callback mode?

Another thing - I know the spislave example uses the BOARD_MASTER_READY and BOARD_SLAVE_READY pins to coordinate between the master and slave. I have configured the CC1352P1 as the master and the ENC28J60 as the slave. I cannot program any pins on the slave, so I cannot control the BOARD_SLAVE_READY. I removed all references to the BOARD_MASTER_READY and BOARD_SLAVE_READY and my code disappears when I encounter the spi_transfer code. Either that, or what I'm reading back from registers is not correct. (I was reading back the correct values when in blocking mode) Here's my code : 

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

/*
 *  ======== transferCompleteFxn ========
 *  Callback function for SPI_transfer().
 */
void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction)
{
    sem_post(&masterSem);
}

My spi_write function : 

void spi_write(uint8_t reg, uint8_t data){
    //uint16_t controlWord = setBufWriteToAddress(address, data);
    uint8_t bank_selector = whichBank(reg);
    if ((bank_selector != 0) && (bank_selector != 1) && (bank_selector != 2) && (bank_selector != 3) && (bank_selector != 4)){
        Display_printf(display, 0, 0, "Fatal Error - Wrong Register");
        while(1);
    }

    selectMemBank(bank_selector);
    uint8_t address = reg & 0x1f;

    bool transferOK;
    masterTxBuffer_eight[0] = 0x2<<5 | (address & 0x1f);//((1<<14) | (address & 0x1F) << 8 ) ;
    masterTxBuffer_eight[1] = data;

    memset((void *) masterRxBuffer_eight, 0, SPI_MSG_LENGTH);
    controlReg.count = SPI_MSG_LENGTH;
    controlReg.txBuf = (void *) masterTxBuffer_eight;
    controlReg.rxBuf = (void *) masterRxBuffer_eight;

    /* Toggle user LED, indicating a SPI transfer is in progress */
    GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON);

    /* Bitbanging attempt for Chip Select */
    GPIO_write(Board_GPIO_CSN0, 0);

    /* Perform SPI transfer */
    transferOK = SPI_transfer(masterSpi, &controlReg);
    if (!transferOK){
        Display_printf(display, 0, 0, "Unsuccessful SPI transfer\n");
        while(1);
    }
    else{
            /* Wait until transfer has completed */
            sem_wait(&masterSem);
    }
    /* Bitbanging attempt for Chip Select */
    GPIO_write(Board_GPIO_CSN0, 1);
    GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF);


    sleep(0.5);
}

How I opened the SPI module : 

    /* Open SPI as master (default) */
    SPI_Params_init(&spiParams);
    spiParams.dataSize = 8;
    spiParams.frameFormat = SPI_POL0_PHA0;
    spiParams.bitRate = 8000000;
    spiParams.transferCallbackFxn = transferCompleteFxn;
    spiParams.transferMode = SPI_MODE_CALLBACK;
    masterSpi = SPI_open(Board_SPI_MASTER, &spiParams);
    if (masterSpi == NULL) {
        Display_printf(display, 0, 0, "Error initializing master SPI\n");
        while (1);
    }
    else {
        Display_printf(display, 0, 0, "Master SPI initialized\n");
    }

Please let me know what could be going wrong.

Warm regards,

Samyukta

1 Reply

  • Hi,

    No problem to use the SPI module from different tasks including in callback mode.

    I don't see what can potentially be wrong in your code. Maybe you should use a logic analyzer to see what is happening on the SPI.

    Kind regards,

    __________

    Clément