diff options
Diffstat (limited to 'platform/atm2/ATM22xx-x1x/driver')
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/atm_gpio/atm_gpio.h | 198 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/atm_pm/atm_pm.h | 120 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/atm_vkey/atm_vkey.h | 898 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/batt_model/batt_model.h | 86 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/gadc/gadc.h | 122 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/ir/ir.h | 63 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/ir/ir_ctl.h | 147 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/ir/nec_ir.h | 47 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/keyboard/keyboard.h | 60 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/keyboard/keyboard_internal.h | 262 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/led_blink/led_blink.h | 84 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/sw_event/sw_event.h | 91 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/sw_timer/sw_timer.h | 95 | ||||
-rw-r--r-- | platform/atm2/ATM22xx-x1x/driver/timer/timer.h | 266 |
14 files changed, 2539 insertions, 0 deletions
diff --git a/platform/atm2/ATM22xx-x1x/driver/atm_gpio/atm_gpio.h b/platform/atm2/ATM22xx-x1x/driver/atm_gpio/atm_gpio.h new file mode 100644 index 0000000..7a9d647 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/atm_gpio/atm_gpio.h @@ -0,0 +1,198 @@ +/* + *----------------------------------------------------------------------------- + * The confidential and proprietary information contained in this file may + * only be used by a person authorised under and to the extent permitted + * by a subsisting licensing agreement from ARM Limited. + * + * (C) COPYRIGHT 2010-2013 ARM Limited. + * ALL RIGHTS RESERVED + * + * This entire notice must be reproduced on all copies of this file + * and copies of this file may only be made by a person if such person is + * permitted to do so under the terms of a subsisting license agreement + * from ARM Limited. + * + * SVN Information + * + * Checked In : $Date: 2012-05-28 18:02:18 +0100 (Mon, 28 May 2012) $ + * + * Revision : $Revision: 210377 $ + * + * Release Information : Cortex-M System Design Kit-r1p0-00rel0 + *----------------------------------------------------------------------------- + */ +/************************************************************************* + * @file atm_gpio.h + * @brief ATM GPIO Device Driver Header File + * Copyright (C) Atmosic 2019-2020 + ******************************************************************************/ + +/** @addtogroup ATM_GPIO_Driver_definitions + This file defines Atmosic GPIO Driver functions. + @{ + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/// The atm_gpio error code +typedef enum atm_gpio_err_s { + /// No Error + ATM_GPIO_NO_ERR, + /// GPIO invalid + ATM_GPIO_ERR_INVALID, + /// GPIO unconfigured + ATM_GPIO_ERR_UNCFG +} atm_gpio_err_t; + + /** + * @brief Sets up internal config for use as GPIO + * This function needs to be called prior to any GPIO configuration. + * @param[in] gpio pin number + */ + + void atm_gpio_setup(uint8_t gpio); + + /** + * @brief Set GPIO PIN as input. + * @param[in] gpio pin number + */ + + void atm_gpio_set_input(uint8_t gpio); + + /** + * @brief Clear GPIO PIN as input. + * @param[in] gpio pin number + */ + + void atm_gpio_clear_input(uint8_t gpio); + + /** + * @brief Set GPIO PIN as output. + * @param[in] gpio pin number + */ + + void atm_gpio_set_output(uint8_t gpio); + + /** + * @brief Clear GPIO PIN as output. + * @param[in] gpio pin number + */ + + void atm_gpio_clear_output(uint8_t gpio); + + /** + * @brief Set GPIO PIN pullup. + * @param[in] gpio pin number + */ + + void atm_gpio_set_pullup(uint8_t gpio); + + /** + * @brief Clear GPIO PIN pullup. + * @param[in] gpio pin number + */ + + void atm_gpio_clear_pullup(uint8_t gpio); + + /** + * @brief Read GPIO Interrupt Status. + * @param[in] gpio pin number + */ + + bool atm_gpio_read_int_status(uint8_t gpio); + + /** + * @brief Clear GPIO PIN Interrupt Status. + * @param[in] gpio pin number + */ + + void atm_gpio_clear_int_status(uint8_t gpio); + + /** + * @brief Enable GPIO PIN Interrupt. + * @param[in] gpio pin number + */ + + void atm_gpio_set_int_enable(uint8_t gpio); + + /** + * @brief Disable GPIO PIN Interrupt. + * @param[in] gpio pin number + */ + + void atm_gpio_set_int_disable(uint8_t gpio); + + /** + * @brief Setup GPIO PIN Interrupt as high level. + * @param[in] gpio pin number + */ + + void atm_gpio_int_set_high(uint8_t gpio); + + /** + * @brief Setup GPIO PIN Interrupt as rising edge. + * @param[in] gpio pin number + */ + + void atm_gpio_int_set_rising(uint8_t gpio); + + /** + * @brief Setup GPIO PIN Interrupt as low level. + * @param[in] gpio pin number + */ + + void atm_gpio_int_set_low(uint8_t gpio); + + /** + * @brief Setup GPIO PIN Interrupt as falling edge. + * @param[in] gpio pin number + */ + + void atm_gpio_int_set_falling(uint8_t gpio); + + /** + * @brief Setup GPIO PIN Interrupt as high or low level. + * @param[in] gpio pin number + * @return Previous Interrupt edge configure. + */ + + bool atm_gpio_toggle_int_edge(uint8_t gpio); + + /** + * @brief Write GPIO PIN output (1: high, 0: low) + * @param[in] gpio pin number + * @param[in] value (0/1) + */ + + void atm_gpio_write(uint8_t gpio, bool value); + + /** + * @brief Read GPIO PIN. + * @param[in] gpio pin number + */ + + bool atm_gpio_read_gpio(uint8_t gpio); + + /** + * @brief Toggle GPIO PIN. + * @param[in] gpio pin number + * @return GPIO pin value after toggling. + */ + bool atm_gpio_toggle(uint8_t gpio); + + /** + * @brief GPIO pin validation. + * @param[in] gpio pin number + * @return Error code (@ref atm_gpio_err_t) + */ + uint8_t atm_gpio_validate_gpio(uint8_t gpio); + +#ifdef __cplusplus +} +#endif + + /*@}*/ /* end of group ATM_GPIO_Driver_definitions Atmosic GPIO Driver definitions */ diff --git a/platform/atm2/ATM22xx-x1x/driver/atm_pm/atm_pm.h b/platform/atm2/ATM22xx-x1x/driver/atm_pm/atm_pm.h new file mode 100644 index 0000000..fbab226 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/atm_pm/atm_pm.h @@ -0,0 +1,120 @@ +/******************************************************************************* + * + * @file atm_pm.h + * + * @brief Power wakelock manager + * + * Copyright (C) Atmosic 2020 + * + ******************************************************************************* + */ + +#pragma once + +/** + ******************************************************************************* + * @defgroup ATM_DEV_PM Power managerment + * @ingroup DRIVERS + * @brief ATM power managerment driver + * + * This module contains the necessary functions to control the power modes + * + * @{ + ******************************************************************************* +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/// Lock type of low power mode +typedef enum { + /// Sleep mode + PM_LOCK_SLEEP, + /// Retention mode + PM_LOCK_RETENTION, + /// Hibernation mode + PM_LOCK_HIBERNATE, + PM_LOCK_TYPE_MAX, +} pm_lock_type_e; + +/// Lock identifier +typedef struct { + /// Lock id + uint32_t id; + /// Lock type + pm_lock_type_e type; +} pm_lock_id_t; + +/** + ******************************************************************************* + * @brief Allocate lock identifier with specified id + * @param[in] id Identifier of specific lock and id. + * @param[in] type Type of low power to be manipulated. + ******************************************************************************* + */ +bool atm_pm_realloc(pm_lock_id_t id, pm_lock_type_e type); + +/** + ******************************************************************************* + * @brief Allocate lock identifier. + * @param[in] type Type of low power to be manipulated. + * @return Identifier of specific lock. + ******************************************************************************* + */ +pm_lock_id_t atm_pm_alloc(pm_lock_type_e type); + +/** + ******************************************************************************* + * @brief Free allocated lock + * @param[in] id Identifier of specific lock and id. + ******************************************************************************* + */ +void atm_pm_free(pm_lock_id_t id); + +/** + ******************************************************************************* + * @brief Lock specific power mode + * @param[in] index Lock index + ******************************************************************************* + */ +void atm_pm_lock(pm_lock_id_t index); + +/** + ******************************************************************************* + * @brief Unlock specific power mode + * @param[in] index Lock index + ******************************************************************************* + */ +void atm_pm_unlock(pm_lock_id_t index); + +/** + ******************************************************************************* + * @brief Print wakelocks + ******************************************************************************* + */ +void atm_pm_lock_info(void); + +/** + ******************************************************************************* + * @brief Set restart time from hibernate + * @param[in] restart_time Hibernation time in centisec. + ******************************************************************************* + */ +void atm_pm_set_hib_restart_time(uint32_t restart_time); + +/** + ******************************************************************************* + * @brief Set function of atm_pm replacement vector of hibernate. + * @param[in] cb Function of replacement vector. + * @note The cb should be placed in RAM using __FAST. + ******************************************************************************* + */ +void atm_pm_set_hibernate_cb(rep_vec_fn__ret_bool__int32_t__uint32_t__t cb); + +#ifdef __cplusplus +} +#endif + +///@} + diff --git a/platform/atm2/ATM22xx-x1x/driver/atm_vkey/atm_vkey.h b/platform/atm2/ATM22xx-x1x/driver/atm_vkey/atm_vkey.h new file mode 100644 index 0000000..cc84616 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/atm_vkey/atm_vkey.h @@ -0,0 +1,898 @@ +/** + ******************************************************************************* + * + * @file atm_vkey.h + * + * @brief Virtual key event modeling + * + * Copyright (C) Atmosic 2021-2023 + * + ******************************************************************************* + */ +#pragma once + +#include "co_math.h" + +/** + ******************************************************************************* + * @defgroup ATM_DEV_VKEY Virtual key models + * @ingroup DRIVERS + * @brief ATM virtual key handling module + * + * This module contains the necessary procedure to deal with keys based user + * events. In general, application registers interesting events initially and + * provids virtual key number with pressed(or released) information when user + * operated via some physical input like key matrixes and gpio buttons. If some + * event condition matched, callback function which was registered will be called. + * + * ## Register event table + * The Application could define preferred key events by atm_vk_reg_t type and + * form them as atm_vk_reg_t array table. Each array entry could be easily + * declared by macro such as @ref VKEY_CLICK, @ref VKEY_DB_CLICK, and so on. + * By calling @ref atm_vkey_add_table function, application could add the event + * table into atm_vkey module. Application could add many event tables and each + * table adding would return a handle to application. + * + * Below is two sets of event array registered in a HID keyboard example: + * @code + * // Key event on connected state + * static const atm_vk_reg_t kbd_conn_vkeys[] = { + * VKEY_DOWN_FIRST(kbd_send_rpt, atm_vk_any), + * VKEY_DOWN_MORE (kbd_send_rpt_more, atm_vk_any), + * VKEY_UP_INTER (kbd_send_rpt_more, atm_vk_any), + * VKEY_UP_LAST (kbd_send_rpt, atm_vk_any), + * VKEY_HOLD_1KEY (kbd_hold_test1, NULL, 1000, VK_FN), + * VKEY_HOLD_2KEY (kbd_hold_test2, NULL, 1000, VK_FN, VK_F1), + * VKEY_HOLD_1KEY_CLICK(kbd_clear_all_bond, VK_U, VK_FN), + * VKEY_HOLD_2KEY_CLICK(kbd_enter_rftest, VK_ENTER, VK_FN, VK_F1), + * }; + * + * // Key event on disconnected state + * static const atm_vk_reg_t kbd_unconn_vkeys[] = { + * VKEY_DOWN_FIRST(kbd_save_key, atm_vk_any), + * VKEY_DOWN_MORE (kbd_save_key_more, atm_vk_any), + * VKEY_UP_INTER (kbd_save_key_more, atm_vk_any), + * VKEY_UP_LAST (kbd_save_key, atm_vk_any), + * VKEY_HOLD_1KEY (kbd_hold_test1, NULL, 1000, VK_FN), + * VKEY_HOLD_2KEY (kbd_hold_test2, NULL, 1000, VK_FN, VK_F1), + * VKEY_HOLD_1KEY_CLICK(kbd_clear_all_bond, VK_U, VK_FN), + * VKEY_HOLD_2KEY_CLICK(kbd_enter_rftest, VK_ENTER, VK_FN, VK_F1), + * }; + * + * ... + * + * // Register events for connected state + * vkey_handles[0] = atm_vkey_add_table(kbd_unconn_vkeys, + * ARRAY_LEN(kbd_unconn_vkeys), &mmi_vkey_ctx); + * // Register events for disconnected state + * vkey_handles[1] = atm_vkey_add_table(kbd_conn_vkeys, + * ARRAY_LEN(kbd_conn_vkeys), &mmi_vkey_ctx); + * @endcode + * + * ## Feed virtual key + * When application was triggered by user input, it could use @ref atm_vkey_feed + * to provide the virtual key index and its pressed or release state. + * + * Below is the example of feeding virtual key into atm_vkey module: + * @code + * + * // key matrix callback function + * static void key_matrix_event(bool pressed, uint32_t idx) + * { + * switch (atm_asm_get_current_state(MMI_S_TBL_IDX)) { + * // Feed key when state is disconnected + * case MMI_S_BOOTED: + * case MMI_S_INITING: + * case MMI_S_IDLE: { + * atm_vkey_feed(vkey_handles[0], idx, pressed); + * } break; + * ... + * // Feed key when state is connected + * case MMI_S_HID_ONLY: { + * atm_vkey_feed(vkey_handles[1], idx, pressed); + * } break; + * ... + * } + * } + * @endcode + * + * @{ + * + ******************************************************************************* + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ATM_VKEY_MAX +#define ATM_VKEY_MAX 32 +#endif + +/** + ******************************************************************************* + * @brief Create double click event entry. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. + * @param[in] fn Callback function + * @ref atm_vk_dck_reg_t.cb + * @param[in] vkey Key index to monitor. @ref atm_vk_dck_reg_t.vkey + * @param[in] max_ms Maximal triggered interval within two clicks. + * @ref atm_vk_dck_reg_t.max_ms + * + * Here is the example of monitoring double click events on key index x or + * y while the time between two clicks is shorter than 100 milliseconds: + * - Method one: + * @code + * + * // Handler for double click event + * static void vkey_any_dbclick(atm_vk_dck_evt_t *evt, void const *ctx) + * { + * DEBUG_TRACE("Key (%03u) double clicked", evt->vkey); + * + * if (evt->vkey == x) { + * // Doing things when key x was double clicked + * ... + * } else if (evt->vkey == y) { + * // Doing things when key y was double clicked + * ... + * } + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_DB_CLICK(vkey_any_dbclick, atm_vk_any, 100), + * ... + * }; + * @endcode + * - Method two: + * @code + * + * // Handler for double click event of key 3 + * static void vkey_x_dbclick(atm_vk_dck_evt_t *evt, void const *ctx) + * { + * DEBUG_TRACE("Key (%03u) double clicked", evt->vkey); + * // Doing things when key x was double clicked + * ... + * } + * + * // Handler for double click event of key y + * static void vkey_y_dbclick(atm_vk_dck_evt_t *evt, void const *ctx) + * { + * DEBUG_TRACE("Key (%03u) double clicked", evt->vkey); + * // Doing things when key y was double clicked + * ... + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_DB_CLICK(vkey_x_dbclick, x, 100), + * VKEY_DB_CLICK(vkey_y_dbclick, y, 100), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_DB_CLICK(fn, vkey, max_ms) { \ + atm_vk_db_click, .db_click = {fn, vkey, max_ms} \ +} + +/** + ******************************************************************************* + * @brief Create click event entry. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. + * @param[in] fn Callback function + * @ref atm_vk_ck_reg_t.cb + * @param[in] vkey Key index to monitor. @ref atm_vk_ck_reg_t.vkey + * @param[in] min_ms Minimal triggered interval within up and down. + * @ref atm_vk_ck_reg_t.min_ms + * @param[in] max_ms Maximal triggered interval within up and down. + * @ref atm_vk_ck_reg_t.max_ms + * + * Here is the example of monitoring click event on key index x with click interval + * within 50 to 100 millisecond and 500 to 1000 millisecond correspondingly: + * - Method one + * @code + * // Handler for key x quick click event + * static void vkey_x_quick_click(atm_vk_ck_evt_t *evt, void const *ctx) + * { + * // evt->vkey shall be x + * // evt->time_ms shall be from 50 to 100. + * DEBUG_TRACE("Key (%03u) quick clicked in %ld ms", evt->vkey, evt->time_ms); + * // Do things of quick clicking + * ... + * } + * + * // Handler for key x slow click event + * static void vkey_x_slow_click(atm_vk_ck_evt_t *evt, void const *ctx) + * { + * // evt->vkey shall be x + * // evt->time_ms shall be from 500 to 1000. + * DEBUG_TRACE("Key (%03u) slow clicked in %ld ms", evt->vkey, evt->time_ms); + * // Do things of slow clicking + * ... + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_CLICK(vkey_3_quick_click, x, 50, 100), + * ... + * VKEY_CLICK(vkey_3_slow_click, x, 500, 1000), + * ... + * }; + * @endcode + * - Method two + * @code + * // Handler for key x quick click event + * static void vkey_x_click(atm_vk_ck_evt_t *evt, void const *ctx) + * { + * // evt->vkey shall be x + * // evt->time_ms shall be from 50 to 1000. + * DEBUG_TRACE("Key (%03u) clicked in %ld ms", evt->vkey, evt->time_ms); + * if (evt->time_ms <= 100) { + * // Do things of quick clicking + * ... + * } else if(evt->time_ms >= 500) { + * // Do things of slow clicking + * ... + * } + * } + * + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_CLICK(vkey_x_click, x, 50, 1000), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_CLICK(fn, vkey, min_ms, max_ms) { \ + atm_vk_click, .click = {fn, vkey, min_ms, max_ms} \ +} + +/** + ******************************************************************************* + * @brief Create hold click event entry. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. + * @param[in] fn Callback function + * @ref atm_vk_hc_reg_t.cb + * @param[in] vkey Virtual key index for clicking monitor. + * @param[in] ... Held keys' mask. + * @note VKEY_HOLD_CLICK don't support ATM_MASK_ANY + * + * Here is the example of monitoring click events on key index x clicking with + * key indexes a,b and c (where a < 32, b < 32, 32 < c < 64) held and key index + * y clicking with key index d (where d < 32) held: + * @code + * + * // Handler for key index x clicking with key indexes a,b and c held. + * static void vkey_x_click_in_abc(atm_vk_hc_evt_t *evt, void const *ctx) + * { + * // evt->vkey shall be x + * DEBUG_TRACE("Key (%03u) clicked", evt->vkey); + * // evt->held.mask[0] should equal to (1 << a) | (1 << b) + * DEBUG_TRACE("Key held mask[0] = %l#x", evt->held.mask[0]); + * // evt->held.mask[1] should equal to (1 << (c-32)) + * DEBUG_TRACE("Key held mask[1] = %l#x", evt->held.mask[1]); + * } + * + * // Handler for key index y click with key index d held. + * static void vkey_y_click_in_d(atm_vk_hc_evt_t *evt, void const *ctx) + * { + * // evt->vkey will be y + * DEBUG_TRACE("Key (%03u) clicked", evt->vkey); + * // evt->held.mask[0] should equal to (1 << d) + * DEBUG_TRACE("Key held mask[0] = %l#x", evt->held.mask[0]); + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_HOLD_CLICK(vkey_x_click_in_abc, x, (1 << a) | (1 << b), (1 << (c - 32))), + * ... + * VKEY_HOLD_CLICK(vkey_y_click_in_d, y, (1 << d)), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_HOLD_CLICK(fn, vkey, ...) { \ + atm_vk_hold_click, .hold_click = {fn, vkey, {__VA_ARGS__}} \ +} + +/** + ******************************************************************************* + * @brief Create hold click event entry with 1 key holding. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. This is convenient version + * of @ref VKEY_HOLD_CLICK with 1 key holding. + * @param[in] fn Callback function + * @ref atm_vk_hc_reg_t.cb + * @param[in] vkey Virtual key index for clicking monitor. + * @param[in] mk Virtual key index for holding. + * + * Here is the example of monitoring click event on key index x clicking with + * key index a held: + * @code + * + * // Handler for key x click with key index a held. + * static void vkey_x_click_with_a(atm_vk_hc_evt_t *evt, void const *ctx) + * { + * // evt->vkey will be x + * DEBUG_TRACE("Key (%03u) clicked", evt->vkey); + * // evt->held.mask[a/32] should equal to (1 << (a%32)) + * DEBUG_TRACE("Key held mask[%x] = %l#x", a/32, evt->held.mask[a/32]); + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * // If a < 32, this equals to VKEY_HOLD_CLICK(vkey_x_click_with_a, x, (1 << a)) + * // If a < 64, this equals to VKEY_HOLD_CLICK(vkey_x_click_with_a, x, 0, (1 << a % 32)) + * // If a < 96, this equals to VKEY_HOLD_CLICK(vkey_x_click_with_a, x, 0, 0, (1 << a % 32)) + * // Etc,. + * VKEY_HOLD_1KEY_CLICK(vkey_x_click_with_a, x, a), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_HOLD_1KEY_CLICK(fn, vkey, mk) \ + VKEY_HOLD_CLICK(fn, vkey, VKEY_1KEY_MASK(mk)) + +/** + ******************************************************************************* + * @brief Create hold click event entry with 2 key holding. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. This is the convenient version + * of @ref VKEY_HOLD_CLICK with 2 key holding. + * @param[in] fn Callback function + * @ref atm_vk_hc_reg_t.cb + * @param[in] vkey Virtual key index for clicking monitor. + * @param[in] mk1 First virtual key index for holding. + * @param[in] mk2 Second virtual key index for holding. + * Here is the example of monitoring click event on key index x clicking with + * key index a and key index b held: + * @code + * + * // Handler for key index x click with key index a and b held. + * static void vkey_x_click_with_ab(atm_vk_hc_evt_t *evt, void const *ctx) + * { + * // evt->vkey shall be x + * DEBUG_TRACE("Key (%03u) clicked", evt->vkey); + * // evt->held.mask[a/32] bit a%32 shall be 1 + * // evt->held.mask[b/32] bit b%32 shall be 1 + * DEBUG_TRACE("mask %d = %l#x mask %d = %l#x", a/32, evt->held.mask[a/32], b/32, + * evt->held.mask[b/32]); + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_HOLD_2KEY_CLICK(vkey_x_click_with_ab, x, a, b), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_HOLD_2KEY_CLICK(fn, vkey, mk1, mk2) \ + VKEY_HOLD_CLICK(fn, vkey, VKEY_2KEY_MASK(mk1, mk2)) + +/** + ******************************************************************************* + * @brief Create hold event entry. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. + * @param[in] fn Callback function + * @ref atm_vk_hd_reg_t.cb + * @param[in] fn1 Callback function + * @ref atm_vk_hd_reg_t.status_cb + * @param[in] min_ms Minimal hold time to trigger the event. + * @ref atm_vk_hd_reg_t.time_ms + * @param[in] ... Held keys' mask. + * + * Here is the example of monitoring click events on key a, b, and c held for + * 500 milliseconds and key index d held for 1000 milliseconds. + * @code + * + * // Handler for key index a,b and c held. + * static void vkey_abc_hold(atm_vk_hd_evt_t *evt, void const *ctx) + * { + * // evt->held.mask[a/32] bit a%32 shall be 1 + * // evt->held.mask[b/32] bit b%32 shall be 1 + * // evt->held.mask[c/32] bit c%32 shall be 1 + * DEBUG_TRACE("mask %d = %l#x mask %d = %l#x", a/32, evt->held.mask[a/32], b/32, + * evt->held.mask[b/32], c/32, evt->held.mask[c/32]); + * // evt->time_ms should be longer than 500 milliseconds + * DEBUG_TRACE("time = %ld", evt->time_ms); + * } + * + * // Handler for key index d held. + * static void vkey_d_hold(atm_vk_hd_evt_t *evt, void const *ctx) + * { + * // evt->held.mask[d/32] bit d%32 shall be 1 + * DEBUG_TRACE("mask %d = %l#x", d/32, evt->held.mask[d/32]); + * // evt->time_ms should be longer than 1000 milliseconds + * DEBUG_TRACE("time = %ld", evt->time_ms); + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * // The (1 << (a%32)), (1 << (b%32)) and (1 << (c%32)) would be located in + * // mask a/32, b/32, c/32 respectively + * VKEY_HOLD(vkey_abc_hold, NULL, 500, ... (1 << (a%32)) ... (1 << (b%32)) ... (1 << (c%32))), + * ... + * // The (1 << (d%32)) would be located in mask d/32 + * VKEY_HOLD(vkey_d_hold, NULL, 1000, ...(1 << (d%32)...), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_HOLD(fn, fn1, min_ms, ...) { \ + atm_vk_hold, .hold = {fn, fn1, min_ms, {__VA_ARGS__}} \ +} + +/** + ******************************************************************************* + * @brief Create hold event entry with 1 key holding. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. This is convenient version of + * @ref VKEY_HOLD with 1 key holding + * @param[in] fn Callback function + * @ref atm_vk_hd_reg_t.cb + * @param[in] fn1 Callback function + * @ref atm_vk_hd_reg_t.status_cb + * @param[in] min_ms Minimal hold time to trigger the event. + * @param[in] mk Virtual key index for holding. + * + * Here is the example of monitoring click event on and key index x holding for + * 1000 ms. + * @code + * + * // Handler for key x held. + * static void vkey_x_hold(atm_vk_hd_evt_t *evt, void const *ctx) + * { + * // evt->held.mask[x/32] bit x%32 shall be 1 + * DEBUG_TRACE("Holding key mask[%d] = %l#x", x/32,evt->held.mask[x/32]); + * // evt->time_ms shall be longer than 1000 + * DEBUG_TRACE("time = %ld", evt->time_ms); + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_HOLD_1KEY(vkey_x_hold, NULL, 1000, x), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_HOLD_1KEY(fn, fn1, min_ms, mk) \ + VKEY_HOLD(fn, fn1, min_ms, VKEY_1KEY_MASK(mk)) + +/** + ******************************************************************************* + * @brief Create hold click event entry with 2 key holding. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. This is convenient version + * of @ref VKEY_HOLD with 2 keys holding. + * @param[in] fn Callback function + * @ref atm_vk_hd_reg_t.cb + * @param[in] fn1 Callback function + * @ref atm_vk_hd_reg_t.status_cb + * @param[in] min_ms Minimal hold time to trigger the event. + * @param[in] mk1 First virtual key index for holding. + * @param[in] mk2 Second virtual key index for holding. + * + * Here is the example of monitoring click event on and key index x and y holding for + * 1500 ms. + * @code + * + * // Handler for key index x and y held. + * static void vkey_xy_hold(atm_vk_hd_evt_t *evt, void const *ctx) + * { + * // evt->held.mask[x/32] bit x%32 shall be 1 + * DEBUG_TRACE("Holding key mask[%d] = %l#x", x/32, evt->held.mask[x/32]); + * // evt->held.mask[y/32] bit y%32 shall be 1 + * DEBUG_TRACE("Holding key mask[%d] = %l#x", y/32, evt->held.mask[y/32]); + * // evt->time_ms shall be longer than 1000 + * DEBUG_TRACE("time = %ld", evt->time_ms); + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_HOLD_2KEY(vkey_xy_hold, NULL, 1500, x, y), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_HOLD_2KEY(fn, fn1, min_ms, mk1, mk2) \ + VKEY_HOLD(fn, fn1, min_ms, VKEY_2KEY_MASK(mk1, mk2)) + +/** + ******************************************************************************* + * @brief Create non-first down event entry. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. + * @param[in] fn Callback function + * @ref atm_vk_dnup_reg_t.cb + * @param[in] vkey Virtual key index for down monitor. + * + * @anchor down_more_example + * Here is the example of monitoring all kinds of down and up events and report + * them to a single callback: + * @code + * + * static void vkey_any_up_down_inter(atm_vk_dnup_inter_evt_t *evt, void const *ctx) + * { + * if(evt->eid == atm_vk_down_1st || evt->eid == atm_vk_down_more) { + * DEBUG_TRACE("vkey %d is pressed", evt->vkey); + * } else { + * DEBUG_TRACE("vkey %d is release", evt->vkey); + * } + * + * if(evt->eid == atm_vk_down_more || evt->eid == atm_vk_up_inter) { + * DEBUG_TRACE("Some key held mask:") + * for (int i = 0; i < VKEY_MASK_NUM; i++) { + * DEBUG_TRACE("mask[%d] = %lu", evt->held.mask[i]); + * } + * } + * } + * + * static void vkey_any_up_down(atm_vk_dnup_evt_t *evt, void const *ctx) + * { + * atm_vk_dnup_inter_evt_t new_evt; + * memcpy(&new_evt, &evt, sizeof(atm_vk_dnup_evt_t)); + * vkey_any_up_down_inter(&new_evt, ctx); + * } + * + * // Key event array + * static const atm_vk_reg_t key_event_array[] = { + * ... + * VKEY_DOWN_MORE(vkey_any_up_down, atm_vk_any), + * VKEY_DOWN_FIRST(vkey_any_up_down_inter, atm_vk_any), + * VKEY_UP_INTER(vkey_any_up_down_inter, atm_vk_any), + * VKEY_UP_LAST(vkey_any_up_down, atm_vk_any), + * ... + * }; + * @endcode + ******************************************************************************* + */ +#define VKEY_DOWN_MORE(fn, vkey) { \ + atm_vk_down_more, .dn = {fn, vkey} \ +} + +/** + ******************************************************************************* + * @brief Create first down event entry. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. + * @param[in] fn Callback function + * @ref atm_vk_dnup_reg_t.cb + * @param[in] vkey Virtual key index for down monitor. + * @note Please refer example @ref down_more_example "here" + ******************************************************************************* + */ +#define VKEY_DOWN_FIRST(fn, vkey) { \ + atm_vk_down_1st, .dn_fst = {fn, vkey} \ +} + +/** + ******************************************************************************* + * @brief Create non-last up event entry. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. + * @param[in] fn Callback function + * @ref atm_vk_dnup_reg_t.cb + * @param[in] vkey Virtual key index for up monitor. + * @note Please refer example @ref down_more_example "here" + ******************************************************************************* + */ +#define VKEY_UP_INTER(fn, vkey) { \ + atm_vk_up_inter, .up = {fn, vkey} \ +} + +/** + ******************************************************************************* + * @brief Create last up event entry. + * The entry is part of a @ref atm_vk_reg_t array which is used to + * registered into @ref atm_vkey_add_table function. + * @param[in] fn Callback function + * @ref atm_vk_dnup_reg_t.cb + * @param[in] vkey Virtual key index for up monitor. + * @note Please refer example @ref down_more_example "here" + ******************************************************************************* + */ +#define VKEY_UP_LAST(fn, vkey) { \ + atm_vk_up_last, .up_lst = {fn, vkey} \ +} + +/// Internal macro used by VKEY_1KEY_MASK +#define _MK_N(n, v) ((v / 32 == n) ? CO_BIT(v % 32) : 0) +/// Internal macro used by VKEY_2KEY_MASK +#define _MK_N2(n, v1, v2) (_MK_N(n,v1) | _MK_N(n,v2)) +/// Vkey index to vkey mask conversion by maximum vkey number +#define _MK_N_64(v) _MK_N(0, v), _MK_N(1, v) +#define _MK_N_96(v) _MK_N_64(v), _MK_N(2, v) +#define _MK_N_128(v) _MK_N_96(v), _MK_N(3, v) +#define _MK_N_160(v) _MK_N_128(v), _MK_N(4, v) +#define _MK_N_192(v) _MK_N_160(v), _MK_N(5, v) +#define _MK_N2_64(v1, v2) _MK_N2(0, v1, v2), _MK_N2(1, v1, v2) +#define _MK_N2_96(v1, v2) _MK_N2_64(v1, v2), _MK_N2(2, v1, v2) +#define _MK_N2_128(v1, v2) _MK_N2_96(v1, v2), _MK_N2(3, v1, v2) +#define _MK_N2_160(v1, v2) _MK_N2_128(v1, v2), _MK_N2(4, v1, v2) +#define _MK_N2_192(v1, v2) _MK_N2_160(v1, v2), _MK_N2(5, v1, v2) +#if (ATM_VKEY_MAX <= 32) +#define VKEY_1KEY_MASK(v) _MK_N(0, v) +#define VKEY_2KEY_MASK(v1, v2) _MK_N2(0, v1, v2) +#elif (ATM_VKEY_MAX <= 64) +#define VKEY_1KEY_MASK(v) _MK_N_64(v) +#define VKEY_2KEY_MASK(v1, v2) _MK_N2_64(v1, v2) +#elif (ATM_VKEY_MAX <= 96) +#define VKEY_1KEY_MASK(v) _MK_N_96(v) +#define VKEY_2KEY_MASK(v1, v2) _MK_N2_96(v1, v2) +#elif (ATM_VKEY_MAX <= 128) +#define VKEY_1KEY_MASK(v) _MK_N_128(v) +#define VKEY_2KEY_MASK(v1, v2) _MK_N2_128(v1, v2) +#elif (ATM_VKEY_MAX <= 160) +#define VKEY_1KEY_MASK(v) _MK_N_160(v) +#define VKEY_2KEY_MASK(v1, v2) _MK_N2_160(v1, v2) +#else +#define VKEY_1KEY_MASK(v) _MK_N_192(v) +#define VKEY_2KEY_MASK(v1, v2) _MK_N2_192(v1, v2) +#endif // (ATM_VKEY_MAX <= 32) +/// Check if a key is in mask array +#define VKEY_IS_MASK_HIT(m, k) (m[k / 32] & CO_BIT(k % 32)) +/// Check if two mask array is equal +#define VKEY_IS_MASK_EQU(m1, m2) \ + (!memcmp(m1, m2, sizeof(uint32_t) * VKEY_MASK_NUM)) +/// Special number for any mask +#define ATM_MASK_ANY 0xFFFFFFFF +/// Number for vkey mask +#define VKEY_MASK_NUM CO_DIVIDE_CEIL(ATM_VKEY_MAX, 32) + +/// Key event ID +typedef enum { + /// First key down event. + atm_vk_down_1st, + /// Non-first key down event. Other pressed key(s) exist. + atm_vk_down_more, + /// Key held event. + atm_vk_hold, + /// Non-last Key up event. Other pressed key(s) exist. + atm_vk_up_inter, + /// Last key up event. + atm_vk_up_last, + /// Event for key clicking. + atm_vk_click, + /// Event for key clicking with some key(s) held. + atm_vk_hold_click, + /// Event for key double clicking. + atm_vk_db_click, +} atm_vk_eid_t; + +/// key index: 0 to 254 is valid index. +/// Here defined is special usage. +typedef enum { + /// any keys + atm_vk_any = 0xff +} atm_vk_idx_t; + +/// Held keys +typedef struct { + /// Masks of current held keys. + uint32_t mask[VKEY_MASK_NUM]; +} atm_vk_held_keys_t; + + +/// Event structure header +typedef struct { + /// Event id + atm_vk_eid_t eid; + union { + /// Key index have been acted. @ref atm_vk_idx_t + atm_vk_idx_t vkey; + /// Key index of uint8_t type. + uint8_t u8vkey; + }; +} atm_vk_basic_evt_t; + +/// Event structure for atm_vk_down_fist and atm_vk_up_last. +typedef struct { + /// Basic event + atm_vk_basic_evt_t top; +} atm_vk_dnup_evt_t; + +/// Event structure for atm_vk_hold +typedef struct atm_vk_hd_evt_s { + /// Basic event + /// @note the vkey in top is unused in atm_vk_hold + atm_vk_basic_evt_t top; + /// Minimal time of holding. Unit is millisecond. Zero for ignoring. + uint16_t time_ms; + /// Current held key + atm_vk_held_keys_t held; +} atm_vk_hd_evt_t; + +/// Event structure for atm_vk_hold_click, atm_vk_down_more and +/// atm_vk_up_inter +typedef struct { + /// Basic event; + atm_vk_basic_evt_t top; + /// Masks of current held key. + atm_vk_held_keys_t held; +} atm_vk_hc_evt_t, atm_vk_dnup_inter_evt_t; + +/// Click and double click event structure +typedef struct atm_vk_ck_evt_s { + /// Basic event; + atm_vk_basic_evt_t top; + /// Measured time for click and double click + /// click: time between press and release. + /// double click: time between two clicks. + uint16_t time_ms; +} atm_vk_ck_evt_t, atm_vk_dck_evt_t; + +/// Entry structure for hold detection. +typedef struct atm_vk_hd_reg_s { + /// callback while event happen + /// @brief This function will be called if hold condition matched. + /// @param[in] evt Event for hold and click structure + /// @param[in] ctx Context data. + /// @return Return true to keep detecting this hold. otherwise, false. + bool (*cb)(atm_vk_hd_evt_t const *evt, void const *ctx); + /// @brief This function will be called if hold key has been pressed or + /// released. + /// @param[in] pressed Indicate the hold key is pressed and a timer is + /// starting to count. + /// @param[in] ctx Context data. + void (*status_cb)(bool pressed, void const *ctx); + /// Minimal time of holding. Unit is millisecond. Zero for ignoring. + uint16_t time_ms; + /// Masks of expecting held keys. + uint32_t mask[VKEY_MASK_NUM]; +} atm_vk_hd_reg_t; + +/// Entry structure for hold and click +typedef struct atm_vk_hc_reg_s { + /// callback while event happen + /// @brief This function will be called if hold and click condition matched. + /// @param[in] evt Event for hold structure + /// @param[in] ctx Context data. + void (*cb)(atm_vk_hc_evt_t const *evt, void const *ctx); + /// Key index of clicking. @ref atm_vk_idx_t + uint8_t vkey; + /// Masks of expecting held keys. + uint32_t mask[VKEY_MASK_NUM]; +} atm_vk_hc_reg_t; + +/// Entry structure of click event +typedef struct atm_vk_ck_reg_s { + /// callback while event happen + /// @brief This function will be called if click condition matched. + /// @param[in] evt Event for click structure + /// @note min_ms and max_ms represent the real click interval and they should + /// equal. + /// @param[in] ctx Context data. + void (*cb)(atm_vk_ck_evt_t const *evt, void const *ctx); + /// Key index of clicking. @ref atm_vk_idx_t + uint8_t vkey; + /// Minimal time between press and release. zero for ignoring. + uint16_t min_ms; + /// Maximal time between press and release. zero for ignoring. + uint16_t max_ms; +} atm_vk_ck_reg_t; + +/// Entry structure for double click detection +typedef struct atm_vk_dck_reg_s { + /// callback while event happen + /// @brief This function will be called if double click condition matched. + /// @param[in] evt Event for double click structure + /// @param[in] ctx Context data. + void (*cb)(atm_vk_dck_evt_t const *evt, void const *ctx); + /// Listening key index of double clicking. @ref atm_vk_idx_t + uint8_t vkey; + /// Maximal time between two clicks. zero for ignoring. + uint16_t max_ms; +} atm_vk_dck_reg_t; + +/// Entry structure for down and up +typedef struct atm_vk_dnup_reg_s { + /// callback while event happen + /// @brief This function will be called if down or up condition matched. + /// @param[in] evt Event for down or up structure + /// @param[in] ctx Context data. + void (*cb)(atm_vk_dnup_evt_t const *evt, void const *ctx); + /// Key listen index for atm_vk_down_fist, atm_vk_up_last + /// @ref atm_vk_idx_t + uint8_t vkey; +} atm_vk_dnup_reg_t; + +/// Event structure for non-lonely down and up +typedef struct atm_vk_dnup_inter_reg_s { + /// callback while event happen + /// @brief This function will be called if down or up condition matched. + /// @param[in] evt Event for non-lonely down or up structure + /// @param[in] ctx Context data. + void (*cb)(atm_vk_dnup_inter_evt_t const *evt, void const *ctx); + /// Key index for atm_vk_down_more, atm_vk_up_inter + /// @ref atm_vk_idx_t + uint8_t vkey; +} atm_vk_dnup_inter_reg_t; + +/// Event union for table +typedef struct { + /// Event id + atm_vk_eid_t eid; + union { + /// Non-first down event + atm_vk_dnup_inter_reg_t dn; + /// Non-last up event + atm_vk_dnup_inter_reg_t up; + /// First down event + atm_vk_dnup_reg_t dn_fst; + /// Last up event + atm_vk_dnup_reg_t up_lst; + /// Hold event + atm_vk_hd_reg_t hold; + /// Hold and click event + atm_vk_hc_reg_t hold_click; + /// click event + atm_vk_ck_reg_t click; + /// double click event + atm_vk_dck_reg_t db_click; + }; +} atm_vk_reg_t; + +/** + ******************************************************************************* + * @brief Add a virtual key event table + * @param[in] table Virtual key event table + * @param[in] ent_cnt Entry count of event table + * @param[in] ctx application context + * @return Handle of this table. This handle is used to feed virtual key while + * some user input happened. + ******************************************************************************* + */ +__NONNULL(1) +struct vkll_ctx_s *atm_vkey_add_table(atm_vk_reg_t const *table, uint16_t ent_cnt, + void const *ctx); + +/** + ******************************************************************************* + * @brief Virtual key feed. + * When some user input happened, use this function to put virtual key into + * system. + * @param[in] handle Handle of virtual key event table. + * @param[in] vkey Virtual key to be inputted. + * @param[in] is_pressed True for key pressing. Otherwise for releasing. + ******************************************************************************* + */ +__NONNULL(1) +void atm_vkey_feed(struct vkll_ctx_s *handle, uint8_t vkey, bool is_pressed); + +/** + ******************************************************************************* + * @brief Virtual key flush. + * @param[in] handle Handle of virtual key event table. + ******************************************************************************* + */ +__NONNULL_ALL +void atm_vkey_flush(struct vkll_ctx_s *handle); + +#ifdef __cplusplus +} +#endif + +/// @} ATM_BTFM_PVKEY diff --git a/platform/atm2/ATM22xx-x1x/driver/batt_model/batt_model.h b/platform/atm2/ATM22xx-x1x/driver/batt_model/batt_model.h new file mode 100644 index 0000000..916ddde --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/batt_model/batt_model.h @@ -0,0 +1,86 @@ +/** + ******************************************************************************* + * + * @file batt_model.h + * + * @brief Battery model common prototype + * + * Copyright (C) Atmosic 2022-2023 + * + ******************************************************************************* + */ + +#pragma once + +/** + * @defgroup BATT_MODEL Battery model + * @ingroup DRIVERS + * @brief Driver for battery model + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/// Device abstract state for battery model +typedef enum { + /// Invalid state. Use to report error when get state. + DEV_INVALID, + /// Reset state. It represents system is booting and doesn't decide whether + /// goes to normal function or not. + DEV_RESET, + /// Active state. System is in normal function. + DEV_ACTV, + /// Hibernate state. It represents system is going to hibernation or waking + /// up from hibernation. + DEV_HIB, + /// Soc off state. It represents system is going to SOC off or waking up + /// from SOC off. + DEV_SOCOFF, +} dev_state_t; + +/// Device state getter and setter. +typedef struct { + /// Get current device state. + dev_state_t (*get)(void); + /// Set current device state. + void (*set)(dev_state_t); +} dev_state_fns_t; + +/// Hibernation flag getter and setter +typedef struct { + /// Get hibernation flag + bool (*get)(uint8_t); + /// Set hibernation flag + void (*set)(uint8_t, bool); +} hib_flag_fns_t; + +/// Callback functions from batt_model +typedef struct { + /// Device state getter and setter. + dev_state_fns_t state; + /// Hibernation getter and setter. + hib_flag_fns_t flag; +} batt_cbs; + +/// Battery model virtual functions +typedef struct { + /// Initialization of the battery model. + void (*init)(batt_cbs const *); + /// Issue a battery capacity sampling. + bool (*sample)(void (*cb)(uint8_t level)); +} batt_fns; + +/** + ******************************************************************************* + * @brief Retrieve the functions of battery model + * return Battery model functions. + ******************************************************************************* + */ +batt_fns const *batt_model(void); +#ifdef __cplusplus +} +#endif + +/// @} BATT_MODEL diff --git a/platform/atm2/ATM22xx-x1x/driver/gadc/gadc.h b/platform/atm2/ATM22xx-x1x/driver/gadc/gadc.h new file mode 100644 index 0000000..6f1719a --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/gadc/gadc.h @@ -0,0 +1,122 @@ +/** + ******************************************************************************* + * + * @file gadc.h + * + * @brief Analog-to-digital converter + * + * Copyright (C) Atmosic 2020 + * + ******************************************************************************* + */ + +#pragma once + +/** + ******************************************************************************* + * @defgroup GADC General purpose ADC + * @ingroup DRIVERS + * @brief User driver for General purpose Analog to Digital Converter + * + * @{ + ******************************************************************************* + */ + + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__IEEE_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) +/// Calibration data type +struct gadc_cal_s { + union { + /// 32 bits data which combine offset and gain + uint32_t value; + /// Decomposition structure. + struct { + /// Mantissa part of gain. + unsigned int c1_mantissa:12; + /// Exponent part of gain. + int c1_exponent:6; + /// Sign part of gain. + unsigned int c1_sign:1; + /// Double value of offset + int c0_x2:13; + }; + }; +}; + +STATIC_ASSERT(sizeof(struct gadc_cal_s) == 4, "wrong size"); +/// Float data type +typedef union { + /// C float value + float value; + /// Decomposition structure. + struct { + /// Mantissa part of float. + unsigned int fraction: 23; + /// Exponent part of float. + int exponent: 8; + /// Sign part of float. + unsigned int sign : 1; + } number; +} __ieee_float_shape_type; +#else +#error "Unsupported floating point endian" +#endif + +/// Channels used by GADC +typedef enum { + /// VBAT channel. + VBATT = 0, + /// VSTORE channel. + VSTORE = 1, + /// VDD1A channel. + CORE = 2, + /// Temperature channel. + TEMP = 3, + /// P10/P11 differential channel. + PORT0_DIFFERENTIAL = 4, + /// P10 single-ended channel. + PORT0_SINGLE_ENDED_0 = 6, + /// P11 single-ended channel. + PORT0_SINGLE_ENDED_1 = 7, + /// For GADC driver use only + ZV_PORT = 8, + /// P9 single-ended channel. + PORT1_SINGLE_ENDED_1 = 9, +} gadc_chan_t; + +/// Callback context data +typedef struct { + /// Sensed channel. + gadc_chan_t ch; + /// Gext setting. (0 = more range / 1 = better resolution) + uint8_t gext; + /// Application context. + void const *app_ctx; +} gadc_cb_ctx_t; + +/// Callback prototype +typedef void (*gadc_callback_t)(float result, int16_t raw, struct gadc_cal_s cal, + gadc_cb_ctx_t const *ctx); + +/** + * @brief Sample given GADC channel and invoke callback on completion of measurement + * @param[in] channel GADC channel to monitor + * @param[in] cb Callback invoked with channel measurement on completion. + * @param[in] gext gain setting + * @param[in] ctx Context associated. + */ +void gadc_sample_channel(gadc_chan_t channel, gadc_callback_t cb, uint8_t gext, + void const *ctx); + +#ifdef __cplusplus +} +#endif + +/// @} GADC + diff --git a/platform/atm2/ATM22xx-x1x/driver/ir/ir.h b/platform/atm2/ATM22xx-x1x/driver/ir/ir.h new file mode 100644 index 0000000..42d222a --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/ir/ir.h @@ -0,0 +1,63 @@ +/** + ******************************************************************************* + * + * @file ir.h + * + * @brief IR driver interface + * + * Copyright (C) Atmosic 2019-2022 + * + ******************************************************************************* + */ + +#pragma once + +/** + * @defgroup IR IR + * @ingroup DRIVERS + * @brief Driver for IR module + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Reset IR sequence. + * + */ +void reset_ir_sequence(void); + +/** + * @brief Send IR sequence. + * + */ +void send_ir_sequence(void); + +/** + * @brief add IR period in period_us and carrier_on or off flag + * @param[in] carrier_on true if carrier freq needs to be used during the period + * @param[in] period_us Period in us + */ +void ir_add_period(uint8_t carrier_on, uint32_t period_us); + +/** + * @brief Initialize IR subsystem with given protocol + * @param[in] callback Callback to receive IR sequence completion event. + * @note This callback is invoked in interrupt context. + */ +void ir_init(void (*callback)(void)); + +/** + * @brief Configure IR carrier parameters + * @param[in] freq Carrier frequency setting in Hz + * @param[in] duty Carrier duty cycle setting in percentage + */ +void ir_config_carr(uint32_t freq, uint8_t duty); + +#ifdef __cplusplus +} +#endif + +/// @} IR diff --git a/platform/atm2/ATM22xx-x1x/driver/ir/ir_ctl.h b/platform/atm2/ATM22xx-x1x/driver/ir/ir_ctl.h new file mode 100644 index 0000000..2645ef0 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/ir/ir_ctl.h @@ -0,0 +1,147 @@ +/** + ******************************************************************************* + * + * @file ir_ctl.h + * + * @brief IR control interface + * + * Copyright (C) Atmosic 2022 + * + ******************************************************************************* + */ + +#pragma once + +/** + * @defgroup IR_CTL IR_CTL + * @ingroup DRIVERS + * @brief Driver for IR control + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + IR_MSG_TYPE_IR_CMD, + IR_MSG_TYPE_IR_SEQ, +} ir_msg_type_t; + +/// IR protocol definition +typedef struct { + /// Name of IR protocol + const char *name; + /// IR Protocol Header ON duration in us + uint32_t header_on_dur; + /// IR Protocol Header OFF duration in us + uint32_t header_off_dur; + /// IR Protocol address bits + uint8_t addr_len; + /// IR Protocol command bits + uint8_t cmd_len; + /// IR Protocol logical one ON duration in us + uint32_t one_on_dur; + /// IR Protocol logical one OFF duration in us + uint32_t one_off_dur; + /// IR Protocol logical zero ON duration in us + uint32_t zero_on_dur; + /// IR Protocol logical zero OFF duration in us + uint32_t zero_off_dur; + /// IR Protocol message end duration in us + uint32_t msg_end_dur; + /// IR Protocol message end space in cs + uint32_t msg_end_space; + /// IR Protocol repeat ON duration in us + uint32_t rept_on_dur; + /// IR Protocol repeat OFF duration in us + uint32_t rept_off_dur; + /// IR Protocol repeat end ON duration in us + uint32_t rept_end_on_dur; + /// IR Protocol repeat delay in us + uint32_t rept_delay; +} __PACKED ir_prot_t; + +typedef struct { + uint32_t addr; + uint32_t inv_addr; + uint32_t cmd; + uint32_t inv_cmd; +} ir_data_t; + +typedef struct { + ir_prot_t const *prot; + ir_data_t const *data; + bool repeat; +} __PACKED ir_cmd_t; + +typedef struct { + uint16_t us_per_seq; + uint16_t seq_len; + uint16_t const *seq; + uint16_t rept_len; + uint16_t const *rept_seq; +} ir_seq_t; + +typedef struct { + ir_msg_type_t type; + uint8_t duty; + uint32_t freq; + union { + ir_cmd_t ir_cmd; + ir_seq_t ir_seq; + }; +} ir_msg_t; + +/** + * @brief Initial IR control instance. + * @param[in] cb_end Callback to receive IR sequence completion event. + */ +__NONNULL_ALL +void ir_ctl_init(void(*cb_end)(void)); + +/** + * @brief Start transmiting IR signals + * @param[in] msg IR message + */ +__NONNULL_ALL +void ir_ctl_start(ir_msg_t *msg); + +/** + * @brief Stop repeat IR sequence + */ +void ir_ctl_stop_rept(void); + +/** + * @brief Send IR data using NEC protocol. + * @param[in] data IR address, inverse address, IR command, inverse command + * @param[in] repeat true for repeating IR until ir_ctl_stop_rept() is invoked + * @note If repeat is set, need to call @ref ir_ctl_stop_rept to stop repeat + * code. + */ +__NONNULL(1) +void nec_ir_send(ir_data_t const *data, bool repeat); + +#ifdef CFG_ATVRC_UNI_IR +/** + * @brief Send Universal IR message. + * @param[in] ir_code Universal IR code data + * @param[in] size IR code data size + */ +__NONNULL(1) +void uni_ir_send(uint8_t const *code, uint16_t size); + +/** + * @brief Get repeat delay from Universal IR code data + * @param[in] uni_ir_code Universal IR code data + * @return repeat delay in us. return 0 if IR code type not match + */ +__NONNULL_ALL +uint32_t uni_ir_get_rept_delay(uint8_t const *uni_ir_code); +#endif + +#ifdef __cplusplus +} +#endif + +/// @} IR_CTL diff --git a/platform/atm2/ATM22xx-x1x/driver/ir/nec_ir.h b/platform/atm2/ATM22xx-x1x/driver/ir/nec_ir.h new file mode 100644 index 0000000..87d6a48 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/ir/nec_ir.h @@ -0,0 +1,47 @@ +/** + ******************************************************************************* + * + * @file nec_ir.h + * + * @brief NEC IR driver interface + * + * Copyright (C) Atmosic 2022 + * + ******************************************************************************* + */ + +#pragma once + +/** + * @defgroup NEC_IR NEC_IR + * @ingroup DRIVERS + * @brief Driver for NEC IR module + * @{ + */ + +#include "ir_ctl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configure NEC IR instance. + * @param[in] cb_end Callback to receive IR sequence completion event. + */ +__NONNULL_ALL +void nec_ir_init(void(*cb_end)(void)); + +/** + * @brief Send IR address and cmd using NEC protocol. + * @param[in] data IR data: address, inverse address, command, inverse command + * @note If repeat is set, need to call @ref nec_ir_repeat_end to stop repeat + * code. + */ +void nec_ir_send(ir_data_t *data, bool repeat); + +#ifdef __cplusplus +} +#endif + +/// @} NEC_IR
\ No newline at end of file diff --git a/platform/atm2/ATM22xx-x1x/driver/keyboard/keyboard.h b/platform/atm2/ATM22xx-x1x/driver/keyboard/keyboard.h new file mode 100644 index 0000000..d243602 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/keyboard/keyboard.h @@ -0,0 +1,60 @@ +/** + ******************************************************************************* + * + * @file keyboard.h + * + * @brief keyboard driver + * + * Copyright (C) Atmosic 2018-2021 + * + ******************************************************************************* + */ + +#pragma once + +/** + * @defgroup KEYBOARD KEYBOARD + * @ingroup DRIVERS + * @brief User driver for KSM module. + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/// Key matrix event +typedef enum ksm_event_s { + /// A key was released. + KSM_RELEASE, + /// A Key was pressed. + KSM_PRESS, + /// Hardware overflow error. + KSM_ERR_HW_OVF +} ksm_event_t; + +/** + * @brief Callback function prototype + * @param[in] event True if the key is pressed + * @param[in] idx Key index which is used in KSM_RELEASE and KSM_PRESS event. + * The index is Ri*Cn + Ci where Ci, Cn and Ri are column index, number of + * columns and row index respectively. + * @param[in] ctx Context from keyboard_run() + */ +typedef void (*keyboard_cb)(ksm_event_t event, uint32_t idx, void const *ctx); + +/** + * @brief Register callbacks and activate device. + * The callback is called from SW event. + * @param[in] callback Callback function. Called when a new keyboard + * event occurred. + * @param[in] ctx Context passed to callback + */ +__NONNULL(1) +void keyboard_run(keyboard_cb callback, void const *ctx); + +#ifdef __cplusplus +} +#endif + +/// @} KEYBOARD diff --git a/platform/atm2/ATM22xx-x1x/driver/keyboard/keyboard_internal.h b/platform/atm2/ATM22xx-x1x/driver/keyboard/keyboard_internal.h new file mode 100644 index 0000000..9f3b750 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/keyboard/keyboard_internal.h @@ -0,0 +1,262 @@ +/** + ******************************************************************************* + * + * @file keyboard_internal.h + * + * @brief keyboard ini helper macro + * This file is only included by keyboard_init() to reduce the context length. + * + * Copyright (C) Atmosic 2018-2021 + * + ******************************************************************************* + */ +#ifdef __KEYBOARD_INIT_USAGE__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Macro for setting mux +#define KSM_COL_SET(x) do { \ + if (!(ksm_pin_check & (1ULL << PIN_COL##x))) { \ + DEBUG_TRACE("P%d is not supported.", PIN_COL##x); \ + ASSERT_ERR(0); \ + } \ + PINMUX_KSO_SET(x); \ + col[COL##x##_KSO] = x; \ +} while (0) + +#define KSM_ROW_SET(x) do { \ + if (!(ksm_pin_check & (1ULL << PIN_ROW##x))) { \ + DEBUG_TRACE("P%d is not supported.", PIN_ROW##x); \ + ASSERT_ERR(0); \ + } \ + PINMUX_KSI_SET(x); \ + row[ROW##x##_KSI] = x; \ +} while (0) + +#if (MAX_ROW > 0) && defined(PIN_ROW0) && defined(ROW0_KSI) + KSM_ROW_SET(0); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW0); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 0) && defined(PIN_ROW0) && defined(ROW0_KSI) + +#if (MAX_ROW > 1) && defined(PIN_ROW1) && defined(ROW1_KSI) + KSM_ROW_SET(1); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW1); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 1) && defined(PIN_ROW1) && defined(ROW1_KSI) + +#if (MAX_ROW > 2) && defined(PIN_ROW2) && defined(ROW2_KSI) + KSM_ROW_SET(2); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW2); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 2) && defined(PIN_ROW2) && defined(ROW2_KSI) + +#if (MAX_ROW > 3) && defined(PIN_ROW3) && defined(ROW3_KSI) + KSM_ROW_SET(3); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW3); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 3) && defined(PIN_ROW3) && defined(ROW3_KSI) + +#if (MAX_ROW > 4) && defined(PIN_ROW4) && defined(ROW4_KSI) + KSM_ROW_SET(4); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW4); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 4) && defined(PIN_ROW4) && defined(ROW4_KSI) + +#if (MAX_ROW > 5) && defined(PIN_ROW5) && defined(ROW5_KSI) + KSM_ROW_SET(5); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW5); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 5) && defined(PIN_ROW5) && defined(ROW5_KSI) + +#if (MAX_ROW > 6) && defined(PIN_ROW6) && defined(ROW6_KSI) + KSM_ROW_SET(6); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW6); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 6) && defined(PIN_ROW6) && defined(ROW6_KSI) + +#if (MAX_ROW > 7) && defined(PIN_ROW7) && defined(ROW7_KSI) + KSM_ROW_SET(7); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW7); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 7) && defined(PIN_ROW7) && defined(ROW7_KSI) + +#if (MAX_ROW > 8) && defined(PIN_ROW8) && defined(ROW8_KSI) + KSM_ROW_SET(8); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW8); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 8) && defined(PIN_ROW8) && defined(ROW8_KSI) + +#if (MAX_ROW > 9) && defined(PIN_ROW9) && defined(ROW9_KSI) + KSM_ROW_SET(9); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW9); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 9) && defined(PIN_ROW9) && defined(ROW9_KSI) + +#if (MAX_ROW > 10) && defined(PIN_ROW10) && defined(ROW10_KSI) + KSM_ROW_SET(10); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW10); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 10) && defined(PIN_ROW10) && defined(ROW10_KSI) + +#if (MAX_ROW > 11) && defined(PIN_ROW11) && defined(ROW11_KSI) + KSM_ROW_SET(11); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW11); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 11) && defined(PIN_ROW11) && defined(ROW11_KSI) + +#if (MAX_ROW > 12) && defined(PIN_ROW12) && defined(ROW12_KSI) + KSM_ROW_SET(12); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW12); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 12) && defined(PIN_ROW12) && defined(ROW12_KSI) + +#if (MAX_ROW > 13) && defined(PIN_ROW13) && defined(ROW13_KSI) + KSM_ROW_SET(13); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW13); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 13) && defined(PIN_ROW13) && defined(ROW13_KSI) + +#if (MAX_ROW > 14) && defined(PIN_ROW14) && defined(ROW14_KSI) + KSM_ROW_SET(14); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW14); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 14) && defined(PIN_ROW14) && defined(ROW14_KSI) + +#if (MAX_ROW > 15) && defined(PIN_ROW15) && defined(ROW15_KSI) + KSM_ROW_SET(15); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW15); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 15) && defined(PIN_ROW15) && defined(ROW15_KSI) + +#if (MAX_ROW > 16) && defined(PIN_ROW16) && defined(ROW16_KSI) + KSM_ROW_SET(16); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW16); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 16) && defined(PIN_ROW16) && defined(ROW16_KSI) + +#if (MAX_ROW > 17) && defined(PIN_ROW17) && defined(ROW17_KSI) + KSM_ROW_SET(17); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW17); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 17) && defined(PIN_ROW17) && defined(ROW17_KSI) + +#if (MAX_ROW > 18) && defined(PIN_ROW18) && defined(ROW18_KSI) + KSM_ROW_SET(18); +#ifdef KSI_PULLUPS + PIN_PULLUP(PIN_ROW18); +#endif // KSI_PULLUPS +#endif // (MAX_ROW > 18) && defined(PIN_ROW18) && defined(ROW18_KSI) + +#if (MAX_COL > 0) && defined(PIN_COL0) && defined(COL0_KSO) + KSM_COL_SET(0); +#endif // (MAX_COL > 0) && defined(PIN_COL0) && defined(COL0_KSO) + +#if (MAX_COL > 1) && defined(PIN_COL1) && defined(COL1_KSO) + KSM_COL_SET(1); +#endif // (MAX_COL > 1) && defined(PIN_COL1) && defined(COL1_KSO) + +#if (MAX_COL > 2) && defined(PIN_COL2) && defined(COL2_KSO) + KSM_COL_SET(2); +#endif // (MAX_COL > 2) && defined(PIN_COL2) && defined(COL2_KSO) + +#if (MAX_COL > 3) && defined(PIN_COL3) && defined(COL3_KSO) + KSM_COL_SET(3); +#endif // (MAX_COL > 3) && defined(PIN_COL3) && defined(COL3_KSO) + +#if (MAX_COL > 4) && defined(PIN_COL4) && defined(COL4_KSO) + KSM_COL_SET(4); +#endif // (MAX_COL > 4) && defined(PIN_COL4) && defined(COL4_KSO) + +#if (MAX_COL > 5) && defined(PIN_COL5) && defined(COL5_KSO) + KSM_COL_SET(5); +#endif // (MAX_COL > 5) && defined(PIN_COL5) && defined(COL5_KSO) + +#if (MAX_COL > 6) && defined(PIN_COL6) && defined(COL6_KSO) + KSM_COL_SET(6); +#endif // (MAX_COL > 6) && defined(PIN_COL6) && defined(COL6_KSO) + +#if (MAX_COL > 7) && defined(PIN_COL7) && defined(COL7_KSO) + KSM_COL_SET(7); +#endif // (MAX_COL > 7) && defined(PIN_COL7) && defined(COL7_KSO) + +#if (MAX_COL > 8) && defined(PIN_COL8) && defined(COL8_KSO) + KSM_COL_SET(8); +#endif // (MAX_COL > 8) && defined(PIN_COL8) && defined(COL8_KSO) + +#if (MAX_COL > 9) && defined(PIN_COL9) && defined(COL9_KSO) + KSM_COL_SET(9); +/// In hw_cfg_pseq_init, the P1 was pullup to avoid leakage on designs +/// that tie TMC high. But if P1 is used for column of keymatrix, pullup will +/// cause current leakage when keyscan. So here clears the pull up for P1. +#if (PIN_COL9 == 1) + PIN_PULL_CLR(PIN_COL9); +#endif +#endif // (MAX_COL > 9) && defined(PIN_COL9) && defined(COL9_KSO) + +#if (MAX_COL > 10) && defined(PIN_COL10) && defined(COL10_KSO) + KSM_COL_SET(10); +#endif // (MAX_COL > 10) && defined(PIN_COL10) && defined(COL10_KSO) + +#if (MAX_COL > 11) && defined(PIN_COL11) && defined(COL11_KSO) + KSM_COL_SET(11); +#endif // (MAX_COL > 11) && defined(PIN_COL11) && defined(COL11_KSO) + +#if (MAX_COL > 12) && defined(PIN_COL12) && defined(COL12_KSO) + KSM_COL_SET(12); +#endif // (MAX_COL > 12) && defined(PIN_COL12) && defined(COL12_KSO) + +#if (MAX_COL > 13) && defined(PIN_COL13) && defined(COL13_KSO) + KSM_COL_SET(13); +#endif // (MAX_COL > 13) && defined(PIN_COL13) && defined(COL13_KSO) + +#if (MAX_COL > 14) && defined(PIN_COL14) && defined(COL14_KSO) + KSM_COL_SET(14); +#endif // (MAX_COL > 14) && defined(PIN_COL14) && defined(COL14_KSO) + +#if (MAX_COL > 15) && defined(PIN_COL15) && defined(COL15_KSO) + KSM_COL_SET(15); +#endif // (MAX_COL > 15) && defined(PIN_COL15) && defined(COL15_KSO) + +#if (MAX_COL > 16) && defined(PIN_COL16) && defined(COL16_KSO) + KSM_COL_SET(16); +#endif // (MAX_COL > 16) && defined(PIN_COL16) && defined(COL16_KSO) + +#if (MAX_COL > 17) && defined(PIN_COL17) && defined(COL17_KSO) + KSM_COL_SET(17); +#endif // (MAX_COL > 17) && defined(PIN_COL17) && defined(COL17_KSO) + +#if (MAX_COL > 18) && defined(PIN_COL18) && defined(COL18_KSO) + KSM_COL_SET(18); +#endif // (MAX_COL > 18) && defined(PIN_COL18) && defined(COL18_KSO) + +#if (MAX_COL > 19) && defined(PIN_COL19) && defined(COL19_KSO) + KSM_COL_SET(19); +#endif // (MAX_COL > 19) && defined(PIN_COL19) && defined(COL19_KSO) + +#ifdef __cplusplus +} +#endif + +#undef __KEYBOARD_INIT_USAGE__ +#endif // __KEYBOARD_INIT_USAGE__ diff --git a/platform/atm2/ATM22xx-x1x/driver/led_blink/led_blink.h b/platform/atm2/ATM22xx-x1x/driver/led_blink/led_blink.h new file mode 100644 index 0000000..278a792 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/led_blink/led_blink.h @@ -0,0 +1,84 @@ +/** + ******************************************************************************* + * + * @file led_blink.h + * + * @brief LED control + * + * Copyright (C) Atmosic 2020-2021 + * + ******************************************************************************* + */ +#pragma once + +/** + ******************************************************************************* + * @defgroup LED LED driver + * @ingroup DRIVERS + * @brief ATM bluetooth framework LED driver + * + * This module contains the necessary function of LED. + * + * @{ + ******************************************************************************* + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/// LED ID type +typedef uint8_t led_id_t; + +/// LED enum +enum { + /// LED_0 + LED_0, + /// LED_1 + LED_1, + + /// LED_MAX + LED_MAX +}; + +/** + ******************************************************************************* + * @brief Config LED blink parameter + * @param[in] id LED ID + * @param[in] hi_dur LED hi activity time(unit: 10ms) + * @param[in] low_dur LED low activity time(unit: 10ms) + * @param[in] times The count for Hi+Low LED activity + ******************************************************************************* + */ +void led_blink(led_id_t id, uint16_t hi_dur, uint16_t low_dur, uint16_t times); + +/** + ******************************************************************************* + * @brief Turn on LED + * @param[in] id LED ID + ******************************************************************************* + */ +void led_on(led_id_t id); + +/** + ******************************************************************************* + * @brief Turn off LED + * @param[in] id LED ID + ******************************************************************************* + */ +void led_off(led_id_t id); + +/** + ******************************************************************************* + * @brief Get LED status + * @param[in] id LED ID + * @return LED pin value. + ******************************************************************************* + */ +bool led_status(led_id_t id); + +#ifdef __cplusplus +} +#endif + +///@} LED diff --git a/platform/atm2/ATM22xx-x1x/driver/sw_event/sw_event.h b/platform/atm2/ATM22xx-x1x/driver/sw_event/sw_event.h new file mode 100644 index 0000000..adcf1df --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/sw_event/sw_event.h @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * + * @file sw_event.h + * + * @brief Atmosic Software Event Driver + * + * Copyright (C) Atmosic 2020 + * + ****************************************************************************** + */ + +#ifndef __SW_EVENT_H__ +#define __SW_EVENT_H__ + +/** + * @defgroup SW_EVENT Software Event APIs + * @ingroup DRIVERS + * @brief User driver for application to use software events + * @{ + */ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/// Maximum number of concurrent events - adjust as needed +#define SW_EVENT_ID_MAX 8 + +/// Event ID type +typedef uint8_t sw_event_id_t; + +/// Event triggered callback function type +typedef void (*sw_event_func_t)(sw_event_id_t event_id, const void *ctx); + +/** + * @brief Allocate and configure event + * @param[in] handler Event triggered callback (called from main event loop) + * @param[in] ctx Context to pass to handler + * @return Event ID + */ +sw_event_id_t sw_event_alloc(sw_event_func_t handler, const void *ctx); + +/** + * @brief Deallocate event + * @note Caller must guarantee that set/clear methods are not invoked from + * an ISR while this method is running + * @param[in] event_id Event ID from sw_event_alloc() + */ +void sw_event_free(sw_event_id_t event_id); + +/** + * @brief Reconfigure event handler and context + * @param[in] event_id Event ID from sw_event_alloc() + * @param[in] handler Event triggered callback (called from main event loop) + * @param[in] ctx Context to pass to handler + */ +void sw_event_reconfig(sw_event_id_t event_id, sw_event_func_t handler, + const void *ctx); + +/** + * @brief Trigger event + * @note Safe to be called from ISR + * @param[in] event_id Event ID from sw_event_alloc() + */ +void sw_event_set(sw_event_id_t event_id); + +/** + * @brief Clear event + * @note Safe to be called from ISR + * @param[in] event_id Event ID from sw_event_alloc() + */ +void sw_event_clear(sw_event_id_t event_id); + +/** + * @brief Get event status + * @param[in] event_id Event ID from sw_event_alloc() + * @return True when event is valid and triggered + */ +bool sw_event_get(sw_event_id_t event_id); + +#ifdef __cplusplus +} +#endif + +/// @} SW_EVENT + +#endif // __SW_EVENT_H__ diff --git a/platform/atm2/ATM22xx-x1x/driver/sw_timer/sw_timer.h b/platform/atm2/ATM22xx-x1x/driver/sw_timer/sw_timer.h new file mode 100644 index 0000000..1f249e5 --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/sw_timer/sw_timer.h @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * + * @file sw_timer.h + * + * @brief Atmosic Software Timer Driver + * + * Copyright (C) Atmosic 2020-2021 + * + ****************************************************************************** + */ + +#ifndef __SW_TIMER_H__ +#define __SW_TIMER_H__ + +/** + * @defgroup SW_TIMER Software Timer APIs + * @ingroup DRIVERS + * @brief User driver for application to use software timers + * @{ + */ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/// Maximum number of concurrent timers - adjust as needed +#ifndef SW_TIMER_ID_MAX +#define SW_TIMER_ID_MAX 8 +#endif // SW_TIMER_ID_MAX + +/// Smallest granularity for sw_timer_set() +#define SW_TIMER_10_MS 1 +/// Commonly used quantity for sw_timer_set() +#define SW_TIMER_1_SEC 100 + +/// Timer ID type +typedef uint8_t sw_timer_id_t; + +/// Timer expired callback function type +typedef void (*sw_timer_func_t)(sw_timer_id_t timer_id, const void *ctx); + +/** + * @brief Allocate and configure timer + * @param[in] handler Timer expired callback (called from main event loop) + * @param[in] ctx Context to pass to handler + * @return Timer ID + */ +sw_timer_id_t sw_timer_alloc(sw_timer_func_t handler, const void *ctx); + +/** + * @brief Deallocate timer + * @param[in] timer_id Timer ID from sw_timer_alloc() + */ +void sw_timer_free(sw_timer_id_t timer_id); + +/** + * @brief Reconfigure timer handler and context + * @param[in] timer_id Timer ID from sw_timer_alloc() + * @param[in] handler Timer expired callback (called from main event loop) + * @param[in] ctx Context to pass to handler + */ +void sw_timer_reconfig(sw_timer_id_t timer_id, sw_timer_func_t handler, + const void *ctx); + +/** + * @brief Start one-shot timer running + * @param[in] timer_id Timer ID from sw_timer_alloc() + * @param[in] centisec Duration in hundredths of seconds + */ +void sw_timer_set(sw_timer_id_t timer_id, uint32_t centisec); + +/** + * @brief Stop/abort running timer + * @param[in] timer_id Timer ID from sw_timer_alloc() + */ +void sw_timer_clear(sw_timer_id_t timer_id); + +/** + * @brief Get timer status + * @param[in] timer_id Timer ID from sw_timer_alloc() + * @return True when timer is valid and running + */ +bool sw_timer_active(sw_timer_id_t timer_id); + +#ifdef __cplusplus +} +#endif + +/// @} SW_TIMER + +#endif // __SW_TIMER_H__ diff --git a/platform/atm2/ATM22xx-x1x/driver/timer/timer.h b/platform/atm2/ATM22xx-x1x/driver/timer/timer.h new file mode 100644 index 0000000..ac5d77c --- /dev/null +++ b/platform/atm2/ATM22xx-x1x/driver/timer/timer.h @@ -0,0 +1,266 @@ +/** + ****************************************************************************** + * + * @file timer.h + * + * @brief Atmosic Timer Driver + * + * Copyright (C) Atmosic 2019-2022 + * + ****************************************************************************** + */ + +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#include "at_wrpr.h" + +/** + * @defgroup TIMER HW Timer APIs + * @ingroup DRIVERS + * @brief User driver for application to use HW timers + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/// Number of centisecond per second +#define CS_PER_SEC 100 + +/// Number of millisecond per second +#define MS_PER_SEC 1000 + +/// Number of millisecond per centisecond +#define MS_PER_CS 10 + +/// Number of microsecond per centisecond +#define US_PER_CS 10000 + +/// Number of microsecond per millisecond +#define US_PER_MS 1000 + +/// Number of second per minute +#define SEC_PER_MIN 60 + +/// Number of minute per hour +#define MIN_PER_HOUR 60 + +typedef enum { + ATM_TIMER0 = 0, + ATM_TIMER1 = 1, + ATM_DUALTIMER1 = 2, + ATM_DUALTIMER2 = 3, + ATM_SYSTICK = 4, + ATM_SLWTIMER = 5, // Runs off 32Khz clock + ATM_TIMERS_MAX = 6 +} atm_timer_id_t; + +typedef enum { + ATM_TIMER_MODE_SINGLE_SHOT = 0, + ATM_TIMER_MODE_PERIODIC = 1, + ATM_TIMER_MODE_MAX = 2 +} atm_timer_mode_t; + +typedef enum { + ATM_TIMER_SUCCESS = 0, + ATM_TIMER_INVALID_PARAM = 1, + ATM_TIMER_RESOURCE_BUSY = 2, + ATM_TIMER_GENERIC_ERROR = 3 +} atm_timer_error_t; + +typedef void (*atm_timer_callback_t) (void *app_context); + +/** + * @brief Setup timer. + * @param[in] id Timer ID + * @param[in] mode SingleShot vs Periodic + * @param[in] timeout_handler Application layer callback handler + * (called from interrupt context) + * @return Success or Error status + */ +atm_timer_error_t atm_timer_setup(atm_timer_id_t id, atm_timer_mode_t mode, + atm_timer_callback_t timeout_handler); + +/** + * @brief Start timer. + * @param[in] id Timer ID + * @param[in] timeout_us Timer value in micro seconds + * @param[in] app_context Application specific context + * @return Success or Error status + */ +atm_timer_error_t atm_timer_start(atm_timer_id_t id, uint32_t timeout_us, + void *app_context); + +/** + * @brief Start dual timer with more accurate unit.(Only for single shot mode) + * @param[in] id Dual timer ID + * @param[in] timeout_cycles Timer value in cycles + */ +void atm_dual_timer_single_shot_quick_start(atm_timer_id_t id, + uint32_t timeout_cycles); + +/** + * @brief Stop timer. + * @param[in] id Timer ID + * @return Success or Error status + */ +atm_timer_error_t atm_timer_stop(atm_timer_id_t id); + +/** + * @brief Busy wait using CMSDK_PSEQ->CURRENT_REAL_TIME. + * @param[in] msec Delay value in milliseconds + * @return Success or Error status + */ +atm_timer_error_t atm_timer_mdelay(uint32_t msec); + +/** + * @brief Busy wait using the Cortex-M0 SysTick. + * @param[in] usec Delay value in microseconds + * @return Success or Error status + */ +atm_timer_error_t atm_timer_udelay(uint32_t usec); + +/** + * @brief Sleep in WFI using a timer. + * @param[in] id Timer ID + * @param[in] usec Timer value in microseconds + * @return Success or Error status + */ +atm_timer_error_t atm_timer_usleep(atm_timer_id_t id, uint32_t usec); + +// Permit customization for restrictive calling contexts +// or to analyze rt{,1,2,3} locals +#ifndef TIMER_ASSERT_ERR +#define TIMER_ASSERT_ERR ASSERT_ERR +#endif + +/** + * @brief Get the current system time based on the 32kHz clock + */ +__INLINE uint32_t atm_get_sys_time(void) +{ + // The high clock domain latch low clock domain signal directly + // would probably get bad value due to metastability. Considering + // the combinations, it could have 3 conditions: + // 1. bad -> good -> good + // 2. good -> good + // 3. good -> bad -> good -> good + + uint32_t rt; + WRPR_CTRL_PUSH(CMSDK_PSEQ, WRPR_CTRL__CLK_ENABLE) { + GLOBAL_INT_DISABLE(); + uint32_t rt1 = CMSDK_PSEQ->CURRENT_REAL_TIME; + rt = CMSDK_PSEQ->CURRENT_REAL_TIME; + if (rt != rt1) { + uint32_t rt3 = CMSDK_PSEQ->CURRENT_REAL_TIME; + if (rt != rt3) { + __UNUSED uint32_t rt2 = rt; + rt = CMSDK_PSEQ->CURRENT_REAL_TIME; + TIMER_ASSERT_ERR(rt == rt3); + } + } + GLOBAL_INT_RESTORE(); + } WRPR_CTRL_POP(); + return rt; +} + +#ifdef LPC_RCOS +/** + * @brief Fetch LP clock frequency + * + * @return Value in Hz, or 0 when using a xtal + */ +uint32_t lpc_rcos_hz(void); + +#define TIMER_GET_LPC_FREQ ({ \ + uint32_t lp_hz = lpc_rcos_hz(); \ + lp_hz ? lp_hz : 32768; \ +}) +#else +#define TIMER_GET_LPC_FREQ (32768) +#endif + +/** + * @brief Busy wait using CMSDK_PSEQ->CURRENT_REAL_TIME. + * @param[in] ticks Delay value in counts of CMSDK_PSEQ->CURRENT_REAL_TIME. + * @return Success or Error status + */ +__INLINE void atm_timer_lpc_delay(uint32_t ticks) +{ + uint32_t then = atm_get_sys_time(); + while (atm_get_sys_time() - then < ticks) { + YIELD(); + } +} + +/** + * @brief Translate centiseconds to ticks + * @param[in] cs Number of centiseconds + * @return LPC duration + */ +static inline uint32_t atm_cs_to_lpc(uint32_t cs) +{ + return ((uint64_t)cs * TIMER_GET_LPC_FREQ) / CS_PER_SEC; +} + +/** + * @brief Translate milliseconds to ticks + * @param[in] ms Number of milliseconds + * @return LPC duration + */ +static inline uint32_t atm_ms_to_lpc(uint32_t ms) +{ + return ((uint64_t)ms * TIMER_GET_LPC_FREQ) / MS_PER_SEC; +} + +/** + * @brief Translate microseconds to ticks + * @param[in] us Number of microseconds + * @return LPC duration + */ +static inline uint32_t atm_us_to_lpc(uint64_t us) +{ + return (us * TIMER_GET_LPC_FREQ) / (US_PER_MS * MS_PER_SEC); +} + +/** + * @brief Translate ticks to centiseconds + * @param[in] lpc LPC duration + * @return Number of centiseconds + */ +static inline uint32_t atm_lpc_to_cs(uint32_t lpc) +{ + return ((uint64_t)lpc * CS_PER_SEC) / TIMER_GET_LPC_FREQ; +} + +/** + * @brief Translate ticks to milliseconds + * @param[in] lpc LPC duration + * @return Number of milliseconds + */ +static inline uint32_t atm_lpc_to_ms(uint32_t lpc) +{ + return ((uint64_t)lpc * MS_PER_SEC) / TIMER_GET_LPC_FREQ; +} + +/** + * @brief Translate ticks to microseconds + * @param[in] lpc LPC duration + * @return Number of microseconds + */ +static inline uint64_t atm_lpc_to_us(uint32_t lpc) +{ + return ((uint64_t)lpc * US_PER_MS * MS_PER_SEC) / TIMER_GET_LPC_FREQ; +} + +#undef TIMER_GET_LPC_FREQ + +#ifdef __cplusplus +} +#endif + +/// @} TIMER + +#endif // __TIMER_H__ |