论坛元老
 
- 积分
- 7462
- 金钱
- 7462
- 注册时间
- 2015-1-15
- 在线时间
- 1367 小时
|
发表于 2020-2-25 15:37:36
|
显示全部楼层
uint8_t m_dma_recv_buf[eUSARTn][USART_DMA_RECV_SIZE];
uint8_t m_dma_send_buf[eUSARTn][USART_DMA_SEND_SIZE];
const usart_type usart_handlers[eUSARTn] =
{
[eUSART1] =
{
.irq_vector = USART1_IRQn,
.mpriority = 1,
.spriority = 1,
.port = USART1,
.pin_tx = &gpio_handlers[eUSART1Tx],
.pin_rx = &gpio_handlers[eUSART1Rx],
.pin_cts = NULL,
.pin_rts = NULL,
.pin_en = &gpio_handlers[eUSART1En],
.pin_en_config = &pin_config_handlers[eUSART1En],
.tx_dma_config =
{
.irq_vector = DMA2_Stream7_IRQn,
.mpriority = 2,
.spriority = 1,
.controller = DMA2,
.stream = DMA2_Stream7,
.channel = DMA_Channel_4,
.complete_flags = DMA_IT_TCIF7,
.error_flags = 0,
},
.rx_dma_config =
{
.irq_vector = DMA2_Stream2_IRQn,
.mpriority = 2,
.spriority = 1,
.controller = DMA2,
.stream = DMA2_Stream2,
.channel = DMA_Channel_4,
.complete_flags = DMA_IT_TCIF2,
.error_flags = 0,
},
},
[eUSART2] =
{
.irq_vector = USART2_IRQn,
.mpriority = 1,
.spriority = 1,
.port = USART2,
.pin_tx = &gpio_handlers[eUSART2Tx],
.pin_rx = &gpio_handlers[eUSART2Rx],
.pin_cts = NULL,
.pin_rts = NULL,
.pin_en = &gpio_handlers[eUSART2En],
.pin_en_config = &pin_config_handlers[eUSART2En],
.tx_dma_config =
{
.irq_vector = DMA1_Stream6_IRQn,
.mpriority = 2,
.spriority = 1,
.controller = DMA1,
.stream = DMA1_Stream6,
.channel = DMA_Channel_4,
.complete_flags = DMA_IT_TCIF6,
.error_flags = 0,
},
.rx_dma_config =
{
.irq_vector = DMA1_Stream5_IRQn,
.mpriority = 2,
.spriority = 1,
.controller = DMA1,
.stream = DMA1_Stream5,
.channel = DMA_Channel_4,
.complete_flags = DMA_IT_TCIF5,
.error_flags = 0,
},
},
[eUSART3] =
{
.irq_vector = USART3_IRQn,
.mpriority = 1,
.spriority = 1,
.port = USART3,
.pin_tx = &gpio_handlers[eUSART3Tx],
.pin_rx = &gpio_handlers[eUSART3Rx],
.pin_cts = NULL,
.pin_rts = NULL,
.pin_en = &gpio_handlers[eUSART3En],
.pin_en_config = &pin_config_handlers[eUSART3En],
.tx_dma_config =
{
.irq_vector = DMA1_Stream3_IRQn,
.mpriority = 2,
.spriority = 1,
.controller = DMA1,
.stream = DMA1_Stream3,
.channel = DMA_Channel_4,
.complete_flags = DMA_IT_TCIF3,
.error_flags = 0,
},
.rx_dma_config =
{
.irq_vector = DMA1_Stream1_IRQn,
.mpriority = 2,
.spriority = 1,
.controller = DMA1,
.stream = DMA1_Stream1,
.channel = DMA_Channel_4,
.complete_flags = DMA_IT_TCIF1,
.error_flags = 0,
},
},
[eUSART6] =
{
.irq_vector = USART6_IRQn,
.mpriority = 1,
.spriority = 1,
.port = USART6,
.pin_tx = &gpio_handlers[eUSART6Tx],
.pin_rx = &gpio_handlers[eUSART6Rx],
.pin_cts = NULL,
.pin_rts = NULL,
.pin_en = &gpio_handlers[eUSART6En],
.pin_en_config = &pin_config_handlers[eUSART6En],
.tx_dma_config =
{
.irq_vector = DMA2_Stream6_IRQn,
.mpriority = 2,
.spriority = 1,
.controller = DMA2,
.stream = DMA2_Stream6,
.channel = DMA_Channel_5,
.complete_flags = DMA_IT_TCIF6,
.error_flags = 0,
},
.rx_dma_config =
{
.irq_vector = DMA2_Stream1_IRQn,
.mpriority = 2,
.spriority = 1,
.controller = DMA2,
.stream = DMA2_Stream1,
.channel = DMA_Channel_5,
.complete_flags = DMA_IT_TCIF1,
.error_flags = 0,
},
},
};
const usart_config_type usart_config_handlers[eUSARTn] =
{
[eUSART1] = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED, 0},
[eUSART2] = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED, 0},
[eUSART3] = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED, 0},
[eUSART6] = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED, 0},
};
static const uint8_t usart_alternate_functions[eUSARTn] =
{
[eUSART1] = GPIO_AF_USART1,
[eUSART2] = GPIO_AF_USART2,
[eUSART3] = GPIO_AF_USART3,
[eUSART6] = GPIO_AF_USART6,
};
static const mico_peripheral_clock_function_type usart_peripheral_clock_functions[eUSARTn] =
{
[eUSART1] = RCC_APB2PeriphClockCmd,
[eUSART2] = RCC_APB1PeriphClockCmd,
[eUSART3] = RCC_APB1PeriphClockCmd,
[eUSART6] = RCC_APB2PeriphClockCmd,
};
static const uint32_t usart_peripheral_clocks[eUSARTn] =
{
[eUSART1] = RCC_APB2Periph_USART1,
[eUSART2] = RCC_APB1Periph_USART2,
[eUSART3] = RCC_APB1Periph_USART3,
[eUSART6] = RCC_APB2Periph_USART6,
};
usart_driver_type usart_drivers[eUSARTn] =
{
[eUSART1] =
{
.uFrameFlag = false,
.peripheral = (usart_type*)&usart_handlers[eUSART1],
.uFrameObj =
{
.event = eUSART1,
.rxbuf = &m_dma_recv_buf[eUSART1][0],
.txbuf = &m_dma_send_buf[eUSART1][0],
.rxlen = 0,
.txlen = 0,
},
.tx_buf = &m_dma_send_buf[eUSART1][0],
.rx_buf = &m_dma_recv_buf[eUSART1][0],
.tx_size = 0,
.rx_size = 0,
},
[eUSART2] =
{
.uFrameFlag = false,
.peripheral = (usart_type*)&usart_handlers[eUSART2],
.uFrameObj =
{
.event = eUSART2,
.rxbuf = &m_dma_recv_buf[eUSART1][0],
.txbuf = &m_dma_send_buf[eUSART1][0],
.rxlen = 0,
.txlen = 0,
},
.tx_buf = &m_dma_send_buf[eUSART2][0],
.rx_buf = &m_dma_recv_buf[eUSART2][0],
.tx_size = 0,
.rx_size = 0,
},
[eUSART3] =
{
.uFrameFlag = false,
.peripheral = (usart_type*)&usart_handlers[eUSART3],
.uFrameObj =
{
.event = eUSART3,
.rxbuf = &m_dma_recv_buf[eUSART1][0],
.txbuf = &m_dma_send_buf[eUSART1][0],
.rxlen = 0,
.txlen = 0,
},
.tx_buf = &m_dma_send_buf[eUSART3][0],
.rx_buf = &m_dma_recv_buf[eUSART3][0],
.tx_size = 0,
.rx_size = 0,
},
[eUSART6] =
{
.uFrameFlag = false,
.peripheral = (usart_type*)&usart_handlers[eUSART6],
.uFrameObj =
{
.event = eUSART6,
.rxbuf = &m_dma_recv_buf[eUSART1][0],
.txbuf = &m_dma_send_buf[eUSART1][0],
.rxlen = 0,
.txlen = 0,
},
.tx_buf = &m_dma_send_buf[eUSART6][0],
.rx_buf = &m_dma_recv_buf[eUSART6][0],
.tx_size = 0,
.rx_size = 0,
},
};
static uint8_t usart_port_number(USART_TypeDef *usart)
{
switch( (uint32_t)usart )
{
case USART1_BASE:
return 0;
case USART2_BASE:
return 1;
case USART3_BASE:
return 2;
case USART6_BASE:
return 3;
default:
return 0xFF;
}
}
void sUSARTx_DMA_Configuration(usart_driver_type *driver, const usart_type *peripheral, const usart_config_type *config)
{
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
uint8_t usart_number = usart_port_number(driver->peripheral->port);
driver->rx_size = 0;
driver->tx_size = 0;
driver->peripheral = (usart_type*)peripheral;
usart_peripheral_clock_functions[usart_number](usart_peripheral_clocks[usart_number], ENABLE);
/* Enable DMA peripheral clock */
if ( peripheral->tx_dma_config.controller == DMA1 )
{
RCC->AHB1ENR |= RCC_AHB1Periph_DMA1;
}
else
{
RCC->AHB1ENR |= RCC_AHB1Periph_DMA2;
}
gpio_set_alternate_function(peripheral->pin_tx->port, peripheral->pin_tx->pin_number, GPIO_OType_PP, GPIO_PuPd_UP, usart_alternate_functions[ usart_number ] );
gpio_set_alternate_function(peripheral->pin_rx->port, peripheral->pin_rx->pin_number, GPIO_OType_PP, GPIO_PuPd_UP, usart_alternate_functions[ usart_number ] );
if ( ( peripheral->pin_cts != NULL ) && ( config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS ) )
{
gpio_set_alternate_function( peripheral->pin_cts->port, peripheral->pin_cts->pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, usart_alternate_functions[ usart_number ] );
}
if ( ( peripheral->pin_rts != NULL ) && ( config->flow_control == FLOW_CONTROL_RTS || config->flow_control == FLOW_CONTROL_CTS_RTS ) )
{
gpio_set_alternate_function( peripheral->pin_rts->port, peripheral->pin_rts->pin_number, GPIO_OType_PP, GPIO_PuPd_NOPULL, usart_alternate_functions[ usart_number ] );
}
if(driver->peripheral->pin_en != NULL)
{
gpio_init(peripheral->pin_en, *peripheral->pin_en_config);
gpio_low(peripheral->pin_en);
}
/* Initialise USART peripheral */
USART_DeInit(peripheral->port);
/* Enable the USART OverSampling by 8 */
USART_OverSampling8Cmd(peripheral->port, ENABLE);
/* USARTx configuration ----------------------------------------------------*/
/* USARTx configured as follows:
- BaudRate = 5250000 baud
- Maximum BaudRate that can be achieved when using the Oversampling by 8
is: (USART APB Clock / 8)
Example:
- (USART3 APB1 Clock / 8) = (42 MHz / 8) = 5250000 baud
- (USART1 APB2 Clock / 8) = (84 MHz / 8) = 10500000 baud
- Maximum BaudRate that can be achieved when using the Oversampling by 16
is: (USART APB Clock / 16)
Example: (USART3 APB1 Clock / 16) = (42 MHz / 16) = 2625000 baud
Example: (USART1 APB2 Clock / 16) = (84 MHz / 16) = 5250000 baud
- Word Length = 8 Bits
- one Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_BaudRate = config->baud_rate;
USART_InitStructure.USART_WordLength = ( ( config->data_width == DATA_WIDTH_9BIT ) || ( ( config->data_width == DATA_WIDTH_8BIT ) && ( config->parity != NO_PARITY ) ) ) ? USART_WordLength_9b : USART_WordLength_8b;
USART_InitStructure.USART_StopBits = ( config->stop_bits == STOP_BITS_1 ) ? USART_StopBits_1 : USART_StopBits_2;
switch ( config->parity )
{
case NO_PARITY:
USART_InitStructure.USART_Parity = USART_Parity_No;
break;
case EVEN_PARITY:
USART_InitStructure.USART_Parity = USART_Parity_Even;
break;
case ODD_PARITY:
USART_InitStructure.USART_Parity = USART_Parity_Odd;
break;
default:
break;
}
switch ( config->flow_control )
{
case FLOW_CONTROL_DISABLED:
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
break;
case FLOW_CONTROL_CTS:
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_CTS;
break;
case FLOW_CONTROL_RTS:
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS;
break;
case FLOW_CONTROL_CTS_RTS:
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
break;
default:
break;
}
USART_Init(peripheral->port, &USART_InitStructure);
/* Disable USART */
USART_Cmd(peripheral->port, DISABLE);
/* Enable the USART Receive interrupt: this interrupt is generated when the
USART receive data register is not empty */
//USART_ITConfig(driver->peripheral->port, USART_IT_RXNE, ENABLE);
//USART IDLE Interrupt
USART_ITConfig(peripheral->port, USART_IT_IDLE, ENABLE);
/* Enable USART */
USART_Cmd(peripheral->port, ENABLE);
/* Clear USART TC Flag */
USART_ClearFlag(peripheral->port, USART_FLAG_TC);
/*Enable the USART Interrupt*/
NVIC_InitStructure.NVIC_IRQChannel = peripheral->irq_vector;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = peripheral->mpriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = peripheral->spriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// FOR USART DMA RX
NVIC_InitStructure.NVIC_IRQChannel = peripheral->rx_dma_config.irq_vector;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = peripheral->rx_dma_config.mpriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = peripheral->rx_dma_config.spriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// FOR USART DMA TX
NVIC_InitStructure.NVIC_IRQChannel = peripheral->tx_dma_config.irq_vector;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = peripheral->tx_dma_config.mpriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = peripheral->tx_dma_config.spriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
reload_usart_dma_rx(driver, (uint8_t*)&m_dma_recv_buf[usart_number][0], USART_DMA_RECV_SIZE);
}
/*RX*/
void reload_usart_dma_rx(usart_driver_type *driver, uint8_t *p_data, uint16_t rx_size)
{
DMA_InitTypeDef DMA_InitStructure;
uint8_t usart_number = usart_port_number(driver->peripheral->port);
/* Configure DMA controller to manage USART TX DMA request ----------*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&driver->peripheral->port->DR);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_DeInit(driver->peripheral->rx_dma_config.stream);
DMA_InitStructure.DMA_Channel = driver->peripheral->rx_dma_config.channel;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)p_data;
DMA_InitStructure.DMA_BufferSize = (uint16_t)rx_size;
DMA_Init(driver->peripheral->rx_dma_config.stream, &DMA_InitStructure);
DMA_ClearITPendingBit(driver->peripheral->rx_dma_config.stream, driver->peripheral->rx_dma_config.complete_flags);
DMA_ITConfig(driver->peripheral->rx_dma_config.stream, DMA_IT_TC, ENABLE);
/* Enable the USART Rx DMA request */
USART_DMACmd(driver->peripheral->port, USART_DMAReq_Rx, ENABLE);
/* Enable the DMA RX Stream */
DMA_Cmd(driver->peripheral->rx_dma_config.stream, ENABLE);
}
/*TX*/
void reload_usart_dma_tx(usart_driver_type *driver, uint8_t *p_data, uint16_t tx_size)
{
DMA_InitTypeDef DMA_InitStructure;
uint8_t usart_number = usart_port_number(driver->peripheral->port);
/* Configure DMA controller to manage USART TX DMA request ----------*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&driver->peripheral->port->DR);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_DeInit(driver->peripheral->tx_dma_config.stream);
DMA_InitStructure.DMA_Channel = driver->peripheral->tx_dma_config.channel;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)p_data;
DMA_InitStructure.DMA_BufferSize = (uint16_t)tx_size;
DMA_Init(driver->peripheral->tx_dma_config.stream, &DMA_InitStructure);
DMA_ClearITPendingBit(driver->peripheral->tx_dma_config.stream, driver->peripheral->tx_dma_config.complete_flags);
/* Enable the DMA Stream Interrupt */
DMA_ITConfig(driver->peripheral->tx_dma_config.stream, DMA_IT_TC, ENABLE);
/* Enable the USART DMA requests */
USART_DMACmd(driver->peripheral->port, USART_DMAReq_Tx, ENABLE);
/* Clear the TC bit in the SR register by writing 0 to it */
USART_ClearFlag(driver->peripheral->port, USART_FLAG_TC);
/* Enable the DMA TX Stream */
DMA_Cmd(driver->peripheral->tx_dma_config.stream, ENABLE);
}
void usart_send_data_packet(usart_driver_type *driver, uint8_t* p_cmd, uint16_t cmd_len)
{
if(0 == cmd_len)
return;
uint8_t usart_number = usart_port_number(driver->peripheral->port);
if(driver->peripheral->pin_en != NULL)
gpio_high(driver->peripheral->pin_en);
memcpy((uint8_t*)&m_dma_send_buf[usart_number][0], p_cmd, cmd_len);
reload_usart_dma_tx(driver, &m_dma_send_buf[usart_number][0], cmd_len);
}
/*TX*/
void sDMA_StreamTx_Interrupt(usart_driver_type *driver)
{
uint8_t usart_number = usart_port_number(driver->peripheral->port);
//TX Interrupt
if(DMA_GetITStatus(driver->peripheral->tx_dma_config.stream, driver->peripheral->tx_dma_config.complete_flags) != RESET)
{
DMA_Cmd(driver->peripheral->tx_dma_config.stream, DISABLE);
DMA_ITConfig(driver->peripheral->tx_dma_config.stream, DMA_IT_TC, DISABLE);
USART_ITConfig(driver->peripheral->port, USART_IT_TC, ENABLE);
DMA_ClearITPendingBit(driver->peripheral->tx_dma_config.stream, driver->peripheral->tx_dma_config.complete_flags);
}
}
/*RX*/
void sDMA_StreamRx_Interrupt(usart_driver_type *driver)
{
uint8_t usart_number = usart_port_number(driver->peripheral->port);
//RX Interrupt
if(DMA_GetITStatus(driver->peripheral->rx_dma_config.stream, driver->peripheral->rx_dma_config.complete_flags) != RESET)
{
reload_usart_dma_rx(driver, (uint8_t*)&m_dma_recv_buf[usart_number][0], USART_DMA_RECV_SIZE);
DMA_ClearITPendingBit(driver->peripheral->rx_dma_config.stream, driver->peripheral->rx_dma_config.complete_flags);
}
}
void sUSART_DMA_Interrupt(usart_driver_type *driver)
{
Comm_Type *pEvt = NULL;
uint8_t usart_number = usart_port_number(driver->peripheral->port);
if(driver->peripheral->port->SR & 0x00000008) driver->peripheral->port->SR |= 0x00000008;
if(USART_GetITStatus(driver->peripheral->port, USART_IT_IDLE) != RESET)
{
//USART_ClearITPendingBit(driver->peripheral->port, USART_IT_IDLE);
DMA_Cmd(driver->peripheral->rx_dma_config.stream, DISABLE);
driver->uFrameFlag = true;
pEvt = &driver->uFrameObj;
if(pEvt != NULL)
{
memset(pEvt, 0x00, sizeof(Comm_Type));
pEvt->event = usart_number;
pEvt->rxlen = USART_DMA_RECV_SIZE - DMA_GetCurrDataCounter(driver->peripheral->rx_dma_config.stream);
pEvt->rxbuf = (uint8_t*)&m_dma_recv_buf[usart_number][0];
pEvt->txbuf = (uint8_t*)&m_dma_send_buf[usart_number][0];
}
USART_ReceiveData(driver->peripheral->port);
DMA_SetCurrDataCounter(driver->peripheral->rx_dma_config.stream, USART_DMA_RECV_SIZE);
DMA_Cmd(driver->peripheral->rx_dma_config.stream, ENABLE);
}
if(USART_GetITStatus(driver->peripheral->port, USART_IT_TC) != RESET)
{
if(driver->peripheral->pin_en != NULL)
gpio_low(driver->peripheral->pin_en);
USART_ITConfig(driver->peripheral->port, USART_IT_TC, DISABLE);
USART_ClearITPendingBit(driver->peripheral->port, USART_IT_TC);
}
}
以上代码楼主可以参考
|
|