主题: CC2520,sysconfig中讨论的其它部件
您好,
我正在探索使用CC2652RSIP模拟CC2520的可能性。
这意味着CC2652接收命令,非常快速地解析它们,并准备好在下一次SPI传输中回复。
命令在数据表 cc2520.pdf的第52页中指定
是否有人尝试过类似的方法?
感谢您参加高级会议!
此致,
Ivan Sojic
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.
您好,
我正在探索使用CC2652RSIP模拟CC2520的可能性。
这意味着CC2652接收命令,非常快速地解析它们,并准备好在下一次SPI传输中回复。
命令在数据表 cc2520.pdf的第52页中指定
是否有人尝试过类似的方法?
感谢您参加高级会议!
此致,
Ivan Sojic
您好Ivan:
如果您想要复制2.4 GHz专有RF收发器功能,我建议您评估 rfEasyLinkNp 示例。 您可以查看 自述文件, EasyLink网络处理器 SimpleLink Academy实验室和 专有RF用户指南 以开始使用。 但是,请注意,默认情况下仅支持UART通信, AT命令与请求的CC2520指令集不同,因此需要进行一些迁移,不需要完全仿真。
此致,
Ryan
您好,Ryan:
感谢您的回复。
我已经查看了rfEasyLinkNp示例和您指出的文档。 示例在我的评估版上运行。 不幸的是 ,目前无法在终端硬件上使用UART。 所以我继续介绍一个使用SPI的示例。 为此,我选择了spislave示例。
我有一个问题。 我无法配置板(SPI从属)为来自SPI主控的单个CS断言发送多个字节(例如,当CS低时接收3个字节)。
我尝试了以下配置:
使用硬件CS
在sysconfig中:MX25R8035F SPI闪存和 四引脚SS活动低电平。
如果SPI主中继器发送3个字节,当SPI从中继器为spiParams.dataSize =8;时 ,SPI从中继器将为每个CS断言只对1个字节进行时钟超时。 对于 来自其他2个字节的clk,miso为零。
如果dataSize为16,则spiSlave (我的设备)将为每个CS断言计时2个字节。 对于第3字节,miso再次为零。
对于此方案,如果我在每个字节之后在SPI主控制器上取消断言并断言CS,则SPI从控制器将发送3个1字节并报告所有数据均已发送。
在所附的SPI.h doxygen文档中,我发现了一个关于“断言多个SPI数据帧上的CS”的部分。 我不完全理解在这种情况下应该对SPI从属设备执行什么操作。
应使用软件CS (sysconfig中的三针配置)。 SPI从属设备在每个帧之后都应取消断言并断言CS引脚吗?
请您在此帮助我吗?
谢谢,此致,
伊凡
----------------
SPI协议要求SPI主控在开始SPI事务之前断言SPI从属芯片选择引脚。 虽然通常遵循此协议,但对于SPI事务,芯片选择引脚必须保持断言状态的时间和时间,各种类型的SPI外设具有不同的计时要求。
通常,SPI主控制器使用硬件芯片选择来断言和取消断言每个数据帧的SPI从属设备。 在其他情况下,SPI从属设备要求在多个SPI数据帧上断言芯片选择。 这通常通过使用常规的通用输出引脚来实现。 由于此类SPI外设实施的复杂性,此SPI驱动程序设计为对SPI芯片选择透明运行。 使用硬件芯片选择时,外围设备会自动选择/启用外围设备。 使用软件芯片选择时,应用程序需要处理正确的芯片选择和引脚配置。 芯片选择支持因SPI外设而异,有关芯片选择支持的详细信息,请参阅特定于设备的实施文档。
嗨,Ivan,
预期的行为是,只要断言了CS引脚且SPI主控制器继续驱动SPI时钟线,SPI从属设备将从其缓冲区传输尽可能多的字节。 SPI从属设备是否确认接收到三个字节,而只发送一个字节? 是否可以提供逻辑分析仪或示波器屏幕截图以及持续通信的终端显示,以进一步显示当前的问题? 请注意,spislave示例旨在与spimaster示例一起使用,因此最好先按预期评估这些示例 ,然后再与不同的主SPI MCU比较行为。 有一些可选的引脚,如 CONFIG_SPI_MASTER_READY /CONFIG_SPI_SLAN_READY,如果不需要,可以将其移除。
如果与芯片选择有关 ,只要SPI主MCU能够正确驱动引脚,则首选具有硬件芯片选择的四引脚模式。 这将不需要对申请采取进一步行动。 使用三引脚模式或软件芯片选择时,SPI从属应用程序必须确定是 传输从属数据还是启用/禁用外围设备,而不管主控制器的SPI引脚上发生了什么交互。 如果SPI从属设备是同一SPI线路上唯一由主控制的设备(例如,在示例中,MS25R8035F通过Boart_init -> Board_shutDownExtFlash关闭),则更可行。
此致,
Ryan
您好,Ryan:
请参阅随附的项目示例。 我的示例中未使用CONFIG_SPI_MASTER_READY_CONFIG_SPI_SLAVE_READY。
信号描述:CH1 - CS,CH2 - Miso,ch3 - MOSI,CH4 - CLK
SPI从属设备应从 "Hello from Slave"发送3个第一字节。
SPI主节点正在发送0x10 0x40 0x80 (如下图所示)。
SPI从机每次只使用一个字节应答。 如果在SPI主端重复上述命令(使用CS去断和断言),SPI从机将发送"e"和第三次发送"l"。 第三次之后,SPI从属设备将报告发送了3个字节并调用回调。
e2e.ti.com/.../spislave_5F00_LP_5F00_CC2652RSIP_5F00_tirtos7_5F00_ccs.zip
终端正在打印以下内容。
SPI2.6552万/4048TI#4048921]SPI从属4048从属设备404.8921万设备在发送时是否确认只接收到三个字节[/报价单]?它还关注SPI从属设备每次只收到第一个字节(0x10)! 在SPI主端重复3个命令后,SPI从机将确认接收到3个字节。
,则更可行3引2652引脚2520脚模式2.6552万模式下4048下,404.8921万,无论从芯片 上的传输数据是否必须启用或禁用软件从动,都必须选择从芯片上的传输。 如果SPI从属设备是同一SPI线路上唯一由主控制的设备这是我的申请案例。 我不一定需要CS。 当我尝试在三引脚模式下配置SPI时,没有发送任何数据。 如何从源代码启用SPI从属?
谢谢,伊凡
[/quote]
感谢您提供更多信息。 我也能够创建类似的设置并产生有问题的行为。 在遵循之前的主题 https://e2e.ti.com/f/1/t/107.8279万中的建议后,这些问题大大减少了
/* * ======== spislave.c ======== */ #include <stddef.h> #include <stdbool.h> #include <stdint.h> #include <string.h> /* POSIX Header files */ #include <pthread.h> #include <semaphore.h> #include <unistd.h> /* Driver Header files */ #include <ti/drivers/GPIO.h> #include <ti/drivers/SPI.h> #include <ti/display/Display.h> #include <ti/devices/cc13x2_cc26x2/driverlib/ssi.h> #include <ti/drivers/spi/SPICC26X2DMA.h> /* Driver configuration */ #include "ti_drivers_config.h" #define THREADSTACKSIZE (1024) #define SPI_MSG_LENGTH (4) #define SLAVE_MSG ("Sl") #define MAX_LOOP (10) static Display_Handle display; unsigned char slaveRxBuffer[SPI_MSG_LENGTH]; unsigned char slaveTxBuffer[SPI_MSG_LENGTH]; /* Semaphore to block slave until transfer is complete */ sem_t slaveSem; /* Status indicating whether or not SPI transfer succeeded. */ bool transferStatus; static void flushFifos(SPICC26X2DMA_HWAttrs const *hwAttrs); /* * ======== transferCompleteFxn ======== * Callback function for SPI_transfer(). */ void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction) { if (transaction->status != SPI_TRANSFER_COMPLETED) { transferStatus = false; } else { transferStatus = true; } sem_post(&slaveSem); } /* * ======== slaveThread ======== * Slave SPI sends a message to master while simultaneously receiving a * message from the master. */ void *slaveThread(void *arg0) { SPI_Handle slaveSpi; SPI_Params spiParams; SPI_Transaction transaction; uint32_t i; bool transferOK; int32_t status; /* * CONFIG_SPI_MASTER_READY & CONFIG_SPI_SLAVE_READY are GPIO pins connected * between the master & slave. These pins are used to synchronize * the master & slave applications via a small 'handshake'. The pins * are later used to synchronize transfers & ensure the master will not * start a transfer until the slave is ready. These pins behave * differently between spimaster & spislave examples: * * spislave example: * * CONFIG_SPI_MASTER_READY is configured as an input pin. During the * 'handshake' this pin is read & a high value will indicate the * master is ready to run the application. Afterwards, the pin is * read to determine if the master has already opened its SPI pins. * The master will pull this pin low when it has opened its SPI. * * * CONFIG_SPI_SLAVE_READY is configured as an output pin. During the * 'handshake' this pin is changed from low to high output. This * notifies the master the slave is ready to run the application. * Afterwards, the pin is used by the slave to notify the master it * is ready for a transfer. When ready for a transfer, this pin will * be pulled low. * * Below we set CONFIG_SPI_MASTER_READY & CONFIG_SPI_SLAVE_READY initial * conditions for the 'handshake'. */ // GPIO_setConfig(CONFIG_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW); // GPIO_setConfig(CONFIG_SPI_MASTER_READY, GPIO_CFG_INPUT); /* * Handshake - Set CONFIG_SPI_SLAVE_READY high to indicate slave is ready * to run. Wait for CONFIG_SPI_MASTER_READY to be high. */ // GPIO_write(CONFIG_SPI_SLAVE_READY, 1); // while (GPIO_read(CONFIG_SPI_MASTER_READY) == 0) {} /* * Create synchronization semaphore; this semaphore will block the slave * until a transfer is complete. The slave is configured in callback mode * to allow us to configure the SPI transfer & then notify the master the * slave is ready. However, we must still wait for the current transfer * to be complete before setting up the next. Thus, we wait on slaveSem; * once the transfer is complete the callback function will unblock the * slave. */ status = sem_init(&slaveSem, 0, 0); if (status != 0) { Display_printf(display, 0, 0, "Error creating slaveSem\n"); while(1); } /* * Wait until master SPI is open. When the master is configuring SPI pins * the clock may toggle from low to high (or high to low depending on * polarity). If using 3-pin SPI & the slave has been opened before the * master, clock transitions may cause the slave to shift bits out assuming * it is an actual transfer. We can prevent this behavior by opening the * master first & then opening the slave. */ // while (GPIO_read(CONFIG_SPI_MASTER_READY)) {} /* * Open SPI as slave in callback mode; callback mode is used to allow us to * configure the transfer & then set CONFIG_SPI_SLAVE_READY high. */ SPI_Params_init(&spiParams); spiParams.frameFormat = SPI_POL0_PHA0; spiParams.mode = SPI_SLAVE; spiParams.transferCallbackFxn = transferCompleteFxn; spiParams.transferMode = SPI_MODE_CALLBACK; slaveSpi = SPI_open(CONFIG_SPI_SLAVE, &spiParams); if (slaveSpi == NULL) { Display_printf(display, 0, 0, "Error initializing slave SPI\n"); while (1); } else { Display_printf(display, 0, 0, "Slave SPI initialized\n"); } /* Copy message to transmit buffer */ strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH); for (i = 0; i < MAX_LOOP; i++) { /* Initialize slave SPI transaction structure */ slaveTxBuffer[sizeof(SLAVE_MSG) - 1] = (i % 10) + '0'; memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH); transaction.count = SPI_MSG_LENGTH; transaction.txBuf = (void *) slaveTxBuffer+1; transaction.rxBuf = (void *) slaveRxBuffer; /* Toggle on user LED, indicating a SPI transfer is in progress */ GPIO_toggle(CONFIG_GPIO_LED_1); /* * Setup SPI transfer; CONFIG_SPI_SLAVE_READY will be set to notify * master the slave is ready. */ flushFifos(slaveSpi->hwAttrs); SSIDataPut(SSI0_BASE, (uint32_t) slaveTxBuffer[0]); transferOK = SPI_transfer(slaveSpi, &transaction); if (transferOK) { // GPIO_write(CONFIG_SPI_SLAVE_READY, 0); /* Wait until transfer has completed */ sem_wait(&slaveSem); /* * Drive CONFIG_SPI_SLAVE_READY high to indicate slave is not ready * for another transfer yet. */ // GPIO_write(CONFIG_SPI_SLAVE_READY, 1); if (transferStatus == false) { Display_printf(display, 0, 0, "SPI transfer failed!"); } else { Display_printf(display, 0, 0, "Slave received: %s", slaveRxBuffer); } } else { Display_printf(display, 0, 0, "Unsuccessful slave SPI transfer"); } } SPI_close(slaveSpi); /* Example complete - set pins to a known state */ // GPIO_setConfig(CONFIG_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW); // GPIO_write(CONFIG_SPI_SLAVE_READY, 0); Display_printf(display, 0, 0, "\nDone"); return (NULL); } /* * ======== mainThread ======== */ void *mainThread(void *arg0) { pthread_t thread0; pthread_attr_t attrs; struct sched_param priParam; int retc; int detachState; /* Call driver init functions. */ Display_init(); GPIO_init(); SPI_init(); /* Configure the LED pins */ GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW); GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW); /* Open the display for output */ display = Display_open(Display_Type_UART, NULL); if (display == NULL) { /* Failed to open display driver */ while (1); } /* Turn on user LED */ GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON); Display_printf(display, 0, 0, "Starting the SPI slave example"); Display_printf(display, 0, 0, "This example requires external wires to be " "connected to the header pins. Please see the Board.html for details.\n"); /* Create application thread */ 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 slave thread */ priParam.sched_priority = 1; pthread_attr_setschedparam(&attrs, &priParam); retc = pthread_create(&thread0, &attrs, slaveThread, NULL); if (retc != 0) { /* pthread_create() failed */ while (1); } return (NULL); } static void flushFifos(SPICC26X2DMA_HWAttrs const *hwAttrs) { /* Flush RX FIFO */ while(HWREG(hwAttrs->baseAddr + SSI_O_SR) & SSI_RX_NOT_EMPTY) { /* Read element from RX FIFO and discard */ HWREG(hwAttrs->baseAddr + SSI_O_DR); } /* Enable TESTFIFO mode */ HWREG(hwAttrs->baseAddr + 0x00000080) = 0x2; /* Flush TX FIFO */ while(!(HWREG(hwAttrs->baseAddr + SSI_O_SR) & SSI_TX_EMPTY)) { /* Read element from TX FIFO and discard */ HWREG(hwAttrs->baseAddr + 0x0000008C); } /* Disable TESTFIFO mode */ HWREG(hwAttrs->baseAddr + 0x00000080) = 0x0; }
请告诉我这是否也能改善您的设置。
此致,
Ryan
您好,Ryan:
感谢提示。 我进行了不带“使用硬件”的SPI配置,在那里我可以选择另一个CS (SPI_CS)。
在我关闭此问题之前,还有一个澄清:
根据第1796页上的“CC13x2_CC26x2 SimpleLink Wireless MCU - TechnicalReferenceManual.pdf”- SpO =0且SPH =0的Motorola SPI帧格式, 其中显示:
"对于连续的背对背传输,SSIN_FSS信号必须在 每个数据 字传输之间发出高脉冲,因为从属选择引脚会冻结其串行外设寄存器中的数据,并且如果SPH位清晰,则不允许更改数据。 主设备必须在每次数据传输之间提升从属设备的SSIn_FSS引脚,以启用串行外围设备数据写入。 当连续传输完成时,SSIn_FSS引脚在 捕获最后一位后的一个SSIn_CLK周期内返回到空闲状态"
基于这一点,我假设SPI从属设备不能使用三引脚模式。 每个帧后,CS帽都要轻拍。 是这样吗?
谢谢,伊凡