UART TX_CALLBACK_SIZE question

⚠️
嗨,...感谢您来论坛。令人兴奋的消息!我们现在正在迁至我们的新论坛平台,将提供更好的功能,并包含在主对话框网站中。所有帖子和帐户都已迁移。我们现在只接受新论坛上的流量 - 请发布任何新线程https://www.dialog-seminile.com/support.。我们将在未来几天修复错误/优化搜索和标记。
3个帖子/ 0新
最后一篇
kqtrinh.
离线
Last seen:3 years 10 months ago
加入:2016-08-24 00:17
UART TX_CALLBACK_SIZE question

Hi Dialog Engineer,

I am using the DSPS application firmware as my baseline code to start with.
我通过UART行与外部MCU进行了通信。这款UART是在56.7kbps的波特拉特的建立。

I have implemented two functions to send data across from the DA to the external MCU.

功能1:
- 在da powers上升,此功能从Flash读取并在此UART行下载外部MCU固件。此功能始终如一地工作100%,因为外部MCU实际上可以旋转并使用固件运行。这是代码:

//从闪存地址“地址”和“尺寸”读取QPI FWS /表格和
// write it out the UART channel(s) where the QPI(s) attached to
void user_sps_qpi_fw_upload(unsigned int address) {

byte buf [2];
// read the firmware size in bytes stored in flash from the Host UI flash program.
//固件Len是Flash中每个FW地址部分中的前两个字节
unsigned int fwLen;
if(spi_flash_read_data(buf, address, USER_FLASH_QPI_FWSIZE_HDR) == USER_FLASH_QPI_FWSIZE_HDR) {
fwLen = (buf[0] << 8) | buf[1];
address += USER_FLASH_QPI_FWSIZE_HDR;
}
无符号char data_ptr [user_flash_qpi_ci_blk_size];
//计算闪存读数的数量。每个读取的是user_flash_qpi_ci_blk_size字节
int n = fwLen/USER_FLASH_QPI_CI_BLK_SIZE + 1;
for(int i = 0; i // read the QPI FW from Flash. This can be FW, Degamma Table, LUM Tables
unsigned int ret = spi_flash_read_data(data_ptr, address + i*USER_FLASH_QPI_CI_BLK_SIZE,
USER_FLASH_QPI_CI_BLK_SIZE);
UART2_WRITE(data_ptr,user_flash_qpi_ci_blk_size,null);
uart2_finish_transfers();
}
}

- In this function, I am reading USER_FLASH_QPI_CI_BLK_SIZE = 256 bytes at a time from Flash and write over the UART2.

功能2:
- 此功能从来自BLE线的数据读取,并在UART2总线上发送到外部MCU。以下是代码:

void user_ble_push(uint8_t* wrdata, uint16_t write_amount)
{
ASSERT_ERR(wrdata != NULL);
assert_err(write_amount!= 0);

bool send_flow_off = false;

// write the BLE "data" to the peripheral buffer "ble_to_periph_buffer"
user_buffer_write_items(&ble_to_periph_buffer,wrdata,write_amount);

//check if buffer is almost full and issue to send a XOFF if so
send_flow_off = user_check_buffer_almost_full(&ble_to_periph_buffer);

//if XOFF must be send, send asap
if(send_flow_off){
user_send_ble_flow_ctrl(flow_off);
}
//start transmitting
__disable_irq();

if(!uart_qpi_tx_callbackbusy) {
UART_QPI_TX_CALLBACKBUSY = TRUE;
UART_QPI_TX_CALLBACK(UART_STATUS_INIT);
}
__enable_irq();
}

- 此功能是DSPS示例应用程序固件的一部分。我修改了它用于我们自己的应用程序。UART_QPI_TX_CALLBACK()与DSPS样本中的内容相同。下面是您参考此功能的代码:

static void uart_qpi_tx_callback(uint8_t res)
{
static uint8_t size=0;
uint8_t * periph_tx_ptr = null;

//在未运行时从UART传输ISR或应用程序调用函数
开关(RES)
{
case UART_STATUS_OK:
//获取数据和指针
size = user_periph_pull(&periph_tx_ptr,size);
break;
案例UART_STATUS_INIT:
size = user_buffer_read_address(&ble_to_periph_buffer,&periph_tx_ptr,tx_callback_size);
break;
default:
assert_error(0);//错误:从未知来源调用回调
}
//if there is data available, send data over periph
if(size > 0) {
UART2_WRITE(Periph_tx_ptr,size,&uart_qpi_tx_callback);
return;
}
//缓冲区中没有数据,因此回调已完成
uart_qpi_tx_callbackbusy = false;
}

现在我的问题/问题上面的两个功能::

1.在函数1中,我实际上使用了UART写入大小256字节。我知道TX FIFO大小只有16个字节。为什么和如何在我的情况下工作。我不抱怨。我只是想更好地了解它。

2.在函数二,我有问题发送任何东西more than 16 bytes to the external MCU. If I sent 16 bytes or less, the MCU received everything. If I sent a packet that is more than 16 bytes, the bytes beyond the 16th byte will not be received. However, if I were to step into the uart2_write() function one line at a time and walk through the uart2_thr_empty_isr() inside uart2_write(), I can see all the data and the data will end up be received by the external MCU correctly. This will happen every time. If I step into the code, it will work. If I let the code run, It will fail every time.

Please let me know what you see and explain to me what's going on?

感谢您的关注,
--Khai

Device:
MT_dialog
离线
Last seen:3 months 3 days ago
职员
加入:2015-06-08 11:34
嗨kqtrinh,

嗨kqtrinh,

1. The FIFO has 16 bytes but that doesn't mean that you can only send 16 bytes at a time, i mean that as long as you keep on pushing data in the FIFO then the UART will output the data and you can keep on pushing data as long as the FIFO has room (if the FIFO has room for additional bytes is checked by the uart2_txfifo_full_getf() ), if the FIFO is full and you keep on pushing data, that means that the data will be overwritten and apparently you will have missing bytes. In the UART driver the first 16 bytes are pushed from the uart2_write() function and as soon as the uart2_txfifo_full_getf() returns 0 (no more room in the FIFO) the function will return and wait for the UART FIFO to get empty, as soon as it gets empty, a UART interrupt will hit indicating an empty FIFO and the uart2_thr_empty_isr() is getting invoked in interrupt context in order to re-fill the FIFO.

2.关于你可以在踩通过代码时看到所有数据的事实,并且如果正常运行代码,只有16个字节,我只能假设这是因为手动和通过踩到uart fifo有时间拍摄由MCU提供的数据并将其打印出来,因此UART FIFO中总是空间(UART2_TXFIFO_FULL_GETF()函数始终是非零,所以所有打印都是从UART2_THR_EMPTY_ISR()所做的所有打印UART2_WRITE())。但是在处理器以全速运行的实际情况和调用UART2_WRITE()之后,FIFO将完整,UART2_THR_EMPTY_ISR()将返回并等到UART FIFO打印所有数据,之后,将发生UART中断,以便通知FIFO是空的,并且您可以将更多数据推入FIFO,因此UART2_Handler()将被调用并按UART2_THR_EMPTY_ISR()填写下一批16的批准字节,所以显然来自UART2_Handler的UART2_THR_EMPTY_ISR()永远不会被调用。我最信任最多可能这是你在第二种情况下获得16个字节的数据的原因,但你需要更多的调试,因为这只是一个假设,我不能忘记在这种情况下会发生什么,并且精确是什么您无法在另一边获取数据的原因。

Thanks MT_dialog

kqtrinh.
离线
Last seen:3 years 10 months ago
加入:2016-08-24 00:17
嗨MT,

嗨MT,

谢谢你通过UART2_WRITE()机制来步行。通过解释FIFO如何工作,我简单地放置了每16个字节的1毫秒等待每16个字节事务,以允许FIFO时间在再次发送接下来的16字节块之前清空其数据。这就像冠军一样。

谢谢,
--Khai