Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //ColorChordEmbedded implementation on the STM32F407 for the stm32f4-discovery.
- //Uses on-board microphone and outputs WS2812 signal for configurable number of LEDs
- //on PB5 via DMA+SPI
- #include <stdint.h>
- #include <stdio.h>
- #include "adc.h"
- #include <systems.h>
- #include <math.h>
- #include <stm32f4xx_exti.h>
- #include <DFT32.h>
- #include <embeddednf.h>
- #include <embeddedout.h>
- #include "mp45dt02.h"
- //retarted shit
- #include <misc.h>
- #include <stm32f4xx_rcc.h>
- #include <stm32f4xx_gpio.h>
- #include <stm32f4xx_adc.h>
- #include <stm32f4xx_tim.h>
- #include <adc.h>
- #include <stm32f4xx_rcc.h>
- #include <stm32f4xx_gpio.h>
- #include <stm32f4xx_spi.h>
- #include <stm32f4xx_dma.h>
- #include <misc.h>
- #include "stm32f4xx_it.h"
- #include <stdint.h>
- #include "ccconfig.h"
- #include "mp45dt02.h"
- #include <stm32f4xx_rcc.h>
- #include <stm32f4xx_gpio.h>
- #include <stm32f4xx_spi.h>
- #include <pdm_filter.h>
- #include "spi2812.h"
- //void TimingDelay_Decrement();
- #ifndef _SPI_2812_H
- #define _SPI_2812_H
- #define SPI2812_MAX_LEDS 60
- //24 bits per LED, can fit two bits per byte of output.
- #define SPI2812_BUFFSIZE (SPI2812_MAX_LEDS * 24 / 2)
- /////void send_text( const char * text );
- void InitSPI2812();
- void SendSPI2812(unsigned char *lightarray, int leds); //Need one R, G, B per element.
- #endif
- volatile int wasclicked = 0; //Used for if the root change button was clicked.
- RCC_ClocksTypeDef RCC_Clocks;
- gpio freepin;
- volatile int adcer;
- volatile int hit = 0;
- //Circular buffer for incoming data so we don't spend much time servicing the interrupt and we can handle colorchord in the main thread.
- #define CIRCBUFSIZE 256
- volatile int last_samp_pos;
- int16_t sampbuff[CIRCBUFSIZE];
- volatile int samples;
- //This gets called by the ADC/Microphone
- void GotSample(int samp)
- {
- sampbuff[last_samp_pos] = samp;
- last_samp_pos = ((last_samp_pos + 1) % CIRCBUFSIZE);
- samples++;
- }
- //Call this once we've stacked together one full colorchord frame.
- void NewFrame()
- {
- // uint8_t led_outs[NUM_LIN_LEDS*3];
- int i;
- HandleFrameInfo();
- // UpdateLinearLEDs();
- UpdateAllSameLEDs();
- SendSPI2812(ledOut, NUM_LIN_LEDS);
- }
- void Configure_PA0(void) //disabled in case it interfieres with the ADC1
- {
- /* Set variables used */
- GPIO_InitTypeDef GPIO_InitStruct;
- EXTI_InitTypeDef EXTI_InitStruct;
- NVIC_InitTypeDef NVIC_InitStruct;
- /* Enable clock for GPIOD */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
- /* Enable clock for SYSCFG */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
- /* Set pin as input */
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
- GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_Init(GPIOA, &GPIO_InitStruct);
- /* Tell system that you will use PA0 for EXTI_Line0 */
- SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
- /* PA0 is connected to EXTI_Line0 */
- EXTI_InitStruct.EXTI_Line = EXTI_Line0;
- /* Enable interrupt */
- EXTI_InitStruct.EXTI_LineCmd = ENABLE;
- /* Interrupt mode */
- EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
- /* Triggers on rising and falling edge */
- EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
- /* Add to EXTI */
- EXTI_Init(&EXTI_InitStruct);
- /* Add IRQ vector to NVIC */
- /* PA0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
- NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
- NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; /* Set priority */
- NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; /* Set sub priority */
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; /* Enable interrupt */
- NVIC_Init(&NVIC_InitStruct); /* Add to NVIC */
- }
- //Handle button press on PA0.
- void EXTI0_IRQHandler(void)
- {
- static int rootoffset;
- if (EXTI_GetITStatus(EXTI_Line0) != RESET)
- {
- if (wasclicked == 0)
- wasclicked = 10;
- EXTI_ClearITPendingBit(EXTI_Line0);
- }
- }
- int main(void)
- {
- uint32_t i = 0;
- RCC_GetClocksFreq(&RCC_Clocks);
- ConfigureLED();
- LED_OFF;
- // SysTick end of count event each 10ms
- SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
- float fv = RCC_Clocks.HCLK_Frequency / 1000000.0f;
- // We can use printf to print back through the debugging interface, but that's slow and
- // it also takes up a bunch of space. No printf = no space wasted in printf.
- // printf( "Operating at %.3fMHz\n", fv );
- InitColorChord();
- //Configure_PA0(); //disabled for now in case it interfieres with ADC1
- InitMP45DT02();
- InitADC();
- InitSPI2812();
- int this_samp = 0;
- int wf = 0;
- while (1)
- {
- if (this_samp != last_samp_pos)
- {
- LED_OFF; //Use led on the board to show us how much CPU we're using. (You can also probe PB15)
- PushSample32(sampbuff[this_samp] / 2); //Can't put in full volume.
- this_samp = (this_samp + 1) % CIRCBUFSIZE;
- wf++;
- if (wf == 128)
- {
- NewFrame();
- wf = 0;
- }
- LED_ON;
- }
- LED_ON; //Take up a little more time to make sure we don't miss this.
- }
- }
- void TimingDelay_Decrement()
- {
- static int rootoffset;
- //A way of making sure we debounce the button.
- if (wasclicked)
- {
- if (wasclicked == 10)
- {
- if (rootoffset++ >= 12)
- rootoffset = 0;
- RootNoteOffset = (rootoffset * NOTERANGE) / 12;
- }
- wasclicked--;
- }
- }
- void ADCCallback(int16_t adcval)
- {
- sampbuff[last_samp_pos] = adcval;
- last_samp_pos = ((last_samp_pos + 1) % CIRCBUFSIZE);
- samples++;
- }
- //==========================================================================================
- //============================ adc.c below ================================================
- //Mostly from: http://www.pezzino.ch/stm32-adc-voltage-monitor/
- //Also: http://www.micromouseonline.com/2009/05/26/simple-adc-use-on-the-stm32/
- #include <misc.h>
- #include <stm32f4xx_rcc.h>
- #include <stm32f4xx_gpio.h>
- #include <stm32f4xx_adc.h>
- #include <stm32f4xx_tim.h>
- #include <adc.h>
- #include <systems.h>
- //======================
- static int calibration_value;
- extern RCC_ClocksTypeDef RCC_Clocks;
- void InitADC()
- {
- ADC_InitTypeDef ADC_InitStructure;
- ADC_CommonInitTypeDef ADC_CommonInitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- // Configure the ADC clock
- //enable interface clock
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
- //enable clock for adc
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
- //Configure ADC Channel7 as analog input
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- _delay_us(10);
- ADC_StructInit(&ADC_InitStructure);
- ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
- ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
- ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //^
- ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
- ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfConversion = 1;
- ADC_Init(ADC1, &ADC_InitStructure);
- ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_480Cycles);
- ADC_Cmd(ADC1, ENABLE);
- //while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY)); //commented out as there is no longer a flag used in F4 for this
- NVIC_InitTypeDef NVIC_InitStructure;
- // Enable the TIM2 gloabal Interrupt
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- // TIM2 clock enable
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
- // Time base configuration
- RCC->CFGR |= 0X1400;
- TIM_TimeBaseStructure.TIM_Period = (RCC_Clocks.HCLK_Frequency / (ADCFS * ADCOVERSAMP)) - 1;
- TIM_TimeBaseStructure.TIM_Prescaler = 1 - 1; // Operate at clock frequency
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
- // TIM IT enable
- TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
- // TIM2 enable counter
- TIM_Cmd(TIM2, ENABLE);
- // Start ADC4 Software Conversion
- ADC_SoftwareStartConv(ADC1);
- }
- void TIM2_IRQHandler(void)
- {
- static uint8_t oversamp = 0;
- static int32_t average = 0;
- static int32_t oversampout = 0;
- //trash test code
- //int16_t value = ADC_GetConversionValue(ADC1);
- //ADCCallback(value);
- ///end of trash test code
- if (TIM_GetITStatus (TIM2, TIM_IT_Update) != RESET) {
- TIM_ClearITPendingBit (TIM2, TIM_IT_Update);
- //int16_t value = ADC_GetConversionValue(ADC4);
- int16_t value = ADC_GetSoftwareStartConvStatus(ADC1);
- //ADC_StartConversion( ADC4 );
- ADC_SoftwareStartConv(ADC1);
- oversampout += value;
- oversamp++;
- if( oversamp >= ADCOVERSAMP )
- {
- value = oversampout / ADCOVERSAMP;
- average = ((average*1023) + (value*1024))/1024;
- value = value-(average/1024);
- oversamp = 0;
- ADCCallback( value );
- oversampout = 0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement