diff --git a/embeddedcommon/embeddedout.c b/embeddedcommon/embeddedout.c index 5712a19..a20483e 100644 --- a/embeddedcommon/embeddedout.c +++ b/embeddedcommon/embeddedout.c @@ -8,6 +8,8 @@ uint16_t ledAmpOut[NUM_LIN_LEDS]; uint8_t ledFreqOut[NUM_LIN_LEDS]; uint8_t ledFreqOutOld[NUM_LIN_LEDS]; +uint8_t RootNoteOffset; + void UpdateLinearLEDs() { //Source material: @@ -188,7 +190,7 @@ void UpdateLinearLEDs() uint16_t amp = ledAmpOut[j]; if( amp > 255 ) amp = 255; - uint32_t color = ECCtoHEX( ledFreqOut[j], 255, amp ); + uint32_t color = ECCtoHEX( (ledFreqOut[j]+RootNoteOffset)%NOTERANGE, 255, amp ); ledOut[l*3+0] = ( color >> 0 ) & 0xff; ledOut[l*3+1] = ( color >> 8 ) & 0xff; ledOut[l*3+2] = ( color >>16 ) & 0xff; diff --git a/embeddedcommon/embeddedout.h b/embeddedcommon/embeddedout.h index 3985569..4bf9246 100644 --- a/embeddedcommon/embeddedout.h +++ b/embeddedcommon/embeddedout.h @@ -19,6 +19,7 @@ extern uint8_t ledArray[]; extern uint8_t ledOut[]; //[NUM_LIN_LEDS*3] +extern uint8_t RootNoteOffset; //Set to define what the root note is. 0 = A. void UpdateLinearLEDs(); uint32_t ECCtoHEX( uint8_t note, uint8_t sat, uint8_t val ); diff --git a/embeddedstm32f407/Makefile b/embeddedstm32f407/Makefile index 3e82e7b..c9a6f59 100644 --- a/embeddedstm32f407/Makefile +++ b/embeddedstm32f407/Makefile @@ -46,6 +46,8 @@ SRC = main.c \ $(STLIB)/src/misc.c \ $(STLIB)/src/stm32f4xx_dma.c \ $(STLIB)/src/stm32f4xx_spi.c \ + $(STLIB)/src/stm32f4xx_syscfg.c \ + $(STLIB)/src/stm32f4xx_exti.c \ $(STLIB)/src/stm32f4xx_rcc.c \ $(STLIB)/src/stm32f4xx_gpio.c \ ../embeddedcommon/DFT32.c \ diff --git a/embeddedstm32f407/main.c b/embeddedstm32f407/main.c index 927dd58..b689729 100644 --- a/embeddedstm32f407/main.c +++ b/embeddedstm32f407/main.c @@ -1,31 +1,37 @@ +//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 #include #include #include -#include "mp45dt02.h" - +#include #include #include #include +#include "mp45dt02.h" + +volatile int wasclicked = 0; //Used for if the root change button was clicked. RCC_ClocksTypeDef RCC_Clocks; -#define CIRCBUFSIZE 256 +//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 ) { -// lastsamp = 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]; @@ -37,6 +43,61 @@ void NewFrame() } +void Configure_PA0(void) { + /* 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; @@ -47,14 +108,16 @@ int main(void) LED_OFF; - /* SysTick end of count event each 10ms */ + // 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 ); Init(); - + Configure_PA0(); InitMP45DT02(); InitSPI2812(); @@ -66,7 +129,7 @@ int main(void) if( this_samp != last_samp_pos ) { - LED_OFF; + 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. @@ -86,19 +149,19 @@ int main(void) void TimingDelay_Decrement() { - static int i; - static int k; - int j; + static int rootoffset; -/* uint8_t obuf[16*3]; - for( j = 0; j < 16; j++ ) + //A way of making sure we debounce the button. + if( wasclicked ) { - obuf[j*3+0] = (sampbuff[j]>0)?sampbuff[j]/256:0 ;//(sampbuff[0]&(1<= 12 ) rootoffset = 0; + RootNoteOffset = (rootoffset * NOTERANGE) / 12; + } + + wasclicked--; } - k++; - SendSPI2812( obuf, 16 );*/ }