Change in ...osmo-ccid-firmware[master]: WIP: Add card_uart driver for ASF4 USART

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Wed Oct 9 13:04:02 UTC 2019


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/15723


Change subject: WIP: Add card_uart driver for ASF4 USART
......................................................................

WIP: Add card_uart driver for ASF4 USART

Change-Id: I9a141e9d2125fbfc992ad51aa4b11a39ee186607
---
M ccid_common/ccid_slot_fsm.c
M ccid_common/cuart.h
A sysmoOCTSIM/cuart_driver_asf4_usart_async.c
3 files changed, 252 insertions(+), 1 deletion(-)



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

diff --git a/ccid_common/ccid_slot_fsm.c b/ccid_common/ccid_slot_fsm.c
index 06c14f1..76279ec 100644
--- a/ccid_common/ccid_slot_fsm.c
+++ b/ccid_common/ccid_slot_fsm.c
@@ -30,12 +30,18 @@
 
 static struct iso_fsm_slot_instance g_si;
 
-struct iso_fsm_slot *ccid_slot2iso_fsm_slot(struct ccid_slot *cs)
+static struct iso_fsm_slot *ccid_slot2iso_fsm_slot(struct ccid_slot *cs)
 {
 	OSMO_ASSERT(cs->slot_nr < ARRAY_SIZE(g_si.slot));
 	return &g_si.slot[cs->slot_nr];
 }
 
+struct card_uart *cuart4slot_nr(uint8_t slot_nr)
+{
+	OSMO_ASSERT(slot_nr < ARRAY_SIZE(g_si.slot));
+	return g_si.slot[slot_nr].cuart;
+}
+
 static const uint8_t sysmousim_sjs1_atr[] = {
 		0x3B, 0x9F, 0x96, 0x80, 0x1F, 0xC7, 0x80, 0x31,
 		0xA0, 0x73, 0xBE, 0x21, 0x13, 0x67, 0x43, 0x20,
diff --git a/ccid_common/cuart.h b/ccid_common/cuart.h
index 790c277..cadd65f 100644
--- a/ccid_common/cuart.h
+++ b/ccid_common/cuart.h
@@ -6,6 +6,8 @@
 #include <osmocom/core/select.h>
 #include "utils_ringbuffer.h"
 
+struct usart_async_descriptor;
+
 enum card_uart_event {
 	/* a single byte was received, it's present at the (uint8_t *) data location */
 	CUART_E_RX_SINGLE,
@@ -83,6 +85,10 @@
 			struct osmo_fd ofd;
 			unsigned int baudrate;
 		} tty;
+		struct {
+			struct usart_async_descriptor *usa_pd;
+			uint8_t slot_nr;
+		} asf4;
 	} u;
 };
 
diff --git a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c
new file mode 100644
index 0000000..299a2df
--- /dev/null
+++ b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c
@@ -0,0 +1,239 @@
+/* Card (ICC) UART driver for the Atmel ASF4 asynchronous USART */
+
+#include <errno.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/utils.h>
+
+#include <hal_usart_async.h>
+#include <utils_ringbuffer.h>
+#include "driver_init.h"
+
+#include "ncn8025.h"
+
+#include "cuart.h"
+
+static struct usart_async_descriptor* SIM_peripheral_descriptors[] = {&SIM0, &SIM1, &SIM2, &SIM3, &SIM4, &SIM5, &SIM6, NULL};
+
+extern struct card_uart *cuart4slot_nr(uint8_t slot_nr);
+
+/***********************************************************************
+ * low-level helper routines
+ ***********************************************************************/
+
+static void _SIM_rx_cb(const struct usart_async_descriptor *const io_descr, uint8_t slot_nr)
+{
+	struct card_uart *cuart = cuart4slot_nr(slot_nr);
+	int rc;
+	OSMO_ASSERT(cuart);
+
+	if (cuart->rx_threshold == 1) {
+		/* bypass ringbuffer and report byte directly */
+		uint8_t rx[1];
+		rc = io_read((struct io_descriptor * const)&io_descr->io, rx, sizeof(rx));
+		OSMO_ASSERT(rc == sizeof(rx));
+		card_uart_notification(cuart, CUART_E_RX_SINGLE, rx);
+	} else {
+		/* go via ringbuffer and notify only after threshold */
+		if (ringbuffer_num(&io_descr->rx) >= cuart->rx_threshold)
+			card_uart_notification(cuart, CUART_E_RX_COMPLETE, NULL);
+	}
+}
+
+static void _SIM_tx_cb(const struct usart_async_descriptor *const io_descr, uint8_t slot_nr)
+{
+	struct card_uart *cuart = cuart4slot_nr(slot_nr);
+	OSMO_ASSERT(cuart);
+	card_uart_notification(cuart, CUART_E_TX_COMPLETE, io_descr->tx_buffer);
+}
+
+
+/* the below ugli-ness is required as the usart_async_descriptor doesn't have
+ * some kind of 'private' member that could provide the call-back anty kind of
+ * context */
+static void SIM0_rx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_rx_cb(io_descr, 0);
+}
+static void SIM1_rx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_rx_cb(io_descr, 1);
+}
+static void SIM2_rx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_rx_cb(io_descr, 2);
+}
+static void SIM3_rx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_rx_cb(io_descr, 3);
+}
+static void SIM4_rx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_rx_cb(io_descr, 4);
+}
+static void SIM5_rx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_rx_cb(io_descr, 5);
+}
+static void SIM6_rx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_rx_cb(io_descr, 6);
+}
+static void SIM7_rx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_rx_cb(io_descr, 7);
+}
+static usart_cb_t SIM_rx_cb[8] = {
+	SIM0_rx_cb, SIM1_rx_cb, SIM2_rx_cb, SIM3_rx_cb,
+	SIM4_rx_cb, SIM5_rx_cb, SIM6_rx_cb, SIM7_rx_cb,
+};
+static void SIM0_tx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_tx_cb(io_descr, 0);
+}
+static void SIM1_tx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_tx_cb(io_descr, 1);
+}
+static void SIM2_tx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_tx_cb(io_descr, 2);
+}
+static void SIM3_tx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_tx_cb(io_descr, 3);
+}
+static void SIM4_tx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_tx_cb(io_descr, 4);
+}
+static void SIM5_tx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_tx_cb(io_descr, 5);
+}
+static void SIM6_tx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_tx_cb(io_descr, 6);
+}
+static void SIM7_tx_cb(const struct usart_async_descriptor *const io_descr)
+{
+	_SIM_tx_cb(io_descr, 7);
+}
+static usart_cb_t SIM_tx_cb[8] = {
+	SIM0_tx_cb, SIM1_tx_cb, SIM2_tx_cb, SIM3_tx_cb,
+	SIM4_tx_cb, SIM5_tx_cb, SIM6_tx_cb, SIM7_tx_cb,
+};
+
+/***********************************************************************
+ * Interface with card_uart (cuart) core
+ ***********************************************************************/
+
+/* forward-declaration */
+static struct card_uart_driver asf4_usart_driver;
+static int asf4_usart_close(struct card_uart *cuart);
+
+static int asf4_usart_open(struct card_uart *cuart, const char *device_name)
+{
+	struct usart_async_descriptor *usa_pd;
+	int slot_nr = atoi(device_name);
+
+	if (slot_nr >= ARRAY_SIZE(SIM_peripheral_descriptors))
+		return -ENODEV;
+	usa_pd = SIM_peripheral_descriptors[slot_nr];
+	if (!usa_pd)
+		return -ENODEV;
+
+	cuart->u.asf4.usa_pd = usa_pd;
+	cuart->u.asf4.slot_nr = slot_nr;
+
+	usart_async_register_callback(usa_pd, USART_ASYNC_RXC_CB, SIM_rx_cb[slot_nr]);
+	usart_async_register_callback(usa_pd, USART_ASYNC_TXC_CB, SIM_tx_cb[slot_nr]);
+	usart_async_enable(usa_pd);
+
+        return 0;
+}
+
+static int asf4_usart_close(struct card_uart *cuart)
+{
+	struct usart_async_descriptor *usa_pd = cuart->u.asf4.usa_pd;
+
+	OSMO_ASSERT(cuart->driver == &asf4_usart_driver);
+
+	usart_async_disable(usa_pd);
+
+	return 0;
+}
+
+static int asf4_usart_async_tx(struct card_uart *cuart, const uint8_t *data, size_t len, bool rx_after)
+{
+	struct usart_async_descriptor *usa_pd = cuart->u.asf4.usa_pd;
+	int rc;
+
+	OSMO_ASSERT(cuart->driver == &asf4_usart_driver);
+	OSMO_ASSERT(usart_async_is_tx_empty(usa_pd));
+
+	rc = io_write(&usa_pd->io, data, len);
+	if (rc < 0)
+		return rc;
+
+	cuart->tx_busy = true;
+
+	return rc;
+}
+
+static int asf4_usart_async_rx(struct card_uart *cuart, uint8_t *data, size_t len)
+{
+	struct usart_async_descriptor *usa_pd = cuart->u.asf4.usa_pd;
+
+	OSMO_ASSERT(cuart->driver == &asf4_usart_driver);
+
+	return io_read(&usa_pd->io, data, len);
+}
+
+static int asf4_usart_ctrl(struct card_uart *cuart, enum card_uart_ctl ctl, bool enable)
+{
+	struct ncn8025_settings settings;
+	Sercom *sercom = cuart->u.asf4.usa_pd->device.hw;
+
+	switch (ctl) {
+	case CUART_CTL_RX:
+		if (enable)
+			sercom->USART.CTRLB.bit.RXEN = 1;
+		else
+			sercom->USART.CTRLB.bit.RXEN = 0;
+		break;
+	case CUART_CTL_RST:
+		ncn8025_get(cuart->u.asf4.slot_nr, &settings);
+		settings.rstin = enable;
+		ncn8025_set(cuart->u.asf4.slot_nr, &settings);
+		break;
+	case CUART_CTL_POWER:
+		ncn8025_get(cuart->u.asf4.slot_nr, &settings);
+		settings.cmdvcc = enable;
+		ncn8025_set(cuart->u.asf4.slot_nr, &settings);
+		break;
+	case CUART_CTL_CLOCK:
+		/* FIXME */
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static const struct card_uart_ops asf4_usart_ops = {
+	.open = asf4_usart_open,
+	.close = asf4_usart_close,
+	.async_tx = asf4_usart_async_tx,
+	.async_rx = asf4_usart_async_rx,
+	.ctrl = asf4_usart_ctrl,
+};
+
+static struct card_uart_driver asf4_usart_driver = {
+	.name = "asf4",
+	.ops = &asf4_usart_ops,
+};
+
+static __attribute__((constructor)) void on_dso_load_cuart_asf4(void)
+{
+	card_uart_driver_register(&asf4_usart_driver);
+}

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/15723
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-Change-Id: I9a141e9d2125fbfc992ad51aa4b11a39ee186607
Gerrit-Change-Number: 15723
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191009/1f940362/attachment.htm>


More information about the gerrit-log mailing list