UART TX_CALLBALL_SIZE问题

⚠️
Hi there.. thanks for coming to the forums. Exciting news! we’re now in the process of moving to our new forum platform that will offer better functionality and is contained within the main Dialog website. All posts and accounts have been migrated. We’re now accepting traffic on the new forum only - please POST any new threads at//www.xmece.com/support. We’ll be fixing bugs / optimising the searching and tagging over the coming days.
3 posts / 0 new
Last post
kqtrinh
Offline
最后一次露面:3年10个月前
Joined:2016-08-24 00:17
UART TX_CALLBALL_SIZE问题

嗨对话工程师,

我正在使用DSPS应用程序固件作为我的基准代码开始。
I have a DA communicating with an external MCU via the UART line. This UART is setup at a baudrate of 56.7kbps.

我已经实现了两个函数来向外部MCU向外部MCU发送数据。

Function 1:
- Upon DA powers up, this function reads from Flash and downloads the external MCU firmware over this UART line. This function is working consistently 100% since the external MCU can actually spin up and run with its firmware. Here is the code:

// Read QPI FWs/Tables from flash address "address" and "size" &
//将其写入QPI附加的UART频道
void user_sps_qpi_fw_upload(无符号int地址){

BYTE buf[2];
//从主机UI闪存程序中读取存储在闪存中的字节中的固件大小。
// The firmware len is the first two bytes in each FW address section in flash
unsigned int fwlen;
if(spi_flash_read_data(buf,地址,user_flash_fwsize_hdr)== user_flash_qpi_fwsize_hdr){
fwlen =(buf [0] << 8)|buf [1];
地址+ = user_flash_qpi_fwsize_hdr;
}
unsigned char data_ptr[USER_FLASH_QPI_CI_BLK_SIZE];
// calculate the number of flash reads. Each read is of USER_FLASH_QPI_CI_BLK_SIZE bytes
int n = fwlen / user_flash_qpi_ci_blk_size + 1;
for(int i=0; i < n; i++) {
//从闪存中读取QPI FW。这可以是fw,degamma表,lum表
unsigned int ret = spi_flash_read_data(data_ptr,地址+ 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();
}
}

- 在此函数中,我正在阅读user_flash_qpi_ci_blk_size = 256字节从闪存,写在UART2上。

Function 2:
- this function reads from the data coming in from the BLE line and send that across the UART2 bus to the external MCU. Below is the code:

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;

//将BLE“数据”写入外围缓冲区“BLE_TO_PERIPH_BUFFER”
user_buffer_write_items(&ble_to_periph_buffer, wrdata, write_amount);

//检查缓冲区几乎已满,如果是,请发送Xoff
send_flow_off = user_check_buffer_almost_full(&ble_to_periph_buffer);

//如果必须发送Xoff,请尽快发送
if(send_flow_off) {
user_send_ble_flow_ctrl(FLOW_OFF);
}
//开始传输
__disable_irq();

if(!auart_qpi_tx_callbackbusy){
uart_qpi_tx_callbackbusy = true;
uart_qpi_tx_callback(UART_STATUS_INIT);
}
__enable_irq();
}

——这个函数是需求方样本品的一部分ation firmware. I modified it to use for our own application. uart_qpi_tx_callback() is the same as what's in the DSPS sample. Below is the code for this function for your reference:

静态void UART_QPI_TX_CALLBALL(UINT8_T RES)
{
静态UINT8_T大小= 0;
uint8_t *periph_tx_ptr = NULL;

//function gets called from uart transmit isr or application when its not running
switch(res)
{
案例UART_STATUS_OK:
//get data and pointer
size = user_periph_pull(&periph_tx_ptr, size);
休息;
case UART_STATUS_INIT:
size = user_buffer_read_address(&ble_to_periph_buffer, &periph_tx_ptr, TX_CALLBACK_SIZE);
休息;
默认:
ASSERT_ERROR(0); //error: callback called from unknown source
}
//如果有数据可用,请通过Periph发送数据
if(size> 0){
uart2_write(periph_tx_ptr, size, &uart_qpi_tx_callback);
返回;
}
//there is no data in the buffer so the callback is done
uart_qpi_tx_callbackbusy = false;
}

Now my questions/issues with the two functions above::

1. In function 1, I was actually using the UART write with size 256 bytes. I know that the TX FIFO size is only 16 bytes. Why and how did this even work in my case. I am not complaining. I just would like to understand it better.

2.在功能2中,我的问题将超过16个字节的问题发送到外部MCU。如果我发送了16个字节或更少,MCU收到了一切。如果我发送了超过16个字节的数据包,则不会收到超过16个字节的字节。但是,如果我要一次进入UART2_WRITE()函数一行并浏览UART2_WRITE()中的UART2_THR_EMPTY_ISR(),我可以看到所有数据,数据将最终正确接收到完全的数据。这将每次都会发生。如果我进入代码,它将起作用。如果我让代码运行,每次都会失败。

请让我知道你看到了什么并向我解释了什么?

Thank you for your attention,
- khai

设备:
mt_dialog.
Offline
最后一次露面:3个月3天前
Staff
Joined:2015-06-08 11:34
Hi kqtrinh,

Hi kqtrinh,

1. FIFO有16个字节,但这并不意味着您只能一次发送16个字节,我的意思是只要您继续推动FIFO中的数据,那么UART会输出数据,您可以继续输出数据只要FIFO具有空间(如果FIFO有用于额外字节的空间,请通过UART2_TXFIFO_FURL_GETF())),如果FIFO已满,并且您继续推送数据,这意味着数据将被覆盖,显然您将被覆盖,显然您将覆盖将有遗失的字节。在UART驱动程序中,从UART2_WRITE()函数中推动前16个字节,一旦UART2_TXFIFO_FULL_GETF()返回0(在FIFO中没有更多的空间),函数将返回并等待UART FIFO以获得空,即立时由于它变为空,UART中断将点击指示空FIFO,并且在中断上下文中调用UART2_PREMPY_ISR()以重新填充FIFO。

2. Regarding the fact that you can see all the data when stepping through the code, and only 16 bytes if run the code normally, i can only assume that this is because manually and via stepping through the code the UART FIFO has time to take the data provided by the MCU and print it out, so there is always room in the UART FIFO (the while(uart2_txfifo_full_getf()) function is always non zero, so all the printing is done from the uart2_thr_empty_isr() which is invoked by the uart2_write()). But in the real case where the processor runs at full speed and you invoke the uart2_write() after the first 16 bytes the FIFO will get full and the uart2_thr_empty_isr() is going to return and wait until the UART FIFO to print all its data, after that a UART interrupt will occur in order to notify that the FIFO is empty and you can push more data into the FIFO, so the UART2_Handler() will get invoked and in order for the uart2_thr_empty_isr() to fill in the next batch of 16 bytes, so apparently the uart2_thr_empty_isr() from the UART2_Handler never gets invoked. I trust that most probably this is the reason why you get only 16 bytes of data in the second case, but you need more debugging on this since this is only an assumption and i cannot forsee what will happen in that case and what is the exact reason that you aren't able to get data on the other side.

谢谢mt_dialog.

kqtrinh
Offline
最后一次露面:3年10个月前
Joined:2016-08-24 00:17
Hi MT,

Hi MT,

Thanks for walking me thru the uart2_write() mechanism. With your explanation of how the FIFO works, I simply placed a 1 msec wait per 16 bytes transaction to allow the FIFO time to empty its data before the next 16 byte chunk is sent again. This works like a champ.

Thank you,
- khai