Hi all,
I am working on a small project using Spark Core. Great product thank you Spark team!!!.
In my project there is a need that DMA copies received serial data to memory. So far, by current setting it seems DMA controller copies received data to memory, I am checking it by constantly printing all rx_buffer.buffer to terminal.
My questions are:
- Where and how should I implement DMA1_Channel6 interrupt handler?
- Any suggestions or advices on USART2 reception using DMA?
Thanks :-).
PS: I am aware that latest I2C is using same DMA resource (DMA1_Channel6).
Current settings.
Brief explanations:
ONE
core-firmware/src/spark_wiring_usartserial.cpp
beginDMA(…) function was added. It is modified version of original begin(unsigned long baud) function.
TWO
core-firmware/inc/spark_wiring_usartserial.h
"private" is changed to public. For purpose of debugging rx_buffer.
THREE
core-firmware/src/application.cpp
Checking whether first element of buffer has changed. If so print all elements. Which are 64.
=====================================================================================
CODES:
From: spark_wiring_usartserial.cpp
....
#define USART2_DR_ADDRESS ((uint32_t)0x40004404)
// It's DMA added version of begin();
void USARTSerial::beginDMA(unsigned long baud)
{
// AFIO clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// Enable USART Clock
*usartMap->usart_apbReg |= usartMap->usart_clock_en;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
//Configuring DMA1 on USART2 RX
DMA_DeInit(DMA1_Channel6);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART2_DR_ADDRESS;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&(_rx_buffer.buffer);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = SERIAL_BUFFER_SIZE;
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_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
// Enable the USART Interrupt
NVIC_InitStructure.NVIC_IRQChannel = usartMap->usart_int_n;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USART2_IRQ_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Configure USART Rx as input floating
pinMode(usartMap->usart_rx_pin, INPUT);
// Configure USART Tx as alternate function push-pull
pinMode(usartMap->usart_tx_pin, AF_OUTPUT_PUSHPULL);
// Remap USARTn to alternate pins EG. USART1 to pins TX/PB6, RX/PB7
GPIO_PinRemapConfig(usartMap->usart_pin_remap, ENABLE);
// USART default configuration
// USART configured as follow:
// - BaudRate = (set baudRate as 9600 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_BaudRate = baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// Configure USART
USART_Init(usartMap->usart_peripheral, &USART_InitStructure);
// Enable USART Receive and Transmit interrupts
// //USART_ITConfig(usartMap->usart_peripheral, USART_IT_RXNE, ENABLE);
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
USART_ITConfig(usartMap->usart_peripheral, USART_IT_TXE, ENABLE);
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
// Enable the USART
USART_Cmd(usartMap->usart_peripheral, ENABLE);
DMA_Cmd(DMA1_Channel6, ENABLE);
USARTSerial_Enabled = true;
transmitting = false;
}
...
From: src/application.cpp
....
void setup(void)
{
WiFi.on();
Serial1.beginDMA(115200);
.... //Some GPIO setting code
}
void loop()
{
if (Serial1._rx_buffer.buffer[0] != 0)
{
for (uint8_t i = 0; i < SERIAL_BUFFER_SIZE; i++){
Serial1.print(Serial1._rx_buffer.buffer[i]);
}
Serial1.println("");
delay(1000);
}
}