From 8476b94ab008805db1e91d74fc47b1619953f48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Redon?= Date: Tue, 11 Dec 2018 17:43:40 +0100 Subject: use USB CDC Echo example project this is the USB CDC Echo example project source code, for the Microchip SAM E54 Xplained Pro development board, based on the ATSAME54P20A micro-controller, exported from the Atmel START website, using the ASFv4 library. Change-Id: Ic0e58e42d1a4076bc84a0a8d3509ec4b09a37f46 --- hal/documentation/usb_device_async.rst | 195 ++++++++++ hal/include/hal_atomic.h | 120 ++++++ hal/include/hal_cache.h | 96 +++++ hal/include/hal_delay.h | 89 +++++ hal/include/hal_gpio.h | 201 ++++++++++ hal/include/hal_init.h | 72 ++++ hal/include/hal_io.h | 110 ++++++ hal/include/hal_sleep.h | 74 ++++ hal/include/hal_usb_device.h | 295 ++++++++++++++ hal/include/hpl_cmcc.h | 277 +++++++++++++ hal/include/hpl_core.h | 56 +++ hal/include/hpl_delay.h | 97 +++++ hal/include/hpl_dma.h | 166 ++++++++ hal/include/hpl_gpio.h | 185 +++++++++ hal/include/hpl_init.h | 124 ++++++ hal/include/hpl_irq.h | 116 ++++++ hal/include/hpl_missing_features.h | 37 ++ hal/include/hpl_ramecc.h | 100 +++++ hal/include/hpl_reset.h | 93 +++++ hal/include/hpl_sleep.h | 88 +++++ hal/include/hpl_usb.h | 270 +++++++++++++ hal/include/hpl_usb_device.h | 377 ++++++++++++++++++ hal/include/hpl_usb_host.h | 618 ++++++++++++++++++++++++++++++ hal/src/hal_atomic.c | 66 ++++ hal/src/hal_cache.c | 78 ++++ hal/src/hal_delay.c | 80 ++++ hal/src/hal_gpio.c | 44 +++ hal/src/hal_init.c | 47 +++ hal/src/hal_io.c | 63 +++ hal/src/hal_sleep.c | 73 ++++ hal/src/hal_usb_device.c | 592 ++++++++++++++++++++++++++++ hal/utils/include/compiler.h | 64 ++++ hal/utils/include/err_codes.h | 73 ++++ hal/utils/include/events.h | 54 +++ hal/utils/include/parts.h | 41 ++ hal/utils/include/utils.h | 368 ++++++++++++++++++ hal/utils/include/utils_assert.h | 93 +++++ hal/utils/include/utils_event.h | 115 ++++++ hal/utils/include/utils_increment_macro.h | 308 +++++++++++++++ hal/utils/include/utils_list.h | 164 ++++++++ hal/utils/include/utils_repeat_macro.h | 322 ++++++++++++++++ hal/utils/src/utils_assert.c | 46 +++ hal/utils/src/utils_event.c | 125 ++++++ hal/utils/src/utils_list.c | 136 +++++++ hal/utils/src/utils_syscalls.c | 152 ++++++++ 45 files changed, 6960 insertions(+) create mode 100644 hal/documentation/usb_device_async.rst create mode 100644 hal/include/hal_atomic.h create mode 100644 hal/include/hal_cache.h create mode 100644 hal/include/hal_delay.h create mode 100644 hal/include/hal_gpio.h create mode 100644 hal/include/hal_init.h create mode 100644 hal/include/hal_io.h create mode 100644 hal/include/hal_sleep.h create mode 100644 hal/include/hal_usb_device.h create mode 100644 hal/include/hpl_cmcc.h create mode 100644 hal/include/hpl_core.h create mode 100644 hal/include/hpl_delay.h create mode 100644 hal/include/hpl_dma.h create mode 100644 hal/include/hpl_gpio.h create mode 100644 hal/include/hpl_init.h create mode 100644 hal/include/hpl_irq.h create mode 100644 hal/include/hpl_missing_features.h create mode 100644 hal/include/hpl_ramecc.h create mode 100644 hal/include/hpl_reset.h create mode 100644 hal/include/hpl_sleep.h create mode 100644 hal/include/hpl_usb.h create mode 100644 hal/include/hpl_usb_device.h create mode 100644 hal/include/hpl_usb_host.h create mode 100644 hal/src/hal_atomic.c create mode 100644 hal/src/hal_cache.c create mode 100644 hal/src/hal_delay.c create mode 100644 hal/src/hal_gpio.c create mode 100644 hal/src/hal_init.c create mode 100644 hal/src/hal_io.c create mode 100644 hal/src/hal_sleep.c create mode 100644 hal/src/hal_usb_device.c create mode 100644 hal/utils/include/compiler.h create mode 100644 hal/utils/include/err_codes.h create mode 100644 hal/utils/include/events.h create mode 100644 hal/utils/include/parts.h create mode 100644 hal/utils/include/utils.h create mode 100644 hal/utils/include/utils_assert.h create mode 100644 hal/utils/include/utils_event.h create mode 100644 hal/utils/include/utils_increment_macro.h create mode 100644 hal/utils/include/utils_list.h create mode 100644 hal/utils/include/utils_repeat_macro.h create mode 100644 hal/utils/src/utils_assert.c create mode 100644 hal/utils/src/utils_event.c create mode 100644 hal/utils/src/utils_list.c create mode 100644 hal/utils/src/utils_syscalls.c (limited to 'hal') diff --git a/hal/documentation/usb_device_async.rst b/hal/documentation/usb_device_async.rst new file mode 100644 index 0000000..647eec0 --- /dev/null +++ b/hal/documentation/usb_device_async.rst @@ -0,0 +1,195 @@ +The USB Device Asynchronous Driver +================================== + +Universal Serial Bus (USB) is an industry standard that defines the cables, +connectors and communication protocols used in a bus for connection, +communication, and power supply between computers and electronic devices. + +The USB device driver provides necessary APIs to support USB Device states and +USB data flow. So that the USB Device enumeration, class and vendor support can +be implemented base on it. The driver is asynchronous, which means that all USB +data processing is done in callbacks.. + +To be recognized by a host, a USB device must handle a subset of the USB events. +The USB device should build up control communication to report its descriptors +to the host and accept host's requests. An application or upper stack that uses +the USB device driver should have its descriptors prepared, catch the callbacks, +monitor the control requests and handle them correctly. +Usually, a USB device application that can be enumerated may use the following +sequence: + +* Initialize +* Register callback and handle Reset event, where: + + * Initialize endpoint 0 + * Register callbacks for endpoint 0, where some of the standard requests + defined in Chapter 9, USB specification + (see `USB 2.0 Documents `_) + are handled + + * Setup request handling callback + + * On *GetDeviceDescriptor* request, sends device descriptor + * On *GetConfigurationDescriptor* request, sends configuration descriptors + * On *SetAddress* request sends no data, just goes to status phase + * On *SetConfigure* request initialize and enable other endpoints, sends + no data, just goes to status phase + * Transfer done handling callback + + * On *SetAddress* request apply the new address + * On *SetConfigure* request a global variable can be set to indicates + that the host driver is loaded and device is ready to work + * Enable endpoint 0 +* Enable +* Attach device + +To support USB transfer on endpoints, endpoints information is stored +by the driver internally, including control request data, endpoint status, +callbacks and transfer data pointers. The number of endpoints that the driver +can support is defined through configuration. To optimize RAM usage, the +number of endpoints the driver needs to support should be minimized. + +Features +-------- + +* Initialization/de-initialization +* Enabling/disabling +* USB device attachment/detachment +* USB device address control +* USB working speed status +* USB device frame number and micro frame number status +* Sending remote wakeup to host +* Callback management for following USB events: + + * Start of Frame (SOF) + * Other USB events: + + * VBus change + * Reset + * Wakeup + * Linked Power Management (LPM) Suspend + * Suspend + * Error +* Endpoints management: + + * Endpoint initialization/de-initialization + * Endpoint enabling/disabling + * Control endpoint setup request packet + * Data transfer and abort + * Endpoint halt state control + * Endpoint status, including: + + * Endpoint address + * Last transfer result status code + * Last error status code + * Current transfer state + * Transfer size and done count + * Endpoint callback management for endpoint and its transfer events: + + * In case a setup request received on control endpoint + * In case transfer finished with/without error + +Applications +------------ + +USB Device stack, to monitor USB events, handle control requests and process +data. + +Dependencies +------------ + +* USB device capable hardware +* 48MHz clock for low-speed and full-speed and 480MHz clock for high-speed + +Concurrency +----------- + +N/A + +Limitations +----------- + +* When a buffer is used by a USB endpoint to transfer data, it must be kept + unchanged while the transfer is in progress. +* After receiving a request that has no data expected, the transfer function + must be called with data length zero to complete control status phase. + +Known issues and workarounds +---------------------------- + +N/A + +Considerations for D21 USB +-------------------------- + +Clocks +^^^^^^ + +DFLL must be used to generate 48MHz clock for USB device with either of the +following mode: + +* USB Clock Recovery Mode + + * Set "DFLL Enable", "Bypass Coarse Lock", "Chill Cycle Disable", + "USB Clock Recovery Mode", "Stable DFLL Frequency" + * Clear "Wait Lock" + * Leave "Operating Mode Selection" to "Closed Loop Mode" + +* Closed Loop Mode + + * Set "DFLL Enable" + * Clear "USB Clock Recovery Mode", "Stable DFLL Frequency" + * Select "Closed Loop Mode" of "Operating Mode Selection" + * Set "DFLL Multiply Factor" to 1464 or 1465 (48000000/32768) + * Select "Reference Clock Source" to use 32768Hz source, e.g., use GCLK1 and + for GCLK1 settings: + + * Set "Generic Clock Generator Enable" + * Select "XOSC32K" of "Generic clock generator 1 source", and for XOSC32K + settings: + + * Set "External 32K Oscillator Enable", "Enable 32KHz Output", + "Enable XTAL" + * Set a right value for "Startup time for the 32K Oscillator", e.g., + 1125092 us + +Endpoints +^^^^^^^^^ + +Each USB device endpoint number supports two endpoint addresses, corresponding +to IN and OUT endpoint. E.g., for endpoint 1, the endpoint IN has address 0x81 +and endpoint OUT has address 0x01. Thus, the possible supported endpoint +addresses are almost two times of max endpoint number (endpoint 0 must be used +as control endpoint instead of dedicated IN and OUT endpoints). + +Buffering and RAM usage optimization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When transferring data through USB device endpoints, buffer pointers can be +used to let endpoint get access to the buffer, but there are some limits: + +* For control endpoint there must always be a buffer available to put received + setup packet. +* For IN endpoint (transmit to host) the data must in RAM. +* For OUT endpoint (receive from host) the data pointer must be aligned, and + the data size must be aligned by max endpoint size and not zero. + +The driver has option for each endpoint to allocate internal static buffer as +cache to buffer input/output data, to remove upper limits. The configuration +affects the parameter check of transfer functions, and the RAM usage. + +* For control endpoints, cache buffer must be enabled to fill setup packet. + In addition, to support unaligned OUT packet and IN packet inside flash, the + buffer size must be equal to or larger than max endpoint size. +* For OUT endpoints, if the cache is allocated, it's possible to pass unaligned + buffer address and buffer size to transfer function. Else the transfer + function only accepts aligned buffer with it's size multiple of endpoint + packet size. +* For IN endpoints, if the cache is allocated, it's possible to pass buffer + pointer to internal flash or other memory part other than RAM to the transfer + function. + +To optimize the RAM usage, the configuration of max endpoint number, max number +of endpoints supported and the buffer usage of used input and/or output +endpoints can be adjusted. + diff --git a/hal/include/hal_atomic.h b/hal/include/hal_atomic.h new file mode 100644 index 0000000..82151fc --- /dev/null +++ b/hal/include/hal_atomic.h @@ -0,0 +1,120 @@ +/** + * \file + * + * \brief Critical sections 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_ATOMIC_H_INCLUDED +#define _HAL_ATOMIC_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup doc_driver_hal_helper_atomic + * + *@{ + */ + +/** + * \brief Type for the register holding global interrupt enable flag + */ +typedef uint32_t hal_atomic_t; + +/** + * \brief Helper macro for entering critical sections + * + * This macro is recommended to be used instead of a direct call + * hal_enterCritical() function to enter critical + * sections. No semicolon is required after the macro. + * + * \section atomic_usage Usage Example + * \code + * CRITICAL_SECTION_ENTER() + * Critical code + * CRITICAL_SECTION_LEAVE() + * \endcode + */ +#define CRITICAL_SECTION_ENTER() \ + { \ + volatile hal_atomic_t __atomic; \ + atomic_enter_critical(&__atomic); + +/** + * \brief Helper macro for leaving critical sections + * + * This macro is recommended to be used instead of a direct call + * hal_leaveCritical() function to leave critical + * sections. No semicolon is required after the macro. + */ +#define CRITICAL_SECTION_LEAVE() \ + atomic_leave_critical(&__atomic); \ + } + +/** + * \brief Disable interrupts, enter critical section + * + * Disables global interrupts. Supports nested critical sections, + * so that global interrupts are only re-enabled + * upon leaving the outermost nested critical section. + * + * \param[out] atomic The pointer to a variable to store the value of global + * interrupt enable flag + */ +void atomic_enter_critical(hal_atomic_t volatile *atomic); + +/** + * \brief Exit atomic section + * + * Enables global interrupts. Supports nested critical sections, + * so that global interrupts are only re-enabled + * upon leaving the outermost nested critical section. + * + * \param[in] atomic The pointer to a variable, which stores the latest stored + * value of the global interrupt enable flag + */ +void atomic_leave_critical(hal_atomic_t volatile *atomic); + +/** + * \brief Retrieve the current driver version + * + * \return Current driver version. + */ +uint32_t atomic_get_version(void); +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _HAL_ATOMIC_H_INCLUDED */ diff --git a/hal/include/hal_cache.h b/hal/include/hal_cache.h new file mode 100644 index 0000000..071486b --- /dev/null +++ b/hal/include/hal_cache.h @@ -0,0 +1,96 @@ +/** + * \file + * + * \brief HAL cache functionality implementation. + * + * Copyright (c)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 + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef HAL_CACHE_H_ +#define HAL_CACHE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Enable cache module + * + * \param[in] pointer pointing to the starting address of cache module + * + * \return status of operation + */ +int32_t cache_enable(const void *hw); + +/** + * \brief Disable cache module + * + * \param[in] pointer pointing to the starting address of cache module + * + * \return status of operation + */ +int32_t cache_disable(const void *hw); + +/** + * \brief Initialize cache module + * + * This function initialize cache module configuration. + * + * \return status of operation + */ +int32_t cache_init(void); + +/** + * \brief Configure cache module + * + * \param[in] pointer pointing to the starting address of cache module + * \param[in] cache configuration structure pointer + * + * \return status of operation + */ +int32_t cache_configure(const void *hw, struct _cache_cfg *cache); + +/** + * \brief Invalidate entire cache entries + * + * \param[in] pointer pointing to the starting address of cache module + * + * \return status of operation + */ +int32_t cache_invalidate_all(const void *hw); + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_CACHE_H_ */ diff --git a/hal/include/hal_delay.h b/hal/include/hal_delay.h new file mode 100644 index 0000000..9d4aa5c --- /dev/null +++ b/hal/include/hal_delay.h @@ -0,0 +1,89 @@ +/** + * \file + * + * \brief HAL delay 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 + * + */ + +#include +#include +#include + +#ifndef _HAL_DELAY_H_INCLUDED +#define _HAL_DELAY_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup doc_driver_hal_delay Delay Driver + * + *@{ + */ + +/** + * \brief Initialize Delay driver + * + * \param[in] hw The pointer to hardware instance + */ +void delay_init(void *const hw); + +/** + * \brief Perform delay in us + * + * This function performs delay for the given amount of microseconds. + * + * \param[in] us The amount delay in us + */ +void delay_us(const uint16_t us); + +/** + * \brief Perform delay in ms + * + * This function performs delay for the given amount of milliseconds. + * + * \param[in] ms The amount delay in ms + */ +void delay_ms(const uint16_t ms); + +/** + * \brief Retrieve the current driver version + * + * \return Current driver version. + */ +uint32_t delay_get_version(void); + +/**@}*/ +#ifdef __cplusplus +} +#endif +#endif /* _HAL_DELAY_H_INCLUDED */ diff --git a/hal/include/hal_gpio.h b/hal/include/hal_gpio.h new file mode 100644 index 0000000..fbfa2d4 --- /dev/null +++ b/hal/include/hal_gpio.h @@ -0,0 +1,201 @@ +/** + * \file + * + * \brief Port + * + * 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_GPIO_INCLUDED_ +#define _HAL_GPIO_INCLUDED_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Set gpio pull mode + * + * Set pin pull mode, non existing pull modes throws an fatal assert + * + * \param[in] pin The pin number for device + * \param[in] pull_mode GPIO_PULL_DOWN = Pull pin low with internal resistor + * GPIO_PULL_UP = Pull pin high with internal resistor + * GPIO_PULL_OFF = Disable pin pull mode + */ +static inline void gpio_set_pin_pull_mode(const uint8_t pin, const enum gpio_pull_mode pull_mode) +{ + _gpio_set_pin_pull_mode((enum gpio_port)GPIO_PORT(pin), pin & 0x1F, pull_mode); +} + +/** + * \brief Set pin function + * + * Select which function a pin will be used for + * + * \param[in] pin The pin number for device + * \param[in] function The pin function is given by a 32-bit wide bitfield + * found in the header files for the device + * + */ +static inline void gpio_set_pin_function(const uint32_t pin, uint32_t function) +{ + _gpio_set_pin_function(pin, function); +} + +/** + * \brief Set port data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + * \param[in] mask Bit mask where 1 means apply direction setting to the + * corresponding pin + * \param[in] direction GPIO_DIRECTION_IN = Data direction in + * GPIO_DIRECTION_OUT = Data direction out + * GPIO_DIRECTION_OFF = Disables the pin + * (low power state) + */ +static inline void gpio_set_port_direction(const enum gpio_port port, const uint32_t mask, + const enum gpio_direction direction) +{ + _gpio_set_direction(port, mask, direction); +} + +/** + * \brief Set gpio data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] pin The pin number for device + * \param[in] direction GPIO_DIRECTION_IN = Data direction in + * GPIO_DIRECTION_OUT = Data direction out + * GPIO_DIRECTION_OFF = Disables the pin + * (low power state) + */ +static inline void gpio_set_pin_direction(const uint8_t pin, const enum gpio_direction direction) +{ + _gpio_set_direction((enum gpio_port)GPIO_PORT(pin), 1U << GPIO_PIN(pin), direction); +} + +/** + * \brief Set port level + * + * Sets output level on the pins defined by the bit mask + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + * \param[in] mask Bit mask where 1 means apply port level to the corresponding + * pin + * \param[in] level true = Pin levels set to "high" state + * false = Pin levels set to "low" state + */ +static inline void gpio_set_port_level(const enum gpio_port port, const uint32_t mask, const bool level) +{ + _gpio_set_level(port, mask, level); +} + +/** + * \brief Set gpio level + * + * Sets output level on a pin + * + * \param[in] pin The pin number for device + * \param[in] level true = Pin level set to "high" state + * false = Pin level set to "low" state + */ +static inline void gpio_set_pin_level(const uint8_t pin, const bool level) +{ + _gpio_set_level((enum gpio_port)GPIO_PORT(pin), 1U << GPIO_PIN(pin), level); +} + +/** + * \brief Toggle out level on pins + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + * \param[in] mask Bit mask where 1 means toggle pin level to the corresponding + * pin + */ +static inline void gpio_toggle_port_level(const enum gpio_port port, const uint32_t mask) +{ + _gpio_toggle_level(port, mask); +} + +/** + * \brief Toggle output level on pin + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] pin The pin number for device + */ +static inline void gpio_toggle_pin_level(const uint8_t pin) +{ + _gpio_toggle_level((enum gpio_port)GPIO_PORT(pin), 1U << GPIO_PIN(pin)); +} + +/** + * \brief Get input level on pins + * + * Read the input level on pins connected to a port + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + */ +static inline uint32_t gpio_get_port_level(const enum gpio_port port) +{ + return _gpio_get_level(port); +} + +/** + * \brief Get level on pin + * + * Reads the level on pins connected to a port + * + * \param[in] pin The pin number for device + */ +static inline bool gpio_get_pin_level(const uint8_t pin) +{ + return (bool)(_gpio_get_level((enum gpio_port)GPIO_PORT(pin)) & (0x01U << GPIO_PIN(pin))); +} +/** + * \brief Get current driver version + */ +uint32_t gpio_get_version(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hal/include/hal_init.h b/hal/include/hal_init.h new file mode 100644 index 0000000..d7bc6fe --- /dev/null +++ b/hal/include/hal_init.h @@ -0,0 +1,72 @@ +/** + * \file + * + * \brief HAL initialization 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_INIT_H_INCLUDED +#define _HAL_INIT_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup doc_driver_hal_helper_init Init Driver + * + *@{ + */ + +/** + * \brief Initialize the hardware abstraction layer + * + * This function calls the various initialization functions. + * Currently the following initialization functions are supported: + * - System clock initialization + */ +static inline void init_mcu(void) +{ + _init_chip(); +} + +/** + * \brief Retrieve the current driver version + * + * \return Current driver version. + */ +uint32_t init_get_version(void); + +/**@}*/ +#ifdef __cplusplus +} +#endif +#endif /* _HAL_INIT_H_INCLUDED */ diff --git a/hal/include/hal_io.h b/hal/include/hal_io.h new file mode 100644 index 0000000..f50401d --- /dev/null +++ b/hal/include/hal_io.h @@ -0,0 +1,110 @@ +/** + * \file + * + * \brief I/O 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_IO_INCLUDED +#define _HAL_IO_INCLUDED + +/** + * \addtogroup doc_driver_hal_helper_io I/O Driver + * + *@{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief I/O descriptor + * + * The I/O descriptor forward declaration. + */ +struct io_descriptor; + +/** + * \brief I/O write function pointer type + */ +typedef int32_t (*io_write_t)(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length); + +/** + * \brief I/O read function pointer type + */ +typedef int32_t (*io_read_t)(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length); + +/** + * \brief I/O descriptor + */ +struct io_descriptor { + io_write_t write; /*! The write function pointer. */ + io_read_t read; /*! The read function pointer. */ +}; + +/** + * \brief I/O write interface + * + * This function writes up to \p length of bytes to a given I/O descriptor. + * It returns the number of bytes actually write. + * + * \param[in] descr An I/O descriptor to write + * \param[in] buf The buffer pointer to story the write data + * \param[in] length The number of bytes to write + * + * \return The number of bytes written + */ +int32_t io_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length); + +/** + * \brief I/O read interface + * + * This function reads up to \p length bytes from a given I/O descriptor, and + * stores it in the buffer pointed to by \p buf. It returns the number of bytes + * actually read. + * + * \param[in] descr An I/O descriptor to read + * \param[in] buf The buffer pointer to story the read data + * \param[in] length The number of bytes to read + * + * \return The number of bytes actually read. This number can be less than the + * requested length. E.g., in a driver that uses ring buffer for + * reception, it may depend on the availability of data in the + * ring buffer. + */ +int32_t io_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length); + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HAL_IO_INCLUDED */ diff --git a/hal/include/hal_sleep.h b/hal/include/hal_sleep.h new file mode 100644 index 0000000..b90ef6a --- /dev/null +++ b/hal/include/hal_sleep.h @@ -0,0 +1,74 @@ +/** + * \file + * + * \brief Sleep 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_SLEEP_H_INCLUDED +#define _HAL_SLEEP_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup doc_driver_hal_helper_sleep + * + *@{ + */ + +/** + * \brief Set the sleep mode of the device and put the MCU to sleep + * + * For an overview of which systems are disabled in sleep for the different + * sleep modes, see the data sheet. + * + * \param[in] mode Sleep mode to use + * + * \return The status of a sleep request + * \retval -1 The requested sleep mode was invalid or not available + * \retval 0 The operation completed successfully, returned after leaving the + * sleep + */ +int sleep(const uint8_t mode); + +/** + * \brief Retrieve the current driver version + * + * \return Current driver version. + */ +uint32_t sleep_get_version(void); +/**@}*/ +#ifdef __cplusplus +} +#endif +#endif /* _HAL_SLEEP_H_INCLUDED */ diff --git a/hal/include/hal_usb_device.h b/hal/include/hal_usb_device.h new file mode 100644 index 0000000..7e19f68 --- /dev/null +++ b/hal/include/hal_usb_device.h @@ -0,0 +1,295 @@ +/** + * \file + * + * \brief SAM USB device HAL + * + * Copyright (c) 2015-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_USB_DEVICE_H_INCLUDED +#define _HAL_USB_DEVICE_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup doc_driver_hal_usb_device + * + * @{ + */ + +/** USB device endpoint status structure. */ +struct usb_d_ep_status { + /** Endpoint address, including direction. */ + uint8_t ep; + /** Endpoint transfer status code that triggers the callback. + * \ref usb_xfer_code. */ + uint8_t code; + /** Endpoint error, if \c code is \ref USB_TRANS_ERROR. */ + uint8_t error; + /** Transfer state, \ref usb_ep_state. */ + uint8_t state; + /** Transfer count. */ + uint32_t count; + /** Transfer size. */ + uint32_t size; +}; + +/** Prototype function for callback that is invoked on USB device SOF. */ +typedef void (*usb_d_sof_cb_t)(void); + +/** Prototype function for callback that is invoked on USB device events. */ +typedef void (*usb_d_event_cb_t)(const enum usb_event event, const uint32_t param); + +/** USB device callbacks. */ +struct usb_d_callbacks { + /** Callback that is invoked on SOF. */ + usb_d_sof_cb_t sof; + /** Callback that is invoked on USB RESET/WAKEUP/RESUME/SUSPEND. */ + usb_d_event_cb_t event; +}; + +/** Callback that is invoked when setup packet is received. + * Return \c true if request has been handled, or control endpoint will + * stall IN/OUT transactions. + */ +typedef bool (*usb_d_ep_cb_setup_t)(const uint8_t ep, const uint8_t *req); + +/** Callback that is invoked when buffer is done without error, but last packet + * is full size packet without ZLP. + * Return \c true if more data has been requested. + */ +typedef bool (*usb_d_ep_cb_more_t)(const uint8_t ep, const uint32_t count); + +/** Callback that is invoked when all data is finished, including background + * transfer, or error happens. + * In control transfer data stage, return value is checked, + * return \c false if no error happens. + */ +typedef bool (*usb_d_ep_cb_xfer_t)(const uint8_t ep, const enum usb_xfer_code code, void *param); + +/** + * \brief Initialize the USB device driver + * \return Operation status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t usb_d_init(void); + +/** + * \brief Deinitialize the USB device driver + */ +void usb_d_deinit(void); + +/** + * \brief Register the USB device callback + * \param[in] type The callback type to register. + * \param[in] func The callback function, NULL to disable callback. + */ +void usb_d_register_callback(const enum usb_d_cb_type type, const FUNC_PTR func); + +/** + * \brief Enable the USB device driver + * \return Operation status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t usb_d_enable(void); + +/** + * \brief Disable the USB device driver + */ +void usb_d_disable(void); + +/** + * \brief Attach the USB device + */ +void usb_d_attach(void); + +/** + * \brief Detach the USB device + */ +void usb_d_detach(void); + +/** + * \brief Retrieve current USB working speed. + * \return USB Speed. See \ref usb_speed. + */ +enum usb_speed usb_d_get_speed(void); + +/** + * \brief Retrieve current USB frame number. + * \return Frame number. + */ +uint16_t usb_d_get_frame_num(void); + +/** + * \brief Retrieve current USB micro frame number. + * \return Micro frame number inside a frame (0~7). + * 0 if not available (not HS). + */ +uint8_t usb_d_get_uframe_num(void); + +/** + * \brief Set the USB address that is used. + * \param[in] addr The address to set. + */ +void usb_d_set_address(const uint8_t addr); + +/** + * \brief Send remote wakeup to host + * \return Operation status. + */ +void usb_d_send_remotewakeup(void); + +/** + * \brief Initialize the endpoint 0. + * + * Note that endpoint 0 must be initialized as control endpoint. + * + * \param[in] max_pkt_size Max. packet size of EP0. + * \return Operation status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t usb_d_ep0_init(const uint8_t max_pkt_size); + +/** + * \brief Initialize the endpoint. + * + * \param[in] ep The endpoint address. + * \param[in] attr The endpoint attributes. + * \param[in] max_pkt_size Max. packet size of EP0. + * \return Operation status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t usb_d_ep_init(const uint8_t ep, const uint8_t attr, const uint16_t max_pkt_size); + +/** + * \brief Disable and deinitialize the endpoint. + * \param[in] ep The endpoint address to deinitialize. + */ +void usb_d_ep_deinit(const uint8_t ep); + +/** + * \brief Register the USB device endpoint callback on initialized endpoint. + * + * \param[in] ep The endpoint address. + * \param[in] type The callback type to register. + * \param[in] func The callback function, NULL to disable callback. + */ +void usb_d_ep_register_callback(const uint8_t ep, const enum usb_d_ep_cb_type type, const FUNC_PTR func); + +/** + * \brief Enabled the initialized endpoint. + * + * Setup request will be monitored after enabling a control endpoint. + * + * \param[in] ep The endpoint address. + * \return Operation status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t usb_d_ep_enable(const uint8_t ep); + +/** + * \brief Disable the initialized endpoint. + * \param[in] ep The endpoint address. + */ +void usb_d_ep_disable(const uint8_t ep); + +/** + * \brief Get request data pointer to access received setup request packet + * \param[in] ep The endpoint address. + * \return Pointer to the request data. + * \retval NULL The endpoint is not a control endpoint. + */ +uint8_t *usb_d_ep_get_req(const uint8_t ep); + +/** + * \brief Endpoint transfer. + * + * For control endpoints, start the transfer according to the direction in the bmRequest + * type, and finish with STATUS stage. + * For non-control endpoints, the transfer will be unique direction. Defined by + * bit 8 of the endpoint address. + * + * \param[in] xfer Pointer to the transfer description. + * \return Operation status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t usb_d_ep_transfer(const struct usb_d_transfer *xfer); + +/** + * \brief Abort an on-going transfer on a specific endpoint. + * + * \param[in] ep The endpoint address. + */ +void usb_d_ep_abort(const uint8_t ep); + +/** + * \brief Retrieve the endpoint status. + * + * \param[in] ep The endpoint address. + * \param[out] stat Pointer to the buffer to fill the status description. + * + * \return Endpoint status. + * \retval 1 Busy. + * \retval 0 Idle. + * \retval <0 Error code. + */ +int32_t usb_d_ep_get_status(const uint8_t ep, struct usb_d_ep_status *stat); + +/** + * \brief Endpoint halt control. + * + * \param[in] ep The endpoint address. + * \param[in] ctrl Control code (SET/CLEAR/GET). + * + * \return Operation status or HALT state (if \c ctrl is \ref USB_EP_HALT_GET). + */ +int32_t usb_d_ep_halt(const uint8_t ep, const enum usb_ep_halt_ctrl ctrl); + +/** \brief Retrieve the current driver version + * + * \return Current driver version. + */ +uint32_t usb_d_get_version(void); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _HAL_USB_DEVICE_H_INCLUDED */ diff --git a/hal/include/hpl_cmcc.h b/hal/include/hpl_cmcc.h new file mode 100644 index 0000000..cb26091 --- /dev/null +++ b/hal/include/hpl_cmcc.h @@ -0,0 +1,277 @@ +/** + * \file + * + * \brief Generic CMCC(Cortex M Cache Controller) related functionality. + * + * Copyright (c)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 + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef HPL_CMCC_H_ +#define HPL_CMCC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \Cache driver MACROS + */ +#define CMCC_DISABLE 0U +#define CMCC_ENABLE 1U +#define IS_CMCC_DISABLED 0U +#define IS_CMCC_ENABLED 1U +#define CMCC_WAY_NOS 4U +#define CMCC_LINE_NOS 64U +#define CMCC_MONITOR_DISABLE 0U + +/** + * \brief Cache size configurations + */ +enum conf_cache_size { CONF_CSIZE_1KB = 0u, CONF_CSIZE_2KB, CONF_CSIZE_4KB }; + +/** + * \brief Way Numbers + */ +enum way_num_index { WAY0 = 1u, WAY1 = 2u, WAY2 = 4u, WAY3 = 8 }; + +/** + * \brief Cache monitor configurations + */ +enum conf_cache_monitor { CYCLE_COUNT = 0u, IHIT_COUNT, DHIT_COUNT }; + +/** + * \brief Cache configuration structure + */ +struct _cache_cfg { + enum conf_cache_size cache_size; + bool data_cache_disable; + bool inst_cache_disable; + bool gclk_gate_disable; +}; + +/** + * \brief Cache enable status + */ +static inline bool _is_cache_enabled(const void *hw) +{ + return (hri_cmcc_get_SR_CSTS_bit(hw) == IS_CMCC_ENABLED ? true : false); +} + +/** + * \brief Cache disable status + */ +static inline bool _is_cache_disabled(const void *hw) +{ + return (hri_cmcc_get_SR_CSTS_bit(hw) == IS_CMCC_DISABLED ? true : false); +} + +/** + * \brief Cache enable + */ +static inline int32_t _cmcc_enable(const void *hw) +{ + int32_t return_value; + + if (_is_cache_disabled(hw)) { + hri_cmcc_write_CTRL_reg(hw, CMCC_CTRL_CEN); + return_value = _is_cache_enabled(hw) == true ? ERR_NONE : ERR_FAILURE; + } else { + return_value = ERR_NO_CHANGE; + } + + return return_value; +} + +/** + * \brief Cache disable + */ +static inline int32_t _cmcc_disable(const void *hw) +{ + hri_cmcc_write_CTRL_reg(hw, (CMCC_DISABLE << CMCC_CTRL_CEN_Pos)); + while (!(_is_cache_disabled(hw))) + ; + + return ERR_NONE; +} + +/** + * \brief Initialize Cache Module + * + * This function initialize low level cmcc module configuration. + * + * \return initialize status + */ +int32_t _cmcc_init(void); + +/** + * \brief Configure CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] cache configuration structure pointer + * + * \return status of operation + */ +int32_t _cmcc_configure(const void *hw, struct _cache_cfg *cache_ctrl); + +/** + * \brief Enable data cache in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] boolean 1 -> Enable the data cache, 0 -> disable the data cache + * + * \return status of operation + */ +int32_t _cmcc_enable_data_cache(const void *hw, bool value); + +/** + * \brief Enable instruction cache in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] boolean 1 -> Enable the inst cache, 0 -> disable the inst cache + * + * \return status of operation + */ +int32_t _cmcc_enable_inst_cache(const void *hw, bool value); + +/** + * \brief Enable clock gating in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] boolean 1 -> Enable the clock gate, 0 -> disable the clock gate + * + * \return status of operation + */ +int32_t _cmcc_enable_clock_gating(const void *hw, bool value); + +/** + * \brief Configure the cache size in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] element from cache size configuration enumerator + * 0->1K, 1->2K, 2->4K(default) + * + * \return status of operation + */ +int32_t _cmcc_configure_cache_size(const void *hw, enum conf_cache_size size); + +/** + * \brief Lock the mentioned WAY in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] element from "way_num_index" enumerator + * + * \return status of operation + */ +int32_t _cmcc_lock_way(const void *hw, enum way_num_index); + +/** + * \brief Unlock the mentioned WAY in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] element from "way_num_index" enumerator + * + * \return status of operation + */ +int32_t _cmcc_unlock_way(const void *hw, enum way_num_index); + +/** + * \brief Invalidate the mentioned cache line in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] element from "way_num" enumerator (valid arg is 0-3) + * \param[in] line number (valid arg is 0-63 as each way will have 64 lines) + * + * \return status of operation + */ +int32_t _cmcc_invalidate_by_line(const void *hw, uint8_t way_num, uint8_t line_num); + +/** + * \brief Invalidate entire cache entries in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * + * \return status of operation + */ +int32_t _cmcc_invalidate_all(const void *hw); + +/** + * \brief Configure cache monitor in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * \param[in] element from cache monitor configurations enumerator + * + * \return status of operation + */ +int32_t _cmcc_configure_monitor(const void *hw, enum conf_cache_monitor monitor_cfg); + +/** + * \brief Enable cache monitor in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * + * \return status of operation + */ +int32_t _cmcc_enable_monitor(const void *hw); + +/** + * \brief Disable cache monitor in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * + * \return status of operation + */ +int32_t _cmcc_disable_monitor(const void *hw); + +/** + * \brief Reset cache monitor in CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * + * \return status of operation + */ +int32_t _cmcc_reset_monitor(const void *hw); + +/** + * \brief Get cache monitor event counter value from CMCC module + * + * \param[in] pointer pointing to the starting address of CMCC module + * + * \return event counter value + */ +uint32_t _cmcc_get_monitor_event_count(const void *hw); + +#ifdef __cplusplus +} +#endif +#endif /* HPL_CMCC_H_ */ diff --git a/hal/include/hpl_core.h b/hal/include/hpl_core.h new file mode 100644 index 0000000..9324c43 --- /dev/null +++ b/hal/include/hpl_core.h @@ -0,0 +1,56 @@ +/** + * \file + * + * \brief CPU core related functionality declaration. + * + * Copyright (c) 2015-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 _HPL_CORE_H_INCLUDED +#define _HPL_CORE_H_INCLUDED + +/** + * \addtogroup HPL Core + * + * \section hpl_core_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#include "hpl_core_port.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HPL_CORE_H_INCLUDED */ diff --git a/hal/include/hpl_delay.h b/hal/include/hpl_delay.h new file mode 100644 index 0000000..a0f1ac8 --- /dev/null +++ b/hal/include/hpl_delay.h @@ -0,0 +1,97 @@ +/** + * \file + * + * \brief Delay 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 _HPL_DELAY_H_INCLUDED +#define _HPL_DELAY_H_INCLUDED + +/** + * \addtogroup HPL Delay + * + * \section hpl_delay_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#ifndef _UNIT_TEST_ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name HPL functions + */ +//@{ + +/** + * \brief Initialize delay functionality + * + * \param[in] hw The pointer to hardware instance + */ +void _delay_init(void *const hw); + +/** + * \brief Retrieve the amount of cycles to delay for the given amount of us + * + * \param[in] us The amount of us to delay for + * + * \return The amount of cycles + */ +uint32_t _get_cycles_for_us(const uint16_t us); + +/** + * \brief Retrieve the amount of cycles to delay for the given amount of ms + * + * \param[in] ms The amount of ms to delay for + * + * \return The amount of cycles + */ +uint32_t _get_cycles_for_ms(const uint16_t ms); + +/** + * \brief Delay loop to delay n number of cycles + * + * \param[in] hw The pointer to hardware instance + * \param[in] cycles The amount of cycles to delay for + */ +void _delay_cycles(void *const hw, uint32_t cycles); +//@} + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HPL_DELAY_H_INCLUDED */ diff --git a/hal/include/hpl_dma.h b/hal/include/hpl_dma.h new file mode 100644 index 0000000..315be93 --- /dev/null +++ b/hal/include/hpl_dma.h @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief DMA related functionality declaration. + * + * Copyright (c) 2015-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 _HPL_DMA_H_INCLUDED +#define _HPL_DMA_H_INCLUDED + +/** + * \addtogroup HPL DMA + * + * \section hpl_dma_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct _dma_resource; + +/** + * \brief DMA callback types + */ +enum _dma_callback_type { DMA_TRANSFER_COMPLETE_CB, DMA_TRANSFER_ERROR_CB }; + +/** + * \brief DMA interrupt callbacks + */ +struct _dma_callbacks { + void (*transfer_done)(struct _dma_resource *resource); + void (*error)(struct _dma_resource *resource); +}; + +/** + * \brief DMA resource structure + */ +struct _dma_resource { + struct _dma_callbacks dma_cb; + void * back; +}; + +/** + * \brief Initialize DMA + * + * This function does low level DMA configuration. + * + * \return initialize status + */ +int32_t _dma_init(void); + +/** + * \brief Set destination address + * + * \param[in] channel DMA channel to set destination address for + * \param[in] dst Destination address + * + * \return setting status + */ +int32_t _dma_set_destination_address(const uint8_t channel, const void *const dst); + +/** + * \brief Set source address + * + * \param[in] channel DMA channel to set source address for + * \param[in] src Source address + * + * \return setting status + */ +int32_t _dma_set_source_address(const uint8_t channel, const void *const src); + +/** + * \brief Enable/disable source address incrementation during DMA transaction + * + * \param[in] channel DMA channel to set source address for + * \param[in] enable True to enable, false to disable + * + * \return status of operation + */ +int32_t _dma_srcinc_enable(const uint8_t channel, const bool enable); + +/** + * \brief Enable/disable Destination address incrementation during DMA transaction + * + * \param[in] channel DMA channel to set destination address for + * \param[in] enable True to enable, false to disable + * + * \return status of operation + */ +int32_t _dma_dstinc_enable(const uint8_t channel, const bool enable); +/** + * \brief Set the amount of data to be transfered per transaction + * + * \param[in] channel DMA channel to set data amount for + * \param[in] amount Data amount + * + * \return status of operation + */ +int32_t _dma_set_data_amount(const uint8_t channel, const uint32_t amount); + +/** + * \brief Trigger DMA transaction on the given channel + * + * \param[in] channel DMA channel to trigger transaction on + * + * \return status of operation + */ +int32_t _dma_enable_transaction(const uint8_t channel, const bool software_trigger); + +/** + * \brief Retrieves DMA resource structure + * + * \param[out] resource The resource to be retrieved + * \param[in] channel DMA channel to retrieve structure for + * + * \return status of operation + */ +int32_t _dma_get_channel_resource(struct _dma_resource **resource, const uint8_t channel); + +/** + * \brief Enable/disable DMA interrupt + * + * \param[in] channel DMA channel to enable/disable interrupt for + * \param[in] type The type of interrupt to disable/enable if applicable + * \param[in] state Enable or disable + */ +void _dma_set_irq_state(const uint8_t channel, const enum _dma_callback_type type, const bool state); + +#ifdef __cplusplus +} +#endif + +#endif /* HPL_DMA_H_INCLUDED */ diff --git a/hal/include/hpl_gpio.h b/hal/include/hpl_gpio.h new file mode 100644 index 0000000..5cdd387 --- /dev/null +++ b/hal/include/hpl_gpio.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief Port 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 _HPL_GPIO_H_INCLUDED +#define _HPL_GPIO_H_INCLUDED + +/** + * \addtogroup HPL Port + * + * \section hpl_port_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +/** + * \brief Macros for the pin and port group, lower 5 + * bits stands for pin number in the group, higher 3 + * bits stands for port group + */ +#define GPIO_PIN(n) (((n)&0x1Fu) << 0) +#define GPIO_PORT(n) ((n) >> 5) +#define GPIO(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu)) +#define GPIO_PIN_FUNCTION_OFF 0xffffffff + +/** + * \brief PORT pull mode settings + */ +enum gpio_pull_mode { GPIO_PULL_OFF, GPIO_PULL_UP, GPIO_PULL_DOWN }; + +/** + * \brief PORT direction settins + */ +enum gpio_direction { GPIO_DIRECTION_OFF, GPIO_DIRECTION_IN, GPIO_DIRECTION_OUT }; + +/** + * \brief PORT group abstraction + */ + +enum gpio_port { GPIO_PORTA, GPIO_PORTB, GPIO_PORTC, GPIO_PORTD, GPIO_PORTE }; + +/** + * \name HPL functions + */ +//@{ +/** + * \brief Port initialization function + * + * Port initialization function should setup the port module based + * on a static configuration file, this function should normally + * not be called directly, but is a part of hal_init() + */ +void _gpio_init(void); + +/** + * \brief Set direction on port with mask + * + * Set data direction for each pin, or disable the pin + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + * \param[in] mask Bit mask where 1 means apply direction setting to the + * corresponding pin + * \param[in] direction GPIO_DIRECTION_OFF = set pin direction to input + * and disable input buffer to disable the pin + * GPIO_DIRECTION_IN = set pin direction to input + * and enable input buffer to enable the pin + * GPIO_DIRECTION_OUT = set pin direction to output + * and disable input buffer + */ +static inline void _gpio_set_direction(const enum gpio_port port, const uint32_t mask, + const enum gpio_direction direction); + +/** + * \brief Set output level on port with mask + * + * Sets output state on pin to high or low with pin masking + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + * \param[in] mask Bit mask where 1 means apply direction setting to + * the corresponding pin + * \param[in] level true = pin level is set to 1 + * false = pin level is set to 0 + */ +static inline void _gpio_set_level(const enum gpio_port port, const uint32_t mask, const bool level); + +/** + * \brief Change output level to the opposite with mask + * + * Change pin output level to the opposite with pin masking + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + * \param[in] mask Bit mask where 1 means apply direction setting to + * the corresponding pin + */ +static inline void _gpio_toggle_level(const enum gpio_port port, const uint32_t mask); + +/** + * \brief Get input levels on all port pins + * + * Get input level on all port pins, will read IN register if configured to + * input and OUT register if configured as output + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + */ +static inline uint32_t _gpio_get_level(const enum gpio_port port); + +/** + * \brief Set pin pull mode + * + * Set pull mode on a single pin + * + * \notice This function will automatically change pin direction to input + * + * \param[in] port Ports are grouped into groups of maximum 32 pins, + * GPIO_PORTA = group 0, GPIO_PORTB = group 1, etc + * \param[in] pin The pin in the group that pull mode should be selected + * for + * \param[in] pull_mode GPIO_PULL_OFF = pull resistor on pin is disabled + * GPIO_PULL_DOWN = pull resistor on pin will pull pin + * level to ground level + * GPIO_PULL_UP = pull resistor on pin will pull pin + * level to VCC + */ +static inline void _gpio_set_pin_pull_mode(const enum gpio_port port, const uint8_t pin, + const enum gpio_pull_mode pull_mode); + +/** + * \brief Set gpio function + * + * Select which function a gpio is used for + * + * \param[in] gpio The gpio to set function for + * \param[in] function The gpio function is given by a 32-bit wide bitfield + * found in the header files for the device + * + */ +static inline void _gpio_set_pin_function(const uint32_t gpio, const uint32_t function); + +#include +//@} + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HPL_GPIO_H_INCLUDED */ diff --git a/hal/include/hpl_init.h b/hal/include/hpl_init.h new file mode 100644 index 0000000..71bf49c --- /dev/null +++ b/hal/include/hpl_init.h @@ -0,0 +1,124 @@ +/** + * \file + * + * \brief Init 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 _HPL_INIT_H_INCLUDED +#define _HPL_INIT_H_INCLUDED + +/** + * \addtogroup HPL Init + * + * \section hpl_init_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name HPL functions + */ +//@{ +/** + * \brief Initializes clock sources + */ +void _sysctrl_init_sources(void); + +/** + * \brief Initializes Power Manager + */ +void _pm_init(void); + +/** + * \brief Initialize generators + */ +void _gclk_init_generators(void); + +/** + * \brief Initialize 32 kHz clock sources + */ +void _osc32kctrl_init_sources(void); + +/** + * \brief Initialize clock sources + */ +void _oscctrl_init_sources(void); + +/** + * \brief Initialize clock sources that need input reference clocks + */ +void _sysctrl_init_referenced_generators(void); + +/** + * \brief Initialize clock sources that need input reference clocks + */ +void _oscctrl_init_referenced_generators(void); + +/** + * \brief Initialize master clock generator + */ +void _mclk_init(void); + +/** + * \brief Initialize clock generator + */ +void _lpmcu_misc_regs_init(void); + +/** + * \brief Initialize clock generator + */ +void _pmc_init(void); + +/** + * \brief Set performance level + * + * \param[in] level The performance level to set + */ +void _set_performance_level(const uint8_t level); + +/** + * \brief Initialize the chip + */ +void _init_chip(void); + +//@} + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HPL_INIT_H_INCLUDED */ diff --git a/hal/include/hpl_irq.h b/hal/include/hpl_irq.h new file mode 100644 index 0000000..2894944 --- /dev/null +++ b/hal/include/hpl_irq.h @@ -0,0 +1,116 @@ +/** + * \file + * + * \brief IRQ 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 _HPL_IRQ_H_INCLUDED +#define _HPL_IRQ_H_INCLUDED + +/** + * \addtogroup HPL IRQ + * + * \section hpl_irq_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief IRQ descriptor + */ +struct _irq_descriptor { + void (*handler)(void *parameter); + void *parameter; +}; + +/** + * \name HPL functions + */ +//@{ +/** + * \brief Retrieve current IRQ number + * + * \return The current IRQ number + */ +uint8_t _irq_get_current(void); + +/** + * \brief Disable the given IRQ + * + * \param[in] n The number of IRQ to disable + */ +void _irq_disable(uint8_t n); + +/** + * \brief Set the given IRQ + * + * \param[in] n The number of IRQ to set + */ +void _irq_set(uint8_t n); + +/** + * \brief Clear the given IRQ + * + * \param[in] n The number of IRQ to clear + */ +void _irq_clear(uint8_t n); + +/** + * \brief Enable the given IRQ + * + * \param[in] n The number of IRQ to enable + */ +void _irq_enable(uint8_t n); + +/** + * \brief Register IRQ handler + * + * \param[in] number The number registered IRQ + * \param[in] irq The pointer to irq handler to register + * + * \return The status of IRQ handler registering + * \retval -1 Passed parameters were invalid + * \retval 0 The registering is completed successfully + */ +void _irq_register(const uint8_t number, struct _irq_descriptor *const irq); +//@} + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HPL_IRQ_H_INCLUDED */ diff --git a/hal/include/hpl_missing_features.h b/hal/include/hpl_missing_features.h new file mode 100644 index 0000000..7071db2 --- /dev/null +++ b/hal/include/hpl_missing_features.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief Family-dependent missing features expected by HAL + * + * Copyright (c) 2016-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 _HPL_MISSING_FEATURES +#define _HPL_MISSING_FEATURES + +#endif /* _HPL_MISSING_FEATURES */ diff --git a/hal/include/hpl_ramecc.h b/hal/include/hpl_ramecc.h new file mode 100644 index 0000000..d79d514 --- /dev/null +++ b/hal/include/hpl_ramecc.h @@ -0,0 +1,100 @@ +/** + * \file + * + * \brief RAMECC related functionality declaration. + * + * Copyright (c) 2016-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 _HPL_RAMECC_H_INCLUDED +#define _HPL_RAMECC_H_INCLUDED + +/** + * \addtogroup HPL RAMECC + * + * \section hpl_ramecc_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief RAMECC callback type + */ +typedef void (*ramecc_cb_t)(const uint32_t data); + +/** + * \brief RAMECC callback types + */ +enum _ramecc_callback_type { RAMECC_DUAL_ERROR_CB, RAMECC_SINGLE_ERROR_CB }; + +/** + * \brief RAMECC interrupt callbacks + */ +struct _ramecc_callbacks { + ramecc_cb_t dual_bit_err; + ramecc_cb_t single_bit_err; +}; + +/** + * \brief RAMECC device structure + */ +struct _ramecc_device { + struct _ramecc_callbacks ramecc_cb; + struct _irq_descriptor irq; +}; + +/** + * \brief Initialize RAMECC + * + * This function does low level RAMECC configuration. + * + * \return initialize status + */ +int32_t _ramecc_init(void); + +/** + * \brief Register RAMECC callback + * + * \param[in] type The type of callback + * \param[in] cb A callback function + */ +void _ramecc_register_callback(const enum _ramecc_callback_type type, ramecc_cb_t cb); + +#ifdef __cplusplus +} +#endif + +#endif /* _HPL_RAMECC_H_INCLUDED */ diff --git a/hal/include/hpl_reset.h b/hal/include/hpl_reset.h new file mode 100644 index 0000000..d627ea6 --- /dev/null +++ b/hal/include/hpl_reset.h @@ -0,0 +1,93 @@ +/** + * \file + * + * \brief Reset 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 _HPL_RESET_H_INCLUDED +#define _HPL_RESET_H_INCLUDED + +/** + * \addtogroup HPL Reset + * + * \section hpl_reset_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#ifndef _UNIT_TEST_ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Reset reason enumeration + * + * The list of possible reset reasons. + */ +enum reset_reason { + RESET_REASON_POR = 1, + RESET_REASON_BOD12 = 2, + RESET_REASON_BOD33 = 4, + RESET_REASON_NVM = 8, + RESET_REASON_EXT = 16, + RESET_REASON_WDT = 32, + RESET_REASON_SYST = 64, + RESET_REASON_BACKUP = 128 +}; + +/** + * \name HPL functions + */ +//@{ +/** + * \brief Retrieve the reset reason + * + * Retrieves the reset reason of the last MCU reset. + * + *\return An enum value indicating the reason of the last reset. + */ +enum reset_reason _get_reset_reason(void); + +/** + * \brief Reset MCU + */ +void _reset_mcu(void); +//@} + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HPL_RESET_H_INCLUDED */ diff --git a/hal/include/hpl_sleep.h b/hal/include/hpl_sleep.h new file mode 100644 index 0000000..6731ec3 --- /dev/null +++ b/hal/include/hpl_sleep.h @@ -0,0 +1,88 @@ +/** + * \file + * + * \brief Sleep 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 _HPL_SLEEP_H_INCLUDED +#define _HPL_SLEEP_H_INCLUDED + +/** + * \addtogroup HPL Sleep + * + * \section hpl_sleep_rev Revision History + * - v1.0.0 Initial Release + * + *@{ + */ + +#ifndef _UNIT_TEST_ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name HPL functions + */ +//@{ +/** + * \brief Set the sleep mode for the device + * + * This function sets the sleep mode for the device. + * For an overview of which systems are disabled in sleep for the different + * sleep modes see datasheet. + * + * \param[in] mode Sleep mode to use + * + * \return the status of a sleep request + * \retval -1 The requested sleep mode was invalid + * \retval 0 The operation completed successfully, sleep mode is set + */ +int32_t _set_sleep_mode(const uint8_t mode); + +/** + * \brief Reset MCU + */ +void _reset_mcu(void); + +/** + * \brief Put MCU to sleep + */ +void _go_to_sleep(void); +//@} + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* _HPL_SLEEP_H_INCLUDED */ diff --git a/hal/include/hpl_usb.h b/hal/include/hpl_usb.h new file mode 100644 index 0000000..2e165d7 --- /dev/null +++ b/hal/include/hpl_usb.h @@ -0,0 +1,270 @@ +/** + * \file + * + * \brief SAM USB HPL + * + * Copyright (c) 2015-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 _HPL_USB_H_INCLUDED +#define _HPL_USB_H_INCLUDED + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \name USB Spec definitions */ +/*@{*/ + +/** Return 8-bit unsigned USB data. */ +#define USB_GET_U8(addr, offset) (((uint8_t *)(addr))[(offset)]) + +/** Return 16-bit unsigned USB data. */ +#define USB_GET_U16(addr, offset) ((((uint8_t *)(addr))[(offset) + 0] << 0) + (((uint8_t *)(addr))[(offset) + 1] << 8)) + +/** Return 32-bit unsigned USB data. */ +#define USB_GET_U32(addr, offset) \ + ((((uint8_t *)(addr))[(offset) + 0] << 0) + (((uint8_t *)(addr))[(offset) + 1] << 8) \ + + (((uint8_t *)(addr))[(offset) + 2] << 16) + (((uint8_t *)(addr))[(offset) + 3] << 32)) + +/** Offset of bmRequestType in USB request buffer. */ +#define USB_bmRequestType_Offset 0 + +/** Offset of bRequest in USB request buffer. */ +#define USB_bRequest_Offset 1 + +/** Offset of wValue in USB request buffer. */ +#define USB_wValue_Offset 2 + +/** Offset of wIndex in USB request buffer. */ +#define USB_wIndex_Offset 4 + +/** Offset of wLength in USB request buffer. */ +#define USB_wLength_Offset 6 + +/** Get value of bmRequestType from USB request. */ +#define USB_GET_bmRequestType(req) USB_GET_U8((req), USB_bmRequestType_Offset) + +/** Get value of bRequest from USB request. */ +#define USB_GET_bRequest(req) USB_GET_U8((req), USB_bRequest_Offset) + +/** Get value of wValue from USB request. */ +#define USB_GET_wValue(req) USB_GET_U16((req), USB_wValue_Offset) + +/** Get value of wIndex from USB request. */ +#define USB_GET_wIndex(req) USB_GET_U16((req), USB_wIndex_Offset) + +/** Get value of wLength from USB request. */ +#define USB_GET_wLength(req) USB_GET_U16((req), USB_wLength_Offset) + +/** USB request IN indication of bmRequestType. */ +#define USB_REQ_TYPE_IN 0x80u + +/** USB endpoint number mask of bEndpointAddress. */ +#define USB_EP_N_MASK 0x0Fu + +/** USB endpoint direction bit of bEndpointAddress. */ +#define USB_EP_DIR 0x80u + +/** Get USB endpoint direction from endpoint address. */ +#define USB_EP_GET_DIR(ep_addr) ((ep_addr)&USB_EP_DIR) + +/** Get USB endpoint number from endpoint address. */ +#define USB_EP_GET_N(ep_addr) ((ep_addr)&USB_EP_N_MASK) + +/** Transfer type in EP descriptor bmAttributes: Control. */ +#define USB_EP_XTYPE_CTRL 0x0 + +/** Transfer type in EP descriptor bmAttributes: Isochronous. */ +#define USB_EP_XTYPE_ISOCH 0x1 + +/** Transfer type in EP descriptor bmAttributes: Bulk. */ +#define USB_EP_XTYPE_BULK 0x2 + +/** Transfer type in EP descriptor bmAttributes: Interrupt. */ +#define USB_EP_XTYPE_INTERRUPT 0x3 + +/** Transfer type mask in EP descriptor bmAttributes. */ +#define USB_EP_XTYPE_MASK 0x3u + +/*@}*/ + +/** \name USB status codes + *@{ + */ +/** USB operation is done successfully. */ +#define USB_OK 0 +/** USB (endpoint) is busy. */ +#define USB_BUSY 1 +/** USB (endpoint) is halted. */ +#define USB_HALTED 2 + +/** General error. */ +#define USB_ERROR 0x10 +/** Operation is denied by hardware (e.g., syncing). */ +#define USB_ERR_DENIED 0x11 +/** Input parameter error. */ +#define USB_ERR_PARAM 0x12 +/** Functionality is not supported (e.g., initialize endpoint without cache to be control). */ +#define USB_ERR_FUNC 0x13 +/** Re-initialize, re-enable ... */ +#define USB_ERR_REDO 0x14 +/** Not enough resource (memory, endpoints ...). */ +#define USB_ERR_ALLOC_FAIL 0x15 +/*@}*/ + +/** USB speed. */ +enum usb_speed { + /** USB Low Speed. */ + USB_SPEED_LS, + /** USB Full Speed. */ + USB_SPEED_FS, + /** USB High Speed. */ + USB_SPEED_HS, + /** USB Super Speed. */ + USB_SPEED_SS +}; + +/** USB transaction type. */ +enum usb_trans_type { + /** USB SETUP transaction. */ + USB_TRANS_SETUP, + /** USB IN transaction. */ + USB_TRANS_IN, + /** USB OUT transaction. */ + USB_TRANS_OUT +}; + +/** USB events that generates the device callbacks. */ +enum usb_event { + /** USB VBus changed, with parameter as present/not present. */ + USB_EV_VBUS, + /** USB RESET detected on bus. */ + USB_EV_RESET, + /** USB wakeup. */ + USB_EV_WAKEUP, + /** USB LPM suspend, with parameter as \ref usb_lpm_attributes. */ + USB_EV_LPM_SUSPEND, + /** USB suspend. */ + USB_EV_SUSPEND, + /** USB error, with parameter as error code. */ + USB_EV_ERROR, + /** Number of USB event types. */ + USB_EV_N +}; + +/** Control action for USB device endpoint stall. */ +enum usb_ep_stall_ctrl { + /** Clear stall of the endpoint. */ + USB_EP_STALL_CLR, + /** Stall the endpoint. */ + USB_EP_STALL_SET, + /** Return the stall status. */ + USB_EP_STALL_GET +}; + +/** Control action for USB device endpoint halt. */ +enum usb_ep_halt_ctrl { + /** Clear halt of the endpoint. */ + USB_EP_HALT_CLR = USB_EP_STALL_CLR, + /** Stall the endpoint. */ + USB_EP_HALT_SET = USB_EP_STALL_SET, + /** Return the halt status. */ + USB_EP_HALT_GET = USB_EP_STALL_GET +}; + +/** USB transactions status codes. */ +enum usb_trans_code { + /** TX or RX has been done without error. */ + USB_TRANS_DONE, + /** The endpoint is stalled. */ + USB_TRANS_STALL, + /** The endpoint transactions are aborted (cancel, control setup/status). */ + USB_TRANS_ABORT, + /** The endpoint transactions are aborted by reset/disable. */ + USB_TRANS_RESET, + /** Error is reported on the endpoint. */ + USB_TRANS_ERROR +}; + +/** Transfer status codes. */ +enum usb_xfer_code { + /** Transfer is done without error, for ctrl it means status packet done. */ + USB_XFER_DONE, + /** For control transfer only, data stage is done without error. */ + USB_XFER_DATA, + /** Endpoint stall is set. */ + USB_XFER_HALT, + /** Endpoint stall is cleared. */ + USB_XFER_UNHALT, + /** Transfer is aborted. */ + USB_XFER_ABORT, + /** Transfer is aborted because endpoint reset/disable. */ + USB_XFER_RESET, + /** There was an error. */ + USB_XFER_ERROR +}; + +/** USB endpoint errors. */ +enum usb_ep_error { + /** No error. */ + USB_EP_NO_ERROR, + /** CRC error. */ + USB_EP_ERR_CRC, + /** Endpoint transfer overflow. */ + USB_EP_ERR_OVERFLOW, + /** Other endpoint errors. */ + USB_EP_ERR_GENERAL +}; + +/** Endpoint transfer state. */ +enum usb_ep_state { + /** Endpoint is disabled. */ + USB_EP_S_DISABLED, + /** Endpoint is not busy. */ + USB_EP_S_IDLE, + /** Control transfer only, endpoint is transferring setup packet. */ + USB_EP_S_X_SETUP, + /** Endpoint is transferring data. */ + USB_EP_S_X_DATA, + /** Control transfer only, endpoint is in status stage. */ + USB_EP_S_X_STATUS, + /** Endpoint is halted. */ + USB_EP_S_HALTED, + /** Endpoint error. */ + USB_EP_S_ERROR +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _HPL_USB_H_INCLUDED */ diff --git a/hal/include/hpl_usb_device.h b/hal/include/hpl_usb_device.h new file mode 100644 index 0000000..43dd17f --- /dev/null +++ b/hal/include/hpl_usb_device.h @@ -0,0 +1,377 @@ +/** + * \file + * + * \brief SAM USB HPL + * + * Copyright (c) 2016-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 _HPL_USB_DEVICE_H_INCLUDED +#define _HPL_USB_DEVICE_H_INCLUDED + +#include +#include "hpl_usb_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** USB Device callback type. */ +enum usb_d_cb_type { + /** USB device SOF callback. */ + USB_D_CB_SOF, + /** USB device events callbacks. */ + USB_D_CB_EVENT, + /** Number of types of USB device callback types. */ + USB_D_CB_N +}; + +/** USB Device endpoint callback type. */ +enum usb_d_ep_cb_type { + /** USB device endpoint setup callback. */ + USB_D_EP_CB_SETUP, + /** USB device endpoint more data callback. */ + USB_D_EP_CB_MORE, + /** USB device endpoint transaction done or error callback. */ + USB_D_EP_CB_XFER, + /** Number of types of USB device endpoint callback types. */ + USB_D_EP_CB_N +}; + +/** Control action for USB device LPM handshake. */ +enum usb_d_lpm_ctrl { + /** No LPM handshake, not supported. */ + USB_D_LPM_DISABLE, + /** ACK the LPM transaction. */ + USB_D_LPM_ACK, + /** NYET the LPM transaction. */ + USB_D_LPM_NYET +}; + +/** + * USB device transfer descriptor. + */ +struct usb_d_transfer { + /** Pointer to data buffer to transfer. + * Note that it's recommended that the buffer is 32-bit aligned since + * some of USB peripheral require this. + */ + uint8_t *buf; + /** Transfer size, in number of bytes. + * Note that it's recommended that the buffer size is 32-bit aligned + * (modeled by 4) since some of USB peripheral require this. + */ + uint32_t size; + /** Endpoint address. */ + uint8_t ep; + /** Append ZLP for IN transfer, wait ZLP for OUT transfer. */ + uint8_t zlp; +}; + +/** USB device transactions status structure. */ +struct usb_d_trans_status { + /** Total data size. */ + uint32_t size; + /** Total transfered data count. */ + uint32_t count; + /** Endpoint address. */ + uint8_t ep; + /** Endpoint type - CTRL/ISO/INT/BULK. */ + uint8_t xtype : 2; + /** Transactions state, busy or not. */ + uint8_t busy : 1; + /** Transactions state, setup received or not. */ + uint8_t setup : 1; + /** Transactions state, stall or not. */ + uint8_t stall : 1; + /** Transactions direction. */ + uint8_t dir : 1; +}; + +/** Prototype function for callback that is invoked on USB device SOF. */ +typedef void (*_usb_d_dev_sof_cb_t)(void); + +/** Prototype function for callback that is invoked on USB device events. */ +typedef void (*_usb_d_dev_event_cb_t)(const enum usb_event, const uint32_t param); + +/** HPL USB device callbacks. */ +struct _usb_d_dev_callbacks { + /** Callback that is invoked on SOF. */ + _usb_d_dev_sof_cb_t sof; + /** Callback that is invoked on USB RESET/WAKEUP/RESUME/SUSPEND. */ + _usb_d_dev_event_cb_t event; +}; + +/** USB device endpoint callbacks. */ +enum usb_d_dev_ep_cb_type { + /** Setup packet is received. */ + USB_D_DEV_EP_CB_SETUP, + /** Try to require more data. */ + USB_D_DEV_EP_CB_MORE, + /** Transaction done OK/ERROR. */ + USB_D_DEV_EP_CB_DONE, + /** Number of device endpoint callbacks. */ + USB_D_DEV_EP_CB_N +}; + +/** + * Callback that is invoked when control SETUP packet has bee received. + * \ref _usb_d_dev_ep_read_req() must be invoked to read setup data, and allow + * IN/OUT transactions on control endpoint. + */ +typedef void (*_usb_d_dev_ep_cb_setup_t)(const uint8_t ep); + +/** Callback that is invoked when buffer is done, but last packet is full size + * packet without ZLP. Return \c true if more data has been requested. */ +typedef bool (*_usb_d_dev_ep_cb_more_t)(const uint8_t ep, const uint32_t transfered); + +/** Callback that is invoked when all data is finished, including background + * transfer, or error happens. */ +typedef void (*_usb_d_dev_ep_cb_done_t)(const uint8_t ep, const int32_t code, const uint32_t transfered); + +/** Callbacks for HPL USB device endpoint. */ +struct _usb_d_dev_ep_callbacks { + /** Callback that is invoked when SETUP packet is received. + * \ref _usb_d_dev_ep_read_req() must be invoked to read setup data, and + * allow IN/OUT transactions on control endpoint. + */ + _usb_d_dev_ep_cb_setup_t setup; + /** Callback that is invoked to check if buffer is NULL and more data is + * required. + * It's called when last packet is full size packet, without + * auto ZLP enabled. + * It could be called when background transfer is still in progress. + */ + _usb_d_dev_ep_cb_more_t more; + /** Callback that is invoked when transaction is done, including background + * transfer, or error occurs. + */ + _usb_d_dev_ep_cb_done_t done; +}; + +/** + * \brief Initialize the USB device instance + * \return Operation result status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t _usb_d_dev_init(void); + +/** + * \brief Deinitialize the USB device instance + * \return Operation result status. + * \retval 0 Success. + * \retval <0 Error code. + */ +void _usb_d_dev_deinit(void); + +/** + * \brief Register callback to handle USB device events + * \param[in] type Callback type. See \ref usb_d_cb_type. + * \param[in] func Pointer to callback function. + * Refer to \ref _usb_d_dev_callbacks for the prototypes. + */ +void _usb_d_dev_register_callback(const enum usb_d_cb_type type, const FUNC_PTR func); + +/** + * \brief Register callback to handle USB device endpoint events + * \param[in] type Callback type. See \ref usb_d_dev_ep_cb_type. + * \param[in] func Pointer to callback function. + * Refer to \ref _usb_d_dev_ep_callbacks for the prototypes. + */ +void _usb_d_dev_register_ep_callback(const enum usb_d_dev_ep_cb_type type, const FUNC_PTR func); + +/** + * \brief Enable the USB device + * \return Operation result status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t _usb_d_dev_enable(void); + +/** + * \brief Disable the USB device + * \return Operation result status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t _usb_d_dev_disable(void); + +/** + * \brief Attach the USB device + */ +void _usb_d_dev_attach(void); + +/** + * \brief Detach the USB device + */ +void _usb_d_dev_detach(void); + +/** + * \brief Send the USB device remote wakeup to host + */ +void _usb_d_dev_send_remotewakeup(void); + +/** + * \brief Get the USB device working speed + * \return USB speed. See \ref usb_speed. + */ +enum usb_speed _usb_d_dev_get_speed(void); + +/** + * \brief Set the USB device address + * \param[in] addr Address to be used. + */ +void _usb_d_dev_set_address(const uint8_t addr); + +/** + * \brief Get the USB device address + * \return Address that is used. + */ +uint8_t _usb_d_dev_get_address(void); + +/** + * \brief Get the USB device frame number + * \return The frame number. + */ +uint16_t _usb_d_dev_get_frame_n(void); + +/** + * \brief Get the USB device micro frame number + * \return The micro frame number inside one frame (0~7). + */ +uint8_t _usb_d_dev_get_uframe_n(void); + +/** + * \brief Initialize and enable the USB device default endpoint 0 + * \param[in] max_pkt_siz Max endpoint size. + * \return Operation result status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t _usb_d_dev_ep0_init(const uint8_t max_pkt_siz); + +/** + * \brief Initialize and enable the USB device endpoint + * \param[in] ep Endpoint address, + * see endpoint descriptor details in USB spec. + * \param[in] attr Endpoint attributes, + * see endpoint descriptor details in USB spec. + * \param[in] max_pkt_siz Endpoint size, + * see endpoint descriptor details in USB spec. + * \return Operation result status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t _usb_d_dev_ep_init(const uint8_t ep, const uint8_t attr, uint16_t max_pkt_siz); + +/** + * \brief Disable and deinitialize the USB device endpoint + + * \param[in] ep The endpoint to deinitialize. + */ +void _usb_d_dev_ep_deinit(const uint8_t ep); + +/** + * \brief Enable the endpoint + * \param[in] ep The endpoint to enable. + * \return Operation result status. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t _usb_d_dev_ep_enable(const uint8_t ep); + +/** + * \brief Disable the endpoint + * \param[in] ep The endpoint to disable. + */ +void _usb_d_dev_ep_disable(const uint8_t ep); + +/** + * \brief Set/Clear/Get USB device endpoint stall status + * \param[in] ep Endpoint address. + * \param[in] ctrl Operation selector. See \ref usb_ep_stall_ctrl. + * \return Operation result or stall status. + * \retval 0 Success or not stall. + * \retval 1 Endpoint is stalled. + * \retval -1 error. + */ +int32_t _usb_d_dev_ep_stall(const uint8_t ep, const enum usb_ep_stall_ctrl ctrl); + +/** + * \brief Read setup request data from specific endpoint + * \param[in] ep Endpoint address. + * \param[out] req_buf Pointer to buffer to locate the setup packet. + * \return Number of bytes or error code. + * \retval <0 error code. + * \retval 0 No setup packet ready for read. + * \retval >0 Size of bytes read, and ready to start IN/OUT. Note that if + * this number is over 8, only first 8 bytes will be copied. + */ +int32_t _usb_d_dev_ep_read_req(const uint8_t ep, uint8_t *req_buf); + +/** + * \brief Start USB device transfer + * + * On different USB peripheral hardware the transaction buffer address and size + * may have different constraints. E.g., some hardware may require input address + * 32-bit aligned, and input size 32-bit aligned. Refer to the corresponding + * hardware usage reference documents. + * The constraints are checked in implementation, with error code returned. + * + * \param[in] trans Pointer to the transaction description. + * \return Operation result status. + * \retval 1 Busy. + * \retval 0 Success. + * \retval <0 Error code. + */ +int32_t _usb_d_dev_ep_trans(const struct usb_d_transfer *trans); + +/** + * \brief Abort pending USB device transaction on specific endpoint + * \param[in] ep Endpoint address to abort. + */ +void _usb_d_dev_ep_abort(const uint8_t ep); + +/** + * \brief Retrieve endpoint status. + * \param[in] ep Endpoint address. + * \param[out] stat Pointer to buffer to fill status description. + * \return Status. + * \retval 2 Packet writing. + * \retval 1 Busy. + * \retval 0 Ready. + * \retval <0 Error code. + */ +int32_t _usb_d_dev_ep_get_status(const uint8_t ep, struct usb_d_trans_status *stat); + +#ifdef __cplusplus +} +#endif + +#endif /* _HPL_USB_DEVICE_H_INCLUDED */ diff --git a/hal/include/hpl_usb_host.h b/hal/include/hpl_usb_host.h new file mode 100644 index 0000000..635950b --- /dev/null +++ b/hal/include/hpl_usb_host.h @@ -0,0 +1,618 @@ +/** + * \file + * + * \brief SAM USB host HPL + * + * Copyright (c) 2016-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 _HPL_USB_HOST_H_INCLUDED +#define _HPL_USB_HOST_H_INCLUDED + +#include +#include +#include "hpl_usb_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Driver version */ +#define USB_H_VERSION 0x00000001 + +/** + * @brief USB HCD callback types + */ +enum usb_h_cb_type { + /** SOF generated */ + USB_H_CB_SOF, + /** Root Hub change detected */ + USB_H_CB_ROOTHUB_CHANGE, + /** Number of USB HCD callback types */ + USB_H_CB_N +}; + +/** + * @brief USB HCD resource strategy + */ +enum usb_h_rsc_strategy { + /** Normal resource allocation, e.g., + * 1 bank for interrupt endpoint, + * 2 bank for bulk endpoint and normal iso endpoint, + * 3 bank for iso high bandwidth endpoint. + */ + USB_H_RSC_NORMAL = false, + /** Minimal resource allocation, e.g., only 1 bank for bulk endpoints */ + USB_H_RSC_MINIMAL = true +}; + +/** + * @brief USB HCD pipe states + */ +enum usb_h_pipe_state { + /** Pipe is free to allocate */ + USB_H_PIPE_S_FREE = 0x00, + /** Pipe is in configuration */ + USB_H_PIPE_S_CFG = 0x01, + /** Pipe is allocated and idle */ + USB_H_PIPE_S_IDLE = 0x02, + /** Pipe in control setup stage */ + USB_H_PIPE_S_SETUP = 0x03, + /** Pipe in data IN stage */ + USB_H_PIPE_S_DATI = 0x05, + /** Pipe in data OUT stage */ + USB_H_PIPE_S_DATO = 0x06, + /** Pipe in data IN ZLP stage */ + USB_H_PIPE_S_ZLPI = 0x07, + /** Pipe in data OUT ZLP stage */ + USB_H_PIPE_S_ZLPO = 0x08, + /** Pipe in control status IN stage */ + USB_H_PIPE_S_STATI = 0x09, + /** Pipe in control status OUT stage */ + USB_H_PIPE_S_STATO = 0x0A, + /** Taken by physical pipe (in process) */ + USB_H_PIPE_S_TAKEN = 0x10 +}; + +/** + * @brief USB HCD status code + */ +enum usb_h_status { + /** OK */ + USB_H_OK = ERR_NONE, + /** Busy */ + USB_H_BUSY = ERR_BUSY, + /** Denied */ + USB_H_DENIED = ERR_DENIED, + /** Timeout */ + USB_H_TIMEOUT = ERR_TIMEOUT, + /** Abort */ + USB_H_ABORT = ERR_ABORTED, + /** Stall protocol */ + USB_H_STALL = ERR_PROTOCOL, + /** Transfer reset by pipe re-configure */ + USB_H_RESET = ERR_REQ_FLUSHED, + /** Argument error */ + USB_H_ERR_ARG = ERR_INVALID_ARG, + /** Operation not supported */ + USB_H_ERR_UNSP_OP = ERR_UNSUPPORTED_OP, + /** No resource */ + USB_H_ERR_NO_RSC = ERR_NO_RESOURCE, + /** Not initialized */ + USB_H_ERR_NOT_INIT = ERR_NOT_INITIALIZED, + /** Some general error */ + USB_H_ERR = ERR_IO +}; + +/** Forward declare for pipe structure */ +struct usb_h_pipe; + +/** Forward declare for driver descriptor structure */ +struct usb_h_desc; + +/** + * \brief Prototyping USB HCD callback of SOF + */ +typedef void (*usb_h_cb_sof_t)(struct usb_h_desc *drv); + +/** + * \brief Prototyping USB HCD callback of root hub changing. + * According to the bitmap size, max port number is 31. + */ +typedef void (*usb_h_cb_roothub_t)(struct usb_h_desc *drv, uint8_t port, uint8_t ftr); + +/** + * Prototyping USB HCD callback of pipe transfer done. + * For control pipe, it's forced to call even if there is no transfer + * in progress, since the pipe size could be changed at run time. + */ +typedef void (*usb_h_pipe_cb_xfer_t)(struct usb_h_pipe *pipe); + +/** Access to max packet size of a pipe */ +#define usb_h_pipe_max_pkt_size(p) (p->max_pkt_size) + +/** Access to device address of a pipe */ +#define usb_h_pipe_dev_addr(p) (p->dev) + +/** Access to endpoint address of a pipe */ +#define usb_h_pipe_ep_addr(p) (p->ep) + +/** Access to state of a pipe */ +#define usb_h_pipe_state(p) (p->x.general.state) + +/** Access to status of a pipe */ +#define usb_h_pipe_status(p) (p->x.general.status) + +/** + * @brief USB Host Controller device structure + */ +struct usb_h_desc { + /** Pointer to hardware base */ + void *hw; + /** Pointer to private data for Host Controller driver */ + void *prvt; + /** Interrupt handling descriptor */ + struct _irq_descriptor irq; + /** Callback of SOF */ + usb_h_cb_sof_t sof_cb; + /** Callback of root hub change */ + usb_h_cb_roothub_t rh_cb; +#if CONF_USB_H_INST_OWNER_SP + /** Extension for the driver owner (upper layer user) */ + void *owner; +#endif +}; + +/** + * @brief Transfer descriptor for control transfer + * + * Timing in USB 2.0 spec.: + * - 9.2.6.1 : USB sets an upper limit of 5 seconds as the upper limit for any + * command to be processed. + * - 9.2.6.3 : if a device receives a SetAddress() request, the device must be + * able to complete processing of the request and be able to + * successfully complete the Status stage of the request within + * 50 ms. + * After successful completion of the Status stage, the device is + * allowed a SetAddress() recovery interval of 2 ms. At the end of + * this interval, the device must be able to accept Setup packets + * addressed to the new address. + * - 9.2.6.4 : For standard device requests that require no Data stage, a device + * must be able to complete the request and be able to successfully + * complete the Status stage of the request within 50 ms of receipt + * of the request. This limitation applies to requests to the + * device, interface, or endpoint. + * For standard device requests that require data stage transfer to + * the host, the device must be able to return the first data packet + * to the host within 500 ms of receipt of the request. For + * subsequent data packets, if any, the device must be able to + * return them within 500 ms of successful completion of the + * transmission of the previous packet. The device must then be + * able to successfully complete the status stage within 50 ms after + * returning the last data packet. + * For standard device requests that require a data stage transfer + * to the device, the 5-second limit applies. + * - 9.2.6.5 : Unless specifically exempted in the class document, all + * class-specific requests must meet the timing limitations for + * standard device requests. + * + * Conclusion: + * 1. Whole request with data: 5 seconds + * 2. Whole request without data: 50 ms + * 3. Data packets: 500 ms + */ +struct usb_h_ctrl_xfer { + /** Pointer to transfer data */ + uint8_t *data; + /** Pointer to setup packet */ + uint8_t *setup; + /** Expected transfer size */ + uint16_t size; + /** Transfer count */ + uint16_t count; + /** Timeout for request, -1 if disable timeout */ + int16_t req_timeout; + /** Timeout between packets + * (500ms for data and 50ms for status), -1 if disabled */ + int16_t pkt_timeout; + /** Packet size during transfer (<= allocate max packet size) */ + uint16_t pkt_size; + + /** Transfer state */ + uint8_t state; + /** Last transfer status */ + int8_t status; +}; + +/** + * @brief Transfer descriptor for bulk / interrupt / iso transfer + */ +struct usb_h_bulk_int_iso_xfer { + /** Expected transfer size */ + uint32_t size; + /** Transfer count */ + uint32_t count; + /** Pointer to transfer data */ + uint8_t *data; + /** Reserved */ + uint16_t reserved[3]; + + /** Transfer state */ + uint8_t state; + /** Last transfer status */ + int8_t status; +}; + +/** + * @brief Transfer descriptor for periodic high bandwidth transfer + */ +struct usb_h_high_bw_xfer { + /** Expected transfer size */ + uint32_t size; + /** Transfer count */ + uint32_t count; + /** Pointer to transfer data */ + uint8_t *data; + /** Micro frame packet sizes */ + uint16_t pkt_size[3]; + + /** Transfer state */ + uint8_t state; + /** Last transfer status */ + int8_t status; +}; + +/** + * @brief General transfer descriptor + */ +struct usb_h_xfer { + /** Reserved for different transfer */ + union { + uint16_t u16[9]; + uint8_t u8[18]; + } reserved; + /** Transfer state */ + uint8_t state; + /** Last transfer status */ + int8_t status; +}; + +/** + * @brief USB Host Controller Driver Pipe structure + */ +struct usb_h_pipe { + /** Pointer to the USB Host Controller Driver */ + struct usb_h_desc *hcd; + /** Pointer to the callback for transfer done */ + usb_h_pipe_cb_xfer_t done; +#if CONF_USB_H_INST_OWNER_SP + /** Pointer to the pipe owner */ + void *owner; +#endif + + /** Endpoint max packet size (bits 10..0) */ + uint16_t max_pkt_size; + /** Device address */ + uint8_t dev; + /** Endpoint address */ + uint8_t ep; + + /** Endpoint interval */ + uint8_t interval; + /** Endpoint type: Control, Isochronous, Bulk or Interrupt */ + uint8_t type; + /** Current toggle (driver dependent) */ + uint8_t toggle; + /** Endpoint number of banks (HW dependent) */ + uint8_t bank : 2; + /** Transfer speed (HW dependent) */ + uint8_t speed : 2; + /** High bandwidth periodic out */ + uint8_t high_bw_out : 1; + /** Uses DMA (on transfer) */ + uint8_t dma : 1; + /** Transfer ZLP support */ + uint8_t zlp : 1; + /** Transfer periodic */ + uint8_t periodic_start : 1; + + /** Transfer status */ + union { + /** General transfer info */ + struct usb_h_xfer general; + /** Control transfer status */ + struct usb_h_ctrl_xfer ctrl; + /** Bulk interrupt iso transfer status */ + struct usb_h_bulk_int_iso_xfer bii; + /** Periodic high bandwidth transfer status */ + struct usb_h_high_bw_xfer hbw; + } x; +}; + +/** + * @brief USB HCD Initialization + * + * @param drv Pointer to the HCD driver instance + * @param[in] hw Pointer to hardware base + * @param[in] prvt The private driver data (implement specific) + * + * @return Operation result status + * @retval ERR_DENIED Hardware has been enabled + * @retval ERR_NONE Operation done successfully + */ +int32_t _usb_h_init(struct usb_h_desc *drv, void *hw, void *prvt); + +/** + * @brief USB HCD de-initialization + * + * @param drv The driver + */ +void _usb_h_deinit(struct usb_h_desc *drv); + +/** + * @brief USB HCD enable + * + * @param drv The driver + */ +void _usb_h_enable(struct usb_h_desc *drv); + +/** + * @brief USB HCD disable + * + * @param drv The driver + */ +void _usb_h_disable(struct usb_h_desc *drv); + +/** + * @brief Register callbacks for USB HCD + * + * @param drv The driver + * @param[in] type The callback type + * @param[in] cb The callback function entry + * + * @return Operation result status + * @retval ERR_INVALID_ARG Argument error + * @retval ERR_NONE Operation done successfully + */ +int32_t _usb_h_register_callback(struct usb_h_desc *drv, enum usb_h_cb_type type, FUNC_PTR cb); + +/** + * @brief Return current frame number + * + * @param drv The driver + * + * @return current frame number + */ +uint16_t _usb_h_get_frame_n(struct usb_h_desc *drv); + +/** + * @brief Return current micro frame number + * + * @param drv The driver + * + * @return current micro frame number + */ +uint8_t _usb_h_get_microframe_n(struct usb_h_desc *drv); + +/** + * @brief Suspend the USB bus + * + * @param drv The driver + */ +void _usb_h_suspend(struct usb_h_desc *drv); + +/** + * @brief Resume the USB bus + * + * @param drv The driver + */ +void _usb_h_resume(struct usb_h_desc *drv); + +/* Root hub related APIs */ + +/** + * \brief Reset the root hub port + * + * \param[in,out] drv Pointer to the USB HCD driver + * \param[in] port Root hub port, ignored if there is only one port + */ +void _usb_h_rh_reset(struct usb_h_desc *drv, uint8_t port); + +/** + * \brief Suspend the root hub port + * + * \param[in,out] drv Pointer to the USB HCD driver + * \param[in] port Root hub port, ignored if there is only one port + */ +void _usb_h_rh_suspend(struct usb_h_desc *drv, uint8_t port); + +/** + * \brief Resume the root hub port + * + * \param[in,out] drv Pointer to the USB HCD driver + * \param[in] port Root hub port, ignored if there is only one port + */ +void _usb_h_rh_resume(struct usb_h_desc *drv, uint8_t port); + +/** + * \brief Root hub or port feature status check + * + * Check USB Spec. for hub status and feature selectors. + * + * \param[in] drv Pointer to the USB HCD driver + * \param[in] port Set to 0 to get hub status, otherwise to get port status + * \param[in] ftr Hub feature/status selector + * (0: connection, 2: suspend, 4: reset, 9: LS, 10: HS) + * + * \return \c true if the status bit is 1 + */ +bool _usb_h_rh_check_status(struct usb_h_desc *drv, uint8_t port, uint8_t ftr); + +/* Pipe transfer functions */ + +/** + * @brief Allocate a pipe for USB host communication + * + * @param drv The USB HCD driver + * @param[in] dev The device address + * @param[in] ep The endpoint address + * @param[in] max_pkt_size The endpoint maximum packet size + * @param[in] attr The endpoint attribute + * @param[in] interval The endpoint interval + * (bInterval of USB Endpoint Descriptor) + * @param[in] speed The transfer speed of the endpoint + * @param[in] minimum_rsc Minimum the resource usage, \sa usb_h_rsc_strategy + * + * @return Pointer to allocated pipe structure instance + * @retval NULL allocation fail + */ +struct usb_h_pipe *_usb_h_pipe_allocate(struct usb_h_desc *drv, uint8_t dev, uint8_t ep, uint16_t max_pkt_size, + uint8_t attr, uint8_t interval, uint8_t speed, bool minimum_rsc); + +/** + * @brief Free an allocated pipe + * + * @param pipe The pipe + * + * @return Operation result status + * @retval ERR_BUSY Pipe is busy, use \ref _usb_h_pipe_abort to abort + * @retval ERR_NONE Operation done successfully + */ +int32_t _usb_h_pipe_free(struct usb_h_pipe *pipe); + +/** + * @brief Modify parameters of an allocated control pipe + * + * @param pipe The pipe + * @param[in] dev The device address + * @param[in] ep The endpoint address + * @param[in] max_pkt_size The maximum packet size, must be equal or + * less than allocated size + * @param[in] speed The working speed + * + * @return Operation result status + * @retval ERR_NOT_INITIALIZED Pipe is not allocated + * @retval ERR_BUSY Pipe is busy transferring + * @retval ERR_INVALID_ARG Argument error + * @retval ERR_UNSUPPORTED_OP Pipe is not control pipe + * @retval ERR_NONE Operation done successfully + */ +int32_t _usb_h_pipe_set_control_param(struct usb_h_pipe *pipe, uint8_t dev, uint8_t ep, uint16_t max_pkt_size, + uint8_t speed); + +/** + * @brief Register transfer callback on a pipe + * + * @param pipe The pipe + * @param[in] cb Transfer callback function + * + * @return Operation result status + * @retval ERR_INVALID_ARG Argument error + * @retval ERR_NONE Operation done successfully + */ +int32_t _usb_h_pipe_register_callback(struct usb_h_pipe *pipe, usb_h_pipe_cb_xfer_t cb); + +/** + * @brief Issue a control transfer (request) on a pipe + * + * \note When there is data stage, timeout between data packets is 500ms, the + * timeout between last data packet and the status packet is 50ms. + * + * @param pipe The pipe + * @param[in] setup Pointer to the setup packet + * @param[in,out] data Pointer to the data buffer + * @param[in] length The data length + * @param[in] timeout Timeout for whole request in ms + * + * @return Operation result status + * @retval ERR_NOT_INITIALIZED Pipe is not allocated + * @retval ERR_BUSY Pipe is busy transferring + * @retval ERR_INVALID_ARG Argument error + * @retval ERR_UNSUPPORTED_OP Pipe is not control pipe + * @retval ERR_NONE Operation done successfully + */ +int32_t _usb_h_control_xfer(struct usb_h_pipe *pipe, uint8_t *setup, uint8_t *data, uint16_t length, int16_t timeout); + +/** + * @brief Issue a bulk / interrupt / iso transfer on a pipe + * + * @param pipe The pipe + * @param[in,out] data Pointer to the data buffer + * @param[in] length The data length + * @param[in] auto_zlp Auto append ZLP for OUT + * + * @return Operation result status + * @retval ERR_NOT_INITIALIZED Pipe is not allocated + * @retval ERR_BUSY Pipe is busy transferring + * @retval ERR_INVALID_ARG Argument error + * @retval ERR_UNSUPPORTED_OP Pipe is control pipe + * @retval ERR_NONE Operation done successfully + */ +int32_t _usb_h_bulk_int_iso_xfer(struct usb_h_pipe *pipe, uint8_t *data, uint32_t length, bool auto_zlp); + +/** + * @brief Issue a periodic high bandwidth output on a pipe + * + * @param pipe The pipe + * @param[in,out] data Pointer to the data buffer + * @param[in] length The data length + * @param[in] trans_pkt_size The transaction packet sizes in a micro frame, + * 0 to use endpoint max packet size + * + * @return Operation result status + * @retval ERR_NOT_INITIALIZED Pipe is not allocated + * @retval ERR_BUSY Pipe is busy transferring + * @retval ERR_INVALID_ARG Argument error + * @retval ERR_UNSUPPORTED_OP Pipe is not high bandwidth periodic pipe, or + * DMA feature not enabled, or + * high bandwidth not enabled + * @retval ERR_NONE Operation done successfully + */ +int32_t _usb_h_high_bw_out(struct usb_h_pipe *pipe, uint8_t *data, uint32_t length, uint16_t trans_pkt_size[3]); + +/** + * @brief Check if pipe is busy transferring + * + * @param pipe The pipe + * + * @return \c true if pipe is busy + */ +bool _usb_h_pipe_is_busy(struct usb_h_pipe *pipe); + +/** + * @brief Abort pending transfer on a pipe + * + * @param pipe The pipe + */ +void _usb_h_pipe_abort(struct usb_h_pipe *pipe); + +#ifdef __cplusplus +} +#endif + +#endif /* _HPL_USB_HOST_H_INCLUDED */ diff --git a/hal/src/hal_atomic.c b/hal/src/hal_atomic.c new file mode 100644 index 0000000..f56418e --- /dev/null +++ b/hal/src/hal_atomic.c @@ -0,0 +1,66 @@ +/** + * \file + * + * \brief Critical sections 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_atomic.h" + +/** + * \brief Driver version + */ +#define DRIVER_VERSION 0x00000001u + +/** + * \brief Disable interrupts, enter critical section + */ +void atomic_enter_critical(hal_atomic_t volatile *atomic) +{ + *atomic = __get_PRIMASK(); + __disable_irq(); + __DMB(); +} + +/** + * \brief Exit atomic section + */ +void atomic_leave_critical(hal_atomic_t volatile *atomic) +{ + __DMB(); + __set_PRIMASK(*atomic); +} + +/** + * \brief Retrieve the current driver version + */ +uint32_t atomic_get_version(void) +{ + return DRIVER_VERSION; +} diff --git a/hal/src/hal_cache.c b/hal/src/hal_cache.c new file mode 100644 index 0000000..b2e75aa --- /dev/null +++ b/hal/src/hal_cache.c @@ -0,0 +1,78 @@ +/** + * \file + * + * \brief HAL cache functionality implementation. + * + * Copyright (c)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 + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include +#include + +/** + * \brief Initialize cache module + */ +int32_t cache_init(void) +{ + return _cmcc_init(); +} + +/** + * \brief Enable cache module + */ +int32_t cache_enable(const void *hw) +{ + return _cmcc_enable(hw); +} + +/** + * \brief Disable cache module + */ +int32_t cache_disable(const void *hw) +{ + return _cmcc_disable(hw); +} + +/** + * \brief Configure cache module + */ +int32_t cache_configure(const void *hw, struct _cache_cfg *cache) +{ + return _cmcc_configure(hw, cache); +} + +/** + * \brief Invalidate entire cache entries + */ +int32_t cache_invalidate_all(const void *hw) +{ + return _cmcc_invalidate_all(hw); +} diff --git a/hal/src/hal_delay.c b/hal/src/hal_delay.c new file mode 100644 index 0000000..6f77cc7 --- /dev/null +++ b/hal/src/hal_delay.c @@ -0,0 +1,80 @@ +/** + * \file + * + * \brief HAL delay 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 +#include +#include +#include "hal_delay.h" +#include + +/** + * \brief Driver version + */ +#define DRIVER_VERSION 0x00000001u + +/** + * \brief The pointer to a hardware instance used by the driver. + */ +static void *hardware; + +/** + * \brief Initialize Delay driver + */ +void delay_init(void *const hw) +{ + _delay_init(hardware = hw); +} + +/** + * \brief Perform delay in us + */ +void delay_us(const uint16_t us) +{ + _delay_cycles(hardware, _get_cycles_for_us(us)); +} + +/** + * \brief Perform delay in ms + */ +void delay_ms(const uint16_t ms) +{ + _delay_cycles(hardware, _get_cycles_for_ms(ms)); +} + +/** + * \brief Retrieve the current driver version + */ +uint32_t delay_get_version(void) +{ + return DRIVER_VERSION; +} diff --git a/hal/src/hal_gpio.c b/hal/src/hal_gpio.c new file mode 100644 index 0000000..00dfea6 --- /dev/null +++ b/hal/src/hal_gpio.c @@ -0,0 +1,44 @@ +/** + * \file + * + * \brief Port + * + * 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_gpio.h" + +/** + * \brief Driver version + */ +#define DRIVER_VERSION 0x00000001u + +uint32_t gpio_get_version(void) +{ + return DRIVER_VERSION; +} diff --git a/hal/src/hal_init.c b/hal/src/hal_init.c new file mode 100644 index 0000000..fb65341 --- /dev/null +++ b/hal/src/hal_init.c @@ -0,0 +1,47 @@ +/** + * \file + * + * \brief HAL initialization 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_init.h" + +/** + * \brief Driver version + */ +#define HAL_INIT_VERSION 0x00000001u + +/** + * \brief Retrieve the current driver version + */ +uint32_t init_get_version(void) +{ + return HAL_INIT_VERSION; +} diff --git a/hal/src/hal_io.c b/hal/src/hal_io.c new file mode 100644 index 0000000..7e8feb0 --- /dev/null +++ b/hal/src/hal_io.c @@ -0,0 +1,63 @@ +/** + * \file + * + * \brief I/O functionality implementation. + * + * Copyright (c) 2015-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 +#include + +/** + * \brief Driver version + */ +#define DRIVER_VERSION 0x00000001u + +uint32_t io_get_version(void) +{ + return DRIVER_VERSION; +} + +/** + * \brief I/O write interface + */ +int32_t io_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length) +{ + ASSERT(io_descr && buf); + return io_descr->write(io_descr, buf, length); +} + +/** + * \brief I/O read interface + */ +int32_t io_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length) +{ + ASSERT(io_descr && buf); + return io_descr->read(io_descr, buf, length); +} diff --git a/hal/src/hal_sleep.c b/hal/src/hal_sleep.c new file mode 100644 index 0000000..89472f1 --- /dev/null +++ b/hal/src/hal_sleep.c @@ -0,0 +1,73 @@ +/** + * \file + * + * \brief Sleep 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_sleep.h" +#include + +/** + * \brief Driver version + */ +#define DRIVER_VERSION 0x00000001u + +/** + * \brief Set the sleep mode of the device and put the MCU to sleep + * + * For an overview of which systems are disabled in sleep for the different + * sleep modes, see the data sheet. + * + * \param[in] mode Sleep mode to use + * + * \return The status of a sleep request + * \retval -1 The requested sleep mode was invalid or not available + * \retval 0 The operation completed successfully, returned after leaving the + * sleep + */ +int sleep(const uint8_t mode) +{ + if (ERR_NONE != _set_sleep_mode(mode)) + return ERR_INVALID_ARG; + + _go_to_sleep(); + + return ERR_NONE; +} + +/** + * \brief Retrieve the current driver version + * + * \return Current driver version + */ +uint32_t sleep_get_version(void) +{ + return DRIVER_VERSION; +} diff --git a/hal/src/hal_usb_device.c b/hal/src/hal_usb_device.c new file mode 100644 index 0000000..aa80ede --- /dev/null +++ b/hal/src/hal_usb_device.c @@ -0,0 +1,592 @@ +/** + * \file + * + * \brief SAM USB device HAL + * + * Copyright (c) 2015-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_usb_device.h" +#include "hal_atomic.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** USB device HAL driver version. */ +#define USB_D_VERSION 0x00000001u + +/** + * Endpoint callbacks for data transfer. + */ +struct usb_d_ep_callbacks { + /** Callback that is invoked when setup packet is received. */ + usb_d_ep_cb_setup_t req; + /** Callback invoked when buffer is done, but last packet is full size + * packet without ZLP. Return \c true if new transfer has been submitted. + */ + usb_d_ep_cb_more_t more; + /** Callback invoked when transfer is finished/halted/aborted or error + * occurs. + */ + usb_d_ep_cb_xfer_t xfer; +}; + +/** + * Endpoint transfer descriptor header. + */ +struct usb_ep_xfer_hdr { + /** Transfer type, reuse \ref usb_ep_type. */ + uint8_t type; + /** Endpoint address. */ + uint8_t ep; + /** Endpoint state. */ + uint8_t state; + /** Last status code. */ + uint8_t status; +}; + +/** + * Transfer descriptor. + */ +struct usb_ep_xfer { + /** General transfer descriptor. */ + struct usb_ep_xfer_hdr hdr; + /** Pointer to data buffer. */ + uint8_t *buf; + /** Transfer size. */ + uint32_t size; + /** Control request packet. */ + uint8_t req[8]; +}; + +/** + * USB device endpoint descriptor. + */ +struct usb_d_ep { + /** On-going transfer on the endpoint. */ + struct usb_ep_xfer xfer; + /** Endpoint callbacks. */ + struct usb_d_ep_callbacks callbacks; +}; + +/** + * USB device HAL driver descriptor. + */ +struct usb_d_descriptor { + /** USB device endpoints. */ + struct usb_d_ep ep[CONF_USB_D_NUM_EP_SP]; +}; + +/** The USB HAL driver descriptor instance. */ +static struct usb_d_descriptor usb_d_inst; + +/** \brief Find the endpoint. + * \param[in] ep Endpoint address. + * \return Index of endpoint descriptor. + * \retval >=0 The index. + * \retval <0 Not found (endpoint is not initialized). + */ +static int8_t _usb_d_find_ep(const uint8_t ep) +{ + int8_t i; + for (i = 0; i < CONF_USB_D_NUM_EP_SP; i++) { + if (usb_d_inst.ep[i].xfer.hdr.ep == ep) { + return i; + } + if (usb_d_inst.ep[i].xfer.hdr.type == USB_EP_XTYPE_CTRL + && (ep & USB_EP_N_MASK) == usb_d_inst.ep[i].xfer.hdr.ep) { + return i; + } + } + return -1; +} + +/** + * \brief Start transactions + * \param[in] ep Endpoint address. + * \param[in] dir Endpoint transfer direction. + * \param[in] buf Pointer to transfer buffer. + * \param[in] size Transfer size. + * \param[in] zlp Auto append ZLP for IN, or wait ZLP for OUT. + */ +static inline int32_t _usb_d_trans(const uint8_t ep, const bool dir, const uint8_t *buf, const uint32_t size, + const uint8_t zlp) +{ + struct usb_d_transfer trans + = {(uint8_t *)buf, size, dir ? (uint8_t)(ep | USB_EP_DIR) : (uint8_t)(ep & USB_EP_N_MASK), zlp}; + + return _usb_d_dev_ep_trans(&trans); +} + +/** + * \brief Dummy callback that returns false + * \param[in] unused0 Unused parameter. + * \param[in] unused1 Unused parameter. + * \param[in] unused2 Unused parameter. + * \return Always \c false. + */ +static bool usb_d_dummy_cb_false(uint32_t unused0, uint32_t unused1, uint32_t unused2) +{ + (void)unused0; + (void)unused1; + (void)unused2; + return false; +} + +/** + * \brief Callback invoked when SETUP packet is ready + * \param[in] ep Endpoint number with transfer direction on bit 8. + */ +static void usb_d_cb_trans_setup(const uint8_t ep) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + uint8_t * req = ept->xfer.req; + + uint8_t n = _usb_d_dev_ep_read_req(ep, req); + if (n != 8) { + _usb_d_dev_ep_stall(ep, USB_EP_STALL_SET); + _usb_d_dev_ep_stall(ep | USB_EP_DIR, USB_EP_STALL_SET); + return; + } + + _usb_d_dev_ep_stall(ep, USB_EP_STALL_CLR); + _usb_d_dev_ep_stall(ep | USB_EP_DIR, USB_EP_STALL_CLR); + ept->xfer.hdr.state = USB_EP_S_IDLE; + if (!ept->callbacks.req(ep, req)) { + ept->xfer.hdr.state = USB_EP_S_HALTED; + _usb_d_dev_ep_stall(ep, USB_EP_STALL_SET); + _usb_d_dev_ep_stall(ep | USB_EP_DIR, USB_EP_STALL_SET); + } +} + +/** + * \brief Callback invoked when request more data + * \param[in] ep Endpoint number with transfer direction on bit 8. + * \param[in] transfered Number of bytes transfered. + */ +static bool usb_d_cb_trans_more(const uint8_t ep, const uint32_t transfered) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + if (ept->xfer.hdr.state == USB_EP_S_X_DATA) { + return ept->callbacks.more(ep, transfered); + } + return false; +} + +/** + * \brief Handles the case that control endpoint transactions are done + * \param[in,out] ept Pointer to endpoint information. + */ +static inline void usb_d_ctrl_trans_done(struct usb_d_ep *ept) +{ + uint8_t state = ept->xfer.hdr.state; + bool req_dir = USB_GET_bmRequestType(ept->xfer.req) & USB_REQ_TYPE_IN; + + if (state == USB_EP_S_X_DATA) { + /* Data stage -> Status stage */ + bool err = ept->callbacks.xfer(ept->xfer.hdr.ep, USB_XFER_DATA, ept->xfer.req); + if (err) { + ept->xfer.hdr.state = USB_EP_S_HALTED; + ept->xfer.hdr.status = USB_XFER_HALT; + _usb_d_dev_ep_stall(req_dir ? ept->xfer.hdr.ep : (ept->xfer.hdr.ep | USB_EP_DIR), USB_EP_STALL_SET); + } else { + ept->xfer.hdr.state = USB_EP_S_X_STATUS; + _usb_d_trans(ept->xfer.hdr.ep, !req_dir, NULL, 0, 1); + } + } else { + /* Status stage done */ + ept->callbacks.xfer(ept->xfer.hdr.ep, USB_XFER_DONE, ept->xfer.req); + ept->xfer.hdr.state = USB_EP_S_X_SETUP; + } +} + +/** + * Callback when USB transactions are finished. + */ +static void _usb_d_cb_trans_done(const uint8_t ep, const int32_t code, const uint32_t transferred) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + + if (code == USB_TRANS_DONE) { + ept->xfer.hdr.status = USB_XFER_DONE; + if (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) { + usb_d_ctrl_trans_done(ept); + return; + } + ept->xfer.hdr.state = USB_EP_S_IDLE; + } else if (code == USB_TRANS_STALL) { + ept->xfer.hdr.status = USB_XFER_HALT; + if (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) { + ept->xfer.hdr.state = USB_EP_S_X_SETUP; + _usb_d_dev_ep_stall(ep, USB_EP_STALL_CLR); + } else { + ept->xfer.hdr.state = USB_EP_S_HALTED; + } + } else if (code == USB_TRANS_ABORT) { + ept->xfer.hdr.status = USB_XFER_ABORT; + if (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) { + ept->xfer.hdr.state = USB_EP_S_X_SETUP; + return; + } + ept->xfer.hdr.state = USB_EP_S_IDLE; + } else if (code == USB_TRANS_RESET) { + ept->xfer.hdr.state = USB_EP_S_DISABLED; + ept->xfer.hdr.status = USB_XFER_RESET; + } else { + ept->xfer.hdr.state = USB_EP_S_ERROR; + ept->xfer.hdr.status = USB_XFER_ERROR; + } + + ept->callbacks.xfer(ep, (enum usb_xfer_code)ept->xfer.hdr.status, (void *)transferred); +} + +int32_t usb_d_init(void) +{ + int32_t rc = _usb_d_dev_init(); + uint8_t i; + if (rc < 0) { + return rc; + } + memset(usb_d_inst.ep, 0x00, sizeof(struct usb_d_ep) * CONF_USB_D_NUM_EP_SP); + for (i = 0; i < CONF_USB_D_NUM_EP_SP; i++) { + usb_d_inst.ep[i].xfer.hdr.ep = 0xFF; + usb_d_inst.ep[i].callbacks.req = (usb_d_ep_cb_setup_t)usb_d_dummy_cb_false; + usb_d_inst.ep[i].callbacks.more = (usb_d_ep_cb_more_t)usb_d_dummy_cb_false; + usb_d_inst.ep[i].callbacks.xfer = (usb_d_ep_cb_xfer_t)usb_d_dummy_cb_false; + } + /* Handles device driver endpoint callbacks to build transfer. */ + _usb_d_dev_register_ep_callback(USB_D_DEV_EP_CB_SETUP, (FUNC_PTR)usb_d_cb_trans_setup); + _usb_d_dev_register_ep_callback(USB_D_DEV_EP_CB_MORE, (FUNC_PTR)usb_d_cb_trans_more); + _usb_d_dev_register_ep_callback(USB_D_DEV_EP_CB_DONE, (FUNC_PTR)_usb_d_cb_trans_done); + return ERR_NONE; +} + +void usb_d_deinit(void) +{ + _usb_d_dev_deinit(); +} + +void usb_d_register_callback(const enum usb_d_cb_type type, const FUNC_PTR func) +{ + /* Directly uses device driver callback. */ + _usb_d_dev_register_callback(type, func); +} + +int32_t usb_d_enable(void) +{ + return _usb_d_dev_enable(); +} + +void usb_d_disable(void) +{ + _usb_d_dev_disable(); +} + +void usb_d_attach(void) +{ + _usb_d_dev_attach(); +} + +void usb_d_detach(void) +{ + _usb_d_dev_detach(); +} + +enum usb_speed usb_d_get_speed(void) +{ + return _usb_d_dev_get_speed(); +} + +uint16_t usb_d_get_frame_num(void) +{ + return _usb_d_dev_get_frame_n(); +} + +uint8_t usb_d_get_uframe_num(void) +{ + return _usb_d_dev_get_uframe_n(); +} + +void usb_d_set_address(const uint8_t addr) +{ + _usb_d_dev_set_address(addr); +} + +void usb_d_send_remotewakeup(void) +{ + _usb_d_dev_send_remotewakeup(); +} + +int32_t usb_d_ep0_init(const uint8_t max_pkt_size) +{ + return usb_d_ep_init(0, USB_EP_XTYPE_CTRL, max_pkt_size); +} + +int32_t usb_d_ep_init(const uint8_t ep, const uint8_t attr, const uint16_t max_pkt_size) +{ + int32_t rc; + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + if (ep_index >= 0) { + return -USB_ERR_REDO; + } else { + ep_index = _usb_d_find_ep(0xFF); + if (ep_index < 0) { + return -USB_ERR_ALLOC_FAIL; + } + ept = &usb_d_inst.ep[ep_index]; + } + rc = _usb_d_dev_ep_init(ep, attr, max_pkt_size); + if (rc < 0) { + return rc; + } + ept->xfer.hdr.ep = ep; + ept->xfer.hdr.type = attr & USB_EP_XTYPE_MASK; + return ERR_NONE; +} + +void usb_d_ep_deinit(const uint8_t ep) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + if (ep_index < 0) { + return; + } + _usb_d_dev_ep_deinit(ep); + ept->xfer.hdr.ep = 0xFF; +} + +int32_t usb_d_ep_enable(const uint8_t ep) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + int32_t rc; + if (ep_index < 0) { + return -USB_ERR_PARAM; + } + ept->xfer.hdr.state = (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) ? USB_EP_S_X_SETUP : USB_EP_S_IDLE; + rc = _usb_d_dev_ep_enable(ep); + if (rc < 0) { + ept->xfer.hdr.state = USB_EP_S_DISABLED; + } + return rc; +} + +void usb_d_ep_disable(const uint8_t ep) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + if (ep_index < 0) { + return; + } + _usb_d_dev_ep_disable(ep); + ept->xfer.hdr.state = USB_EP_S_DISABLED; +} + +uint8_t *usb_d_ep_get_req(const uint8_t ep) +{ + int8_t ep_index = _usb_d_find_ep(ep); + if (ep_index < 0) { + return NULL; + } + return usb_d_inst.ep[ep_index].xfer.req; +} + +int32_t usb_d_ep_transfer(const struct usb_d_transfer *xfer) +{ + int8_t ep_index = _usb_d_find_ep(xfer->ep); + struct usb_d_ep * ept = &usb_d_inst.ep[ep_index]; + bool dir = USB_EP_GET_DIR(xfer->ep), zlp = xfer->zlp; + uint32_t len = xfer->size; + int32_t rc; + volatile uint8_t state; + volatile hal_atomic_t flags; + + if (ep_index < 0) { + return -USB_ERR_PARAM; + } + + atomic_enter_critical(&flags); + state = ept->xfer.hdr.state; + if (state == USB_EP_S_IDLE) { + ept->xfer.hdr.state = USB_EP_S_X_DATA; + atomic_leave_critical(&flags); + } else { + atomic_leave_critical(&flags); + switch (state) { + case USB_EP_S_HALTED: + return USB_HALTED; + case USB_EP_S_ERROR: + return -USB_ERROR; + case USB_EP_S_DISABLED: + return -USB_ERR_FUNC; + default: /* USB_EP_S_X_xxxx */ + return USB_BUSY; + } + } + + if (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) { + uint16_t req_len = USB_GET_wLength(ept->xfer.req); + /* SETUP without data: ZLP IN as status. */ + if (req_len == 0) { + dir = true; + len = 0; + zlp = true; + ept->xfer.hdr.state = USB_EP_S_X_STATUS; + } else { + dir = (USB_GET_bmRequestType(ept->xfer.req) & USB_REQ_TYPE_IN); + /* Data length not exceed requested. */ + if (len > req_len) { + len = req_len; + } + if (dir) { + /* Setup -> In */ + zlp = (req_len > len); + } else { + zlp = false; + } + } + } + + rc = _usb_d_trans(xfer->ep, dir, xfer->buf, len, zlp); + return rc; +} + +void usb_d_ep_abort(const uint8_t ep) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + if (ep_index < 0) { + return; + } + _usb_d_dev_ep_abort(ep); + ept->xfer.hdr.state = USB_EP_S_IDLE; + ept->xfer.hdr.status = USB_XFER_ABORT; +} + +int32_t usb_d_ep_get_status(const uint8_t ep, struct usb_d_ep_status *stat) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep * ept = &usb_d_inst.ep[ep_index]; + struct usb_d_trans_status tmp; + uint8_t state = ept->xfer.hdr.state; + if (ep_index < 0) { + return -USB_ERR_PARAM; + } + if (stat) { + /* Check transaction status if transferring data. */ + _usb_d_dev_ep_get_status(ep, &tmp); + stat->ep = ep; + stat->state = state; + stat->code = ept->xfer.hdr.status; + stat->count = tmp.count; + stat->size = tmp.size; + } + switch (state) { + case USB_EP_S_IDLE: + return USB_OK; + case USB_EP_S_HALTED: + return USB_HALTED; + case USB_EP_S_ERROR: + return -USB_ERROR; + case USB_EP_S_DISABLED: + return -USB_ERR_FUNC; + default: + /* Busy */ + return USB_BUSY; + } +} + +static inline int32_t _usb_d_ep_halt_clr(const uint8_t ep) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + int32_t rc; + if (ep_index < 0) { + return -USB_ERR_PARAM; + } + if (_usb_d_dev_ep_stall(ep, USB_EP_STALL_GET)) { + rc = _usb_d_dev_ep_stall(ep, USB_EP_STALL_CLR); + if (rc < 0) { + return rc; + } + ept->xfer.hdr.state = USB_EP_S_IDLE; + ept->xfer.hdr.status = USB_XFER_UNHALT; + ept->callbacks.xfer(ep, USB_XFER_UNHALT, NULL); + } + return ERR_NONE; +} + +int32_t usb_d_ep_halt(const uint8_t ep, const enum usb_ep_halt_ctrl ctrl) +{ + if (ctrl == USB_EP_HALT_CLR) { + return _usb_d_ep_halt_clr(ep); + } else if (ctrl == USB_EP_HALT_SET) { + return _usb_d_dev_ep_stall(ep, USB_EP_STALL_SET); + } else { + return _usb_d_dev_ep_stall(ep, USB_EP_STALL_GET); + } +} + +void usb_d_ep_register_callback(const uint8_t ep, const enum usb_d_ep_cb_type type, const FUNC_PTR func) +{ + int8_t ep_index = _usb_d_find_ep(ep); + struct usb_d_ep *ept = &usb_d_inst.ep[ep_index]; + FUNC_PTR f = func ? (FUNC_PTR)func : (FUNC_PTR)usb_d_dummy_cb_false; + if (ep_index < 0) { + return; + } + switch (type) { + case USB_D_EP_CB_SETUP: + ept->callbacks.req = (usb_d_ep_cb_setup_t)f; + break; + case USB_D_EP_CB_MORE: + ept->callbacks.more = (usb_d_ep_cb_more_t)f; + break; + case USB_D_EP_CB_XFER: + ept->callbacks.xfer = (usb_d_ep_cb_xfer_t)f; + break; + default: + break; + } +} + +uint32_t usb_d_get_version(void) +{ + return USB_D_VERSION; +} + +#ifdef __cplusplus +} +#endif diff --git a/hal/utils/include/compiler.h b/hal/utils/include/compiler.h new file mode 100644 index 0000000..f35db3d --- /dev/null +++ b/hal/utils/include/compiler.h @@ -0,0 +1,64 @@ +/** + * \file + * + * \brief Header + * + * Copyright (c) 2016-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 + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/****************************************************************************** + * compiler.h + * + * Created: 05.05.2014 + * Author: N. Fomin + ******************************************************************************/ + +#ifndef _COMPILER_H +#define _COMPILER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#ifndef _UNIT_TEST_ +#include "parts.h" +#endif +#include "err_codes.h" + +#ifdef __cplusplus +} +#endif + +#endif /* _COMPILER_H */ diff --git a/hal/utils/include/err_codes.h b/hal/utils/include/err_codes.h new file mode 100644 index 0000000..a7aff01 --- /dev/null +++ b/hal/utils/include/err_codes.h @@ -0,0 +1,73 @@ +/** + * \file + * + * \brief Error code definitions. + * + * This file defines various status codes returned by functions, + * indicating success or failure as well as what kind of failure. + * + * Copyright (c) 2015-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 ERROR_CODES_H_INCLUDED +#define ERROR_CODES_H_INCLUDED + +#define ERR_NONE 0 +#define ERR_INVALID_DATA -1 +#define ERR_NO_CHANGE -2 +#define ERR_ABORTED -3 +#define ERR_BUSY -4 +#define ERR_SUSPEND -5 +#define ERR_IO -6 +#define ERR_REQ_FLUSHED -7 +#define ERR_TIMEOUT -8 +#define ERR_BAD_DATA -9 +#define ERR_NOT_FOUND -10 +#define ERR_UNSUPPORTED_DEV -11 +#define ERR_NO_MEMORY -12 +#define ERR_INVALID_ARG -13 +#define ERR_BAD_ADDRESS -14 +#define ERR_BAD_FORMAT -15 +#define ERR_BAD_FRQ -16 +#define ERR_DENIED -17 +#define ERR_ALREADY_INITIALIZED -18 +#define ERR_OVERFLOW -19 +#define ERR_NOT_INITIALIZED -20 +#define ERR_SAMPLERATE_UNAVAILABLE -21 +#define ERR_RESOLUTION_UNAVAILABLE -22 +#define ERR_BAUDRATE_UNAVAILABLE -23 +#define ERR_PACKET_COLLISION -24 +#define ERR_PROTOCOL -25 +#define ERR_PIN_MUX_INVALID -26 +#define ERR_UNSUPPORTED_OP -27 +#define ERR_NO_RESOURCE -28 +#define ERR_NOT_READY -29 +#define ERR_FAILURE -30 +#define ERR_WRONG_LENGTH -31 + +#endif diff --git a/hal/utils/include/events.h b/hal/utils/include/events.h new file mode 100644 index 0000000..3ee891a --- /dev/null +++ b/hal/utils/include/events.h @@ -0,0 +1,54 @@ +/** + * \file + * + * \brief Events declaration. + * + * Copyright (c) 2015-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 _EVENTS_H_INCLUDED +#define _EVENTS_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \brief List of events. Must start with 0, be unique and follow numerical order. + */ +#define EVENT_IS_READY_TO_SLEEP_ID 0 +#define EVENT_PREPARE_TO_SLEEP_ID 1 +#define EVENT_WOKEN_UP_ID 2 + +#ifdef __cplusplus +} +#endif + +#endif /* _EVENTS_H_INCLUDED */ diff --git a/hal/utils/include/parts.h b/hal/utils/include/parts.h new file mode 100644 index 0000000..78c1637 --- /dev/null +++ b/hal/utils/include/parts.h @@ -0,0 +1,41 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (c) 2015-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 ATMEL_PARTS_H +#define ATMEL_PARTS_H + +#include "same54.h" + +#include "hri_e54.h" + +#endif /* ATMEL_PARTS_H */ diff --git a/hal/utils/include/utils.h b/hal/utils/include/utils.h new file mode 100644 index 0000000..1cf2699 --- /dev/null +++ b/hal/utils/include/utils.h @@ -0,0 +1,368 @@ +/** + * \file + * + * \brief Different macros. + * + * 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_H_INCLUDED +#define UTILS_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup doc_driver_hal_utils_macro + * + * @{ + */ + +/** + * \brief Retrieve pointer to parent structure + */ +#define CONTAINER_OF(ptr, type, field_name) ((type *)(((uint8_t *)ptr) - offsetof(type, field_name))) + +/** + * \brief Retrieve array size + */ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +/** + * \brief Emit the compiler pragma \a arg. + * + * \param[in] arg The pragma directive as it would appear after \e \#pragma + * (i.e. not stringified). + */ +#define COMPILER_PRAGMA(arg) _Pragma(#arg) + +/** + * \def COMPILER_PACK_SET(alignment) + * \brief Set maximum alignment for subsequent struct and union definitions to \a alignment. + */ +#define COMPILER_PACK_SET(alignment) COMPILER_PRAGMA(pack(alignment)) + +/** + * \def COMPILER_PACK_RESET() + * \brief Set default alignment for subsequent struct and union definitions. + */ +#define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack()) + +/** + * \brief Set aligned boundary. + */ +#if defined __GNUC__ +#define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) +#elif defined __ICCARM__ +#define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) +#elif defined __CC_ARM +#define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) +#endif + +/** + * \brief Flash located data macros + */ +#if defined __GNUC__ +#define PROGMEM_DECLARE(type, name) const type name +#define PROGMEM_T const +#define PROGMEM_READ_BYTE(x) *((uint8_t *)(x)) +#define PROGMEM_PTR_T const * +#define PROGMEM_STRING_T const uint8_t * +#elif defined __ICCARM__ +#define PROGMEM_DECLARE(type, name) const type name +#define PROGMEM_T const +#define PROGMEM_READ_BYTE(x) *((uint8_t *)(x)) +#define PROGMEM_PTR_T const * +#define PROGMEM_STRING_T const uint8_t * +#elif defined __CC_ARM +#define PROGMEM_DECLARE(type, name) const type name +#define PROGMEM_T const +#define PROGMEM_READ_BYTE(x) *((uint8_t *)(x)) +#define PROGMEM_PTR_T const * +#define PROGMEM_STRING_T const uint8_t * +#endif + +/** + * \brief Optimization + */ +#if defined __GNUC__ +#define OPTIMIZE_HIGH __attribute__((optimize(s))) +#elif defined __CC_ARM +#define OPTIMIZE_HIGH _Pragma("O3") +#elif defined __ICCARM__ +#define OPTIMIZE_HIGH _Pragma("optimize=high") +#endif + +/** + * \brief RAM located function attribute + */ +#if defined(__CC_ARM) /* Keil ?Vision 4 */ +#define RAMFUNC __attribute__((section(".ramfunc"))) +#elif defined(__ICCARM__) /* IAR Ewarm 5.41+ */ +#define RAMFUNC __ramfunc +#elif defined(__GNUC__) /* GCC CS3 2009q3-68 */ +#define RAMFUNC __attribute__((section(".ramfunc"))) +#endif + +/** + * \brief No-init section. + * Place a data object or a function in a no-init section. + */ +#if defined(__CC_ARM) +#define NO_INIT(a) __attribute__((zero_init)) +#elif defined(__ICCARM__) +#define NO_INIT(a) __no_init +#elif defined(__GNUC__) +#define NO_INIT(a) __attribute__((section(".no_init"))) +#endif + +/** + * \brief Set user-defined section. + * Place a data object or a function in a user-defined section. + */ +#if defined(__CC_ARM) +#define COMPILER_SECTION(a) __attribute__((__section__(a))) +#elif defined(__ICCARM__) +#define COMPILER_SECTION(a) COMPILER_PRAGMA(location = a) +#elif defined(__GNUC__) +#define COMPILER_SECTION(a) __attribute__((__section__(a))) +#endif + +/** + * \brief Define WEAK attribute. + */ +#if defined(__CC_ARM) /* Keil ?Vision 4 */ +#define WEAK __attribute__((weak)) +#elif defined(__ICCARM__) /* IAR Ewarm 5.41+ */ +#define WEAK __weak +#elif defined(__GNUC__) /* GCC CS3 2009q3-68 */ +#define WEAK __attribute__((weak)) +#endif + +/** + * \brief Pointer to function + */ +typedef void (*FUNC_PTR)(void); + +#define LE_BYTE0(a) ((uint8_t)(a)) +#define LE_BYTE1(a) ((uint8_t)((a) >> 8)) +#define LE_BYTE2(a) ((uint8_t)((a) >> 16)) +#define LE_BYTE3(a) ((uint8_t)((a) >> 24)) + +#define LE_2_U16(p) ((p)[0] + ((p)[1] << 8)) +#define LE_2_U32(p) ((p)[0] + ((p)[1] << 8) + ((p)[2] << 16) + ((p)[3] << 24)) + +/** \name Zero-Bit Counting + * + * Under GCC, __builtin_clz and __builtin_ctz behave like macros when + * applied to constant expressions (values known at compile time), so they are + * more optimized than the use of the corresponding assembly instructions and + * they can be used as constant expressions e.g. to initialize objects having + * static storage duration, and like the corresponding assembly instructions + * when applied to non-constant expressions (values unknown at compile time), so + * they are more optimized than an assembly periphrasis. Hence, clz and ctz + * ensure a possible and optimized behavior for both constant and non-constant + * expressions. + * + * @{ */ + +/** \brief Counts the leading zero bits of the given value considered as a 32-bit integer. + * + * \param[in] u Value of which to count the leading zero bits. + * + * \return The count of leading zero bits in \a u. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +#define clz(u) __builtin_clz(u) +#else +#define clz(u) \ + ( \ + ((u) == 0) \ + ? 32 \ + : ((u) & (1ul << 31)) \ + ? 0 \ + : ((u) & (1ul << 30)) \ + ? 1 \ + : ((u) & (1ul << 29)) \ + ? 2 \ + : ((u) & (1ul << 28)) \ + ? 3 \ + : ((u) & (1ul << 27)) \ + ? 4 \ + : ((u) & (1ul << 26)) \ + ? 5 \ + : ((u) & (1ul << 25)) \ + ? 6 \ + : ((u) & (1ul << 24)) \ + ? 7 \ + : ((u) & (1ul << 23)) \ + ? 8 \ + : ((u) & (1ul << 22)) \ + ? 9 \ + : ((u) & (1ul << 21)) \ + ? 10 \ + : ((u) & (1ul << 20)) \ + ? 11 \ + : ((u) & (1ul << 19)) \ + ? 12 \ + : ((u) & (1ul << 18)) \ + ? 13 \ + : ((u) & (1ul << 17)) ? 14 \ + : ((u) & (1ul << 16)) ? 15 \ + : ((u) & (1ul << 15)) ? 16 \ + : ((u) & (1ul << 14)) ? 17 \ + : ((u) & (1ul << 13)) ? 18 \ + : ((u) & (1ul << 12)) ? 19 \ + : ((u) \ + & (1ul \ + << 11)) \ + ? 20 \ + : ((u) \ + & (1ul \ + << 10)) \ + ? 21 \ + : ((u) \ + & (1ul \ + << 9)) \ + ? 22 \ + : ((u) \ + & (1ul \ + << 8)) \ + ? 23 \ + : ((u) & (1ul << 7)) ? 24 \ + : ((u) & (1ul << 6)) ? 25 \ + : ((u) \ + & (1ul \ + << 5)) \ + ? 26 \ + : ((u) & (1ul << 4)) ? 27 \ + : ((u) & (1ul << 3)) ? 28 \ + : ((u) & (1ul << 2)) ? 29 \ + : ( \ + (u) & (1ul << 1)) \ + ? 30 \ + : 31) +#endif + +/** \brief Counts the trailing zero bits of the given value considered as a 32-bit integer. + * + * \param[in] u Value of which to count the trailing zero bits. + * + * \return The count of trailing zero bits in \a u. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +#define ctz(u) __builtin_ctz(u) +#else +#define ctz(u) \ + ( \ + (u) & (1ul << 0) \ + ? 0 \ + : (u) & (1ul << 1) \ + ? 1 \ + : (u) & (1ul << 2) \ + ? 2 \ + : (u) & (1ul << 3) \ + ? 3 \ + : (u) & (1ul << 4) \ + ? 4 \ + : (u) & (1ul << 5) \ + ? 5 \ + : (u) & (1ul << 6) \ + ? 6 \ + : (u) & (1ul << 7) \ + ? 7 \ + : (u) & (1ul << 8) \ + ? 8 \ + : (u) & (1ul << 9) \ + ? 9 \ + : (u) & (1ul << 10) \ + ? 10 \ + : (u) & (1ul << 11) \ + ? 11 \ + : (u) & (1ul << 12) \ + ? 12 \ + : (u) & (1ul << 13) \ + ? 13 \ + : (u) & (1ul << 14) \ + ? 14 \ + : (u) & (1ul << 15) \ + ? 15 \ + : (u) & (1ul << 16) \ + ? 16 \ + : (u) & (1ul << 17) \ + ? 17 \ + : (u) & (1ul << 18) \ + ? 18 \ + : (u) & (1ul << 19) ? 19 \ + : (u) & (1ul << 20) ? 20 \ + : (u) & (1ul << 21) ? 21 \ + : (u) & (1ul << 22) ? 22 \ + : (u) & (1ul << 23) ? 23 \ + : (u) & (1ul << 24) ? 24 \ + : (u) & (1ul << 25) ? 25 \ + : (u) & (1ul << 26) ? 26 \ + : (u) & (1ul << 27) ? 27 \ + : (u) & (1ul << 28) ? 28 : (u) & (1ul << 29) ? 29 : (u) & (1ul << 30) ? 30 : (u) & (1ul << 31) ? 31 : 32) +#endif +/** @} */ + +/** + * \brief Counts the number of bits in a mask (no more than 32 bits) + * \param[in] mask Mask of which to count the bits. + */ +#define size_of_mask(mask) (32 - clz(mask) - ctz(mask)) + +/** + * \brief Retrieve the start position of bits mask (no more than 32 bits) + * \param[in] mask Mask of which to retrieve the start position. + */ +#define pos_of_mask(mask) ctz(mask) + +/** + * \brief Return division result of a/b and round up the result to the closest + * number divisible by "b" + */ +#define round_up(a, b) (((a)-1) / (b) + 1) + +/** + * \brief Get the minimum of x and y + */ +#define min(x, y) ((x) > (y) ? (y) : (x)) + +/** + * \brief Get the maximum of x and y + */ +#define max(x, y) ((x) > (y) ? (x) : (y)) + +/**@}*/ + +#ifdef __cplusplus +} +#endif +#endif /* UTILS_H_INCLUDED */ diff --git a/hal/utils/include/utils_assert.h b/hal/utils/include/utils_assert.h new file mode 100644 index 0000000..c2328d6 --- /dev/null +++ b/hal/utils/include/utils_assert.h @@ -0,0 +1,93 @@ +/** + * \file + * + * \brief Asserts related functionality. + * + * 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 _ASSERT_H_INCLUDED +#define _ASSERT_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifndef USE_SIMPLE_ASSERT +//# define USE_SIMPLE_ASSERT +#endif + +/** + * \brief Assert macro + * + * This macro is used to throw asserts. It can be mapped to different function + * based on debug level. + * + * \param[in] condition A condition to be checked; + * assert is thrown if the given condition is false + */ +#define ASSERT(condition) ASSERT_IMPL((condition), __FILE__, __LINE__) + +#ifdef DEBUG + +#ifdef USE_SIMPLE_ASSERT +#define ASSERT_IMPL(condition, file, line) \ + if (!(condition)) \ + __asm("BKPT #0"); +#else +#define ASSERT_IMPL(condition, file, line) assert((condition), file, line) +#endif + +#else /* DEBUG */ + +#ifdef USE_SIMPLE_ASSERT +#define ASSERT_IMPL(condition, file, line) ((void)0) +#else +#define ASSERT_IMPL(condition, file, line) ((void)0) +#endif + +#endif /* DEBUG */ + +/** + * \brief Assert function + * + * This function is used to throw asserts. + * + * \param[in] condition A condition to be checked; assert is thrown if the given + * condition is false + * \param[in] file File name + * \param[in] line Line number + */ +void assert(const bool condition, const char *const file, const int line); + +#ifdef __cplusplus +} +#endif +#endif /* _ASSERT_H_INCLUDED */ diff --git a/hal/utils/include/utils_event.h b/hal/utils/include/utils_event.h new file mode 100644 index 0000000..13067c4 --- /dev/null +++ b/hal/utils/include/utils_event.h @@ -0,0 +1,115 @@ +/** + * \file + * + * \brief Events declaration. + * + * Copyright (c) 2015-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_EVENT_H_INCLUDED +#define _UTILS_EVENT_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \brief The maximum amount of events + */ +#define EVENT_MAX_AMOUNT 8 + +/** + * \brief The size of event mask used, it is EVENT_MAX_AMOUNT rounded up to the + * closest number divisible by 8. + */ +#define EVENT_MASK_SIZE (round_up(EVENT_MAX_AMOUNT, 8)) + +/** + * \brief The type of event ID. IDs should start with 0 and be in numerical order. + */ +typedef uint8_t event_id_t; + +/** + * \brief The type of returned parameter. This type is big enough to contain + * pointer to data on any platform. + */ +typedef uintptr_t event_data_t; + +/** + * \brief The type of returned parameter. This type is big enough to contain + * pointer to data on any platform. + */ +typedef void (*event_cb_t)(event_id_t id, event_data_t data); + +/** + * \brief Event structure + */ +struct event { + struct list_element elem; /*! The pointer to next event */ + uint8_t mask[EVENT_MASK_SIZE]; /*! Mask of event IDs callback is called for */ + event_cb_t cb; /*! Callback to be called when an event occurs */ +}; + +/** + * \brief Subscribe to event + * + * \param[in] event The pointer to event structure + * \param[in] id The event ID to subscribe to + * \param[in] cb The callback function to call when the given event occurs + * + * \return The status of subscription + */ +int32_t event_subscribe(struct event *const event, const event_id_t id, event_cb_t cb); + +/** + * \brief Remove event from subscription + * + * \param[in] event The pointer to event structure + * \param[in] id The event ID to remove subscription from + * + * \return The status of subscription removing + */ +int32_t event_unsubscribe(struct event *const event, const event_id_t id); + +/** + * \brief Post event + * + * \param[in] id The event ID to post + * \param[in] data The event data to be passed to event subscribers + */ +void event_post(const event_id_t id, const event_data_t data); + +#ifdef __cplusplus +} +#endif + +#endif /* _UTILS_EVENT_H_INCLUDED */ diff --git a/hal/utils/include/utils_increment_macro.h b/hal/utils/include/utils_increment_macro.h new file mode 100644 index 0000000..464c6cb --- /dev/null +++ b/hal/utils/include/utils_increment_macro.h @@ -0,0 +1,308 @@ +/** + * \file + * + * \brief Increment macro. + * + * 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_INCREMENT_MACRO_H +#define _UTILS_INCREMENT_MACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Compile time increment, result value is entire integer literal + * + * \param[in] val - value to be incremented (254 max) + */ +#define INC_VALUE(val) SP_INC_##val + +// Preprocessor increment implementation +#define SP_INC_0 1 +#define SP_INC_1 2 +#define SP_INC_2 3 +#define SP_INC_3 4 +#define SP_INC_4 5 +#define SP_INC_5 6 +#define SP_INC_6 7 +#define SP_INC_7 8 +#define SP_INC_8 9 +#define SP_INC_9 10 +#define SP_INC_10 11 +#define SP_INC_11 12 +#define SP_INC_12 13 +#define SP_INC_13 14 +#define SP_INC_14 15 +#define SP_INC_15 16 +#define SP_INC_16 17 +#define SP_INC_17 18 +#define SP_INC_18 19 +#define SP_INC_19 20 +#define SP_INC_20 21 +#define SP_INC_21 22 +#define SP_INC_22 23 +#define SP_INC_23 24 +#define SP_INC_24 25 +#define SP_INC_25 26 +#define SP_INC_26 27 +#define SP_INC_27 28 +#define SP_INC_28 29 +#define SP_INC_29 30 +#define SP_INC_30 31 +#define SP_INC_31 32 +#define SP_INC_32 33 +#define SP_INC_33 34 +#define SP_INC_34 35 +#define SP_INC_35 36 +#define SP_INC_36 37 +#define SP_INC_37 38 +#define SP_INC_38 39 +#define SP_INC_39 40 +#define SP_INC_40 41 +#define SP_INC_41 42 +#define SP_INC_42 43 +#define SP_INC_43 44 +#define SP_INC_44 45 +#define SP_INC_45 46 +#define SP_INC_46 47 +#define SP_INC_47 48 +#define SP_INC_48 49 +#define SP_INC_49 50 +#define SP_INC_50 51 +#define SP_INC_51 52 +#define SP_INC_52 53 +#define SP_INC_53 54 +#define SP_INC_54 55 +#define SP_INC_55 56 +#define SP_INC_56 57 +#define SP_INC_57 58 +#define SP_INC_58 59 +#define SP_INC_59 60 +#define SP_INC_60 61 +#define SP_INC_61 62 +#define SP_INC_62 63 +#define SP_INC_63 64 +#define SP_INC_64 65 +#define SP_INC_65 66 +#define SP_INC_66 67 +#define SP_INC_67 68 +#define SP_INC_68 69 +#define SP_INC_69 70 +#define SP_INC_70 71 +#define SP_INC_71 72 +#define SP_INC_72 73 +#define SP_INC_73 74 +#define SP_INC_74 75 +#define SP_INC_75 76 +#define SP_INC_76 77 +#define SP_INC_77 78 +#define SP_INC_78 79 +#define SP_INC_79 80 +#define SP_INC_80 81 +#define SP_INC_81 82 +#define SP_INC_82 83 +#define SP_INC_83 84 +#define SP_INC_84 85 +#define SP_INC_85 86 +#define SP_INC_86 87 +#define SP_INC_87 88 +#define SP_INC_88 89 +#define SP_INC_89 90 +#define SP_INC_90 91 +#define SP_INC_91 92 +#define SP_INC_92 93 +#define SP_INC_93 94 +#define SP_INC_94 95 +#define SP_INC_95 96 +#define SP_INC_96 97 +#define SP_INC_97 98 +#define SP_INC_98 99 +#define SP_INC_99 100 +#define SP_INC_100 101 +#define SP_INC_101 102 +#define SP_INC_102 103 +#define SP_INC_103 104 +#define SP_INC_104 105 +#define SP_INC_105 106 +#define SP_INC_106 107 +#define SP_INC_107 108 +#define SP_INC_108 109 +#define SP_INC_109 110 +#define SP_INC_110 111 +#define SP_INC_111 112 +#define SP_INC_112 113 +#define SP_INC_113 114 +#define SP_INC_114 115 +#define SP_INC_115 116 +#define SP_INC_116 117 +#define SP_INC_117 118 +#define SP_INC_118 119 +#define SP_INC_119 120 +#define SP_INC_120 121 +#define SP_INC_121 122 +#define SP_INC_122 123 +#define SP_INC_123 124 +#define SP_INC_124 125 +#define SP_INC_125 126 +#define SP_INC_126 127 +#define SP_INC_127 128 +#define SP_INC_128 129 +#define SP_INC_129 130 +#define SP_INC_130 131 +#define SP_INC_131 132 +#define SP_INC_132 133 +#define SP_INC_133 134 +#define SP_INC_134 135 +#define SP_INC_135 136 +#define SP_INC_136 137 +#define SP_INC_137 138 +#define SP_INC_138 139 +#define SP_INC_139 140 +#define SP_INC_140 141 +#define SP_INC_141 142 +#define SP_INC_142 143 +#define SP_INC_143 144 +#define SP_INC_144 145 +#define SP_INC_145 146 +#define SP_INC_146 147 +#define SP_INC_147 148 +#define SP_INC_148 149 +#define SP_INC_149 150 +#define SP_INC_150 151 +#define SP_INC_151 152 +#define SP_INC_152 153 +#define SP_INC_153 154 +#define SP_INC_154 155 +#define SP_INC_155 156 +#define SP_INC_156 157 +#define SP_INC_157 158 +#define SP_INC_158 159 +#define SP_INC_159 160 +#define SP_INC_160 161 +#define SP_INC_161 162 +#define SP_INC_162 163 +#define SP_INC_163 164 +#define SP_INC_164 165 +#define SP_INC_165 166 +#define SP_INC_166 167 +#define SP_INC_167 168 +#define SP_INC_168 169 +#define SP_INC_169 170 +#define SP_INC_170 171 +#define SP_INC_171 172 +#define SP_INC_172 173 +#define SP_INC_173 174 +#define SP_INC_174 175 +#define SP_INC_175 176 +#define SP_INC_176 177 +#define SP_INC_177 178 +#define SP_INC_178 179 +#define SP_INC_179 180 +#define SP_INC_180 181 +#define SP_INC_181 182 +#define SP_INC_182 183 +#define SP_INC_183 184 +#define SP_INC_184 185 +#define SP_INC_185 186 +#define SP_INC_186 187 +#define SP_INC_187 188 +#define SP_INC_188 189 +#define SP_INC_189 190 +#define SP_INC_190 191 +#define SP_INC_191 192 +#define SP_INC_192 193 +#define SP_INC_193 194 +#define SP_INC_194 195 +#define SP_INC_195 196 +#define SP_INC_196 197 +#define SP_INC_197 198 +#define SP_INC_198 199 +#define SP_INC_199 200 +#define SP_INC_200 201 +#define SP_INC_201 202 +#define SP_INC_202 203 +#define SP_INC_203 204 +#define SP_INC_204 205 +#define SP_INC_205 206 +#define SP_INC_206 207 +#define SP_INC_207 208 +#define SP_INC_208 209 +#define SP_INC_209 210 +#define SP_INC_210 211 +#define SP_INC_211 212 +#define SP_INC_212 213 +#define SP_INC_213 214 +#define SP_INC_214 215 +#define SP_INC_215 216 +#define SP_INC_216 217 +#define SP_INC_217 218 +#define SP_INC_218 219 +#define SP_INC_219 220 +#define SP_INC_220 221 +#define SP_INC_221 222 +#define SP_INC_222 223 +#define SP_INC_223 224 +#define SP_INC_224 225 +#define SP_INC_225 226 +#define SP_INC_226 227 +#define SP_INC_227 228 +#define SP_INC_228 229 +#define SP_INC_229 230 +#define SP_INC_230 231 +#define SP_INC_231 232 +#define SP_INC_232 233 +#define SP_INC_233 234 +#define SP_INC_234 235 +#define SP_INC_235 236 +#define SP_INC_236 237 +#define SP_INC_237 238 +#define SP_INC_238 239 +#define SP_INC_239 240 +#define SP_INC_240 241 +#define SP_INC_241 242 +#define SP_INC_242 243 +#define SP_INC_243 244 +#define SP_INC_244 245 +#define SP_INC_245 246 +#define SP_INC_246 247 +#define SP_INC_247 248 +#define SP_INC_248 249 +#define SP_INC_249 250 +#define SP_INC_250 251 +#define SP_INC_251 252 +#define SP_INC_252 253 +#define SP_INC_253 254 +#define SP_INC_254 255 + +#ifdef __cplusplus +} +#endif +#endif /* _UTILS_INCREMENT_MACRO_H */ diff --git a/hal/utils/include/utils_list.h b/hal/utils/include/utils_list.h new file mode 100644 index 0000000..977e8cc --- /dev/null +++ b/hal/utils/include/utils_list.h @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief List 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_LIST_H_INCLUDED +#define _UTILS_LIST_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup doc_driver_hal_utils_list + * + * @{ + */ + +#include + +/** + * \brief List element type + */ +struct list_element { + struct list_element *next; +}; + +/** + * \brief List head type + */ +struct list_descriptor { + struct list_element *head; +}; + +/** + * \brief Reset list + * + * \param[in] list The pointer to a list descriptor + */ +static inline void list_reset(struct list_descriptor *const list) +{ + list->head = NULL; +} + +/** + * \brief Retrieve list head + * + * \param[in] list The pointer to a list descriptor + * + * \return A pointer to the head of the given list or NULL if the list is + * empty + */ +static inline void *list_get_head(const struct list_descriptor *const list) +{ + return (void *)list->head; +} + +/** + * \brief Retrieve next list head + * + * \param[in] list The pointer to a list element + * + * \return A pointer to the next list element or NULL if there is not next + * element + */ +static inline void *list_get_next_element(const void *const element) +{ + return element ? ((struct list_element *)element)->next : NULL; +} + +/** + * \brief Insert an element as list head + * + * \param[in] list The pointer to a list element + * \param[in] element An element to insert to the given list + */ +void list_insert_as_head(struct list_descriptor *const list, void *const element); + +/** + * \brief Insert an element after the given list element + * + * \param[in] after An element to insert after + * \param[in] element Element to insert to the given list + */ +void list_insert_after(void *const after, void *const element); + +/** + * \brief Insert an element at list end + * + * \param[in] after An element to insert after + * \param[in] element Element to insert to the given list + */ +void list_insert_at_end(struct list_descriptor *const list, void *const element); + +/** + * \brief Check whether an element belongs to a list + * + * \param[in] list The pointer to a list + * \param[in] element An element to check + * + * \return The result of checking + * \retval true If the given element is an element of the given list + * \retval false Otherwise + */ +bool is_list_element(const struct list_descriptor *const list, const void *const element); + +/** + * \brief Removes list head + * + * This function removes the list head and sets the next element after the list + * head as a new list head. + * + * \param[in] list The pointer to a list + * + * \return The pointer to the new list head of NULL if the list head is NULL + */ +void *list_remove_head(struct list_descriptor *const list); + +/** + * \brief Removes the list element + * + * \param[in] list The pointer to a list + * \param[in] element An element to remove + * + * \return The result of element removing + * \retval true The given element is removed from the given list + * \retval false The given element is not an element of the given list + */ +bool list_delete_element(struct list_descriptor *const list, const void *const element); + +/**@}*/ + +#ifdef __cplusplus +} +#endif +#endif /* _UTILS_LIST_H_INCLUDED */ diff --git a/hal/utils/include/utils_repeat_macro.h b/hal/utils/include/utils_repeat_macro.h new file mode 100644 index 0000000..89e6f52 --- /dev/null +++ b/hal/utils/include/utils_repeat_macro.h @@ -0,0 +1,322 @@ +/** + * \file + * + * \brief Repeat macro. + * + * 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_REPEAT_MACRO_H +#define _UTILS_REPEAT_MACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * \brief Sequently repeates specified macro for n times (255 max). + * + * Specified macro shall have two arguments: macro(arg, i) + * arg - user defined argument, which have the same value for all iterations. + * i - iteration number; numbering begins from zero and increments on each + * iteration. + * + * \param[in] macro - macro to be repeated + * \param[in] arg - user defined argument for repeated macro + * \param[in] n - total number of iterations (255 max) + */ +#define REPEAT_MACRO(macro, arg, n) REPEAT_MACRO_I(macro, arg, n) + +/* + * \brief Second level is needed to get integer literal from "n" if it is + * defined as macro + */ +#define REPEAT_MACRO_I(macro, arg, n) REPEAT##n(macro, arg, 0) + +#define REPEAT1(macro, arg, n) macro(arg, n) +#define REPEAT2(macro, arg, n) macro(arg, n) REPEAT1(macro, arg, INC_VALUE(n)) +#define REPEAT3(macro, arg, n) macro(arg, n) REPEAT2(macro, arg, INC_VALUE(n)) +#define REPEAT4(macro, arg, n) macro(arg, n) REPEAT3(macro, arg, INC_VALUE(n)) +#define REPEAT5(macro, arg, n) macro(arg, n) REPEAT4(macro, arg, INC_VALUE(n)) +#define REPEAT6(macro, arg, n) macro(arg, n) REPEAT5(macro, arg, INC_VALUE(n)) +#define REPEAT7(macro, arg, n) macro(arg, n) REPEAT6(macro, arg, INC_VALUE(n)) +#define REPEAT8(macro, arg, n) macro(arg, n) REPEAT7(macro, arg, INC_VALUE(n)) +#define REPEAT9(macro, arg, n) macro(arg, n) REPEAT8(macro, arg, INC_VALUE(n)) +#define REPEAT10(macro, arg, n) macro(arg, n) REPEAT9(macro, arg, INC_VALUE(n)) +#define REPEAT11(macro, arg, n) macro(arg, n) REPEAT10(macro, arg, INC_VALUE(n)) +#define REPEAT12(macro, arg, n) macro(arg, n) REPEAT11(macro, arg, INC_VALUE(n)) +#define REPEAT13(macro, arg, n) macro(arg, n) REPEAT12(macro, arg, INC_VALUE(n)) +#define REPEAT14(macro, arg, n) macro(arg, n) REPEAT13(macro, arg, INC_VALUE(n)) +#define REPEAT15(macro, arg, n) macro(arg, n) REPEAT14(macro, arg, INC_VALUE(n)) +#define REPEAT16(macro, arg, n) macro(arg, n) REPEAT15(macro, arg, INC_VALUE(n)) +#define REPEAT17(macro, arg, n) macro(arg, n) REPEAT16(macro, arg, INC_VALUE(n)) +#define REPEAT18(macro, arg, n) macro(arg, n) REPEAT17(macro, arg, INC_VALUE(n)) +#define REPEAT19(macro, arg, n) macro(arg, n) REPEAT18(macro, arg, INC_VALUE(n)) +#define REPEAT20(macro, arg, n) macro(arg, n) REPEAT19(macro, arg, INC_VALUE(n)) +#define REPEAT21(macro, arg, n) macro(arg, n) REPEAT20(macro, arg, INC_VALUE(n)) +#define REPEAT22(macro, arg, n) macro(arg, n) REPEAT21(macro, arg, INC_VALUE(n)) +#define REPEAT23(macro, arg, n) macro(arg, n) REPEAT22(macro, arg, INC_VALUE(n)) +#define REPEAT24(macro, arg, n) macro(arg, n) REPEAT23(macro, arg, INC_VALUE(n)) +#define REPEAT25(macro, arg, n) macro(arg, n) REPEAT24(macro, arg, INC_VALUE(n)) +#define REPEAT26(macro, arg, n) macro(arg, n) REPEAT25(macro, arg, INC_VALUE(n)) +#define REPEAT27(macro, arg, n) macro(arg, n) REPEAT26(macro, arg, INC_VALUE(n)) +#define REPEAT28(macro, arg, n) macro(arg, n) REPEAT27(macro, arg, INC_VALUE(n)) +#define REPEAT29(macro, arg, n) macro(arg, n) REPEAT28(macro, arg, INC_VALUE(n)) +#define REPEAT30(macro, arg, n) macro(arg, n) REPEAT29(macro, arg, INC_VALUE(n)) +#define REPEAT31(macro, arg, n) macro(arg, n) REPEAT30(macro, arg, INC_VALUE(n)) +#define REPEAT32(macro, arg, n) macro(arg, n) REPEAT31(macro, arg, INC_VALUE(n)) +#define REPEAT33(macro, arg, n) macro(arg, n) REPEAT32(macro, arg, INC_VALUE(n)) +#define REPEAT34(macro, arg, n) macro(arg, n) REPEAT33(macro, arg, INC_VALUE(n)) +#define REPEAT35(macro, arg, n) macro(arg, n) REPEAT34(macro, arg, INC_VALUE(n)) +#define REPEAT36(macro, arg, n) macro(arg, n) REPEAT35(macro, arg, INC_VALUE(n)) +#define REPEAT37(macro, arg, n) macro(arg, n) REPEAT36(macro, arg, INC_VALUE(n)) +#define REPEAT38(macro, arg, n) macro(arg, n) REPEAT37(macro, arg, INC_VALUE(n)) +#define REPEAT39(macro, arg, n) macro(arg, n) REPEAT38(macro, arg, INC_VALUE(n)) +#define REPEAT40(macro, arg, n) macro(arg, n) REPEAT39(macro, arg, INC_VALUE(n)) +#define REPEAT41(macro, arg, n) macro(arg, n) REPEAT40(macro, arg, INC_VALUE(n)) +#define REPEAT42(macro, arg, n) macro(arg, n) REPEAT41(macro, arg, INC_VALUE(n)) +#define REPEAT43(macro, arg, n) macro(arg, n) REPEAT42(macro, arg, INC_VALUE(n)) +#define REPEAT44(macro, arg, n) macro(arg, n) REPEAT43(macro, arg, INC_VALUE(n)) +#define REPEAT45(macro, arg, n) macro(arg, n) REPEAT44(macro, arg, INC_VALUE(n)) +#define REPEAT46(macro, arg, n) macro(arg, n) REPEAT45(macro, arg, INC_VALUE(n)) +#define REPEAT47(macro, arg, n) macro(arg, n) REPEAT46(macro, arg, INC_VALUE(n)) +#define REPEAT48(macro, arg, n) macro(arg, n) REPEAT47(macro, arg, INC_VALUE(n)) +#define REPEAT49(macro, arg, n) macro(arg, n) REPEAT48(macro, arg, INC_VALUE(n)) +#define REPEAT50(macro, arg, n) macro(arg, n) REPEAT49(macro, arg, INC_VALUE(n)) +#define REPEAT51(macro, arg, n) macro(arg, n) REPEAT50(macro, arg, INC_VALUE(n)) +#define REPEAT52(macro, arg, n) macro(arg, n) REPEAT51(macro, arg, INC_VALUE(n)) +#define REPEAT53(macro, arg, n) macro(arg, n) REPEAT52(macro, arg, INC_VALUE(n)) +#define REPEAT54(macro, arg, n) macro(arg, n) REPEAT53(macro, arg, INC_VALUE(n)) +#define REPEAT55(macro, arg, n) macro(arg, n) REPEAT54(macro, arg, INC_VALUE(n)) +#define REPEAT56(macro, arg, n) macro(arg, n) REPEAT55(macro, arg, INC_VALUE(n)) +#define REPEAT57(macro, arg, n) macro(arg, n) REPEAT56(macro, arg, INC_VALUE(n)) +#define REPEAT58(macro, arg, n) macro(arg, n) REPEAT57(macro, arg, INC_VALUE(n)) +#define REPEAT59(macro, arg, n) macro(arg, n) REPEAT58(macro, arg, INC_VALUE(n)) +#define REPEAT60(macro, arg, n) macro(arg, n) REPEAT59(macro, arg, INC_VALUE(n)) +#define REPEAT61(macro, arg, n) macro(arg, n) REPEAT60(macro, arg, INC_VALUE(n)) +#define REPEAT62(macro, arg, n) macro(arg, n) REPEAT61(macro, arg, INC_VALUE(n)) +#define REPEAT63(macro, arg, n) macro(arg, n) REPEAT62(macro, arg, INC_VALUE(n)) +#define REPEAT64(macro, arg, n) macro(arg, n) REPEAT63(macro, arg, INC_VALUE(n)) +#define REPEAT65(macro, arg, n) macro(arg, n) REPEAT64(macro, arg, INC_VALUE(n)) +#define REPEAT66(macro, arg, n) macro(arg, n) REPEAT65(macro, arg, INC_VALUE(n)) +#define REPEAT67(macro, arg, n) macro(arg, n) REPEAT66(macro, arg, INC_VALUE(n)) +#define REPEAT68(macro, arg, n) macro(arg, n) REPEAT67(macro, arg, INC_VALUE(n)) +#define REPEAT69(macro, arg, n) macro(arg, n) REPEAT68(macro, arg, INC_VALUE(n)) +#define REPEAT70(macro, arg, n) macro(arg, n) REPEAT69(macro, arg, INC_VALUE(n)) +#define REPEAT71(macro, arg, n) macro(arg, n) REPEAT70(macro, arg, INC_VALUE(n)) +#define REPEAT72(macro, arg, n) macro(arg, n) REPEAT71(macro, arg, INC_VALUE(n)) +#define REPEAT73(macro, arg, n) macro(arg, n) REPEAT72(macro, arg, INC_VALUE(n)) +#define REPEAT74(macro, arg, n) macro(arg, n) REPEAT73(macro, arg, INC_VALUE(n)) +#define REPEAT75(macro, arg, n) macro(arg, n) REPEAT74(macro, arg, INC_VALUE(n)) +#define REPEAT76(macro, arg, n) macro(arg, n) REPEAT75(macro, arg, INC_VALUE(n)) +#define REPEAT77(macro, arg, n) macro(arg, n) REPEAT76(macro, arg, INC_VALUE(n)) +#define REPEAT78(macro, arg, n) macro(arg, n) REPEAT77(macro, arg, INC_VALUE(n)) +#define REPEAT79(macro, arg, n) macro(arg, n) REPEAT78(macro, arg, INC_VALUE(n)) +#define REPEAT80(macro, arg, n) macro(arg, n) REPEAT79(macro, arg, INC_VALUE(n)) +#define REPEAT81(macro, arg, n) macro(arg, n) REPEAT80(macro, arg, INC_VALUE(n)) +#define REPEAT82(macro, arg, n) macro(arg, n) REPEAT81(macro, arg, INC_VALUE(n)) +#define REPEAT83(macro, arg, n) macro(arg, n) REPEAT82(macro, arg, INC_VALUE(n)) +#define REPEAT84(macro, arg, n) macro(arg, n) REPEAT83(macro, arg, INC_VALUE(n)) +#define REPEAT85(macro, arg, n) macro(arg, n) REPEAT84(macro, arg, INC_VALUE(n)) +#define REPEAT86(macro, arg, n) macro(arg, n) REPEAT85(macro, arg, INC_VALUE(n)) +#define REPEAT87(macro, arg, n) macro(arg, n) REPEAT86(macro, arg, INC_VALUE(n)) +#define REPEAT88(macro, arg, n) macro(arg, n) REPEAT87(macro, arg, INC_VALUE(n)) +#define REPEAT89(macro, arg, n) macro(arg, n) REPEAT88(macro, arg, INC_VALUE(n)) +#define REPEAT90(macro, arg, n) macro(arg, n) REPEAT89(macro, arg, INC_VALUE(n)) +#define REPEAT91(macro, arg, n) macro(arg, n) REPEAT90(macro, arg, INC_VALUE(n)) +#define REPEAT92(macro, arg, n) macro(arg, n) REPEAT91(macro, arg, INC_VALUE(n)) +#define REPEAT93(macro, arg, n) macro(arg, n) REPEAT92(macro, arg, INC_VALUE(n)) +#define REPEAT94(macro, arg, n) macro(arg, n) REPEAT93(macro, arg, INC_VALUE(n)) +#define REPEAT95(macro, arg, n) macro(arg, n) REPEAT94(macro, arg, INC_VALUE(n)) +#define REPEAT96(macro, arg, n) macro(arg, n) REPEAT95(macro, arg, INC_VALUE(n)) +#define REPEAT97(macro, arg, n) macro(arg, n) REPEAT96(macro, arg, INC_VALUE(n)) +#define REPEAT98(macro, arg, n) macro(arg, n) REPEAT97(macro, arg, INC_VALUE(n)) +#define REPEAT99(macro, arg, n) macro(arg, n) REPEAT98(macro, arg, INC_VALUE(n)) +#define REPEAT100(macro, arg, n) macro(arg, n) REPEAT99(macro, arg, INC_VALUE(n)) +#define REPEAT101(macro, arg, n) macro(arg, n) REPEAT100(macro, arg, INC_VALUE(n)) +#define REPEAT102(macro, arg, n) macro(arg, n) REPEAT101(macro, arg, INC_VALUE(n)) +#define REPEAT103(macro, arg, n) macro(arg, n) REPEAT102(macro, arg, INC_VALUE(n)) +#define REPEAT104(macro, arg, n) macro(arg, n) REPEAT103(macro, arg, INC_VALUE(n)) +#define REPEAT105(macro, arg, n) macro(arg, n) REPEAT104(macro, arg, INC_VALUE(n)) +#define REPEAT106(macro, arg, n) macro(arg, n) REPEAT105(macro, arg, INC_VALUE(n)) +#define REPEAT107(macro, arg, n) macro(arg, n) REPEAT106(macro, arg, INC_VALUE(n)) +#define REPEAT108(macro, arg, n) macro(arg, n) REPEAT107(macro, arg, INC_VALUE(n)) +#define REPEAT109(macro, arg, n) macro(arg, n) REPEAT108(macro, arg, INC_VALUE(n)) +#define REPEAT110(macro, arg, n) macro(arg, n) REPEAT109(macro, arg, INC_VALUE(n)) +#define REPEAT111(macro, arg, n) macro(arg, n) REPEAT110(macro, arg, INC_VALUE(n)) +#define REPEAT112(macro, arg, n) macro(arg, n) REPEAT111(macro, arg, INC_VALUE(n)) +#define REPEAT113(macro, arg, n) macro(arg, n) REPEAT112(macro, arg, INC_VALUE(n)) +#define REPEAT114(macro, arg, n) macro(arg, n) REPEAT113(macro, arg, INC_VALUE(n)) +#define REPEAT115(macro, arg, n) macro(arg, n) REPEAT114(macro, arg, INC_VALUE(n)) +#define REPEAT116(macro, arg, n) macro(arg, n) REPEAT115(macro, arg, INC_VALUE(n)) +#define REPEAT117(macro, arg, n) macro(arg, n) REPEAT116(macro, arg, INC_VALUE(n)) +#define REPEAT118(macro, arg, n) macro(arg, n) REPEAT117(macro, arg, INC_VALUE(n)) +#define REPEAT119(macro, arg, n) macro(arg, n) REPEAT118(macro, arg, INC_VALUE(n)) +#define REPEAT120(macro, arg, n) macro(arg, n) REPEAT119(macro, arg, INC_VALUE(n)) +#define REPEAT121(macro, arg, n) macro(arg, n) REPEAT120(macro, arg, INC_VALUE(n)) +#define REPEAT122(macro, arg, n) macro(arg, n) REPEAT121(macro, arg, INC_VALUE(n)) +#define REPEAT123(macro, arg, n) macro(arg, n) REPEAT122(macro, arg, INC_VALUE(n)) +#define REPEAT124(macro, arg, n) macro(arg, n) REPEAT123(macro, arg, INC_VALUE(n)) +#define REPEAT125(macro, arg, n) macro(arg, n) REPEAT124(macro, arg, INC_VALUE(n)) +#define REPEAT126(macro, arg, n) macro(arg, n) REPEAT125(macro, arg, INC_VALUE(n)) +#define REPEAT127(macro, arg, n) macro(arg, n) REPEAT126(macro, arg, INC_VALUE(n)) +#define REPEAT128(macro, arg, n) macro(arg, n) REPEAT127(macro, arg, INC_VALUE(n)) +#define REPEAT129(macro, arg, n) macro(arg, n) REPEAT128(macro, arg, INC_VALUE(n)) +#define REPEAT130(macro, arg, n) macro(arg, n) REPEAT129(macro, arg, INC_VALUE(n)) +#define REPEAT131(macro, arg, n) macro(arg, n) REPEAT130(macro, arg, INC_VALUE(n)) +#define REPEAT132(macro, arg, n) macro(arg, n) REPEAT131(macro, arg, INC_VALUE(n)) +#define REPEAT133(macro, arg, n) macro(arg, n) REPEAT132(macro, arg, INC_VALUE(n)) +#define REPEAT134(macro, arg, n) macro(arg, n) REPEAT133(macro, arg, INC_VALUE(n)) +#define REPEAT135(macro, arg, n) macro(arg, n) REPEAT134(macro, arg, INC_VALUE(n)) +#define REPEAT136(macro, arg, n) macro(arg, n) REPEAT135(macro, arg, INC_VALUE(n)) +#define REPEAT137(macro, arg, n) macro(arg, n) REPEAT136(macro, arg, INC_VALUE(n)) +#define REPEAT138(macro, arg, n) macro(arg, n) REPEAT137(macro, arg, INC_VALUE(n)) +#define REPEAT139(macro, arg, n) macro(arg, n) REPEAT138(macro, arg, INC_VALUE(n)) +#define REPEAT140(macro, arg, n) macro(arg, n) REPEAT139(macro, arg, INC_VALUE(n)) +#define REPEAT141(macro, arg, n) macro(arg, n) REPEAT140(macro, arg, INC_VALUE(n)) +#define REPEAT142(macro, arg, n) macro(arg, n) REPEAT141(macro, arg, INC_VALUE(n)) +#define REPEAT143(macro, arg, n) macro(arg, n) REPEAT142(macro, arg, INC_VALUE(n)) +#define REPEAT144(macro, arg, n) macro(arg, n) REPEAT143(macro, arg, INC_VALUE(n)) +#define REPEAT145(macro, arg, n) macro(arg, n) REPEAT144(macro, arg, INC_VALUE(n)) +#define REPEAT146(macro, arg, n) macro(arg, n) REPEAT145(macro, arg, INC_VALUE(n)) +#define REPEAT147(macro, arg, n) macro(arg, n) REPEAT146(macro, arg, INC_VALUE(n)) +#define REPEAT148(macro, arg, n) macro(arg, n) REPEAT147(macro, arg, INC_VALUE(n)) +#define REPEAT149(macro, arg, n) macro(arg, n) REPEAT148(macro, arg, INC_VALUE(n)) +#define REPEAT150(macro, arg, n) macro(arg, n) REPEAT149(macro, arg, INC_VALUE(n)) +#define REPEAT151(macro, arg, n) macro(arg, n) REPEAT150(macro, arg, INC_VALUE(n)) +#define REPEAT152(macro, arg, n) macro(arg, n) REPEAT151(macro, arg, INC_VALUE(n)) +#define REPEAT153(macro, arg, n) macro(arg, n) REPEAT152(macro, arg, INC_VALUE(n)) +#define REPEAT154(macro, arg, n) macro(arg, n) REPEAT153(macro, arg, INC_VALUE(n)) +#define REPEAT155(macro, arg, n) macro(arg, n) REPEAT154(macro, arg, INC_VALUE(n)) +#define REPEAT156(macro, arg, n) macro(arg, n) REPEAT155(macro, arg, INC_VALUE(n)) +#define REPEAT157(macro, arg, n) macro(arg, n) REPEAT156(macro, arg, INC_VALUE(n)) +#define REPEAT158(macro, arg, n) macro(arg, n) REPEAT157(macro, arg, INC_VALUE(n)) +#define REPEAT159(macro, arg, n) macro(arg, n) REPEAT158(macro, arg, INC_VALUE(n)) +#define REPEAT160(macro, arg, n) macro(arg, n) REPEAT159(macro, arg, INC_VALUE(n)) +#define REPEAT161(macro, arg, n) macro(arg, n) REPEAT160(macro, arg, INC_VALUE(n)) +#define REPEAT162(macro, arg, n) macro(arg, n) REPEAT161(macro, arg, INC_VALUE(n)) +#define REPEAT163(macro, arg, n) macro(arg, n) REPEAT162(macro, arg, INC_VALUE(n)) +#define REPEAT164(macro, arg, n) macro(arg, n) REPEAT163(macro, arg, INC_VALUE(n)) +#define REPEAT165(macro, arg, n) macro(arg, n) REPEAT164(macro, arg, INC_VALUE(n)) +#define REPEAT166(macro, arg, n) macro(arg, n) REPEAT165(macro, arg, INC_VALUE(n)) +#define REPEAT167(macro, arg, n) macro(arg, n) REPEAT166(macro, arg, INC_VALUE(n)) +#define REPEAT168(macro, arg, n) macro(arg, n) REPEAT167(macro, arg, INC_VALUE(n)) +#define REPEAT169(macro, arg, n) macro(arg, n) REPEAT168(macro, arg, INC_VALUE(n)) +#define REPEAT170(macro, arg, n) macro(arg, n) REPEAT169(macro, arg, INC_VALUE(n)) +#define REPEAT171(macro, arg, n) macro(arg, n) REPEAT170(macro, arg, INC_VALUE(n)) +#define REPEAT172(macro, arg, n) macro(arg, n) REPEAT171(macro, arg, INC_VALUE(n)) +#define REPEAT173(macro, arg, n) macro(arg, n) REPEAT172(macro, arg, INC_VALUE(n)) +#define REPEAT174(macro, arg, n) macro(arg, n) REPEAT173(macro, arg, INC_VALUE(n)) +#define REPEAT175(macro, arg, n) macro(arg, n) REPEAT174(macro, arg, INC_VALUE(n)) +#define REPEAT176(macro, arg, n) macro(arg, n) REPEAT175(macro, arg, INC_VALUE(n)) +#define REPEAT177(macro, arg, n) macro(arg, n) REPEAT176(macro, arg, INC_VALUE(n)) +#define REPEAT178(macro, arg, n) macro(arg, n) REPEAT177(macro, arg, INC_VALUE(n)) +#define REPEAT179(macro, arg, n) macro(arg, n) REPEAT178(macro, arg, INC_VALUE(n)) +#define REPEAT180(macro, arg, n) macro(arg, n) REPEAT179(macro, arg, INC_VALUE(n)) +#define REPEAT181(macro, arg, n) macro(arg, n) REPEAT180(macro, arg, INC_VALUE(n)) +#define REPEAT182(macro, arg, n) macro(arg, n) REPEAT181(macro, arg, INC_VALUE(n)) +#define REPEAT183(macro, arg, n) macro(arg, n) REPEAT182(macro, arg, INC_VALUE(n)) +#define REPEAT184(macro, arg, n) macro(arg, n) REPEAT183(macro, arg, INC_VALUE(n)) +#define REPEAT185(macro, arg, n) macro(arg, n) REPEAT184(macro, arg, INC_VALUE(n)) +#define REPEAT186(macro, arg, n) macro(arg, n) REPEAT185(macro, arg, INC_VALUE(n)) +#define REPEAT187(macro, arg, n) macro(arg, n) REPEAT186(macro, arg, INC_VALUE(n)) +#define REPEAT188(macro, arg, n) macro(arg, n) REPEAT187(macro, arg, INC_VALUE(n)) +#define REPEAT189(macro, arg, n) macro(arg, n) REPEAT188(macro, arg, INC_VALUE(n)) +#define REPEAT190(macro, arg, n) macro(arg, n) REPEAT189(macro, arg, INC_VALUE(n)) +#define REPEAT191(macro, arg, n) macro(arg, n) REPEAT190(macro, arg, INC_VALUE(n)) +#define REPEAT192(macro, arg, n) macro(arg, n) REPEAT191(macro, arg, INC_VALUE(n)) +#define REPEAT193(macro, arg, n) macro(arg, n) REPEAT192(macro, arg, INC_VALUE(n)) +#define REPEAT194(macro, arg, n) macro(arg, n) REPEAT193(macro, arg, INC_VALUE(n)) +#define REPEAT195(macro, arg, n) macro(arg, n) REPEAT194(macro, arg, INC_VALUE(n)) +#define REPEAT196(macro, arg, n) macro(arg, n) REPEAT195(macro, arg, INC_VALUE(n)) +#define REPEAT197(macro, arg, n) macro(arg, n) REPEAT196(macro, arg, INC_VALUE(n)) +#define REPEAT198(macro, arg, n) macro(arg, n) REPEAT197(macro, arg, INC_VALUE(n)) +#define REPEAT199(macro, arg, n) macro(arg, n) REPEAT198(macro, arg, INC_VALUE(n)) +#define REPEAT200(macro, arg, n) macro(arg, n) REPEAT199(macro, arg, INC_VALUE(n)) +#define REPEAT201(macro, arg, n) macro(arg, n) REPEAT200(macro, arg, INC_VALUE(n)) +#define REPEAT202(macro, arg, n) macro(arg, n) REPEAT201(macro, arg, INC_VALUE(n)) +#define REPEAT203(macro, arg, n) macro(arg, n) REPEAT202(macro, arg, INC_VALUE(n)) +#define REPEAT204(macro, arg, n) macro(arg, n) REPEAT203(macro, arg, INC_VALUE(n)) +#define REPEAT205(macro, arg, n) macro(arg, n) REPEAT204(macro, arg, INC_VALUE(n)) +#define REPEAT206(macro, arg, n) macro(arg, n) REPEAT205(macro, arg, INC_VALUE(n)) +#define REPEAT207(macro, arg, n) macro(arg, n) REPEAT206(macro, arg, INC_VALUE(n)) +#define REPEAT208(macro, arg, n) macro(arg, n) REPEAT207(macro, arg, INC_VALUE(n)) +#define REPEAT209(macro, arg, n) macro(arg, n) REPEAT208(macro, arg, INC_VALUE(n)) +#define REPEAT210(macro, arg, n) macro(arg, n) REPEAT209(macro, arg, INC_VALUE(n)) +#define REPEAT211(macro, arg, n) macro(arg, n) REPEAT210(macro, arg, INC_VALUE(n)) +#define REPEAT212(macro, arg, n) macro(arg, n) REPEAT211(macro, arg, INC_VALUE(n)) +#define REPEAT213(macro, arg, n) macro(arg, n) REPEAT212(macro, arg, INC_VALUE(n)) +#define REPEAT214(macro, arg, n) macro(arg, n) REPEAT213(macro, arg, INC_VALUE(n)) +#define REPEAT215(macro, arg, n) macro(arg, n) REPEAT214(macro, arg, INC_VALUE(n)) +#define REPEAT216(macro, arg, n) macro(arg, n) REPEAT215(macro, arg, INC_VALUE(n)) +#define REPEAT217(macro, arg, n) macro(arg, n) REPEAT216(macro, arg, INC_VALUE(n)) +#define REPEAT218(macro, arg, n) macro(arg, n) REPEAT217(macro, arg, INC_VALUE(n)) +#define REPEAT219(macro, arg, n) macro(arg, n) REPEAT218(macro, arg, INC_VALUE(n)) +#define REPEAT220(macro, arg, n) macro(arg, n) REPEAT219(macro, arg, INC_VALUE(n)) +#define REPEAT221(macro, arg, n) macro(arg, n) REPEAT220(macro, arg, INC_VALUE(n)) +#define REPEAT222(macro, arg, n) macro(arg, n) REPEAT221(macro, arg, INC_VALUE(n)) +#define REPEAT223(macro, arg, n) macro(arg, n) REPEAT222(macro, arg, INC_VALUE(n)) +#define REPEAT224(macro, arg, n) macro(arg, n) REPEAT223(macro, arg, INC_VALUE(n)) +#define REPEAT225(macro, arg, n) macro(arg, n) REPEAT224(macro, arg, INC_VALUE(n)) +#define REPEAT226(macro, arg, n) macro(arg, n) REPEAT225(macro, arg, INC_VALUE(n)) +#define REPEAT227(macro, arg, n) macro(arg, n) REPEAT226(macro, arg, INC_VALUE(n)) +#define REPEAT228(macro, arg, n) macro(arg, n) REPEAT227(macro, arg, INC_VALUE(n)) +#define REPEAT229(macro, arg, n) macro(arg, n) REPEAT228(macro, arg, INC_VALUE(n)) +#define REPEAT230(macro, arg, n) macro(arg, n) REPEAT229(macro, arg, INC_VALUE(n)) +#define REPEAT231(macro, arg, n) macro(arg, n) REPEAT230(macro, arg, INC_VALUE(n)) +#define REPEAT232(macro, arg, n) macro(arg, n) REPEAT231(macro, arg, INC_VALUE(n)) +#define REPEAT233(macro, arg, n) macro(arg, n) REPEAT232(macro, arg, INC_VALUE(n)) +#define REPEAT234(macro, arg, n) macro(arg, n) REPEAT233(macro, arg, INC_VALUE(n)) +#define REPEAT235(macro, arg, n) macro(arg, n) REPEAT234(macro, arg, INC_VALUE(n)) +#define REPEAT236(macro, arg, n) macro(arg, n) REPEAT235(macro, arg, INC_VALUE(n)) +#define REPEAT237(macro, arg, n) macro(arg, n) REPEAT236(macro, arg, INC_VALUE(n)) +#define REPEAT238(macro, arg, n) macro(arg, n) REPEAT237(macro, arg, INC_VALUE(n)) +#define REPEAT239(macro, arg, n) macro(arg, n) REPEAT238(macro, arg, INC_VALUE(n)) +#define REPEAT240(macro, arg, n) macro(arg, n) REPEAT239(macro, arg, INC_VALUE(n)) +#define REPEAT241(macro, arg, n) macro(arg, n) REPEAT240(macro, arg, INC_VALUE(n)) +#define REPEAT242(macro, arg, n) macro(arg, n) REPEAT241(macro, arg, INC_VALUE(n)) +#define REPEAT243(macro, arg, n) macro(arg, n) REPEAT242(macro, arg, INC_VALUE(n)) +#define REPEAT244(macro, arg, n) macro(arg, n) REPEAT243(macro, arg, INC_VALUE(n)) +#define REPEAT245(macro, arg, n) macro(arg, n) REPEAT244(macro, arg, INC_VALUE(n)) +#define REPEAT246(macro, arg, n) macro(arg, n) REPEAT245(macro, arg, INC_VALUE(n)) +#define REPEAT247(macro, arg, n) macro(arg, n) REPEAT246(macro, arg, INC_VALUE(n)) +#define REPEAT248(macro, arg, n) macro(arg, n) REPEAT247(macro, arg, INC_VALUE(n)) +#define REPEAT249(macro, arg, n) macro(arg, n) REPEAT248(macro, arg, INC_VALUE(n)) +#define REPEAT250(macro, arg, n) macro(arg, n) REPEAT249(macro, arg, INC_VALUE(n)) +#define REPEAT251(macro, arg, n) macro(arg, n) REPEAT250(macro, arg, INC_VALUE(n)) +#define REPEAT252(macro, arg, n) macro(arg, n) REPEAT251(macro, arg, INC_VALUE(n)) +#define REPEAT253(macro, arg, n) macro(arg, n) REPEAT252(macro, arg, INC_VALUE(n)) +#define REPEAT254(macro, arg, n) macro(arg, n) REPEAT253(macro, arg, INC_VALUE(n)) +#define REPEAT255(macro, arg, n) macro(arg, n) REPEAT254(macro, arg, INC_VALUE(n)) + +#ifdef __cplusplus +} +#endif + +#include +#endif /* _UTILS_REPEAT_MACRO_H */ diff --git a/hal/utils/src/utils_assert.c b/hal/utils/src/utils_assert.c new file mode 100644 index 0000000..b376c97 --- /dev/null +++ b/hal/utils/src/utils_assert.c @@ -0,0 +1,46 @@ +/** + * \file + * + * \brief Asserts related functionality. + * + * 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 + +/** + * \brief Assert function + */ +void assert(const bool condition, const char *const file, const int line) +{ + if (!(condition)) { + __asm("BKPT #0"); + } + (void)file; + (void)line; +} diff --git a/hal/utils/src/utils_event.c b/hal/utils/src/utils_event.c new file mode 100644 index 0000000..d1af9d0 --- /dev/null +++ b/hal/utils/src/utils_event.c @@ -0,0 +1,125 @@ +/** + * \file + * + * \brief Events implementation. + * + * Copyright (c) 2015-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 +#include +#include + +#define EVENT_WORD_BITS (sizeof(event_word_t) * 8) + +static struct list_descriptor events; +static uint8_t subscribed[EVENT_MASK_SIZE]; + +int32_t event_subscribe(struct event *const event, const event_id_t id, event_cb_t cb) +{ + /* get byte and bit number of the given event in the event mask */ + const uint8_t position = id >> 3; + const uint8_t mask = 1 << (id & 0x7); + + ASSERT(event && cb && (id < EVENT_MAX_AMOUNT)); + + if (event->mask[position] & mask) { + return ERR_NO_CHANGE; /* Already subscribed */ + } + + if (!is_list_element(&events, event)) { + memset(event->mask, 0, EVENT_MASK_SIZE); + list_insert_as_head(&events, event); + } + event->cb = cb; + event->mask[position] |= mask; + + subscribed[position] |= mask; + + return ERR_NONE; +} + +int32_t event_unsubscribe(struct event *const event, const event_id_t id) +{ + /* get byte and bit number of the given event in the event mask */ + const uint8_t position = id >> 3; + const uint8_t mask = 1 << (id & 0x7); + const struct event *current; + uint8_t i; + + ASSERT(event && (id < EVENT_MAX_AMOUNT)); + + if (!(event->mask[position] & mask)) { + return ERR_NO_CHANGE; /* Already unsubscribed */ + } + + event->mask[position] &= ~mask; + + /* Check if there are more subscribers */ + for ((current = (const struct event *)list_get_head(&events)); current; + current = (const struct event *)list_get_next_element(current)) { + if (current->mask[position] & mask) { + break; + } + } + if (!current) { + subscribed[position] &= ~mask; + } + + /* Remove event from the list. Can be unsave, document it! */ + for (i = 0; i < ARRAY_SIZE(event->mask); i++) { + if (event->mask[i]) { + return ERR_NONE; + } + } + list_delete_element(&events, event); + + return ERR_NONE; +} + +void event_post(const event_id_t id, const event_data_t data) +{ + /* get byte and bit number of the given event in the event mask */ + const uint8_t position = id >> 3; + const uint8_t mask = 1 << (id & 0x7); + const struct event *current; + + ASSERT((id < EVENT_MAX_AMOUNT)); + + if (!(subscribed[position] & mask)) { + return; /* No subscribers */ + } + + /* Find all subscribers */ + for ((current = (const struct event *)list_get_head(&events)); current; + current = (const struct event *)list_get_next_element(current)) { + if (current->mask[position] & mask) { + current->cb(id, data); + } + } +} diff --git a/hal/utils/src/utils_list.c b/hal/utils/src/utils_list.c new file mode 100644 index 0000000..4006a01 --- /dev/null +++ b/hal/utils/src/utils_list.c @@ -0,0 +1,136 @@ +/** + * \file + * + * \brief List 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 +#include + +/** + * \brief Check whether element belongs to list + */ +bool is_list_element(const struct list_descriptor *const list, const void *const element) +{ + struct list_element *it; + for (it = list->head; it; it = it->next) { + if (it == element) { + return true; + } + } + + return false; +} + +/** + * \brief Insert an element as list head + */ +void list_insert_as_head(struct list_descriptor *const list, void *const element) +{ + ASSERT(!is_list_element(list, element)); + + ((struct list_element *)element)->next = list->head; + list->head = (struct list_element *)element; +} + +/** + * \brief Insert an element after the given list element + */ +void list_insert_after(void *const after, void *const element) +{ + ((struct list_element *)element)->next = ((struct list_element *)after)->next; + ((struct list_element *)after)->next = (struct list_element *)element; +} + +/** + * \brief Insert an element at list end + */ +void list_insert_at_end(struct list_descriptor *const list, void *const element) +{ + struct list_element *it = list->head; + + ASSERT(!is_list_element(list, element)); + + if (!list->head) { + list->head = (struct list_element *)element; + ((struct list_element *)element)->next = NULL; + return; + } + + while (it->next) { + it = it->next; + } + it->next = (struct list_element *)element; + ((struct list_element *)element)->next = NULL; +} + +/** + * \brief Removes list head + */ +void *list_remove_head(struct list_descriptor *const list) +{ + if (list->head) { + struct list_element *tmp = list->head; + + list->head = list->head->next; + return (void *)tmp; + } + + return NULL; +} + +/** + * \brief Removes list element + */ +bool list_delete_element(struct list_descriptor *const list, const void *const element) +{ + if (!element) { + return false; + } + + if (list->head == element) { + list->head = list->head->next; + return true; + } else { + struct list_element *it = list->head; + + while (it && it->next != element) { + it = it->next; + } + if (it) { + it->next = ((struct list_element *)element)->next; + return true; + } + } + + return false; +} + +//@} diff --git a/hal/utils/src/utils_syscalls.c b/hal/utils/src/utils_syscalls.c new file mode 100644 index 0000000..79e2f1f --- /dev/null +++ b/hal/utils/src/utils_syscalls.c @@ -0,0 +1,152 @@ +/** + * \file + * + * \brief Syscalls for SAM0 (GCC). + * + * Copyright (c) 2015-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 +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#undef errno +extern int errno; +extern int _end; + +extern caddr_t _sbrk(int incr); +extern int link(char *old, char *_new); +extern int _close(int file); +extern int _fstat(int file, struct stat *st); +extern int _isatty(int file); +extern int _lseek(int file, int ptr, int dir); +extern void _exit(int status); +extern void _kill(int pid, int sig); +extern int _getpid(void); + +/** + * \brief Replacement of C library of _sbrk + */ +extern caddr_t _sbrk(int incr) +{ + static unsigned char *heap = NULL; + unsigned char * prev_heap; + + if (heap == NULL) { + heap = (unsigned char *)&_end; + } + prev_heap = heap; + + heap += incr; + + return (caddr_t)prev_heap; +} + +/** + * \brief Replacement of C library of link + */ +extern int link(char *old, char *_new) +{ + (void)old, (void)_new; + return -1; +} + +/** + * \brief Replacement of C library of _close + */ +extern int _close(int file) +{ + (void)file; + return -1; +} + +/** + * \brief Replacement of C library of _fstat + */ +extern int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + + return 0; +} + +/** + * \brief Replacement of C library of _isatty + */ +extern int _isatty(int file) +{ + (void)file; + return 1; +} + +/** + * \brief Replacement of C library of _lseek + */ +extern int _lseek(int file, int ptr, int dir) +{ + (void)file, (void)ptr, (void)dir; + return 0; +} + +/** + * \brief Replacement of C library of _exit + */ +extern void _exit(int status) +{ + printf("Exiting with status %d.\n", status); + + for (;;) + ; +} + +/** + * \brief Replacement of C library of _kill + */ +extern void _kill(int pid, int sig) +{ + (void)pid, (void)sig; + return; +} + +/** + * \brief Replacement of C library of _getpid + */ +extern int _getpid(void) +{ + return -1; +} + +#ifdef __cplusplus +} +#endif -- cgit v1.2.3