From f1a75267fbb99740d52e880dca03a0aef190a2c2 Mon Sep 17 00:00:00 2001 From: cnlohr Date: Wed, 22 Jul 2015 09:12:21 -0400 Subject: [PATCH] clean up + Add utilities to the system.c/.h +Fix filter --- embeddedstm32f303/LICENSE | 6 +++ embeddedstm32f303/Makefile | 7 ++- embeddedstm32f303/adc.c | 31 ++++++----- embeddedstm32f303/adc.h | 1 + embeddedstm32f303/lib/stm32f303.ld | 1 + embeddedstm32f303/lib/systems.c | 82 +++++++++++++++++++++++++++--- embeddedstm32f303/lib/systems.h | 28 ++++++++++ embeddedstm32f303/main.c | 62 ++++++---------------- embeddedstm32f407/main.c | 2 +- embeddedstm32f407/mp45dt02.c | 2 +- 10 files changed, 150 insertions(+), 72 deletions(-) diff --git a/embeddedstm32f303/LICENSE b/embeddedstm32f303/LICENSE index 8a9a833..9ff6416 100644 --- a/embeddedstm32f303/LICENSE +++ b/embeddedstm32f303/LICENSE @@ -1,5 +1,11 @@ STM32F303-based ColorChord 2.0 Build +Based off of other code including the ST Standard Library. + +Other code is under different licenses. + +This core project is... + Copyright (c) 2015 Charles Lohr Roughly based off of: https://github.com/devthrash/0xWS2812 diff --git a/embeddedstm32f303/Makefile b/embeddedstm32f303/Makefile index e134f2b..8012b23 100644 --- a/embeddedstm32f303/Makefile +++ b/embeddedstm32f303/Makefile @@ -17,13 +17,12 @@ BIN=$(CP) -O ihex DEFS = -DSTM32F30X -DHSE_VALUE=25000000 STARTUP = lib/startup_stm32f30x.s -MCU = cortex-m3 +MCU = cortex-m4 MCFLAGS = -mcpu=$(MCU) -mthumb -mlittle-endian -mthumb-interwork STM32_INCLUDES = -Ilib -I. -ISTM32F30x_StdPeriph_Driver/inc - -OPTIMIZE = -Os +OPTIMIZE = -Ofast -mfloat-abi=hard -mfpu=fpv4-sp-d16 -flto -ffunction-sections -fdata-sections -Wl,--relax CFLAGS = $(MCFLAGS) $(OPTIMIZE) $(DEFS) \ -I. \ @@ -31,7 +30,7 @@ CFLAGS = $(MCFLAGS) $(OPTIMIZE) $(DEFS) \ -I../embeddedcommon \ -Wl,-T,lib/stm32f303.ld CFLAGS+=-DDEBUG -CFLAGS+=-DNUM_LIN_LEDS=17 -DDFREQ=15000 -DCCEMBEDDED +CFLAGS+=-DNUM_LIN_LEDS=17 -DDFREQ=12500 -DCCEMBEDDED AFLAGS = $(MCFLAGS) diff --git a/embeddedstm32f303/adc.c b/embeddedstm32f303/adc.c index 5240616..bca4ec5 100644 --- a/embeddedstm32f303/adc.c +++ b/embeddedstm32f303/adc.c @@ -1,4 +1,3 @@ -//TODO: Consider oversampling the ADC using DMA. //Mostly from: http://www.pezzino.ch/stm32-adc-voltage-monitor/ //Also: http://www.micromouseonline.com/2009/05/26/simple-adc-use-on-the-stm32/ @@ -41,14 +40,8 @@ void InitADC() ADC_VoltageRegulatorCmd( ADC4, ENABLE ); /* Insert delay equal to 10 µs */ - //vTaskDelay(5); _delay_us( 10 ); -// ADC_SelectCalibrationMode( ADC4, ADC_CalibrationMode_Single ); -// ADC_StartCalibration( ADC4 ); -// while ( ADC_GetCalibrationStatus( ADC4 ) != RESET ); -// calibration_value = ADC_GetCalibrationValue( ADC4 ); - ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; @@ -84,12 +77,11 @@ void InitADC() 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) - 1; + 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; @@ -99,21 +91,34 @@ void InitADC() /* TIM2 enable counter */ TIM_Cmd (TIM2, ENABLE); - /* Start ADC4 Software Conversion */ ADC_StartConversion( ADC4 ); } -void TIM2_IRQHandler (void) //Timer Interupt for sending data +void TIM2_IRQHandler (void) { + static uint8_t oversamp = 0; static int32_t average = 0; + static int32_t oversampout = 0; + if (TIM_GetITStatus (TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit (TIM2, TIM_IT_Update); int16_t value = ADC_GetConversionValue(ADC4); - average = ((average*1023) + (value*1024))/1024; ADC_StartConversion( ADC4 ); - ADCCallback( value-(average/1024)); + + 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; + } } } diff --git a/embeddedstm32f303/adc.h b/embeddedstm32f303/adc.h index 613295b..000f638 100644 --- a/embeddedstm32f303/adc.h +++ b/embeddedstm32f303/adc.h @@ -4,6 +4,7 @@ #include #define ADCFS DFREQ +#define ADCOVERSAMP 4 void InitADC(); void ADCCallback( int16_t value ); diff --git a/embeddedstm32f303/lib/stm32f303.ld b/embeddedstm32f303/lib/stm32f303.ld index 9c1f180..959adab 100644 --- a/embeddedstm32f303/lib/stm32f303.ld +++ b/embeddedstm32f303/lib/stm32f303.ld @@ -43,6 +43,7 @@ SECTIONS KEEP (*(.init)) KEEP (*(.fini)) + . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH diff --git a/embeddedstm32f303/lib/systems.c b/embeddedstm32f303/lib/systems.c index 30bba7a..ce7481a 100644 --- a/embeddedstm32f303/lib/systems.c +++ b/embeddedstm32f303/lib/systems.c @@ -33,13 +33,13 @@ void send_text( const char * text ) send_openocd_command(0x05, m); } -int _write (int fd, const void *buf, size_t count) +int __attribute__((used)) _write (int fd, const void *buf, size_t count) { uint32_t m[] = { 2, (uint32_t)buf, count }; send_openocd_command(0x05, m); } -void * _sbrk(int incr) { +void __attribute__((used)) * _sbrk(int incr) { extern char _ebss; // Defined by the linker static char *heap_end; char *prev_heap_end; @@ -71,17 +71,87 @@ void _delay_us(uint32_t us) { } void ConfigureLED() +{ + ConfigureGPIO( GetGPIOFromString( "PB8" ), INOUT_OUT ); +} + +uint8_t GetGPIOFromString( const char * str ) +{ + int mode = 0; + int port = -1; + int pin = -1; + const char * st = str; + for( ; *st; st++ ) + { + char c = *st; + if( mode == 0 ) + { + if( c >= 'A' && c <= 'F' ) + { + port = c - 'A'; + mode = 2; + } + else if( c >= 'a' && c <= 'f' ) + { + port = c - 'a'; + mode = 2; + } + } + else if( mode == 2 ) + { + if( c >= '0' && c <= '9' ) + { + pin = 0; + mode = 3; + } + } + + if( mode == 3 ) + { + if( c >= '0' && c <= '9' ) + { + pin = pin * 10; + pin+= c - '0'; + } + else + { + break; + } + } + } + + if( port > 0 && pin > 0 && port <= 6 && pin <= 15) + { + return (port<<4)|pin; + } + else + { + return 0xff; + } +} + + +void ConfigureGPIO( uint8_t gpio, int parameters ) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable the GPIO_LED Clock */ - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); + RCC_AHBPeriphClockCmd( 1<<(17+(gpio>>4)), ENABLE); + + if( parameters & DEFAULT_VALUE_FLAG ) + { + GPIOOn( gpio ); + } + else + { + GPIOOff( gpio ); + } /* Configure the GPIO_LED pin */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //| GPIO_Pin_15 (15 = CTS) - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Pin = 1<<(gpio&0xf); + GPIO_InitStructure.GPIO_Mode = (parameters&INOUT_FLAG)?GPIO_Mode_OUT:GPIO_Mode_IN; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_PuPd = (parameters&PUPD_FLAG)?( (parameters&PUPD_UP)?GPIO_PuPd_UP:GPIO_PuPd_DOWN ):GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } diff --git a/embeddedstm32f303/lib/systems.h b/embeddedstm32f303/lib/systems.h index 8ee2423..574ccca 100644 --- a/embeddedstm32f303/lib/systems.h +++ b/embeddedstm32f303/lib/systems.h @@ -5,6 +5,34 @@ void send_openocd_command(int command, void *message); void send_text( const char * text ); void _delay_us(uint32_t us); + +typedef uint8_t gpio; + +gpio GetGPIOFromString( const char * str ); + + +#define DEFAULT_VALUE_FLAG 0x00000001 +#define DEFAULT_ON 0x00000001 +#define DEFAULT_OFF 0x00000000 + +#define INOUT_FLAG 0x00000002 +#define INOUT_OUT 0x00000002 +#define INOUT_IN 0x00000000 + +#define PUPD_FLAG 0x0000000C +#define PUPD_NONE 0x00000000 +#define PUPD_UP 0x00000004 +#define PUPD_DOWN 0x00000008 + +void ConfigureGPIO( gpio gpio, int parameters ); + +#define GPIOOf(x) ((GPIO_TypeDef *) ((((x)>>4)<=6)?(AHB2PERIPH_BASE+0x400*((x)>>4)):0x60000000) ) +#define GPIOPin(x) ((1<<((x)&0x0f))) +#define GPIOLatch(x) GPIOOf(x)->ODR +#define GPIOOff(x) GPIOOf(x)->BRR = (1<<((x)&0x0f)); +#define GPIOOn(x) GPIOOf(x)->BSRR = (1<<((x)&0x0f)); + + void ConfigureLED(); #define LED_TOGGLE {GPIOB->ODR ^= GPIO_Pin_8;} #define LED_ON {GPIOB->BSRR ^= GPIO_Pin_8;} diff --git a/embeddedstm32f303/main.c b/embeddedstm32f303/main.c index 51f28ee..db8156a 100644 --- a/embeddedstm32f303/main.c +++ b/embeddedstm32f303/main.c @@ -10,6 +10,8 @@ #include +gpio freepin; + RCC_ClocksTypeDef RCC_Clocks; volatile int adcer; @@ -47,28 +49,12 @@ int main(void) RCC_GetClocksFreq( &RCC_Clocks ); - ConfigureLED(); LED_ON; - - //Notes: - // * CTS pin is connected to PB15 (SPI2_MOSI). - // * SPI2 is connected to DMA1, on Channel 5. - - //Alternatively, try using the crazy timer-based DMA? - //This would be good for driving parallel strings, but bad for memory density on one. + ConfigureLED(); LED_OFF; GPIO_InitTypeDef GPIO_InitStructure; - - //Turn B10 (TX) on, so we can have something to bias the ADC with. - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; - GPIO_Init(GPIOB, &GPIO_InitStructure); - GPIOB->ODR |= GPIO_Pin_10; - + //Turn B10 (TX) on, so we can have something positive to bias the ADC with. + ConfigureGPIO( GetGPIOFromString( "PB10" ), INOUT_OUT | DEFAULT_ON ); /* SysTick end of count event each 10ms */ SysTick_Config( RCC_Clocks.HCLK_Frequency/100 ); /// 100); @@ -79,17 +65,21 @@ int main(void) InitADC(); Init(); //Colorchord - //printf( "Operating at %.3fMHz\n", fv ); +// printf( "Operating at %.3fMHz\n", fv ); + + freepin = GetGPIOFromString( "PB11" ); + ConfigureGPIO( freepin, INOUT_OUT | DEFAULT_ON ); int this_samp = 0; int wf = 0; + LED_ON; + 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) - + GPIOOn( freepin ); PushSample32( sampbuff[this_samp] ); //Can't put in full volume. this_samp = (this_samp+1)%CIRCBUFSIZE; @@ -100,37 +90,15 @@ int main(void) NewFrame(); wf = 0; } - LED_ON; + + GPIOOff( freepin ); } - LED_ON; //Take up a little more time to make sure we don't miss this. } } void TimingDelay_Decrement() { -/* static int i; - static int k; - int j; - i++; - - if( i == 100 ) - { - printf( "%d\n", hit ); - i = hit = 0; - } - - #define LEDS 20 - uint8_t obuf[LEDS*3]; - for( j = 0; j < LEDS; j++ ) - { - obuf[j*3+0] = sin((k+j*2)/10.0)*100; - obuf[j*3+1] = sin((k+j*2+20)/10.0)*100; - obuf[j*3+2] = sin((k+j*2+40)/10.0)*100; - } - k++; - SendSPI2812( obuf, LEDS ); - LED_ON; -*/ + LED_TOGGLE; } diff --git a/embeddedstm32f407/main.c b/embeddedstm32f407/main.c index b689729..7ebdbd5 100644 --- a/embeddedstm32f407/main.c +++ b/embeddedstm32f407/main.c @@ -34,7 +34,7 @@ void GotSample( int samp ) //Call this once we've stacked together one full colorchord frame. void NewFrame() { - uint8_t led_outs[NUM_LIN_LEDS*3]; +// uint8_t led_outs[NUM_LIN_LEDS*3]; int i; HandleFrameInfo(); UpdateLinearLEDs(); diff --git a/embeddedstm32f407/mp45dt02.c b/embeddedstm32f407/mp45dt02.c index 439cd90..56cfaae 100644 --- a/embeddedstm32f407/mp45dt02.c +++ b/embeddedstm32f407/mp45dt02.c @@ -22,7 +22,7 @@ void InitMP45DT02() RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE); #ifdef ST_PDM - pdm_filter.LP_HZ=DFREQ/2; + pdm_filter.LP_HZ=DFREQ*2; //??? This is wrong, but if I make it lower, it really cuts into my bandwidth. pdm_filter.HP_HZ=20; pdm_filter.Fs=FS; pdm_filter.Out_MicChannels=1;