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.

[参考译文] TMS320F280039C:SCI FIFO 中断帧错误

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1123907/tms320f280039c-sci-fifo-interrupt-framing-error

器件型号:TMS320F280039C

您好、  

在我的应用中、我有一个微控制 器、它的代码无法更改、从而向 TMS320F280039C 发送连续数据流。 我每次读取1个字节的数据、直到看到起始字符、然后连续读取47个字节的数据。  

如果我在接收到 Rx 中断时按如下所示对所有数据进行阻塞式读取、我可以确保这项工作可靠:  

但是、在57600波特率下、这需要8ms、而我的应用需要一个快速250us 中断来控制电机、因此我无法阻断8ms。 因此、与我在该 MCU 上的 SPI 上执行的操作一样、我切换到了以下过程:  

1) 1)一次读取1个字节、直到我看到停止字符

2) 2)将 FIFO 大小设置为16字节、等待 FIFO 中断接收 FIFO 满

3) 3)将字节存储在数组中

4) 4)获取另一个满16字节的 FIFO

5) 5)将字节存储在数组中

6)获取另一个15字节的 FIFO

7) 7)将字节存储在数组中

8) 8)现在我有了完整的数据包、返回到每次读取1个字节、直到我看到停止字符。  

现在的问题是、随着连续数据流进入、我会得到一个 Rx 组帧错误。 我关注的是、在 TI e2e 上、这似乎是 SCI 驱动程序中的一个错误、如果您使用具有连续数据流的 FIFO、它需要2个停止位? 如果是这种情况、这将是我们使用此 MCU 的主要问题。 我们无法将发送连续数据流的器件更改为发送2个停止位。 轮询不是一个选项、因为我的应用程序有很多必须处理的中断。  

这是我的初始化

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void UcapBox_InitRS485(GE_Primary_Container_t *pContainer)
{
// Register interrupt ISRs
Interrupt_register(INT_SCIA_TX, &sciATxISR);
Interrupt_register(INT_SCIA_RX, &sciARxISR);
// Initialize SCIA and its FIFO.
SCI_performSoftwareReset(REPJ_REPC_RS485_UART);
// Configure SCIA
SCI_setConfig(REPJ_REPC_RS485_UART, DEVICE_LSPCLK_FREQ, REPJ_REPC_BAUDRATE,
( SCI_CONFIG_WLEN_8 |
SCI_CONFIG_STOP_ONE |
SCI_CONFIG_PAR_NONE ) );
SCI_resetChannels(REPJ_REPC_RS485_UART);
SCI_clearInterruptStatus(REPJ_REPC_RS485_UART, SCI_INT_RXFF | SCI_INT_FE | SCI_INT_RXERR);
SCI_enableInterrupt(REPJ_REPC_RS485_UART, SCI_INT_RXFF); // We don't transmit to REPJ
SCI_enableInterrupt(REPJ_REPC_RS485_UART, SCI_INT_FE);
SCI_enableInterrupt(REPJ_REPC_RS485_UART, SCI_INT_RXERR);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

下面介绍了如何根据我是要读取1字节还是47字节来更改 FIFO 大小。  

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int32_t UcapBox_StartUartTransfer(GE_Primary_Container_t *pContainer)
{
pContainer->debugCnt++;
// Perform software reset of SCI in case of any errors
SCI_performSoftwareReset(REPJ_REPC_RS485_UART);
pContainer->debugCnt++;
if((dataSize < 16) && (dataSize > 0))
{
SCI_setFIFOInterruptLevel(REPJ_REPC_RS485_UART, SCI_FIFO_TX0, (SCI_RxFIFOLevel) dataSize);
}
else if(dataSize > 0)
{
SCI_setFIFOInterruptLevel(REPJ_REPC_RS485_UART, SCI_FIFO_TX0, SCI_FIFO_RX16);
}
bytesRemaining = dataSize;
pContainer->debugCnt++;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

这是我的 Rx 中断-  

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void sciARxISRFunc(GE_Primary_Container_t *pContainer)
{
uint32_t sciInterruptStatus = SCI_getInterruptStatus(REPJ_REPC_RS485_UART);
pContainer->debugCnt++;
// Rx error occurred
if((sciInterruptStatus & SCI_INT_FE) || (sciInterruptStatus & SCI_INT_RXERR))
{
errorCnt++;
SCI_clearInterruptStatus(REPJ_REPC_RS485_UART, SCI_INT_RXFF | SCI_INT_FE | SCI_INT_RXERR);
SCI_clearOverflowStatus(REPJ_REPC_RS485_UART);
SCI_resetRxFIFO(REPJ_REPC_RS485_UART);
// Restart transfer
UcapBox_SetTransferSize(1); // go back to reading 1 byte at a time
UcapBox_StartUartTransfer(pContainer);
pContainer->debugCnt++;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

感谢您的帮助!

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

    尊敬的 Derek:

    我们的 SCI 专家将立即对此进行讨论。

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

    尊敬的 Derek:

    感谢您的提问。 遗憾的是、您所指的 SCI 错误是真实存在的、因为中断之间需要~2位周期才能触发 SCI 中断。

    目前有以下缓解方法:

    让另一个器件在每个16字节的数据包之后发送一个小延迟

    2.在另一个发送设备中使用2个停止位

    3.使用轮询而不是中断

      

    在您使用的器件中、另一种方法是此器件上有带有 DMA 连接的 LIN。 LIN 可在 SCI 模式下用作 SCI、因此理论上可以使用这种方法将 SCI 任务完全卸载到 DMA。

    如果您的系统可以这样做、我建议在 SCI 模式下使用具有 DMA 的 LIN。

    此致、

    Vince

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

    感谢您的回复! 这很不幸。 我们无法更改传输端的任何内容、但我有一个变通办法想法、可能起作用。  

    我们的应用具有1ms 中断、每1ms 数据从发送器获取6个字节。 我可以使用16字节 FIFO、然后每1ms 将 FIFO 中的任何内容存储到我自己的软件 FIFO 中。 让我尝试一下、如果遇到任何问题、我会告诉您!  

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

    您好、Vince、  

    我只想确认使用轮询对我有效! 我所做的是:  

    1) 1)在慢速1ms 中断开始时、我检查 SCI Rx FIFO 中有多少字节

    2) 2)我将这些字节存储在大型软件 FIFO 中

    3) 3)接收到所需的字节数后、我会处理数据

    这很好! 轮询仅占用我的慢速中断220个时钟周期、因此大约2us 即可完成所有这些操作!  

    感谢您的帮助!