TI中文支持网
TI专业的中文技术问题搜集分享网站

LAUNCHXL-CC1310: CC1310 iic 卡死

Part Number:LAUNCHXL-CC1310Other Parts Discussed in Thread:CC1310, CC1350, UNIFLASH

1. 板子上没有接iic设备时,调用iic接口会卡死,在调试模式是正常的,断开调试器,直接上电会卡死!rfPacketTx_CC1310_LAUNCHXL_nortos_ccs.zip

2.

/*
 * Copyright (c) 2019, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *notice, this list of conditions and the following disclaimer in the
 *documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *its contributors may be used to endorse or promote products derived
 *from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/***** Includes *****/
/* Standard C Libraries */
#include <stdlib.h>
#include <unistd.h>

/* TI Drivers */
#include <ti/drivers/rf/RF.h>
#include <ti/drivers/PIN.h>
#include <ti/drivers/I2C.h>
#include <ti/drivers/pin/PINCC26XX.h>

/* Driverlib Header files */
#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)

/* Board Header files */
#include "Board.h"
#include "CC1310_LAUNCHXL.h"
#include "smartrf_settings/smartrf_settings.h"

#include <ti/drivers/ADCBuf.h>
#include <ti/drivers/adcbuf/ADCBufCC26XX.h>

/***** Defines *****/

/* Do power measurement */
//#define POWER_MEASUREMENT
#define M117_ENABLE 1

/* Packet TX Configuration */
#define PAYLOAD_LENGTH10
#ifdef POWER_MEASUREMENT
#define PACKET_INTERVAL5  /* For power measurement set packet interval to 5s */
#else
#define PACKET_INTERVAL500000  /* Set packet interval to 500000us or 500ms */
#endif

/***** Prototypes *****/

/***** Variable declarations *****/
static RF_Object rfObject;
static RF_Handle rfHandle;

/* Pin driver handle */
static PIN_Handle ledPinHandle;
static PIN_State ledPinState;

static uint8_t packet[PAYLOAD_LENGTH];
static uint16_t seqNumber;

/*
 * Application LED pin configuration table:
 *- All LEDs board LEDs are off.
 */
PIN_Config pinTable[] =
{Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
#ifdef POWER_MEASUREMENT
#if defined(Board_CC1350_LAUNCHXL)Board_DIO30_SWPWR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
#endif
#endifPIN_TERMINATE
};

/***** Function definitions *****/
extern void iic_map(uint8_t sclPin,uint8_t sdaPin);

void *mainThread(void *arg0)
{

#if M117_ENABLE// One-time init of I2C driverI2C_init();// initialize optional I2C bus parametersI2C_Params params;I2C_Params_init(&params);params.bitRate = I2C_100kHz;params.transferMode = I2C_MODE_BLOCKING;// Open I2C bus for usage//I2C_Handle i2cHandle = I2C_open(0, &params);// Initialize slave address of transactionI2C_Transaction transaction = {0};transaction.slaveAddress = 0x44;I2C_Handle i2cHandle;I2C_Handle i2cHandle2;i2cHandle = I2C_open(0, &params);

#endifRF_Params rfParams;RF_Params_init(&rfParams);/* Open LED pins */ledPinHandle = PIN_open(&ledPinState, pinTable);if (ledPinHandle == NULL){while(1);}

#ifdef POWER_MEASUREMENT
#if defined(Board_CC1350_LAUNCHXL)/* Route out PA active pin to Board_DIO30_SWPWR */PINCC26XX_setMux(ledPinHandle, Board_DIO30_SWPWR, PINCC26XX_MUX_RFC_GPO1);
#endif
#endifRF_cmdPropTx.pktLen = PAYLOAD_LENGTH;RF_cmdPropTx.pPkt = packet;RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;/* Request access to the radio */
#if defined(DeviceFamily_CC26X0R2)rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioSetup, &rfParams);
#elserfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
#endif// DeviceFamily_CC26X0R2/* Set the frequency */RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);while(1){

#if M117_ENABLE//i2cHandle = I2C_open(0, &params);uint8_t iic_write_data[] = {0xCC,0x44};uint8_t iic_read_data[3];// Write to I2C slave devicetransaction.writeBuf = iic_write_data;transaction.writeCount = sizeof(iic_write_data);transaction.readCount = 0;I2C_transfer(i2cHandle, &transaction);//I2C_close(i2cHandle);usleep(10000);//i2cHandle = I2C_open(0, &params);// Read from I2C slave devicetransaction.readBuf = iic_read_data;transaction.readCount = sizeof(iic_read_data);transaction.writeCount = 0;I2C_transfer(i2cHandle, &transaction);packet[2] = iic_read_data[0];packet[3] = iic_read_data[1];packet[4] = iic_read_data[2];//I2C_close(i2cHandle);//usleep(5000);//屏蔽这行会死机//I2C_cancel(i2cHandle);

#if 1//iic_map(IOID_20,IOID_21);//i2cHandle = I2C_open(0, &params);// Write to I2C slave devicetransaction.writeBuf = iic_write_data;transaction.writeCount = sizeof(iic_write_data);transaction.readCount = 0;I2C_transfer(i2cHandle, &transaction);//I2C_close(i2cHandle);usleep(10000);//i2cHandle = I2C_open(0, &params);// Read from I2C slave devicetransaction.readBuf = iic_read_data;transaction.readCount = sizeof(iic_read_data);transaction.writeCount = 0;I2C_transfer(i2cHandle, &transaction);packet[2] = iic_read_data[0];packet[3] = iic_read_data[1];packet[4] = iic_read_data[2];//I2C_close(i2cHandle);//iic_map(IOID_4,IOID_5);

#endif



#if 0//iiC_map(IOID_20,IOID_21);i2cHandle2 = I2C_open(1, &params);// Write to I2C slave devicetransaction.writeBuf = iic_write_data;transaction.writeCount = sizeof(iic_write_data);transaction.readCount = 0;I2C_transfer(i2cHandle2, &transaction);//I2C_close(i2cHandle2);usleep(10000);//i2cHandle2 = I2C_open(0, &params);// Read from I2C slave devicetransaction.readBuf = iic_read_data;transaction.readCount = sizeof(iic_read_data);transaction.writeCount = 0;I2C_transfer(i2cHandle2, &transaction);packet[2] = iic_read_data[0];packet[3] = iic_read_data[1];packet[4] = iic_read_data[2];I2C_close(i2cHandle2);//iiC_map(IOID_4,IOID_5);
#endif

#endif/* Create packet with incrementing sequence number and random payload */packet[0] = (uint8_t)(seqNumber >> 8);packet[1] = (uint8_t)(seqNumber++);//uint8_t i;//for (i = 2; i < PAYLOAD_LENGTH; i++)//{//packet[i] = rand();//}packet[2] = 2;packet[3] = 3;packet[4] = 4;/* Send packet */RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx,RF_PriorityNormal, NULL, 0);switch(terminationReason){case RF_EventLastCmdDone:// A stand-alone radio operation command or the last radio// operation command in a chain finished.break;case RF_EventCmdCancelled:// Command cancelled before it was started; it can be caused// by RF_cancelCmd() or RF_flushCmd().break;case RF_EventCmdAborted:// Abrupt command termination caused by RF_cancelCmd() or// RF_flushCmd().break;case RF_EventCmdStopped:// Graceful command termination caused by RF_cancelCmd() or// RF_flushCmd().break;default:// Uncaught error eventwhile(1);}uint32_t cmdStatus = ((volatile RF_Op*)&RF_cmdPropTx)->status;switch(cmdStatus){case PROP_DONE_OK:// Packet transmitted successfullybreak;case PROP_DONE_STOPPED:// received CMD_STOP while transmitting packet and finished// transmitting packetbreak;case PROP_DONE_ABORT:// Received CMD_ABORT while transmitting packetbreak;case PROP_ERROR_PAR:// Observed illegal parameterbreak;case PROP_ERROR_NO_SETUP:// Command sent without setting up the radio in a supported// mode using CMD_PROP_RADIO_SETUP or CMD_RADIO_SETUPbreak;case PROP_ERROR_NO_FS:// Command sent without the synthesizer being programmedbreak;case PROP_ERROR_TXUNF:// TX underflow observed during operationbreak;default:// Uncaught error event - these could come from the// pool of states defined in rf_mailbox.hwhile(1);}

#ifndef POWER_MEASUREMENTPIN_setOutputValue(ledPinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
#endif/* Power down the radio */RF_yield(rfHandle);

#ifdef POWER_MEASUREMENT/* Sleep for PACKET_INTERVAL s */sleep(PACKET_INTERVAL);
#else/* Sleep for PACKET_INTERVAL us */usleep(PACKET_INTERVAL);
#endif}
}

Alex Zhang:

您好,我需要一些时间来查看并测试您的代码,谢谢。

,

Alex Zhang:

您好,如果您这边外接iic设备呢,会出现什么现象

,

genyi liu:

就不会死机,正常工作

,

genyi liu:

通过led是否在闪烁,来判断是否被卡死

,

Alex Zhang:

现在我这边运行代码,led是闪烁状态。

,

genyi liu:

你是直接跑的是压缩包的工程吗。

,

Alex Zhang:

您好,您的代码中rfPacket.c文件中,第156行代码开始至189行,

#if M117_ENABLE//i2cHandle = I2C_open(0, &params);uint8_t iic_write_data[] = {0xCC,0x44};uint8_t iic_read_data[3];// Write to I2C slave devicetransaction.writeBuf = iic_write_data;transaction.writeCount = sizeof(iic_write_data);transaction.readCount = 0;I2C_transfer(i2cHandle, &transaction);//I2C_close(i2cHandle);usleep(10000);//i2cHandle = I2C_open(0, &params);// Read from I2C slave devicetransaction.readBuf = iic_read_data;transaction.readCount = sizeof(iic_read_data);transaction.writeCount = 0;I2C_transfer(i2cHandle, &transaction);packet[2] = iic_read_data[0];packet[3] = iic_read_data[1];packet[4] = iic_read_data[2];//I2C_close(i2cHandle);//usleep(5000);//ÆÁ±ÎÕâÐлáËÀ»ú//I2C_cancel(i2cHandle);#if 1//iic_map(IOID_20,IOID_21);//i2cHandle = I2C_open(0, &params);// Write to I2C slave devicetransaction.writeBuf = iic_write_data;transaction.writeCount = sizeof(iic_write_data);transaction.readCount = 0;I2C_transfer(i2cHandle, &transaction);

我看到您的#define M117_ENABLE 1 也是1

这段代码是什么意思,我不太明白。

,

Alex Zhang:

对的 跑的是您这边发的工程代码。

,

genyi liu:

表明那段代码也要执行,实际代码就是运行那段代码就出问题了。发现iic读失败后,继续读写就会错

,

Alex Zhang:

那您定义的 #if 1 可以解释一下吗

,

genyi liu:

就是使能,方便注释代码用的

,

Alex Zhang:

还有就是 我现在开发板状态是 闪烁,这个状态是 您这边说的 “锁死” 状态吗?

,

genyi liu:

压缩包应该有已经生成的固件,能否直接对比下,跟你生成的固件有没有区别

,

genyi liu:

闪烁就说明有正常发数据,程序的逻辑是每隔500ms 执行下iic,并发送数据出去。闪烁了说明程序在正常工作的

,

Alex Zhang:

genyi liu said:表明那段代码也要执行,实际代码就是运行那段代码就出问题了。发现iic读失败后,继续读写就会错

iic在读取数据时,如果某一个时序在通信过程中,没有接收到反馈或者是您这边说的没有接入外设,可能会使引脚电平跳变引起通信错误,导致iic通信死锁。

另外:

IIC的SDA和SCL在空闲时都处于高电平状态。

在实际使用中,IIC比较容易出现一个问题就是死锁,主要表现是:SCL为高,SDA一直为低。

在IIC主设备进行读写操作的过程中,主设备在开始信号后控制SCL生产8个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。

如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,就会继续IIC的应答,将SDA一直拉为低电平,直到SCL变为低电平,才会结束应答信号。而对于IIC主设备来说,复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为IIC总线被占用,会一直等待SCL和SDA信号变为高电平。

这样,IIC主设备等待从设备释放SDA信号,而同时IIC从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,IIC总线进入一种死锁状态。

同样的,当IIC进行读操作,从设备应答后输出数据,如果在这个时候IIC主设备异常复位而此时从设备输出的数据正好为0,也会导致IIC总线进入死锁状态。

在下面我为您这边解决死锁问题提供了一些思路:

1. 主设备在检测到SDA被拉低超过一段时间后,主动复位从设备从而使之释放SDA。这种方法的前提是主设备连接了从设备的复位引脚,主设备就可以控制从设备的复位管脚使之复位。

2. 主设备在检测到SDA被拉低超过一段时间后,推送9个Clock到时钟总线上,取走从设备的ACK位,从而使从设备释放SDA为高电平。

3. 在主从设备之间串联一个IIC缓冲器,该缓冲器可以自动检测死锁状态。当检测到死锁时会主动断开与主设备的连接,并发送9个Clock给从设备,等从设备释放SDA线后重新与主设备建立连接。

IIC的死锁问题无法从根本上避免,除了主设备的异常复位导致IIC死锁,从设备在正常通信过程中也有可能异常拉低SDA导致死锁。所以软件在设计时要考虑当死锁发生时能够从死锁中恢复,使得IIC通信可以继续进行。

,

Alex Zhang:

您好,我这边没有compare软件,是这样,我把生成的文件,给您上传,您这边下载之后可以自行比较。

我给您邮箱发过去,提供一个邮箱地址。

,

genyi liu:

1. 有没有测试那个压缩包的固件,并且出现iic卡死的现象?

2. 想先知道这个问题的根源是软件问题还是eclipse编译器问题?

,

genyi liu:

1. 好的,我的邮箱 liugenyi@jupiter-i.com

2. 麻烦你测试下压缩包的固件,这样好分析下问题根源

,

Alex Zhang:

是这样,判断问题的出现,您这边可以提供邮箱,你用自己的开发板去烧录我的out文件,然后看看是不是正常。

如果这样是正常的,那就是编译器的问题。

,

genyi liu:

out 要怎么烧录

,

Alex Zhang:

直接烧录就行了。uniflash软件打开,连接开发板,然后选择out文件,然后load。

1.

2.

,

genyi liu:

好的,那我去下载uniflash软件

,

Alex Zhang:

我给您发链接,直接下载

www.ti.com.cn/…/UNIFLASH

,

genyi liu:

好的,最好还是双向确认下,就是互相烧录下对方的固件,测试下比较好定位问题

,

genyi liu:

我对比下代码,固件是不一样的

,

genyi liu:

我用的CCS9.0软件

sdksimplelink_cc13x0_sdk_4_20_02_07

,

Alex Zhang:

那就是这边编译器出现问题了

我的ccs版本号: Version: 12.2.0.00009 

跟sdk版本没太大关系

,

genyi liu:

用ccs12也编译下,错误还是出现了

,

genyi liu:

方便烧录下压缩包的文件,测试下bug是否能复现

,

genyi liu:

这个是没有接iic从设备,出现这个bug,要怎么恢复iic

,

genyi liu:

解决这个bug的一种方法,就是在读后面加延时就可以恢复正常,我觉得这有可能是潜在一个大bug.

出现bug的现象是有条件的,把中间的写操作去掉,bug就消失了

,

Alex Zhang:

genyi liu said:好的,最好还是双向确认下,就是互相烧录下对方的固件,测试下比较好定位问题

好的 我需要一些时间。

,

genyi liu:

用逻辑分析查看波形,卡死时,SCL 和SDA 都是高电平 

,

Alex Zhang:

Alex Zhang said:

IIC的SDA和SCL在空闲时都处于高电平状态。

在实际使用中,IIC比较容易出现一个问题就是死锁,主要表现是:SCL为高,SDA一直为低。

在IIC主设备进行读写操作的过程中,主设备在开始信号后控制SCL生产8个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。

如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,就会继续IIC的应答,将SDA一直拉为低电平,直到SCL变为低电平,才会结束应答信号。而对于IIC主设备来说,复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为IIC总线被占用,会一直等待SCL和SDA信号变为高电平。

这样,IIC主设备等待从设备释放SDA信号,而同时IIC从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,IIC总线进入一种死锁状态。

同样的,当IIC进行读操作,从设备应答后输出数据,如果在这个时候IIC主设备异常复位而此时从设备输出的数据正好为0,也会导致IIC总线进入死锁状态。

在下面我为您这边解决死锁问题提供了一些思路:

1. 主设备在检测到SDA被拉低超过一段时间后,主动复位从设备从而使之释放SDA。这种方法的前提是主设备连接了从设备的复位引脚,主设备就可以控制从设备的复位管脚使之复位。

2. 主设备在检测到SDA被拉低超过一段时间后,推送9个Clock到时钟总线上,取走从设备的ACK位,从而使从设备释放SDA为高电平。

3. 在主从设备之间串联一个IIC缓冲器,该缓冲器可以自动检测死锁状态。当检测到死锁时会主动断开与主设备的连接,并发送9个Clock给从设备,等从设备释放SDA线后重新与主设备建立连接。

IIC的死锁问题无法从根本上避免,除了主设备的异常复位导致IIC死锁,从设备在正常通信过程中也有可能异常拉低SDA导致死锁。所以软件在设计时要考虑当死锁发生时能够从死锁中恢复,使得IIC通信可以继续进行。

还是我在上面提到的这个内容,您可以尝试使用上述思路解决问题。但是我仍然好奇我的编译器去编译您的工程进行烧录,为什么是正常的。

,

Alex Zhang:

您这边使用uniflash烧录out文件之后,什么现象?

,

Alex Zhang:

烧录我给您发的out文件是什么现象。

,

genyi liu:

还是卡死,灯也不闪烁。我那个有问题的固件还会闪一下,所以要确认下你用的是什么板子来测试的?

,

genyi liu:

 这是我测试的主板

,

Alex Zhang:

我这边用的开发板跟您的是一样的。只不过是跳线帽我全部都插上了。

,

genyi liu:

那Green的灯正常闪烁?看起来是板子的问题

,

Alex Zhang:

您更换一个开发板试一下。

,

genyi liu:

更换了,问题还是一样出现!

,

Alex Zhang:

有点奇怪 我明天到公司再看一下。看看到底是哪个地方出现的问题。

,

genyi liu:

好的,期待你的结果

,

Alex Zhang:

您好,您这边使用您的开发板去跑sdk中的例程,有问题吗?

因为我看到我们的开发板同样是cc1310 pad但是仔细看版本是有区别的,我的是Rev 1.4.1     PG2.1   FW Rev 1.0

,

Alex Zhang:

我今天在我的这个版本的开发板烧录您编译生成的固件,测试效果,led绿灯闪烁。

,

genyi liu:

版本是rev A

,

Alex Zhang:

您好,很抱歉我这边没有revA版本的开发板所以没办法进行测试

您这边如果使用ti的例程烧录进您的revA版本的开发板中,可以实现示例代码中的实验现象吗?

,

genyi liu:

死机、死机,还是死机,开发CC1310有点难哦?

,

Alex Zhang:

您好,很抱歉我这边没有revA版本的开发板所以没办法进行测试

您这边如果使用ti的例程烧录进您的revA版本的开发板中,可以实现示例代码中的实验现象吗?

赞(0)
未经允许不得转载:TI中文支持网 » LAUNCHXL-CC1310: CC1310 iic 卡死
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1