-
Notifications
You must be signed in to change notification settings - Fork 117
/
main.c
170 lines (133 loc) · 4.19 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//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 <systems.h>
#include <math.h>
#include <stm32f4xx_exti.h>
#include <DFT32.h>
#include <embeddednf.h>
#include <embeddedout.h>
#include "mp45dt02.h"
volatile int wasclicked = 0; //Used for if the root change button was clicked.
RCC_ClocksTypeDef RCC_Clocks;
//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) {
/* 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();
InitMP45DT02();
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--;
}
}