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.

[参考译文] TMDSDOCK28335:从器件(TMDSDOCK28335)传入的 SPI 数据错误

Guru**** 2349670 points
Other Parts Discussed in Thread: TMDSDOCK28335, CC3200-LAUNCHXL, CC3200
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/588377/tmdsdock28335-incoming-spi-data-from-slave-tmdsdock28335-is-wrong

器件型号:TMDSDOCK28335
主题中讨论的其他器件: CC3200-LAUNCHXLCC3200

大家好、

对于过去一直在帮助我的人员(顺便说一下、非常感谢)、这是我一直在努力的 SPI 代码的最新更新。

到目前为止、从主器件(CC3200-LAUNCHXL)发送到从器件(TMDSDOCK28335)的数据是正确的。 但问题在于第五次传输(这是从机唯一发送数据的时间)、该值完全错误。 我尝试使用一些校正代码修复收到的数据、但我仍然遇到 lsb 错误。 我有一些示例数据以及代码、因此您可以看到问题。

加载到 TMDSDOCK28335传输缓冲区中的内容 接收缓冲器上接收到的内容 在接收缓冲器校正之后(来自 CC3200代码的第151-155行)
0x0011 0x0080 0x0010
0xAAAA 0x5555 0xAAAA
0x5555 0xAA2a 0x5554
0xFFFF 0xFF7F 0xFFFE
0x0000 0x0000 0x0000
0xABCD 0xE655 0xABCC
0x274E 0xA713 0x274E

CC3200-LAUNCHXL 代码

//代码基于 CC3200-LAUNCHXL 板附带的"SPI 演示"

//标准包括
#include 

//驱动程序库包括
#include "hw_types.h"
#include "hw_memmap.h"
#include "hw_common_reg.h"
#include "hw_ints.h"
#include "spi.h"
#include "rom.h"
#include "rom_map.h"
#include "utils.h"
#include "prcm.h"

#define






100bits /inuarts.h"#include "100bits #include "inuart.h"#define /inuart.h"#define #include "100bits #define /inuarts.h"#include "100bits #include "inuart.h"#define #.h"#.h"#include "inuart.h"#.h.h"#include "inuart.h
2

/***** 全局变量的起始*****
静态 unsigned char sendtoDSP[TR_buff _size];
静态 unsigned char receivefromDSP[TR_buff size];
unsigned int char_array_to_int、STORE_MSB、remove_lsb、correct_integer 向后、correct_integer;

//不太确定这个东西在这里执行什么操作,但附带了 SPI 示例
#if defined (CCS)
extern void (* const g_pfnVectors [])(void);
#endif
defined (ewarm)
extern uVectorEntry __vector_table;
#endif
//***** 全局变量的末尾*****

//***** 电路板初始化和配置开始***** (也随 SPI 演示一起提供)
静态 void
BoardInit(void)
{
/*在 TI-RTOS 矢量表由操作系统本身初始化时*/
#ifndef use_TIRTOS
//
设置矢量表基址
//
#if defined (CCS)
MAP_IntVTableBaseSet ((无符号长整型)&g_pfnVectors[0]);
#endif
已定义(ewarm)
MAP_IntVTableBaseSet ((unsigned long)&__vector_table);
#endif
#endif
//
//启用处理器
//
MAP_IntMasterEnable();
MAP_IntEnable (FAULT_SysTick);

PRCMCC3200MCUInit();
}//*****
电路板结束初始化和配置*****

void main(){

//Initialize Board Configurations
BoardInit();

//多路复用 UART 和 SPI 线路
//所有这一切都是为 MOSI、MISO、芯片选择和时钟配置引脚。
PinMuxConfig ();

//启用 SPI 模块时钟
//启用外设时钟
//PRCM_GSPI = SPI 外设的宏(0x00000003)
//PRCM_RUN_MODE_CLK =解锁外设时钟(也可以是 PRCM_CMP_MODE_CLK
//它会使
外设保持睡眠状态) MAP_CLK_PRCMP_RUN_CLK、PRCMP_CLK (PRCMP_CLK)

//重置外设
// PRCM_GSPI = SPI 外设的宏(重置 SPI 外设)
MAP_PRCMPeripheralReset (PRCM_GSPI);

//重置 SPI
//执行 SPI 模块的软件重置
//GSPI_base = SPI 基地址的宏(0x44021000)
MAP_SPIReset (GSPI_base);

//配置 SPI 接口(所有值都是宏)
//第一个参数是 SPI 模块的基址(即 GSPI_base)
//第二个参数是提供给 SPI 模块的时钟速率
//第三个参数是所需的位速率(在上面的"有用宏"部分中定义)
//第四个参数是 SPI_MODE_MASTER, 将主板配置为主
控//第5个参数是 SPI_SUB_MODE_0、它将时钟极性和相位设置为0
//第6个参数是逻辑或组合、 它将芯片选择设置为由软件控制(SPI_SW_CTRL_CS)、
//将模块设置为4引脚模式(SPI_4PIN_MODE)、将 Turbo 模式设置为关闭(SPI_Turbo_OFF)并且我不知道 Turbo 模式是什么、
//将芯片选择设置为低电平有效(SPI_CS_ACTIVELOW)、 并将位长度设置为每字符8位(SPI_WL_8)
MAP_SPIConfigSetExpClk (GSPI_base、MAP_PRCMPeripheralClockGet (PRCM_GSPI)、SPI_IF_bit_rate、SPI_MODE_MASTER、SPI_SUB_MODE_0、
(SPI_SW_CTRL_CS | MACRIV_GEL (PRCM_GSPI)| SPI_BIST_8_RATE












= 0x1000)| SPI_TOW/ TOSS_RATE = 0x1000 | SPI_TOSS_RATE = 0x1000 | SPI_TOSSI8[SPI_TO_SS_SSI1]/ TOSSEM_RATE = 0x1000 | SPI_TO_TO_SSEM_RACK_MODE](SPI_CL_ST_SS_TO_TO_RAT0)|针对 SPI_CL_ST_ST_ST/ TO_SSEM_ST/ TOSSEM_RAP| //0x42

//通过 MOSI 引脚发送数据
//第一个参数是 SPI 模块(GSPI_base)的基址
//第二个参数是传输缓冲区的指针(sendtoDSP)
//第三个参数是接收缓冲区的指针(receivefromDSP)
//第四个参数是以字节为单位的数据大小(1字节= 8位)
//第5个参数是逻辑参数、或在传输前启用芯片选择引脚、
//在传输后禁用芯片选择引脚(SPI_CS_ENABLE|SPI_CS_DISABLE)
MAP_SPITransfer (GSPI_base、sendtoDSP、receivefromDSP、2、SPI_CS_ENABLE|SPI_DISABLE);

//将第二个数据集加载到传输中,SPI_DSP_STOPENABLE[0x43]|SP_DSP_DSP_TRANSFORT|SP_ENABLE[SP_ST_STACT_SP_0]|SP_D]|SP_ENABLE[SP_D]|SP_ENABLE[SP_D]|SP_END]|SP_MODE]





;SP_ENDSP_ST_DSP_ENDSP_
//0x45
sendtoDSP[1]='F';//0x46

MAP_SPITransfer (GSPI_base、sendtoDSP、receiveDSP-2、SPI_ENABLE|SPI_CS_DISABLE);

//将第四个数据集加载到传输缓冲区
sendtoDSP[0]='G';//从 SPI_DAC_ENABLE[0x48_DSP_DISAB]












传输到 SP_ENABLE[SP_ST_ENABLE[SP_ST_ENABLE];//从 SPI_TRANSF_STACT_SP_ENABLE[SP_END]+SP_END]+SP_END]+SP_ENDSP_END]+SP_DISAF[0|SP_ENABLE[SP_DISAF[0|SP_ENABLE[SP_END]+SP_END]+SP_END]+SP_DISAF[SP_DISAF[SP_ENABLE[SP_END]|END]+SP_END]+SP_DISAFICEST_

correct_integer 向后= remove_lsb|store_msb;
correct_integer =((correct_integer_eile<<8)&0xFF00)|((correct_integer_fore>>8)&0x00FF);
}
} 

TMDSDOCK28335代码

//基于 TMS320F28335 SPI 示例的代码

//器件头文件和示例包括文件
#include "DSP28x_Project.h"

//prototype 语句,用于此文件中的函数。
void SPI_Fifo_init (void);
void SPI_init (void);

//全局变量(用于读取寄存器)
unsigned int first_data_set、second_data_set、third_data_set、nour_data_set、fify_data_set;

void main (void){

//初始化系统控制:
//PLL、看门狗、启用外设时钟
//此示例函数位于 DSP2833x_sysctrl.c 文件中。
InitSysCtrl();

//Initialize GPIO:
//this 示例函数位于 DSP2833x_GPIO.c 文件中,
//说明如何将 GPIO 设置为其默认状态。
//仅为 SPI-A 功能设置 GP I/O
//此函数可在 DSP2833x_SPI.c
InitSpiaGpio()中找到;

//清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
DINT;

//将 PIE 控制寄存器初始化为默认状态。
//默认状态是禁用所有 PIE 中断并
清除标志//。
//此函数位于 DSP2833x_PIECTRL.c 文件中。
InitPieCtrl();

//禁用 CPU 中断并清除所有 CPU 中断标志:
IER = 0x0000;
IFR = 0x0000;

//使用指向 shell 中断
//服务例程(ISR)的指针初始化 PIE 矢量表。
//这将填充整个表,即使在
本示例中未使用中断//也是如此。 这对于调试很有用。
//可以在 DSP2833x_DefaultIsr.c 中找到 shell ISR 例程
//此函数位于 DSP2833x_PieVect.c 中
InitPieVectTable();

SPI_Fifo_init ();//初始化 SPI FIFO
SPI_init (); //初始化 SPI

//用户特定代码:
//此示例中不使用中断。

for (;;)
{
//加载传输缓冲器,无任何内容
SpiaRegs.SPITXBUF = 0x0000;

//等待接收到第一组数据
while (SpiaRegs.SPIFFRX.bit.RXFFST!=1){}

//读取第一组数据
FIRST_DATA_SET = SpiaRegs.SPIRXBUF;

//加载传输缓冲器,无任何内容
SpiaRegs.SPITXBUF = 0x0000;

//等待接收到第二组数据
while (SpiaRegs.SPIFFRX.bit.RXFFST!=1){}

//读取第二组数据
second_data_set = SpiaRegs.SPIRXBUF;

//加载传输缓冲器,无任何内容
SpiaRegs.SPITXBUF = 0x0000;

//等待接收到第三组数据
while (SpiaRegs.SPIFFRX.bit.RXFFST!=1){}

//读取第三组数据
third_data_set = SpiaRegs.SPIRXBUF;

//加载传输缓冲器,无任何内容
SpiaRegs.SPITXBUF = 0x0000;

//等待接收到第四组数据
while (SpiaRegs.SPIFFRX.bit.RXFFST!=1){}

//读取第四组数据
Four_data_set = SpiaRegs.SPIRXBUF;

//加载具有新命令值的传输缓冲区
SpiaRegs.SPITXBUF = 0xAAAA;//通过 SPI 发回的测试值在此加载

//等待服务器 CC3200请求新的命令值
while (SpiaRegs.SPIFFRX.bit.RXFFST!=1){}

//读取第五组数据(不应为任何数据)
Fify_data_set = SpiaRegs.SPIRXBUF;
}


void SPI_init (){

// SPICCR 是8位寄存器
//bit 7 (软件复位):设置为0、必须在配置
//位6 (时钟极性)之前清除:设置为0、在上升沿输出的数据和传入的数据为下降沿
//位5 (保留): 禁止写入
//位4 (SPI 回送):设置为0禁用,仅用于内部测试
//位3-0 (字符长度位):设置为0b1111 (16位字符(CC3200发送两个字符,共16位)
SpiaRegs.SPICCR.all =0x000F;

// SPICTL 是8位寄存器
//保留位: 不允许写入
//位4 (溢出中断使能):暂时设置为0,只需尝试简单的 SPI 连接
//位3 (时钟相位):设置为0,正常的 SPI 时钟方案(不被延迟半个周期)
//位2 (主控/受控位): 设置为0作为从
机//位1 (TALK 位):设置为1、尝试发回数据
//位0 (SPI 中断使能):设置为0、不担心立即发生中断
SpiaRegs.SPICTL.all =0x0002;

//该寄存器无关紧要、因为时钟来自 CC3200-LAUNCHXL
SpiaRegs.SPIBRR =0x0002;

//SPICCR 是8位寄存
器//bit 7 (软件复位):设置为1、当数据传输就绪时必须置位
//位6 (时钟极性):设置为0、上升沿输出的数据和输入的数据为下降沿
//位5 (保留):不允许写入
//位4 (SPI 回送): 设置为0以禁用、仅用于内部测试
//位3-0 (字符长度位):设置为0b1111以显示16位字符(CC3200发送两个字符、共16位)
SpiaRegs.SPICCR.all =0x008F;

//设置断点以避免传输
SpiaRegs.SPIPRI.bit.FREE = 1;SpiaReg=0x20SPIF.SPIF.fife.fif.f=0xSPIF.SPIF.SPIFs




;// SPIFfif.fif.SPIFfif.f.fif.f.fif_all 寄存器


SpiaRegs.SPIFFCT.ALL=0x0;
} 

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

    请提供一些示波器捕获。 此外、请验证您的相位和极性设置是否在器件之间一致。 我知道 C2000 SPI 不一定与 Wikipedia 定义匹配。 您似乎只是在错误的边沿对数据进行采样。 乍一看、您可能会"幸运"并获得正确的位值。 我发现奇怪的是、即使是0xFFFF 也没有正确采样、因此这可能不是唯一的事情。
    您以什么 SPICLK 频率运行?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    下图是 TMDSDOCK28335发送0x274E、而我接收到0xA713 (如图所示)。 位大约每10us (或100kHz)变化一次。 我还认为每一端的"尖峰"是开始信号还是停止信号? 此外、数据似乎是正确的、但我可能会读取错误的数据。

    下图是 TMDSDOCK 发送0xFFFF、但我仍在接收0xFF7F。 再说一次、传入的数据是正确的、但被读取的数据是错误的。

    下图是 TMDSDOCK 发送0xABCD、但我仍接收0xE655的情况。 再说一次、传入的数据是正确的、但在末尾似乎有一个额外的高位标记

    下图是 TMDSDOCK 发送0x5555、但我仍在接收0xAA2A。 请注意、第四个高电平位保持高电平两倍、最后一个位也是如此。

    如果您看一下我对 CC3200代码第98行的评论、则使用宏 SPI_SUB_MODE_0将时钟极性和相位设置为0。 在 TMDSDOCK28335代码中、寄存 器 SpiaRegs.SPICCR.all 等于0x008F (0b0000000010001111)。 位6控制时钟极性、当该位设置为0时 、数据在上升沿输出、输入的数据为下降沿。 SpiaRegs.SPICTL.ALL 寄存 器等于0x0002 (0b000000000010)。 位3控制时钟相位、当该位设置为0时、则 采用正常 SPI 时钟方案(不会延迟半个周期)。 我在两个代码集中都有这一切作为注释、如果您需要有关为什么像我那样设置寄存器的更多信息、请参阅更多内容。

    CC3200设置的比特率为每秒100、000位(在第24行上有一个宏设置)。 因此、SPICLK 引脚应为10uH。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    也许来自 CC3200-LAUNCHXL 的人会知道发生了什么情况? 由于数据似乎正确传入、因此我猜测 CC3200 SPI 外设读取的数据错误。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    达伦

    我担心您的代码中的这些尖峰。 它们不应该在那里。 我将看到我是否可以让 CC3200代表转到此帖子。
    您能否将示波器捕获与其他信号线共享? 时钟基准在这里非常有用。 如果您还可以将 SPISTE 与数据添加到另一个图上、如果您无法将它们全部放到该范围上。 我认为这些 runt 脉冲将对应于事务之前和之后驱动的 SPISTE。
    您是否尝试减慢 SPICLK 的速度进行测试? 如果这有帮助、可能需要解决一些时序问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Dalen:

    是的、需要额外的信号线来分析所发生的情况。 请将时钟和 CS 线路添加到几个捕捉中。

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

    您是否能够弄清这一点?

    谢谢、
    标记