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.

[参考译文] CC3220SF:我使用 cc3220sf 芯片。 修改 SPI 程序后、程序停止运行并返回 ti.driver.config 文件 DMA 错误处理函数、异常中断、原因是什么

Guru**** 2535750 points
Other Parts Discussed in Thread: CC3220SF

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

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/984018/cc3220sf-i-use-cc3220sf-chip-after-modifying-the-spi-program-the-program-stops-running-and-returns-to-the-ti-driver-config-file-dma-error-handling-function-abnormal-interrupt-what-is-the-reason

器件型号:CC3220SF

值得注意的是:1. 当程序异常中断时、下次重新运行程序是正常操作、不会被中断。 2.如果我在每次运行程序之前复位器件硬件、将不会出现异常中断。

程序异常中断、中断至以下功能位置

*========================================= DMA ================================================
*

#include
#include
#include
#include
#include

/*确保 DMA 控制表按照 UDMA 硬件的要求对齐*/
静态 tDMAControlTable dmaControlTable[64]__attribute__((对齐(1024)));

/*这是 uDMA 错误中断的处理程序。 *
静态空 dmaErrorFxn (uintptr_t arg)

int status = map_uDMAErrorStatusGet ();
map_uDMAErrorStatusClear ();

/*禁止未使用的变量警告*/
(无效)地位;

while (1);

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

    您好!

    您在 SPI 演示中修改了什么?

    另外请记住、如果通过 JTAG 调试器加载应用、 则复位时不会保留该应用。 您需要将应用刷写到串行闪存中。 如需更多说明 、请参阅 CC3220开箱即用体验中的器件概述:链接

    此致、

    Sarah

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

    我修改了传输的数据部分、以便与 ADC 芯片通信、将控制指令写入 ADC 并接收数据。

    我认为串行下载没有任何效果、因为我仍处于调试阶段、每次都通过调试加载程序。

    DMA 在 SPI 传输里程中发挥着什么作用? 常见的错误是什么? 我希望您能给我一些建议、因为我对 DMA 的使用不是很了解。

    这就是我如何写入数据和写入数据函数、以及如何在线程中调用它们。

    unsigned char AD7124_SPI_read (unsigned char slaveDeviceId、
    unsigned char*数据,
    unsigned char bytesNumber、
    SPI_Handle masterSpi)

    uint8_t i=0;
    // SPI_Handle masterSpi;
    SPI_Transaction 事务;
    transaction.count = SPI_MSG_length;
    masterTxBuffer[0]=数据[0];
    transaction.txBuf =(void *) masterTxBuffer;
    SPI_TRANSFCTION (masterSpi、事务);
    memset ((void *) masterRxBuffer、0、SPI_MSG_LENGTH);
    对于(i=1 <bytesNumber; i++)

    DATA[i]= masterRxBuffer[i];

    transaction.rxBuf =(void *) masterRxBuffer;
    SPI_TRANSFCTION (masterSpi、事务);

    返回0;

    unsigned char AD7124_SPI_Write (unsigned char slaveDeviceId、
    unsigned char*数据,
    unsigned char bytesNumber、
    SPI_Handle masterSpi)


    uint8_t i=0;
    // SPI_Handle masterSpi;
    SPI_Transaction 事务;
    // btransferool OK;

    for (i=0;<bytesNumber; i++)

    masterTxBuffer[i]=数据[i];


    transaction.count =字节编号;
    transaction.txBuf =(void *) masterTxBuffer;
    SPI_TRANSFCTION (masterSpi、事务);

    返回0;

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

    您好!

    SPI 驱动器使用 DMA 与数据缓冲器之间传输数据。 这是内置在驱动程序中的。 您可以在 SDK 中的 docs/drivers/tidriversAPI.html 中找到相关文档。

    DMA 错误通常是因为您将错误的指针传递到 SPI 驱动程序(因此无法访问存储器位置)、或者您正在编辑数据缓冲区、而数据缓冲区仍在被 DMA 使用。 我无法从您的代码段中得知、但我要验证您的 TX 和 RX 缓冲区是如何定义的。 如果这些是全局函数、请确保您不会同时调用读取和写入函数。

    此致、

    Sarah

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

    同时调用读取和写入函数的情况是什么? 我确实按顺序调用了同一函数中的读取和写入函数。 应该可以。

    此外、请帮助我了解、在 TI 提供的例程中、它不是一个循环、先将数据放入读写缓冲区中、然后调用 SPI 传输函数进行传输

    对于(I = 0;I < MAX_LOOP;I++){
    /*
    *等待从器件准备好传输;从器件将拉取
    * CONFIG_SPI_SLAVE_READY 低电平。
    *
    SEM_WAIT (masterSem);

    /*初始化主 SPI 事务结构*/
    masterTxBuffer[sizeof (master_MSG)- 1]=(i % 10)+'0';
    memset ((void *) masterRxBuffer、0、SPI_MSG_LENGTH);
    transaction.count = SPI_MSG_length;
    transaction.txBuf =(void *) masterTxBuffer;
    transaction.rxBuf =(void *) masterRxBuffer;

    /*切换用户 LED、指示正在进行 SPI 传输*/
    GPIO_TOGGLE (CONFIG_GPIO_LED_1);

    /*执行 SPI 传输*/
    transferOK = SPI_transfer (masterSpi、事务);
    if (transferOK){
    Display_printf (display、0、0、"主设备接收到:%s"、masterRxBuffer);

    否则{
    display_printf (display、0、0、"unsuccessful master SPI transfer");

    /*在开始下一个 SPI 传输前睡眠一位*/
    睡眠(3);

    SPI_CLOSE (masterSpi);

    另一个问题是、每当我调用 SPI 传输函数时、句柄是否使用指针变量 masterspi? 每当我调用读写函数时、我都会传递该句柄。 影响是什么

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

    您好!

    如果您的应用程序可能在另一个 SPI_TRANSFERT()完成之前调用 SPI_TRANSFERT(),则您应该使用单独的事务结构和单独的数据缓冲区。

    您是否还在上面的环路上看到了 DMA 错误?

    此致、

    Sarah

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

    在官方例程中获得上述循环、将不会出现 DMA 错误。 在使用过程中、我还设置了两个缓冲区、mastertxbuffer 和 masterrxbuffer、用于读取和写入。 它不应是单独的缓冲器。 至于单独的事务结构、

    SPI_TRANSFCTION (masterSpi、事务);

    上述程序语句的第二个变量是单独的事务结构吗? 我在所有 SPI 传输函数调用中使用此(& Transaction)变量。

    另一个问题是、我无法判断最后一次 SPI 传输何时完成、因为我的程序按如下方式逐一调用

    int32_t AD7124_Setup (ad7124_device * device、int slave_select、
    ad7124_st_reg *寄存器、SPI_Handle A)

    int32_t ret;
    unsigned char i=0;
    enum ad7124_registers regNr;
    if (!device ||!regs)
    返回 INVALID_VAL;
    device->regs = regs;
    DEVICE_>SLAVE_SELECT_ID = SLAVE_SELECT;
    DEVICE_>SPI_RY_POLL_cnt = 25000;
    RET = AD7124_Reset (器件、A);  

    ------ (int32_t AD7124_Reset (ad7124_device *设备、spi_handle b)

    int32_t ret = 0;
    uint8_t wrBuf[8]={0xFF、0xFF、0xFF、0xFF、0xFF、 0xFF、0xFF、0xFF};
    if (!device)(如果!device)
    返回 INVALID_VAL;
    RET = AD7124_SPI_Write (device->slave_select_id、wrBuf、8、b);
    RET = AD7124_WaitToPowerOn (器件、器件->SPI_rdy _poll_cnt、b);
    回程;

    )------

    如果(RET < 0)
    回程;
    RET = AD7124_ReadRegister (device、&regs[AD7124_ID]、a);--- (__LW_AT__相似地,这个函数调用 SPI 读取函数。)----

    下面有更多的函数调用、调用上面发送给您的 SPI 读取函数和 SPI 写入函数。所有函数都是按顺序调用的、因此我不知道如何确定程序执行时是否发生了抢占。

    感谢您为患者提供指导。

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

    您好!

    是否调用  SPI_Params_init()来初始化事务?  您是否在任何位置设置了传输模式? 请参阅 docs/drivers/tidriversapi.html 中的 spi_transfer()文档。

    如果您只从一个线程调用 SPI_TRANSF(),并且它们处于默认阻塞模式,则应该可以。 如果您从多个线程调用读取/写入函数、则应使用不同的事务结构。

    此致、

    Sarah

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

    是的、我在一个线程中调用函数。 该线程中的初始化设置与给定示例相同。 如下所示、在不改变传输模式的情况下执行 SPI 参数初始化。

    void *线程 Fxn0 (void * arg0)

    SPI_Handle masterSpi;
    SPI_Params spiParams;
    struct ad7124_device ad7124;
    状态= SEM_INIT (&masterSem、0、0);
    SPI_Params_init (&spiParams);
    spiParams.frameFormat = SPI_POL1_PHA1;
    spiParams.bitrate = 1000000;
    masterSpi = SPI_open (CONFIG_SPI_MASTER、&spiParams);
    if (masterSpi == NULL){
    Display_printf (display、0、0、"初始化主器件 SPI\n"时出错);

    while (1);

    否则{
    display_printf (display、0、0、"Master SPI initialized");

    AD7124_Setup (&ad7124、AD7124_SLAVE_ID、(ad7124_st_reg *)&ad7124_regs、masterSpi);

    我的所有程序中都有其他线程、但我没有调用相关的 SPI 函数。 我只调用了上面的线程中提到的函数。

    还有另一个问题。 我通过函数变量将 SPI 从主程序传输所需的 masterspi 变量传递给读写函数、但我不传递在读写函数中定义和使用的另一个变量 transaction。 会有什么影响

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

    当我在 SPI 读取函数中写入程序时、该程序可能会跳转到启动以及 cc32xx 文件中错误循环中的 DMA 中断周期_、如下所示

    静态空
    FAULTISR (空)

    /*输入无限循环。 *
    while (1)


    此外、当我在 SPI 读取函数中编写程序时、我发现我的 P05引脚 SCLK 信号线是否已连接、对我的程序操作是否没有影响、 不能使用示波器测量波形。如果 SPI 读取未写入任何程序、SCLK 具有波形

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

    您好!

    我认为您需要在 SPI_TRANSFORT()处设置断点,并将参数与 工作循环或 SDK 示例进行比较。 我认为您可能会在某个位置遇到指针问题。

    此致、

    Sarah

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

    这是否意味着我需要设置一个断点来测试 SPI 传输函数中主指针和传输指针指向的地址是否与正在运行的 SDK 的地址一致?

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

    我找到了问题。 我在 SPI 通信测试中使用了两个相同的 cc3220sf launchxl。 我发现 SPI 传输过程必须确保发送数据和接收数据同时存在、否则将报告错误。 例如、从器件中删除程序的发送部分、并按如下所示修改程序:

    对于(I = 0;I < MAX_LOOP;I++){
    SEM_WAIT (masterSem);
    memset ((void *) masterRxBuffer、0、SPI_MSG_LENGTH);
    transaction.count = SPI_MSG_length;
    transaction.rxBuf =(void *) masterRxBuffer;
    GPIO_TOGGLE (CONFIG_GPIO_LED_1);
    transferOK = SPI_transfer (masterSpi、事务);

    程序无法正常工作、当我重写程序时、我将单独使用 transation.Rx 或 transation.Rx 以及 SPI 传输、当我向芯片发送数据时、我不需要接收 ADC 返回的数据。 我不确定是否要将数据返回到主机。 如何解决此问题? 因为我不太了解、所有 DMA 通信都是双向的、还是这是 TI 公司编写示例时的特殊设置。

    祝你一切顺利。

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

    您好!

    如果只需要发送数据,则可以将事务的 rxBuf 设置为 NULL。

    此致、

    Sarah