Sensor Watch Simulator (#35)
* Put something on screen * Use the 32bit watch_date_time repr to pass from JS * Implement periodic callbacks * Clear display on enabling * Hook up watch_set_led_color() to SVG (green-only) * Make debug output full-width * Remove default Emscripten canvas * Implement sleep and button clicks * Fix time zone conversion bug in beats-time app * Clean up warnings * Fix pin levels * Set time zone to browser value (if available) * Add basic backup data saving * Silence format specifier warnings in both targets * Remove unnecessary, copied files * Use RTC pointer to clear callbacks (if available) * Use preprocessor define to avoid hardcoding MOVEMENT_NUM_FACES * Change each face to const preprocessor definition * Remove Intl.DateTimeFormat usage * Update shell.html title, header * Add touch start/end event handlers on SVG buttons * Update shell.html * Update folder structure (shared, simulator, hardware under watch-library) * Tease out shared components from watch_slcd * Clean up simulator watch_slcd.c inline JS calls * Fix missing newlines at end of file * Add simulator warnings (except format, unused-paremter) * Implement remaining watch_rtc functions * Fix button bug on mouse down then drag out * Implement remaining watch_slcd functions * Link keyboard events to buttons (for keys A, L, M) * Rewrite event handling (mouse, touch, keyboard) in C * Set explicit text UTF-8 charset in shell.html * Address PR comments * Remove unused directories from include paths
This commit is contained in:
202
watch-library/hardware/hpl/core/hpl_core_m0plus_base.c
Normal file
202
watch-library/hardware/hpl/core/hpl_core_m0plus_base.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Core 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_core.h>
|
||||
#include <hpl_irq.h>
|
||||
#include <hpl_reset.h>
|
||||
#include <hpl_sleep.h>
|
||||
#include <hpl_delay.h>
|
||||
#ifndef _UNIT_TEST_
|
||||
#include <utils.h>
|
||||
#endif
|
||||
#include <utils_assert.h>
|
||||
#include <peripheral_clk_config.h>
|
||||
|
||||
#ifndef CONF_CPU_FREQUENCY
|
||||
#define CONF_CPU_FREQUENCY 1000000
|
||||
#endif
|
||||
|
||||
#if CONF_CPU_FREQUENCY < 1000
|
||||
#define CPU_FREQ_POWER 3
|
||||
#elif CONF_CPU_FREQUENCY < 10000
|
||||
#define CPU_FREQ_POWER 4
|
||||
#elif CONF_CPU_FREQUENCY < 100000
|
||||
#define CPU_FREQ_POWER 5
|
||||
#elif CONF_CPU_FREQUENCY < 1000000
|
||||
#define CPU_FREQ_POWER 6
|
||||
#elif CONF_CPU_FREQUENCY < 10000000
|
||||
#define CPU_FREQ_POWER 7
|
||||
#elif CONF_CPU_FREQUENCY < 100000000
|
||||
#define CPU_FREQ_POWER 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The array of interrupt handlers
|
||||
*/
|
||||
struct _irq_descriptor *_irq_table[PERIPH_COUNT_IRQn];
|
||||
|
||||
/**
|
||||
* \brief Reset MCU
|
||||
*/
|
||||
void _reset_mcu(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Put MCU to sleep
|
||||
*/
|
||||
void _go_to_sleep(void)
|
||||
{
|
||||
__DSB();
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve current IRQ number
|
||||
*/
|
||||
uint8_t _irq_get_current(void)
|
||||
{
|
||||
return (uint8_t)__get_IPSR() - 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable the given IRQ
|
||||
*/
|
||||
void _irq_disable(uint8_t n)
|
||||
{
|
||||
NVIC_DisableIRQ((IRQn_Type)n);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the given IRQ
|
||||
*/
|
||||
void _irq_set(uint8_t n)
|
||||
{
|
||||
NVIC_SetPendingIRQ((IRQn_Type)n);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear the given IRQ
|
||||
*/
|
||||
void _irq_clear(uint8_t n)
|
||||
{
|
||||
NVIC_ClearPendingIRQ((IRQn_Type)n);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable the given IRQ
|
||||
*/
|
||||
void _irq_enable(uint8_t n)
|
||||
{
|
||||
NVIC_EnableIRQ((IRQn_Type)n);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Register IRQ handler
|
||||
*/
|
||||
void _irq_register(const uint8_t n, struct _irq_descriptor *const irq)
|
||||
{
|
||||
ASSERT(n < PERIPH_COUNT_IRQn);
|
||||
|
||||
_irq_table[n] = irq;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Default interrupt handler for unused IRQs.
|
||||
*/
|
||||
void Default_Handler(void)
|
||||
{
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve the amount of cycles to delay for the given amount of us
|
||||
*/
|
||||
static inline uint32_t _get_cycles_for_us_internal(const uint16_t us, const uint32_t freq, const uint8_t power)
|
||||
{
|
||||
switch (power) {
|
||||
case 8:
|
||||
return (us * (freq / 100000) - 1) / 10 + 1;
|
||||
case 7:
|
||||
return (us * (freq / 10000) - 1) / 100 + 1;
|
||||
case 6:
|
||||
return (us * (freq / 1000) - 1) / 1000 + 1;
|
||||
case 5:
|
||||
return (us * (freq / 100) - 1) / 10000 + 1;
|
||||
case 4:
|
||||
return (us * (freq / 10) - 1) / 100000 + 1;
|
||||
default:
|
||||
return (us * freq - 1) / 1000000 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve the amount of cycles to delay for the given amount of us
|
||||
*/
|
||||
uint32_t _get_cycles_for_us(const uint16_t us)
|
||||
{
|
||||
int32_t freq = hri_usbdevice_get_CTRLA_ENABLE_bit(USB) ? 8000000 : 4000000;
|
||||
return _get_cycles_for_us_internal(us, freq, CPU_FREQ_POWER);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve the amount of cycles to delay for the given amount of ms
|
||||
*/
|
||||
static inline uint32_t _get_cycles_for_ms_internal(const uint16_t ms, const uint32_t freq, const uint8_t power)
|
||||
{
|
||||
switch (power) {
|
||||
case 8:
|
||||
return (ms * (freq / 100000)) * 100;
|
||||
case 7:
|
||||
return (ms * (freq / 10000)) * 10;
|
||||
case 6:
|
||||
return (ms * (freq / 1000));
|
||||
case 5:
|
||||
return (ms * (freq / 100) - 1) / 10 + 1;
|
||||
case 4:
|
||||
return (ms * (freq / 10) - 1) / 100 + 1;
|
||||
default:
|
||||
return (ms * freq - 1) / 1000 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve the amount of cycles to delay for the given amount of ms
|
||||
*/
|
||||
uint32_t _get_cycles_for_ms(const uint16_t ms)
|
||||
{
|
||||
int32_t freq = hri_usbdevice_get_CTRLA_ENABLE_bit(USB) ? 8000000 : 4000000;
|
||||
return _get_cycles_for_ms_internal(ms, freq, CPU_FREQ_POWER);
|
||||
}
|
||||
63
watch-library/hardware/hpl/core/hpl_core_port.h
Normal file
63
watch-library/hardware/hpl/core/hpl_core_port.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Core related 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _HPL_CORE_PORT_H_INCLUDED
|
||||
#define _HPL_CORE_PORT_H_INCLUDED
|
||||
|
||||
#include <peripheral_clk_config.h>
|
||||
|
||||
/* It's possible to include this file in ARM ASM files (e.g., in FreeRTOS IAR
|
||||
* portable implement, portasm.s -> FreeRTOSConfig.h -> hpl_core_port.h),
|
||||
* there will be assembling errors.
|
||||
* So the following things are not included for assembling.
|
||||
*/
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
|
||||
#ifndef _UNIT_TEST_
|
||||
#include <compiler.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Check if it's in ISR handling
|
||||
* \return \c true if it's in ISR
|
||||
*/
|
||||
static inline bool _is_in_isr(void)
|
||||
{
|
||||
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
|
||||
}
|
||||
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
void Default_Handler(void);
|
||||
|
||||
#endif /* _HPL_CORE_PORT_H_INCLUDED */
|
||||
74
watch-library/hardware/hpl/core/hpl_init.c
Normal file
74
watch-library/hardware/hpl/core/hpl_init.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief HPL 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 <hpl_gpio.h>
|
||||
#include <hpl_init.h>
|
||||
#include <hpl_gclk_base.h>
|
||||
#include <hpl_mclk_config.h>
|
||||
|
||||
#include <hpl_dma.h>
|
||||
#include <hpl_dmac_config.h>
|
||||
|
||||
/* Referenced GCLKs (out of 0~4), should be initialized firstly
|
||||
*/
|
||||
#define _GCLK_INIT_1ST 0x00000000
|
||||
/* Not referenced GCLKs, initialized last */
|
||||
#define _GCLK_INIT_LAST 0x0000001F
|
||||
|
||||
/**
|
||||
* \brief Initialize the hardware abstraction layer
|
||||
*/
|
||||
void _init_chip(void)
|
||||
{
|
||||
hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, CONF_NVM_WAIT_STATE);
|
||||
|
||||
_set_performance_level(2);
|
||||
|
||||
_osc32kctrl_init_sources();
|
||||
_oscctrl_init_sources();
|
||||
_mclk_init();
|
||||
#if _GCLK_INIT_1ST
|
||||
_gclk_init_generators_by_fref(_GCLK_INIT_1ST);
|
||||
#endif
|
||||
_oscctrl_init_referenced_generators();
|
||||
_gclk_init_generators_by_fref(_GCLK_INIT_LAST);
|
||||
|
||||
#if CONF_DMAC_ENABLE
|
||||
hri_mclk_set_AHBMASK_DMAC_bit(MCLK);
|
||||
_dma_init();
|
||||
#endif
|
||||
|
||||
#if (CONF_PORT_EVCTRL_PORT_0 | CONF_PORT_EVCTRL_PORT_1 | CONF_PORT_EVCTRL_PORT_2 | CONF_PORT_EVCTRL_PORT_3)
|
||||
_port_event_init();
|
||||
#endif
|
||||
}
|
||||
244
watch-library/hardware/hpl/dmac/hpl_dmac.c
Normal file
244
watch-library/hardware/hpl/dmac/hpl_dmac.c
Normal file
@@ -0,0 +1,244 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Generic DMAC related functionality.
|
||||
*
|
||||
* Copyright (c) 2016-2019 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 <compiler.h>
|
||||
#include <hpl_dma.h>
|
||||
#include <hpl_dmac_config.h>
|
||||
#include <utils.h>
|
||||
#include <utils_assert.h>
|
||||
#include <utils_repeat_macro.h>
|
||||
|
||||
#if CONF_DMAC_ENABLE
|
||||
|
||||
/* Section containing first descriptors for all DMAC channels */
|
||||
COMPILER_ALIGNED(16)
|
||||
DmacDescriptor _descriptor_section[DMAC_CH_NUM] SECTION_DMAC_DESCRIPTOR;
|
||||
|
||||
/* Section containing current descriptors for all DMAC channels */
|
||||
COMPILER_ALIGNED(16)
|
||||
DmacDescriptor _write_back_section[DMAC_CH_NUM] SECTION_DMAC_DESCRIPTOR;
|
||||
|
||||
/* Array containing callbacks for DMAC channels */
|
||||
static struct _dma_resource _resources[DMAC_CH_NUM];
|
||||
|
||||
/* This macro DMAC configuration */
|
||||
#define DMAC_CHANNEL_CFG(i, n) \
|
||||
{(CONF_DMAC_RUNSTDBY_##n << DMAC_CHCTRLA_RUNSTDBY_Pos) | (CONF_DMAC_ENABLE_##n << DMAC_CHCTRLA_ENABLE_Pos), \
|
||||
DMAC_CHCTRLB_TRIGACT(CONF_DMAC_TRIGACT_##n) | DMAC_CHCTRLB_TRIGSRC(CONF_DMAC_TRIGSRC_##n) \
|
||||
| DMAC_CHCTRLB_LVL(CONF_DMAC_LVL_##n) | (CONF_DMAC_EVOE_##n << DMAC_CHCTRLB_EVOE_Pos) \
|
||||
| (CONF_DMAC_EVIE_##n << DMAC_CHCTRLB_EVIE_Pos) | DMAC_CHCTRLB_EVACT(CONF_DMAC_EVACT_##n), \
|
||||
DMAC_BTCTRL_STEPSIZE(CONF_DMAC_STEPSIZE_##n) | (CONF_DMAC_STEPSEL_##n << DMAC_BTCTRL_STEPSEL_Pos) \
|
||||
| (CONF_DMAC_DSTINC_##n << DMAC_BTCTRL_DSTINC_Pos) | (CONF_DMAC_SRCINC_##n << DMAC_BTCTRL_SRCINC_Pos) \
|
||||
| DMAC_BTCTRL_BEATSIZE(CONF_DMAC_BEATSIZE_##n) | DMAC_BTCTRL_BLOCKACT(CONF_DMAC_BLOCKACT_##n) \
|
||||
| DMAC_BTCTRL_EVOSEL(CONF_DMAC_EVOSEL_##n)},
|
||||
|
||||
/* DMAC channel configuration */
|
||||
struct dmac_channel_cfg {
|
||||
uint8_t ctrla;
|
||||
uint32_t ctrlb;
|
||||
uint16_t btctrl;
|
||||
};
|
||||
|
||||
/* DMAC channel configurations */
|
||||
const static struct dmac_channel_cfg _cfgs[] = {REPEAT_MACRO(DMAC_CHANNEL_CFG, i, DMAC_CH_NUM)};
|
||||
|
||||
/**
|
||||
* \brief Initialize DMAC
|
||||
*/
|
||||
int32_t _dma_init(void)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
hri_dmac_clear_CTRL_DMAENABLE_bit(DMAC);
|
||||
hri_dmac_clear_CTRL_CRCENABLE_bit(DMAC);
|
||||
hri_dmac_set_CHCTRLA_SWRST_bit(DMAC);
|
||||
|
||||
hri_dmac_write_CTRL_reg(DMAC,
|
||||
(CONF_DMAC_LVLEN0 << DMAC_CTRL_LVLEN0_Pos) | (CONF_DMAC_LVLEN1 << DMAC_CTRL_LVLEN1_Pos)
|
||||
| (CONF_DMAC_LVLEN2 << DMAC_CTRL_LVLEN2_Pos)
|
||||
| (CONF_DMAC_LVLEN3 << DMAC_CTRL_LVLEN3_Pos));
|
||||
hri_dmac_write_DBGCTRL_DBGRUN_bit(DMAC, CONF_DMAC_DBGRUN);
|
||||
|
||||
hri_dmac_write_QOSCTRL_reg(DMAC,
|
||||
DMAC_QOSCTRL_WRBQOS(CONF_DMAC_WRBQOS) | DMAC_QOSCTRL_FQOS(CONF_DMAC_FQOS)
|
||||
| DMAC_QOSCTRL_DQOS(CONF_DMAC_DQOS));
|
||||
|
||||
hri_dmac_write_PRICTRL0_reg(
|
||||
DMAC,
|
||||
DMAC_PRICTRL0_LVLPRI0(CONF_DMAC_LVLPRI0) | DMAC_PRICTRL0_LVLPRI1(CONF_DMAC_LVLPRI1)
|
||||
| DMAC_PRICTRL0_LVLPRI2(CONF_DMAC_LVLPRI2) | DMAC_PRICTRL0_LVLPRI3(CONF_DMAC_LVLPRI3)
|
||||
| (CONF_DMAC_RRLVLEN0 << DMAC_PRICTRL0_RRLVLEN0_Pos) | (CONF_DMAC_RRLVLEN1 << DMAC_PRICTRL0_RRLVLEN1_Pos)
|
||||
| (CONF_DMAC_RRLVLEN2 << DMAC_PRICTRL0_RRLVLEN2_Pos) | (CONF_DMAC_RRLVLEN3 << DMAC_PRICTRL0_RRLVLEN3_Pos));
|
||||
hri_dmac_write_BASEADDR_reg(DMAC, (uint32_t)_descriptor_section);
|
||||
hri_dmac_write_WRBADDR_reg(DMAC, (uint32_t)_write_back_section);
|
||||
|
||||
for (; i < DMAC_CH_NUM; i++) {
|
||||
hri_dmac_write_CHID_reg(DMAC, i);
|
||||
|
||||
hri_dmac_write_CHCTRLA_RUNSTDBY_bit(DMAC, _cfgs[i].ctrla & DMAC_CHCTRLA_RUNSTDBY);
|
||||
|
||||
hri_dmac_write_CHCTRLB_reg(DMAC, _cfgs[i].ctrlb);
|
||||
hri_dmacdescriptor_write_BTCTRL_reg(&_descriptor_section[i], _cfgs[i].btctrl);
|
||||
hri_dmacdescriptor_write_DESCADDR_reg(&_descriptor_section[i], 0x0);
|
||||
}
|
||||
|
||||
NVIC_DisableIRQ(DMAC_IRQn);
|
||||
NVIC_ClearPendingIRQ(DMAC_IRQn);
|
||||
NVIC_EnableIRQ(DMAC_IRQn);
|
||||
|
||||
hri_dmac_set_CTRL_DMAENABLE_bit(DMAC);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable/disable DMA interrupt
|
||||
*/
|
||||
void _dma_set_irq_state(const uint8_t channel, const enum _dma_callback_type type, const bool state)
|
||||
{
|
||||
hri_dmac_write_CHID_reg(DMAC, channel);
|
||||
|
||||
if (DMA_TRANSFER_COMPLETE_CB == type) {
|
||||
hri_dmac_write_CHINTEN_TCMPL_bit(DMAC, state);
|
||||
} else if (DMA_TRANSFER_ERROR_CB == type) {
|
||||
hri_dmac_write_CHINTEN_TERR_bit(DMAC, state);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t _dma_set_destination_address(const uint8_t channel, const void *const dst)
|
||||
{
|
||||
hri_dmacdescriptor_write_DSTADDR_reg(&_descriptor_section[channel], (uint32_t)dst);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _dma_set_source_address(const uint8_t channel, const void *const src)
|
||||
{
|
||||
hri_dmacdescriptor_write_SRCADDR_reg(&_descriptor_section[channel], (uint32_t)src);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _dma_set_next_descriptor(const uint8_t current_channel, const uint8_t next_channel)
|
||||
{
|
||||
hri_dmacdescriptor_write_DESCADDR_reg(&_descriptor_section[current_channel],
|
||||
(uint32_t)&_descriptor_section[next_channel]);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _dma_srcinc_enable(const uint8_t channel, const bool enable)
|
||||
{
|
||||
hri_dmacdescriptor_write_BTCTRL_SRCINC_bit(&_descriptor_section[channel], enable);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _dma_set_data_amount(const uint8_t channel, const uint32_t amount)
|
||||
{
|
||||
uint32_t address = hri_dmacdescriptor_read_DSTADDR_reg(&_descriptor_section[channel]);
|
||||
uint8_t beat_size = hri_dmacdescriptor_read_BTCTRL_BEATSIZE_bf(&_descriptor_section[channel]);
|
||||
|
||||
if (hri_dmacdescriptor_get_BTCTRL_DSTINC_bit(&_descriptor_section[channel])) {
|
||||
hri_dmacdescriptor_write_DSTADDR_reg(&_descriptor_section[channel], address + amount * (1 << beat_size));
|
||||
}
|
||||
|
||||
address = hri_dmacdescriptor_read_SRCADDR_reg(&_descriptor_section[channel]);
|
||||
|
||||
if (hri_dmacdescriptor_get_BTCTRL_SRCINC_bit(&_descriptor_section[channel])) {
|
||||
hri_dmacdescriptor_write_SRCADDR_reg(&_descriptor_section[channel], address + amount * (1 << beat_size));
|
||||
}
|
||||
|
||||
hri_dmacdescriptor_write_BTCNT_reg(&_descriptor_section[channel], amount);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _dma_enable_transaction(const uint8_t channel, const bool software_trigger)
|
||||
{
|
||||
hri_dmac_write_CHID_reg(DMAC, channel);
|
||||
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[channel]);
|
||||
hri_dmac_set_CHCTRLA_ENABLE_bit(DMAC);
|
||||
if (software_trigger) {
|
||||
hri_dmac_set_SWTRIGCTRL_reg(DMAC, 1 << channel);
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _dma_get_channel_resource(struct _dma_resource **resource, const uint8_t channel)
|
||||
{
|
||||
*resource = &_resources[channel];
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _dma_dstinc_enable(const uint8_t channel, const bool enable)
|
||||
{
|
||||
hri_dmacdescriptor_write_BTCTRL_DSTINC_bit(&_descriptor_section[channel], enable);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal DMAC interrupt handler
|
||||
*/
|
||||
static inline void _dmac_handler(void)
|
||||
{
|
||||
uint8_t channel = hri_dmac_read_INTPEND_ID_bf(DMAC);
|
||||
uint8_t current_channel = hri_dmac_read_CHID_reg(DMAC);
|
||||
uint8_t flag_status;
|
||||
struct _dma_resource *tmp_resource = &_resources[channel];
|
||||
|
||||
hri_dmac_write_CHID_reg(DMAC, channel);
|
||||
flag_status = hri_dmac_get_CHINTFLAG_reg(DMAC, DMAC_CHINTFLAG_MASK);
|
||||
|
||||
if (flag_status & DMAC_CHINTFLAG_TERR) {
|
||||
hri_dmac_clear_CHINTFLAG_TERR_bit(DMAC);
|
||||
tmp_resource->dma_cb.error(tmp_resource);
|
||||
} else if (flag_status & DMAC_CHINTFLAG_TCMPL) {
|
||||
hri_dmac_clear_CHINTFLAG_TCMPL_bit(DMAC);
|
||||
tmp_resource->dma_cb.transfer_done(tmp_resource);
|
||||
}
|
||||
hri_dmac_write_CHID_reg(DMAC, current_channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief DMAC interrupt handler
|
||||
*/
|
||||
void DMAC_Handler(void)
|
||||
{
|
||||
_dmac_handler();
|
||||
}
|
||||
|
||||
#endif /* CONF_DMAC_ENABLE */
|
||||
255
watch-library/hardware/hpl/eic/hpl_eic.c
Normal file
255
watch-library/hardware/hpl/eic/hpl_eic.c
Normal file
@@ -0,0 +1,255 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief EIC related 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 <compiler.h>
|
||||
#include <hpl_eic_config.h>
|
||||
#include <hpl_ext_irq.h>
|
||||
#include <string.h>
|
||||
#include <utils.h>
|
||||
#include <utils_assert.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define ffs __builtin_ffs
|
||||
#endif
|
||||
#if defined(__CC_ARM) || defined(__ICCARM__)
|
||||
/* Find the first bit set */
|
||||
static int ffs(int v)
|
||||
{
|
||||
int i, bit = 1;
|
||||
for (i = 0; i < sizeof(int) * 8; i++) {
|
||||
if (v & bit) {
|
||||
return i + 1;
|
||||
}
|
||||
bit <<= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Invalid external interrupt and pin numbers
|
||||
*/
|
||||
#define INVALID_EXTINT_NUMBER 0xFF
|
||||
#define INVALID_PIN_NUMBER 0xFFFFFFFF
|
||||
|
||||
#ifndef CONFIG_EIC_EXTINT_MAP
|
||||
/** Dummy mapping to pass compiling. */
|
||||
#define CONFIG_EIC_EXTINT_MAP \
|
||||
{ \
|
||||
INVALID_EXTINT_NUMBER, INVALID_PIN_NUMBER \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define EXT_IRQ_AMOUNT 6
|
||||
|
||||
/**
|
||||
* \brief EXTINTx and pin number map
|
||||
*/
|
||||
struct _eic_map {
|
||||
uint8_t extint;
|
||||
uint32_t pin;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief PIN and EXTINT map for enabled external interrupts
|
||||
*/
|
||||
static const struct _eic_map _map[] = {CONFIG_EIC_EXTINT_MAP};
|
||||
|
||||
/**
|
||||
* \brief The callback to upper layer's interrupt processing routine
|
||||
*/
|
||||
static void (*callback)(const uint32_t pin);
|
||||
|
||||
static void _ext_irq_handler(void);
|
||||
|
||||
/**
|
||||
* \brief Initialize external interrupt module
|
||||
*/
|
||||
int32_t _ext_irq_init(void (*cb)(const uint32_t pin))
|
||||
{
|
||||
if (!hri_eic_is_syncing(EIC, EIC_SYNCBUSY_SWRST)) {
|
||||
if (hri_eic_get_CTRLA_reg(EIC, EIC_CTRLA_ENABLE)) {
|
||||
hri_eic_clear_CTRLA_ENABLE_bit(EIC);
|
||||
hri_eic_wait_for_sync(EIC, EIC_SYNCBUSY_ENABLE);
|
||||
}
|
||||
hri_eic_write_CTRLA_reg(EIC, EIC_CTRLA_SWRST);
|
||||
}
|
||||
hri_eic_wait_for_sync(EIC, EIC_SYNCBUSY_SWRST);
|
||||
|
||||
hri_eic_write_CTRLA_CKSEL_bit(EIC, CONF_EIC_CKSEL);
|
||||
|
||||
hri_eic_write_NMICTRL_reg(EIC,
|
||||
(CONF_EIC_NMIFILTEN << EIC_NMICTRL_NMIFILTEN_Pos)
|
||||
| EIC_NMICTRL_NMISENSE(CONF_EIC_NMISENSE) | EIC_ASYNCH_ASYNCH(CONF_EIC_NMIASYNCH)
|
||||
| 0);
|
||||
|
||||
hri_eic_write_EVCTRL_reg(EIC,
|
||||
(CONF_EIC_EXTINTEO0 << 0) | (CONF_EIC_EXTINTEO1 << 1) | (CONF_EIC_EXTINTEO2 << 2)
|
||||
| (CONF_EIC_EXTINTEO3 << 3) | (CONF_EIC_EXTINTEO4 << 4) | (CONF_EIC_EXTINTEO5 << 5)
|
||||
| (CONF_EIC_EXTINTEO6 << 6) | (CONF_EIC_EXTINTEO7 << 7) | (CONF_EIC_EXTINTEO8 << 8)
|
||||
| (CONF_EIC_EXTINTEO9 << 9) | (CONF_EIC_EXTINTEO10 << 10) | (CONF_EIC_EXTINTEO11 << 11)
|
||||
| (CONF_EIC_EXTINTEO12 << 12) | (CONF_EIC_EXTINTEO13 << 13)
|
||||
| (CONF_EIC_EXTINTEO14 << 14) | (CONF_EIC_EXTINTEO15 << 15) | 0);
|
||||
hri_eic_write_ASYNCH_reg(EIC,
|
||||
(CONF_EIC_ASYNCH0 << 0) | (CONF_EIC_ASYNCH1 << 1) | (CONF_EIC_ASYNCH2 << 2)
|
||||
| (CONF_EIC_ASYNCH3 << 3) | (CONF_EIC_ASYNCH4 << 4) | (CONF_EIC_ASYNCH5 << 5)
|
||||
| (CONF_EIC_ASYNCH6 << 6) | (CONF_EIC_ASYNCH7 << 7) | (CONF_EIC_ASYNCH8 << 8)
|
||||
| (CONF_EIC_ASYNCH9 << 9) | (CONF_EIC_ASYNCH10 << 10) | (CONF_EIC_ASYNCH11 << 11)
|
||||
| (CONF_EIC_ASYNCH12 << 12) | (CONF_EIC_ASYNCH13 << 13) | (CONF_EIC_ASYNCH14 << 14)
|
||||
| (CONF_EIC_ASYNCH15 << 15) | 0);
|
||||
|
||||
hri_eic_write_CONFIG_reg(EIC,
|
||||
0,
|
||||
(CONF_EIC_FILTEN0 << EIC_CONFIG_FILTEN0_Pos) | EIC_CONFIG_SENSE0(CONF_EIC_SENSE0)
|
||||
| (CONF_EIC_FILTEN1 << EIC_CONFIG_FILTEN1_Pos) | EIC_CONFIG_SENSE1(CONF_EIC_SENSE1)
|
||||
| (CONF_EIC_FILTEN2 << EIC_CONFIG_FILTEN2_Pos) | EIC_CONFIG_SENSE2(CONF_EIC_SENSE2)
|
||||
| (CONF_EIC_FILTEN3 << EIC_CONFIG_FILTEN3_Pos) | EIC_CONFIG_SENSE3(CONF_EIC_SENSE3)
|
||||
| (CONF_EIC_FILTEN4 << EIC_CONFIG_FILTEN4_Pos) | EIC_CONFIG_SENSE4(CONF_EIC_SENSE4)
|
||||
| (CONF_EIC_FILTEN5 << EIC_CONFIG_FILTEN5_Pos) | EIC_CONFIG_SENSE5(CONF_EIC_SENSE5)
|
||||
| (CONF_EIC_FILTEN6 << EIC_CONFIG_FILTEN6_Pos) | EIC_CONFIG_SENSE6(CONF_EIC_SENSE6)
|
||||
| (CONF_EIC_FILTEN7 << EIC_CONFIG_FILTEN7_Pos) | EIC_CONFIG_SENSE7(CONF_EIC_SENSE7)
|
||||
| 0);
|
||||
|
||||
hri_eic_write_CONFIG_reg(EIC,
|
||||
1,
|
||||
(CONF_EIC_FILTEN8 << EIC_CONFIG_FILTEN0_Pos) | EIC_CONFIG_SENSE0(CONF_EIC_SENSE8)
|
||||
| (CONF_EIC_FILTEN9 << EIC_CONFIG_FILTEN1_Pos) | EIC_CONFIG_SENSE1(CONF_EIC_SENSE9)
|
||||
| (CONF_EIC_FILTEN10 << EIC_CONFIG_FILTEN2_Pos) | EIC_CONFIG_SENSE2(CONF_EIC_SENSE10)
|
||||
| (CONF_EIC_FILTEN11 << EIC_CONFIG_FILTEN3_Pos) | EIC_CONFIG_SENSE3(CONF_EIC_SENSE11)
|
||||
| (CONF_EIC_FILTEN12 << EIC_CONFIG_FILTEN4_Pos) | EIC_CONFIG_SENSE4(CONF_EIC_SENSE12)
|
||||
| (CONF_EIC_FILTEN13 << EIC_CONFIG_FILTEN5_Pos) | EIC_CONFIG_SENSE5(CONF_EIC_SENSE13)
|
||||
| (CONF_EIC_FILTEN14 << EIC_CONFIG_FILTEN6_Pos) | EIC_CONFIG_SENSE6(CONF_EIC_SENSE14)
|
||||
| (CONF_EIC_FILTEN15 << EIC_CONFIG_FILTEN7_Pos) | EIC_CONFIG_SENSE7(CONF_EIC_SENSE15)
|
||||
| 0);
|
||||
|
||||
hri_eic_set_CTRLA_ENABLE_bit(EIC);
|
||||
NVIC_DisableIRQ(EIC_IRQn);
|
||||
NVIC_ClearPendingIRQ(EIC_IRQn);
|
||||
NVIC_EnableIRQ(EIC_IRQn);
|
||||
|
||||
callback = cb;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief De-initialize external interrupt module
|
||||
*/
|
||||
int32_t _ext_irq_deinit(void)
|
||||
{
|
||||
NVIC_DisableIRQ(EIC_IRQn);
|
||||
callback = NULL;
|
||||
|
||||
hri_eic_clear_CTRLA_ENABLE_bit(EIC);
|
||||
hri_eic_set_CTRLA_SWRST_bit(EIC);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable / disable external irq
|
||||
*/
|
||||
int32_t _ext_irq_enable(const uint32_t pin, const bool enable)
|
||||
{
|
||||
uint8_t extint = INVALID_EXTINT_NUMBER;
|
||||
uint8_t i = 0;
|
||||
|
||||
for (; i < ARRAY_SIZE(_map); i++) {
|
||||
if (_map[i].pin == pin) {
|
||||
extint = _map[i].extint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (INVALID_EXTINT_NUMBER == extint) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
hri_eic_set_INTEN_reg(EIC, 1ul << extint);
|
||||
} else {
|
||||
hri_eic_clear_INTEN_reg(EIC, 1ul << extint);
|
||||
hri_eic_clear_INTFLAG_reg(EIC, 1ul << extint);
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Inter EIC interrupt handler
|
||||
*/
|
||||
static void _ext_irq_handler(void)
|
||||
{
|
||||
volatile uint32_t flags = hri_eic_read_INTFLAG_reg(EIC);
|
||||
int8_t pos;
|
||||
uint32_t pin = INVALID_PIN_NUMBER;
|
||||
|
||||
hri_eic_clear_INTFLAG_reg(EIC, flags);
|
||||
|
||||
ASSERT(callback);
|
||||
|
||||
while (flags) {
|
||||
pos = ffs(flags) - 1;
|
||||
while (-1 != pos) {
|
||||
uint8_t lower = 0, middle, upper = EXT_IRQ_AMOUNT;
|
||||
|
||||
while (upper >= lower) {
|
||||
middle = (upper + lower) >> 1;
|
||||
if (_map[middle].extint == pos) {
|
||||
pin = _map[middle].pin;
|
||||
break;
|
||||
}
|
||||
if (_map[middle].extint < pos) {
|
||||
lower = middle + 1;
|
||||
} else {
|
||||
upper = middle - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (INVALID_PIN_NUMBER != pin) {
|
||||
callback(pin);
|
||||
}
|
||||
flags &= ~(1ul << pos);
|
||||
pos = ffs(flags) - 1;
|
||||
}
|
||||
flags = hri_eic_read_INTFLAG_reg(EIC);
|
||||
hri_eic_clear_INTFLAG_reg(EIC, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief EIC interrupt handler
|
||||
*/
|
||||
void EIC_Handler(void)
|
||||
{
|
||||
_ext_irq_handler();
|
||||
}
|
||||
164
watch-library/hardware/hpl/gclk/hpl_gclk.c
Normal file
164
watch-library/hardware/hpl/gclk/hpl_gclk.c
Normal file
@@ -0,0 +1,164 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Generic Clock Controller related functionality.
|
||||
*
|
||||
* 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 <hpl_gclk_config.h>
|
||||
#include <hpl_gclk_base.h>
|
||||
#include <hpl_init.h>
|
||||
#include <utils_assert.h>
|
||||
|
||||
/* Compatible naming definition */
|
||||
#ifndef GCLK_GENCTRL_SRC_DPLL
|
||||
#define GCLK_GENCTRL_SRC_DPLL GCLK_GENCTRL_SRC_FDPLL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initializes generators
|
||||
*/
|
||||
void _gclk_init_generators(void)
|
||||
{
|
||||
|
||||
#if CONF_GCLK_GENERATOR_0_CONFIG == 1
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
0,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_0_DIV) | (CONF_GCLK_GEN_0_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_0_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_0_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_0_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_0_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_0_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_0_SOURCE);
|
||||
#endif
|
||||
|
||||
#if CONF_GCLK_GENERATOR_1_CONFIG == 1
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
1,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_1_DIV) | (CONF_GCLK_GEN_1_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_1_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_1_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_1_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_1_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_1_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_1_SOURCE);
|
||||
#endif
|
||||
|
||||
#if CONF_GCLK_GENERATOR_2_CONFIG == 1
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
2,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_2_DIV) | (CONF_GCLK_GEN_2_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_2_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_2_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_2_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_2_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_2_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_2_SOURCE);
|
||||
#endif
|
||||
|
||||
#if CONF_GCLK_GENERATOR_3_CONFIG == 1
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
3,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_3_DIV) | (CONF_GCLK_GEN_3_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_3_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_3_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_3_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_3_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_3_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_3_SOURCE);
|
||||
#endif
|
||||
|
||||
#if CONF_GCLK_GENERATOR_4_CONFIG == 1
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
4,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_4_DIV) | (CONF_GCLK_GEN_4_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_4_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_4_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_4_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_4_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_4_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_4_SOURCE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _gclk_init_generators_by_fref(uint32_t bm)
|
||||
{
|
||||
|
||||
#if CONF_GCLK_GENERATOR_0_CONFIG == 1
|
||||
if (bm & (1ul << 0)) {
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
0,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_0_DIV) | (CONF_GCLK_GEN_0_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_0_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_0_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_0_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_0_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_0_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_0_SOURCE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONF_GCLK_GENERATOR_1_CONFIG == 1
|
||||
if (bm & (1ul << 1)) {
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
1,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_1_DIV) | (CONF_GCLK_GEN_1_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_1_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_1_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_1_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_1_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_1_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_1_SOURCE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONF_GCLK_GENERATOR_2_CONFIG == 1
|
||||
if (bm & (1ul << 2)) {
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
2,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_2_DIV) | (CONF_GCLK_GEN_2_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_2_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_2_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_2_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_2_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_2_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_2_SOURCE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONF_GCLK_GENERATOR_3_CONFIG == 1
|
||||
if (bm & (1ul << 3)) {
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
3,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_3_DIV) | (CONF_GCLK_GEN_3_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_3_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_3_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_3_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_3_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_3_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_3_SOURCE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONF_GCLK_GENERATOR_4_CONFIG == 1
|
||||
if (bm & (1ul << 4)) {
|
||||
hri_gclk_write_GENCTRL_reg(
|
||||
GCLK,
|
||||
4,
|
||||
GCLK_GENCTRL_DIV(CONF_GCLK_GEN_4_DIV) | (CONF_GCLK_GEN_4_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_GCLK_GEN_4_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) | (CONF_GCLK_GEN_4_OE << GCLK_GENCTRL_OE_Pos)
|
||||
| (CONF_GCLK_GEN_4_OOV << GCLK_GENCTRL_OOV_Pos) | (CONF_GCLK_GEN_4_IDC << GCLK_GENCTRL_IDC_Pos)
|
||||
| (CONF_GCLK_GENERATOR_4_CONFIG << GCLK_GENCTRL_GENEN_Pos) | CONF_GCLK_GEN_4_SOURCE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
87
watch-library/hardware/hpl/gclk/hpl_gclk_base.h
Normal file
87
watch-library/hardware/hpl/gclk/hpl_gclk_base.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Generic Clock Controller.
|
||||
*
|
||||
* 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_GCLK_H_INCLUDED
|
||||
#define _HPL_GCLK_H_INCLUDED
|
||||
|
||||
#include <compiler.h>
|
||||
#ifdef _UNIT_TEST_
|
||||
#include <hri_gclk1_v210_mock.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup gclk_group GCLK Hardware Proxy Layer
|
||||
*
|
||||
* \section gclk_hpl_rev Revision History
|
||||
* - v0.0.0.1 Initial Commit
|
||||
*
|
||||
*@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \name HPL functions
|
||||
*/
|
||||
//@{
|
||||
/**
|
||||
* \brief Enable clock on the given channel with the given clock source
|
||||
*
|
||||
* This function maps the given clock source to the given clock channel
|
||||
* and enables channel.
|
||||
*
|
||||
* \param[in] channel The channel to enable clock for
|
||||
* \param[in] source The clock source for the given channel
|
||||
*/
|
||||
static inline void _gclk_enable_channel(const uint8_t channel, const uint8_t source)
|
||||
{
|
||||
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, channel, source | GCLK_PCHCTRL_CHEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize GCLK generators by function references
|
||||
* \param[in] bm Bit mapping for referenced generators,
|
||||
* a bit 1 in position triggers generator initialization.
|
||||
*/
|
||||
void _gclk_init_generators_by_fref(uint32_t bm);
|
||||
|
||||
//@}
|
||||
/**@}*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HPL_GCLK_H_INCLUDED */
|
||||
46
watch-library/hardware/hpl/mclk/hpl_mclk.c
Normal file
46
watch-library/hardware/hpl/mclk/hpl_mclk.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Main Clock.
|
||||
*
|
||||
* 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 <compiler.h>
|
||||
#include <hpl_mclk_config.h>
|
||||
#include <hpl_init.h>
|
||||
|
||||
/**
|
||||
* \brief Initialize master clock generator
|
||||
*/
|
||||
void _mclk_init(void)
|
||||
{
|
||||
void *hw = (void *)MCLK;
|
||||
hri_mclk_write_BUPDIV_reg(hw, MCLK_BUPDIV_BUPDIV(CONF_MCLK_BUPDIV));
|
||||
hri_mclk_write_CPUDIV_reg(hw, MCLK_CPUDIV_CPUDIV(CONF_MCLK_CPUDIV));
|
||||
}
|
||||
782
watch-library/hardware/hpl/nvmctrl/hpl_nvmctrl.c
Executable file
782
watch-library/hardware/hpl/nvmctrl/hpl_nvmctrl.c
Executable file
@@ -0,0 +1,782 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Non-Volatile Memory Controller
|
||||
*
|
||||
* 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 <hpl_flash.h>
|
||||
#include <hpl_user_area.h>
|
||||
#include <string.h>
|
||||
#include <utils_assert.h>
|
||||
#include <utils.h>
|
||||
#include <hpl_nvmctrl_config.h>
|
||||
|
||||
#define NVM_MEMORY ((volatile uint16_t *)FLASH_ADDR)
|
||||
|
||||
/**
|
||||
* \brief NVM configuration type
|
||||
*/
|
||||
struct nvm_configuration {
|
||||
hri_nvmctrl_ctrlb_reg_t ctrlb; /*!< Control B Register */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Array of NVM configurations
|
||||
*/
|
||||
static struct nvm_configuration _nvm
|
||||
= {(CONF_NVM_CACHE << NVMCTRL_CTRLB_CACHEDIS_Pos) | (CONF_NVM_READ_MODE << NVMCTRL_CTRLB_READMODE_Pos)
|
||||
| (CONF_NVM_SLEEPPRM << NVMCTRL_CTRLB_SLEEPPRM_Pos)};
|
||||
|
||||
/*!< Pointer to hpl device */
|
||||
static struct _flash_device *_nvm_dev = NULL;
|
||||
|
||||
static void _flash_erase_row(void *const hw, const uint32_t dst_addr, uint32_t nvmctrl_cmd);
|
||||
static void _flash_program(void *const hw, const uint32_t dst_addr, const uint8_t *buffer, const uint16_t size,
|
||||
uint32_t nvmctrl_cmd);
|
||||
|
||||
/**
|
||||
* \brief Initialize NVM
|
||||
*/
|
||||
int32_t _flash_init(struct _flash_device *const device, void *const hw)
|
||||
{
|
||||
ASSERT(device && (hw == NVMCTRL));
|
||||
uint32_t ctrlb;
|
||||
|
||||
device->hw = hw;
|
||||
ctrlb = _nvm.ctrlb & ~(NVMCTRL_CTRLB_RWS_Msk | NVMCTRL_CTRLB_MANW);
|
||||
ctrlb |= hri_nvmctrl_get_CTRLB_reg(device->hw, NVMCTRL_CTRLB_RWS_Msk | NVMCTRL_CTRLB_MANW);
|
||||
hri_nvmctrl_write_CTRLB_reg(device->hw, ctrlb);
|
||||
|
||||
_nvm_dev = device;
|
||||
NVIC_DisableIRQ(NVMCTRL_IRQn);
|
||||
NVIC_ClearPendingIRQ(NVMCTRL_IRQn);
|
||||
NVIC_EnableIRQ(NVMCTRL_IRQn);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief De-initialize NVM
|
||||
*/
|
||||
void _flash_deinit(struct _flash_device *const device)
|
||||
{
|
||||
device->hw = NULL;
|
||||
NVIC_DisableIRQ(NVMCTRL_IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the flash page size.
|
||||
*/
|
||||
uint32_t _flash_get_page_size(struct _flash_device *const device)
|
||||
{
|
||||
(void)device;
|
||||
return (uint32_t)NVMCTRL_PAGE_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the numbers of flash page.
|
||||
*/
|
||||
uint32_t _flash_get_total_pages(struct _flash_device *const device)
|
||||
{
|
||||
(void)device;
|
||||
return (uint32_t)FLASH_NB_OF_PAGES;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the number of wait states for read and write operations.
|
||||
*/
|
||||
uint8_t _flash_get_wait_state(struct _flash_device *const device)
|
||||
{
|
||||
return hri_nvmctrl_get_CTRLB_reg(device->hw, NVMCTRL_CTRLB_RWS_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the number of wait states for read and write operations.
|
||||
*/
|
||||
void _flash_set_wait_state(struct _flash_device *const device, uint8_t state)
|
||||
{
|
||||
hri_nvmctrl_write_CTRLB_RWS_bf(device->hw, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads a number of bytes to a page in the internal Flash.
|
||||
*/
|
||||
void _flash_read(struct _flash_device *const device, const uint32_t src_addr, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
uint32_t nvm_address = src_addr / 2;
|
||||
uint32_t i;
|
||||
uint16_t data;
|
||||
|
||||
/* Check if the module is busy */
|
||||
while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
/* Clear flags */
|
||||
hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
|
||||
|
||||
/* Check whether byte address is word-aligned*/
|
||||
if (src_addr % 2) {
|
||||
data = NVM_MEMORY[nvm_address++];
|
||||
buffer[0] = data >> 8;
|
||||
i = 1;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
/* NVM _must_ be accessed as a series of 16-bit words, perform manual copy
|
||||
* to ensure alignment */
|
||||
while (i < length) {
|
||||
data = NVM_MEMORY[nvm_address++];
|
||||
buffer[i] = (data & 0xFF);
|
||||
if (i < (length - 1)) {
|
||||
buffer[i + 1] = (data >> 8);
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes a number of bytes to a page in the internal Flash.
|
||||
*/
|
||||
void _flash_write(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
uint8_t tmp_buffer[NVMCTRL_ROW_PAGES][NVMCTRL_PAGE_SIZE];
|
||||
uint32_t row_start_addr, row_end_addr;
|
||||
uint32_t i, j, k;
|
||||
uint32_t wr_start_addr = dst_addr;
|
||||
|
||||
do {
|
||||
row_start_addr = wr_start_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
|
||||
row_end_addr = row_start_addr + NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE - 1;
|
||||
|
||||
/* store the erase data into temp buffer before write */
|
||||
for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
|
||||
_flash_read(device, row_start_addr + i * NVMCTRL_PAGE_SIZE, tmp_buffer[i], NVMCTRL_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* temp buffer update */
|
||||
j = (wr_start_addr - row_start_addr) / NVMCTRL_PAGE_SIZE;
|
||||
k = wr_start_addr - row_start_addr - j * NVMCTRL_PAGE_SIZE;
|
||||
while ((wr_start_addr <= row_end_addr) && (length > 0)) {
|
||||
tmp_buffer[j][k] = *buffer;
|
||||
k = (k + 1) % NVMCTRL_PAGE_SIZE;
|
||||
if (0 == k) {
|
||||
j++;
|
||||
}
|
||||
wr_start_addr++;
|
||||
buffer++;
|
||||
length--;
|
||||
}
|
||||
|
||||
/* erase row before write */
|
||||
_flash_erase_row(device->hw, row_start_addr, NVMCTRL_CTRLA_CMD_ER);
|
||||
|
||||
/* write buffer to flash */
|
||||
for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
|
||||
_flash_program(device->hw,
|
||||
row_start_addr + i * NVMCTRL_PAGE_SIZE,
|
||||
tmp_buffer[i],
|
||||
NVMCTRL_PAGE_SIZE,
|
||||
NVMCTRL_CTRLA_CMD_WP);
|
||||
}
|
||||
|
||||
} while (row_end_addr < (wr_start_addr + length - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Appends a number of bytes in the internal Flash.
|
||||
*/
|
||||
void _flash_append(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
uint32_t page_start_addr = dst_addr & ~(NVMCTRL_PAGE_SIZE - 1);
|
||||
uint32_t size;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (dst_addr != page_start_addr) {
|
||||
/* Need to write some data to the end of a page */
|
||||
size = min(length, NVMCTRL_PAGE_SIZE - (dst_addr - page_start_addr));
|
||||
_flash_program(device->hw, dst_addr, buffer, size, NVMCTRL_CTRLA_CMD_WP);
|
||||
page_start_addr += NVMCTRL_PAGE_SIZE;
|
||||
offset += size;
|
||||
}
|
||||
|
||||
while (offset < length) {
|
||||
size = min(length - offset, NVMCTRL_PAGE_SIZE);
|
||||
_flash_program(device->hw, page_start_addr, buffer + offset, size, NVMCTRL_CTRLA_CMD_WP);
|
||||
page_start_addr += NVMCTRL_PAGE_SIZE;
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Execute erase in the internal flash
|
||||
*/
|
||||
void _flash_erase(struct _flash_device *const device, uint32_t dst_addr, uint32_t page_nums)
|
||||
{
|
||||
uint8_t tmp_buffer[NVMCTRL_PAGE_SIZE];
|
||||
uint32_t row_start_addr;
|
||||
uint32_t i;
|
||||
|
||||
row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
|
||||
|
||||
memset(tmp_buffer, 0xFF, NVMCTRL_PAGE_SIZE);
|
||||
|
||||
/* when address is not aligned with row start address */
|
||||
if (dst_addr != row_start_addr) {
|
||||
row_start_addr += NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE;
|
||||
for (i = 0; i < NVMCTRL_ROW_PAGES - 1; i++) {
|
||||
_flash_write(device, dst_addr, tmp_buffer, NVMCTRL_PAGE_SIZE);
|
||||
if (--page_nums == 0) {
|
||||
return;
|
||||
}
|
||||
dst_addr += NVMCTRL_PAGE_SIZE;
|
||||
if (dst_addr == row_start_addr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (page_nums >= NVMCTRL_ROW_PAGES) {
|
||||
_flash_erase_row(device->hw, row_start_addr, NVMCTRL_CTRLA_CMD_ER);
|
||||
row_start_addr += NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE;
|
||||
page_nums -= NVMCTRL_ROW_PAGES;
|
||||
}
|
||||
|
||||
if (page_nums != 0) {
|
||||
for (i = 0; i < page_nums; i++) {
|
||||
_flash_write(device, row_start_addr, tmp_buffer, NVMCTRL_PAGE_SIZE);
|
||||
row_start_addr += NVMCTRL_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Execute lock in the internal flash
|
||||
*/
|
||||
int32_t _flash_lock(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums)
|
||||
{
|
||||
uint32_t region_pages;
|
||||
uint32_t row_start_addr;
|
||||
|
||||
region_pages = (uint32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
|
||||
row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
|
||||
|
||||
if ((page_nums != region_pages) || (dst_addr != row_start_addr)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
/* Clear flags */
|
||||
hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
|
||||
|
||||
hri_nvmctrl_write_ADDR_reg(device->hw, dst_addr / 2);
|
||||
hri_nvmctrl_write_CTRLA_reg(device->hw, NVMCTRL_CTRLA_CMD_LR | NVMCTRL_CTRLA_CMDEX_KEY);
|
||||
|
||||
return (int32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Execute unlock in the internal flash
|
||||
*/
|
||||
int32_t _flash_unlock(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums)
|
||||
{
|
||||
uint32_t region_pages;
|
||||
uint32_t row_start_addr;
|
||||
|
||||
region_pages = (uint32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
|
||||
row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
|
||||
|
||||
if ((page_nums != region_pages) || (dst_addr != row_start_addr)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
/* Clear flags */
|
||||
hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
|
||||
|
||||
hri_nvmctrl_write_ADDR_reg(device->hw, dst_addr / 2);
|
||||
hri_nvmctrl_write_CTRLA_reg(device->hw, NVMCTRL_CTRLA_CMD_UR | NVMCTRL_CTRLA_CMDEX_KEY);
|
||||
|
||||
return (int32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief check whether the region which is pointed by address
|
||||
*/
|
||||
bool _flash_is_locked(struct _flash_device *const device, const uint32_t dst_addr)
|
||||
{
|
||||
uint16_t region_id;
|
||||
|
||||
/* Get region for given page */
|
||||
region_id = dst_addr / (NVMCTRL_FLASH_SIZE / 16);
|
||||
|
||||
return !(hri_nvmctrl_get_LOCK_reg(device->hw, 1 << region_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable/disable Flash interrupt
|
||||
*/
|
||||
void _flash_set_irq_state(struct _flash_device *const device, const enum _flash_cb_type type, const bool state)
|
||||
{
|
||||
ASSERT(device);
|
||||
|
||||
if (FLASH_DEVICE_CB_READY == type) {
|
||||
hri_nvmctrl_write_INTEN_READY_bit(device->hw, state);
|
||||
} else if (FLASH_DEVICE_CB_ERROR == type) {
|
||||
hri_nvmctrl_write_INTEN_ERROR_bit(device->hw, state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal erase a row in flash
|
||||
* \param[in] hw The pointer to hardware instance
|
||||
* \param[in] dst_addr Destination page address to erase
|
||||
*/
|
||||
static void _flash_erase_row(void *const hw, const uint32_t dst_addr, uint32_t nvmctrl_cmd)
|
||||
{
|
||||
while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
/* Clear flags */
|
||||
hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
|
||||
|
||||
/* Set address and command */
|
||||
hri_nvmctrl_write_ADDR_reg(hw, dst_addr / 2);
|
||||
hri_nvmctrl_write_CTRLA_reg(hw, nvmctrl_cmd | NVMCTRL_CTRLA_CMDEX_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal write a page in flash
|
||||
* \param[in] hw The pointer to hardware instance
|
||||
* \param[in] dst_addr Destination page address to write
|
||||
* \param[in] buffer Pointer to buffer where the data to
|
||||
* write is stored
|
||||
* \param[in] size The size of data to write to a page
|
||||
*/
|
||||
static void _flash_program(void *const hw, const uint32_t dst_addr, const uint8_t *buffer, const uint16_t size,
|
||||
uint32_t nvmctrl_cmd)
|
||||
{
|
||||
ASSERT(!(dst_addr % 2));
|
||||
|
||||
uint32_t nvm_address = dst_addr / 2;
|
||||
uint16_t i, data;
|
||||
|
||||
while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_PBC | NVMCTRL_CTRLA_CMDEX_KEY);
|
||||
|
||||
while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
/* Clear flags */
|
||||
hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
|
||||
|
||||
for (i = 0; i < size; i += 2) {
|
||||
data = buffer[i];
|
||||
if (i < NVMCTRL_PAGE_SIZE - 1) {
|
||||
data |= (buffer[i + 1] << 8);
|
||||
}
|
||||
NVM_MEMORY[nvm_address++] = data;
|
||||
}
|
||||
|
||||
while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
hri_nvmctrl_write_ADDR_reg(hw, dst_addr / 2);
|
||||
hri_nvmctrl_write_CTRLA_reg(hw, nvmctrl_cmd | NVMCTRL_CTRLA_CMDEX_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal NVM interrupt handler
|
||||
*/
|
||||
void NVMCTRL_Handler(void)
|
||||
{
|
||||
void *const hw = _nvm_dev->hw;
|
||||
|
||||
if (hri_nvmctrl_get_interrupt_READY_bit(hw)) {
|
||||
if (NULL != _nvm_dev->flash_cb.ready_cb) {
|
||||
_nvm_dev->flash_cb.ready_cb(_nvm_dev);
|
||||
}
|
||||
} else if (hri_nvmctrl_get_interrupt_ERROR_bit(hw)) {
|
||||
hri_nvmctrl_clear_interrupt_ERROR_bit(hw);
|
||||
if (NULL != _nvm_dev->flash_cb.error_cb) {
|
||||
_nvm_dev->flash_cb.error_cb(_nvm_dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The NVM User Row contains calibration data that are automatically read at device
|
||||
power on.
|
||||
The NVM User Row can be read at address 0x804000.
|
||||
*/
|
||||
#ifndef _NVM_USER_ROW_BASE
|
||||
#define _NVM_USER_ROW_BASE 0x804000
|
||||
#endif
|
||||
#define _NVM_USER_ROW_N_BITS 64
|
||||
#define _NVM_USER_ROW_N_BYTES (_NVM_USER_ROW_N_BITS / 8)
|
||||
#define _NVM_USER_ROW_END (((uint8_t *)_NVM_USER_ROW_BASE) + _NVM_USER_ROW_N_BYTES - 1)
|
||||
#define _IS_NVM_USER_ROW(b) \
|
||||
(((uint8_t *)(b) >= (uint8_t *)(_NVM_USER_ROW_BASE)) && ((uint8_t *)(b) <= (uint8_t *)(_NVM_USER_ROW_END)))
|
||||
#define _IN_NVM_USER_ROW(b, o) (((uint8_t *)(b) + (o)) <= (uint8_t *)(_NVM_USER_ROW_END))
|
||||
|
||||
/*
|
||||
The NVM Software Calibration Area can be read at address 0x806020.
|
||||
The NVM Software Calibration Area can not be written.
|
||||
*/
|
||||
#ifndef _NVM_SW_CALIB_AREA_BASE
|
||||
#define _NVM_SW_CALIB_AREA_BASE 0x806020
|
||||
#endif
|
||||
#define _NVM_SW_CALIB_AREA_N_BITS 128
|
||||
#define _NVM_SW_CALIB_AREA_N_BYTES (_NVM_SW_CALIB_AREA_N_BITS / 8)
|
||||
#define _NVM_SW_CALIB_AREA_END (((uint8_t *)_NVM_SW_CALIB_AREA_BASE) + _NVM_SW_CALIB_AREA_N_BYTES - 1)
|
||||
#define _IS_NVM_SW_CALIB_AREA(b) \
|
||||
(((uint8_t *)(b) >= (uint8_t *)_NVM_SW_CALIB_AREA_BASE) && ((uint8_t *)(b) <= (uint8_t *)_NVM_SW_CALIB_AREA_END))
|
||||
#define _IN_NVM_SW_CALIB_AREA(b, o) (((uint8_t *)(b) + (o)) <= (uint8_t *)(_NVM_SW_CALIB_AREA_END))
|
||||
|
||||
/**
|
||||
* \internal Read left aligned data bits
|
||||
* \param[in] base Base address for the data
|
||||
* \param[in] bit_offset Offset for the bitfield start
|
||||
* \param[in] n_bits Number of bits in the bitfield
|
||||
*/
|
||||
static inline uint32_t _user_area_read_l32_bits(const volatile uint32_t *base, const uint32_t bit_offset,
|
||||
const uint8_t n_bits)
|
||||
{
|
||||
return base[bit_offset >> 5] & ((1 << n_bits) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal Read right aligned data bits
|
||||
* \param[in] base Base address for the data
|
||||
* \param[in] bit_offset Offset for the bitfield start
|
||||
* \param[in] n_bits Number of bits in the bitfield
|
||||
*/
|
||||
static inline uint32_t _user_area_read_r32_bits(const volatile uint32_t *base, const uint32_t bit_offset,
|
||||
const uint8_t n_bits)
|
||||
{
|
||||
return (base[bit_offset >> 5] >> (bit_offset & 0x1F)) & ((1 << n_bits) - 1);
|
||||
}
|
||||
|
||||
int32_t _user_area_read(const void *base, const uint32_t offset, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
ASSERT(buf);
|
||||
|
||||
/** Parameter check. */
|
||||
if (_IS_NVM_USER_ROW(base)) {
|
||||
if (!_IN_NVM_USER_ROW(base, offset)) {
|
||||
return ERR_BAD_ADDRESS;
|
||||
}
|
||||
/* Cut off if request too many bytes */
|
||||
if (!_IN_NVM_USER_ROW(base, offset + size - 1)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
} else if (_IS_NVM_SW_CALIB_AREA(base)) {
|
||||
if (!_IN_NVM_SW_CALIB_AREA(base, offset)) {
|
||||
return ERR_BAD_ADDRESS;
|
||||
}
|
||||
/* Cut off if request too many bytes */
|
||||
if (!_IN_NVM_SW_CALIB_AREA(base, offset + size - 1)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
} else {
|
||||
return ERR_UNSUPPORTED_OP;
|
||||
}
|
||||
|
||||
/* Copy data */
|
||||
memcpy(buf, ((uint8_t *)base) + offset, size);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
uint32_t _user_area_read_bits(const void *base, const uint32_t bit_offset, const uint8_t n_bits)
|
||||
{
|
||||
volatile uint32_t *mem_base = (volatile uint32_t *)base;
|
||||
uint32_t l_off, l_bits;
|
||||
uint32_t r_off, r_bits;
|
||||
|
||||
/** Parameter check. */
|
||||
if (_IS_NVM_USER_ROW(base)) {
|
||||
ASSERT(_IN_NVM_USER_ROW(base, bit_offset >> 3) && _IN_NVM_USER_ROW(base, (bit_offset + n_bits - 1) >> 3));
|
||||
} else if (_IS_NVM_SW_CALIB_AREA(base)) {
|
||||
ASSERT(_IN_NVM_SW_CALIB_AREA(base, bit_offset >> 3)
|
||||
&& _IN_NVM_SW_CALIB_AREA(base, (bit_offset + n_bits - 1) >> 3));
|
||||
} else {
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
/* Since the bitfield can cross 32-bits boundaries,
|
||||
* left and right bits are read from 32-bit aligned address
|
||||
* and then combined together. */
|
||||
l_off = bit_offset & (~(32 - 1));
|
||||
r_off = l_off + 32;
|
||||
l_bits = 32 - (bit_offset & (32 - 1));
|
||||
if (n_bits > l_bits) {
|
||||
r_bits = n_bits - l_bits;
|
||||
} else {
|
||||
l_bits = n_bits;
|
||||
r_bits = 0;
|
||||
}
|
||||
return _user_area_read_r32_bits(mem_base, bit_offset, l_bits)
|
||||
+ (_user_area_read_l32_bits(mem_base, r_off, r_bits) << l_bits);
|
||||
}
|
||||
|
||||
/** \internal Write 64-bit user row
|
||||
* \param[in] _row Pointer to 64-bit user row data.
|
||||
*/
|
||||
static int32_t _user_row_write_exec(const uint32_t *_row)
|
||||
{
|
||||
Nvmctrl *hw = NVMCTRL;
|
||||
uint32_t ctrlb = hri_nvmctrl_read_CTRLB_reg(NVMCTRL);
|
||||
|
||||
/* Denie if Security Bit is set */
|
||||
if (hri_nvmctrl_get_STATUS_reg(hw, NVMCTRL_STATUS_SB)) {
|
||||
return ERR_DENIED;
|
||||
}
|
||||
|
||||
/* Do Save */
|
||||
|
||||
/* - Prepare. */
|
||||
while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
|
||||
hri_nvmctrl_set_CTRLB_MANW_bit(hw);
|
||||
|
||||
/* - Erase AUX row. */
|
||||
hri_nvmctrl_write_ADDR_reg(hw, (hri_nvmctrl_addr_reg_t)(_NVM_USER_ROW_BASE / 2));
|
||||
hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_EAR | NVMCTRL_CTRLA_CMDEX_KEY);
|
||||
while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
/* - Page buffer clear & write. */
|
||||
hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_PBC | NVMCTRL_CTRLA_CMDEX_KEY);
|
||||
while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
*((uint32_t *)NVMCTRL_AUX0_ADDRESS) = _row[0];
|
||||
*(((uint32_t *)NVMCTRL_AUX0_ADDRESS) + 1) = _row[1];
|
||||
|
||||
/* - Write AUX row. */
|
||||
hri_nvmctrl_write_ADDR_reg(hw, (hri_nvmctrl_addr_reg_t)(_NVM_USER_ROW_BASE / 2));
|
||||
hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_WAP | NVMCTRL_CTRLA_CMDEX_KEY);
|
||||
while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
|
||||
/* Wait until this module isn't busy */
|
||||
}
|
||||
|
||||
/* Restore CTRLB */
|
||||
hri_nvmctrl_write_CTRLB_reg(NVMCTRL, ctrlb);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _user_area_write(void *base, const uint32_t offset, const uint8_t *buf, const uint32_t size)
|
||||
{
|
||||
uint32_t _row[2]; /* Copy of user row. */
|
||||
|
||||
/** Parameter check. */
|
||||
if (_IS_NVM_USER_ROW(base)) {
|
||||
if (!_IN_NVM_USER_ROW(base, offset)) {
|
||||
return ERR_BAD_ADDRESS;
|
||||
} else if (!_IN_NVM_USER_ROW(base, offset + size - 1)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
} else if (_IS_NVM_SW_CALIB_AREA(base)) {
|
||||
return ERR_DENIED;
|
||||
} else {
|
||||
return ERR_UNSUPPORTED_OP;
|
||||
}
|
||||
|
||||
memcpy(_row, base, 8); /* Store previous data. */
|
||||
memcpy((uint8_t *)_row + offset, buf, size); /* Modify with buf data. */
|
||||
|
||||
return _user_row_write_exec(_row);
|
||||
}
|
||||
|
||||
int32_t _user_area_write_bits(void *base, const uint32_t bit_offset, const uint32_t bits, const uint8_t n_bits)
|
||||
{
|
||||
uint32_t _row[2]; /* Copy of user row. */
|
||||
uint32_t l_off, l_bits;
|
||||
uint32_t r_off, r_bits;
|
||||
|
||||
/** Parameter check. */
|
||||
if (_IS_NVM_USER_ROW(base)) {
|
||||
if (!_IN_NVM_USER_ROW(base, bit_offset >> 3)) {
|
||||
return ERR_BAD_ADDRESS;
|
||||
} else if (!_IN_NVM_USER_ROW(base, (bit_offset + n_bits - 1) >> 3)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
} else if (_IS_NVM_SW_CALIB_AREA(base)) {
|
||||
return ERR_DENIED;
|
||||
} else {
|
||||
return ERR_UNSUPPORTED_OP;
|
||||
}
|
||||
|
||||
/* Since the bitfield can cross 32-bits boundaries,
|
||||
* left and right bits are splitted for 32-bit aligned address
|
||||
* and then saved. */
|
||||
l_off = bit_offset & (~(32 - 1));
|
||||
r_off = l_off + 32;
|
||||
l_bits = 32 - (bit_offset & (32 - 1));
|
||||
if (n_bits > l_bits) {
|
||||
r_bits = n_bits - l_bits;
|
||||
} else {
|
||||
l_bits = n_bits;
|
||||
r_bits = 0;
|
||||
}
|
||||
|
||||
memcpy(_row, base, 8); /* Store previous data. */
|
||||
if (l_bits) {
|
||||
uint32_t l_mask = ((1 << l_bits) - 1) << (bit_offset & (32 - 1));
|
||||
_row[bit_offset >> 5] &= ~l_mask;
|
||||
_row[bit_offset >> 5] |= (bits << (bit_offset & (32 - 1))) & l_mask;
|
||||
}
|
||||
if (r_bits) {
|
||||
uint32_t r_mask = (1 << r_bits) - 1;
|
||||
_row[r_off >> 5] &= ~r_mask;
|
||||
_row[r_off >> 5] |= bits >> l_bits;
|
||||
}
|
||||
return _user_row_write_exec(_row);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return if given address is in Flash RWWEE array range.
|
||||
*/
|
||||
static bool _is_valid_rww_flash_address(uint32_t addr)
|
||||
{
|
||||
#define RWWEE_ADDR_START NVMCTRL_RWW_EEPROM_ADDR
|
||||
#define RWWEE_ADDR_END (NVMCTRL_RWW_EEPROM_ADDR + NVMCTRL_PAGE_SIZE * NVMCTRL_RWWEE_PAGES)
|
||||
|
||||
if ((addr < NVMCTRL_RWW_EEPROM_ADDR)
|
||||
|| (addr > (NVMCTRL_RWW_EEPROM_ADDR + NVMCTRL_PAGE_SIZE * NVMCTRL_RWWEE_PAGES))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the RWWEE flash page size.
|
||||
*/
|
||||
uint32_t _rww_flash_get_page_size(struct _flash_device *const device)
|
||||
{
|
||||
(void)device;
|
||||
return (uint32_t)NVMCTRL_PAGE_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the total page numbers of RWWEE flash.
|
||||
*/
|
||||
uint32_t _rww_flash_get_total_pages(struct _flash_device *const device)
|
||||
{
|
||||
(void)device;
|
||||
return (uint32_t)NVMCTRL_RWWEE_PAGES;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads a number of bytes in the internal RWWEE Flash.
|
||||
*/
|
||||
int32_t _rww_flash_read(struct _flash_device *const device, const uint32_t src_addr, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
/* Check if the address is valid */
|
||||
if (!_is_valid_rww_flash_address(src_addr) || !_is_valid_rww_flash_address(src_addr + length)) {
|
||||
return ERR_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
_flash_read(device, src_addr, buffer, length);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes a number of bytes in the internal RWWEE Flash.
|
||||
*/
|
||||
int32_t _rww_flash_write(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
uint8_t tmp_buffer[NVMCTRL_ROW_PAGES][NVMCTRL_PAGE_SIZE];
|
||||
uint32_t row_start_addr, row_end_addr;
|
||||
uint32_t i, j, k;
|
||||
uint32_t wr_start_addr = dst_addr;
|
||||
|
||||
/* Check if the address is valid */
|
||||
if (!_is_valid_rww_flash_address(dst_addr) || !_is_valid_rww_flash_address(dst_addr + length)) {
|
||||
return ERR_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
do {
|
||||
row_start_addr = wr_start_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
|
||||
row_end_addr = row_start_addr + NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE - 1;
|
||||
|
||||
/* store the erase data into temp buffer before write */
|
||||
for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
|
||||
_rww_flash_read(device, row_start_addr + i * NVMCTRL_PAGE_SIZE, tmp_buffer[i], NVMCTRL_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* temp buffer update */
|
||||
j = (wr_start_addr - row_start_addr) / NVMCTRL_PAGE_SIZE;
|
||||
k = wr_start_addr - row_start_addr - j * NVMCTRL_PAGE_SIZE;
|
||||
while ((wr_start_addr <= row_end_addr) && (length > 0)) {
|
||||
tmp_buffer[j][k] = *buffer;
|
||||
k = (k + 1) % NVMCTRL_PAGE_SIZE;
|
||||
if (0 == k) {
|
||||
j++;
|
||||
}
|
||||
wr_start_addr++;
|
||||
buffer++;
|
||||
length--;
|
||||
}
|
||||
|
||||
/* erase row before write */
|
||||
_flash_erase_row(device->hw, row_start_addr, NVMCTRL_CTRLA_CMD_RWWEEER);
|
||||
|
||||
/* write buffer to flash */
|
||||
for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
|
||||
_flash_program(device->hw,
|
||||
row_start_addr + i * NVMCTRL_PAGE_SIZE,
|
||||
tmp_buffer[i],
|
||||
NVMCTRL_PAGE_SIZE,
|
||||
NVMCTRL_CTRLA_CMD_RWWEEWP);
|
||||
}
|
||||
|
||||
} while (row_end_addr < (wr_start_addr + length - 1));
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
86
watch-library/hardware/hpl/osc32kctrl/hpl_osc32kctrl.c
Normal file
86
watch-library/hardware/hpl/osc32kctrl/hpl_osc32kctrl.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM 32k Oscillators Controller.
|
||||
*
|
||||
* 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 <hpl_init.h>
|
||||
#include <compiler.h>
|
||||
#include <hpl_osc32kctrl_config.h>
|
||||
|
||||
/**
|
||||
* \brief Initialize 32 kHz clock sources
|
||||
*/
|
||||
void _osc32kctrl_init_sources(void)
|
||||
{
|
||||
void * hw = (void *)OSC32KCTRL;
|
||||
uint16_t calib = 0;
|
||||
|
||||
#if CONF_XOSC32K_CONFIG == 1
|
||||
hri_osc32kctrl_write_XOSC32K_reg(
|
||||
hw,
|
||||
OSC32KCTRL_XOSC32K_STARTUP(CONF_XOSC32K_STARTUP) | (CONF_XOSC32K_ONDEMAND << OSC32KCTRL_XOSC32K_ONDEMAND_Pos)
|
||||
| (CONF_XOSC32K_RUNSTDBY << OSC32KCTRL_XOSC32K_RUNSTDBY_Pos)
|
||||
| (CONF_XOSC32K_EN1K << OSC32KCTRL_XOSC32K_EN1K_Pos) | (CONF_XOSC32K_EN32K << OSC32KCTRL_XOSC32K_EN32K_Pos)
|
||||
| (CONF_XOSC32K_XTALEN << OSC32KCTRL_XOSC32K_XTALEN_Pos)
|
||||
| (CONF_XOSC32K_ENABLE << OSC32KCTRL_XOSC32K_ENABLE_Pos));
|
||||
|
||||
hri_osc32kctrl_write_CFDCTRL_reg(hw,
|
||||
(CONF_XOSC32K_CFDEN << OSC32KCTRL_CFDCTRL_CFDEN_Pos)
|
||||
| (CONF_XOSC32K_SWBEN << OSC32KCTRL_CFDCTRL_SWBACK_Pos));
|
||||
|
||||
hri_osc32kctrl_write_EVCTRL_reg(hw, (CONF_XOSC32K_CFDEO << OSC32KCTRL_EVCTRL_CFDEO_Pos));
|
||||
#endif
|
||||
|
||||
#if CONF_OSCULP32K_CONFIG == 1
|
||||
calib = hri_osc32kctrl_read_OSCULP32K_CALIB_bf(hw);
|
||||
hri_osc32kctrl_write_OSCULP32K_reg(hw,
|
||||
#if CONF_OSC32K_CALIB_ENABLE == 1
|
||||
OSC32KCTRL_OSCULP32K_CALIB(CONF_OSC32K_CALIB)
|
||||
#else
|
||||
OSC32KCTRL_OSCULP32K_CALIB(calib)
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
|
||||
#if CONF_XOSC32K_CONFIG
|
||||
#if CONF_XOSC32K_ENABLE == 1 && CONF_XOSC32K_ONDEMAND == 0
|
||||
while (!hri_osc32kctrl_get_STATUS_XOSC32KRDY_bit(hw))
|
||||
;
|
||||
#endif
|
||||
#if CONF_OSCULP32K_ULP32KSW == 1
|
||||
hri_osc32kctrl_set_OSCULP32K_reg(hw, OSC32KCTRL_OSCULP32K_ULP32KSW);
|
||||
while (!hri_osc32kctrl_get_STATUS_ULP32KSW_bit(hw))
|
||||
;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
hri_osc32kctrl_write_RTCCTRL_reg(hw, OSC32KCTRL_RTCCTRL_RTCSEL(CONF_RTCCTRL));
|
||||
(void)calib;
|
||||
}
|
||||
179
watch-library/hardware/hpl/oscctrl/hpl_oscctrl.c
Normal file
179
watch-library/hardware/hpl/oscctrl/hpl_oscctrl.c
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Oscillators Controller.
|
||||
*
|
||||
* 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 <compiler.h>
|
||||
#include <hpl_init.h>
|
||||
#include <hpl_oscctrl_config.h>
|
||||
|
||||
/**
|
||||
* \brief Initialize clock sources
|
||||
*/
|
||||
void _oscctrl_init_sources(void)
|
||||
{
|
||||
void *hw = (void *)OSCCTRL;
|
||||
|
||||
#if CONF_XOSC_CONFIG == 1
|
||||
hri_oscctrl_write_XOSCCTRL_reg(
|
||||
hw,
|
||||
OSCCTRL_XOSCCTRL_STARTUP(CONF_XOSC_STARTUP) | (0 << OSCCTRL_XOSCCTRL_AMPGC_Pos)
|
||||
| OSCCTRL_XOSCCTRL_GAIN(CONF_XOSC_GAIN) | (0 << OSCCTRL_XOSCCTRL_ONDEMAND_Pos)
|
||||
| (CONF_XOSC_RUNSTDBY << OSCCTRL_XOSCCTRL_RUNSTDBY_Pos) | (CONF_XOSC_SWBEN << OSCCTRL_XOSCCTRL_SWBEN_Pos)
|
||||
| (CONF_XOSC_CFDEN << OSCCTRL_XOSCCTRL_CFDEN_Pos) | (CONF_XOSC_XTALEN << OSCCTRL_XOSCCTRL_XTALEN_Pos)
|
||||
| (CONF_XOSC_ENABLE << OSCCTRL_XOSCCTRL_ENABLE_Pos));
|
||||
|
||||
hri_oscctrl_write_EVCTRL_reg(hw, (CONF_XOSC_CFDEO << OSCCTRL_EVCTRL_CFDEO_Pos));
|
||||
#endif
|
||||
|
||||
#if CONF_OSC16M_CONFIG == 1
|
||||
hri_oscctrl_write_OSC16MCTRL_reg(hw,
|
||||
(CONF_OSC16M_ONDEMAND << OSCCTRL_OSC16MCTRL_ONDEMAND_Pos)
|
||||
| (CONF_OSC16M_RUNSTDBY << OSCCTRL_OSC16MCTRL_RUNSTDBY_Pos)
|
||||
| (CONF_OSC16M_ENABLE << OSCCTRL_OSC16MCTRL_ENABLE_Pos)
|
||||
| OSCCTRL_OSC16MCTRL_FSEL(CONF_OSC16M_FSEL));
|
||||
#endif
|
||||
|
||||
#if CONF_XOSC_CONFIG == 1
|
||||
#if CONF_XOSC_ENABLE == 1
|
||||
while (!hri_oscctrl_get_STATUS_XOSCRDY_bit(hw))
|
||||
;
|
||||
#endif
|
||||
#if CONF_XOSC_AMPGC == 1
|
||||
hri_oscctrl_set_XOSCCTRL_AMPGC_bit(hw);
|
||||
#endif
|
||||
#if CONF_XOSC_ONDEMAND == 1
|
||||
hri_oscctrl_set_XOSCCTRL_ONDEMAND_bit(hw);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONF_OSC16M_CONFIG == 1
|
||||
#if CONF_OSC16M_ENABLE == 1
|
||||
while (!hri_oscctrl_get_STATUS_OSC16MRDY_bit(hw))
|
||||
;
|
||||
#endif
|
||||
#if CONF_OSC16M_ONDEMAND == 1
|
||||
hri_oscctrl_set_OSC16MCTRL_ONDEMAND_bit(hw);
|
||||
#endif
|
||||
#endif
|
||||
(void)hw;
|
||||
}
|
||||
|
||||
void _oscctrl_init_referenced_generators(void)
|
||||
{
|
||||
void * hw = (void *)OSCCTRL;
|
||||
hri_oscctrl_dfllctrl_reg_t tmp = 0;
|
||||
|
||||
#if CONF_DFLL_CONFIG == 1
|
||||
#if CONF_DFLL_OVERWRITE_CALIBRATION == 0
|
||||
#define NVM_DFLL_COARSE_POS 26
|
||||
#define NVM_DFLL_COARSE_SIZE 6
|
||||
uint32_t coarse;
|
||||
coarse = *((uint32_t *)(NVMCTRL_OTP5)) >> NVM_DFLL_COARSE_POS;
|
||||
#endif
|
||||
#if CONF_DFLL_USBCRM != 1 && CONF_DFLL_MODE != 0
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, 0, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_DFLL_GCLK));
|
||||
#endif
|
||||
hri_oscctrl_write_DFLLCTRL_reg(hw, OSCCTRL_DFLLCTRL_ENABLE);
|
||||
while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
|
||||
;
|
||||
hri_oscctrl_write_DFLLMUL_reg(hw,
|
||||
OSCCTRL_DFLLMUL_CSTEP(CONF_DFLL_CSTEP) | OSCCTRL_DFLLMUL_FSTEP(CONF_DFLL_FSTEP)
|
||||
| OSCCTRL_DFLLMUL_MUL(CONF_DFLL_MUL));
|
||||
while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
|
||||
;
|
||||
|
||||
#if CONF_DFLL_OVERWRITE_CALIBRATION == 0
|
||||
/* FINE is set to fixed value, which defined by DFLL48M Characteristics */
|
||||
hri_oscctrl_write_DFLLVAL_reg(hw, OSCCTRL_DFLLVAL_COARSE(coarse) | OSCCTRL_DFLLVAL_FINE(512));
|
||||
#else
|
||||
hri_oscctrl_write_DFLLVAL_reg(hw, OSCCTRL_DFLLVAL_COARSE(CONF_DFLL_COARSE) | OSCCTRL_DFLLVAL_FINE(CONF_DFLL_FINE));
|
||||
#endif
|
||||
|
||||
tmp = (CONF_DFLL_WAITLOCK << OSCCTRL_DFLLCTRL_WAITLOCK_Pos) | (CONF_DFLL_BPLCKC << OSCCTRL_DFLLCTRL_BPLCKC_Pos)
|
||||
| (CONF_DFLL_QLDIS << OSCCTRL_DFLLCTRL_QLDIS_Pos) | (CONF_DFLL_CCDIS << OSCCTRL_DFLLCTRL_CCDIS_Pos)
|
||||
| (CONF_DFLL_RUNSTDBY << OSCCTRL_DFLLCTRL_RUNSTDBY_Pos) | (CONF_DFLL_USBCRM << OSCCTRL_DFLLCTRL_USBCRM_Pos)
|
||||
| (CONF_DFLL_LLAW << OSCCTRL_DFLLCTRL_LLAW_Pos) | (CONF_DFLL_STABLE << OSCCTRL_DFLLCTRL_STABLE_Pos)
|
||||
| (CONF_DFLL_MODE << OSCCTRL_DFLLCTRL_MODE_Pos) | (CONF_DFLL_ENABLE << OSCCTRL_DFLLCTRL_ENABLE_Pos);
|
||||
hri_oscctrl_write_DFLLCTRL_reg(hw, tmp);
|
||||
|
||||
#endif
|
||||
|
||||
#if CONF_DPLL_CONFIG == 1
|
||||
#if CONF_DPLL_REFCLK == 2
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, 1, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_DPLL_GCLK));
|
||||
#endif
|
||||
hri_oscctrl_write_DPLLRATIO_reg(
|
||||
hw, OSCCTRL_DPLLRATIO_LDRFRAC(CONF_DPLL_LDRFRAC) | OSCCTRL_DPLLRATIO_LDR(CONF_DPLL_LDR));
|
||||
hri_oscctrl_write_DPLLCTRLB_reg(
|
||||
hw,
|
||||
OSCCTRL_DPLLCTRLB_DIV(CONF_DPLL_DIV) | (CONF_DPLL_LBYPASS << OSCCTRL_DPLLCTRLB_LBYPASS_Pos)
|
||||
| OSCCTRL_DPLLCTRLB_LTIME(CONF_DPLL_LTIME) | OSCCTRL_DPLLCTRLB_REFCLK(CONF_DPLL_REFCLK)
|
||||
| (CONF_DPLL_WUF << OSCCTRL_DPLLCTRLB_WUF_Pos) | (CONF_DPLL_LPEN << OSCCTRL_DPLLCTRLB_LPEN_Pos)
|
||||
| OSCCTRL_DPLLCTRLB_FILTER(CONF_DPLL_FILTER));
|
||||
hri_oscctrl_write_DPLLPRESC_reg(hw, OSCCTRL_DPLLPRESC_PRESC(CONF_DPLL_PRESC));
|
||||
hri_oscctrl_write_DPLLCTRLA_reg(hw,
|
||||
(0 << OSCCTRL_DPLLCTRLA_ONDEMAND_Pos)
|
||||
| (CONF_DPLL_RUNSTDBY << OSCCTRL_DPLLCTRLA_RUNSTDBY_Pos)
|
||||
| (CONF_DPLL_ENABLE << OSCCTRL_DPLLCTRLA_ENABLE_Pos));
|
||||
#endif
|
||||
|
||||
#if CONF_DFLL_CONFIG == 1
|
||||
if (hri_oscctrl_get_DFLLCTRL_MODE_bit(hw)) {
|
||||
hri_oscctrl_status_reg_t status_mask = OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC;
|
||||
|
||||
while (hri_oscctrl_get_STATUS_reg(hw, status_mask) != status_mask)
|
||||
;
|
||||
} else {
|
||||
while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
|
||||
;
|
||||
}
|
||||
#if CONF_DFLL_ONDEMAND == 1
|
||||
hri_oscctrl_set_DFLLCTRL_ONDEMAND_bit(hw);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONF_DPLL_CONFIG == 1
|
||||
#if CONF_DPLL_ENABLE == 1
|
||||
while (!(hri_oscctrl_get_DPLLSTATUS_LOCK_bit(hw) || hri_oscctrl_get_DPLLSTATUS_CLKRDY_bit(hw)))
|
||||
;
|
||||
#endif
|
||||
#if CONF_DPLL_ONDEMAND == 1
|
||||
hri_oscctrl_set_DPLLCTRLA_ONDEMAND_bit(hw);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONF_DFLL_CONFIG == 1
|
||||
while (hri_gclk_read_SYNCBUSY_reg(GCLK))
|
||||
;
|
||||
#endif
|
||||
(void)hw, (void)tmp;
|
||||
}
|
||||
77
watch-library/hardware/hpl/pm/hpl_pm.c
Normal file
77
watch-library/hardware/hpl/pm/hpl_pm.c
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Power manager
|
||||
*
|
||||
* 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_sleep.h>
|
||||
#include <hpl_reset.h>
|
||||
#include <hpl_init.h>
|
||||
|
||||
/**
|
||||
* \brief Retrieve the reset reason
|
||||
*/
|
||||
enum reset_reason _get_reset_reason(void)
|
||||
{
|
||||
return (enum reset_reason)hri_rstc_read_RCAUSE_reg(RSTC);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the sleep mode for the device
|
||||
*/
|
||||
int32_t _set_sleep_mode(const uint8_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 2: /* IDLE */
|
||||
case 4: /* STANDBY */
|
||||
case 5: /* BACKUP */
|
||||
case 6: /* OFF */
|
||||
hri_pm_write_SLEEPCFG_SLEEPMODE_bf(PM, mode);
|
||||
break;
|
||||
default:
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set performance level
|
||||
*/
|
||||
void _set_performance_level(const uint8_t level)
|
||||
{
|
||||
if (hri_pm_get_PLCFG_PLSEL_bf(PM, PM_PLCFG_PLSEL_Msk) != level) {
|
||||
hri_pm_clear_INTFLAG_reg(PM, 0xFF);
|
||||
hri_pm_write_PLCFG_PLSEL_bf(PM, level);
|
||||
while (!hri_pm_read_INTFLAG_reg(PM))
|
||||
;
|
||||
}
|
||||
}
|
||||
45
watch-library/hardware/hpl/pm/hpl_pm_base.h
Normal file
45
watch-library/hardware/hpl/pm/hpl_pm_base.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Power manager
|
||||
*
|
||||
* 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_PM_BASE_H_INCLUDED
|
||||
#define _HPL_PM_BASE_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <utils_assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _HPL_PM_BASE_H_INCLUDED */
|
||||
170
watch-library/hardware/hpl/port/hpl_gpio_base.h
Normal file
170
watch-library/hardware/hpl/port/hpl_gpio_base.h
Normal file
@@ -0,0 +1,170 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM 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 <compiler.h>
|
||||
#include <hpl_gpio.h>
|
||||
#include <utils_assert.h>
|
||||
#include <hpl_port_config.h>
|
||||
|
||||
/**
|
||||
* \brief Set direction on port with mask
|
||||
*/
|
||||
static inline void _gpio_set_direction(const enum gpio_port port, const uint32_t mask,
|
||||
const enum gpio_direction direction)
|
||||
{
|
||||
switch (direction) {
|
||||
case GPIO_DIRECTION_OFF:
|
||||
hri_port_clear_DIR_reg(PORT_IOBUS, port, mask);
|
||||
hri_port_write_WRCONFIG_reg(PORT, port, PORT_WRCONFIG_WRPINCFG | (mask & 0xffff));
|
||||
hri_port_write_WRCONFIG_reg(
|
||||
PORT, port, PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | ((mask & 0xffff0000) >> 16));
|
||||
break;
|
||||
|
||||
case GPIO_DIRECTION_IN:
|
||||
hri_port_clear_DIR_reg(PORT_IOBUS, port, mask);
|
||||
hri_port_write_WRCONFIG_reg(PORT, port, PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_INEN | (mask & 0xffff));
|
||||
hri_port_write_WRCONFIG_reg(PORT,
|
||||
port,
|
||||
PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_INEN
|
||||
| ((mask & 0xffff0000) >> 16));
|
||||
break;
|
||||
|
||||
case GPIO_DIRECTION_OUT:
|
||||
hri_port_set_DIR_reg(PORT_IOBUS, port, mask);
|
||||
hri_port_write_WRCONFIG_reg(PORT, port, PORT_WRCONFIG_WRPINCFG | (mask & 0xffff));
|
||||
hri_port_write_WRCONFIG_reg(
|
||||
PORT, port, PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | ((mask & 0xffff0000) >> 16));
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set output level on port with mask
|
||||
*/
|
||||
static inline void _gpio_set_level(const enum gpio_port port, const uint32_t mask, const bool level)
|
||||
{
|
||||
if (level) {
|
||||
hri_port_set_OUT_reg(PORT_IOBUS, port, mask);
|
||||
} else {
|
||||
hri_port_clear_OUT_reg(PORT_IOBUS, port, mask);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Change output level to the opposite with mask
|
||||
*/
|
||||
static inline void _gpio_toggle_level(const enum gpio_port port, const uint32_t mask)
|
||||
{
|
||||
hri_port_toggle_OUT_reg(PORT_IOBUS, port, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get input levels on all port pins
|
||||
*/
|
||||
static inline uint32_t _gpio_get_level(const enum gpio_port port)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
CRITICAL_SECTION_ENTER();
|
||||
|
||||
uint32_t dir_tmp = hri_port_read_DIR_reg(PORT_IOBUS, port);
|
||||
|
||||
tmp = hri_port_read_IN_reg(PORT, port) & ~dir_tmp;
|
||||
tmp |= hri_port_read_OUT_reg(PORT_IOBUS, port) & dir_tmp;
|
||||
|
||||
CRITICAL_SECTION_LEAVE();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set pin pull mode
|
||||
*/
|
||||
static inline void _gpio_set_pin_pull_mode(const enum gpio_port port, const uint8_t pin,
|
||||
const enum gpio_pull_mode pull_mode)
|
||||
{
|
||||
switch (pull_mode) {
|
||||
case GPIO_PULL_OFF:
|
||||
hri_port_clear_PINCFG_PULLEN_bit(PORT, port, pin);
|
||||
break;
|
||||
|
||||
case GPIO_PULL_UP:
|
||||
hri_port_clear_DIR_reg(PORT_IOBUS, port, 1U << pin);
|
||||
hri_port_set_PINCFG_PULLEN_bit(PORT, port, pin);
|
||||
hri_port_set_OUT_reg(PORT_IOBUS, port, 1U << pin);
|
||||
break;
|
||||
|
||||
case GPIO_PULL_DOWN:
|
||||
hri_port_clear_DIR_reg(PORT_IOBUS, port, 1U << pin);
|
||||
hri_port_set_PINCFG_PULLEN_bit(PORT, port, pin);
|
||||
hri_port_clear_OUT_reg(PORT_IOBUS, port, 1U << pin);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set gpio pin function
|
||||
*/
|
||||
static inline void _gpio_set_pin_function(const uint32_t gpio, const uint32_t function)
|
||||
{
|
||||
uint8_t port = GPIO_PORT(gpio);
|
||||
uint8_t pin = GPIO_PIN(gpio);
|
||||
|
||||
if (function == GPIO_PIN_FUNCTION_OFF) {
|
||||
hri_port_write_PINCFG_PMUXEN_bit(PORT, port, pin, false);
|
||||
|
||||
} else {
|
||||
hri_port_write_PINCFG_PMUXEN_bit(PORT, port, pin, true);
|
||||
|
||||
if (pin & 1) {
|
||||
// Odd numbered pin
|
||||
hri_port_write_PMUX_PMUXO_bf(PORT, port, pin >> 1, function & 0xffff);
|
||||
} else {
|
||||
// Even numbered pin
|
||||
hri_port_write_PMUX_PMUXE_bf(PORT, port, pin >> 1, function & 0xffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _port_event_init()
|
||||
{
|
||||
hri_port_set_EVCTRL_reg(PORT, 0, CONF_PORTA_EVCTRL);
|
||||
hri_port_set_EVCTRL_reg(PORT, 1, CONF_PORTB_EVCTRL);
|
||||
}
|
||||
2932
watch-library/hardware/hpl/sercom/hpl_sercom.c
Normal file
2932
watch-library/hardware/hpl/sercom/hpl_sercom.c
Normal file
File diff suppressed because it is too large
Load Diff
289
watch-library/hardware/hpl/slcd/hpl_slcd.c
Normal file
289
watch-library/hardware/hpl/slcd/hpl_slcd.c
Normal file
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SLCD Segment Liquid Crystal Display Controller(Sync) 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 <utils_assert.h>
|
||||
#include <hpl_slcd_sync.h>
|
||||
#include <hpl_slcd_config.h>
|
||||
|
||||
static int32_t _slcd_sync_set_segment(struct _slcd_sync_device *dev, const uint32_t com, const uint32_t seg,
|
||||
const bool on);
|
||||
|
||||
/**
|
||||
* \brief SLCD configuration type
|
||||
*/
|
||||
struct slcd_configuration {
|
||||
hri_slcd_ctrla_reg_t ctrla; /*!< Control A Register */
|
||||
hri_slcd_ctrlb_reg_t ctrlb; /*!< Control B Register */
|
||||
hri_slcd_ctrlc_reg_t ctrlc; /*!< Control C Register */
|
||||
hri_slcd_ctrld_reg_t ctrld; /*!< Control D Register */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Array of AC configurations
|
||||
*/
|
||||
static struct slcd_configuration _slcd
|
||||
= {SLCD_CTRLA_DUTY(CONF_SLCD_COM_NUM) | CONF_SLCD_WMOD << SLCD_CTRLA_WMOD_Pos
|
||||
| CONF_SLCD_RUNSTDBY << SLCD_CTRLA_RUNSTDBY_Pos | SLCD_CTRLA_PRESC(CONF_SLCD_PRESC)
|
||||
| SLCD_CTRLA_CKDIV(CONF_SLCD_CKDIV) | SLCD_CTRLA_BIAS(CONF_SLCD_BIAS)
|
||||
| CONF_SLCD_XVLCD << SLCD_CTRLA_XVLCD_Pos | SLCD_CTRLA_PRF(CONF_SLCD_PRF) | SLCD_CTRLA_RRF(CONF_SLCD_RRF),
|
||||
CONF_SLCD_BBEN << SLCD_CTRLB_BBEN_Pos | SLCD_CTRLB_BBD(CONF_SLCD_BBD - 1),
|
||||
SLCD_CTRLC_CTST(CONF_SLCD_CONTRAST_ADJUST),
|
||||
SLCD_CTRLD_DISPEN};
|
||||
/**
|
||||
* \brief Initialize SLCD Device Descriptor
|
||||
*/
|
||||
int32_t _slcd_sync_init(struct _slcd_sync_device *dev, void *const hw)
|
||||
{
|
||||
if (!hri_slcd_is_syncing(hw, SLCD_SYNCBUSY_SWRST)) {
|
||||
if (hri_slcd_get_CTRLA_ENABLE_bit(hw)) {
|
||||
hri_slcd_clear_CTRLA_ENABLE_bit(hw);
|
||||
hri_slcd_wait_for_sync(hw, SLCD_SYNCBUSY_ENABLE);
|
||||
}
|
||||
hri_slcd_write_CTRLA_reg(hw, SLCD_CTRLA_SWRST);
|
||||
}
|
||||
hri_slcd_wait_for_sync(hw, SLCD_SYNCBUSY_SWRST);
|
||||
|
||||
dev->hw = hw;
|
||||
hri_slcd_write_CTRLA_reg(hw, _slcd.ctrla);
|
||||
hri_slcd_write_CTRLB_reg(hw, _slcd.ctrlb);
|
||||
hri_slcd_write_CTRLC_reg(hw, _slcd.ctrlc);
|
||||
hri_slcd_write_CTRLD_reg(hw, _slcd.ctrld);
|
||||
hri_slcd_write_LPENL_reg(hw, CONF_SLCD_LPENL);
|
||||
hri_slcd_write_LPENH_reg(hw, CONF_SLCD_LPENH);
|
||||
hri_slcd_write_SDATAL0_reg(hw, 0);
|
||||
hri_slcd_write_SDATAH0_reg(hw, 0);
|
||||
hri_slcd_write_SDATAL1_reg(hw, 0);
|
||||
hri_slcd_write_SDATAH1_reg(hw, 0);
|
||||
hri_slcd_write_SDATAL2_reg(hw, 0);
|
||||
hri_slcd_write_SDATAH2_reg(hw, 0);
|
||||
hri_slcd_write_SDATAL3_reg(hw, 0);
|
||||
hri_slcd_write_SDATAH3_reg(hw, 0);
|
||||
hri_slcd_write_SDATAL4_reg(hw, 0);
|
||||
hri_slcd_write_SDATAH4_reg(hw, 0);
|
||||
hri_slcd_write_SDATAL5_reg(hw, 0);
|
||||
hri_slcd_write_SDATAH5_reg(hw, 0);
|
||||
hri_slcd_write_SDATAL6_reg(hw, 0);
|
||||
hri_slcd_write_SDATAH6_reg(hw, 0);
|
||||
hri_slcd_write_SDATAL7_reg(hw, 0);
|
||||
hri_slcd_write_SDATAH7_reg(hw, 0);
|
||||
hri_slcd_set_BCFG_MODE_bit(dev->hw);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief DeInitialize SLCD Device Descriptor
|
||||
*/
|
||||
int32_t _slcd_sync_deinit(struct _slcd_sync_device *dev)
|
||||
{
|
||||
hri_slcd_clear_CTRLA_ENABLE_bit(dev->hw);
|
||||
hri_slcd_wait_for_sync(dev->hw, SLCD_SYNCBUSY_ENABLE);
|
||||
hri_slcd_set_CTRLA_SWRST_bit(dev->hw);
|
||||
dev->hw = NULL;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable SLCD driver
|
||||
*
|
||||
* \param[in] dev SLCD device descriptor to be enabled
|
||||
*/
|
||||
int32_t _slcd_sync_enable(struct _slcd_sync_device *dev)
|
||||
{
|
||||
hri_slcd_set_CTRLA_ENABLE_bit(dev->hw);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable SLCD driver
|
||||
*/
|
||||
int32_t _slcd_sync_disable(struct _slcd_sync_device *dev)
|
||||
{
|
||||
hri_slcd_clear_CTRLA_ENABLE_bit(dev->hw);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Turn on a Segment
|
||||
*/
|
||||
int32_t _slcd_sync_seg_on(struct _slcd_sync_device *dev, uint32_t seg)
|
||||
{
|
||||
return _slcd_sync_set_segment(dev, SLCD_COMNUM(seg), SLCD_SEGNUM(seg), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Turn off a Segment
|
||||
*/
|
||||
int32_t _slcd_sync_seg_off(struct _slcd_sync_device *dev, uint32_t seg)
|
||||
{
|
||||
return _slcd_sync_set_segment(dev, SLCD_COMNUM(seg), SLCD_SEGNUM(seg), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Blink a Segment
|
||||
*/
|
||||
int32_t _slcd_sync_seg_blink(struct _slcd_sync_device *dev, uint32_t seg, const uint32_t period)
|
||||
{
|
||||
if ((SLCD_COMNUM(seg) >= CONF_SLCD_COM_NUM) || (SLCD_SEGNUM(seg) >= CONF_SLCD_SEG_NUM)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
/* COM[0..7], Seg[0,1] support blink */
|
||||
if (SLCD_SEGNUM(seg) >= 2) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
/* Verify period */
|
||||
if (period > SLCD_FC_MAX_MS || period < SLCD_FC_MIN_MS) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
/* Set Period, use Frame Counter 0 for blink */
|
||||
hri_slcd_clear_CTRLD_FC0EN_bit(dev->hw);
|
||||
hri_slcd_wait_for_sync(dev->hw, SLCD_SYNCBUSY_CTRLD);
|
||||
if (period <= SLCD_FC_BYPASS_MAX_MS) {
|
||||
hri_slcd_set_FC0_reg(dev->hw, SLCD_FC0_PB | ((period / (1000 / SLCD_FRAME_FREQUENCY)) - 1));
|
||||
} else {
|
||||
hri_slcd_set_FC0_reg(dev->hw, (((period / (1000 / SLCD_FRAME_FREQUENCY)) / 8 - 1)));
|
||||
}
|
||||
hri_slcd_set_CTRLD_FC0EN_bit(dev->hw);
|
||||
|
||||
/* Set Blink Segments */
|
||||
_slcd_sync_set_segment(dev, SLCD_COMNUM(seg), SLCD_SEGNUM(seg), true);
|
||||
hri_slcd_clear_CTRLD_BLINK_bit(dev->hw);
|
||||
|
||||
hri_slcd_clear_CTRLA_ENABLE_bit(dev->hw);
|
||||
hri_slcd_wait_for_sync(dev->hw, SLCD_SYNCBUSY_ENABLE);
|
||||
|
||||
/* Update BCFG */
|
||||
if (SLCD_SEGNUM(seg) == 0) {
|
||||
hri_slcd_set_BCFG_BSS0_bf(dev->hw, 1 << SLCD_COMNUM(seg));
|
||||
} else {
|
||||
hri_slcd_set_BCFG_BSS1_bf(dev->hw, 1 << SLCD_COMNUM(seg));
|
||||
}
|
||||
hri_slcd_set_CTRLA_ENABLE_bit(dev->hw);
|
||||
hri_slcd_set_CTRLD_BLINK_bit(dev->hw);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Start animation play by a segment array
|
||||
*/
|
||||
int32_t _slcd_sync_start_animation(struct _slcd_sync_device *dev, const uint32_t segs[], uint32_t len,
|
||||
const uint32_t period)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t csrlen = 0;
|
||||
if (len > 16) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
/* COM[0..7], Seg[2,3] support animation */
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((SLCD_SEGNUM(segs[i]) != 2 && SLCD_SEGNUM(segs[i]) != 3)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
/* Verify period */
|
||||
if (period > SLCD_FC_MAX_MS || period < SLCD_FC_MIN_MS) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
/* Set Period */
|
||||
_slcd_sync_set_animation_period(dev, period);
|
||||
|
||||
/* Set animation segments */
|
||||
hri_slcd_clear_CTRLA_ENABLE_bit(dev->hw);
|
||||
hri_slcd_clear_CTRLD_CSREN_bit(dev->hw);
|
||||
|
||||
hri_slcd_wait_for_sync(dev->hw, SLCD_SYNCBUSY_ENABLE | SLCD_SYNCBUSY_CTRLD);
|
||||
hri_slcd_set_CSRCFG_FCS_bf(dev->hw, 1);
|
||||
hri_slcd_write_CSRCFG_DATA_bf(dev->hw, 0);
|
||||
for (i = 0; i < len; i++) {
|
||||
hri_slcd_set_CSRCFG_DATA_bf(dev->hw, (1 << ((SLCD_COMNUM(segs[i]) * 2) + (SLCD_SEGNUM(segs[i]) - 2))));
|
||||
if (((SLCD_COMNUM(segs[i]) * 2) + (SLCD_SEGNUM(segs[i]) - 2)) > csrlen) {
|
||||
csrlen = (SLCD_COMNUM(segs[i]) * 2) + (SLCD_SEGNUM(segs[i]) - 2);
|
||||
}
|
||||
}
|
||||
hri_slcd_set_CSRCFG_SIZE_bf(dev->hw, csrlen + 1);
|
||||
hri_slcd_set_BCFG_MODE_bit(dev->hw);
|
||||
hri_slcd_set_CTRLD_CSREN_bit(dev->hw);
|
||||
hri_slcd_set_CTRLA_ENABLE_bit(dev->hw);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Stop animation play by a segment array
|
||||
*/
|
||||
int32_t _slcd_sync_stop_animation(struct _slcd_sync_device *dev, const uint32_t segs[], uint32_t len)
|
||||
{
|
||||
/* Not used because of the current version is not supported, Reserved */
|
||||
(void)segs;
|
||||
(void)len;
|
||||
hri_slcd_wait_for_sync(dev->hw, SLCD_SYNCBUSY_CTRLD);
|
||||
hri_slcd_clear_CTRLD_CSREN_bit(dev->hw);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set animation Frequency
|
||||
*/
|
||||
int32_t _slcd_sync_set_animation_period(struct _slcd_sync_device *dev, const uint32_t period)
|
||||
{
|
||||
hri_slcd_clear_CTRLD_FC1EN_bit(dev->hw);
|
||||
hri_slcd_wait_for_sync(dev->hw, SLCD_SYNCBUSY_CTRLD);
|
||||
/* Use Frame Counter 1 for blink */
|
||||
if (period <= SLCD_FC_BYPASS_MAX_MS) {
|
||||
hri_slcd_set_FC1_reg(dev->hw, SLCD_FC1_PB | ((period / (1000 / SLCD_FRAME_FREQUENCY)) - 1));
|
||||
} else {
|
||||
hri_slcd_set_FC1_reg(dev->hw, (((period / (1000 / SLCD_FRAME_FREQUENCY)) / 8 - 1)));
|
||||
}
|
||||
hri_slcd_set_CTRLD_FC1EN_bit(dev->hw);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
static int32_t _slcd_sync_set_segment(struct _slcd_sync_device *dev, const uint32_t com, const uint32_t seg,
|
||||
const bool on)
|
||||
{
|
||||
if ((SLCD_COMNUM(seg) >= CONF_SLCD_COM_NUM) || (SLCD_SEGNUM(seg) >= CONF_SLCD_SEG_NUM)) {
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
/* Use register instead hri interface to optimization code */
|
||||
if (on) {
|
||||
((uint32_t *)&(((Slcd *)dev->hw)->SDATAL0))[(com * 2) + (seg >> 5)]
|
||||
|= (seg < 32) ? (1 << seg) : (1 << (seg >> 5));
|
||||
} else {
|
||||
((uint32_t *)&(((Slcd *)dev->hw)->SDATAL0))[(com * 2) + (seg >> 5)]
|
||||
&= ~((seg < 32) ? (1 << seg) : (1 << (seg >> 5)));
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
59
watch-library/hardware/hpl/slcd/hpl_slcd_cm.h
Normal file
59
watch-library/hardware/hpl/slcd/hpl_slcd_cm.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SLCD Character Mapping 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_SLCD_CM_H_INCLUDED
|
||||
#define HPL_SLCD_CM_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Character Mapping Struct */
|
||||
struct slcd_char_mapping {
|
||||
uint32_t character : 8; /*!< ASCII character */
|
||||
uint32_t mapping : 24; /*!< Mapping value */
|
||||
};
|
||||
|
||||
/* SLCD Character settting Struct */
|
||||
struct slcd_char_setting {
|
||||
uint8_t com_index; /*!< Common terminal index, start from 0 */
|
||||
uint8_t seg_index; /*!< Segment terminal index, start from 0 */
|
||||
uint8_t nseg; /*!< Number of Segment, this field is used to
|
||||
indentify which segments line will be
|
||||
used. For example, if char mapping from
|
||||
COM1/SEG2 and nseg=2,size=7, then
|
||||
COM1/SEG2, COM1/SEG3, COM2/SEG2,
|
||||
COM2/SEG3, COM3/SEG2, COM3/SEG3,
|
||||
COM4/SEG2 will be used for mapping
|
||||
*/
|
||||
uint8_t size; /*!< char size, typical is 7/14/16 */
|
||||
};
|
||||
#endif /* HPL_SLCD_CM_H_INCLUDED */
|
||||
104
watch-library/hardware/hpl/systick/hpl_systick.c
Normal file
104
watch-library/hardware/hpl/systick/hpl_systick.c
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SysTick 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_time_measure.h>
|
||||
#include <hpl_systick_config.h>
|
||||
#include <hpl_delay.h>
|
||||
|
||||
/**
|
||||
* \brief Initialize system time module
|
||||
*/
|
||||
void _system_time_init(void *const hw)
|
||||
{
|
||||
(void)hw;
|
||||
SysTick->LOAD = (0xFFFFFF << SysTick_LOAD_RELOAD_Pos);
|
||||
SysTick->CTRL = (1 << SysTick_CTRL_ENABLE_Pos) | (CONF_SYSTICK_TICKINT << SysTick_CTRL_TICKINT_Pos)
|
||||
| (1 << SysTick_CTRL_CLKSOURCE_Pos);
|
||||
}
|
||||
/**
|
||||
* \brief Initialize delay functionality
|
||||
*/
|
||||
void _delay_init(void *const hw)
|
||||
{
|
||||
_system_time_init(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief De-initialize system time module
|
||||
*/
|
||||
void _system_time_deinit(void *const hw)
|
||||
{
|
||||
(void)hw;
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get system time
|
||||
*/
|
||||
system_time_t _system_time_get(const void *const hw)
|
||||
{
|
||||
(void)hw;
|
||||
return (system_time_t)SysTick->VAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get maximum possible system time
|
||||
*/
|
||||
system_time_t _system_time_get_max_time_value(const void *const hw)
|
||||
{
|
||||
(void)hw;
|
||||
return 0xFFFFFF;
|
||||
}
|
||||
/**
|
||||
* \brief Delay loop to delay n number of cycles
|
||||
*/
|
||||
void _delay_cycles(void *const hw, uint32_t cycles)
|
||||
{
|
||||
(void)hw;
|
||||
uint8_t n = cycles >> 24;
|
||||
uint32_t buf = cycles;
|
||||
|
||||
while (n--) {
|
||||
SysTick->LOAD = 0xFFFFFF;
|
||||
SysTick->VAL = 0xFFFFFF;
|
||||
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk))
|
||||
;
|
||||
buf -= 0xFFFFFF;
|
||||
}
|
||||
|
||||
SysTick->LOAD = buf;
|
||||
SysTick->VAL = buf;
|
||||
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk))
|
||||
;
|
||||
}
|
||||
110
watch-library/hardware/hpl/trng/hpl_trng.c
Executable file
110
watch-library/hardware/hpl/trng/hpl_trng.c
Executable file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief True Random Number Generator
|
||||
*
|
||||
* 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 <err_codes.h>
|
||||
#include <hpl_rand_sync.h>
|
||||
#include <hpl_trng_config.h>
|
||||
#include <utils_assert.h>
|
||||
|
||||
static inline int32_t _trng_init(void *hw)
|
||||
{
|
||||
if (hri_trng_get_CTRLA_reg(hw, TRNG_CTRLA_ENABLE)) {
|
||||
return ERR_DENIED;
|
||||
}
|
||||
if (CONF_TRNG_RUNSTDBY) {
|
||||
hri_trng_set_CTRLA_RUNSTDBY_bit(hw);
|
||||
} else {
|
||||
hri_trng_clear_CTRLA_RUNSTDBY_bit(hw);
|
||||
}
|
||||
if (CONF_TRNG_DATARDYEO) {
|
||||
hri_trng_set_EVCTRL_DATARDYEO_bit(hw);
|
||||
} else {
|
||||
hri_trng_clear_EVCTRL_DATARDYEO_bit(hw);
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t _rand_sync_init(struct _rand_sync_dev *const dev, void *const hw)
|
||||
{
|
||||
int32_t rc;
|
||||
|
||||
ASSERT(dev && hw);
|
||||
|
||||
rc = _trng_init(hw);
|
||||
if (rc == ERR_NONE) {
|
||||
dev->prvt = hw;
|
||||
dev->n_bits = 32;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void _rand_sync_deinit(struct _rand_sync_dev *const dev)
|
||||
{
|
||||
_rand_sync_disable(dev);
|
||||
}
|
||||
|
||||
int32_t _rand_sync_enable(struct _rand_sync_dev *const dev)
|
||||
{
|
||||
ASSERT(dev);
|
||||
ASSERT(dev->prvt);
|
||||
|
||||
hri_trng_set_CTRLA_ENABLE_bit(dev->prvt);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
void _rand_sync_disable(struct _rand_sync_dev *const dev)
|
||||
{
|
||||
ASSERT(dev);
|
||||
ASSERT(dev->prvt);
|
||||
|
||||
hri_trng_clear_CTRLA_ENABLE_bit(dev->prvt);
|
||||
}
|
||||
|
||||
int32_t _rand_sync_set_seed(struct _rand_sync_dev *const dev, const uint32_t seed)
|
||||
{
|
||||
(void)dev;
|
||||
(void)seed;
|
||||
return ERR_UNSUPPORTED_OP;
|
||||
}
|
||||
|
||||
uint32_t _rand_sync_read_one(const struct _rand_sync_dev *const dev)
|
||||
{
|
||||
ASSERT(dev);
|
||||
ASSERT(dev->prvt);
|
||||
ASSERT(hri_trng_get_CTRLA_reg(dev->prvt, TRNG_CTRLA_ENABLE));
|
||||
|
||||
while (!hri_trng_get_INTFLAG_reg(dev->prvt, TRNG_INTFLAG_DATARDY)) {
|
||||
/* Wait until data ready. */
|
||||
}
|
||||
return hri_trng_read_DATA_reg(dev->prvt);
|
||||
}
|
||||
Reference in New Issue
Block a user