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/.
Kévin Redon gerrit-no-reply at lists.osmocom.orgKévin Redon has uploaded this change for review. ( https://gerrit.osmocom.org/12803 Change subject: add SERCOM HAL Async library ...................................................................... add SERCOM HAL Async library Change-Id: I530a5bc5ee7e89149eb251bda0adf7963733d2ee --- M sysmoOCTSIM/AtmelStart.gpdsc M sysmoOCTSIM/atmel_start_config.atstart M sysmoOCTSIM/driver_init.c M sysmoOCTSIM/driver_init.h M sysmoOCTSIM/examples/driver_examples.c M sysmoOCTSIM/gcc/Makefile A sysmoOCTSIM/hal/documentation/usart_async.rst A sysmoOCTSIM/hal/include/hal_usart_async.h A sysmoOCTSIM/hal/src/hal_usart_async.c A sysmoOCTSIM/hal/utils/include/utils_ringbuffer.h A sysmoOCTSIM/hal/utils/src/utils_ringbuffer.c M sysmoOCTSIM/hpl/sercom/hpl_sercom.c 12 files changed, 1,207 insertions(+), 30 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware refs/changes/03/12803/1 diff --git a/sysmoOCTSIM/AtmelStart.gpdsc b/sysmoOCTSIM/AtmelStart.gpdsc index 44b5c62..ebb4d1e 100644 --- a/sysmoOCTSIM/AtmelStart.gpdsc +++ b/sysmoOCTSIM/AtmelStart.gpdsc @@ -42,7 +42,7 @@ <description>Atmel Start Framework</description> <RTE_Components_h>#define ATMEL_START</RTE_Components_h> <files> - <file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/usart_sync.rst"/> + <file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/usart_async.rst"/> <file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/usb_device_async.rst"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_atomic.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_cache.h"/> @@ -94,9 +94,11 @@ <file category="header" condition="ARMCC, GCC, IAR" name="hal/utils/include/utils_increment_macro.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/utils/include/utils_list.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/utils/include/utils_repeat_macro.h"/> + <file category="header" condition="ARMCC, GCC, IAR" name="hal/utils/include/utils_ringbuffer.h"/> <file category="source" condition="ARMCC, GCC, IAR" name="hal/utils/src/utils_assert.c"/> <file category="source" condition="ARMCC, GCC, IAR" name="hal/utils/src/utils_event.c"/> <file category="source" condition="ARMCC, GCC, IAR" name="hal/utils/src/utils_list.c"/> + <file category="source" condition="ARMCC, GCC, IAR" name="hal/utils/src/utils_ringbuffer.c"/> <file category="source" condition="GCC" name="hal/utils/src/utils_syscalls.c"/> <file category="header" condition="ARMCC, GCC, IAR" name="hri/hri_ac_e54.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="hri/hri_adc_e54.h"/> @@ -165,12 +167,12 @@ <file category="header" condition="ARMCC, GCC, IAR" name="atmel_start_pins.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="examples/driver_examples.h"/> <file category="source" condition="ARMCC, GCC, IAR" name="examples/driver_examples.c"/> - <file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_usart_sync.h"/> + <file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_usart_async.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_missing_features.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_reset.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_usart_async.h"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_usart_sync.h"/> - <file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_usart_sync.c"/> + <file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_usart_async.c"/> <file category="header" condition="ARMCC, GCC, IAR" name="hal/utils/include/parts.h"/> <file category="source" condition="ARMCC, GCC, IAR" name="hpl/cmcc/hpl_cmcc.c"/> <file category="source" condition="ARMCC, GCC, IAR" name="hpl/core/hpl_core_m4.c"/> diff --git a/sysmoOCTSIM/atmel_start_config.atstart b/sysmoOCTSIM/atmel_start_config.atstart index cb7826a..af87e97 100644 --- a/sysmoOCTSIM/atmel_start_config.atstart +++ b/sysmoOCTSIM/atmel_start_config.atstart @@ -959,9 +959,9 @@ domain_group: null UART_debug: user_label: UART_debug - definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::SERCOM2::driver_config_definition::UART::HAL:Driver:USART.Sync + definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::SERCOM2::driver_config_definition::UART::HAL:Driver:USART.Async functionality: USART - api: HAL:Driver:USART_Sync + api: HAL:Driver:USART_Async configuration: usart_advanced: false usart_arch_clock_mode: USART with internal clock diff --git a/sysmoOCTSIM/driver_init.c b/sysmoOCTSIM/driver_init.c index 72f2c88..efd24bc 100644 --- a/sysmoOCTSIM/driver_init.c +++ b/sysmoOCTSIM/driver_init.c @@ -11,9 +11,33 @@ #include <utils.h> #include <hal_init.h> -struct usart_sync_descriptor UART_debug; +/*! The buffer size for USART */ +#define UART_DEBUG_BUFFER_SIZE 16 -void UART_debug_PORT_init(void) +struct usart_async_descriptor UART_debug; + +static uint8_t UART_debug_buffer[UART_DEBUG_BUFFER_SIZE]; + +/** + * \brief USART Clock initialization function + * + * Enables register interface and peripheral clock + */ +void UART_debug_CLOCK_init() +{ + + hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM2_GCLK_ID_CORE, CONF_GCLK_SERCOM2_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); + hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM2_GCLK_ID_SLOW, CONF_GCLK_SERCOM2_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); + + hri_mclk_set_APBBMASK_SERCOM2_bit(MCLK); +} + +/** + * \brief USART pinmux initialization function + * + * Set each required pin to USART functionality + */ +void UART_debug_PORT_init() { gpio_set_pin_function(PB25, PINMUX_PB25D_SERCOM2_PAD0); @@ -21,18 +45,15 @@ gpio_set_pin_function(PB24, PINMUX_PB24D_SERCOM2_PAD1); } -void UART_debug_CLOCK_init(void) -{ - hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM2_GCLK_ID_CORE, CONF_GCLK_SERCOM2_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); - hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM2_GCLK_ID_SLOW, CONF_GCLK_SERCOM2_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); - - hri_mclk_set_APBBMASK_SERCOM2_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, SERCOM2, (void *)NULL); + usart_async_init(&UART_debug, SERCOM2, 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 7067684..25e6370 100644 --- a/sysmoOCTSIM/driver_init.h +++ b/sysmoOCTSIM/driver_init.h @@ -21,11 +21,11 @@ #include <hal_io.h> #include <hal_sleep.h> -#include <hal_usart_sync.h> +#include <hal_usart_async.h> #include "hal_usb_device.h" -extern struct usart_sync_descriptor UART_debug; +extern struct usart_async_descriptor UART_debug; void UART_debug_PORT_init(void); void UART_debug_CLOCK_init(void); diff --git a/sysmoOCTSIM/examples/driver_examples.c b/sysmoOCTSIM/examples/driver_examples.c index 56247ff..8384c87 100644 --- a/sysmoOCTSIM/examples/driver_examples.c +++ b/sysmoOCTSIM/examples/driver_examples.c @@ -12,12 +12,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/gcc/Makefile b/sysmoOCTSIM/gcc/Makefile index 57ec70c..ff11dd9 100644 --- a/sysmoOCTSIM/gcc/Makefile +++ b/sysmoOCTSIM/gcc/Makefile @@ -52,7 +52,7 @@ hpl/core/hpl_core_m4.o \ usb/class/cdc/device/cdcdf_acm.o \ hal/utils/src/utils_syscalls.o \ -hpl/dmac/hpl_dmac.o \ +usb_start.o \ gcc/system_same54.o \ hpl/usb/hpl_usb.o \ hal/src/hal_delay.o \ @@ -61,9 +61,8 @@ hpl/gclk/hpl_gclk.o \ hal/utils/src/utils_list.o \ hal/utils/src/utils_assert.o \ -usb_start.o \ +hpl/dmac/hpl_dmac.o \ hpl/oscctrl/hpl_oscctrl.o \ -hal/src/hal_usart_sync.o \ hpl/mclk/hpl_mclk.o \ hpl/ramecc/hpl_ramecc.o \ usb/usb_protocol.o \ @@ -73,7 +72,9 @@ hpl/osc32kctrl/hpl_osc32kctrl.o \ examples/driver_examples.o \ driver_init.o \ +hal/src/hal_usart_async.o \ hpl/sercom/hpl_sercom.o \ +hal/utils/src/utils_ringbuffer.o \ hal/src/hal_gpio.o \ hal/utils/src/utils_event.o \ hal/src/hal_sleep.o \ @@ -89,7 +90,7 @@ "hpl/core/hpl_core_m4.o" \ "usb/class/cdc/device/cdcdf_acm.o" \ "hal/utils/src/utils_syscalls.o" \ -"hpl/dmac/hpl_dmac.o" \ +"usb_start.o" \ "gcc/system_same54.o" \ "hpl/usb/hpl_usb.o" \ "hal/src/hal_delay.o" \ @@ -98,9 +99,8 @@ "hpl/gclk/hpl_gclk.o" \ "hal/utils/src/utils_list.o" \ "hal/utils/src/utils_assert.o" \ -"usb_start.o" \ +"hpl/dmac/hpl_dmac.o" \ "hpl/oscctrl/hpl_oscctrl.o" \ -"hal/src/hal_usart_sync.o" \ "hpl/mclk/hpl_mclk.o" \ "hpl/ramecc/hpl_ramecc.o" \ "usb/usb_protocol.o" \ @@ -110,7 +110,9 @@ "hpl/osc32kctrl/hpl_osc32kctrl.o" \ "examples/driver_examples.o" \ "driver_init.o" \ +"hal/src/hal_usart_async.o" \ "hpl/sercom/hpl_sercom.o" \ +"hal/utils/src/utils_ringbuffer.o" \ "hal/src/hal_gpio.o" \ "hal/utils/src/utils_event.o" \ "hal/src/hal_sleep.o" \ @@ -135,7 +137,7 @@ "hpl/usb/hpl_usb.d" \ "hal/utils/src/utils_list.d" \ "hpl/cmcc/hpl_cmcc.d" \ -"usb_start.d" \ +"hpl/dmac/hpl_dmac.d" \ "hal/utils/src/utils_assert.d" \ "hal/src/hal_delay.d" \ "hpl/core/hpl_init.d" \ @@ -143,16 +145,17 @@ "usb/usb_protocol.d" \ "hpl/gclk/hpl_gclk.d" \ "hal/src/hal_usb_device.d" \ -"hpl/dmac/hpl_dmac.d" \ +"usb_start.d" \ "hal/src/hal_init.d" \ -"hal/src/hal_usart_sync.d" \ "main.d" \ "hpl/mclk/hpl_mclk.d" \ "driver_init.d" \ +"hal/src/hal_usart_async.d" \ "hpl/osc32kctrl/hpl_osc32kctrl.d" \ "examples/driver_examples.d" \ "hal/src/hal_cache.d" \ "hal/src/hal_sleep.d" \ +"hal/utils/src/utils_ringbuffer.d" \ "hpl/sercom/hpl_sercom.d" \ "hal/src/hal_gpio.d" \ "hal/src/hal_atomic.d" \ diff --git a/sysmoOCTSIM/hal/documentation/usart_async.rst b/sysmoOCTSIM/hal/documentation/usart_async.rst new file mode 100644 index 0000000..6bf4a23 --- /dev/null +++ b/sysmoOCTSIM/hal/documentation/usart_async.rst @@ -0,0 +1,72 @@ +The USART Asynchronous Driver +============================= + +The universal synchronous and asynchronous receiver and transmitter +(USART) is usually used to transfer data from one device to the other. + +The USART driver use a ring buffer to store received data. When the USART +raise the data received interrupt, this data will be stored in the ring buffer +at the next free location. When the ring buffer is full, the next reception +will overwrite the oldest data stored in the ring buffer. There is one +USART_BUFFER_SIZE macro per used hardware instance, e.g. for SERCOM0 the macro +is called SERCOM0_USART_BUFFER_SIZE. + +On the other hand, when sending data over USART, the data is not copied to an +internal buffer, but the data buffer supplied by the user is used. The callback +will only be generated at the end of the buffer and not for each byte. + +User can set action for flow control pins by function usart_set_flow_control, +if the flow control is enabled. All the available states are defined in union +usart_flow_control_state. + +Note that user can set state of flow control pins only if automatic support of +the flow control is not supported by the hardware. + +Features +-------- + +* Initialization/de-initialization +* Enabling/disabling +* Control of the following settings: + + * Baudrate + * UART or USRT communication mode + * Character size + * Data order + * Flow control +* Data transfer: transmission, reception +* Notifications about transfer done or error case via callbacks +* Status information with busy state and transfer count + +Applications +------------ + +They are commonly used in a terminal application or low-speed communication +between devices. + +Dependencies +------------ + +USART capable hardware, with interrupt on each character is sent or +received. + +Concurrency +----------- + +Write buffer should not be changed while data is being sent. + + +Limitations +----------- + +* The driver does not support 9-bit character size. +* The "USART with ISO7816" mode can be only used in ISO7816 capable devices. + And the SCK pin can't be set directly. Application can use a GCLK output PIN + to generate SCK. For example to communicate with a SMARTCARD with ISO7816 + (F = 372 ; D = 1), and baudrate=9600, the SCK pin output frequency should be + config as 372*9600=3571200Hz. More information can be refer to ISO7816 Specification. + +Known issues and workarounds +---------------------------- + +N/A diff --git a/sysmoOCTSIM/hal/include/hal_usart_async.h b/sysmoOCTSIM/hal/include/hal_usart_async.h new file mode 100644 index 0000000..3a6de39 --- /dev/null +++ b/sysmoOCTSIM/hal/include/hal_usart_async.h @@ -0,0 +1,339 @@ +/** + * \file + * + * \brief USART related functionality declaration. + * + * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ + +#ifndef _HAL_USART_ASYNC_H_INCLUDED +#define _HAL_USART_ASYNC_H_INCLUDED + +#include "hal_io.h" +#include <hpl_usart_async.h> +#include <utils_ringbuffer.h> + +/** + * \addtogroup doc_driver_hal_usart_async + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief USART descriptor + * + * The USART descriptor forward declaration. + */ +struct usart_async_descriptor; + +/** + * \brief USART callback type + */ +typedef void (*usart_cb_t)(const struct usart_async_descriptor *const descr); + +/** + * \brief USART callback types + */ +enum usart_async_callback_type { USART_ASYNC_RXC_CB, USART_ASYNC_TXC_CB, USART_ASYNC_ERROR_CB }; + +/** + * \brief USART callbacks + */ +struct usart_async_callbacks { + usart_cb_t tx_done; + usart_cb_t rx_done; + usart_cb_t error; +}; + +/** \brief USART status + * Status descriptor holds the current status of transfer. + */ +struct usart_async_status { + /** Status flags */ + uint32_t flags; + /** Number of characters transmitted */ + uint16_t txcnt; + /** Number of characters receviced */ + uint16_t rxcnt; +}; + +/** + * \brief Asynchronous USART descriptor structure + */ +struct usart_async_descriptor { + struct io_descriptor io; + struct _usart_async_device device; + struct usart_async_callbacks usart_cb; + uint32_t stat; + + struct ringbuffer rx; + uint16_t tx_por; + uint8_t * tx_buffer; + uint16_t tx_buffer_length; +}; + +/** USART write busy */ +#define USART_ASYNC_STATUS_BUSY 0x0001 + +/** + * \brief Initialize USART interface + * + * This function initializes the given I/O descriptor to be used as USART + * interface descriptor. + * It checks if the given hardware is not initialized and if the given hardware + * is permitted to be initialized. + * + * \param[out] descr A USART descriptor which is used to communicate via the USART + * \param[in] hw The pointer to the hardware instance + * \param[in] rx_buffer An RX buffer + * \param[in] rx_buffer_length The length of the buffer above + * \param[in] func The pointer to a set of function pointers + * + * \return Initialization status. + * \retval -1 Passed parameters were invalid or the interface is already + * initialized + * \retval 0 The initialization is completed successfully + */ +int32_t usart_async_init(struct usart_async_descriptor *const descr, void *const hw, uint8_t *const rx_buffer, + const uint16_t rx_buffer_length, void *const func); + +/** + * \brief Deinitialize USART interface + * + * This function deinitializes the given I/O descriptor. + * It checks if the given hardware is initialized and if the given hardware + * is permitted to be deinitialized. + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * + * \return De-initialization status. + */ +int32_t usart_async_deinit(struct usart_async_descriptor *const descr); + +/** + * \brief Enable USART interface + * + * Enables the USART interface + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * + * \return Enabling status. + */ +int32_t usart_async_enable(struct usart_async_descriptor *const descr); + +/** + * \brief Disable USART interface + * + * Disables the USART interface + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * + * \return Disabling status. + */ +int32_t usart_async_disable(struct usart_async_descriptor *const descr); + +/** + * \brief Retrieve I/O descriptor + * + * This function retrieves the I/O descriptor of the given USART descriptor. + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[out] io An I/O descriptor to retrieve + * + * \return The status of I/O descriptor retrieving. + */ +int32_t usart_async_get_io_descriptor(struct usart_async_descriptor *const descr, struct io_descriptor **io); + +/** + * \brief Register USART callback + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[in] type Callback type + * \param[in] cb A callback function + * + * \return The status of callback assignment. + * \retval -1 Passed parameters were invalid or the interface is not initialized + * \retval 0 A callback is registered successfully + */ +int32_t usart_async_register_callback(struct usart_async_descriptor *const descr, + const enum usart_async_callback_type type, usart_cb_t cb); + +/** + * \brief Specify action for flow control pins + * + * This function sets action (or state) for flow control pins if + * the flow control is enabled. + * It sets state of flow control pins only if automatic support of + * the flow control is not supported by the hardware. + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[in] state A state to set the flow control pins + * + * \return The status of flow control action setup. + */ +int32_t usart_async_set_flow_control(struct usart_async_descriptor *const descr, + const union usart_flow_control_state state); + +/** + * \brief Set USART baud rate + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[in] baud_rate A baud rate to set + * + * \return The status of baud rate setting. + */ +int32_t usart_async_set_baud_rate(struct usart_async_descriptor *const descr, const uint32_t baud_rate); + +/** + * \brief Set USART data order + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[in] data_order A data order to set + * + * \return The status of data order setting. + */ +int32_t usart_async_set_data_order(struct usart_async_descriptor *const descr, const enum usart_data_order data_order); + +/** + * \brief Set USART mode + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[in] mode A mode to set + * + * \return The status of mode setting. + */ +int32_t usart_async_set_mode(struct usart_async_descriptor *const descr, const enum usart_mode mode); + +/** + * \brief Set USART parity + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[in] parity A parity to set + * + * \return The status of parity setting. + */ +int32_t usart_async_set_parity(struct usart_async_descriptor *const descr, const enum usart_parity parity); + +/** + * \brief Set USART stop bits + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[in] stop_bits Stop bits to set + * + * \return The status of stop bits setting. + */ +int32_t usart_async_set_stopbits(struct usart_async_descriptor *const descr, const enum usart_stop_bits stop_bits); + +/** + * \brief Set USART character size + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[in] size A character size to set + * + * \return The status of character size setting. + */ +int32_t usart_async_set_character_size(struct usart_async_descriptor *const descr, + const enum usart_character_size size); + +/** + * \brief Retrieve the state of flow control pins + * + * This function retrieves the flow control pins + * if the flow control is enabled. + * + * The function can return USART_FLOW_CONTROL_STATE_UNAVAILABLE in case + * if the flow control is done by the hardware + * and the pins state cannot be read out. + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[out] state The state of flow control pins + * + * \return The status of flow control state reading. + */ +int32_t usart_async_flow_control_status(const struct usart_async_descriptor *const descr, + union usart_flow_control_state *const state); + +/** + * \brief Check if the USART transmitter is empty + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * + * \return The status of USART TX empty checking. + * \retval 0 The USART transmitter is not empty + * \retval 1 The USART transmitter is empty + */ +int32_t usart_async_is_tx_empty(const struct usart_async_descriptor *const descr); + +/** + * \brief Check if the USART receiver is not empty + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * + * \return The status of the USART RX empty checking. + * \retval 1 The USART receiver is not empty + * \retval 0 The USART receiver is empty + */ +int32_t usart_async_is_rx_not_empty(const struct usart_async_descriptor *const descr); + +/** + * \brief Retrieve the current interface status + * + * \param[in] descr A USART descriptor which is used to communicate via USART + * \param[out] status The state of USART + * + * \return The status of USART status retrieving. + */ +int32_t usart_async_get_status(struct usart_async_descriptor *const descr, struct usart_async_status *const status); + +/** + * \brief flush USART ringbuf + * + * This function flush USART RX ringbuf. + * + * \param[in] descr The pointer to USART descriptor + * + * \return ERR_NONE + */ +int32_t usart_async_flush_rx_buffer(struct usart_async_descriptor *const descr); + +/** + * \brief Retrieve the current driver version + * + * \return Current driver version. + */ +uint32_t usart_async_get_version(void); + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HAL_USART_ASYNC_H_INCLUDED */ diff --git a/sysmoOCTSIM/hal/src/hal_usart_async.c b/sysmoOCTSIM/hal/src/hal_usart_async.c new file mode 100644 index 0000000..f07b266 --- /dev/null +++ b/sysmoOCTSIM/hal/src/hal_usart_async.c @@ -0,0 +1,420 @@ +/** + * \file + * + * \brief I/O USART related functionality implementation. + * + * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ + +#include "hal_usart_async.h" +#include <utils_assert.h> +#include <hal_atomic.h> +#include <utils.h> + +/** + * \brief Driver version + */ +#define DRIVER_VERSION 0x00000001u + +static int32_t usart_async_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length); +static int32_t usart_async_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length); +static void usart_process_byte_sent(struct _usart_async_device *device); +static void usart_transmission_complete(struct _usart_async_device *device); +static void usart_error(struct _usart_async_device *device); +static void usart_fill_rx_buffer(struct _usart_async_device *device, uint8_t data); + +/** + * \brief Initialize usart interface + */ +int32_t usart_async_init(struct usart_async_descriptor *const descr, void *const hw, uint8_t *rx_buffer, + uint16_t rx_buffer_length, void *const func) +{ + int32_t init_status; + ASSERT(descr && hw && rx_buffer && rx_buffer_length); + + if (ERR_NONE != ringbuffer_init(&descr->rx, rx_buffer, rx_buffer_length)) { + return ERR_INVALID_ARG; + } + init_status = _usart_async_init(&descr->device, hw); + if (init_status) { + return init_status; + } + + descr->io.read = usart_async_read; + descr->io.write = usart_async_write; + + descr->device.usart_cb.tx_byte_sent = usart_process_byte_sent; + descr->device.usart_cb.rx_done_cb = usart_fill_rx_buffer; + descr->device.usart_cb.tx_done_cb = usart_transmission_complete; + descr->device.usart_cb.error_cb = usart_error; + + return ERR_NONE; +} + +/** + * \brief Deinitialize usart interface + */ +int32_t usart_async_deinit(struct usart_async_descriptor *const descr) +{ + ASSERT(descr); + _usart_async_deinit(&descr->device); + descr->io.read = NULL; + descr->io.write = NULL; + + return ERR_NONE; +} + +/** + * \brief Enable usart interface + */ +int32_t usart_async_enable(struct usart_async_descriptor *const descr) +{ + ASSERT(descr); + _usart_async_enable(&descr->device); + + return ERR_NONE; +} + +/** + * \brief Disable usart interface + */ +int32_t usart_async_disable(struct usart_async_descriptor *const descr) +{ + ASSERT(descr); + _usart_async_disable(&descr->device); + + return ERR_NONE; +} + +/** + * \brief Retrieve I/O descriptor + */ +int32_t usart_async_get_io_descriptor(struct usart_async_descriptor *const descr, struct io_descriptor **io) +{ + ASSERT(descr && io); + + *io = &descr->io; + return ERR_NONE; +} + +/** + * \brief Register usart callback + */ +int32_t usart_async_register_callback(struct usart_async_descriptor *const descr, + const enum usart_async_callback_type type, usart_cb_t cb) +{ + ASSERT(descr); + + switch (type) { + case USART_ASYNC_RXC_CB: + descr->usart_cb.rx_done = cb; + _usart_async_set_irq_state(&descr->device, USART_ASYNC_RX_DONE, NULL != cb); + break; + case USART_ASYNC_TXC_CB: + descr->usart_cb.tx_done = cb; + _usart_async_set_irq_state(&descr->device, USART_ASYNC_TX_DONE, NULL != cb); + break; + case USART_ASYNC_ERROR_CB: + descr->usart_cb.error = cb; + _usart_async_set_irq_state(&descr->device, USART_ASYNC_ERROR, NULL != cb); + break; + default: + return ERR_INVALID_ARG; + } + + return ERR_NONE; +} + +/** + * \brief Specify action for flow control pins + */ +int32_t usart_async_set_flow_control(struct usart_async_descriptor *const descr, + const union usart_flow_control_state state) +{ + ASSERT(descr); + _usart_async_set_flow_control_state(&descr->device, state); + + return ERR_NONE; +} + +/** + * \brief Set usart baud rate + */ +int32_t usart_async_set_baud_rate(struct usart_async_descriptor *const descr, const uint32_t baud_rate) +{ + ASSERT(descr); + _usart_async_set_baud_rate(&descr->device, baud_rate); + + return ERR_NONE; +} + +/** + * \brief Set usart data order + */ +int32_t usart_async_set_data_order(struct usart_async_descriptor *const descr, const enum usart_data_order data_order) +{ + ASSERT(descr); + _usart_async_set_data_order(&descr->device, data_order); + + return ERR_NONE; +} + +/** + * \brief Set usart mode + */ +int32_t usart_async_set_mode(struct usart_async_descriptor *const descr, const enum usart_mode mode) +{ + ASSERT(descr); + _usart_async_set_mode(&descr->device, mode); + + return ERR_NONE; +} + +/** + * \brief Set usart parity + */ +int32_t usart_async_set_parity(struct usart_async_descriptor *const descr, const enum usart_parity parity) +{ + ASSERT(descr); + _usart_async_set_parity(&descr->device, parity); + + return ERR_NONE; +} + +/** + * \brief Set usart stop bits + */ +int32_t usart_async_set_stopbits(struct usart_async_descriptor *const descr, const enum usart_stop_bits stop_bits) +{ + ASSERT(descr); + _usart_async_set_stop_bits(&descr->device, stop_bits); + + return ERR_NONE; +} + +/** + * \brief Set usart character size + */ +int32_t usart_async_set_character_size(struct usart_async_descriptor *const descr, const enum usart_character_size size) +{ + ASSERT(descr); + _usart_async_set_character_size(&descr->device, size); + + return ERR_NONE; +} + +/** + * \brief Retrieve the state of flow control pins + */ +int32_t usart_async_flow_control_status(const struct usart_async_descriptor *const descr, + union usart_flow_control_state *const state) +{ + ASSERT(descr && state); + *state = _usart_async_get_flow_control_state(&descr->device); + + return ERR_NONE; +} + +/** + * \brief Check if the usart transmitter is empty + */ +int32_t usart_async_is_tx_empty(const struct usart_async_descriptor *const descr) +{ + ASSERT(descr); + return _usart_async_is_byte_sent(&descr->device); +} + +/** + * \brief Check if the usart receiver is not empty + */ +int32_t usart_async_is_rx_not_empty(const struct usart_async_descriptor *const descr) +{ + ASSERT(descr); + + return ringbuffer_num(&descr->rx) > 0; +} + +/** + * \brief Retrieve the current interface status + */ +int32_t usart_async_get_status(struct usart_async_descriptor *const descr, struct usart_async_status *const status) +{ + ASSERT(descr); + + volatile uint32_t *tmp_stat = &(descr->stat); + volatile uint16_t *tmp_txcnt = &(descr->tx_por); + + if (status) { + status->flags = *tmp_stat; + status->txcnt = *tmp_txcnt; + status->rxcnt = ringbuffer_num(&descr->rx); + } + if (*tmp_stat & USART_ASYNC_STATUS_BUSY) { + return ERR_BUSY; + } + + return ERR_NONE; +} + +/** + * \brief flush usart rx ringbuf + */ +int32_t usart_async_flush_rx_buffer(struct usart_async_descriptor *const descr) +{ + ASSERT(descr); + + return ringbuffer_flush(&descr->rx); +} + +/** + * \brief Retrieve the current driver version + */ +uint32_t usart_async_get_version(void) +{ + return DRIVER_VERSION; +} + +/* + * \internal Write the given data to usart interface + * + * \param[in] descr The pointer to an io descriptor + * \param[in] buf Data to write to usart + * \param[in] length The number of bytes to write + * + * \return The number of bytes written. + */ +static int32_t usart_async_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length) +{ + struct usart_async_descriptor *descr = CONTAINER_OF(io_descr, struct usart_async_descriptor, io); + + ASSERT(descr && buf && length); + + if (descr->tx_por != descr->tx_buffer_length) { + return ERR_NO_RESOURCE; + } + descr->tx_buffer = (uint8_t *)buf; + descr->tx_buffer_length = length; + descr->tx_por = 0; + descr->stat = USART_ASYNC_STATUS_BUSY; + _usart_async_enable_byte_sent_irq(&descr->device); + + return (int32_t)length; +} + +/* + * \internal Read data from usart interface + * + * \param[in] descr The pointer to an io descriptor + * \param[in] buf A buffer to read data to + * \param[in] length The size of a buffer + * + * \return The number of bytes read. + */ +static int32_t usart_async_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length) +{ + uint16_t was_read = 0; + uint32_t num; + struct usart_async_descriptor *descr = CONTAINER_OF(io_descr, struct usart_async_descriptor, io); + + ASSERT(descr && buf && length); + + CRITICAL_SECTION_ENTER() + num = ringbuffer_num(&descr->rx); + CRITICAL_SECTION_LEAVE() + + while ((was_read < num) && (was_read < length)) { + ringbuffer_get(&descr->rx, &buf[was_read++]); + } + + return (int32_t)was_read; +} + +/** + * \brief Process "byte is sent" interrupt + * + * \param[in] device The pointer to device structure + */ +static void usart_process_byte_sent(struct _usart_async_device *device) +{ + struct usart_async_descriptor *descr = CONTAINER_OF(device, struct usart_async_descriptor, device); + if (descr->tx_por != descr->tx_buffer_length) { + _usart_async_write_byte(&descr->device, descr->tx_buffer[descr->tx_por++]); + _usart_async_enable_byte_sent_irq(&descr->device); + } else { + _usart_async_enable_tx_done_irq(&descr->device); + } +} + +/** + * \brief Process completion of data sending + * + * \param[in] device The pointer to device structure + */ +static void usart_transmission_complete(struct _usart_async_device *device) +{ + struct usart_async_descriptor *descr = CONTAINER_OF(device, struct usart_async_descriptor, device); + + descr->stat = 0; + if (descr->usart_cb.tx_done) { + descr->usart_cb.tx_done(descr); + } +} + +/** + * \brief Process byte reception + * + * \param[in] device The pointer to device structure + * \param[in] data Data read + */ +static void usart_fill_rx_buffer(struct _usart_async_device *device, uint8_t data) +{ + struct usart_async_descriptor *descr = CONTAINER_OF(device, struct usart_async_descriptor, device); + + ringbuffer_put(&descr->rx, data); + + if (descr->usart_cb.rx_done) { + descr->usart_cb.rx_done(descr); + } +} + +/** + * \brief Process error interrupt + * + * \param[in] device The pointer to device structure + */ +static void usart_error(struct _usart_async_device *device) +{ + struct usart_async_descriptor *descr = CONTAINER_OF(device, struct usart_async_descriptor, device); + + descr->stat = 0; + if (descr->usart_cb.error) { + descr->usart_cb.error(descr); + } +} + +//@} diff --git a/sysmoOCTSIM/hal/utils/include/utils_ringbuffer.h b/sysmoOCTSIM/hal/utils/include/utils_ringbuffer.h new file mode 100644 index 0000000..401d557 --- /dev/null +++ b/sysmoOCTSIM/hal/utils/include/utils_ringbuffer.h @@ -0,0 +1,116 @@ +/** + * \file + * + * \brief Ringbuffer declaration. + * + * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +#ifndef _UTILS_RINGBUFFER_H_INCLUDED +#define _UTILS_RINGBUFFER_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup doc_driver_hal_utils_ringbuffer + * + * @{ + */ + +#include "compiler.h" +#include "utils_assert.h" + +/** + * \brief Ring buffer element type + */ +struct ringbuffer { + uint8_t *buf; /** Buffer base address */ + uint32_t size; /** Buffer size */ + uint32_t read_index; /** Buffer read index */ + uint32_t write_index; /** Buffer write index */ +}; + +/** + * \brief Ring buffer init + * + * \param[in] rb The pointer to a ring buffer structure instance + * \param[in] buf Space to store the data + * \param[in] size The buffer length, must be aligned with power of 2 + * + * \return ERR_NONE on success, or an error code on failure. + */ +int32_t ringbuffer_init(struct ringbuffer *const rb, void *buf, uint32_t size); + +/** + * \brief Get one byte from ring buffer, the user needs to handle the concurrent + * access on buffer via put/get/flush + * + * \param[in] rb The pointer to a ring buffer structure instance + * \param[in] data One byte space to store the read data + * + * \return ERR_NONE on success, or an error code on failure. + */ +int32_t ringbuffer_get(struct ringbuffer *const rb, uint8_t *data); + +/** + * \brief Put one byte to ring buffer, the user needs to handle the concurrent access + * on buffer via put/get/flush + * + * \param[in] rb The pointer to a ring buffer structure instance + * \param[in] data One byte data to be put into ring buffer + * + * \return ERR_NONE on success, or an error code on failure. + */ +int32_t ringbuffer_put(struct ringbuffer *const rb, uint8_t data); + +/** + * \brief Return the element number of ring buffer + * + * \param[in] rb The pointer to a ring buffer structure instance + * + * \return The number of elements in ring buffer [0, rb->size] + */ +uint32_t ringbuffer_num(const struct ringbuffer *const rb); + +/** + * \brief Flush ring buffer, the user needs to handle the concurrent access on buffer + * via put/get/flush + * + * \param[in] rb The pointer to a ring buffer structure instance + * + * \return ERR_NONE on success, or an error code on failure. + */ +uint32_t ringbuffer_flush(struct ringbuffer *const rb); + +/**@}*/ + +#ifdef __cplusplus +} +#endif +#endif /* _UTILS_RINGBUFFER_H_INCLUDED */ diff --git a/sysmoOCTSIM/hal/utils/src/utils_ringbuffer.c b/sysmoOCTSIM/hal/utils/src/utils_ringbuffer.c new file mode 100644 index 0000000..45cac83 --- /dev/null +++ b/sysmoOCTSIM/hal/utils/src/utils_ringbuffer.c @@ -0,0 +1,118 @@ +/** + * \file + * + * \brief Ringbuffer functionality implementation. + * + * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +#include "utils_ringbuffer.h" + +/** + * \brief Ringbuffer init + */ +int32_t ringbuffer_init(struct ringbuffer *const rb, void *buf, uint32_t size) +{ + ASSERT(rb && buf && size); + + /* + * buf size must be aligned to power of 2 + */ + if ((size & (size - 1)) != 0) { + return ERR_INVALID_ARG; + } + + /* size - 1 is faster in calculation */ + rb->size = size - 1; + rb->read_index = 0; + rb->write_index = rb->read_index; + rb->buf = (uint8_t *)buf; + + return ERR_NONE; +} + +/** + * \brief Get one byte from ringbuffer + * + */ +int32_t ringbuffer_get(struct ringbuffer *const rb, uint8_t *data) +{ + ASSERT(rb && data); + + if (rb->write_index != rb->read_index) { + *data = rb->buf[rb->read_index & rb->size]; + rb->read_index++; + return ERR_NONE; + } + + return ERR_NOT_FOUND; +} + +/** + * \brief Put one byte to ringbuffer + * + */ +int32_t ringbuffer_put(struct ringbuffer *const rb, uint8_t data) +{ + ASSERT(rb); + + rb->buf[rb->write_index & rb->size] = data; + + /* + * buffer full strategy: new data will overwrite the oldest data in + * the buffer + */ + if ((rb->write_index - rb->read_index) > rb->size) { + rb->read_index = rb->write_index - rb->size; + } + + rb->write_index++; + + return ERR_NONE; +} + +/** + * \brief Return the element number of ringbuffer + */ +uint32_t ringbuffer_num(const struct ringbuffer *const rb) +{ + ASSERT(rb); + + return rb->write_index - rb->read_index; +} + +/** + * \brief Flush ringbuffer + */ +uint32_t ringbuffer_flush(struct ringbuffer *const rb) +{ + ASSERT(rb); + + rb->read_index = rb->write_index; + + return ERR_NONE; +} diff --git a/sysmoOCTSIM/hpl/sercom/hpl_sercom.c b/sysmoOCTSIM/hpl/sercom/hpl_sercom.c index 130f63a..11192d0 100644 --- a/sysmoOCTSIM/hpl/sercom/hpl_sercom.c +++ b/sysmoOCTSIM/hpl/sercom/hpl_sercom.c @@ -163,6 +163,8 @@ }; #endif +static struct _usart_async_device *_sercom2_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); @@ -563,6 +565,40 @@ } /** + * \internal Sercom interrupt handler + * + * \param[in] p The pointer to interrupt parameter + */ +static void _sercom_usart_interrupt_handler(struct _usart_async_device *device) +{ + void *hw = device->hw; + + if (hri_sercomusart_get_interrupt_DRE_bit(hw) && hri_sercomusart_get_INTEN_DRE_bit(hw)) { + hri_sercomusart_clear_INTEN_DRE_bit(hw); + device->usart_cb.tx_byte_sent(device); + } else if (hri_sercomusart_get_interrupt_TXC_bit(hw) && hri_sercomusart_get_INTEN_TXC_bit(hw)) { + hri_sercomusart_clear_INTEN_TXC_bit(hw); + device->usart_cb.tx_done_cb(device); + } else if (hri_sercomusart_get_interrupt_RXC_bit(hw)) { + if (hri_sercomusart_read_STATUS_reg(hw) + & (SERCOM_USART_STATUS_PERR | SERCOM_USART_STATUS_FERR | SERCOM_USART_STATUS_BUFOVF + | SERCOM_USART_STATUS_ISF | SERCOM_USART_STATUS_COLL)) { + hri_sercomusart_clear_STATUS_reg(hw, SERCOM_USART_STATUS_MASK); + return; + } + + device->usart_cb.rx_done_cb(device, hri_sercomusart_read_DATA_reg(hw)); + } else if (hri_sercomusart_get_interrupt_ERROR_bit(hw)) { + uint32_t status; + + hri_sercomusart_clear_interrupt_ERROR_bit(hw); + device->usart_cb.error_cb(device); + status = hri_sercomusart_read_STATUS_reg(hw); + hri_sercomusart_clear_STATUS_reg(hw, status); + } +} + +/** * \internal Retrieve ordinal number of the given sercom hardware instance * * \param[in] hw The pointer to hardware instance @@ -589,6 +625,10 @@ */ static void _sercom_init_irq_param(const void *const hw, void *dev) { + + if (hw == SERCOM2) { + _sercom2_dev = (struct _usart_async_device *)dev; + } } /** @@ -2349,6 +2389,35 @@ return NULL; } +/** + * \internal Sercom interrupt handler + */ +void SERCOM2_0_Handler(void) +{ + _sercom_usart_interrupt_handler(_sercom2_dev); +} +/** + * \internal Sercom interrupt handler + */ +void SERCOM2_1_Handler(void) +{ + _sercom_usart_interrupt_handler(_sercom2_dev); +} +/** + * \internal Sercom interrupt handler + */ +void SERCOM2_2_Handler(void) +{ + _sercom_usart_interrupt_handler(_sercom2_dev); +} +/** + * \internal Sercom interrupt handler + */ +void SERCOM2_3_Handler(void) +{ + _sercom_usart_interrupt_handler(_sercom2_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); -- To view, visit https://gerrit.osmocom.org/12803 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: I530a5bc5ee7e89149eb251bda0adf7963733d2ee Gerrit-Change-Number: 12803 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/20190203/cc20f45f/attachment.htm>