Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
François Revol
firmware
Commits
db390227
Verified
Commit
db390227
authored
Jul 31, 2019
by
Rahix
Browse files
feat(rtc): Add RTC alarm interrupt
Signed-off-by:
Rahix
<
rahix@rahix.de
>
parent
d66db156
Changes
4
Hide whitespace changes
Inline
Side-by-side
epicardium/epicardium.h
View file @
db390227
...
...
@@ -60,6 +60,7 @@ typedef unsigned int size_t;
#define API_FILE_STAT 0x38
#define API_RTC_GET_SECONDS 0x40
#define API_RTC_SCHEDULE_ALARM 0x41
/* clang-format on */
typedef
uint32_t
api_int_id_t
;
...
...
@@ -100,8 +101,11 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id));
#define EPIC_INT_BHI160_TEST 2
API_ISR
(
EPIC_INT_BHI160_TEST
,
epic_isr_bhi160_test
);
/** RTC Alarm interrupt. See :c:func:`epic_isr_rtc_alarm` */
#define EPIC_INT_RTC_ALARM 3
/* Number of defined interrupts. */
#define EPIC_INT_NUM
3
#define EPIC_INT_NUM
4
/* clang-format on */
API_ISR
(
EPIC_INT_RESET
,
epic_isr_reset
);
...
...
@@ -589,4 +593,23 @@ API(API_FILE_STAT, int epic_file_stat(const char* path, epic_stat_t* stat));
*/
API
(
API_RTC_GET_SECONDS
,
uint32_t
epic_rtc_get_seconds
(
void
));
/**
* Schedule the RTC alarm for the given timestamp.
*
* :param uint32_t timestamp: When to schedule the IRQ
* :return: `0` on success or a negative value if an error occured. Possible
* errors:
*
* - ``-EINVAL``: RTC is in a bad state
*/
API
(
API_RTC_SCHEDULE_ALARM
,
int
epic_rtc_schedule_alarm
(
uint32_t
timestamp
));
/**
* **Interrupt Service Routine**
*
* ``epic_isr_rtc_alarm()`` is called when the RTC alarm triggers. The RTC alarm
* can be scheduled using :c:func:`epic_rtc_schedule_alarm`.
*/
API_ISR
(
EPIC_INT_RTC_ALARM
,
epic_isr_rtc_alarm
);
#endif
/* _EPICARDIUM_H */
epicardium/modules/rtc.c
View file @
db390227
#include
"epicardium.h"
#include
"modules/log.h"
#include
"api/interrupt-sender.h"
#include
"rtc.h"
#include
<stdint.h>
...
...
@@ -6,3 +10,33 @@ uint32_t epic_rtc_get_seconds(void)
{
return
RTC_GetSecond
();
}
void
RTC_IRQHandler
(
void
)
{
int
flags
=
RTC_GetFlags
();
if
(
flags
&
MXC_F_RTC_CTRL_ALDF
)
{
RTC_ClearFlags
(
MXC_F_RTC_CTRL_ALDF
);
api_interrupt_trigger
(
EPIC_INT_RTC_ALARM
);
}
else
{
LOG_WARN
(
"rtc"
,
"Unknown IRQ caught!"
);
/* Disable IRQ so it does not retrigger */
NVIC_DisableIRQ
(
RTC_IRQn
);
}
}
int
epic_rtc_schedule_alarm
(
uint32_t
timestamp
)
{
int
res
;
NVIC_EnableIRQ
(
RTC_IRQn
);
while
((
res
=
RTC_SetTimeofdayAlarm
(
MXC_RTC
,
timestamp
))
==
E_BUSY
)
;
if
(
res
!=
E_SUCCESS
)
{
return
-
EINVAL
;
}
return
0
;
}
pycardium/modules/qstrdefs.h
View file @
db390227
...
...
@@ -13,6 +13,7 @@ Q(TOP_RIGHT)
/* utime */
Q
(
utime
)
Q
(
alarm
)
Q
(
sleep
)
Q
(
sleep_ms
)
Q
(
sleep_us
)
...
...
pycardium/modules/utime.c
View file @
db390227
#include
"interrupt.h"
#include
"epicardium.h"
#include
"mxc_delay.h"
...
...
@@ -12,11 +13,13 @@
// Needs to be after the stdint include ...
#include
"lib/timeutils/timeutils.h"
/* MicroPython has its epoch at 2000-01-01. Our RTC is in UTC */
#define EPOCH_OFFSET 946684800UL
static
mp_obj_t
time_time
(
void
)
{
mp_int_t
seconds
;
/* MicroPython has its epoch at 2000-01-01. Our RTC is in UTC */
seconds
=
epic_rtc_get_seconds
()
-
946684800UL
;
seconds
=
epic_rtc_get_seconds
()
-
EPOCH_OFFSET
;
return
mp_obj_new_int
(
seconds
);
}
MP_DEFINE_CONST_FUN_OBJ_0
(
time_time_obj
,
time_time
);
...
...
@@ -26,7 +29,7 @@ static mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args)
mp_int_t
seconds
;
if
(
n_args
==
0
||
args
[
0
]
==
mp_const_none
)
{
seconds
=
epic_rtc_get_seconds
()
-
946684800UL
;
seconds
=
epic_rtc_get_seconds
()
-
EPOCH_OFFSET
;
}
else
{
seconds
=
mp_obj_get_int
(
args
[
0
]);
}
...
...
@@ -75,6 +78,26 @@ static mp_obj_t time_mktime(mp_obj_t tuple)
}
static
MP_DEFINE_CONST_FUN_OBJ_1
(
time_mktime_obj
,
time_mktime
);
/* Schedule an alarm */
static
mp_obj_t
time_alarm
(
size_t
n_args
,
const
mp_obj_t
*
args
)
{
mp_int_t
timestamp
=
mp_obj_get_int
(
args
[
0
])
+
EPOCH_OFFSET
;
if
(
n_args
==
2
)
{
/* If a callback was given, register it for the RTC Alarm */
mp_obj_t
callback
=
args
[
1
];
mp_obj_t
irq_id
=
MP_OBJ_NEW_SMALL_INT
(
EPIC_INT_RTC_ALARM
);
mp_interrupt_set_callback
(
irq_id
,
callback
);
mp_interrupt_enable_callback
(
irq_id
);
}
int
res
=
epic_rtc_schedule_alarm
(
timestamp
);
if
(
res
<
0
)
{
mp_raise_OSError
(
-
res
);
}
return
mp_const_none
;
}
static
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
time_alarm_obj
,
1
,
2
,
time_alarm
);
static
const
mp_rom_map_elem_t
time_module_globals_table
[]
=
{
{
MP_ROM_QSTR
(
MP_QSTR___name__
),
MP_ROM_QSTR
(
MP_QSTR_utime
)
},
{
MP_ROM_QSTR
(
MP_QSTR_time
),
MP_ROM_PTR
(
&
time_time_obj
)
},
...
...
@@ -83,6 +106,7 @@ static const mp_rom_map_elem_t time_module_globals_table[] = {
{
MP_ROM_QSTR
(
MP_QSTR_sleep
),
MP_ROM_PTR
(
&
mp_utime_sleep_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_sleep_ms
),
MP_ROM_PTR
(
&
mp_utime_sleep_ms_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_sleep_us
),
MP_ROM_PTR
(
&
mp_utime_sleep_us_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_alarm
),
MP_ROM_PTR
(
&
time_alarm_obj
)
},
#if 0
/* TODO: Implement those */
{MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mp_utime_ticks_ms_obj)},
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment