Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.12 KB | None | 0 0
  1. //ColorChordEmbedded implementation on the STM32F407 for the stm32f4-discovery.
  2. //Uses on-board microphone and outputs WS2812 signal for configurable number of LEDs
  3. //on PB5 via DMA+SPI
  4.  
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include "adc.h"
  8. #include <systems.h>
  9. #include <math.h>
  10. #include <stm32f4xx_exti.h>
  11. #include <DFT32.h>
  12. #include <embeddednf.h>
  13. #include <embeddedout.h>
  14. #include "mp45dt02.h"
  15.  
  16.  
  17. //retarted shit
  18. #include <misc.h>
  19. #include <stm32f4xx_rcc.h>
  20. #include <stm32f4xx_gpio.h>
  21. #include <stm32f4xx_adc.h>
  22. #include <stm32f4xx_tim.h>
  23. #include <adc.h>
  24. #include <stm32f4xx_rcc.h>
  25. #include <stm32f4xx_gpio.h>
  26. #include <stm32f4xx_spi.h>
  27. #include <stm32f4xx_dma.h>
  28. #include <misc.h>
  29. #include "stm32f4xx_it.h"
  30. #include <stdint.h>
  31. #include "ccconfig.h"
  32. #include "mp45dt02.h"
  33. #include <stm32f4xx_rcc.h>
  34. #include <stm32f4xx_gpio.h>
  35. #include <stm32f4xx_spi.h>
  36. #include <pdm_filter.h>
  37. #include "spi2812.h"
  38.  
  39. //void TimingDelay_Decrement();
  40.  
  41. #ifndef _SPI_2812_H
  42. #define _SPI_2812_H
  43.  
  44. #define SPI2812_MAX_LEDS 60
  45.  
  46. //24 bits per LED, can fit two bits per byte of output.
  47. #define SPI2812_BUFFSIZE (SPI2812_MAX_LEDS * 24 / 2)
  48. /////void send_text( const char * text );
  49.  
  50. void InitSPI2812();
  51. void SendSPI2812(unsigned char *lightarray, int leds); //Need one R, G, B per element.
  52.  
  53. #endif
  54.  
  55. volatile int wasclicked = 0; //Used for if the root change button was clicked.
  56.  
  57. RCC_ClocksTypeDef RCC_Clocks;
  58. gpio freepin;
  59.  
  60. volatile int adcer;
  61. volatile int hit = 0;
  62.  
  63. //Circular buffer for incoming data so we don't spend much time servicing the interrupt and we can handle colorchord in the main thread.
  64. #define CIRCBUFSIZE 256
  65. volatile int last_samp_pos;
  66. int16_t sampbuff[CIRCBUFSIZE];
  67. volatile int samples;
  68.  
  69. //This gets called by the ADC/Microphone
  70. void GotSample(int samp)
  71. {
  72. sampbuff[last_samp_pos] = samp;
  73. last_samp_pos = ((last_samp_pos + 1) % CIRCBUFSIZE);
  74. samples++;
  75. }
  76.  
  77. //Call this once we've stacked together one full colorchord frame.
  78. void NewFrame()
  79. {
  80. // uint8_t led_outs[NUM_LIN_LEDS*3];
  81. int i;
  82. HandleFrameInfo();
  83.  
  84. // UpdateLinearLEDs();
  85. UpdateAllSameLEDs();
  86.  
  87. SendSPI2812(ledOut, NUM_LIN_LEDS);
  88. }
  89.  
  90. void Configure_PA0(void) //disabled in case it interfieres with the ADC1
  91. {
  92. /* Set variables used */
  93. GPIO_InitTypeDef GPIO_InitStruct;
  94. EXTI_InitTypeDef EXTI_InitStruct;
  95. NVIC_InitTypeDef NVIC_InitStruct;
  96.  
  97. /* Enable clock for GPIOD */
  98. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  99. /* Enable clock for SYSCFG */
  100. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  101.  
  102. /* Set pin as input */
  103. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
  104. GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  105. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
  106. GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
  107. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
  108. GPIO_Init(GPIOA, &GPIO_InitStruct);
  109.  
  110. /* Tell system that you will use PA0 for EXTI_Line0 */
  111. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
  112.  
  113. /* PA0 is connected to EXTI_Line0 */
  114. EXTI_InitStruct.EXTI_Line = EXTI_Line0;
  115. /* Enable interrupt */
  116. EXTI_InitStruct.EXTI_LineCmd = ENABLE;
  117. /* Interrupt mode */
  118. EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
  119. /* Triggers on rising and falling edge */
  120. EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
  121. /* Add to EXTI */
  122. EXTI_Init(&EXTI_InitStruct);
  123.  
  124. /* Add IRQ vector to NVIC */
  125. /* PA0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
  126. NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
  127. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; /* Set priority */
  128. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; /* Set sub priority */
  129. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; /* Enable interrupt */
  130. NVIC_Init(&NVIC_InitStruct); /* Add to NVIC */
  131. }
  132.  
  133. //Handle button press on PA0.
  134. void EXTI0_IRQHandler(void)
  135. {
  136. static int rootoffset;
  137.  
  138. if (EXTI_GetITStatus(EXTI_Line0) != RESET)
  139. {
  140. if (wasclicked == 0)
  141. wasclicked = 10;
  142. EXTI_ClearITPendingBit(EXTI_Line0);
  143. }
  144. }
  145.  
  146. int main(void)
  147. {
  148. uint32_t i = 0;
  149.  
  150. RCC_GetClocksFreq(&RCC_Clocks);
  151.  
  152. ConfigureLED();
  153.  
  154. LED_OFF;
  155.  
  156. // SysTick end of count event each 10ms
  157. SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
  158.  
  159. float fv = RCC_Clocks.HCLK_Frequency / 1000000.0f;
  160. // We can use printf to print back through the debugging interface, but that's slow and
  161. // it also takes up a bunch of space. No printf = no space wasted in printf.
  162. // printf( "Operating at %.3fMHz\n", fv );
  163.  
  164. InitColorChord();
  165. //Configure_PA0(); //disabled for now in case it interfieres with ADC1
  166. InitMP45DT02();
  167. InitADC();
  168. InitSPI2812();
  169.  
  170. int this_samp = 0;
  171. int wf = 0;
  172.  
  173. while (1)
  174. {
  175.  
  176. if (this_samp != last_samp_pos)
  177. {
  178. LED_OFF; //Use led on the board to show us how much CPU we're using. (You can also probe PB15)
  179.  
  180. PushSample32(sampbuff[this_samp] / 2); //Can't put in full volume.
  181.  
  182. this_samp = (this_samp + 1) % CIRCBUFSIZE;
  183.  
  184. wf++;
  185. if (wf == 128)
  186. {
  187. NewFrame();
  188. wf = 0;
  189. }
  190. LED_ON;
  191. }
  192. LED_ON; //Take up a little more time to make sure we don't miss this.
  193. }
  194. }
  195.  
  196. void TimingDelay_Decrement()
  197. {
  198. static int rootoffset;
  199.  
  200. //A way of making sure we debounce the button.
  201. if (wasclicked)
  202. {
  203. if (wasclicked == 10)
  204. {
  205. if (rootoffset++ >= 12)
  206. rootoffset = 0;
  207. RootNoteOffset = (rootoffset * NOTERANGE) / 12;
  208. }
  209.  
  210. wasclicked--;
  211. }
  212. }
  213.  
  214. void ADCCallback(int16_t adcval)
  215. {
  216. sampbuff[last_samp_pos] = adcval;
  217. last_samp_pos = ((last_samp_pos + 1) % CIRCBUFSIZE);
  218. samples++;
  219. }
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228. //==========================================================================================
  229. //============================ adc.c below ================================================
  230.  
  231.  
  232. //Mostly from: http://www.pezzino.ch/stm32-adc-voltage-monitor/
  233. //Also: http://www.micromouseonline.com/2009/05/26/simple-adc-use-on-the-stm32/
  234.  
  235. #include <misc.h>
  236. #include <stm32f4xx_rcc.h>
  237. #include <stm32f4xx_gpio.h>
  238. #include <stm32f4xx_adc.h>
  239. #include <stm32f4xx_tim.h>
  240. #include <adc.h>
  241.  
  242. #include <systems.h>
  243.  
  244. //======================
  245.  
  246.  
  247.  
  248. static int calibration_value;
  249. extern RCC_ClocksTypeDef RCC_Clocks;
  250.  
  251. void InitADC()
  252. {
  253.  
  254. ADC_InitTypeDef ADC_InitStructure;
  255. ADC_CommonInitTypeDef ADC_CommonInitStructure;
  256. GPIO_InitTypeDef GPIO_InitStructure;
  257. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  258.  
  259. // Configure the ADC clock
  260.  
  261. //enable interface clock
  262. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  263. //enable clock for adc
  264. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  265.  
  266. //Configure ADC Channel7 as analog input
  267. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  268. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  269. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  270. GPIO_Init(GPIOA, &GPIO_InitStructure);
  271.  
  272. _delay_us(10);
  273. ADC_StructInit(&ADC_InitStructure);
  274. ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  275. ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  276. ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
  277.  
  278. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //^
  279. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  280. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  281. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  282.  
  283. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  284. ADC_InitStructure.ADC_NbrOfConversion = 1;
  285. ADC_Init(ADC1, &ADC_InitStructure);
  286.  
  287. ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_480Cycles);
  288. ADC_Cmd(ADC1, ENABLE);
  289. //while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY)); //commented out as there is no longer a flag used in F4 for this
  290.  
  291. NVIC_InitTypeDef NVIC_InitStructure;
  292. // Enable the TIM2 gloabal Interrupt
  293. NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  294. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  295. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  296. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  297. NVIC_Init(&NVIC_InitStructure);
  298.  
  299. // TIM2 clock enable
  300. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  301. // Time base configuration
  302. RCC->CFGR |= 0X1400;
  303. TIM_TimeBaseStructure.TIM_Period = (RCC_Clocks.HCLK_Frequency / (ADCFS * ADCOVERSAMP)) - 1;
  304. TIM_TimeBaseStructure.TIM_Prescaler = 1 - 1; // Operate at clock frequency
  305. TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  306. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  307. TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  308. // TIM IT enable
  309. TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
  310. // TIM2 enable counter
  311. TIM_Cmd(TIM2, ENABLE);
  312.  
  313. // Start ADC4 Software Conversion
  314. ADC_SoftwareStartConv(ADC1);
  315.  
  316.  
  317. }
  318.  
  319. void TIM2_IRQHandler(void)
  320. {
  321. static uint8_t oversamp = 0;
  322. static int32_t average = 0;
  323. static int32_t oversampout = 0;
  324.  
  325. //trash test code
  326.  
  327. //int16_t value = ADC_GetConversionValue(ADC1);
  328. //ADCCallback(value);
  329.  
  330. ///end of trash test code
  331.  
  332.  
  333.  
  334. if (TIM_GetITStatus (TIM2, TIM_IT_Update) != RESET) {
  335. TIM_ClearITPendingBit (TIM2, TIM_IT_Update);
  336. //int16_t value = ADC_GetConversionValue(ADC4);
  337. int16_t value = ADC_GetSoftwareStartConvStatus(ADC1);
  338. //ADC_StartConversion( ADC4 );
  339. ADC_SoftwareStartConv(ADC1);
  340.  
  341. oversampout += value;
  342. oversamp++;
  343.  
  344. if( oversamp >= ADCOVERSAMP )
  345. {
  346. value = oversampout / ADCOVERSAMP;
  347. average = ((average*1023) + (value*1024))/1024;
  348. value = value-(average/1024);
  349. oversamp = 0;
  350. ADCCallback( value );
  351. oversampout = 0;
  352. }
  353. }
  354.  
  355.  
  356. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement