Z-stack Serial Communication Usage experience

Source: Internet
Author: User

recently in a smart home project, the use of TI's CC2530 chip and corresponding Zstack protocol stack, the serial communication part of the use of the most, share the following z-stack on the use of the serial packaging experience.


Z-stack in the serial operation of the package is mainly in the HAL_UART.H,HAL_UART.C, support DMA and ISR two processing methods, the real implementation is encapsulated in _HAL_UART_DMA.C and the in _hal_uart_isr.c, However, the system is only recommended to use DMA mode, you can change the macro definition to change the way the ISR, the macro is defined in the hal_board_cfg.h.


Z-stack to the serial operation of the package using a buffer, read and write are directly operating the buffer , either DMA mode or ISR mode is the case, The following are examples of DMA:

typedef struct
{
UInt16 Rxbuf[hal_uart_dma_rx_max];
#if Hal_uart_dma_rx_max < 256
Uint8 Rxhead;
Uint8 Rxtail;
#else
UInt16 Rxhead;
UInt16 Rxtail;
#endif
Uint8 Rxtick;
Uint8 RXSHDW;
Uint8 Txbuf[2][hal_uart_dma_tx_max];
#if Hal_uart_dma_tx_max < 256
Uint8 txidx[2];
#else
UInt16 txidx[2];
#endif
Volatile uint8 Txsel;
Uint8 TXMT;
Uint8 Txtick; 1-character time in 32kHz ticks according to baud rate,
To is used in calculating time lapse since DMA ISR
To allow delay margin before start firing DMA
DMA does not overwrite UART dbuf of previous packet

Volatile uint8 TXSHDW; Sleep Timer LSB Shadow.
Volatile uint8 txshdwvalid; TX Shadow value is valid
Uint8 txdmapending; UART TX DMA is pending
haluartcback_t UARTCB;
} uartdmacfg_t;

The uartdmacfg_t structure forces the relevant data structures, where rxbuf and txbuf correspond to read and write buffers respectively.


1. Write operation

Static UInt16 Haluartwritedma (uint8 *buf, UInt16 len)
{
UInt16 CNT;
halintstate_t his;
Uint8 Txidx, Txsel;
Enforce all or none.
if ((len + Dmacfg.txidx[dmacfg.txsel]) > Hal_uart_dma_tx_max)
{
return 0;
}
Hal_enter_critical_section (HIS);
Txsel = Dmacfg.txsel;
Txidx = Dmacfg.txidx[txsel];
Hal_exit_critical_section (HIS);
for (cnt = 0; cnt < len; cnt++)
{
dmacfg.txbuf[txsel][txidx++] = buf[cnt];
}
Hal_enter_critical_section (HIS);
if (Txsel! = Dmacfg.txsel)
{
Hal_exit_critical_section (HIS);
Txsel = Dmacfg.txsel;
Txidx = Dmacfg.txidx[txsel];
for (cnt = 0; cnt < len; cnt++)
{
dmacfg.txbuf[txsel][txidx++] = buf[cnt];
}
Hal_enter_critical_section (HIS);
}
Dmacfg.txidx[txsel] = Txidx;
if (dmacfg.txidx[(txsel ^ 1)] = = 0)
{
TX DMA is expected to be fired
dmacfg.txdmapending = TRUE;
}
Hal_exit_critical_section (HIS);
return CNT;
}

It can be seen from this code that Z-stack writes to the serial port if the buffer has less space left than the user writes, it returns 0 directly.

That is, the enforce all or nonein the note, because the DMA mode uses a double buffer, this function also switches the buffer

The situation was protected.


2. Read operation

Static UInt16 Haluartreaddma (uint8 *buf, UInt16 len)
{
UInt16 CNT;
for (cnt = 0; cnt < len; cnt++)
{
if (! Hal_uart_dma_new_rx_byte (Dmacfg.rxhead))
{
Break
}
*buf++ = Hal_uart_dma_get_rx_byte (Dmacfg.rxhead);
Hal_uart_dma_clr_rx_byte (Dmacfg.rxhead);
if (+ + (dmacfg.rxhead) >= Hal_uart_dma_rx_max)
{
Dmacfg.rxhead = 0;
}
}
Pxout &= ~hal_uart_px_rts; Re-enable the flow on any read.
return CNT;
}

This function is simple, is to read the data directly from the RXBUF to the user buffer, it should be noted that if read to the end of the buffer, it will automatically adjusts the cursor to the buffer header, which may cause the read data to be not the actual received data, so when calling this function, it is best to do not read data more than Hal_uart_dma_rx_max


3. Poll operation

static void Haluartpolldma (void)
{
UInt16 cnt = 0;
Uint8 evt = 0;
if (Hal_uart_dma_new_rx_byte (Dmacfg.rxhead))
{
UInt16 tail = Findtail ();
If the DMA has transferred in more Rx bytes, reset the RX idle timer.
if (dmacfg.rxtail! = tail)
{
Dmacfg.rxtail = tail;
Re-sync the shadow on any 1st byte (s) received.
if (Dmacfg.rxtick = = 0)
{
DMACFG.RXSHDW = ST0;
}
Dmacfg.rxtick = Hal_uart_dma_idle;
}
else if (Dmacfg.rxtick)
{
Use the LSB of the sleep timer (ST0 must is read first anyway).
Uint8 DECR = ST0-DMACFG.RXSHDW;
if (Dmacfg.rxtick > Decr)
{
Dmacfg.rxtick-= DECR;
DMACFG.RXSHDW = ST0;
}
Else
{
Dmacfg.rxtick = 0;
}
}
CNT = HALUARTRXAVAILDMA ();
}
Else
{
Dmacfg.rxtick = 0;
}
if (CNT >= hal_uart_dma_full)
{
EVT = Hal_uart_rx_full;
}
else if (CNT >= hal_uart_dma_high)
{
EVT = Hal_uart_rx_about_full;
Pxout |= Hal_uart_px_rts;
}
else if (CNT &&!dmacfg.rxtick)
{
EVT = Hal_uart_rx_timeout;
}
if (DMACFG.TXMT)
{
DMACFG.TXMT = FALSE;
EVT |= Hal_uart_tx_empty;
}
if (dmacfg.txshdwvalid)
{
Uint8 DECR = ST0;
DECR-= DMACFG.TXSHDW;
if (Decr > Dmacfg.txtick)
{
No protection for Txshdwvalid are required
Because while the shadow is valid, DMA ISR cannot be triggered
To cause concurrent access to this variable.
Dmacfg.txshdwvalid = FALSE;
}
}

if (dmacfg.txdmapending &&!dmacfg.txshdwvalid)
{
UART TX DMA is expected to be fired and enough time have lapsed since last DMA ISR
To know this dbuf can be overwritten
haldmadesc_t *ch = hal_dma_get_desc1234 (HAL_DMA_CH_TX);
halintstate_t intstate;
Clear the DMA pending flag
dmacfg.txdmapending = FALSE;

Hal_dma_set_source (CH, dmacfg.txbuf[dmacfg.txsel]);
Hal_dma_set_len (CH, dmacfg.txidx[dmacfg.txsel]);
Dmacfg.txsel ^= 1;
Hal_enter_critical_section (intstate);
Hal_dma_arm_ch (HAL_DMA_CH_TX);
Do
{
ASM ("NOP");
} while (! Hal_dma_ch_armed (HAL_DMA_CH_TX));
HAL_DMA_CLEAR_IRQ (HAL_DMA_CH_TX);
Hal_dma_man_trigger (HAL_DMA_CH_TX);
Hal_exit_critical_section (intstate);
}
if (evt && (DMACFG.UARTCB! = NULL))
{
DMACFG.UARTCB (Hal_uart_dma-1, evt);
}
}

The HALUARTPOLLDMA function is the core of the entire serial port operation, and the function is called by the system cycle timed, in this function

The state of the read-write buffer is judged, triggering the callback function Haluartcfg_t.callbackfunc. When the function is triggered,

Several events are passed to the callback function, and these events involve the following 4 values:

#define HAL_UART_DMA_FULL (HAL_UART_DMA_RX_MAX-16)
#define HAL_UART_DMA_HIGH (HAL_UART_DMA_RX_MAX/2-16)
#define HAL_UART_DMA_IDLE (6 * hal_uart_msecs_to_ticks)
Dmacfg.txmt

Hal_uart_rx_full event is triggered when buffer data length is greater than or equal to Hal_uart_dma_full

Hal_uart_rx_about_full event is triggered when buffer data length is greater than or equal to Hal_uart_dma_high

Hal_uart_timeout event is triggered when the buffer data length is less than hal_uart_dma_full and the wait time reaches Hal_uart_dma_idle

When DMACFG.TXMT is true, it indicates that the write buffer data has been written to the serial port, triggering the Hal_uart_tx_empty event


Therefore, when using z-stack 's Hal_uart library to operate the serial port, it is recommended to determine whether the data needs to be read in the callback function according to the event, and the write operation can be placed anywhere in the program, including the callback function. When writing data, determine the return value to see if the data is actually written to the buffer.


The HALUARTPOLLDMA call frequency is approximately 200ms, reference

Http://www.360doc.com/content/11/1022/09/7906690_158136472.shtml




This article is from the "11383655" blog, please be sure to keep this source http://11393655.blog.51cto.com/11383655/1758524

Z-stack Serial Communication Usage experience

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.