This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC1352P7:SPI Callbackmode不会一直触发Callback函数

Guru**** 652440 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/other-wireless-group/other-wireless/f/other-wireless-technologies-forum/1100048/cc1352p7-spi-callbackmode-wont-allways-trigger-callback-function

部件号:CC1352P7

您好,

我在运行SPI设备时遇到问题。 它是KX134-1211 Rev. 1.0 加速传感器套件。

我已按如下方式连接设备:
味增- DIO8
MOSI - DIO9.
CLK  - DIO10
CS   - DIO11.

我正在将空项目用于实验目的。
首先,我将传感器套件初始化为16位阻止模式。 在这里,我可以设置传感器套件的引脚,以在给定频率触发。
正如我在示波器上看到的那样,这很好。

传感器套件的触发器引脚与Launchpad的DIO14 (BTN2)相连。
BTN-2在触发时具有回调函数,该函数启动SPI并发送请求。
此函数处于回调模式。 在我的理解中,这意味着每次使用SPI_TRANSFORT()时,它都会触发给定的Callbackfunction。 但它不是
所以我在锁定模式下尝试了它。 直到循环中的第12次调用,此操作一直运行正常。

我不知道应用程序何时跳进错误函数,但它总是在与SPI相关的呼叫中。
在我尝试运行时,我也尝试了SPICC26xxDMA.h中的手动模式,但它不起作用。  

我还阅读了一些关于SPI-functions are not be called in a thread, because of the used hwi_disable, btriggert callback function of "BTN14"是HWI。 是吗?  

我的syscfg如下所示:
按钮:2 BTNS ->按钮向右和按钮向左。 两个"使用硬件"都是对应的LaunchPad按钮BTN-X
GPIO:4 (2 BTN,2个LED)->按钮1和按钮2 (与上面相同)-名称"Config_GPIO _BTNX"-回调函数:空(在代码中设置)。
中断优先级:7-最低


感谢你的帮助。

TLDR:SPI函数不会触发callbackfunction (为什么?) -阻止模式中的SPI跳转到错误函数-如何使SPI运行?

 *  ======== empty.c ========
 */

/* For usleep() */
#include <unistd.h>
#include <stdint.h>
#include <stddef.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>
// #include <ti/drivers/I2C.h>
#include <ti/drivers/SPI.h>
#include <SPICC26X2DMA.h>
#include <spiKX134.h>
// #include <ti/drivers/UART.h>
// #include <ti/drivers/Watchdog.h>

/* Driver configuration */
#include "ti_drivers_config.h"

// defines


//SPI
uint16_t accelData[10][6];
uint16_t SPI_watermark = 0; //Anzahl der Datensätze im AccelData array
uint8_t spiFrameNbr = 1; // Anzahl der zu übertragenden Frames
SPI_Handle      spi;
SPI_Params      spiParams;
SPI_Transaction spiTransaction;
uint64_t coapData;
static uint16_t SPI_full = 10;
uint16_t         transmitBuffer[6]; //Init des transmitBuffer arrays
uint16_t         receiveBuffer[6]; //Init des receiveBuffer arrays
volatile bool            transferOK;

//Platz für Funktionen..
void spiRun();
static void spi_done_callback();
static void coap_handle_button_press();
void spi_start_request();
void spi_stop_request();




static void btn_interrupt_handler() //uint8_t index
{
        spi_start_request();
        coap_handle_button_press();
        //spi_stop_request();
//    if(index == CONFIG_GPIO_BTN1)    {    }
//    else if(index == CONFIG_GPIO_BTN2)    {    }

}


//SPI Hilfsfunktionen
void spiWritePrep(volatile uint16_t* transmitBuffer) {    //erstes BIT 0 für schreiben auf SPI
    *transmitBuffer = *transmitBuffer << 8;
    *transmitBuffer = *transmitBuffer & 0b0111111111111111;
}

void spiWritePrep16bit(volatile uint16_t* transmitBuffer1, volatile uint16_t* transmitBuffer2) {    //erstes BIT 0 für schreiben auf SPI
    *transmitBuffer1 = *transmitBuffer1 | *transmitBuffer2;
}

void spiReadPrep(volatile uint16_t* transmitBuffer) {    //erstes BIT 1 für lesen auf SPI
    *transmitBuffer = *transmitBuffer | 0b1000000000000000;
}


//SPI Hauptfunktion
void spiRun(){

      SPI_init();  // Initialize the SPI driver

      SPI_Params_init(&spiParams);  // Initialize SPI parameters. Änderungen bestimmter Parameter möglich, siehe nächste Zeile
      //manche Werte sind die Default-Werte, können bei Bedarf umgestellt werden. Infos in SPI.h
      spiParams.transferMode = SPI_MODE_BLOCKING;  //Blocking / Callback
      spiParams.transferTimeout = SPI_WAIT_FOREVER; //Time in system ticks
      spiParams.transferCallbackFxn = NULL; //Funktion nach Übertragung
      spiParams.mode = SPI_MASTER; //Master/Slave mode
      spiParams.bitRate = 1000000; //1Mhz
      spiParams.dataSize = 16;       // 8-bit data size
      spiParams.frameFormat = SPI_POL1_PHA1;    //!< SPI mode Polarity 1 Phase 1


      spi = SPI_open(CONFIG_SPI_0, &spiParams); // SPI_open("nummer des SPI wie in sysconf.", spiParams)
      if (spi == NULL) {
          while (1);  // SPI_open() failed
      }


        // Fill in transmitBuffer 1
        // Set acc to stand-by mode
        spiTransaction.count = spiFrameNbr;
        spiTransaction.txBuf = (void *)transmitBuffer;
        spiTransaction.rxBuf = (void *)receiveBuffer;

        transmitBuffer[0] = CNTL1;
        spiWritePrep(&transmitBuffer[0]);
        transmitBuffer[1] = 0x00; //Value
        spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);

        transferOK = SPI_transfer(spi, &spiTransaction);
        if (!transferOK) {
            // Error in SPI or transfer already in progress.
            while (1);
        }

        // Fill in transmitBuffer 2
        // Interrupt Control1(INC1) enables physical interrupt pin5 INT1 (active high)
        transmitBuffer[0] = INC1;
        spiWritePrep(&transmitBuffer[0]);
        transmitBuffer[1] = 0x30; //Value
        spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);

        transferOK = SPI_transfer(spi, &spiTransaction);
        if (!transferOK) {
            // Error in SPI or transfer already in progress.
            while (1);
        }

        // Fill in transmitBuffer 3
        // set the Data Ready interrupt to be reported
        transmitBuffer[0] =INC4;
        spiWritePrep(&transmitBuffer[0]);
        transmitBuffer[1] =0x10; //Value
        spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);

        transferOK = SPI_transfer(spi, &spiTransaction);
        if (!transferOK) {
            // Error in SPI or transfer already in progress.
            while (1);
        }

        // Fill in transmitBuffer 4
        // set trigger-rate Infos in spiKX134.h
        transmitBuffer[0] =ODCNTL;
        spiWritePrep(&transmitBuffer[0]);
        transmitBuffer[1] = ODR10 | IIR_OFF | LPRO_OFF | FSTUP_OFF; //Value
        spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);

        transferOK = SPI_transfer(spi, &spiTransaction);
        if (!transferOK) {
            // Error in SPI or transfer already in progress.
            while (1);
        }

        // Fill in transmitBuffer 5
        // set acc to operating mode
        transmitBuffer[0] =CNTL1;
        spiWritePrep(&transmitBuffer[0]);
        transmitBuffer[1] =0xE0; //Value
        spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);

        transferOK = SPI_transfer(spi, &spiTransaction);
        if (!transferOK) {
            // Error in SPI or transfer already in progress.
            while (1);
        }

        SPI_close(spi);
}

void spi_start_request(){
    SPI_init();  // Initialize the SPI driver

    SPI_Params_init(&spiParams);  // Initialize SPI parameters. Änderungen bestimmter Parameter möglich, siehe nächste Zeile
    //manche Werte sind die Default-Werte, können bei Bedarf umgestellt werden. Infos in SPI.h
    spiParams.transferMode = SPI_MODE_CALLBACK;  //Blocking / Callback
    spiParams.transferTimeout = SPI_WAIT_FOREVER; //Time in system ticks
    spiParams.transferCallbackFxn = spi_done_callback; // spi_done_callback; //Funktion nach Übertragung
    spiParams.mode = SPI_MASTER; //Master/Slave mode
    spiParams.bitRate = 1000000; //1Mhz
    spiParams.dataSize = 16;       // 8-bit data size
    spiParams.frameFormat = SPI_POL1_PHA1;    //!< SPI mode Polarity 1 Phase 1


    spi = SPI_open(CONFIG_SPI_0, &spiParams); // SPI_open("nummer des SPI wie in sysconf.", spiParams)
    if (spi == NULL) {
        while (1);  // SPI_open() failed
    }
    //SPI_control(spi, SPICC26X2DMA_CMD_CLR_MANUAL, NULL);
    GPIO_write(CONFIG_GPIO_RLED, 1);
}


static void coap_handle_button_press()  //fct for button/HWI
{
    // SPI Request on buttonpress/HWI-trigger

        spiTransaction.count = 6;
        spiTransaction.txBuf = (void *)transmitBuffer;
        spiTransaction.rxBuf = (void *)receiveBuffer;

                //Push arguments to the first 8 bit
                transmitBuffer[0] = XOUT_H << 8;
                transmitBuffer[1] = XOUT_L << 8;
                transmitBuffer[2] = YOUT_H << 8;
                transmitBuffer[3] = YOUT_L << 8;
                transmitBuffer[4] = ZOUT_H << 8;
                transmitBuffer[5] = ZOUT_L << 8;


                transferOK = SPI_transfer(spi, &spiTransaction);
                if (!transferOK)
                {
                    while(1);// Error in SPI or transfer already in progress.
                }
//                accelData[SPI_watermark][0] = receiveBuffer[0];
//                accelData[SPI_watermark][1] = receiveBuffer[1];
//                accelData[SPI_watermark][2] = receiveBuffer[2];
//                accelData[SPI_watermark][3] = receiveBuffer[3];
//                accelData[SPI_watermark][4] = receiveBuffer[4];
//                accelData[SPI_watermark][5] = receiveBuffer[5];
//
//                GPIO_write(CONFIG_GPIO_RLED, 0);
        //eventOS_event_send(&event); gibt kein Event

}

static void spi_done_callback(SPI_Handle spi, SPI_Transaction *spiTransaction){
    if (spiTransaction->status != SPI_TRANSFER_COMPLETED) {
        transferOK = false;
        SPI_transferCancel(spi);
        spi_stop_request();
    }
    else {
        transferOK = true;
        accelData[SPI_watermark][0] = receiveBuffer[0];
        accelData[SPI_watermark][1] = receiveBuffer[1];
        accelData[SPI_watermark][2] = receiveBuffer[2];
        accelData[SPI_watermark][3] = receiveBuffer[3];
        accelData[SPI_watermark][4] = receiveBuffer[4];
        accelData[SPI_watermark][5] = receiveBuffer[5];
        spi_stop_request();
    }

}

void spi_stop_request(){
    if(SPI_watermark == SPI_full){
       SPI_watermark = 0;
    }
    else{
        SPI_watermark++;
    }
    GPIO_write(CONFIG_GPIO_RLED, 0);
    SPI_close(spi);
    spi = NULL;
}

/*
 *  ======== mainThread ========
 */
void *mainThread(void *arg0)
{
    /* 1 second delay */
    uint32_t time = 1;

    /* Call driver init functions */
    GPIO_init();
    // I2C_init();
    // UART_init();
    // Watchdog_init();

    /* Configure the LED pin */
    GPIO_setConfig(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    spiRun();

    /* Setup callback for btn int */
    GPIO_setCallback(CONFIG_GPIO_BTN1, btn_interrupt_handler);
    GPIO_enableInt(CONFIG_GPIO_BTN1);
    GPIO_setCallback(CONFIG_GPIO_BTN2, btn_interrupt_handler);
    GPIO_enableInt(CONFIG_GPIO_BTN2);

    while (1) {
        sleep(time);
        GPIO_toggle(CONFIG_GPIO_GLED);
    }

}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Niels:

    您是否可以设置示例来重现此问题,而无需使用传感器套件,并且只能使用Launchpad? 这将有助于我们重现该问题。

    谢谢!
    Nikolaj

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Nikolaj,

    我将尝试将SPIslave示例更改为使用Launchpad而不是加速度传感器。  

    感谢您的回复

    尼尔斯

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为我已经找到了解决我的问题的方法。
    如上所述,在任务中使用SPI_transfer似乎比使用HWI或线程更好。 在搜索了spiSlave/Master示例以修改这些示例以找到一个很好的问题示例后,我在那里找到了信号。

    我现在用按钮上的HWI发布信号,并有一个运行while (1)循环的任务,其中包含SEM_WAIT。 这种做法一直很好。  


    感谢每一位努力提供帮助的人!