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.orglaforge 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>