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.

[参考译文] CCS/CC1350:使用 SPI 接口时 Raspberry Pi 3和 CC1350不同步

Guru**** 2587365 points
Other Parts Discussed in Thread: CC1350

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/595969/ccs-cc1350-raspberry-pi-3-and-cc1350-not-in-sync-using-an-spi-interface

器件型号:CC1350

工具/软件:Code Composer Studio

我们尝试使用 SPI 将 CC1350连接到 Raspberry Pi 3。 我们观察到器件不同步、如果有任何建议、我们会不胜感激。 附件是代码和输出。
其中 PI 向 CC1350发送两个数字以添加或减去并返回结果。

有3个文件:  
1. rpi_spi2.cpp 为在 Raspberry Pi 上运行的代码进行编码

/*********
SPI_Raspi_Arduino
将 Raspberry Pi 配置为 SPI 主设备、然后
演示了基本的双向通信方案
Arduino 从站。 Raspberry Pi 发送数据
对执行加法和减法的命令
且 Ardunio 返回结果

编译字符串:
G++-o SPI_Raspi_Arduino SPI_Raspi_Arduino.cpp
秘书长的报告 /

#include
#include
#include
#include
#include
#include


使用命名空间 std;

#define DELAY_microsec 10.

/*********
内部管理变量
秘书长的报告 /
INT 结果;
int fd;

/*********
声明函数
秘书长的报告 /

int spiTxRx (unsigned char txDat);
int sendCommand (char i、int j、int k);

/*********
主程序
秘书长的报告 /

int main (空)

int i=0;

INT MAX=100;
/*********
设置 SPI
打开文件 spidev0.0 (芯片启用0)以进行读取/写入访问
使用文件描述符"fD"
配置传输速度(1MkHz)
秘书长的报告 /

FD =开路("/dev/spidev0.0、O_RDWR);

unsigned char SPI_MODE = SPI_MODE_3;
// SPI_MODE_0 => CPOL=0;CPHA=0
// SPI_MODE_1 => CPOL=0;CPHA=1
// SPI_MODE_2 => CPOL=1;CPHA=0
// SPI_MODE_3 => CPOL=1;CPHA=1
//将模式更改为所需的值
ioctl (FD、SPI_IOC_WR_MODE、&SPI_MODE);

unsigned int speed = 1000000;
ioctl (fd、SPI_IOC_WR_MAX_SPEED_Hz、&SPEED);
睡眠(1);

/*********
一个不断循环、该循环会重复发送演示
命令到 Arduino 并显示结果
秘书长的报告 /

while (1)

i++;
如果(i=MAX) i=0;
COUT <<"循环编号"<<(i)<<结束;
结果= sendCommand ('a'、510、655);

COUT <<"添加结果:"<< endl;
COUT <<"510 + 655 ="<<(int)(结果)<< endl;


结果= sendCommand ("S"、1000、250);

COUT <<"减影结果:"<< endl;
COUT <<"1000 - 250 ="<<(int)(结果)<< endl <endl;

睡眠(1);

/*********
spiTxRx
通过 SPI 器件发送一个字节、并返回一个字节
结果。

根据定义建立数据结构 SPI_Ioc_transfer
并 spidev.h 加载各种成员以传递数据
以及通过 IOCTL 将配置参数添加到 SPI 器件

局部变量 txDat 和 rxDat 由定义和传递
基准。
秘书长的报告 /

int spiTxRx (无符号字符 txDat)


unsigned char rxDat;

struct spi_oco_transfer spi;

memset (&SPI、0、sizeof (SPI));

spi.TX_Buf =(无符号长整型)&txDat;
spi.rx_Buf =(无符号长整型)&rxDat;
spi.len = 1;

ioctl (FD、SPI_IOC_MESSAGE (1)、&SPI);

返回 rxDat;


/*********
sendCommand
使用 spiTxRx 函数的协议演示
向 Arduino 发送格式化命令序列/数据包
并捕获结果
秘书长的报告 /


int sendCommand (char 命令、int j、int k)

unsigned char resultByte;
bool ack;

/*********
联合体允许变量占用相同的存储器空间
在8位和之间来回移动的便捷方法
16位值等

此处声明了三个联合体:两个表示要使用的参数
将命令传递给 Arduino、并接收命令
结果
秘书长的报告 /

UNION p1Buffer_T

int p1int;
unsigned char p1char [2];
} p1Buffer;

UNION p2Buffer_T

int p2int;
unsigned char p2char [2];
} p2Buffer;

联合结果 Buffer_T

int resultInt;
unsigned char resultchar [2];
} resultBuffer;


p1Buffer.p1Int = j;
p2Buffer.p2Int = k;
resultBuffer.resultInt = 0;

/*********
一个初始握手序列发送一个字节启动代码
('c')并不停循环、直到它接收到一个字节
确认代码('A')并将 ACK 标志设置为 true。
(请注意、循环还在发送命令字节时发送命令字节
仍然处于握手序列、以避免浪费发送
周期。)
秘书长的报告 /

操作

ACK = false;

spiTxRx ('c');
usleep (delay_microsec);


resultByte = spiTxRx (command);
if (resultByte ='A')

ACK = true;

usleep (delay_microsec);


while (ack == false);

/*********
每次发送一个字节的参数。
秘书长的报告 /

spiTxRx (p1Buffer.p1Char[0]);
usleep (delay_microsec);


spiTxRx (p1Buffer.p1Char[1]);
usleep (delay_microsec);


spiTxRx (p2Buffer.p2Char[0]);
usleep (delay_microsec);


spiTxRx (p2Buffer.p2Char[1]);
usleep (delay_microsec);

/*********
再按两个零、这样 Arduino 就可以返回
结果
秘书长的报告 /


resultByte = spiTxRx (0);
resultBuffer.resultChar[0]= resultByte;
usleep (delay_microsec);


resultByte = spiTxRx (0);
resultBuffer.resultChar[1]= resultByte;
返回 resultBuffer.resultInt;

SPI_cc130.c 是在 CC1350上运行的代码

/*
*==== empty.c ======
*
#define MSGSIZE 10 //数据包中的字节数,包括 pkt. number 作为第一个字节
#define MAX_PKT_NUM 20 //从0开始前数据包的最大数量

/* for usleep()*/
#include
#include
#include

/*驱动程序头文件*/
#include
//#include
//#include
#include
#include
#include

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

//#include
//#include

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

//全局变量
uint8_t rxBuf[1];//接收缓冲区
uint8_t txBuf[1];
//{55、77、88、99};//传输缓冲区
/*********
根据 SPI_Raspi_Arduino 进行了改编
将 ATMEGA 配置为 SPI 从器件并进行演示
基本双向通信方案
Raspberry Pi SPI 主设备将命令传输到
对一对整数和执行加法和减法
Ardunio 传输结果
秘书长的报告 /

/*********
全局变量
-receiveBuffer[]和 dat 用于捕获传入数据
进行了比较
-marker 用作指针来跟踪电流
数据包中的位置
(小部分 /

unsigned char receiveBuffer[5];
unsigned char dat;
无符号字符标记= 0;


/*********
联合体允许变量占用相同的存储器空间 A
在8位和之间来回移动的便捷方法
16位值等 此处声明了三个联合体:
其中两个用于在命令中传递给 Arduino 的参数
另一个用于接收结果
(小部分 /

UNION

int p1int;
unsigned char p1char [2];
} p1Buffer;

UNION

int p2int;
unsigned char p2char [2];
} p2Buffer;


UNION

int resultInt;
unsigned char resultchar [2];
} resultBuffer;


/*
//回调函数
静态空转移回调(SPI_Handle handle、SPI_Transaction *事务)

静态 char pktNum=0;//用于保存数据包编号
txBuf[0]= pktNum;
pktNum++;
如果(pktNum=MAX_PKT_NUM) pktNum=0;

//开始另一个传输
SPI_TRANSFCTION (handle、transaction);
//将 LED 切换为指示器
GPIO_TOGGLE (Board_GPIO_LED1);


*

/*********
SpiHandler
使用标记变量将跟踪当前位置保持在中
传入数据包并执行相应的操作
0 -等待接收起始字节-收到后发送
确认字节
1 -添加或减法的命令
2-5 -要添加或减去的两个整数参数
-当接收到最后一个字节(5)时,调用
ExecuteCommand 函数并加载的第一个字节
SPDR 中
6 -发送结果的第一个字节并加载
SPDR 中的第二个字节
7 -发送结果的第二个字节并进行复位
标记
秘书长的报告 /
void ExecuteCommand (void);//Fwd 定义

//void spiHandler()
静态空转移回调(SPI_Handle handle、SPI_Transaction *事务)

开关(标记)

情况0:
DAT = rxBuf[0];
如果(dat ='c')

txBuf[0]='A';
Marker++;

中断;
案例1:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
中断;
案例2:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
中断;
案例3:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
中断;
案例4:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
中断;
情况5:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
ExecuteCommand();
txBuf[0]= resultBuffer.resultChar[0];
中断;
案例6:
Marker++;
txBuf[0]= resultBuffer.resultChar[1];
中断;
案例7:
DAT = rxBuf[0];
标记=0;

//将 LED 切换为指示器
GPIO_TOGGLE (Board_GPIO_LED1);

//开始另一个传输
SPI_TRANSFCTION (handle、transaction);

/*********
ExecuteCommand
当接收到完整的5字节命令序列时
从 receiveBuffer 重新构成字节变量
解析命令(添加或减)并执行整数
指示的操作-结果将位于 resultBuffer 中
秘书长的报告 /


空 ExecuteCommand (空)

p1Buffer.p1Char[0]= receiveBuffer[1];
p1Buffer.p1Char[1]= receiveBuffer[2];
p2Buffer.p2Char[0]= receiveBuffer[3];
p2Buffer.p2Char[1]=接收缓冲区[4];

if (receiveBuffer[0]='A')

resultBuffer.resultInt = p1Buffer.p1Int + p2Buffer.p2Int;

否则(receiveBuffer[0]=='s')

resultBuffer.resultInt = p1Buffer.p1Int - p2Buffer.p2Int;

否则{
resultBuffer.resultInt = 0;

/*
*==== mainThread ====
*
void * mainThread (void * arg0)

/* 1秒延迟*/
uint32_t 时间= 1;
int i=0;
char ack;

SPI_Handle 句柄;
SPI_Params 参数;
SPI_Transaction 事务;

/*调用驱动程序初始化函数*/
GPIO_init();
// I2C_init ();
// SDSPI_init ();
spi_init();
// uart_init();
// Watchdog_init();


//初始化 SPI 并指定非默认参数
SPI_PARAMS_INIT (params);
params.bitrate = 1000000;
params.frameFormat = SPI_POL1_PHA1;
params.mode = SPI_SLAVE;
//在接收到'c'并发送'a'的位置设置同步锁定,直到
//满足锁定要求
transaction.count = 1;
txBuf[0]='0';rxBuf[0]= 0;
transaction.txBuf = txBuf;
transaction.rxBuf = rxBuf;


//现在设置为数据包模式
params.transferMode = SPI_MODE_CALLACK;
params.transferCallbackFxn = transferCallback;

System_printf ("在 ROV 中启动 SysMin 内容。\n");

/* SysMin 仅在您调用 flush 或 exit 时才会打印到控制台*/
system_flush();


//打开 SPI 并执行传输
句柄= SPI_OPEN (Board_SPI0、&params);
//启动第一个传输
SPI_TRANSFCTION (句柄、事务);
/*
对于(i=0;i<40;i++){
transaction.txBuf = txBuf+I;
transaction.rxBuf = rxBuf+I;
SPI_TRANSFCTION (句柄、事务);

*

/*打开用户 LED */
GPIO_WRITE (Board_GPIO_LED0、Board_GPIO_LED_ON);
GPIO_WRITE (Board_GPIO_LED1、Board_GPIO_LED_ON);

同时(2){
睡眠(时间);
GPIO_TOGGLE (Board_GPIO_LED0);

3. rspi2_out.txt 是圆周率日的输出。 它显示 SPI 不同步并产生错误的结果。

pi@raspberrypi $./RPI_SPI2
环路1
添加结果:
510 + 655 = 1165
减法结果:
1000 - 250 = 750

环路2
添加结果:
510 + 655 = 1165
减法结果:
1000 - 250 = 750

环路3
添加结果:
510 + 655 = 1165
减法结果:
1000 - 250 = 750

环路4
添加结果:
510 + 655 = 24929
减法结果:
1000 - 250 = 24929

环路编号5
添加结果:
510 + 655 = 24929
减法结果:
1000 - 250 = 24929

环路6
添加结果:
510 + 655 = 24929
减法结果:
1000 - 250 = 24929

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

    快速查看您的代码、您的 Raspberry Pi 在每次传输之间只等待10微秒。 这为下一次传输到 TI-RTOS 中的设置留出了极少的时间。 尝试将延迟增加到几毫秒。

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

    感谢您的反馈 Michel。 我们一直尝试到1ms。 您能不能建议您考虑延迟多大? 1ms 本身看起来很像。

    *更新*

    在10ms 和50ms 时,系统似乎挂起。 CC1350上的 CPU 负载图显示接近100%的使用-器件侧的情况并非如此。

    此致、

    Pushkar