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

CC2640R2F SPI SLAVE收不到数据

准备使用CC2640R2F作为SPI从机响应主机发过来的命令,然后参考了C:\ti\simplelink_cc2640r2_sdk_2_30_00_28\examples\rtos\CC2640R2_LAUNCHXL\drivers\spislave中的例程

将IO口重定向后,发现SPI从机收不到数据,SPI时序通过示波器和逻辑分析仪观察过是OK的,

此外Sem_init()返回失败,后来用Flag代替跳过这个问题

另外用SPI MASTER的例程是没问题的

所以这里有几个问题

1. SPI收不到数据,是什么原因引起的

2. 同样是导入的例程,为什么从机例程的Sem_init()会返回失败,而主机例程则不会

3.如果要实现从机不定长SPI数据的接收,有没有其他底层驱动去替代当前的DMA机制

由于省略了Slave_Ready信号线,于是在主机MasterReady后延迟了100ms

从机关键代码如下

#define THREADSTACKSIZE (1024)

#define SPI_MSG_LENGTH (30)
#define SEND_MSG ("Hello from master, msg#: 1")

uint8_t RxBuffer[SPI_MSG_LENGTH];
uint8_t TxBuffer[SPI_MSG_LENGTH];

sem_t Sem;

void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction)
{
    sem_post(&Sem);
}

void *masterThread(void *arg0)
{
SPI_Handle Spi;
SPI_Params spiParams;
SPI_Transaction transaction;
bool transferOK;
int32_t status;

GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_INPUT);
status = sem_init(&Sem, 0, 0);
if (status != 0) {
while(1);
}

SPI_Params_init(&spiParams);
spiParams.frameFormat = SPI_POL0_PHA0;
spiParams.mode = SPI_SLAVE;
spiParams.transferCallbackFxn = transferCompleteFxn;
spiParams.transferMode = SPI_MODE_CALLBACK;
Spi = SPI_open(CC2640R2_LAUNCHXL_SPI0, &spiParams);
if (Spi == NULL) {
while (1);
}

strncpy((char *)TxBuffer, SEND_MSG, SPI_MSG_LENGTH);
memset((void *) RxBuffer, 0, SPI_MSG_LENGTH);

//while (GPIO_read(Board_SPI_MASTER_READY)) {}

transaction.count = SPI_MSG_LENGTH;
transaction.txBuf = (void *) TxBuffer;
transaction.rxBuf = (void *) RxBuffer;
transferOK = SPI_transfer(Spi, &transaction);
if (transferOK) {
sem_wait(&Sem);
}
else {
while(1);
}

SPI_close(Spi);
while(1);
}

void *mainThread(void *arg0)
{
pthread_t thread0;
pthread_attr_t attrs;
struct sched_param priParam;
int retc;
int detachState;

GPIO_init();
SPI_init();

/* Create application threads */
pthread_attr_init(&attrs);

detachState = PTHREAD_CREATE_DETACHED;
/* Set priority and stack size attributes */
retc = pthread_attr_setdetachstate(&attrs, detachState);
if (retc != 0) {
/* pthread_attr_setdetachstate() failed */
while (1);
}

retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
if (retc != 0) {
/* pthread_attr_setstacksize() failed */
while (1);
}

/* Create master thread */
priParam.sched_priority = 1;
pthread_attr_setschedparam(&attrs, &priParam);

retc = pthread_create(&thread0, &attrs, masterThread, NULL);
if (retc != 0) {
/* pthread_create() failed */
while (1);
}

return (NULL);
}

Alvin Chen:

不定长你只能尝试自己写一个看看。
www.ti.com/…/swcu117h.pdf
C:\TI\simplelink_cc2640r2_sdk_2_40_00_32\source\ti\drivers\spi

user4649054:

回复 Alvin Chen:

那为什么例程改编的代码收不到数据,这是为什么

Alvin Chen:

回复 user4649054:

PHA and POL 有关参考:
e2e.ti.com/…/680824

user4649054:

回复 Alvin Chen:

我看了一下,改成了POL=0,PHA=1,但是第一个字节始终收到的是0,这是为什么?

const PIN_Config BoardGpioInitTable[] = { CC2640R2_LAUNCHXL_SPI0_MOSI | PIN_INPUT_EN | PIN_PULLDOWN, /* SPI master out – slave in */ CC2640R2_LAUNCHXL_SPI0_MISO | PIN_INPUT_EN | PIN_PULLDOWN, /* SPI master in – slave out */ CC2640R2_LAUNCHXL_SPI0_CLK | PIN_INPUT_EN | PIN_PULLDOWN, /* SPI clock */

PIN_TERMINATE};

#define CC2640R2_LAUNCHXL_SPI0_MISO IOID_6 /* RF1.20 */#define CC2640R2_LAUNCHXL_SPI0_MOSI IOID_3 /* RF1.18 */#define CC2640R2_LAUNCHXL_SPI0_CLK IOID_2 /* RF1.16 */#define CC2640R2_LAUNCHXL_SPI0_CSN PIN_UNASSIGNED

这里有个疑问,CSN为什么设为UNASSIGNED,

我将MASTER_READY对应的IOID_0填入CC2640R2_LAUNCHXL_SPI0_CSN发现反而收不到数据了

后面不得已CS拉低的判断放在代码中判断了

Alvin Chen:

回复 user4649054:

你看下面的20.4.4.4

www.ti.com/…/swcu117h.pdf

MODE 0: CPOL=0, CPHA=0 ,CLK限制状态为低电平,第一个边沿采样,所以是上升沿采样。
MODE 1: CPOL=0, CPHA=1,CLK限制状态为低电平,第二个边沿采样,所以是下降沿采样。
MODE 2: CPOL=1, CPHA=0 ,CLK限制状态为高电平,第一个边沿采样,所以是下降沿采样。
MODE 3: CPOL=1, CPHA=1 ,CLK限制状态为高电平,第二个边沿采样,所以是上升沿采样。
———————

如果你没有设置则为UNASSIGNED,应该就不会等select芯片,你设置了pin就需要等待select信号。
blog.csdn.net/…/50452355

user4649054:

回复 Alvin Chen:

可能你没明白我的意思

首先SPI主机接沿用例程发送/接收30个字节的数据,发送的内容为0~29,

SPI从机发送的内容为字符串"Hello from slaver, msg#: 1",主机发起30个字节的SPI通信后,主机除了第一个字节收到的是0x00,其余都是正确的,

也就是收到"\0ello from slaver, msg#: 1",所以从CPOL=0,CPHA=1来说应该已经达成同步了,我需要解决的是为什么第一个字节是0x00而不是'H'

其次,例程里不管是MASTER还是SLAVE都将CC2640R2_LAUNCHXL_SPI0_CSN设为PIN_UNASSIGNED,

这里我理解为Board_SPI_MASTER_READY(IOID_0)就是CS,既然SPI中没有配置CS,那么主机需要人为拉低Board_SPI_MASTER_READY

而从机则需要在接收前人为检测Board_SPI_MASTER_READY是否拉低(最初我贴出的代码中while (GPIO_read(Board_SPI_MASTER_READY)) {}是不应该注释的);假如CC2640R2_LAUNCHXL_SPI0_CSN配置为IOID_0,那么Board_SPI_MASTER_READY的功能有SPI外设自动替代了,也就是主机不需要拉低CS,从机不需要判断CS是否拉低。

目前我的困惑点就是这2点,一个是为什么每次只有第一个字节收到固定的0x00,另一个是关于CS的问题上我理解有没有问题

user4649054:

回复 user4649054:

此外CS拉低后,延迟100ms收到的第一个字节还是0x00,图中逻辑分析仪也证实了第一个字节就是0x00

Alvin Chen:

回复 user4649054:

我手头没有逻辑分析仪没办法帮你实验。建议你发到英文版。
e2e.ti.com/…/538

user4649054:

回复 user4649054:

这个帖子也是和我一样的情况
e2echina.ti.com/…/127224

赞(0)
未经允许不得转载:TI中文支持网 » CC2640R2F SPI SLAVE收不到数据
分享到: 更多 (0)