Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMA Serial Reading to Circular buffer #26328

Merged
merged 44 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
fbbf539
Update README.md
rondlh Oct 7, 2023
01dcee1
DMA SERIAL READING TO CIRCULAR RX BUFFER
rondlh Oct 7, 2023
88c976b
Revert "Update README.md"
rondlh Oct 8, 2023
bd49014
Changed HAVE_HWSERIALx to USING_HW_SERIALx
rondlh Oct 8, 2023
2988878
formatting
thinkyhead Oct 8, 2023
f01ca5c
HardwareSerial2 => HAL_HardwareSerial
thinkyhead Oct 8, 2023
f92e20f
misc.
thinkyhead Oct 8, 2023
7506508
Added STM32F1xx support, untested!
rondlh Oct 8, 2023
abd47af
Merge branch 'bugfix-2.1.x' of https://github.com/rondlh/Marlin-DMA_R…
rondlh Oct 8, 2023
6d3d4ef
Merging STM32F1 update with Scott's good work, convert to HAL_Hardwar…
rondlh Oct 8, 2023
da14958
Merge branch 'bugfix-2.1.x' into pr/26328
thinkyhead Oct 8, 2023
d458fd8
format and fix
thinkyhead Oct 8, 2023
44b4e3f
etc
thinkyhead Oct 8, 2023
40d0b36
cleanup. best guess for USART4
thinkyhead Oct 8, 2023
10e866b
etc
thinkyhead Oct 8, 2023
bb77078
Leave STM32F1 (Maple) as-is
thinkyhead Oct 8, 2023
1c1d8dd
fix ctor
thinkyhead Oct 9, 2023
7037a52
Don't break other build, keep old code if not STM32F1 F2 F4
rondlh Oct 9, 2023
b355f8c
RX and TX buffers are required to make this work
rondlh Oct 9, 2023
1a3ea93
Support F1 DMA Structure in the same file
rondlh Oct 9, 2023
0f74099
Set SERIAL_PORT 1 for testing
rondlh Oct 9, 2023
f3ac9c7
Corrected issues with STM32F1
rondlh Oct 9, 2023
ef7ac35
Corrected DMA start register for STM32F1
rondlh Oct 9, 2023
f6ab50b
SERIAL_PORT set back to 0
rondlh Oct 10, 2023
4ddba70
Disable Arduino to resolve variable naming conflicts
rondlh Oct 10, 2023
0ecbb7e
Guard Serial DMA writing code with "SERIAL_DMA"
rondlh Oct 10, 2023
9a155af
STM32F0 and STM32F7 support, added Configuration_adv.h
rondlh Oct 11, 2023
8240dc9
Cleanup items not needed for SERIAL_DMA
rondlh Oct 12, 2023
8fb3072
Increase undefined or 0 size RX Buffer from 64 to 128 bytes
rondlh Oct 12, 2023
20ef32e
Improve code readability, STM32F0 support
rondlh Oct 12, 2023
0da5e5f
Merge remote-tracking branch 'upstream/bugfix-2.1.x' into bugfix-2.1.x
rondlh Oct 12, 2023
9fde816
Merge branch 'MarlinFirmware:bugfix-2.1.x' into bugfix-2.1.x
rondlh Oct 12, 2023
31eaa0f
Merge branch 'bugfix-2.1.x' of https://github.com/rondlh/Marlin-DMA_R…
rondlh Oct 12, 2023
9b4be3e
Merge remote-tracking branch 'upstream/bugfix-2.1.x' into bugfix-2.1.x
rondlh Oct 13, 2023
b644553
Merge remote-tracking branch 'upstream/bugfix-2.1.x' into bugfix-2.1.x
rondlh Oct 14, 2023
68229ab
Merge remote-tracking branch 'upstream/bugfix-2.1.x' into bugfix-2.1.x
rondlh Oct 20, 2023
34dd6bc
Fixed compilation error because UART5 has no DMA support on F0 and F1
rondlh Oct 28, 2023
e096917
Merge remote-tracking branch 'upstream/bugfix-2.1.x' into bugfix-2.1.x
rondlh Oct 28, 2023
423e822
check for defines
thinkyhead Dec 11, 2023
1b42724
Merge branch 'bugfix-2.1.x' into pr/26328
thinkyhead Dec 11, 2023
e9eba89
apply standards
thinkyhead Dec 11, 2023
28ff5d4
update comments
thinkyhead Dec 11, 2023
2f75203
add a test
thinkyhead Dec 11, 2023
6b1b5dd
Move some serial defaults
thinkyhead Dec 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
apply standards
  • Loading branch information
thinkyhead committed Dec 11, 2023
commit e9eba8983942c096c1aaea1cb1c551d37add61dc
154 changes: 76 additions & 78 deletions Marlin/src/HAL/STM32/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,59 +21,62 @@
*
*/

// HAL_HARDWARESERIAL CLASS, ADAPTATION FROM ARDUINO'S HARDWARESERIAL
//
// HAL_HardwareSerial Class. Adapted from Arduino HardwareSerial.
//

#include "../../inc/MarlinConfig.h"

#ifdef SERIAL_DMA
#include "../platforms.h"

#ifdef HAL_STM32

#if defined(HAL_UART_MODULE_ENABLED) && !defined(HAL_UART_MODULE_ONLY)
#include "../../inc/MarlinConfig.h"

#if ENABLED(SERIAL_DMA) && defined(HAL_UART_MODULE_ENABLED) && !defined(HAL_UART_MODULE_ONLY)

#include <stdio.h>
#include "HardwareSerial.h"
#include "uart.h"

// USART/UART PIN MAPPING FOR STM32F0/F1/F2/F4/F7
#if !defined PIN_SERIAL1_TX
#define PIN_SERIAL1_TX 9 // PA9
#ifndef PIN_SERIAL1_TX
#define PIN_SERIAL1_TX PA9
#endif
#if !defined PIN_SERIAL1_RX
#define PIN_SERIAL1_RX 10 // PA10
#ifndef PIN_SERIAL1_RX
#define PIN_SERIAL1_RX PA10
#endif
#if !defined PIN_SERIAL2_TX
#define PIN_SERIAL2_TX 2 // PA2
#ifndef PIN_SERIAL2_TX
#define PIN_SERIAL2_TX PA2
#endif
#if !defined PIN_SERIAL2_RX
#define PIN_SERIAL2_RX 3 // PA3
#ifndef PIN_SERIAL2_RX
#define PIN_SERIAL2_RX PA3
#endif
#if !defined PIN_SERIAL3_TX
#define PIN_SERIAL3_TX 26 // PB10
#ifndef PIN_SERIAL3_TX
#define PIN_SERIAL3_TX PB10
#endif
#if !defined PIN_SERIAL3_RX
#define PIN_SERIAL3_RX 27 // PB11
#ifndef PIN_SERIAL3_RX
#define PIN_SERIAL3_RX PB11
#endif
#if !defined PIN_SERIAL4_TX
#define PIN_SERIAL4_TX 42 // PC10
#ifndef PIN_SERIAL4_TX
#define PIN_SERIAL4_TX PC10
#endif
#if !defined PIN_SERIAL4_RX
#define PIN_SERIAL4_RX 43 // PC11
#ifndef PIN_SERIAL4_RX
#define PIN_SERIAL4_RX PC11
#endif
#if !defined PIN_SERIAL5_TX
#define PIN_SERIAL5_TX 44 // PC12
#ifndef PIN_SERIAL5_TX
#define PIN_SERIAL5_TX PC12
#endif
#if !defined PIN_SERIAL5_RX
#define PIN_SERIAL5_RX 50 // PD2
#ifndef PIN_SERIAL5_RX
#define PIN_SERIAL5_RX PD2
#endif
#if !defined PIN_SERIAL6_TX
#define PIN_SERIAL6_TX 38 // PC6
#ifndef PIN_SERIAL6_TX
#define PIN_SERIAL6_TX PC6
#endif
#if !defined PIN_SERIAL6_RX
#define PIN_SERIAL6_RX 39 // PC7
#ifndef PIN_SERIAL6_RX
#define PIN_SERIAL6_RX PC7
#endif

// TODO: GET FROM INCLUDE FILE
// TODO: Get from include file

#if ANY(STM32F2xx, STM32F4xx, STM32F7xx)

#define RCC_AHB1Periph_DMA1 ((uint32_t)0x00200000)
Expand All @@ -89,6 +92,7 @@
else
RCC->AHB1ENR &= ~RCC_AHB1Periph;
}

#endif

#if ANY(STM32F0xx, STM32F1xx)
Expand All @@ -106,6 +110,7 @@
else
RCC->AHBENR &= ~RCC_AHBPeriph;
}

#endif

// END OF TODO------------------------------------------------------
Expand All @@ -116,17 +121,14 @@
HAL_HardwareSerial HSerial1(USART1);
void serialEvent1() __attribute__((weak));
#endif

#ifdef USING_HW_SERIAL2
HAL_HardwareSerial HSerial2(USART2);
void serialEvent2() __attribute__((weak));
#endif

#ifdef USING_HW_SERIAL3
HAL_HardwareSerial Serial3(USART3);
void serialEvent3() __attribute__((weak));
#endif

#ifdef USING_HW_SERIAL4
#ifdef USART4
HAL_HardwareSerial HSerial4(USART4);
Expand All @@ -135,7 +137,6 @@
#endif
void serialEvent4() __attribute__((weak));
#endif

#ifdef USING_HW_SERIAL5
#ifdef USART5
HAL_HardwareSerial HSerial5(USART5);
Expand All @@ -144,7 +145,6 @@
#endif
void serialEvent5() __attribute__((weak));
#endif

#ifdef USING_HW_SERIAL6
#ifdef USART6
HAL_HardwareSerial HSerial5(USART6);
Expand Down Expand Up @@ -325,13 +325,12 @@ void HAL_HardwareSerial::begin(unsigned long baud, uint8_t config) {

void HAL_HardwareSerial::end() {
flush(); // Wait for transmission of outgoing data

uart_deinit(&_serial);

_serial.rx_head = _serial.rx_tail; // Clear any received data
}

void HAL_HardwareSerial::update_rx_head() { // update buffer head for DMA progress
// Update buffer head for DMA progress
void HAL_HardwareSerial::update_rx_head() {

#if ENABLED(EMERGENCY_PARSER)
static uint32_t flag = 0;
Expand Down Expand Up @@ -393,59 +392,58 @@ void HAL_HardwareSerial::flush() {

#if ANY(STM32F2xx, STM32F4xx, STM32F7xx)

void HAL_HardwareSerial::Serial_DMA_Read_Enable() {
RCC_AHB1PeriphClockCmd(RX_DMA.dma_rcc, ENABLE); // Enable DMA clock
void HAL_HardwareSerial::Serial_DMA_Read_Enable() {
RCC_AHB1PeriphClockCmd(RX_DMA.dma_rcc, ENABLE); // Enable DMA clock

#ifdef STM32F7xx
RX_DMA.dma_streamRX->PAR = (uint32_t)(&RX_DMA.uart->RDR); // RX peripheral receive address (usart) F7
#else
RX_DMA.dma_streamRX->PAR = (uint32_t)(&RX_DMA.uart->DR); // RX peripheral address (usart) F2 / F4
#endif
RX_DMA.dma_streamRX->M0AR = (uint32_t)_serial.rx_buff; // RX destination address (memory)
RX_DMA.dma_streamRX->NDTR = RX_BUFFER_SIZE; // RX buffer size
#ifdef STM32F7xx
RX_DMA.dma_streamRX->PAR = (uint32_t)(&RX_DMA.uart->RDR); // RX peripheral receive address (usart) F7
#else
RX_DMA.dma_streamRX->PAR = (uint32_t)(&RX_DMA.uart->DR); // RX peripheral address (usart) F2 / F4
#endif
RX_DMA.dma_streamRX->M0AR = (uint32_t)_serial.rx_buff; // RX destination address (memory)
RX_DMA.dma_streamRX->NDTR = RX_BUFFER_SIZE; // RX buffer size

RX_DMA.dma_streamRX->CR = (RX_DMA.dma_channel << 25); // RX channel selection, set to 0 all the other CR bits
RX_DMA.dma_streamRX->CR = (RX_DMA.dma_channel << 25); // RX channel selection, set to 0 all the other CR bits

RX_DMA.dma_streamRX->CR |= (3 << 16); // RX priority level: Very High
RX_DMA.dma_streamRX->CR |= (3 << 16); // RX priority level: Very High

//RX_DMA.dma_streamRX->CR &= ~(3 << 13); // RX memory data size: 8 bit
//RX_DMA.dma_streamRX->CR &= ~(3 << 11); // RX peripheral data size: 8 bit
RX_DMA.dma_streamRX->CR |= (1 << 10); // RX memory increment mode
//RX_DMA.dma_streamRX->CR &= ~(1 << 9); // RX peripheral no increment mode
RX_DMA.dma_streamRX->CR |= (1 << 8); // RX circular mode enabled
//RX_DMA.dma_streamRX->CR &= ~(1 << 6); // RX data transfer direction: Peripheral-to-memory
RX_DMA.uart->CR3 |= (1 << 6); // Enable DMA receiver (DMAR)
RX_DMA.dma_streamRX->CR |= (1 << 0); // RX enable DMA
}
//RX_DMA.dma_streamRX->CR &= ~(3 << 13); // RX memory data size: 8 bit
//RX_DMA.dma_streamRX->CR &= ~(3 << 11); // RX peripheral data size: 8 bit
RX_DMA.dma_streamRX->CR |= (1 << 10); // RX memory increment mode
//RX_DMA.dma_streamRX->CR &= ~(1 << 9); // RX peripheral no increment mode
RX_DMA.dma_streamRX->CR |= (1 << 8); // RX circular mode enabled
//RX_DMA.dma_streamRX->CR &= ~(1 << 6); // RX data transfer direction: Peripheral-to-memory
RX_DMA.uart->CR3 |= (1 << 6); // Enable DMA receiver (DMAR)
RX_DMA.dma_streamRX->CR |= (1 << 0); // RX enable DMA
}

#endif // ANY(STM32F2xx, STM32F4xx, STM32F7xx)
#endif // STM32F2xx || STM32F4xx || STM32F7xx

#if ANY(STM32F0xx, STM32F1xx)

void HAL_HardwareSerial::Serial_DMA_Read_Enable() {
RCC_AHBPeriphClockCmd(RX_DMA.dma_rcc, ENABLE); // enable DMA clock
void HAL_HardwareSerial::Serial_DMA_Read_Enable() {
RCC_AHBPeriphClockCmd(RX_DMA.dma_rcc, ENABLE); // enable DMA clock

RX_DMA.dma_channelRX->CPAR = (uint32_t)(&RX_DMA.uart->DR); // RX peripheral address (usart)
RX_DMA.dma_channelRX->CMAR = (uint32_t)_serial.rx_buff; // RX destination address (memory)
RX_DMA.dma_channelRX->CNDTR = RX_BUFFER_SIZE; // RX buffer size
RX_DMA.dma_channelRX->CPAR = (uint32_t)(&RX_DMA.uart->DR); // RX peripheral address (usart)
RX_DMA.dma_channelRX->CMAR = (uint32_t)_serial.rx_buff; // RX destination address (memory)
RX_DMA.dma_channelRX->CNDTR = RX_BUFFER_SIZE; // RX buffer size

RX_DMA.dma_channelRX->CCR = 0; // RX channel selection, set to 0 all the other CR bits
RX_DMA.dma_channelRX->CCR = 0; // RX channel selection, set to 0 all the other CR bits

RX_DMA.dma_channelRX->CCR |= (3<<12); // RX priority level: Very High
RX_DMA.dma_channelRX->CCR |= (3<<12); // RX priority level: Very High

//RX_DMA.dma_channelRX->CCR &= ~(1<<10); // RX memory data size: 8 bit
//RX_DMA.dma_channelRX->CCR &= ~(1<<8); // RX peripheral data size: 8 bit
RX_DMA.dma_channelRX->CCR |= (1<<7); // RX memory increment mode
//RX_DMA.dma_channelRX->CCR &= ~(1<<6); // RX peripheral no increment mode
RX_DMA.dma_channelRX->CCR |= (1<<5); // RX circular mode enabled
//RX_DMA.dma_channelRX->CCR &= ~(1<<4); // RX data transfer direction: Peripheral-to-memory
//RX_DMA.dma_channelRX->CCR &= ~(1<<10); // RX memory data size: 8 bit
//RX_DMA.dma_channelRX->CCR &= ~(1<<8); // RX peripheral data size: 8 bit
RX_DMA.dma_channelRX->CCR |= (1<<7); // RX memory increment mode
//RX_DMA.dma_channelRX->CCR &= ~(1<<6); // RX peripheral no increment mode
RX_DMA.dma_channelRX->CCR |= (1<<5); // RX circular mode enabled
//RX_DMA.dma_channelRX->CCR &= ~(1<<4); // RX data transfer direction: Peripheral-to-memory

RX_DMA.uart->CR3 |= (1<<6); // enable DMA receiver (DMAR)
RX_DMA.dma_channelRX->CCR |= (1<<0); // RX enable DMA
}
RX_DMA.uart->CR3 |= (1<<6); // enable DMA receiver (DMAR)
RX_DMA.dma_channelRX->CCR |= (1<<0); // RX enable DMA
}

#endif // ANY(STM32F0xx, STM32F1xx)
#endif // STM32F0xx || STM32F1xx

#endif // HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY
#endif // SERIAL_DMA && HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY
#endif // HAL_STM32
#endif // SERIAL_DMA
42 changes: 16 additions & 26 deletions Marlin/src/HAL/STM32/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,43 +20,35 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef SERIAL_DMA

// TODO: Move to more appropriate place
#if NONE(STM32F0xx, STM32F1xx, STM32F2xx, STM32F4xx, STM32F7xx)
#error "SERIAL_DMA is currently only supported on STM32F0xx, STM32F1xx STM32F2xx, STM32F4xx and STM32F7xx."
#endif

#pragma once

#if !defined(RX_BUFFER_SIZE) || (RX_BUFFER_SIZE == 0)
//
// HAL_HardwareSerial Class. Adapted from Arduino HardwareSerial.
//

#if RX_BUFFER_SIZE == 0
#undef RX_BUFFER_SIZE
#define RX_BUFFER_SIZE 128
#endif

#if !defined(TX_BUFFER_SIZE) || (TX_BUFFER_SIZE == 0)
#if TX_BUFFER_SIZE == 0
#undef TX_BUFFER_SIZE
#define TX_BUFFER_SIZE 64
#endif

#if ANY(STM32F0xx, STM32F1xx)
typedef struct
{ // F0 / F1
USART_TypeDef * uart;
uint32_t dma_rcc;
typedef struct {
USART_TypeDef * uart;
uint32_t dma_rcc;
#if ANY(STM32F0xx, STM32F1xx) // F0 / F1
DMA_TypeDef * dma_controller;
DMA_Channel_TypeDef * dma_channelRX;
} DMA_CFG;
#else // F2 / F4 / F7
typedef struct {
USART_TypeDef * uart;
uint32_t dma_rcc;
#else // F2 / F4 / F7
uint32_t dma_channel;
DMA_Stream_TypeDef * dma_streamRX;
} DMA_CFG;
#endif
#endif
} DMA_CFG;

class HAL_HardwareSerial : public Stream {
class HAL_HardwareSerial : public Stream {
protected:
// Don't put any members after these buffers, since only the first
// 32 bytes of this struct can be accessed quickly using the ldd instruction.
Expand All @@ -66,14 +58,14 @@
serial_t _serial;

public:
HAL_HardwareSerial(void *peripheral);
HAL_HardwareSerial(void *peripheral);
void begin(unsigned long, uint8_t);
void end();
virtual int available();
virtual int read();
virtual int peek();
virtual size_t write(uint8_t);
virtual void flush();
virtual void flush();
operator bool() { return true; }

void setRx(uint32_t _rx);
Expand All @@ -91,5 +83,3 @@
DMA_CFG RX_DMA;
void Serial_DMA_Read_Enable();
};

#endif // SERIAL_DMA
Loading