aboutsummaryrefslogtreecommitdiffstats
path: root/hal
diff options
context:
space:
mode:
Diffstat (limited to 'hal')
-rw-r--r--hal/documentation/usb_device_async.rst195
-rw-r--r--hal/include/hal_atomic.h120
-rw-r--r--hal/include/hal_cache.h96
-rw-r--r--hal/include/hal_delay.h89
-rw-r--r--hal/include/hal_gpio.h201
-rw-r--r--hal/include/hal_init.h72
-rw-r--r--hal/include/hal_io.h110
-rw-r--r--hal/include/hal_sleep.h74
-rw-r--r--hal/include/hal_usb_device.h295
-rw-r--r--hal/include/hpl_cmcc.h277
-rw-r--r--hal/include/hpl_core.h56
-rw-r--r--hal/include/hpl_delay.h97
-rw-r--r--hal/include/hpl_dma.h166
-rw-r--r--hal/include/hpl_gpio.h185
-rw-r--r--hal/include/hpl_init.h124
-rw-r--r--hal/include/hpl_irq.h116
-rw-r--r--hal/include/hpl_missing_features.h37
-rw-r--r--hal/include/hpl_ramecc.h100
-rw-r--r--hal/include/hpl_reset.h93
-rw-r--r--hal/include/hpl_sleep.h88
-rw-r--r--hal/include/hpl_usb.h270
-rw-r--r--hal/include/hpl_usb_device.h377
-rw-r--r--hal/include/hpl_usb_host.h618
-rw-r--r--hal/src/hal_atomic.c66
-rw-r--r--hal/src/hal_cache.c78
-rw-r--r--hal/src/hal_delay.c80
-rw-r--r--hal/src/hal_gpio.c44
-rw-r--r--hal/src/hal_init.c47
-rw-r--r--hal/src/hal_io.c63
-rw-r--r--hal/src/hal_sleep.c73
-rw-r--r--hal/src/hal_usb_device.c592
-rw-r--r--hal/utils/include/compiler.h64
-rw-r--r--hal/utils/include/err_codes.h73
-rw-r--r--hal/utils/include/events.h54
-rw-r--r--hal/utils/include/parts.h41
-rw-r--r--hal/utils/include/utils.h368
-rw-r--r--hal/utils/include/utils_assert.h93
-rw-r--r--hal/utils/include/utils_event.h115
-rw-r--r--hal/utils/include/utils_increment_macro.h308
-rw-r--r--hal/utils/include/utils_list.h164
-rw-r--r--hal/utils/include/utils_repeat_macro.h322
-rw-r--r--hal/utils/src/utils_assert.c46
-rw-r--r--hal/utils/src/utils_event.c125
-rw-r--r--hal/utils/src/utils_list.c136
-rw-r--r--hal/utils/src/utils_syscalls.c152
45 files changed, 6960 insertions, 0 deletions
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 <http://www.usb.org/developers/docs/usb20_docs>`_)
+ 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 <compiler.h>
+
+#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 <a href="https://www.microchip.com/support/">Microchip Support</a>
+ */
+
+#ifndef HAL_CACHE_H_
+#define HAL_CACHE_H_
+
+#include <hpl_cmcc.h>
+
+#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 <hpl_irq.h>
+#include <hpl_reset.h>
+#include <hpl_sleep.h>
+
+#ifndef _HAL_DELAY_H_INCLUDED
+#define _HAL_DELAY_H_INCLUDED
+
+#include <compiler.h>
+
+#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 <hpl_gpio.h>
+#include <utils_assert.h>
+
+#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 <hpl_init.h>
+
+#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 <compiler.h>
+
+#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 <hpl_sleep.h>
+
+#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 <hpl_usb_device.h>
+
+#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 <a href="https://www.microchip.com/support/">Microchip Support</a>
+ */
+
+#ifndef HPL_CMCC_H_
+#define HPL_CMCC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/**
+ * \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 <compiler.h>
+#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 <compiler.h>
+#include <hpl_irq.h>
+
+#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 <compiler.h>
+
+#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 <hpl_gpio_base.h>
+//@}
+
+#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 <compiler.h>
+
+#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 <compiler.h>
+
+#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 <compiler.h>
+#include <hpl_irq.h>
+
+#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 <compiler.h>
+#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 <compiler.h>
+#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 <compiler.h>
+#include <utils.h>
+
+#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 <hpl_usb.h>
+#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 <hpl_usb.h>
+#include <hpl_irq.h>
+#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 <a href="https://www.microchip.com/support/">Microchip Support</a>
+ */
+
+#include <compiler.h>
+#include <hpl_cmcc.h>
+
+/**
+ * \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 <hpl_irq.h>
+#include <hpl_reset.h>
+#include <hpl_sleep.h>
+#include "hal_delay.h"
+#include <hpl_delay.h>
+
+/**
+ * \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 <hal_io.h>
+#include <utils_assert.h>
+
+/**
+ * \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 <hpl_sleep.h>
+
+/**
+ * \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 <string.h>
+
+#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 <a href="https://www.microchip.com/support/">Microchip Support</a>
+ */
+
+/******************************************************************************
+ * compiler.h
+ *
+ * Created: 05.05.2014
+ * Author: N. Fomin
+ ******************************************************************************/
+
+#ifndef _COMPILER_H
+#define _COMPILER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#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 <compiler.h>
+
+/**
+ * \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 <compiler.h>
+
+#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 <utils.h>
+#include <utils_list.h>
+#include <events.h>
+
+/**
+ * \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 <compiler.h>
+
+/**
+ * \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 <utils_increment_macro.h>
+#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 <utils_assert.h>
+
+/**
+ * \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 <utils_event.h>
+#include <utils_assert.h>
+#include <string.h>
+
+#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 <utils_list.h>
+#include <utils_assert.h>
+
+/**
+ * \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 <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#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