Skip to content
Snippets Groups Projects
Commit bd8e1102 authored by Damien's avatar Damien
Browse files

Add to STM code timer functionality to call Python on interrupt.

parent f72fd0e8
No related branches found
No related tags found
No related merge requests found
......@@ -26,6 +26,7 @@ SRC_C = \
usart.c \
usb.c \
sdio.c \
timer.c \
audio.c \
lexerstm.c \
......
......@@ -6,13 +6,13 @@
#include "nlr.h"
#include "misc.h"
//#include "lexer.h"
//#include "lexerstm.h"
#include "mpyconfig.h"
#include "parse.h"
#include "compile.h"
#include "runtime.h"
#include "audio.h"
#define SAMPLE_BUF_SIZE (32)
// sample_buf_in is always the same or ahead of sample_buf_out
......
......@@ -20,6 +20,7 @@
#include "usart.h"
#include "usb.h"
#include "ff.h"
#include "timer.h"
#include "audio.h"
static FATFS fatfs0;
......@@ -525,7 +526,7 @@ py_obj_t pyb_pwm_set(py_obj_t period, py_obj_t pulse) {
#define MMA_ADDR (0x4c)
py_obj_t pyb_mma_read() {
py_obj_t pyb_mma_read(void) {
mma_start(MMA_ADDR, 1);
mma_send_byte(0);
mma_restart(MMA_ADDR, 0);
......@@ -731,6 +732,8 @@ int main(void) {
storage_init();
usart_init();
int first_soft_reset = true;
soft_reset:
// LCD init
......@@ -749,6 +752,9 @@ soft_reset:
// audio
audio_init();
// timer
timer_init();
// add some functions to the python namespace
{
py_obj_t m = py_module_new();
......@@ -846,7 +852,7 @@ soft_reset:
usb_init();
// MMA
{
if (first_soft_reset) {
// init and reset address to zero
mma_init();
mma_start(MMA_ADDR, 1);
......@@ -1123,6 +1129,8 @@ soft_reset:
pyb_sync();
printf("PYB: soft reboot\n");
first_soft_reset = false;
goto soft_reset;
}
......
......@@ -251,4 +251,19 @@ void SDIO_IRQHandler(void)
{
}*/
// TIM6 Update event
#include "stm32f4xx_tim.h"
void TIM6_DAC_IRQHandler(void) {
// work out if it's TIM6 that had the interrupt
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) {
extern void timer_interrupt(void);
timer_interrupt();
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
} else {
// it seems we get 2 calls to this interrupt handler, and only 1 is the TIM_IT_Update...
// TODO work out what the other one is, and if we can disable it
//printf("unhandled TIM6_DAC\n");
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#include <stdint.h>
#include <stdio.h>
#include "stm_misc.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
#include "nlr.h"
#include "misc.h"
#include "mpyconfig.h"
#include "parse.h"
#include "compile.h"
#include "runtime.h"
#include "timer.h"
// TIM6 is used as an internal interrup to schedule something at a specific rate
py_obj_t timer_py_callback;
py_obj_t timer_py_set_callback(py_obj_t f) {
timer_py_callback = f;
return py_const_none;
}
py_obj_t timer_py_set_period(py_obj_t period) {
TIM6->ARR = py_obj_get_int(period) & 0xffff;
//TIM6->PSC = prescaler & 0xffff;
return py_const_none;
}
py_obj_t timer_py_get_value(void) {
return py_obj_new_int(TIM6->CNT & 0xfffff);
}
void timer_init(void) {
timer_py_callback = py_const_none;
// TIM6 clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
// Compute the prescaler value so TIM6 runs at 10kHz
uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 10000) - 1;
// Time base configuration
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 10000; // timer cycles at 1Hz
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // unused for TIM6
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // unused for TIM6
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
// enable perhipheral preload register
TIM_ARRPreloadConfig(TIM6, ENABLE);
// enable interrupt when counter overflows
TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
// set up interrupt
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0f; // lowest priority
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0f; // lowest priority
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// TIM6 enable counter
TIM_Cmd(TIM6, ENABLE);
// Python interface
py_obj_t m = py_module_new();
rt_store_attr(m, qstr_from_str_static("callback"), rt_make_function_1(timer_py_set_callback));
rt_store_attr(m, qstr_from_str_static("period"), rt_make_function_1(timer_py_set_period));
rt_store_attr(m, qstr_from_str_static("value"), rt_make_function_0(timer_py_get_value));
rt_store_name(qstr_from_str_static("timer"), m);
}
void timer_interrupt(void) {
if (timer_py_callback != py_const_none) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
rt_call_function_0(timer_py_callback);
nlr_pop();
} else {
// uncaught exception
printf("exception in timer interrupt\n");
py_obj_print((py_obj_t)nlr.ret_val);
printf("\n");
}
}
}
void timer_init(void);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment