clean up + Add utilities to the system.c/.h

+Fix filter
This commit is contained in:
cnlohr 2015-07-22 09:12:21 -04:00
parent 560db48adf
commit f1a75267fb
10 changed files with 150 additions and 72 deletions

View file

@ -1,5 +1,11 @@
STM32F303-based ColorChord 2.0 Build 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 Copyright (c) 2015 Charles Lohr
Roughly based off of: https://github.com/devthrash/0xWS2812 Roughly based off of: https://github.com/devthrash/0xWS2812

View file

@ -17,13 +17,12 @@ BIN=$(CP) -O ihex
DEFS = -DSTM32F30X -DHSE_VALUE=25000000 DEFS = -DSTM32F30X -DHSE_VALUE=25000000
STARTUP = lib/startup_stm32f30x.s STARTUP = lib/startup_stm32f30x.s
MCU = cortex-m3 MCU = cortex-m4
MCFLAGS = -mcpu=$(MCU) -mthumb -mlittle-endian -mthumb-interwork MCFLAGS = -mcpu=$(MCU) -mthumb -mlittle-endian -mthumb-interwork
STM32_INCLUDES = -Ilib -I. -ISTM32F30x_StdPeriph_Driver/inc STM32_INCLUDES = -Ilib -I. -ISTM32F30x_StdPeriph_Driver/inc
OPTIMIZE = -Ofast -mfloat-abi=hard -mfpu=fpv4-sp-d16 -flto -ffunction-sections -fdata-sections -Wl,--relax
OPTIMIZE = -Os
CFLAGS = $(MCFLAGS) $(OPTIMIZE) $(DEFS) \ CFLAGS = $(MCFLAGS) $(OPTIMIZE) $(DEFS) \
-I. \ -I. \
@ -31,7 +30,7 @@ CFLAGS = $(MCFLAGS) $(OPTIMIZE) $(DEFS) \
-I../embeddedcommon \ -I../embeddedcommon \
-Wl,-T,lib/stm32f303.ld -Wl,-T,lib/stm32f303.ld
CFLAGS+=-DDEBUG CFLAGS+=-DDEBUG
CFLAGS+=-DNUM_LIN_LEDS=17 -DDFREQ=15000 -DCCEMBEDDED CFLAGS+=-DNUM_LIN_LEDS=17 -DDFREQ=12500 -DCCEMBEDDED
AFLAGS = $(MCFLAGS) AFLAGS = $(MCFLAGS)

View file

@ -1,4 +1,3 @@
//TODO: Consider oversampling the ADC using DMA.
//Mostly from: http://www.pezzino.ch/stm32-adc-voltage-monitor/ //Mostly from: http://www.pezzino.ch/stm32-adc-voltage-monitor/
//Also: http://www.micromouseonline.com/2009/05/26/simple-adc-use-on-the-stm32/ //Also: http://www.micromouseonline.com/2009/05/26/simple-adc-use-on-the-stm32/
@ -41,14 +40,8 @@ void InitADC()
ADC_VoltageRegulatorCmd( ADC4, ENABLE ); ADC_VoltageRegulatorCmd( ADC4, ENABLE );
/* Insert delay equal to 10 µs */ /* Insert delay equal to 10 µs */
//vTaskDelay(5);
_delay_us( 10 ); _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_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode; ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
@ -84,12 +77,11 @@ void InitADC()
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init (&NVIC_InitStructure); NVIC_Init (&NVIC_InitStructure);
/* TIM2 clock enable */ /* TIM2 clock enable */
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2, ENABLE); RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2, ENABLE);
/* Time base configuration */ /* Time base configuration */
RCC->CFGR |= 0X1400; 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_Prescaler = 1 - 1; // Operate at clock frequency
TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
@ -99,21 +91,34 @@ void InitADC()
/* TIM2 enable counter */ /* TIM2 enable counter */
TIM_Cmd (TIM2, ENABLE); TIM_Cmd (TIM2, ENABLE);
/* Start ADC4 Software Conversion */ /* Start ADC4 Software Conversion */
ADC_StartConversion( ADC4 ); 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 average = 0;
static int32_t oversampout = 0;
if (TIM_GetITStatus (TIM2, TIM_IT_Update) != RESET) { if (TIM_GetITStatus (TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit (TIM2, TIM_IT_Update); TIM_ClearITPendingBit (TIM2, TIM_IT_Update);
int16_t value = ADC_GetConversionValue(ADC4); int16_t value = ADC_GetConversionValue(ADC4);
average = ((average*1023) + (value*1024))/1024;
ADC_StartConversion( ADC4 ); 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;
}
} }
} }

View file

@ -4,6 +4,7 @@
#include <stdint.h> #include <stdint.h>
#define ADCFS DFREQ #define ADCFS DFREQ
#define ADCOVERSAMP 4
void InitADC(); void InitADC();
void ADCCallback( int16_t value ); void ADCCallback( int16_t value );

View file

@ -43,6 +43,7 @@ SECTIONS
KEEP (*(.init)) KEEP (*(.init))
KEEP (*(.fini)) KEEP (*(.fini))
. = ALIGN(4); . = ALIGN(4);
_etext = .; /* define a global symbols at end of code */ _etext = .; /* define a global symbols at end of code */
} >FLASH } >FLASH

View file

@ -33,13 +33,13 @@ void send_text( const char * text )
send_openocd_command(0x05, m); 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 }; uint32_t m[] = { 2, (uint32_t)buf, count };
send_openocd_command(0x05, m); send_openocd_command(0x05, m);
} }
void * _sbrk(int incr) { void __attribute__((used)) * _sbrk(int incr) {
extern char _ebss; // Defined by the linker extern char _ebss; // Defined by the linker
static char *heap_end; static char *heap_end;
char *prev_heap_end; char *prev_heap_end;
@ -71,17 +71,87 @@ void _delay_us(uint32_t us) {
} }
void ConfigureLED() 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; GPIO_InitTypeDef GPIO_InitStructure;
/* Enable the GPIO_LED Clock */ /* 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 */ /* Configure the GPIO_LED pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //| GPIO_Pin_15 (15 = CTS) GPIO_InitStructure.GPIO_Pin = 1<<(gpio&0xf);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Mode = (parameters&INOUT_FLAG)?GPIO_Mode_OUT:GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 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_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_Init(GPIOB, &GPIO_InitStructure);
} }

View file

@ -5,6 +5,34 @@ void send_openocd_command(int command, void *message);
void send_text( const char * text ); void send_text( const char * text );
void _delay_us(uint32_t us); 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(); void ConfigureLED();
#define LED_TOGGLE {GPIOB->ODR ^= GPIO_Pin_8;} #define LED_TOGGLE {GPIOB->ODR ^= GPIO_Pin_8;}
#define LED_ON {GPIOB->BSRR ^= GPIO_Pin_8;} #define LED_ON {GPIOB->BSRR ^= GPIO_Pin_8;}

View file

@ -10,6 +10,8 @@
#include <embeddedout.h> #include <embeddedout.h>
gpio freepin;
RCC_ClocksTypeDef RCC_Clocks; RCC_ClocksTypeDef RCC_Clocks;
volatile int adcer; volatile int adcer;
@ -47,28 +49,12 @@ int main(void)
RCC_GetClocksFreq( &RCC_Clocks ); RCC_GetClocksFreq( &RCC_Clocks );
ConfigureLED(); LED_ON; ConfigureLED(); LED_OFF;
//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.
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
//Turn B10 (TX) on, so we can have something positive to bias the ADC with.
//Turn B10 (TX) on, so we can have something to bias the ADC with. ConfigureGPIO( GetGPIOFromString( "PB10" ), INOUT_OUT | DEFAULT_ON );
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;
/* SysTick end of count event each 10ms */ /* SysTick end of count event each 10ms */
SysTick_Config( RCC_Clocks.HCLK_Frequency/100 ); /// 100); SysTick_Config( RCC_Clocks.HCLK_Frequency/100 ); /// 100);
@ -79,17 +65,21 @@ int main(void)
InitADC(); InitADC();
Init(); //Colorchord 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 this_samp = 0;
int wf = 0; int wf = 0;
LED_ON;
while(1) while(1)
{ {
if( this_samp != last_samp_pos ) 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. PushSample32( sampbuff[this_samp] ); //Can't put in full volume.
this_samp = (this_samp+1)%CIRCBUFSIZE; this_samp = (this_samp+1)%CIRCBUFSIZE;
@ -100,37 +90,15 @@ int main(void)
NewFrame(); NewFrame();
wf = 0; 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() void TimingDelay_Decrement()
{ {
/* static int i; LED_TOGGLE;
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;
*/
} }

View file

@ -34,7 +34,7 @@ void GotSample( int samp )
//Call this once we've stacked together one full colorchord frame. //Call this once we've stacked together one full colorchord frame.
void NewFrame() void NewFrame()
{ {
uint8_t led_outs[NUM_LIN_LEDS*3]; // uint8_t led_outs[NUM_LIN_LEDS*3];
int i; int i;
HandleFrameInfo(); HandleFrameInfo();
UpdateLinearLEDs(); UpdateLinearLEDs();

View file

@ -22,7 +22,7 @@ void InitMP45DT02()
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
#ifdef ST_PDM #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.HP_HZ=20;
pdm_filter.Fs=FS; pdm_filter.Fs=FS;
pdm_filter.Out_MicChannels=1; pdm_filter.Out_MicChannels=1;