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.

[参考译文] RTOS/LAUNCHXL-CC2650:中断 SPI 崩溃

Guru**** 2390755 points
Other Parts Discussed in Thread: CC2650, AFE4490

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/817440/rtos-launchxl-cc2650-interrupt-spi-crash

器件型号:LAUNCHXL-CC2650
Thread 中讨论的其他器件:CC2650AFE4490

工具/软件:TI-RTOS

您好!

我一直在使用 CC2650 Launchpad、我遇到了一个问题、无法确定原因。

我使用 CC2650通过 SPI 协议与 AFE4490通信。 我创建了一个任务函数、在该函数中、我已初始化所有 SPI 参数、并写入运行 AFE4490所需的默认寄存器。

现在问题出现了、当我在 RDY 引脚上设置中断并 调用函数 afecallback 时。 在该函数中、我正在读取寄存器以获取 ADC 数据。 当我运行程序时、我没有遇到任何错误、但我无法获取任何数据。 因此、为了验证函数是否被调用、我使用了断点。 我将断点放置在 afecallback 函数中、程序完全到达那里、其中包括写入寄存器和启用寄存器的读取函数。 使用断点继续执行程序后、我看到断点卡在"for (for)"和"if (if)"循环内(如以蓝色突出显示的图像中所示)。 下面也是我的程序。 请尽快恢复。

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

#include 
#include 
#include 

/* XDCtools 头文件*/
#include 
#include 

/* BIOS 头文件*/
#include 
#include 
#include 
#include 
#include 

/* TI-RTOS 头文件*/
#include 
#include 
#include 
#include 

/*板头文件*/
#include "Board.h"

#define TASKSTACKSIZE 1024

Task_Structure0Struct;
Char task0Stack[TASKSTACKSIZE];

/*变量*/
#define arraylength 2
#define DATA_LENGTH 6
uint8_t txBuf[arraylength*2];
uint8_t rxBuf[arraylength*2];
uint8_t transferok;
uint8_t I=0;
uint32_t adcreading[data_length];
uint8_t RxBuffer[1];
uint8_t flag_alt = 1;
uint8_t FLAG = 0;

/* SPI 驱动程序处理*/
静态 SPI_Handle spiHandle;
静态 SPI_Params spiParams;
static SPI_Transaction transaction;

//引脚驱动程序句柄*/
static PIN_Handle pinHandle;
静态 PIN_STATE PinState;

//引脚驱动程序处理*/
static PIN_Handle buttonPinHandle;
static PIN_Handle ledPinHandle;

// PIN_Config 表的全局存储器存储*/
static PIN_State buttonPinState;
static PIN_State ledPinState;

PIN_Config pinTable[]=
{
AFE_CS | PIN_GPIO_OUTP_EN | PIN_GPIO_HIGH | PIN_PushPull | PIN_DRVSTR_MAX、//CSn 引脚
AFE_PDN | PIN_GPIO_OUTP_EN | PIN_GPIO_HIGH | PIN_PushPull | PIN_DRVSTR_MAX、
AFE_RST | PIN_GPIO_OUTP_EN | PIN_GPIO_HIGH | PIN_PushPull | PIN_DRVSTR_MAX、
AFE_RDY | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_DIS、//PIN_IRQ_POedge、
PIN_TERMINATE
};
/*
应用 LED 引脚配置表:
*-所有 LED 板 LED 均关闭。
*/
PIN_Config ledPinTable[]={
BOARD_LED1 | PIN_GPIO_OUTP_EN | PIN_GPIO_LOW | PIN_PushPull | PIN_DRVSTR_MAX、
PIN_TERMINATE
};

/*
应用按钮引脚配置表:
*-按钮中断配置为在下降沿触发。
*/
PIN_Config buttonPinTable[]={
BOARD_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE、
PIN_TERMINATE
};

//函数原型设计*/

带符号长 AFE4490_REG_READ (无符号字符 ReG_address);
void AFE4490_REG_WRITE (无符号字符 reg_address、uint32_t data);
void SPI_read (uint8_t REG_address、uint32_t*数据);
void AFE4490_InReg_it (void AFE4490_Init)
void read_enable (void);
void read_disable (void);
void afeCallbackFxn (PIN_Handle handle、PIN_ID pinId);
void UartApp_UartRxCB (UART_Handle handle、 void * buf、size_t count);
void enable_pin_interrupt ();
void disable_pin_interrupt ();
//void SPI_Int_Callback (SPI_Handle handle、 SPI_Transaction * objTransaction);

/*
===== buttonCallbackFxn ===
*引脚表中配置的引脚中断回调函数板按钮。
*如果定义了 Board_LED3和 Board_LED4、则我们会将它们添加到 PIN
*回调函数中。
//
void buttonCallbackFxn (PIN_Handle handle、PIN_ID pinId){
uint32_t currVal = 0;

/*去抖逻辑,仅在按钮仍被按下(低电平)时切换*/
CPUdelay (8000*50);
if (!PIN_getInputValue (pinId)){
/*根据按下的按钮切换 LED */
开关(pinId){
案例 Board_BUTTON0:
currVal = PIN_getOutputValue (Board_LED1);
PIN_setOutputValue (ledPinHandle、Board_LED1、!currVal);
ENABLE_PIN_INTERRUPT ();
中断;
默认值:
/*不执行任何操作*/
中断;
}
}
}/*


=== 心跳 Fxn ====
*切换 Board_LED1。 Task_sleep 由 arg0确定、而 arg0
*是为心跳任务实例配置的。
//
空 BEBEARBEARFxn (UARg arg0、UARg arg1)
{
spi_init();

//初始化 SPI 并指定非默认参数
SPI_Params_init (&spiParams);
spiParams.transferMode = SPI_MODE_BLOCKING;//SPI_MODE_CALLACK;//
spiParams.bitrate = 2000000;
spiParams.dataSize = 8;
spiParams.frameFormat = SPI_POL0_PHA0;
spiParams.mode = SPI_MASTER;
spiParams.transferCallbackFxn = SPI_Int_Callback;

//配置事务
transaction.count = sizeof (txBuf);
transaction.txBuf =(ptr) txBuf;
transaction.rxBuf =(ptr) rxBuf;

spiHandle = SPI_open (Board_SPI0、&spiParams);

PIN_setOutputValue (pinHandle、AFE_RST、1);
PIN_setOutputValue (pinHandle、AFE_PDN、1);
PIN_setOutputValue (pinHandle、AFE_RST、0);
PIN_setOutputValue (pinHandle、AFE_RST、1);
PIN_setOutputValue (pinHandle、AFE_CS、1);//将 CSn 设置为高电平

AFE4490_Reg_Init();
read_enable();

/*打开 TX LED *//
PIN_setOutputValue (ledPinHandle、Board_LED1、1);
}

/*
=== main ====
*/
int main (void)
{
Task_Params taskParams;

/*呼叫板初始化函数*/
Board_initGeneral();
Board_initSPI();

/*构造心跳任务线程*/
Task_Params_init (&taskParams);
taskParams.arg0 = 1000000 / Clock_tickPeriod;
taskParams.STACKSIZE = TASKSTACKSIZE;
taskParams.stack =_task0Stack;
Task_construct(&task0Struct,(Task_FuncPtr)心跳 BeatFxn、&taskParams、NULL);

/*打开 LED 引脚*/
ledPinHandle = PIN_OPEN (&ledPinState、ledPinTable);
if (!ledPinHandle){
System_abort ("初始化板 LED 引脚时出错");
}

buttonPinHandle = PIN_OPEN (buttonPinState、buttonPinTable);
if (!buttonPinHandle){
System_abort ("初始化按钮针脚时出错");
}

pinHandle = PIN_OPEN (&pinState、pinTable);
if (pinHandle == NULL){
while (1);//初始化在"pintable"中定义的引脚时出错


/*设置按钮引脚的回调*/
if (PIN_registerIntCb (buttonPinHandle、&buttonCallbackFxn)!= 0){
System_abort ("注册按钮回调函数时出错");
}

/* DRDY 引脚的设置回调*/
if (PIN_registerIntCb (pinHandle、&afeCallbackFxn)!= 0)
{
/*注册按钮回调函数时出错*/
while (1);
}

system_printf ("启动示例\n 系统提供程序设置为 SysMin。 "
"停止目标以查看 ROV 中的任何 SysMin 内容。\n");
/* SysMin 仅在您调用 flush 或 exit 时才会打印到控制台*/
system_flush();

/*启动 BIOS */
BIOS_start();

返回(0);
}/*

------------------------------------------------------- /*/* AFE
回调函数*/*
---------------------------------------- //

// void SPI_Int_Callback (SPI_Handle handle、SPI_Transaction * objTransaction)
//{
//
// adcreading[5]= AFE4490_REG_Read (0x2F);//LED1-ALED1差异
//
//}
void afeCallbackFxn (PIN_Handle handle、PIN_ID)

adcreading[0]= AFE4490_reg_read (0x2A);//LED2红色阶段
adcreading[1]=AFE4490_REG_READ (0x2B);//ALED2红色阶段
adcreading[2]=AFE4490_reg_read (0x2C);//LED1 IR 阶段
adcreading[3]=AFE4490_reg_read (0x2D);//ALED1 IR 阶段
adcreading[4]=AFE4490_reg_read (0x2E);//LED2-ALED2差异
adcreading[5]=AFE4490_REG_READ (0x2F);//LED1-ALED1差异
}

/*------------------------------------------------------- /*
SPI 寄存器写入函数*/
/*-------------------------------------------- */

void AFE4490_reg_write (unsigned char reg_address、uint32_t data)

{
txBuf[0]=((uint32_t) reg_address);
txBuf[1]=数据>>16;
txBuf[2]= data>>8;
txBuf[3]=数据;
rxBuf[0]= 0;
rxBuf[1]= 0;
rxBuf[2]= 0;
rxBuf[3]= 0;
PIN_setOutputValue (pinHandle、AFE_CS、0);//将 CSn 设置为低电平
SPI_transfer (spiHandle、&transaction);
PIN_setOutputValue (pinHandle、AFE_CS、1);//将 CSn 设置为高
电平}

/*------------------------------------------------------- */
/* SPI 读取函数*/
/*--------------------------------------------- */

void SPI_read (uint8_t reg_address、uint32_t* data)
{
txBuf[0]=((uint32_t) reg_address);
txBuf[1]= 0;
txBuf[2]= 0;
txBuf[3]= 0;
rxBuf[0]= 0;
rxBuf[1]= 0;
rxBuf[2]= 0;
rxBuf[3]= 0;

/*启动 SPI 传输*/
PIN_setOutputValue (pinHandle、AFE_CS、0);//将 CSn 设置为低电平
transferok = spi_transfer (spiHandle、&transaction);
PIN_setOutputValue (pinHandle、AFE_CS、1);//将 CSn 设置为高电平

if (转让)
{
*data =(rxBuf[1]<<16)|(rxBuf[2]<8)|(rxBuf[3]);
}
其他
{
*data = 0;//data 无效
}
}/*

------------------------------------------------ /*
AFE4490寄存器读取函数*/
/*------------------------------------------------ */

signed long AFE4490_reg_read (unsigned char Reg_address)
{
uint32_t configData;
unsigned long RetVal;

SPI_read (ReG_address、&configData);
RetVal = configData;

返回值;
}/*

------------------------------------------------------- /*
AFE4420 SPI 读取启用和禁用函数*/*
---------------------------------------------------- */

void read_enable (void)
{
TxBuf[0]= 0x00;
txBuf[1]= 0x00;
TxBuf[2]= 0x00;
txBuf[3]= 0x01;

PIN_setOutputValue (pinHandle、AFE_CS、0);//将 CSn 设置为低电平
SPI_transfer (spiHandle、&transaction);
PIN_setOutputValue (pinHandle、AFE_CS、1);//将 CSn 设置为高
电平}

void read_disable (void)
{
TxBuf[0]= 0x00;
txBuf[1]= 0x00;
TxBuf[2]= 0x00;
txBuf[3]= 0x00;

PIN_setOutputValue (pinHandle、AFE_CS、0);//将 CSn 设置为低电平
SPI_transfer (spiHandle、&transaction);
PIN_setOutputValue (pinHandle、AFE_CS、1);//将 CSn 设置为高
电平}

/*------------------------------------------------------- /*
AFE4420寄存器初始化函数*/
/*------------------------------------------------ */

void AFE4490_Reg_Init (void)
{
AFE4490_REG_WRITE (0x01、0x003AE8);
AFE4490_REG_WRITE (0x02、0x003CEE);
AFE4490_REG_WRITE (0x03、0x003A98);
AFE4490_REG_WRITE (0x04、0x004E1F);
AFE4490_REG_WRITE (0x05、0x000050);
AFE4490_REG_WRITE (0x06、0x000256);
AFE4490_REG_WRITE (0x07、0x0013D8);
AFE4490_REG_WRITE (0x08、0x0015DE);
AFE4490_REG_WRITE (0x09、0x001388);
AFE4490_REG_WRITE (0x0A、0x0015DF);
AFE4490_REG_WRITE (0x0B、0x002760);
AFE4490_REG_WRITE (0x0C、0x002966);
AFE4490_REG_WRITE (0x0D、0x000006);
AFE4490_REG_WRITE (0x0E、0x001387);
AFE4490_REG_WRITE (0x0F、0x00138E);
AFE4490_REG_WRITE (0x10、0x00270F);
AFE4490_REG_WRITE (0x11、0x002716);
AFE4490_REG_WRITE (0x12、0x003A97);
AFE4490_REG_WRITE (0x13、0x003A9E);
AFE4490_REG_WRITE (0x14、0x004E1F);
AFE4490_REG_WRITE (0x15、0x000000);
AFE4490_REG_WRITE (0x16、0x000005);
AFE4490_REG_WRITE (0x17、0x001388);
AFE4490_REG_WRITE (0x18、0x00138D);
AFE4490_REG_WRITE (0x19、0x002710);
AFE4490_REG_WRITE (0x1A、0x002715);
AFE4490_REG_WRITE (0x1B、0x003A98);
AFE4490_REG_WRITE (0x1C、0x003A9D);
AFE4490_REG_WRITE (0x1D、0x004E1F);
AFE4490_REG_WRITE (0x1E、0x000102);
AFE4490_REG_WRITE (0x1F、0x000000);
AFE4490_REG_WRITE (0x20、0x000000);
AFE4490_REG_WRITE (0x21、0x000000);
AFE4490_REG_WRITE (0x22、0x01FFFF);
AFE4490_REG_WRITE (0x23、0x020100);
AFE4490_REG_WRITE (0x24、0x000000);
AFE4490_REG_WRITE (0x25、0x000000);
AFE4490_REG_WRITE (0x26、0x000000);
AFE4490_REG_WRITE (0x27、0x000000);
AFE4490_REG_WRITE (0x28、0x000000);
AFE4490_REG_WRITE (0x29、0x000000);
AFE4490_REG_WRITE (0x2A、0x000000);
AFE4490_REG_WRITE (0x2B、0x000000);
AFE4490_REG_WRITE (0x2C、0x000000);
AFE4490_REG_WRITE (0x2D、0x000000);
AFE4490_REG_WRITE (0x2E、0x000000);
AFE4490_REG_WRITE (0x2F、0x000000);
AFE4490_REG_WRITE (0x30、0x000000);
}

void enable_pine_interrupt ()
{
PIN_setInterrupt (pinHandle、AFE_RDY | PIN_IRQ_POedge);
}

void disable_pin_interrupt ()
{
PIN_setInterrupt (pinHandle、AFE_RDY | PIN_IRQ_DIS);
} 

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

    您好、Mohammad、

    您是否尝试对已设置的中断信号进行了范围设置? 您在该环路中"卡住"、这意味着您在不断地为某些引脚提供中断服务。 我建议您尝试监控所有 IO 是否有活动、并查看中断引脚是否按预期运行。  

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

    "尝试监控所有 IO 的活动并查看中断引脚是否按预期运行"是什么意思?

    您能更精确一点吗?

    我只将 AFE_RDY 引脚设置为中断。

    在阅读您的回复后、我尝试为 AFE_RDY 创建单独的 pinTable、但问题仍然相同、使用断点进行调试时的程序会卡在同一个"for"和"if"循环中。

    此外、您能否解释一下图像中该环路内发生的情况?

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

    我的意思是、您应该使用示波器或逻辑分析仪等工具来验证 IO 的行为、以及 IO 在切换方面实际发生的情况等

    这项职能的评论和背景相当清楚。 引脚事件导致调用的是引脚驱动程序 SWI 服务例程。 如果您继续重新输入此函数、我假设您经常发生引脚事件。 因此、我建议您在调试过程中尝试验证实际 IO 状态。

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

    我使用 DSO 来检查寄存器的读数是否正确。

    为此、我在 PIN_cConfig 表中将 AFE_RDY 引脚设置为 PIN_IRQ_POedge。

    所附图像显示了输出。

    现在会出现什么问题?

    黄色通道为寄存器读取。

    绿色通道是 CS。

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

    在您的情况下、"AFE_RDY"引脚的状态不是很清楚。 SPI 事务看起来不错、但在我看来、您的问题似乎与未处理的 IO 中断有关、我不希望 SPI 引脚成为其中的一部分。

    您还可以检查"iEvent"位掩码、以了解导致这些事件的 PIN 可能是什么。

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

    您好!

    您是否有任何有关此内容的其他更新要共享?

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

    您好、

    我对不更新深感抱歉。 但我尝试了解决问题、但仍然无法解决问题。 我还没有找到具体的解决办法。 如果有任何其他方法可以解决该问题、请提供帮助。

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

    您好!

    您是否仔细研究了向您提供的两个帖子、这些帖子的结果是什么?

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

    由于我们尚未收到您的回复、我将关闭此帖子。