Change in osmo-ccid-firmware[master]: switch UART_debug to ASYNC

Kévin Redon gerrit-no-reply at lists.osmocom.org
Tue Apr 16 23:29:20 UTC 2019


Kévin Redon has uploaded this change for review. ( https://gerrit.osmocom.org/13673


Change subject: switch UART_debug to ASYNC
......................................................................

switch UART_debug to ASYNC

using the synchronous HAL library causes RX overflow after 5 bytes
on bulk incoming data (e.g. pasted).
this mainly due to printing synchronously the character, but to
further prevent congestion we switch to asynchronous (e.g.
interrupt driven) communication.

The RX part works great now (no overflow), but the TX part is
malfunctioning because the HAL Async library does not buffer the
data to be transmitted and expects it to be in memory until
the transmission is complete (which printf does not do).

This change will not be reflected in Atmel START since it does not
allow to set the underlying STDIO redirect peripheral to async.

Change-Id: If18883e96f336aa9f6b11607859260da5e1503c7
---
M sysmoOCTSIM/command.c
M sysmoOCTSIM/driver_init.c
M sysmoOCTSIM/driver_init.h
M sysmoOCTSIM/examples/driver_examples.c
M sysmoOCTSIM/hpl/sercom/hpl_sercom.c
M sysmoOCTSIM/main.c
M sysmoOCTSIM/stdio_start.c
7 files changed, 94 insertions(+), 28 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware refs/changes/73/13673/1

diff --git a/sysmoOCTSIM/command.c b/sysmoOCTSIM/command.c
index 9502f05..7ac5662 100644
--- a/sysmoOCTSIM/command.c
+++ b/sysmoOCTSIM/command.c
@@ -76,7 +76,8 @@
 	unsigned int i = 0;
 
 	/* yield CPU after maximum of 10 received characters */
-	while (usart_sync_is_rx_not_empty(&UART_debug) && (i < 10)) {
+	while (usart_async_is_rx_not_empty(&UART_debug) && (i < 10)) {
+		gpio_toggle_pin_level(USER_LED); // toggle LED to show we received something
 		int c = getchar();
 		if (c < 0)
 			return;
diff --git a/sysmoOCTSIM/driver_init.c b/sysmoOCTSIM/driver_init.c
index 06184ee..0d5bb53 100644
--- a/sysmoOCTSIM/driver_init.c
+++ b/sysmoOCTSIM/driver_init.c
@@ -32,6 +32,9 @@
 /*! The buffer size for USART */
 #define SIM6_BUFFER_SIZE 16
 
+/*! The buffer size for USART */
+#define UART_DEBUG_BUFFER_SIZE 32
+
 struct usart_async_descriptor SIM0;
 struct usart_async_descriptor SIM1;
 struct usart_async_descriptor SIM2;
@@ -48,7 +51,9 @@
 static uint8_t SIM5_buffer[SIM5_BUFFER_SIZE];
 static uint8_t SIM6_buffer[SIM6_BUFFER_SIZE];
 
-struct usart_sync_descriptor UART_debug;
+struct usart_async_descriptor UART_debug;
+
+static uint8_t UART_DEBUG_buffer[UART_DEBUG_BUFFER_SIZE];
 
 /**
  * \brief USART Clock initialization function
@@ -309,7 +314,26 @@
 	SIM6_PORT_init();
 }
 
-void UART_debug_PORT_init(void)
+/**
+ * \brief USART Clock initialization function
+ *
+ * Enables register interface and peripheral clock
+ */
+void UART_debug_CLOCK_init()
+{
+
+	hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM7_GCLK_ID_CORE, CONF_GCLK_SERCOM7_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
+	hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM7_GCLK_ID_SLOW, CONF_GCLK_SERCOM7_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
+
+	hri_mclk_set_APBDMASK_SERCOM7_bit(MCLK);
+}
+
+/**
+ * \brief USART pinmux initialization function
+ *
+ * Set each required pin to USART functionality
+ */
+void UART_debug_PORT_init()
 {
 
 	gpio_set_pin_function(UART_TX, PINMUX_PB30C_SERCOM7_PAD0);
@@ -317,18 +341,15 @@
 	gpio_set_pin_function(UART_RX, PINMUX_PB31C_SERCOM7_PAD1);
 }
 
-void UART_debug_CLOCK_init(void)
-{
-	hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM7_GCLK_ID_CORE, CONF_GCLK_SERCOM7_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
-	hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM7_GCLK_ID_SLOW, CONF_GCLK_SERCOM7_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
-
-	hri_mclk_set_APBDMASK_SERCOM7_bit(MCLK);
-}
-
+/**
+ * \brief USART initialization function
+ *
+ * Enables USART peripheral, clocks and initializes USART driver
+ */
 void UART_debug_init(void)
 {
 	UART_debug_CLOCK_init();
-	usart_sync_init(&UART_debug, SERCOM7, (void *)NULL);
+	usart_async_init(&UART_debug, SERCOM7, UART_DEBUG_buffer, UART_DEBUG_BUFFER_SIZE, (void *)NULL);
 	UART_debug_PORT_init();
 }
 
diff --git a/sysmoOCTSIM/driver_init.h b/sysmoOCTSIM/driver_init.h
index d809db8..9d009b9 100644
--- a/sysmoOCTSIM/driver_init.h
+++ b/sysmoOCTSIM/driver_init.h
@@ -40,8 +40,7 @@
 extern struct usart_async_descriptor SIM4;
 extern struct usart_async_descriptor SIM5;
 extern struct usart_async_descriptor SIM6;
-
-extern struct usart_sync_descriptor UART_debug;
+extern struct usart_async_descriptor UART_debug;
 
 void SIM0_PORT_init(void);
 void SIM0_CLOCK_init(void);
diff --git a/sysmoOCTSIM/examples/driver_examples.c b/sysmoOCTSIM/examples/driver_examples.c
index 4ab0ef4..14f1ae5 100644
--- a/sysmoOCTSIM/examples/driver_examples.c
+++ b/sysmoOCTSIM/examples/driver_examples.c
@@ -215,12 +215,29 @@
 
 /**
  * Example of using UART_debug to write "Hello World" using the IO abstraction.
+ *
+ * Since the driver is asynchronous we need to use statically allocated memory for string
+ * because driver initiates transfer and then returns before the transmission is completed.
+ *
+ * Once transfer has been completed the tx_cb function will be called.
  */
+
+static uint8_t example_UART_debug[12] = "Hello World!";
+
+static void tx_cb_UART_debug(const struct usart_async_descriptor *const io_descr)
+{
+	/* Transfer completed */
+}
+
 void UART_debug_example(void)
 {
 	struct io_descriptor *io;
-	usart_sync_get_io_descriptor(&UART_debug, &io);
-	usart_sync_enable(&UART_debug);
 
-	io_write(io, (uint8_t *)"Hello World!", 12);
+	usart_async_register_callback(&UART_debug, USART_ASYNC_TXC_CB, tx_cb_UART_debug);
+	/*usart_async_register_callback(&UART_debug, USART_ASYNC_RXC_CB, rx_cb);
+	usart_async_register_callback(&UART_debug, USART_ASYNC_ERROR_CB, err_cb);*/
+	usart_async_get_io_descriptor(&UART_debug, &io);
+	usart_async_enable(&UART_debug);
+
+	io_write(io, example_UART_debug, 12);
 }
diff --git a/sysmoOCTSIM/hpl/sercom/hpl_sercom.c b/sysmoOCTSIM/hpl/sercom/hpl_sercom.c
index b14e720..f235115 100644
--- a/sysmoOCTSIM/hpl/sercom/hpl_sercom.c
+++ b/sysmoOCTSIM/hpl/sercom/hpl_sercom.c
@@ -177,6 +177,8 @@
 
 static struct _usart_async_device *_sercom6_dev = NULL;
 
+static struct _usart_async_device *_sercom7_dev = NULL;
+
 static uint8_t _get_sercom_index(const void *const hw);
 static uint8_t _sercom_get_irq_num(const void *const hw);
 static void    _sercom_init_irq_param(const void *const hw, void *dev);
@@ -665,6 +667,10 @@
 	if (hw == SERCOM6) {
 		_sercom6_dev = (struct _usart_async_device *)dev;
 	}
+
+	if (hw == SERCOM7) {
+		_sercom7_dev = (struct _usart_async_device *)dev;
+	}
 }
 
 /**
@@ -2628,6 +2634,35 @@
 	_sercom_usart_interrupt_handler(_sercom6_dev);
 }
 
+/**
+ * \internal Sercom interrupt handler
+ */
+void SERCOM7_0_Handler(void)
+{
+	_sercom_usart_interrupt_handler(_sercom7_dev);
+}
+/**
+ * \internal Sercom interrupt handler
+ */
+void SERCOM7_1_Handler(void)
+{
+	_sercom_usart_interrupt_handler(_sercom7_dev);
+}
+/**
+ * \internal Sercom interrupt handler
+ */
+void SERCOM7_2_Handler(void)
+{
+	_sercom_usart_interrupt_handler(_sercom7_dev);
+}
+/**
+ * \internal Sercom interrupt handler
+ */
+void SERCOM7_3_Handler(void)
+{
+	_sercom_usart_interrupt_handler(_sercom7_dev);
+}
+
 int32_t _spi_m_sync_init(struct _spi_m_sync_dev *dev, void *const hw)
 {
 	const struct sercomspi_regs_cfg *regs = _spi_get_regs((uint32_t)hw);
diff --git a/sysmoOCTSIM/main.c b/sysmoOCTSIM/main.c
index dc67406..afd7bf2 100644
--- a/sysmoOCTSIM/main.c
+++ b/sysmoOCTSIM/main.c
@@ -210,19 +210,14 @@
 	ncn8025_set(slotnr, &settings);
 }
 
-
-
-
-
 int main(void)
 {
 	atmel_start_init();
 
-	usart_sync_enable(&UART_debug);
-
 	usb_start();
 
 	board_init();
+
 	command_init("sysmoOCTSIM> ");
 	command_register(&cmd_hello);
 	command_register(&cmd_sim_status);
diff --git a/sysmoOCTSIM/stdio_start.c b/sysmoOCTSIM/stdio_start.c
index 7450a08..e2fb0c2 100644
--- a/sysmoOCTSIM/stdio_start.c
+++ b/sysmoOCTSIM/stdio_start.c
@@ -9,15 +9,13 @@
 #include "atmel_start.h"
 #include "stdio_start.h"
 
-void STDIO_REDIRECT_0_example(void)
+static void UART_debug_rx_cb(const struct usart_async_descriptor *const io_descr)
 {
-	/* Print welcome message */
-	printf("\r\nHello ATMEL World!\r\n");
 }
 
 void stdio_redirect_init(void)
 {
-
-	usart_sync_enable(&UART_debug);
+	usart_async_register_callback(&UART_debug, USART_ASYNC_RXC_CB, UART_debug_rx_cb); // if no callback function is registered receive won't work, even if the callback does nothing
+	usart_async_enable(&UART_debug);
 	stdio_io_init(&UART_debug.io);
 }

-- 
To view, visit https://gerrit.osmocom.org/13673
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: If18883e96f336aa9f6b11607859260da5e1503c7
Gerrit-Change-Number: 13673
Gerrit-PatchSet: 1
Gerrit-Owner: Kévin Redon <kredon at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190416/532c0611/attachment.html>


More information about the gerrit-log mailing list