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

This commit is contained in:
Damien 2013-11-06 23:04:33 +00:00
parent f72fd0e875
commit bd8e110207
6 changed files with 119 additions and 4 deletions

View File

@ -26,6 +26,7 @@ SRC_C = \
usart.c \
usb.c \
sdio.c \
timer.c \
audio.c \
lexerstm.c \

View File

@ -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

View File

@ -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;
}

View File

@ -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****/

90
stm/timer.c Normal file
View File

@ -0,0 +1,90 @@
#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");
}
}
}

1
stm/timer.h Normal file
View File

@ -0,0 +1 @@
void timer_init(void);