diff options
Diffstat (limited to 'stm/audio.c')
-rw-r--r-- | stm/audio.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/stm/audio.c b/stm/audio.c new file mode 100644 index 0000000000..2df4e07941 --- /dev/null +++ b/stm/audio.c @@ -0,0 +1,98 @@ +#include <stdint.h> + +#include "stm32f4xx_rcc.h" +#include "stm32f4xx_gpio.h" +#include "stm32f4xx_dac.h" + +#include "nlr.h" +#include "misc.h" +//#include "lexer.h" +//#include "lexerstm.h" +#include "mpyconfig.h" +#include "parse.h" +#include "compile.h" +#include "runtime.h" + +#define SAMPLE_BUF_SIZE (32) + +// sample_buf_in is always the same or ahead of sample_buf_out +// when they are the same, there are no more samples left to process +// in this scheme, there is always 1 unusable byte in the buffer, just before sample_buf_out +int sample_buf_in; +int sample_buf_out; +byte sample_buf[SAMPLE_BUF_SIZE]; + +bool audio_is_full(void) { + return ((sample_buf_in + 1) % SAMPLE_BUF_SIZE) == sample_buf_out; +} + +void audio_fill(byte sample) { + sample_buf[sample_buf_in] = sample; + sample_buf_in = (sample_buf_in + 1) % SAMPLE_BUF_SIZE; + // enable interrupt +} + +void audio_drain(void) { + if (sample_buf_in == sample_buf_out) { + // buffer is empty; disable interrupt + } else { + // buffer has a sample; output it + byte sample = sample_buf[sample_buf_out]; + DAC_SetChannel2Data(DAC_Align_8b_R, sample); + sample_buf_out = (sample_buf_out + 1) % SAMPLE_BUF_SIZE; + } +} + +// direct access to DAC +py_obj_t pyb_audio_dac(py_obj_t val) { + DAC_SetChannel2Data(DAC_Align_8b_R, py_obj_get_int(val)); + return py_const_none; +} + +py_obj_t pyb_audio_is_full(void) { + if (audio_is_full()) { + return py_const_true; + } else { + return py_const_false; + } +} + +py_obj_t pyb_audio_fill(py_obj_t val) { + audio_fill(py_obj_get_int(val)); + return py_const_none; +} + +void audio_init(void) { + // DAC peripheral clock + RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); + + // DAC channel 2 (DAC_OUT2 = PA.5) configuration + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + // DAC channel2 Configuration + DAC_InitTypeDef DAC_InitStructure; + DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; + DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; + DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; + DAC_Init(DAC_Channel_2, &DAC_InitStructure); + + // Enable DAC Channel2 + DAC_Cmd(DAC_Channel_2, ENABLE); + + // from now on use DAC_SetChannel2Data to trigger a conversion + + sample_buf_in = 0; + sample_buf_out = 0; + // enable interrupt + + // Python interface + py_obj_t m = py_module_new(); + rt_store_attr(m, qstr_from_str_static("dac"), rt_make_function_1(pyb_audio_dac)); + rt_store_attr(m, qstr_from_str_static("is_full"), rt_make_function_0(pyb_audio_is_full)); + rt_store_attr(m, qstr_from_str_static("fill"), rt_make_function_1(pyb_audio_fill)); + rt_store_name(qstr_from_str_static("audio"), m); +} |