working fft shite

This commit is contained in:
2016-05-25 14:10:53 +02:00
parent 58faf80df8
commit bd7f65abdb
295 changed files with 170094 additions and 1499 deletions
+41 -5
View File
@@ -53,13 +53,21 @@ void dmtx_blank(DotMatrix_Cfg* dmtx, bool blank)
max2719_cmd_all(&dmtx->drv, MAX2719_CMD_SHUTDOWN, blank & 0x01);
}
void dmtx_set(DotMatrix_Cfg* dmtx, int32_t x, int32_t y, bool bit)
/**
* @brief Get a cell pointer
* @param dmtx : driver inst
* @param x : x coord
* @param y : y coord
* @param xd : pointer to store the offset in the cell
* @return cell ptr
*/
static uint8_t* cell_ptr(DotMatrix_Cfg* dmtx, int32_t x, int32_t y, uint8_t *xd)
{
if (x < 0 || y < 0) return;
if ((uint32_t)x >= dmtx->cols*8 || (uint32_t)y >= dmtx->rows*8) return;
if (x < 0 || y < 0) return NULL;
if ((uint32_t)x >= dmtx->cols*8 || (uint32_t)y >= dmtx->rows*8) return NULL;
uint32_t cell_x = (uint32_t)x >> 3;
uint8_t xd = x & 7;
*xd = x & 7;
// resolve cell
uint32_t digit = y & 7;
@@ -67,7 +75,35 @@ void dmtx_set(DotMatrix_Cfg* dmtx, int32_t x, int32_t y, bool bit)
uint32_t cell_idx = (digit * dmtx->drv.chain_len) + cell_x;
uint8_t *cell = &dmtx->screen[cell_idx];
return &dmtx->screen[cell_idx];
}
bool dmtx_get(DotMatrix_Cfg* dmtx, int32_t x, int32_t y)
{
uint8_t xd;
uint8_t *cell = cell_ptr(dmtx, x, y, &xd);
if (cell == NULL) return 0;
return (bool)(*cell & (1 << xd));
}
void dmtx_toggle(DotMatrix_Cfg* dmtx, int32_t x, int32_t y)
{
uint8_t xd;
uint8_t *cell = cell_ptr(dmtx, x, y, &xd);
if (cell == NULL) return;
*cell ^= 1 << xd;
}
void dmtx_set(DotMatrix_Cfg* dmtx, int32_t x, int32_t y, bool bit)
{
uint8_t xd;
uint8_t *cell = cell_ptr(dmtx, x, y, &xd);
if (cell == NULL) return;
if (bit) {
*cell |= bit << xd;
+6
View File
@@ -43,6 +43,12 @@ void dmtx_blank(DotMatrix_Cfg* dmtx, bool blank);
*/
void dmtx_set(DotMatrix_Cfg* dmtx, int32_t x, int32_t y, bool bit);
/** Get a single bit */
bool dmtx_get(DotMatrix_Cfg* dmtx, int32_t x, int32_t y);
/** Toggle a single bit */
void dmtx_toggle(DotMatrix_Cfg* dmtx, int32_t x, int32_t y);
/** Clear the screen (not showing) */
void dmtx_clear(DotMatrix_Cfg* dmtx);
+103 -14
View File
@@ -18,7 +18,7 @@ static void conf_spi(void);
static void conf_systick(void);
static void conf_subsystems(void);
static void conf_irq_prios(void);
static void conf_adc(void);
// ---- Public functions ----------
/**
@@ -30,6 +30,7 @@ void hw_init(void)
conf_usart();
conf_systick();
conf_spi();
conf_adc();
conf_irq_prios();
conf_subsystems();
}
@@ -86,23 +87,23 @@ static void conf_gpio(void)
gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOC, &gpio_cnf);
// colorled | sonar trig
gpio_cnf.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;
gpio_cnf.GPIO_Mode = GPIO_Mode_Out_PP;
gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &gpio_cnf);
gpio_cnf.GPIO_Pin = GPIO_Pin_14;
gpio_cnf.GPIO_Mode = GPIO_Mode_IPD;
gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &gpio_cnf);
// A0-sonar trig | UART2 - debug, UART1 - esp
gpio_cnf.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_9 | GPIO_Pin_10;
// UARTs
gpio_cnf.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_9;
gpio_cnf.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &gpio_cnf);
gpio_cnf.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_3;
gpio_cnf.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &gpio_cnf);
// A0 - analog input for ADC
gpio_cnf.GPIO_Pin = GPIO_Pin_0;
gpio_cnf.GPIO_Mode = GPIO_Mode_AIN;
gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &gpio_cnf);
// SPI
gpio_cnf.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
gpio_cnf.GPIO_Mode = GPIO_Mode_AF_PP;
@@ -129,6 +130,7 @@ static void conf_usart(void)
// Datalink iface
data_iface = usart_iface_init(USART1, 460800, 256, 256);
}
/**
@@ -159,3 +161,90 @@ static void conf_systick(void)
{
SysTick_Config(F_CPU / 1000);
}
static void conf_adc(void)
{
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
RCC_APB2PeriphClockCmd(RCC_APB2ENR_ADC1EN, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM3EN, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1EN, ENABLE);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
// Configure the ADC
ADC_DeInit(ADC1);
ADC_InitTypeDef adc_cnf;
adc_cnf.ADC_Mode = ADC_Mode_Independent;
adc_cnf.ADC_ScanConvMode = DISABLE;
adc_cnf.ADC_ContinuousConvMode = DISABLE;
adc_cnf.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;
adc_cnf.ADC_DataAlign = ADC_DataAlign_Right;
adc_cnf.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &adc_cnf);
ADC_Cmd(ADC1, ENABLE);
ADC_ExternalTrigConvCmd(ADC1, ENABLE);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
// calib
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
// Configure the DMA timer
TIM_DeInit(TIM3);
TIM_TimeBaseInitTypeDef tim_cnf;
tim_cnf.TIM_Period = 1800;
tim_cnf.TIM_Prescaler = 1;
tim_cnf.TIM_ClockDivision = TIM_CKD_DIV1;
tim_cnf.TIM_CounterMode = TIM_CounterMode_Up;
tim_cnf.TIM_RepetitionCounter = 0x0000;
TIM_TimeBaseInit(TIM3, &tim_cnf);
TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
//TIM3->CR1 |= TIM_CR1_URS; // generate update on overflow
//TIM3->CR2 |= TIM_CR2_MMS_1; // trig on update
}
void start_adc_dma(uint32_t *memory, uint32_t count)
{
ADC_Cmd(ADC1, DISABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitTypeDef dma_cnf;
dma_cnf.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
dma_cnf.DMA_MemoryBaseAddr = (uint32_t)memory;
dma_cnf.DMA_DIR = DMA_DIR_PeripheralSRC;
dma_cnf.DMA_BufferSize = count;
dma_cnf.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_cnf.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_cnf.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
dma_cnf.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
dma_cnf.DMA_Mode = DMA_Mode_Normal;
dma_cnf.DMA_Priority = DMA_Priority_Low;
dma_cnf.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &dma_cnf);
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE);
TIM_Cmd(TIM3, ENABLE);
}
void DMA1_Channel1_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC1);
DMA_ClearITPendingBit(DMA1_IT_TE1);
DMA_DeInit(DMA1_Channel1);
TIM_Cmd(TIM3, DISABLE);
ADC_DMACmd(ADC1, DISABLE);
tq_post(audio_capture_done, NULL);
}
+1
View File
@@ -4,3 +4,4 @@
void hw_init(void);
void start_adc_dma(uint32_t *memory, uint32_t count);
+66 -23
View File
@@ -18,10 +18,72 @@
#include "max2719.h"
#include "dotmatrix.h"
#include "arm_math.h"
static void poll_subsystems(void);
static DotMatrix_Cfg *dmtx;
#define SAMP_BUF_LEN 128
union samp_buf_union {
uint32_t uints[SAMP_BUF_LEN];
float floats[SAMP_BUF_LEN];
uint8_t as_bytes[SAMP_BUF_LEN*sizeof(uint32_t)];
};
// sample buffers (static - invalidated when sampling starts anew).
static union samp_buf_union samp_buf;
void audio_capture_done(void* unused)
{
(void)unused;
const int samp_count = SAMP_BUF_LEN/2;
const int bin_count = SAMP_BUF_LEN/4;
float *bins = samp_buf.floats;
for (int i = 0; i < samp_count; i++) {
samp_buf.floats[i] = samp_buf.uints[i] - 2045.0f;
}
for (int i = samp_count - 1; i >= 0; i--) {
bins[i * 2 + 1] = 0; // imaginary
bins[i * 2] = samp_buf.floats[i]; // real
}
const arm_cfft_instance_f32 *S;
S = &arm_cfft_sR_f32_len64;
arm_cfft_f32(S, bins, 0, true); // bit reversed FFT
arm_cmplx_mag_f32(bins, bins, bin_count); // get magnitude (extract real values)
// normalize
dmtx_clear(dmtx);
float factor = (1.0f/bin_count)*0.1f;
for(int i = 0; i < bin_count-1; i+=2) {
bins[i] *= factor;
bins[i+1] *= factor;
float avg = i==0 ? bins[1] : (bins[i] + bins[i+1])/2;
for(int j = 0; j < ceilf(avg); j++) {
dmtx_set(dmtx, i/2, j, true);
}
}
dmtx_show(dmtx);
}
static void capture_audio(void *unused)
{
(void)unused;
start_adc_dma(samp_buf.uints, SAMP_BUF_LEN/2);
}
int main(void)
{
@@ -40,36 +102,17 @@ int main(void)
dmtx = dmtx_init(&dmtx_cfg);
dmtx_intensity(dmtx, 2);
dmtx_intensity(dmtx, 7);
add_periodic_task(capture_audio, NULL, 10, false);
ms_time_t last;
while (1) {
if (ms_loop_elapsed(&last, 500)) {
GPIOC->ODR ^= 1 << 13;
}
poll_subsystems();
// 1
dmtx_clear(dmtx);
for (int i = 0; i <= 15; i++) {
dmtx_set(dmtx, i, i, true);
dmtx_set(dmtx, i+2, i-2, true);
dmtx_set(dmtx, i-2, i+2, true);
}
dmtx_show(dmtx);
delay_ms(500);
// 2
dmtx_clear(dmtx);
for (int i = 0; i <= 15; i++) {
dmtx_set(dmtx, 15-i, i, true);
dmtx_set(dmtx, 15-(i+2), i-2, true);
dmtx_set(dmtx, 15-(i-2), i+2, true);
}
dmtx_show(dmtx);
delay_ms(500);
}
}
+3
View File
@@ -15,4 +15,7 @@
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
void audio_capture_done(void* unused);
#endif // MAIN_H