WIP timer wakeup stuff

This commit is contained in:
Joey Castillo 2021-05-02 13:07:51 -04:00
parent 68bada3006
commit 9b381ef6ae
27 changed files with 1066 additions and 498 deletions

View file

@ -48,6 +48,7 @@
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/i2c_master_sync.rst"/>
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/pwm.rst"/>
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/slcd_sync.rst"/>
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/timer.rst"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_atomic.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_calendar.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_delay.h"/>
@ -135,9 +136,6 @@
<file category="header" condition="ARMCC, GCC, IAR" name="hri/hri_trng_l22.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hri/hri_usb_l22.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hri/hri_wdt_l22.h"/>
<file category="doc" condition="ARMCC, GCC, IAR" name="documentation/sleep_manager.rst"/>
<file category="source" condition="ARMCC, GCC, IAR" name="sleep_manager/sleep_manager.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="sleep_manager/sleep_manager.h"/>
<file category="source" condition="ARMCC, GCC, IAR" name="main.c"/>
<file category="source" condition="ARMCC, GCC, IAR" name="driver_init.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="driver_init.h"/>
@ -146,6 +144,7 @@
<file category="source" condition="ARMCC, GCC, IAR" name="examples/driver_examples.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_adc_sync.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_pwm.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_timer.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_adc_async.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_adc_sync.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_calendar.h"/>
@ -164,6 +163,7 @@
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_calendar.c"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_ext_irq.c"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_pwm.c"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_timer.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/utils/include/parts.h"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hpl/adc/hpl_adc.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hpl/adc/hpl_adc_base.h"/>
@ -190,8 +190,6 @@
<file category="header" condition="ARMCC, GCC, IAR" name="hpl/tc/hpl_tc_base.h"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hpl/tcc/hpl_tcc.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hpl/tcc/hpl_tcc.h"/>
<file category="source" condition="ARMCC, GCC, IAR" name="sleep_manager_main.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="sleep_manager_main.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="atmel_start.h"/>
<file category="source" condition="ARMCC, GCC, IAR" name="atmel_start.c"/>
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/hpl_adc_config.h"/>
@ -209,7 +207,6 @@
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/hpl_tc_config.h"/>
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/hpl_tcc_config.h"/>
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/peripheral_clk_config.h"/>
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/sleep_manager_config.h"/>
<file category="include" condition="ARMCC, GCC, IAR" name=""/>
<file category="include" condition="ARMCC, GCC, IAR" name="config"/>
<file category="include" condition="ARMCC, GCC, IAR" name="examples"/>
@ -233,9 +230,6 @@
<file category="include" condition="ARMCC, GCC, IAR" name="hpl/tcc"/>
<file category="include" condition="ARMCC, GCC, IAR" name="hri"/>
<file category="include" condition="ARMCC, GCC, IAR" name=""/>
<file category="include" condition="ARMCC, GCC, IAR" name="config"/>
<file category="include" condition="ARMCC, GCC, IAR" name="sleep_manager"/>
<file category="include" condition="ARMCC, GCC, IAR" name=""/>
</files>
</component>
</components>

View file

@ -18,14 +18,7 @@ board:
device: SAML22J18A-AN
details: null
application: null
middlewares:
SLEEP_MANAGER_0:
user_label: SLEEP_MANAGER_0
configuration: {}
definition: Atmel:Sleep_Manager:0.0.1::Sleep_manager
functionality: Sleep_Manager
api: Sleep-Manager:Sleep-Manager:API
dependencies: {}
middlewares: {}
drivers:
ADC_0:
user_label: ADC_0
@ -524,10 +517,10 @@ drivers:
functionality: System
api: HAL:HPL:GCLK
configuration:
$input: 32768
$input_id: 32kHz External Crystal Oscillator (XOSC32K)
RESERVED_InputFreq: 32768
RESERVED_InputFreq_id: 32kHz External Crystal Oscillator (XOSC32K)
$input: 400000
$input_id: External Crystal Oscillator 0.4-32MHz (XOSC)
RESERVED_InputFreq: 400000
RESERVED_InputFreq_id: External Crystal Oscillator 0.4-32MHz (XOSC)
_$freq_output_Generic clock generator 0: 4000000
_$freq_output_Generic clock generator 1: 400000
_$freq_output_Generic clock generator 2: 400000
@ -638,9 +631,9 @@ drivers:
xosc32k_arch_en1k: true
xosc32k_arch_en32k: true
xosc32k_arch_enable: true
xosc32k_arch_ondemand: true
xosc32k_arch_ondemand: false
xosc32k_arch_runstdby: true
xosc32k_arch_startup: 2000092us
xosc32k_arch_startup: 1000092us
xosc32k_arch_swben: false
xosc32k_arch_xtalen: true
optional_signals: []
@ -866,6 +859,37 @@ drivers:
variant: null
clocks:
domain_group: null
TIMER_0:
user_label: TIMER_0
definition: Atmel:SAML22_Drivers:0.0.1::SAML22J18A-AN::TC0::driver_config_definition::Timer::HAL:Driver:Timer
functionality: Timer
api: HAL:Driver:Timer
configuration:
tc_arch_dbgrun: false
tc_arch_evact: Event action disabled
tc_arch_mceo0: false
tc_arch_mceo1: false
tc_arch_ondemand: false
tc_arch_ovfeo: false
tc_arch_presync: Reload or reset counter on next GCLK
tc_arch_runstdby: true
tc_arch_tcei: false
tc_arch_tcinv: false
timer_advanced_configuration: true
timer_event_control: false
timer_prescaler: Divide by 2
timer_tick: 61
optional_signals: []
variant: null
clocks:
domain_group:
nodes:
- name: TC
input: Generic clock generator 3
external: false
external_frequency: 0
configuration:
tc_gclk_selection: Generic clock generator 3
PWM_0:
user_label: PWM_0
definition: Atmel:SAML22_Drivers:0.0.1::SAML22J18A-AN::TC3::driver_config_definition::PWM::HAL:Driver:PWM

View file

@ -81,14 +81,14 @@
// <0x6=>8000092us
// <id> xosc32k_arch_startup
#ifndef CONF_XOSC32K_STARTUP
#define CONF_XOSC32K_STARTUP 0x4
#define CONF_XOSC32K_STARTUP 0x3
#endif
// <q> On Demand Control
// <i> Indicates whether On Demand Control is enabled or not
// <id> xosc32k_arch_ondemand
#ifndef CONF_XOSC32K_ONDEMAND
#define CONF_XOSC32K_ONDEMAND 1
#define CONF_XOSC32K_ONDEMAND 0
#endif
// <q> Run in Standby

View file

@ -4,6 +4,177 @@
// <<< Use Configuration Wizard in Context Menu >>>
#ifndef CONF_TC0_ENABLE
#define CONF_TC0_ENABLE 1
#endif
#include "peripheral_clk_config.h"
// <h> Basic configuration
// <o> Prescaler
// <0x0=> No division
// <0x1=> Divide by 2
// <0x2=> Divide by 4
// <0x3=> Divide by 8
// <0x4=> Divide by 16
// <0x5=> Divide by 64
// <0x6=> Divide by 256
// <0x7=> Divide by 1024
// <i> This defines the prescaler value
// <id> timer_prescaler
#ifndef CONF_TC0_PRESCALER
#define CONF_TC0_PRESCALER 0x1
#endif
// <o> Length of one timer tick in uS <0-4294967295>
// <id> timer_tick
#ifndef CONF_TC0_TIMER_TICK
#define CONF_TC0_TIMER_TICK 61
#endif
// </h>
// <e> Advanced configuration
// <id> timer_advanced_configuration
#ifndef CONF_TC0__ADVANCED_CONFIGURATION_ENABLE
#define CONF_TC0__ADVANCED_CONFIGURATION_ENABLE 1
#endif
// <y> Prescaler and Counter Synchronization Selection
// <TC_CTRLA_PRESCSYNC_GCLK_Val"> Reload or reset counter on next GCLK
// <TC_CTRLA_PRESCSYNC_PRESC_Val"> Reload or reset counter on next prescaler clock
// <TC_CTRLA_PRESCSYNC_RESYNC_Val"> Reload or reset counter on next GCLK and reset prescaler counter
// <i> These bits select if on retrigger event, the Counter should be cleared or reloaded on the next GCLK_TCx clock or on the next prescaled GCLK_TCx clock.
// <id> tc_arch_presync
#ifndef CONF_TC0_PRESCSYNC
#define CONF_TC0_PRESCSYNC TC_CTRLA_PRESCSYNC_GCLK_Val
#endif
// <q> Run in standby
// <i> Indicates whether the module will continue to run in standby sleep mode
// <id> tc_arch_runstdby
#ifndef CONF_TC0_RUNSTDBY
#define CONF_TC0_RUNSTDBY 1
#endif
// <q> Run in debug mode
// <i> Indicates whether the module will run in debug mode
// <id> tc_arch_dbgrun
#ifndef CONF_TC0_DBGRUN
#define CONF_TC0_DBGRUN 0
#endif
// <q> Run on demand
// <i> Run if requested by some other peripheral in the device
// <id> tc_arch_ondemand
#ifndef CONF_TC0_ONDEMAND
#define CONF_TC0_ONDEMAND 0
#endif
// </e>
// <e> Event control
// <id> timer_event_control
#ifndef CONF_TC0_EVENT_CONTROL_ENABLE
#define CONF_TC0_EVENT_CONTROL_ENABLE 0
#endif
// <q> Output Event On Match or Capture on Channel 0
// <i> Enable output of event on timer tick
// <id> tc_arch_mceo0
#ifndef CONF_TC0_MCEO0
#define CONF_TC0_MCEO0 0
#endif
// <q> Output Event On Match or Capture on Channel 1
// <i> Enable output of event on timer tick
// <id> tc_arch_mceo1
#ifndef CONF_TC0_MCEO1
#define CONF_TC0_MCEO1 0
#endif
// <q> Output Event On Timer Tick
// <i> Enable output of event on timer tick
// <id> tc_arch_ovfeo
#ifndef CONF_TC0_OVFEO
#define CONF_TC0_OVFEO 0
#endif
// <q> Event Input
// <i> Enable asynchronous input events
// <id> tc_arch_tcei
#ifndef CONF_TC0_TCEI
#define CONF_TC0_TCEI 0
#endif
// <q> Inverted Event Input
// <i> Invert the asynchronous input events
// <id> tc_arch_tcinv
#ifndef CONF_TC0_TCINV
#define CONF_TC0_TCINV 0
#endif
// <o> Event action
// <0=> Event action disabled
// <1=> Start, restart or re-trigger TC on event
// <2=> Count on event
// <3=> Start on event
// <4=> Time stamp capture
// <5=> Period captured in CC0, pulse width in CC1
// <6=> Period captured in CC1, pulse width in CC0
// <7=> Pulse width capture
// <i> Event which will be performed on an event
//<id> tc_arch_evact
#ifndef CONF_TC0_EVACT
#define CONF_TC0_EVACT 0
#endif
// </e>
// Default values which the driver needs in order to work correctly
// Mode set to 32-bit
#ifndef CONF_TC0_MODE
#define CONF_TC0_MODE TC_CTRLA_MODE_COUNT32_Val
#endif
// CC 1 register set to 0
#ifndef CONF_TC0_CC1
#define CONF_TC0_CC1 0
#endif
#ifndef CONF_TC0_ALOCK
#define CONF_TC0_ALOCK 0
#endif
// Not used in 32-bit mode
#define CONF_TC0_PER 0
// Calculating correct top value based on requested tick interval.
#define CONF_TC0_PRESCALE (1 << CONF_TC0_PRESCALER)
// Prescaler set to 64
#if CONF_TC0_PRESCALER > 0x4
#undef CONF_TC0_PRESCALE
#define CONF_TC0_PRESCALE 64
#endif
// Prescaler set to 256
#if CONF_TC0_PRESCALER > 0x5
#undef CONF_TC0_PRESCALE
#define CONF_TC0_PRESCALE 256
#endif
// Prescaler set to 1024
#if CONF_TC0_PRESCALER > 0x6
#undef CONF_TC0_PRESCALE
#define CONF_TC0_PRESCALE 1024
#endif
#ifndef CONF_TC0_CC0
#define CONF_TC0_CC0 \
(uint32_t)(((float)CONF_TC0_TIMER_TICK / 1000000.f) / (1.f / (CONF_GCLK_TC0_FREQUENCY / CONF_TC0_PRESCALE)))
#endif
#include <peripheral_clk_config.h>
#ifndef CONF_TC3_ENABLE

View file

@ -145,6 +145,32 @@
// <GCLK_PCHCTRL_GEN_GCLK4_Val"> Generic clock generator 4
// <i> Select the clock source for TC.
#ifndef CONF_GCLK_TC0_SRC
#define CONF_GCLK_TC0_SRC GCLK_PCHCTRL_GEN_GCLK3_Val
#endif
/**
* \def CONF_GCLK_TC0_FREQUENCY
* \brief TC0's Clock frequency
*/
#ifndef CONF_GCLK_TC0_FREQUENCY
#define CONF_GCLK_TC0_FREQUENCY 32768
#endif
// <y> TC Clock Source
// <id> tc_gclk_selection
// <GCLK_PCHCTRL_GEN_GCLK0_Val"> Generic clock generator 0
// <GCLK_PCHCTRL_GEN_GCLK1_Val"> Generic clock generator 1
// <GCLK_PCHCTRL_GEN_GCLK2_Val"> Generic clock generator 2
// <GCLK_PCHCTRL_GEN_GCLK3_Val"> Generic clock generator 3
// <GCLK_PCHCTRL_GEN_GCLK4_Val"> Generic clock generator 4
// <i> Select the clock source for TC.
#ifndef CONF_GCLK_TC3_SRC
#define CONF_GCLK_TC3_SRC GCLK_PCHCTRL_GEN_GCLK0_Val

View file

@ -1,9 +0,0 @@
/* Auto-generated config file sleep_manager_config.h */
#ifndef SLEEP_MANAGER_CONFIG_H
#define SLEEP_MANAGER_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <<< end of configuration section >>>
#endif // SLEEP_MANAGER_CONFIG_H

View file

@ -138,16 +138,15 @@
<AcmeProjectActionInfo Action="File" Source="hri/hri_trng_l22.h" IsConfig="false" Hash="+6CMfjfAU62WldJAEU8JTg" />
<AcmeProjectActionInfo Action="File" Source="hri/hri_usb_l22.h" IsConfig="false" Hash="dPDK2Dcf/T+0icIbtTF0yg" />
<AcmeProjectActionInfo Action="File" Source="hri/hri_wdt_l22.h" IsConfig="false" Hash="KpOZJ+68Hzj/dOLfx94n5g" />
<AcmeProjectActionInfo Action="File" Source="sleep_manager/sleep_manager.c" IsConfig="false" Hash="Y0V7+lcjJKIdSeL4ueYZ6w" />
<AcmeProjectActionInfo Action="File" Source="sleep_manager/sleep_manager.h" IsConfig="false" Hash="wbQ70QzJlJHL0fiCXAXTpQ" />
<AcmeProjectActionInfo Action="File" Source="main.c" IsConfig="false" Hash="k0AH7j+BrmdFhBPzCCMptA" />
<AcmeProjectActionInfo Action="File" Source="driver_init.c" IsConfig="false" Hash="RTBFCGfRONzW/m85hpe4IA" />
<AcmeProjectActionInfo Action="File" Source="driver_init.h" IsConfig="false" Hash="4Dd+xLQL3xA5bugP6hkjbg" />
<AcmeProjectActionInfo Action="File" Source="driver_init.c" IsConfig="false" Hash="Zw9TBuFm3x3YlHbeguapNQ" />
<AcmeProjectActionInfo Action="File" Source="driver_init.h" IsConfig="false" Hash="jGwg9E39uUvuPsyqQD0HpA" />
<AcmeProjectActionInfo Action="File" Source="atmel_start_pins.h" IsConfig="false" Hash="5lmo1agoLOJW6nYY8SQiUQ" />
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.h" IsConfig="false" Hash="vA0AOZ9ZthDRQ3WRx2TPBA" />
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.c" IsConfig="false" Hash="tLQq4aGf9J1UF19OmI/x/Q" />
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.h" IsConfig="false" Hash="0DI0D6jkFhuGhaDnKmEnXA" />
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.c" IsConfig="false" Hash="YRl/+3+qtVZNdSNNmpcdgA" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_adc_sync.h" IsConfig="false" Hash="ez1X5T9kpYwT+1+5x4Pxqg" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_pwm.h" IsConfig="false" Hash="br6uNoL0TWVIiQVzPc8hPA" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_timer.h" IsConfig="false" Hash="5pZVthtMl40VMvofOld2ng" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_adc_async.h" IsConfig="false" Hash="kKbVmqgGDUkuWZYErBwgVA" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_adc_sync.h" IsConfig="false" Hash="dCWrizZn0RtcCM73jZ/k6A" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_calendar.h" IsConfig="false" Hash="E2gwBBatdcqZegUjH8HtWg" />
@ -166,6 +165,7 @@
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_calendar.c" IsConfig="false" Hash="lYVRpDSx+np+02xVeQ9HHQ" />
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_ext_irq.c" IsConfig="false" Hash="l6Jmb4zu10+HvXQ0Iej4dQ" />
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_pwm.c" IsConfig="false" Hash="BSJaZa+fyJkrV3upQM/zBw" />
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_timer.c" IsConfig="false" Hash="F2MrEXhHq4umI9xpONnlGg" />
<AcmeProjectActionInfo Action="File" Source="hal/utils/include/parts.h" IsConfig="false" Hash="WeBzxZ+YnHMwGm/905+44Q" />
<AcmeProjectActionInfo Action="File" Source="hpl/adc/hpl_adc.c" IsConfig="false" Hash="7Fex3op00XgU9E7Lp0VEUg" />
<AcmeProjectActionInfo Action="File" Source="hpl/adc/hpl_adc_base.h" IsConfig="false" Hash="19A6ERNtsVVhqvnpGbR3Lg" />
@ -188,30 +188,27 @@
<AcmeProjectActionInfo Action="File" Source="hpl/slcd/hpl_slcd_cm_14_seg_mapping.h" IsConfig="false" Hash="rYmxchucbzcdRRtphbbizw" />
<AcmeProjectActionInfo Action="File" Source="hpl/slcd/hpl_slcd_cm_7_seg_mapping.h" IsConfig="false" Hash="hcaiqS+ibM0/3hPBICykuw" />
<AcmeProjectActionInfo Action="File" Source="hpl/systick/hpl_systick.c" IsConfig="false" Hash="YYWQVH26EDBDzYTUwepAcA" />
<AcmeProjectActionInfo Action="File" Source="hpl/tc/hpl_tc.c" IsConfig="false" Hash="q1uHBcnbo2uDnGnq/yDLUA" />
<AcmeProjectActionInfo Action="File" Source="hpl/tc/hpl_tc.c" IsConfig="false" Hash="Cu7R+CLmxZgQ2gv6L3xHbQ" />
<AcmeProjectActionInfo Action="File" Source="hpl/tc/hpl_tc_base.h" IsConfig="false" Hash="Eb0LuGB6ltGJO9QC3fi2Sw" />
<AcmeProjectActionInfo Action="File" Source="hpl/tcc/hpl_tcc.c" IsConfig="false" Hash="NHgO5jvkjzWYJ00X3I85jQ" />
<AcmeProjectActionInfo Action="File" Source="hpl/tcc/hpl_tcc.h" IsConfig="false" Hash="vHpM8WwxGAodLqLXX56hlg" />
<AcmeProjectActionInfo Action="File" Source="sleep_manager_main.c" IsConfig="false" Hash="/h7lw4TySqB1SNXNvE2bcA" />
<AcmeProjectActionInfo Action="File" Source="sleep_manager_main.h" IsConfig="false" Hash="qmr52536J7oYjSRDqK5qCA" />
<AcmeProjectActionInfo Action="File" Source="atmel_start.h" IsConfig="false" Hash="2tV6NS3zLO6lMZTeJ1WQ+Q" />
<AcmeProjectActionInfo Action="File" Source="atmel_start.c" IsConfig="false" Hash="M7JixrvrHLkEpjzV6VcZdg" />
<AcmeProjectActionInfo Action="File" Source="atmel_start.h" IsConfig="false" Hash="9RBG5E2ViQiSP2Gn4/FGpA" />
<AcmeProjectActionInfo Action="File" Source="atmel_start.c" IsConfig="false" Hash="1RHIE7zTtYK4DURNPUqF9w" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_adc_config.h" IsConfig="true" Hash="P0t7GiKrHMHBCBrKOSfEnQ" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_dmac_config.h" IsConfig="true" Hash="w3WBXNAk4X2Eyml3c7tQSQ" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_eic_config.h" IsConfig="true" Hash="U9WSM5Hq8sGLa8ysciEfCg" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_gclk_config.h" IsConfig="true" Hash="VW757Ebgq5TyYTRcpY8M7w" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_mclk_config.h" IsConfig="true" Hash="CLrsNUvv74/qlHdF8aFndg" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_osc32kctrl_config.h" IsConfig="true" Hash="b7mSwnFOSDceVn9b3TT9kA" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_osc32kctrl_config.h" IsConfig="true" Hash="LayjFcrIUjhOQ+E6G5sHRA" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_oscctrl_config.h" IsConfig="true" Hash="Vc5u27WzT+UPF5aLAxl2lQ" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_port_config.h" IsConfig="true" Hash="rMTNR+5FXtu+wfT1NbfRRA" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_rtc_config.h" IsConfig="true" Hash="oTcobT9ydLDOqfpwUidHvg" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_sercom_config.h" IsConfig="true" Hash="x/EmsaDJwEm2EI8zXUSlWw" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_slcd_config.h" IsConfig="true" Hash="ErbI2VSUDy3ufREFJTO9Uw" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_systick_config.h" IsConfig="true" Hash="tlT3lNDKWFe82MiGWfQzcA" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_tc_config.h" IsConfig="true" Hash="s9fqdoBaH2BH7Id2JoCHTg" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_tc_config.h" IsConfig="true" Hash="ttsCFzSNH+7C39wCjBDTKg" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_tcc_config.h" IsConfig="true" Hash="5OifPvGmHqsckywrqS3ctQ" />
<AcmeProjectActionInfo Action="File" Source="config/peripheral_clk_config.h" IsConfig="true" Hash="qGv3tsNPPKYSGfAxyoGOsg" />
<AcmeProjectActionInfo Action="File" Source="config/sleep_manager_config.h" IsConfig="true" Hash="DOAee9YybT6XYwA7idJl4g" />
<AcmeProjectActionInfo Action="File" Source="config/peripheral_clk_config.h" IsConfig="true" Hash="6S9yz6YklqQ4b9txk3kYDw" />
</AcmeActionInfos>
<NonsecureFilesInfo />
</AcmeProjectConfig>
@ -232,6 +229,30 @@
<ToolName>Power Debugger</ToolName>
</com_atmel_avrdbg_tool_powerdebugger>
<avrtoolinterfaceclock>2000000</avrtoolinterfaceclock>
<com_atmel_avrdbg_tool_samice>
<ToolOptions>
<InterfaceProperties>
<SwdClock>4000000</SwdClock>
</InterfaceProperties>
<InterfaceName>SWD</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.samice</ToolType>
<ToolNumber>801012234</ToolNumber>
<ToolName>J-Link</ToolName>
</com_atmel_avrdbg_tool_samice>
<custom>
<ToolOptions>
<InterfaceProperties>
<SwdClock>4000000</SwdClock>
</InterfaceProperties>
<InterfaceName>
</InterfaceName>
</ToolOptions>
<ToolType>custom</ToolType>
<ToolNumber>
</ToolNumber>
<ToolName>Custom Programming Tool</ToolName>
</custom>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
@ -271,7 +292,6 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>../sleep_manager</Value>
<Value>%24(PackRepoDir)\atmel\SAML22_DFP\1.2.77\include</Value>
</ListValues>
</armgcc.compiler.directories.IncludePaths>
@ -316,7 +336,6 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>../sleep_manager</Value>
<Value>%24(PackRepoDir)\atmel\SAML22_DFP\1.2.77\include</Value>
</ListValues>
</armgcc.assembler.general.IncludePaths>
@ -345,7 +364,6 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>../sleep_manager</Value>
<Value>%24(PackRepoDir)\atmel\SAML22_DFP\1.2.77\include</Value>
</ListValues>
</armgcc.preprocessingassembler.general.IncludePaths>
@ -390,7 +408,6 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>../sleep_manager</Value>
<Value>%24(PackRepoDir)\atmel\SAML22_DFP\1.2.77\include</Value>
</ListValues>
</armgcc.compiler.directories.IncludePaths>
@ -437,7 +454,6 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>../sleep_manager</Value>
<Value>%24(PackRepoDir)\atmel\SAML22_DFP\1.2.77\include</Value>
</ListValues>
</armgcc.assembler.general.IncludePaths>
@ -467,7 +483,6 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>../sleep_manager</Value>
<Value>%24(PackRepoDir)\atmel\SAML22_DFP\1.2.77\include</Value>
</ListValues>
</armgcc.preprocessingassembler.general.IncludePaths>
@ -533,9 +548,6 @@
<Compile Include="Config\RTE_Components.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="Config\sleep_manager_config.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="Device_Startup\startup_saml22.c">
<SubType>compile</SubType>
</Compile>
@ -590,6 +602,9 @@
<Compile Include="hal\include\hal_sleep.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hal\include\hal_timer.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hal\include\hpl_adc_async.h">
<SubType>compile</SubType>
</Compile>
@ -728,6 +743,9 @@
<Compile Include="hal\src\hal_sleep.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="hal\src\hal_timer.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="hal\utils\include\compiler.h">
<SubType>compile</SubType>
</Compile>
@ -962,18 +980,6 @@
<Compile Include="main.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="sleep_manager\sleep_manager.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="sleep_manager\sleep_manager.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="sleep_manager_main.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="sleep_manager_main.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="watch-library\watch.c">
<SubType>compile</SubType>
</Compile>
@ -984,7 +990,6 @@
<ItemGroup>
<Folder Include="Config\" />
<Folder Include="Device_Startup\" />
<Folder Include="documentation\" />
<Folder Include="examples\" />
<Folder Include="hal\" />
<Folder Include="hal\documentation\" />
@ -1011,7 +1016,6 @@
<Folder Include="hpl\tcc\" />
<Folder Include="hpl\tc\" />
<Folder Include="hri\" />
<Folder Include="sleep_manager\" />
<Folder Include="watch-library" />
</ItemGroup>
<ItemGroup>
@ -1021,9 +1025,6 @@
<None Include="Device_Startup\saml22j18a_sram.ld">
<SubType>compile</SubType>
</None>
<None Include="documentation\sleep_manager.rst">
<SubType>compile</SubType>
</None>
<None Include="hal\documentation\adc_sync.rst">
<SubType>compile</SubType>
</None>
@ -1042,6 +1043,9 @@
<None Include="hal\documentation\slcd_sync.rst">
<SubType>compile</SubType>
</None>
<None Include="hal\documentation\timer.rst">
<SubType>compile</SubType>
</None>
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>

View file

@ -6,5 +6,4 @@
void atmel_start_init(void)
{
system_init();
sleep_manager_init();
}

View file

@ -6,7 +6,6 @@ extern "C" {
#endif
#include "driver_init.h"
#include "sleep_manager_main.h"
/**
* Initializes MCU, drivers and middleware in the project

View file

@ -1,38 +0,0 @@
=============
Sleep Manager
=============
The sleep manager is the middle-ware which provides means to control the sleep of
an MCU by multiple software modules.
The sleep manager uses publish-subscribe pattern to ask subscribers if they are
ready to sleep and to notify them about preparation to sleep and waking up.
If any of the subscribers is not ready to go to sleep, an MCU may stay in active
mode. To let the sleep manager know that a software module is not ready to sleep,
the parameter passed to callback must to set to false. No additional action is
required from the software module to state that it is ready to go to sleep.
Notification about waking up is delivered to all subscribers with information
about wake-up reason.
There are currently only two wake-up reasons: internal interrupt and external
interrupt. It is up to the user to extend this list if required.
Features
--------
* Sleep control
* Notifications:
* ready to sleep
* preparation to sleep
* waking up
Dependencies
------------
* The sleep driver
Limitations
-----------
* Only two wake-up reasons are supported by default

View file

@ -13,6 +13,7 @@
#include <hpl_adc_base.h>
struct timer_descriptor TIMER_0;
struct slcd_sync_descriptor SEGMENT_LCD_0;
struct adc_sync_descriptor ADC_0;
@ -158,6 +159,19 @@ void delay_driver_init(void)
delay_init(SysTick);
}
/**
* \brief Timer initialization function
*
* Enables Timer peripheral, clocks and initializes Timer driver
*/
void TIMER_0_init(void)
{
hri_mclk_set_APBCMASK_TC0_bit(MCLK);
hri_gclk_write_PCHCTRL_reg(GCLK, TC0_GCLK_ID, CONF_GCLK_TC0_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
timer_init(&TIMER_0, TC0, _tc_get_timer());
}
void PWM_0_PORT_init(void)
{
@ -324,6 +338,7 @@ void system_init(void)
delay_driver_init();
TIMER_0_init();
PWM_0_init();
PWM_1_init();

View file

@ -30,6 +30,8 @@ extern "C" {
#include <hal_i2c_m_sync.h>
#include <hal_delay.h>
#include <hal_timer.h>
#include <hpl_tc_base.h>
#include <hal_pwm.h>
#include <hpl_tc_base.h>
@ -43,6 +45,8 @@ extern struct calendar_descriptor CALENDAR_0;
extern struct i2c_m_sync_desc I2C_0;
extern struct timer_descriptor TIMER_0;
extern struct pwm_descriptor PWM_0;
extern struct pwm_descriptor PWM_1;
@ -61,6 +65,8 @@ void I2C_0_PORT_init(void);
void delay_driver_init(void);
void TIMER_0_init(void);
void PWM_0_PORT_init(void);
void PWM_0_CLOCK_init(void);
void PWM_0_init(void);
@ -69,9 +75,9 @@ void PWM_1_PORT_init(void);
void PWM_1_CLOCK_init(void);
void PWM_1_init(void);
void EXTERNAL_IRQ_0_init(void);
void SEGMENT_LCD_0_init(void);
void EXTERNAL_IRQ_0_init(void);
void SEGMENT_LCD_0_init(void);
/**
* \brief Perform system initialization, initialize pins and clocks for

View file

@ -97,6 +97,33 @@ void delay_example(void)
delay_ms(5000);
}
static struct timer_task TIMER_0_task1, TIMER_0_task2;
/**
* Example of using TIMER_0.
*/
static void TIMER_0_task1_cb(const struct timer_task *const timer_task)
{
}
static void TIMER_0_task2_cb(const struct timer_task *const timer_task)
{
}
void TIMER_0_example(void)
{
TIMER_0_task1.interval = 100;
TIMER_0_task1.cb = TIMER_0_task1_cb;
TIMER_0_task1.mode = TIMER_TASK_REPEAT;
TIMER_0_task2.interval = 200;
TIMER_0_task2.cb = TIMER_0_task2_cb;
TIMER_0_task2.mode = TIMER_TASK_REPEAT;
timer_add_task(&TIMER_0, &TIMER_0_task1);
timer_add_task(&TIMER_0, &TIMER_0_task2);
timer_start(&TIMER_0);
}
/**
* Example of using PWM_0.
*/

View file

@ -22,6 +22,8 @@ void I2C_0_example(void);
void delay_example(void);
void TIMER_0_example(void);
void PWM_0_example(void);
void PWM_1_example(void);

View file

@ -0,0 +1,52 @@
============================
The Timer driver (bare-bone)
============================
The Timer driver provides means for delayed and periodical function invocation.
A timer task is a piece of code (function) executed at a specific time or periodically by the timer after the task has
been added to the timers task queue. The execution delay or period is set in ticks, where one tick is defined as a
configurable number of clock cycles in the hardware timer. Changing the number of clock cycles in a tick automatically
changes execution delays and periods for all tasks in the timers task queue.
A task has two operation modes, single-shot or repeating mode. In single-shot mode the task is removed from the task queue
and then is executed once, in repeating mode the task reschedules itself automatically after it has executed based on
the period set in the task configuration.
In single-shot mode a task is removed from the task queue before its callback is invoked. It allows an application to
reuse the memory of expired task in the callback.
Each instance of the Timer driver supports infinite amount of timer tasks, only limited by the amount of RAM available.
Features
--------
* Initialization and de-initialization
* Starting and stopping
* Timer tasks - periodical invocation of functions
* Changing and obtaining of the period of a timer
Applications
------------
* Delayed and periodical function execution for middle-ware stacks and applications.
Dependencies
------------
* Each instance of the driver requires separate hardware timer capable of generating periodic interrupt.
Concurrency
-----------
The Timer driver is an interrupt driven driver.This means that the interrupt that triggers a task may occur during
the process of adding or removing a task via the driver's API. In such case the interrupt processing is postponed
until the task adding or removing is complete.
The task queue is not protected from the access by interrupts not used by the driver. Due to this
it is not recommended to add or remove a task from such interrupts: in case if a higher priority interrupt supersedes
the driver's interrupt, adding or removing a task may cause unpredictable behavior of the driver.
Limitations
-----------
* The driver is designed to work outside of an operating system environment, the task queue is therefore processed in interrupt context which may delay execution of other interrupts.
* If there are a lot of frequently called interrupts with the priority higher than the driver's one, it may cause delay for triggering of a task.
Knows issues and workarounds
----------------------------
Not applicable

View file

@ -0,0 +1,206 @@
/**
* \file
*
* \brief Timer task functionality declaration.
*
* Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _HAL_TIMER_H_INCLUDED
#define _HAL_TIMER_H_INCLUDED
#include <utils_list.h>
#include <hpl_timer.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup doc_driver_hal_timer
*
* @{
*/
/**
* \brief Timer mode type
*/
enum timer_task_mode { TIMER_TASK_ONE_SHOT, TIMER_TASK_REPEAT };
/**
* \brief Timer task descriptor
*
* The timer task descriptor forward declaration.
*/
struct timer_task;
/**
* \brief Timer task callback function type
*/
typedef void (*timer_cb_t)(const struct timer_task *const timer_task);
/**
* \brief Timer task structure
*/
struct timer_task {
struct list_element elem; /*! List element. */
uint32_t time_label; /*! Absolute timer start time. */
uint32_t interval; /*! Number of timer ticks before calling the task. */
timer_cb_t cb; /*! Function pointer to the task. */
enum timer_task_mode mode; /*! Task mode: one shot or repeat. */
};
/**
* \brief Timer structure
*/
struct timer_descriptor {
struct _timer_device device;
uint32_t time;
struct list_descriptor tasks; /*! Timer tasks list. */
volatile uint8_t flags;
};
/**
* \brief Initialize timer
*
* This function initializes the given timer.
* It checks if the given hardware is not initialized and if the given hardware
* is permitted to be initialized.
*
* \param[out] descr A timer descriptor to initialize
* \param[in] hw The pointer to the hardware instance
* \param[in] func The pointer to a set of function pointers
*
* \return Initialization status.
*/
int32_t timer_init(struct timer_descriptor *const descr, void *const hw, struct _timer_hpl_interface *const func);
/**
* \brief Deinitialize timer
*
* This function deinitializes the given timer.
* It checks if the given hardware is initialized and if the given hardware is
* permitted to be deinitialized.
*
* \param[in] descr A timer descriptor to deinitialize
*
* \return De-initialization status.
*/
int32_t timer_deinit(struct timer_descriptor *const descr);
/**
* \brief Start timer
*
* This function starts the given timer.
* It checks if the given hardware is initialized.
*
* \param[in] descr The timer descriptor of a timer to start
*
* \return Timer starting status.
*/
int32_t timer_start(struct timer_descriptor *const descr);
/**
* \brief Stop timer
*
* This function stops the given timer.
* It checks if the given hardware is initialized.
*
* \param[in] descr The timer descriptor of a timer to stop
*
* \return Timer stopping status.
*/
int32_t timer_stop(struct timer_descriptor *const descr);
/**
* \brief Set amount of clock cycles per timer tick
*
* This function sets the amount of clock cycles per timer tick for the given timer.
* It checks if the given hardware is initialized.
*
* \param[in] descr The timer descriptor of a timer to stop
* \param[in] clock_cycles The amount of clock cycles per tick to set
*
* \return Setting clock cycles amount status.
*/
int32_t timer_set_clock_cycles_per_tick(struct timer_descriptor *const descr, const uint32_t clock_cycles);
/**
* \brief Retrieve the amount of clock cycles in a tick
*
* This function retrieves how many clock cycles there are in a single timer tick.
* It checks if the given hardware is initialized.
*
* \param[in] descr The timer descriptor of a timer to convert ticks to
* clock cycles
* \param[out] cycles The amount of clock cycles
*
* \return The status of clock cycles retrieving.
*/
int32_t timer_get_clock_cycles_in_tick(const struct timer_descriptor *const descr, uint32_t *const cycles);
/**
* \brief Add timer task
*
* This function adds the given timer task to the given timer.
* It checks if the given hardware is initialized.
*
* \param[in] descr The timer descriptor of a timer to add task to
* \param[in] task A task to add
*
* \return Timer's task adding status.
*/
int32_t timer_add_task(struct timer_descriptor *const descr, struct timer_task *const task);
/**
* \brief Remove timer task
*
* This function removes the given timer task from the given timer.
* It checks if the given hardware is initialized.
*
* \param[in] descr The timer descriptor of a timer to remove task from
* \param[in] task A task to remove
*
* \return Timer's task removing status.
*/
int32_t timer_remove_task(struct timer_descriptor *const descr, const struct timer_task *const task);
/**
* \brief Retrieve the current driver version
*
* \return Current driver version.
*/
uint32_t timer_get_version(void);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* _HAL_TIMER_H_INCLUDED */

View file

@ -0,0 +1,250 @@
/**
* \file
*
* \brief Timer functionality implementation.
*
* Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "hal_timer.h"
#include <utils_assert.h>
#include <utils.h>
#include <hal_atomic.h>
#include <hpl_irq.h>
/**
* \brief Driver version
*/
#define DRIVER_VERSION 0x00000001u
/**
* \brief Timer flags
*/
#define TIMER_FLAG_QUEUE_IS_TAKEN 1
#define TIMER_FLAG_INTERRUPT_TRIGERRED 2
static void timer_add_timer_task(struct list_descriptor *list, struct timer_task *const new_task, const uint32_t time);
static void timer_process_counted(struct _timer_device *device);
/**
* \brief Initialize timer
*/
int32_t timer_init(struct timer_descriptor *const descr, void *const hw, struct _timer_hpl_interface *const func)
{
ASSERT(descr && hw);
_timer_init(&descr->device, hw);
descr->time = 0;
descr->device.timer_cb.period_expired = timer_process_counted;
return ERR_NONE;
}
/**
* \brief Deinitialize timer
*/
int32_t timer_deinit(struct timer_descriptor *const descr)
{
ASSERT(descr);
_timer_deinit(&descr->device);
return ERR_NONE;
}
/**
* \brief Start timer
*/
int32_t timer_start(struct timer_descriptor *const descr)
{
ASSERT(descr);
if (_timer_is_started(&descr->device)) {
return ERR_DENIED;
}
_timer_start(&descr->device);
return ERR_NONE;
}
/**
* \brief Stop timer
*/
int32_t timer_stop(struct timer_descriptor *const descr)
{
ASSERT(descr);
if (!_timer_is_started(&descr->device)) {
return ERR_DENIED;
}
_timer_stop(&descr->device);
return ERR_NONE;
}
/**
* \brief Set amount of clock cycler per timer tick
*/
int32_t timer_set_clock_cycles_per_tick(struct timer_descriptor *const descr, const uint32_t clock_cycles)
{
ASSERT(descr);
_timer_set_period(&descr->device, clock_cycles);
return ERR_NONE;
}
/**
* \brief Add timer task
*/
int32_t timer_add_task(struct timer_descriptor *const descr, struct timer_task *const task)
{
ASSERT(descr && task);
descr->flags |= TIMER_FLAG_QUEUE_IS_TAKEN;
if (is_list_element(&descr->tasks, task)) {
descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
ASSERT(false);
return ERR_ALREADY_INITIALIZED;
}
task->time_label = descr->time;
timer_add_timer_task(&descr->tasks, task, descr->time);
descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
if (descr->flags & TIMER_FLAG_INTERRUPT_TRIGERRED) {
CRITICAL_SECTION_ENTER()
descr->flags &= ~TIMER_FLAG_INTERRUPT_TRIGERRED;
_timer_set_irq(&descr->device);
CRITICAL_SECTION_LEAVE()
}
return ERR_NONE;
}
/**
* \brief Remove timer task
*/
int32_t timer_remove_task(struct timer_descriptor *const descr, const struct timer_task *const task)
{
ASSERT(descr && task);
descr->flags |= TIMER_FLAG_QUEUE_IS_TAKEN;
if (!is_list_element(&descr->tasks, task)) {
descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
ASSERT(false);
return ERR_NOT_FOUND;
}
list_delete_element(&descr->tasks, task);
descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
if (descr->flags & TIMER_FLAG_INTERRUPT_TRIGERRED) {
CRITICAL_SECTION_ENTER()
descr->flags &= ~TIMER_FLAG_INTERRUPT_TRIGERRED;
_timer_set_irq(&descr->device);
CRITICAL_SECTION_LEAVE()
}
return ERR_NONE;
}
/**
* \brief Retrieve the amount of clock cycles in a tick
*/
int32_t timer_get_clock_cycles_in_tick(const struct timer_descriptor *const descr, uint32_t *const cycles)
{
ASSERT(descr && cycles);
*cycles = _timer_get_period(&descr->device);
return ERR_NONE;
}
/**
* \brief Retrieve the current driver version
*/
uint32_t timer_get_version(void)
{
return DRIVER_VERSION;
}
/**
* \internal Insert a timer task into sorted timer's list
*
* \param[in] head The pointer to the head of timer task list
* \param[in] task The pointer to task to add
* \param[in] time Current timer time
*/
static void timer_add_timer_task(struct list_descriptor *list, struct timer_task *const new_task, const uint32_t time)
{
struct timer_task *it, *prev = NULL, *head = (struct timer_task *)list_get_head(list);
if (!head) {
list_insert_as_head(list, new_task);
return;
}
for (it = head; it; it = (struct timer_task *)list_get_next_element(it)) {
uint32_t time_left;
if (it->time_label <= time) {
time_left = it->interval - (time - it->time_label);
} else {
time_left = it->interval - (0xFFFFFFFF - it->time_label) - time;
}
if (time_left >= new_task->interval)
break;
prev = it;
}
if (it == head) {
list_insert_as_head(list, new_task);
} else {
list_insert_after(prev, new_task);
}
}
/**
* \internal Process interrupts
*/
static void timer_process_counted(struct _timer_device *device)
{
struct timer_descriptor *timer = CONTAINER_OF(device, struct timer_descriptor, device);
struct timer_task * it = (struct timer_task *)list_get_head(&timer->tasks);
uint32_t time = ++timer->time;
if ((timer->flags & TIMER_FLAG_QUEUE_IS_TAKEN) || (timer->flags & TIMER_FLAG_INTERRUPT_TRIGERRED)) {
timer->flags |= TIMER_FLAG_INTERRUPT_TRIGERRED;
return;
}
while (it && ((time - it->time_label) >= it->interval)) {
struct timer_task *tmp = it;
list_remove_head(&timer->tasks);
if (TIMER_TASK_REPEAT == tmp->mode) {
tmp->time_label = time;
timer_add_timer_task(&timer->tasks, tmp, time);
}
it = (struct timer_task *)list_get_head(&timer->tasks);
tmp->cb(tmp);
}
}

View file

@ -139,11 +139,59 @@ static struct _pwm_hpl_interface _tc_pwm_functions = {
_tc_pwm_set_irq_state,
};
static struct _timer_device *_tc0_dev = NULL;
static struct _pwm_device *_tc3_dev = NULL;
static int8_t get_tc_index(const void *const hw);
static void _tc_init_irq_param(const void *const hw, void *dev);
static inline uint8_t _get_hardware_offset(const void *const hw);
/**
* \brief Initialize TC
*/
int32_t _timer_init(struct _timer_device *const device, void *const hw)
{
int8_t i = get_tc_index(hw);
device->hw = hw;
ASSERT(ARRAY_SIZE(_tcs));
if (!hri_tc_is_syncing(hw, TC_SYNCBUSY_SWRST)) {
if (hri_tc_get_CTRLA_reg(hw, TC_CTRLA_ENABLE)) {
hri_tc_clear_CTRLA_ENABLE_bit(hw);
hri_tc_wait_for_sync(hw, TC_SYNCBUSY_ENABLE);
}
hri_tc_write_CTRLA_reg(hw, TC_CTRLA_SWRST);
}
hri_tc_wait_for_sync(hw, TC_SYNCBUSY_SWRST);
hri_tc_write_CTRLA_reg(hw, _tcs[i].ctrl_a);
hri_tc_write_DBGCTRL_reg(hw, _tcs[i].dbg_ctrl);
hri_tc_write_EVCTRL_reg(hw, _tcs[i].event_ctrl);
hri_tc_write_WAVE_reg(hw, TC_WAVE_WAVEGEN_MFRQ);
if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT32) {
hri_tccount32_write_CC_reg(hw, 0, _tcs[i].cc0);
hri_tccount32_write_CC_reg(hw, 1, _tcs[i].cc1);
} else if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT16) {
hri_tccount16_write_CC_reg(hw, 0, (uint16_t)_tcs[i].cc0);
hri_tccount16_write_CC_reg(hw, 1, (uint16_t)_tcs[i].cc1);
} else if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT8) {
hri_tccount8_write_CC_reg(hw, 0, (uint8_t)_tcs[i].cc0);
hri_tccount8_write_CC_reg(hw, 1, (uint8_t)_tcs[i].cc1);
hri_tccount8_write_PER_reg(hw, _tcs[i].per);
}
hri_tc_set_INTEN_OVF_bit(hw);
_tc_init_irq_param(hw, (void *)device);
NVIC_DisableIRQ(_tcs[i].irq);
NVIC_ClearPendingIRQ(_tcs[i].irq);
NVIC_EnableIRQ(_tcs[i].irq);
return ERR_NONE;
}
/**
* \brief Initialize TC for PWM mode
*/
@ -184,6 +232,20 @@ int32_t _tc_pwm_init(struct _pwm_device *const device, void *const hw)
return 0;
}
/**
* \brief De-initialize TC
*/
void _timer_deinit(struct _timer_device *const device)
{
void *const hw = device->hw;
int8_t i = get_tc_index(hw);
ASSERT(ARRAY_SIZE(_tcs));
NVIC_DisableIRQ(_tcs[i].irq);
hri_tc_clear_CTRLA_ENABLE_bit(hw);
hri_tc_set_CTRLA_SWRST_bit(hw);
}
/**
* \brief De-initialize TC for PWM mode
*/
@ -198,6 +260,13 @@ void _tc_pwm_deinit(struct _pwm_device *const device)
hri_tc_clear_CTRLA_ENABLE_bit(hw);
hri_tc_set_CTRLA_SWRST_bit(hw);
}
/**
* \brief Start hardware timer
*/
void _timer_start(struct _timer_device *const device)
{
hri_tc_set_CTRLA_ENABLE_bit(device->hw);
}
/**
* \brief Start PWM
*/
@ -205,6 +274,13 @@ void _tc_start_pwm(struct _pwm_device *const device)
{
hri_tc_set_CTRLA_ENABLE_bit(device->hw);
}
/**
* \brief Stop hardware timer
*/
void _timer_stop(struct _timer_device *const device)
{
hri_tc_clear_CTRLA_ENABLE_bit(device->hw);
}
/**
* \brief Stop PWM
*/
@ -212,6 +288,21 @@ void _tc_stop_pwm(struct _pwm_device *const device)
{
hri_tc_clear_CTRLA_ENABLE_bit(device->hw);
}
/**
* \brief Set timer period
*/
void _timer_set_period(struct _timer_device *const device, const uint32_t clock_cycles)
{
void *const hw = device->hw;
if (TC_CTRLA_MODE_COUNT32_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
hri_tccount32_write_CC_reg(hw, 0, clock_cycles);
} else if (TC_CTRLA_MODE_COUNT16_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
hri_tccount16_write_CC_reg(hw, 0, (uint16_t)clock_cycles);
} else if (TC_CTRLA_MODE_COUNT8_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
hri_tccount8_write_PER_reg(hw, clock_cycles);
}
}
/**
* \brief Set PWM parameter
*/
@ -264,6 +355,30 @@ uint32_t _tc_pwm_get_duty(const struct _pwm_device *const device)
return ((duty_cycle * 1000) / per);
}
/**
* \brief Retrieve timer period
*/
uint32_t _timer_get_period(const struct _timer_device *const device)
{
void *const hw = device->hw;
if (TC_CTRLA_MODE_COUNT32_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
return hri_tccount32_read_CC_reg(hw, 0);
} else if (TC_CTRLA_MODE_COUNT16_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
return hri_tccount16_read_CC_reg(hw, 0);
} else if (TC_CTRLA_MODE_COUNT8_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
return hri_tccount8_read_PER_reg(hw);
}
return 0;
}
/**
* \brief Check if timer is running
*/
bool _timer_is_started(const struct _timer_device *const device)
{
return hri_tc_get_CTRLA_ENABLE_bit(device->hw);
}
/**
* \brief Check if PWM is running
*/
@ -300,6 +415,33 @@ struct _pwm_hpl_interface *_tc_get_pwm(void)
{
return &_tc_pwm_functions;
}
/**
* \brief Set timer IRQ
*
* \param[in] hw The pointer to hardware instance
*/
void _timer_set_irq(struct _timer_device *const device)
{
void *const hw = device->hw;
int8_t i = get_tc_index(hw);
ASSERT(ARRAY_SIZE(_tcs));
_irq_set(_tcs[i].irq);
}
/**
* \internal TC interrupt handler for Timer
*
* \param[in] instance TC instance number
*/
static void tc_interrupt_handler(struct _timer_device *device)
{
void *const hw = device->hw;
if (hri_tc_get_interrupt_OVF_bit(hw)) {
hri_tc_clear_interrupt_OVF_bit(hw);
device->timer_cb.period_expired(device);
}
}
/**
* \internal TC interrupt handler for PWM
*
@ -323,6 +465,14 @@ static void tc_pwm_interrupt_handler(struct _pwm_device *device)
}
}
/**
* \brief TC interrupt handler
*/
void TC0_Handler(void)
{
tc_interrupt_handler(_tc0_dev);
}
/**
* \brief TC interrupt handler
*/
@ -358,6 +508,9 @@ static int8_t get_tc_index(const void *const hw)
*/
static void _tc_init_irq_param(const void *const hw, void *dev)
{
if (hw == TC0) {
_tc0_dev = (struct _timer_device *)dev;
}
if (hw == TC3) {
_tc3_dev = (struct _pwm_device *)dev;
}

View file

@ -4,13 +4,13 @@
#include "mars_clock.h"
Watch watch;
bool local = true;
int light = 1;
void calendar_callback(struct calendar_descriptor *const calendar) {
struct calendar_date_time date_time;
calendar_get_date_time(&CALENDAR_0, &date_time);
update_display(&watch, date_time, true);
update_display(&watch, date_time);
/*
if (date_time.time.min % 2 == 0) {
watch_set_led_color(50, 0);
@ -21,26 +21,42 @@ void calendar_callback(struct calendar_descriptor *const calendar) {
}
static void mode_callback() {
// local = !local;
struct calendar_date_time date_time;
calendar_get_date_time(&CALENDAR_0, &date_time);
update_display(&watch, date_time, local);
}
static void light_callback() {
}
static void alarm_callback() {
}
static void tick_callback() {
gpio_set_pin_level(GREEN, true);
gpio_set_pin_level(GREEN, false);
}
int main(void)
{
atmel_start_init();
watch_init(&watch);
// watch_enable_led(&watch);
gpio_set_pin_level(GREEN, false);
// Set pin direction to output
gpio_set_pin_direction(GREEN, GPIO_DIRECTION_OUT);
gpio_set_pin_function(GREEN, GPIO_PIN_FUNCTION_OFF);
watch_init(&watch);
watch_enable_display(&watch);
watch_display_pixel(&watch, 1, 16);
watch_enable_interrupts(&watch);
watch_register_interrupt_callback(&watch, BTN_MODE, &mode_callback);
watch_enable_buttons(&watch);
watch_register_button_callback(&watch, BTN_MODE, &mode_callback);
watch_register_button_callback(&watch, BTN_ALARM, &alarm_callback);
watch_register_button_callback(&watch, BTN_LIGHT, &light_callback);
watch_enable_tick(tick_callback);
/*
watch_enable_date_time(&watch);
struct calendar_date_time date_time;
date_time.date.year = 2021;
@ -56,11 +72,11 @@ int main(void)
alarm.cal_alarm.datetime.time.sec = 0;
alarm.cal_alarm.option = CALENDAR_ALARM_MATCH_SEC;
alarm.callback = calendar_callback;
update_display(&watch, date_time, local);
update_display(&watch, date_time);
calendar_set_alarm(&CALENDAR_0, &alarm, &calendar_callback);
*/
while (1) {
//sleep(4);
sleep(2);
}
return 0;

View file

@ -10,7 +10,7 @@
// note: mars time not working, committing just the earth clock.
void update_display(Watch *watch, struct calendar_date_time date_time, bool local) {
void update_display(Watch *watch, struct calendar_date_time date_time) {
char buf[6];
sprintf(&buf[0], "TE %02d%02d", date_time.time.hour, date_time.time.min);
watch_display_string(watch, buf, 0);

View file

@ -11,7 +11,7 @@
#include "hpl_calendar.h"
#include "watch-library/watch.h"
void update_display(Watch *watch, struct calendar_date_time date_time, bool local);
void update_display(Watch *watch, struct calendar_date_time date_time);
#endif /* MARS_CLOCK_H_ */

View file

@ -1,156 +0,0 @@
/**
* \file
*
* \brief Sleep manager 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 <sleep_manager.h>
#include <hal_sleep.h>
#include <utils_assert.h>
/** Event structure used to subscribe to sleep events */
static struct event sleepmgr_event;
/** The list of ready-to-sleep callbacks */
static struct list_descriptor ready_to_sleep_cbs;
/** The list of prepare-to-sleep callbacks */
static struct list_descriptor prepare_to_sleep_cbs;
/** The list of wake up callbacks */
static struct list_descriptor wake_up_cbs;
static void sleepmgr_event_callback(event_id_t id, event_data_t data);
/**
* \brief Initialize sleep manager
*/
void sleepmgr_init(void)
{
event_subscribe(&sleepmgr_event, EVENT_PREPARE_TO_SLEEP_ID, sleepmgr_event_callback);
event_subscribe(&sleepmgr_event, EVENT_IS_READY_TO_SLEEP_ID, sleepmgr_event_callback);
event_subscribe(&sleepmgr_event, EVENT_WOKEN_UP_ID, sleepmgr_event_callback);
}
/**
* \brief Register sleep callback
*/
void sleepmgr_register_ready_to_sleep_callback(struct sleepmgr_ready_to_sleep_cb *const cb)
{
ASSERT(cb);
list_insert_as_head(&ready_to_sleep_cbs, cb);
}
/**
* \brief Register wake up callback
*/
void sleepmgr_register_prepare_to_sleep_callback(struct sleepmgr_prepare_to_sleep_cb *const cb)
{
ASSERT(cb);
list_insert_as_head(&prepare_to_sleep_cbs, cb);
}
/**
* \brief Register wake up callback
*/
void sleepmgr_register_wake_up_callback(struct sleepmgr_wake_up_cb *const cb)
{
ASSERT(cb);
list_insert_as_head(&wake_up_cbs, cb);
}
/**
* \brief Go to sleep
*/
void sleepmgr_sleep(const uint8_t mode)
{
event_post(EVENT_PREPARE_TO_SLEEP_ID, mode);
sleep(mode);
}
/**
* \brief Send wake-up notification
*/
void sleepmgr_wakeup(const enum sleepmgr_wakeup_source source)
{
event_post(EVENT_WOKEN_UP_ID, source);
}
/**
* \brief Check if device is ready to sleep
*/
bool sleepmgr_is_ready_to_sleep(const uint8_t mode)
{
struct sleepmgr_ready_to_sleep ready;
ready.ready = true;
ready.mode = mode;
event_post(EVENT_IS_READY_TO_SLEEP_ID, (event_data_t)&ready);
return ready.ready;
}
/**
* \brief "Going to sleep" event callback
*
* \param[in] id The event ID to process
* \param[in] data Not used
*/
static void sleepmgr_event_callback(event_id_t id, event_data_t data)
{
if (EVENT_IS_READY_TO_SLEEP_ID == id) {
struct sleepmgr_ready_to_sleep_cb *cur;
struct sleepmgr_ready_to_sleep * ret_val = (struct sleepmgr_ready_to_sleep *)data;
struct sleepmgr_ready_to_sleep ready;
for (cur = (struct sleepmgr_ready_to_sleep_cb *)list_get_head(&ready_to_sleep_cbs); cur;
cur = (struct sleepmgr_ready_to_sleep_cb *)list_get_next_element(cur)) {
ready.mode = ret_val->mode;
ready.ready = true;
cur->cb(&ready);
ret_val->ready &= ready.ready;
}
} else if (EVENT_WOKEN_UP_ID == id) {
struct sleepmgr_wake_up_cb *cur;
for (cur = (struct sleepmgr_wake_up_cb *)list_get_head(&wake_up_cbs); cur;
cur = (struct sleepmgr_wake_up_cb *)list_get_next_element(cur)) {
cur->cb((const enum sleepmgr_wakeup_source)data);
}
} else if (EVENT_PREPARE_TO_SLEEP_ID == id) {
struct sleepmgr_prepare_to_sleep_cb *cur;
for (cur = (struct sleepmgr_prepare_to_sleep_cb *)list_get_head(&prepare_to_sleep_cbs); cur;
cur = (struct sleepmgr_prepare_to_sleep_cb *)list_get_next_element(cur)) {
cur->cb(data);
}
}
}

View file

@ -1,157 +0,0 @@
/**
* \file
*
* \brief Sleep manager 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 _SLEEP_MANAGER_H_INCLUDED
#define _SLEEP_MANAGER_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include <utils_event.h>
/**
* \brief Wake up sources.
*/
enum sleepmgr_wakeup_source { SM_WAKEUP_SOURCE_EXT_IRQ, SM_WAKEUP_SOURCE_IRQ };
struct sleepmgr_ready_to_sleep;
/**
* \brief The type of a callback called before going to sleep
*/
typedef void (*sleepmgr_ready_to_sleep_callback_t)(struct sleepmgr_ready_to_sleep *const ready);
/**
* \brief The type of a callback called right before going to sleep
*/
typedef void (*sleepmgr_prepare_to_sleep_callback_t)(const uint8_t mode);
/**
* \brief The type of a callback called after waking up
*/
typedef void (*sleepmgr_wake_up_callback_t)(const enum sleepmgr_wakeup_source source);
/**
* \brief The is ready to sleep callback structure
*/
struct sleepmgr_ready_to_sleep_cb {
struct is_ready_to_sleep_service {
struct list_element elem; /*! The pointer to next callback */
} service; /*! For internal use only */
/*! The callback to be called to ask modules about thier active status */
sleepmgr_ready_to_sleep_callback_t cb;
};
/**
* \brief The prepare to sleep callback structure
*/
struct sleepmgr_prepare_to_sleep_cb {
struct prepare_to_sleep_service {
struct list_element elem; /*! The pointer to next callback */
} service; /*! For internal use only */
/*! The callback to be called right before going to sleep */
sleepmgr_prepare_to_sleep_callback_t cb;
};
/**
* \brief The wake up callback structure
*/
struct sleepmgr_wake_up_cb {
struct wake_up_service {
struct list_element elem; /*! The pointer to next callback */
} service; /*! For internal use only */
/*! The callback to be called after waking up */
sleepmgr_wake_up_callback_t cb;
};
/**
* \brief The structure used in ready to sleep callback
*/
struct sleepmgr_ready_to_sleep {
bool ready; /*! Ready to sleep flag */
uint8_t mode; /*! The sleep mode to be used */
};
/**
* \brief Initialize sleep manager
*/
void sleepmgr_init(void);
/**
* \brief Register is ready to sleep callback
*
* \param[in] cb Callback to register
*/
void sleepmgr_register_ready_to_sleep_callback(struct sleepmgr_ready_to_sleep_cb *const cb);
/**
* \brief Register wake up callback
*
* \param[in] cb Callback to register
*/
void sleepmgr_register_prepare_to_sleep_callback(struct sleepmgr_prepare_to_sleep_cb *const cb);
/**
* \brief Register wake up callback
*
* \param[in] cb Callback to register
*/
void sleepmgr_register_wake_up_callback(struct sleepmgr_wake_up_cb *const cb);
/**
* \brief Go to sleep
*
* \param[in] mode Sleep mode to use
*/
void sleepmgr_sleep(const uint8_t mode);
/**
* \brief Send wake-up notification
*/
void sleepmgr_wakeup(const enum sleepmgr_wakeup_source source);
/**
* \brief Check if device is ready to sleep
*
* \param[in] mode Sleep mode to use
*
* \return True if device is ready to sleep, false otherwise
*/
bool sleepmgr_is_ready_to_sleep(const uint8_t mode);
#ifdef __cplusplus
}
#endif
#endif /* _SLEEP_MANAGER_H_INCLUDED */

View file

@ -1,24 +0,0 @@
/*
* Code generated from Atmel Start.
*
* This file will be overwritten when reconfiguring your Atmel Start project.
* Please copy examples or other code you want to keep to a separate file or main.c
* to avoid loosing it when reconfiguring.
*/
#include "atmel_start.h"
#include "sleep_manager_main.h"
static struct sleepmgr_ready_to_sleep_cb sleepmgr_cb;
static void sleep_cb(struct sleepmgr_ready_to_sleep *const ready)
{
ready->ready = false;
}
void sleep_manager_init(void)
{
sleepmgr_init();
sleepmgr_cb.cb = sleep_cb;
sleepmgr_register_ready_to_sleep_callback(&sleepmgr_cb);
}

View file

@ -1,23 +0,0 @@
/*
* Code generated from Atmel Start.
*
* This file will be overwritten when reconfiguring your Atmel Start project.
* Please copy examples or other code you want to keep to a separate file or main.c
* to avoid loosing it when reconfiguring.
*/
#ifndef SLEEP_MANAGER_MAIN_H
#define SLEEP_MANAGER_MAIN_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <sleep_manager.h>
void sleep_manager_init(void);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // SLEEP_MANAGER_MAIN_H

View file

@ -173,11 +173,11 @@ void watch_display_string(Watch *watch, char *string, uint8_t position) {
}
}
void watch_enable_interrupts(Watch *watch) {
void watch_enable_buttons(Watch *watch) {
EXTERNAL_IRQ_0_init();
}
void watch_register_interrupt_callback(Watch *watch, const uint32_t pin, ext_irq_cb_t callback) {
void watch_register_button_callback(Watch *watch, const uint32_t pin, ext_irq_cb_t callback) {
ext_irq_register(pin, callback);
}
@ -189,6 +189,7 @@ void watch_enable_led(Watch *watch) {
pwm_enable(&PWM_0);
watch->led_enabled = true;
watch_set_led_off();
}
void watch_disable_led(Watch *watch) {
@ -215,6 +216,10 @@ void watch_set_led_green() {
watch_set_led_color(0, 65535);
}
void watch_set_led_off() {
watch_set_led_color(0, 0);
}
void watch_enable_date_time(Watch *watch) {
if (watch->calendar_enabled) return;
CALENDAR_0_init();
@ -232,6 +237,26 @@ void watch_get_date_time(struct calendar_date_time *date_time) {
calendar_get_date_time(&CALENDAR_0, date_time);
}
static ext_irq_cb_t tick_user_callback;
static void tick_callback(const struct timer_task *const timer_task) {
tick_user_callback();
}
static struct timer_task tick_task;
void watch_enable_tick(ext_irq_cb_t callback) {
TIMER_0_init();
tick_task.interval = 16384;
tick_task.cb = tick_callback;
tick_task.mode = TIMER_TASK_REPEAT;
tick_user_callback = callback;
timer_add_task(&TIMER_0, &tick_task);
timer_start(&TIMER_0);
}
void watch_enable_analog(Watch *watch, const uint8_t pin) {
if (!watch->adc_enabled) ADC_0_init();

View file

@ -11,6 +11,9 @@
#include <stdint.h>
#include "hpl_calendar.h"
#include "hal_ext_irq.h"
#include "hal_timer.h"
typedef void (*watch_tick_cb)(void);
typedef struct Watch {
bool display_enabled;
@ -37,15 +40,18 @@ void watch_disable_led(Watch *watch);
void watch_set_led_color(uint16_t red, uint16_t green);
void watch_set_led_red();
void watch_set_led_green();
void watch_set_led_off();
void watch_enable_date_time(Watch *watch);
void watch_set_date_time(struct calendar_date_time date_time);
void watch_get_date_time(struct calendar_date_time *date_time);
void watch_enable_tick(ext_irq_cb_t callback);
void watch_enable_analog(Watch *watch, const uint8_t pin);
void watch_enable_interrupts(Watch *watch);
void watch_register_interrupt_callback(Watch *watch, const uint32_t pin, ext_irq_cb_t callback);
void watch_enable_buttons(Watch *watch);
void watch_register_button_callback(Watch *watch, const uint32_t pin, ext_irq_cb_t callback);
void watch_enable_digital_input(const uint8_t pin);
void watch_enable_digital_output(const uint8_t pin);