Skip to content

Core api update serial #340

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

Merged
merged 5 commits into from
May 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion cores/xmc/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ extern void loop(void);
} // extern "C"
// #include "Tone.h"
// #include "WMath.h"
// #include "Uart.h"
#include "Uart.h"
#endif // __cplusplus

// #include "Print.h"
Expand Down
145 changes: 145 additions & 0 deletions cores/xmc/Uart.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@

#include "Uart.h"
#include "Arduino.h"

// Constructors ////////////////////////////////////////////////////////////////

Uart::Uart(XMC_UART_t *xmc_uart_config) { _XMC_UART_config = xmc_uart_config; }

// Public Methods //////////////////////////////////////////////////////////////

void Uart::begin(unsigned long baud) { begin(baud, SERIAL_8N1); }

void Uart::begin(unsigned long baud, unsigned short config) {
begin(baud, static_cast<XMC_UART_MODE_t>(config));
}

void Uart::begin(unsigned long baud, XMC_UART_MODE_t config) {
XMC_UART_CH_CONFIG_t uart_ch_config;
uart_ch_config.oversampling = 0; // Must be 0 or valid oversample for baud rate calculations
uart_ch_config.baudrate = baud;
uart_ch_config.data_bits = (uint8_t)(config & 0x00fU);
uart_ch_config.frame_length = uart_ch_config.data_bits; // Set same as data bits length
uart_ch_config.parity_mode = (XMC_USIC_CH_PARITY_MODE_t)(config & ~0xffU);
uart_ch_config.stop_bits = (uint8_t)((config & 0x0f0U) >> 4);

XMC_UART_CH_Init(_XMC_UART_config->channel, &uart_ch_config);

// dx0 is UART RX: source must be set
XMC_USIC_CH_SetInputSource(_XMC_UART_config->channel, XMC_USIC_CH_INPUT_DX0,
_XMC_UART_config->input_source_dx0);

// Additional input multiplexing
// Check if dx1 is used
if (_XMC_UART_config->input_source_dx1 != XMC_INPUT_INVALID)
XMC_USIC_CH_SetInputSource(_XMC_UART_config->channel, XMC_USIC_CH_INPUT_DX1,
_XMC_UART_config->input_source_dx1);

// Check if dx2 is used
if (_XMC_UART_config->input_source_dx2 != XMC_INPUT_INVALID)
XMC_USIC_CH_SetInputSource(_XMC_UART_config->channel, XMC_USIC_CH_INPUT_DX2,
_XMC_UART_config->input_source_dx2);

// Check if dx3 is used
if (_XMC_UART_config->input_source_dx3 != XMC_INPUT_INVALID)
XMC_USIC_CH_SetInputSource(_XMC_UART_config->channel, XMC_USIC_CH_INPUT_DX3,
_XMC_UART_config->input_source_dx3);

XMC_UART_CH_EnableEvent(_XMC_UART_config->channel, XMC_UART_CH_EVENT_ALTERNATIVE_RECEIVE |
XMC_UART_CH_EVENT_STANDARD_RECEIVE);
XMC_USIC_CH_SetInterruptNodePointer(_XMC_UART_config->channel,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE,
_XMC_UART_config->irq_service_request);
XMC_USIC_CH_SetInterruptNodePointer(_XMC_UART_config->channel,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE,
_XMC_UART_config->irq_service_request);
XMC_USIC_CH_SetInterruptNodePointer(_XMC_UART_config->channel,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER,
_XMC_UART_config->irq_service_request);
NVIC_SetPriority(_XMC_UART_config->irq_num, 3);
NVIC_EnableIRQ(_XMC_UART_config->irq_num);

XMC_UART_CH_Start(_XMC_UART_config->channel);

// TX pin setup put here to avoid startup corrupted characters being first sent
XMC_GPIO_Init(_XMC_UART_config->tx.port, _XMC_UART_config->tx.pin,
&(_XMC_UART_config->tx_config));

XMC_GPIO_Init(_XMC_UART_config->rx.port, _XMC_UART_config->rx.pin,
&(_XMC_UART_config->rx_config));
serial_ready = true;
}

void Uart::end(void) {
// Wait for any outstanding data to be sent
flush();
// Disable UART interrupt in NVIC
NVIC_DisableIRQ(_XMC_UART_config->irq_num);
// Clear any received data after stopping interrupts
_rx_buffer.clear();
serial_ready = false;
}

void Uart::setInterruptPriority(uint32_t priority) {
NVIC_SetPriority(_XMC_UART_config->irq_num, priority & 0x03);
}

uint32_t Uart::getInterruptPriority() { return NVIC_GetPriority(_XMC_UART_config->irq_num); }

int Uart::available(void) { return _rx_buffer.available(); }

int Uart::availableForWrite(void) {
return 1;
} // TODO: there are no tx buffer so we awaly have 1 byte available

int Uart::peek(void) { return _rx_buffer.peek(); }

int Uart::read(void) { return _rx_buffer.read_char(); }

void Uart::flush(void) {
while (XMC_USIC_CH_GetTransmitBufferStatus(_XMC_UART_config->channel) ==
XMC_USIC_CH_TBUF_STATUS_BUSY) {
};
}

size_t Uart::write(const uint8_t uc_data) {
// For sending, write immediately
// This API already have a check for available buffer
XMC_UART_CH_Transmit(_XMC_UART_config->channel, uc_data);
return 1;
}

size_t Uart::write(const uint8_t *buffer, size_t size) {
// Check if the length is valid
if ((size == 0) || (buffer == nullptr)) {
return 0;
}
// For sending, write immediately
for (size_t i = 0; i < size; i++) {
XMC_UART_CH_Transmit(_XMC_UART_config->channel, buffer[i]);
}
return size;
}

Uart::operator bool() { return serial_ready; }

void Uart::IrqHandler(void) {
// Receive data Interrupt handler
uint32_t status = XMC_UART_CH_GetStatusFlag(_XMC_UART_config->channel);

// Did we receive data?
if ((status & (XMC_UART_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION |
XMC_UART_CH_STATUS_FLAG_RECEIVE_INDICATION)) != 0U) {
XMC_UART_CH_ClearStatusFlag(_XMC_UART_config->channel,
(XMC_UART_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION |
XMC_UART_CH_STATUS_FLAG_RECEIVE_INDICATION));

while (_XMC_UART_config->channel->RBUFSR &
(USIC_CH_RBUFSR_RDV0_Msk | USIC_CH_RBUFSR_RDV1_Msk))
_rx_buffer.store_char(XMC_UART_CH_GetReceivedData(_XMC_UART_config->channel));
}
}

//****************************************************************************
// END OF FILE
//****************************************************************************
104 changes: 104 additions & 0 deletions cores/xmc/Uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#pragma once
//****************************************************************************
// @External Prototypes
//****************************************************************************

#include "Arduino.h"
//****************************************************************************
// @Project Includes
//****************************************************************************
#include "api/HardwareSerial.h"
#include "api/RingBuffer.h"

//****************************************************************************
// @Typedefs
//****************************************************************************
// Define config for Serial.begin(baud, config);
#undef SERIAL_5N1
#undef SERIAL_6N1
#undef SERIAL_7N1
#undef SERIAL_8N1
#undef SERIAL_5N2
#undef SERIAL_6N2
#undef SERIAL_7N2
#undef SERIAL_8N2
#undef SERIAL_5E1
#undef SERIAL_6E1
#undef SERIAL_7E1
#undef SERIAL_8E1
#undef SERIAL_5E2
#undef SERIAL_6E2
#undef SERIAL_7E2
#undef SERIAL_8E2
#undef SERIAL_5O1
#undef SERIAL_6O1
#undef SERIAL_7O1
#undef SERIAL_8O1
#undef SERIAL_5O2
#undef SERIAL_6O2
#undef SERIAL_7O2
#undef SERIAL_8O2

typedef enum XMC_UART_MODE {
SERIAL_5N1 = 0x15 | XMC_USIC_CH_PARITY_MODE_NONE,
SERIAL_6N1 = 0x16 | XMC_USIC_CH_PARITY_MODE_NONE,
SERIAL_7N1 = 0x17 | XMC_USIC_CH_PARITY_MODE_NONE,
SERIAL_8N1 = 0x18 | XMC_USIC_CH_PARITY_MODE_NONE,
SERIAL_5N2 = 0x25 | XMC_USIC_CH_PARITY_MODE_NONE,
SERIAL_6N2 = 0x26 | XMC_USIC_CH_PARITY_MODE_NONE,
SERIAL_7N2 = 0x27 | XMC_USIC_CH_PARITY_MODE_NONE,
SERIAL_8N2 = 0x28 | XMC_USIC_CH_PARITY_MODE_NONE,
SERIAL_5E1 = 0x15 | XMC_USIC_CH_PARITY_MODE_EVEN,
SERIAL_6E1 = 0x16 | XMC_USIC_CH_PARITY_MODE_EVEN,
SERIAL_7E1 = 0x17 | XMC_USIC_CH_PARITY_MODE_EVEN,
SERIAL_8E1 = 0x18 | XMC_USIC_CH_PARITY_MODE_EVEN,
SERIAL_5E2 = 0x25 | XMC_USIC_CH_PARITY_MODE_EVEN,
SERIAL_6E2 = 0x26 | XMC_USIC_CH_PARITY_MODE_EVEN,
SERIAL_7E2 = 0x27 | XMC_USIC_CH_PARITY_MODE_EVEN,
SERIAL_8E2 = 0x28 | XMC_USIC_CH_PARITY_MODE_EVEN,
SERIAL_5O1 = 0x15 | XMC_USIC_CH_PARITY_MODE_ODD,
SERIAL_6O1 = 0x16 | XMC_USIC_CH_PARITY_MODE_ODD,
SERIAL_7O1 = 0x17 | XMC_USIC_CH_PARITY_MODE_ODD,
SERIAL_8O1 = 0x18 | XMC_USIC_CH_PARITY_MODE_ODD,
SERIAL_5O2 = 0x25 | XMC_USIC_CH_PARITY_MODE_ODD,
SERIAL_6O2 = 0x26 | XMC_USIC_CH_PARITY_MODE_ODD,
SERIAL_7O2 = 0x27 | XMC_USIC_CH_PARITY_MODE_ODD,
SERIAL_8O2 = 0x28 | XMC_USIC_CH_PARITY_MODE_ODD
} XMC_UART_MODE_t;

//****************************************************************************
// @Class Definitionsw
//****************************************************************************
class Uart : public HardwareSerial {
public:
XMC_UART_t *_XMC_UART_config;
Uart(XMC_UART_t *xmc_uart_config);
void begin(unsigned long);
void begin(unsigned long baudrate, uint16_t config) override;
void begin(unsigned long, XMC_UART_MODE_t config);
void end();
int available(void);
int availableForWrite(void);
int peek(void);
int read(void);
void flush(void);

size_t write(const uint8_t);
size_t write(const uint8_t *buffer, size_t size);
using Print::write; // pull in write(str) and write(buf, size) from Print

operator bool();

void setInterruptPriority(uint32_t priority);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for these functions to be public?

uint32_t getInterruptPriority();

void IrqHandler(void);

private:
static constexpr size_t BUF_LENGTH = 512;
RingBufferN<BUF_LENGTH> _rx_buffer;
bool serial_ready = false;
};

extern Uart Serial;
extern Uart Serial1;
2 changes: 1 addition & 1 deletion cores/xmc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ int main(void) {
setup();
while (1) {
loop();
//::serialEventRun();
::serialEventRun();
}
}

Expand Down
10 changes: 5 additions & 5 deletions tests/test_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @brief Configuration file for board-specific test pin definitions.
*
* This header file contains the definitions of the pins used for testing
* purposes on the specific board. These pins are configured as output and
* purposes on the specific board. These pins are configured as output and
* input pins for various test scenarios.
*
*/
Expand All @@ -13,7 +13,7 @@
#include <stdint.h>

// Test Pin Definitions
#define TEST_DIGITALIO_OUTPUT 4 // IO_4
#define TEST_DIGITALIO_INPUT 3 // IO_3

#endif // TEST_CONFIG_H
#define TEST_DIGITALIO_OUTPUT 2 // IO_4
#define TEST_DIGITALIO_INPUT 3 // IO_3
#define TEST_PIN_SYNC_IO 4 // IO_1
#endif // TEST_CONFIG_H
8 changes: 1 addition & 7 deletions variants/XMC1100/config/XMC1100_Boot_Kit/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,6 @@ XMC_ADC_t mapping_adc[] = {{VADC, 0, DISABLED}, {VADC, 1, DISABLED}, {VADC, 2, D
{VADC, 5, DISABLED}, {VADC, 6, DISABLED}};
const uint8_t NUM_ANALOG_INPUTS = (sizeof(mapping_adc) / sizeof(XMC_ADC_t));

/*
* UART objects
*/
RingBuffer rx_buffer_0;
RingBuffer tx_buffer_0;

/* First UART channel pins are swapped between debug and normal use */
XMC_UART_t XMC_UART_0 = {.channel = XMC_UART0_CH1,
.rx = {.port = (XMC_GPIO_PORT_t *)PORT1_BASE,
Expand Down Expand Up @@ -254,7 +248,7 @@ XMC_UART_t XMC_UART_0 = {.channel = XMC_UART0_CH1,
.irq_num = USIC0_0_IRQn,
.irq_service_request = 0};

HardwareSerial Serial(&XMC_UART_0, &rx_buffer_0, &tx_buffer_0);
HardwareSerial Serial(&XMC_UART_0);

// SPI instance
XMC_SPI_t XMC_SPI_0 = {
Expand Down
8 changes: 1 addition & 7 deletions variants/XMC1100/config/XMC1100_XMC2GO/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,6 @@ XMC_ADC_t mapping_adc[] = {
{VADC, 1, DISABLED}, {VADC, 2, DISABLED}, {VADC, 3, DISABLED}, {VADC, 4, DISABLED}};
const uint8_t NUM_ANALOG_INPUTS = (sizeof(mapping_adc) / sizeof(XMC_ADC_t));

/*
* UART objects
*/
RingBuffer rx_buffer_0;
RingBuffer tx_buffer_0;

/* First UART channel pins are swapped between debug and normal use */
XMC_UART_t XMC_UART_0 = {.channel = XMC_UART0_CH0,
.rx = {.port = (XMC_GPIO_PORT_t *)PORT2_BASE,
Expand Down Expand Up @@ -206,7 +200,7 @@ XMC_UART_t XMC_UART_0 = {.channel = XMC_UART0_CH0,
.irq_num = USIC0_0_IRQn,
.irq_service_request = 0};

HardwareSerial Serial(&XMC_UART_0, &rx_buffer_0, &tx_buffer_0);
HardwareSerial Serial(&XMC_UART_0);

// SPI instance
XMC_SPI_t XMC_SPI_0 = {
Expand Down
8 changes: 1 addition & 7 deletions variants/XMC1300/config/XMC1300_Boot_Kit/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,6 @@ XMC_ADC_t mapping_adc[] = {{VADC, 6, VADC_G1, 1, 4, DISABLED},
{VADC, 5, VADC_G0, 0, 8, DISABLED}};
const uint8_t NUM_ANALOG_INPUTS = (sizeof(mapping_adc) / sizeof(XMC_ADC_t));

/*
* UART objects
*/
RingBuffer rx_buffer_0;
RingBuffer tx_buffer_0;

/* First UART channel pins are swapped between debug and normal use */
XMC_UART_t XMC_UART_0 = {.channel = XMC_UART0_CH1,
.rx = {.port = (XMC_GPIO_PORT_t *)PORT1_BASE,
Expand Down Expand Up @@ -259,7 +253,7 @@ XMC_UART_t XMC_UART_0 = {.channel = XMC_UART0_CH1,
.irq_num = USIC0_0_IRQn,
.irq_service_request = 0};

HardwareSerial Serial(&XMC_UART_0, &rx_buffer_0, &tx_buffer_0);
HardwareSerial Serial(&XMC_UART_0);

// SPI instance
XMC_SPI_t XMC_SPI_0 = {
Expand Down
8 changes: 1 addition & 7 deletions variants/XMC1400/config/XMC1400_Arduino_Kit/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,6 @@ XMC_ADC_t mapping_adc[] = {

const uint8_t NUM_ANALOG_INPUTS = (sizeof(mapping_adc) / sizeof(XMC_ADC_t));

/*
* UART objects
*/
RingBuffer rx_buffer_0;
RingBuffer tx_buffer_0;

/* First UART channel pins are swapped between debug and normal use */
XMC_UART_t XMC_UART_0 = {.channel = XMC_UART0_CH1,
.rx = {.port = (XMC_GPIO_PORT_t *)PORT1_BASE,
Expand Down Expand Up @@ -258,7 +252,7 @@ XMC_UART_t XMC_UART_0 = {.channel = XMC_UART0_CH1,
.irq_num = USIC0_0_IRQn,
.irq_service_request = 0};

HardwareSerial Serial(&XMC_UART_0, &rx_buffer_0, &tx_buffer_0);
HardwareSerial Serial(&XMC_UART_0);

// SPI instance
XMC_SPI_t XMC_SPI_0 = {
Expand Down
Loading
Loading