The main thing here is moving the FFT/Filtering/IFFT to a timer interrupt that has a lower priority than the audio capture/playback timer interrupt. This way I don't care how slow the display code runs in the main loop (for now) enabling me to have the audio processing and the display working at the same time.

This commit is contained in:
Michael Colton 2014-07-14 01:41:46 -06:00
parent 71b87a38d7
commit 31de146601
9 changed files with 458 additions and 292 deletions

Binary file not shown.

View file

@ -50,6 +50,9 @@
__IO uint32_t timingDelay;
// gpio pins
// extern const Gpio_Pin RX_TO_GSM;
// extern const Gpio_Pin TX_FROM_GSM;

View file

@ -16,6 +16,8 @@
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9340.h"
#include "stm32f4xx_hal.h"
//#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_def.h"
#include "string.h"
#include "math.h"
#include "arm_math.h"
@ -28,3 +30,4 @@
#include "stm32f4xx_hal_dac.h"
TIM_HandleTypeDef TimHandle;
TIM_HandleTypeDef TimHandle4;

View file

@ -244,6 +244,8 @@ void Adafruit_ILI9340_begin(void) {
HAL_GPIO_WritePin(LCD_RESET.port, LCD_RESET.pin, 1);
hal_delay_ms(150);
HAL_GPIO_WritePin(LCD_NSS.port, LCD_NSS.pin, 0); //I'm going to try leaving this low the WHOLE TIME!
/*
uint8_t x = readcommand8(ILI9340_RDMODE);
Serial.print("\nDisplay Power Mode: 0x"); Serial.println(x, HEX);

View file

@ -119,7 +119,7 @@ const Gpio_Pin dac2 = { GPIOA, GPIO_PIN_5 };
//};
static uint32_t halMilliseconds;
static uint32_t timingDelay;
//static uint32_t timingDelay;
static hal_sysTickCallback sysTickCallback = 0; //Was NULL, but NULL isn't defined? Where is it defined?
@ -164,14 +164,14 @@ void hal_delay_ms(uint32_t ms)
{
// busy wait for ms milliseconds
//TEMP
int delay, extra;
for(delay = 0; delay < ms; delay++)
for(extra = 0; extra < 1000; extra++);
////TEMP
//int delay, extra;
//for(delay = 0; delay < ms; delay++)
// for(extra = 0; extra < 1000; extra++);
// timingDelay = ms;
// while (timingDelay)
// ;
timingDelay = ms;
while (timingDelay)
;
}

View file

@ -60,17 +60,18 @@ uint16_t filterKernelLength = 100; //what's a good value? How does it relate to
uint16_t menuState = 0;
uint16_t menuLastState = 1;
uint16_t menuCount = 10;
uint16_t menuCount = 9;
uint32_t frequencyDialMultiplier = 1;
long vfoAFrequency = 7260000;
long vfoALastFreq = 7260000;
long vfoAFrequency = 7058960;
long vfoALastFreq = 0;
int encoderPos, encoderLastPos;
int16_t filterUpperLimit = 10;
int16_t filterUpperLimit = 68;
int16_t filterLowerLimit = 0;
float agcLevel = 0;
float agcScale = 160; //Higher is lower volume.. for now
void polarToRect(float m, float a, float32_t* x, float32_t* y)
{
@ -224,6 +225,7 @@ SysTick_Handler (void)
millis++;
timer_tick ();
Tick();
if(timingDelay > 0) timingDelay--;
}
int clickMultiply;
@ -302,9 +304,13 @@ int isFwd;
float samplesA[FFT_BUFFER_SIZE];
float samplesB[FFT_BUFFER_SIZE];
float samplesC[FFT_BUFFER_SIZE];
float samplesDisplay[FFT_BUFFER_SIZE];
int sampleBankAReady = 0;
int sampleBankBReady = 0;
int sampleBankCReady = 0;
uint8_t waterfallBusy = 0;
//float outputSamplesA[512];
//float outputSamplesB[512];
int sampleBank = 0;
@ -328,8 +334,16 @@ int isFwd;
if(samplesB[sampleIndex*2] > agcLevel) agcLevel = samplesB[sampleIndex*2];
if(samplesB[sampleIndex*2+1] > agcLevel) agcLevel = samplesB[sampleIndex*2+1];
dac1SetValue(samplesB[sampleIndex*2] / (agcLevel * 40) * 4096 * gain + 2048);
dac2SetValue(samplesB[sampleIndex*2+1] / (agcLevel * 40) * 4096 * gain + 2048);
// if(sampleIndex < filterKernelLength)
// {
// dac1SetValue(samplesB[sampleIndex*2] + samplesA[(FFT_SIZE - filterKernelLength)
// + sampleIndex * 2] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
// dac2SetValue(samplesB[sampleIndex*2+1] + samplesA[(FFT_SIZE - filterKernelLength)
// + sampleIndex * 2] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
// } else {
dac1SetValue(samplesB[sampleIndex*2] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
dac2SetValue(samplesB[sampleIndex*2+1] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
// }
break;
case 1:
@ -339,8 +353,16 @@ int isFwd;
if(samplesC[sampleIndex*2] > agcLevel) agcLevel =samplesC[sampleIndex*2];
if(samplesC[sampleIndex*2+1] > agcLevel) agcLevel = samplesC[sampleIndex*2+1];
dac1SetValue(samplesC[sampleIndex*2] / (agcLevel * 40) * 4096 * gain + 2048);
dac2SetValue(samplesC[sampleIndex*2+1] / (agcLevel * 40) * 4096 * gain + 2048);
// if(sampleIndex < filterKernelLength)
// {
// dac1SetValue(samplesC[sampleIndex*2] + samplesB[(FFT_SIZE - filterKernelLength)
// + sampleIndex * 2] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
// dac2SetValue(samplesC[sampleIndex*2+1] + samplesB[(FFT_SIZE - filterKernelLength)
// + sampleIndex * 2] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
// } else {
dac1SetValue(samplesC[sampleIndex*2] / (agcLevel * agcScale) * 4096 * gain + 2048);
dac2SetValue(samplesC[sampleIndex*2+1] / (agcLevel * agcScale) * 4096 * gain + 2048);
// }
break;
case 2:
@ -350,8 +372,16 @@ int isFwd;
if(samplesA[sampleIndex*2] > agcLevel) agcLevel = samplesA[sampleIndex*2];
if(samplesA[sampleIndex*2+1] > agcLevel) agcLevel = samplesA[sampleIndex*2+1];
dac1SetValue(samplesA[sampleIndex*2] / (agcLevel * 40) * 4096 * gain + 2048);
dac2SetValue(samplesA[sampleIndex*2+1] / (agcLevel * 40) * 4096 * gain + 2048);
// if(sampleIndex < filterKernelLength)
// {
// dac1SetValue(samplesA[sampleIndex*2] + samplesC[(FFT_SIZE - filterKernelLength)
// + sampleIndex * 2] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
// dac2SetValue(samplesA[sampleIndex*2+1] + samplesC[(FFT_SIZE - filterKernelLength)
// + sampleIndex * 2] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
// } else {
dac1SetValue(samplesA[sampleIndex*2] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
dac2SetValue(samplesA[sampleIndex*2+1] /*/ (agcLevel * agcScale)*/ * 4096 * gain + 2048);
// }
break;
}
//dac1SetValue(outputSamplesA[sampleIndex*2]);
@ -359,7 +389,7 @@ int isFwd;
agcLevel = agcLevel * (1 - 0.0001);
sampleIndex++;
if(sampleIndex >= FFT_SIZE - filterKernelLength)
if(sampleIndex >= FFT_SIZE /*- filterKernelLength*/)
{
sampleRun = 1;
sampleIndex = 0;
@ -408,7 +438,6 @@ void zeroSampleBank(float *samples)
for(i = 0; i < FFT_BUFFER_SIZE; i++) samples[i] = 0;
}
int
main(int argc, char* argv[])
{
@ -711,117 +740,122 @@ main(int argc, char* argv[])
float fftMaxMax = 0;
if(sampleRun)
{
// float fftMaxMax = 0;
// if(sampleRun)
// {
//
// timeMeasurement = millis;
// arm_cfft_radix4_instance_f32 fft_inst;
// //arm_cfft_radix4_init_q31(&fft_inst, FFT_SIZE, 0, 1);
// //arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//
// if (sampleBankAReady == 1)
// {
// blink_led_on();
// arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//
//
// //arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
//
// arm_cfft_radix4_f32(&fft_inst, samplesA);
// // Calculate magnitude of complex numbers output by the FFT.
// //arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//
// //arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//
// //applyCoeficient(samplesA);
//
// arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
// arm_cfft_radix4_f32(&fft_inst, samplesA);
//
// sampleBankAReady = 0;
// blink_led_off();
// }
// else if(sampleBankBReady == 1)
// {
// blink_led_on();
// arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//
// //arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
//
// arm_cfft_radix4_f32(&fft_inst, samplesB);
// // Calculate magnitude of complex numbers output by the FFT.
// //arm_cmplx_mag_f32(samplesB, magnitudes, FFT_SIZE);
// //applyCoeficient(samplesB);
//
// arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
// arm_cfft_radix4_f32(&fft_inst, samplesB);
// sampleBankBReady = 0;
// blink_led_off();
//
// }
// else if (sampleBankCReady == 1)
// {
// blink_led_on();
// arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//
//
// //arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
//
// arm_cfft_radix4_f32(&fft_inst, samplesC);
// // Calculate magnitude of complex numbers output by the FFT.
// //arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//
// //arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
// //applyCoeficient(samplesC);
// arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
// arm_cfft_radix4_f32(&fft_inst, samplesC);
//
// sampleBankCReady = 0;
// blink_led_off();
// }
// timeMeasurement = millis - timeMeasurement;
//
timeMeasurement = millis;
arm_cfft_radix4_instance_f32 fft_inst;
//arm_cfft_radix4_init_q31(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
if (sampleBankAReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samplesA);
// Calculate magnitude of complex numbers output by the FFT.
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
applyCoeficient(samplesA);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesA);
sampleBankAReady = 0;
blink_led_off();
}
else if(sampleBankBReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samplesB);
// Calculate magnitude of complex numbers output by the FFT.
//arm_cmplx_mag_f32(samplesB, magnitudes, FFT_SIZE);
applyCoeficient(samplesB);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesB);
sampleBankBReady = 0;
blink_led_off();
}
else if (sampleBankCReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samplesC);
// Calculate magnitude of complex numbers output by the FFT.
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
applyCoeficient(samplesC);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesC);
sampleBankCReady = 0;
blink_led_off();
}
timeMeasurement = millis - timeMeasurement;
arm_cmplx_mag_f32(samplesDisplay, magnitudes, FFT_SIZE);
float fftMax = 0;
// float fftMin = 100;
// float logMax;
// uint8_t i;
// for(i = 0; i < 255; i++)
// {
// float mags = magnitudes[i];
// if(mags > fftMax) fftMax = mags;
// if(mags < fftMin) fftMin = mags;
// }
// //logMax = log2(fftMax);
//
// if(fftMax > fftMaxMax) fftMaxMax = fftMax;
// logMax = log2(fftMaxMax);
float fftMin = 100;
float fftMaxMax = 0;
float logMax;
uint8_t i;
for(i = 0; i < 255; i++)
{
float mags = magnitudes[i];
if(mags > fftMax) fftMax = mags;
if(mags < fftMin) fftMin = mags;
}
//logMax = log2(fftMax);
if(fftMax > fftMaxMax) fftMaxMax = fftMax;
logMax = log2(fftMaxMax);
//TODOne: SWITCH THESE AND FLIP THEM. So that higher frequencies appear higher on screen.
//TODO: Got rid of the first bin because it's just DC offset, right?
//but now narrow signal can disappear when they are right at the center....
//Will that be better when I lower the sample frequency? Maybe I should do that next.
// for(i = 1; i < 120; i++)
// {
// mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
// //mags = magnitudes[i] / fftMaxMax * 32;
// Adafruit_ILI9340_drawPixel(waterfallScanLine, (120 - i), gradient[(uint8_t) mags]);
// }
//
// for(i = 135; i < 255; i++)
// {
// mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
// //mags = magnitudes[i] / fftMaxMax * 32;
// Adafruit_ILI9340_drawPixel(waterfallScanLine, 359 - (i - 15), gradient[(uint8_t) mags]);
// }
//
// waterfallScanLine++;
// if(waterfallScanLine > 119) waterfallScanLine = 0;
// Adafruit_ILI9340_setVertialScrollStartAddress((119 - waterfallScanLine) + 200);
// TODOne: SWITCH THESE AND FLIP THEM. So that higher frequencies appear higher on screen.
// TODO: Got rid of the first bin because it's just DC offset, right?
// but now narrow signal can disappear when they are right at the center....
// Will that be better when I lower the sample frequency? Maybe I should do that next.
//uint16_t i;
for(i = 1; i < 120; i++)
{
mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
//mags = magnitudes[i] / fftMaxMax * 32;
Adafruit_ILI9340_drawPixel(waterfallScanLine, (120 - i), gradient[(uint8_t) mags]);
}
sampleRun = 0;
}
for(i = 135; i < 255; i++)
{
mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
//mags = magnitudes[i] / fftMaxMax * 32;
Adafruit_ILI9340_drawPixel(waterfallScanLine, 359 - (i - 15), gradient[(uint8_t) mags]);
}
waterfallScanLine++;
if(waterfallScanLine > 119) waterfallScanLine = 0;
Adafruit_ILI9340_setVertialScrollStartAddress((119 - waterfallScanLine) + 200);
//
// sampleRun = 0;
// }
if(vfoAFrequency != vfoALastFreq)
{
@ -881,6 +915,140 @@ main(int argc, char* argv[])
}
}
void processStream()
{
float fftMaxMax = 0;
if(sampleRun)
{
//timeMeasurement = millis;
arm_cfft_radix4_instance_f32 fft_inst;
//arm_cfft_radix4_init_q31(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
if (sampleBankAReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samplesA);
// Calculate magnitude of complex numbers output by the FFT.
if(waterfallBusy != 1)
{
uint16_t i;
for(i = 0; i < FFT_BUFFER_SIZE; i++) samplesDisplay[i] = samplesA[i];
//waterfallBusy = 1;
}
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
applyCoeficient(samplesA);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesA);
sampleBankAReady = 0;
blink_led_off();
}
else if(sampleBankBReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samplesB);
// Calculate magnitude of complex numbers output by the FFT.
//arm_cmplx_mag_f32(samplesB, magnitudes, FFT_SIZE);
applyCoeficient(samplesB);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesB);
sampleBankBReady = 0;
blink_led_off();
}
else if (sampleBankCReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samplesC);
// Calculate magnitude of complex numbers output by the FFT.
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
applyCoeficient(samplesC);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesC);
sampleBankCReady = 0;
blink_led_off();
}
//timeMeasurement = millis - timeMeasurement;
float fftMax = 0;
// float fftMin = 100;
// float logMax;
// uint8_t i;
// for(i = 0; i < 255; i++)
// {
// float mags = magnitudes[i];
// if(mags > fftMax) fftMax = mags;
// if(mags < fftMin) fftMin = mags;
// }
// //logMax = log2(fftMax);
//
// if(fftMax > fftMaxMax) fftMaxMax = fftMax;
// logMax = log2(fftMaxMax);
//TODOne: SWITCH THESE AND FLIP THEM. So that higher frequencies appear higher on screen.
//TODO: Got rid of the first bin because it's just DC offset, right?
//but now narrow signal can disappear when they are right at the center....
//Will that be better when I lower the sample frequency? Maybe I should do that next.
// for(i = 1; i < 120; i++)
// {
// mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
// //mags = magnitudes[i] / fftMaxMax * 32;
// Adafruit_ILI9340_drawPixel(waterfallScanLine, (120 - i), gradient[(uint8_t) mags]);
// }
//
// for(i = 135; i < 255; i++)
// {
// mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
// //mags = magnitudes[i] / fftMaxMax * 32;
// Adafruit_ILI9340_drawPixel(waterfallScanLine, 359 - (i - 15), gradient[(uint8_t) mags]);
// }
//
// waterfallScanLine++;
// if(waterfallScanLine > 119) waterfallScanLine = 0;
// Adafruit_ILI9340_setVertialScrollStartAddress((119 - waterfallScanLine) + 200);
sampleRun = 0;
}
//wrongThings++;
//__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
clearTimUpdateFlag(&TimHandle4);
}
void updateVfo()
{
encoderPos = getPos();
@ -897,105 +1065,105 @@ void updateVfo()
}
//TIM_TimeBaseInitTypeDef timeBaseStructure;
TIM_OC_InitTypeDef tsConfig;
#define PULSE1_VALUE 40961 /* Capture Compare 1 Value */
//
//TIM_OC_InitTypeDef tsConfig;
//#define PULSE1_VALUE 40961 /* Capture Compare 1 Value */
uint32_t uwPrescalerValue = 0;
void TIM_setup()
{
/*##-1- Configure the TIM peripheral #######################################*/
/* -----------------------------------------------------------------------
In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
since APB1 prescaler is different from 1.
TIM3CLK = 2 * PCLK1
PCLK1 = HCLK / 4
=> TIM3CLK = HCLK / 2 = SystemCoreClock /2
To get TIM3 counter clock at 60 KHz, the Prescaler is computed as following:
Prescaler = (TIM3CLK / TIM3 counter clock) - 1
Prescaler = ((SystemCoreClock /2) /60 KHz) - 1
Note:
SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
Each time the core clock (HCLK) changes, user had to update SystemCoreClock
variable value. Otherwise, any configuration based on this variable will be incorrect.
This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
----------------------------------------------------------------------- */
/* Compute the prescaler value to have TIM3 counter clock equal to 60 KHz */
uwPrescalerValue = (uint32_t) ((SystemCoreClock/2) / 60000) - 1;
/* Set TIMx instance */
TimHandle.Instance = TIM3; //TIMx;
/* Initialize TIM3 peripheral as follow:
+ Period = 65535
+ Prescaler = (SystemCoreClock/2)/60000
+ ClockDivision = 0
+ Counter direction = Up
*/
TimHandle.Init.Period = 65535;
TimHandle.Init.Prescaler = uwPrescalerValue;
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
if(HAL_TIM_OC_Init(&TimHandle) != HAL_OK)
{
/* Initialization Error */
//Error_Handler();
doNothing();
}
/*##-2- Configure the PWM channels #########################################*/
/* Common configuration */
tsConfig.OCMode = TIM_OCMODE_TIMING;
tsConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
tsConfig.OCFastMode = TIM_OCFAST_DISABLE;
/* Set the pulse value for channel 1 */
tsConfig.Pulse = PULSE1_VALUE;
if(HAL_TIM_OC_ConfigChannel(&TimHandle, &tsConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Initialization Error */
//Error_Handler();
doNothing();
}
/*##-4- Start the Output Compare mode in interrupt mode ####################*/
/* Start Channel1 */
if(HAL_TIM_OC_Start_IT(&TimHandle, TIM_CHANNEL_1) != HAL_OK)
{
/* Initialization Error */
//Error_Handler();
doNothing();
}
}
///**
// * @brief Configures the TIM IRQ Handler.
// * @param None
// * @retval None
//void TIM_setup()
//{
// /*##-1- Configure the TIM peripheral #######################################*/
// /* -----------------------------------------------------------------------
// In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
// since APB1 prescaler is different from 1.
// TIM3CLK = 2 * PCLK1
// PCLK1 = HCLK / 4
// => TIM3CLK = HCLK / 2 = SystemCoreClock /2
// To get TIM3 counter clock at 60 KHz, the Prescaler is computed as following:
// Prescaler = (TIM3CLK / TIM3 counter clock) - 1
// Prescaler = ((SystemCoreClock /2) /60 KHz) - 1
//
// Note:
// SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
// Each time the core clock (HCLK) changes, user had to update SystemCoreClock
// variable value. Otherwise, any configuration based on this variable will be incorrect.
// This variable is updated in three ways:
// 1) by calling CMSIS function SystemCoreClockUpdate()
// 2) by calling HAL API function HAL_RCC_GetSysClockFreq()
// 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
// ----------------------------------------------------------------------- */
//
// /* Compute the prescaler value to have TIM3 counter clock equal to 60 KHz */
// uwPrescalerValue = (uint32_t) ((SystemCoreClock/2) / 60000) - 1;
//
// /* Set TIMx instance */
// TimHandle.Instance = TIM3; //TIMx;
//
// /* Initialize TIM3 peripheral as follow:
// + Period = 65535
// + Prescaler = (SystemCoreClock/2)/60000
// + ClockDivision = 0
// + Counter direction = Up
// */
void TIM_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock enable */
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
__TIM3_CLK_ENABLE();
/* Enable the TIM3 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// TimHandle.Init.Period = 65535;
// TimHandle.Init.Prescaler = uwPrescalerValue;
// TimHandle.Init.ClockDivision = 0;
// TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
// if(HAL_TIM_OC_Init(&TimHandle) != HAL_OK)
// {
// /* Initialization Error */
// //Error_Handler();
// doNothing();
// }
//
// /*##-2- Configure the PWM channels #########################################*/
// /* Common configuration */
// tsConfig.OCMode = TIM_OCMODE_TIMING;
// tsConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
// tsConfig.OCFastMode = TIM_OCFAST_DISABLE;
//
// /* Set the pulse value for channel 1 */
// tsConfig.Pulse = PULSE1_VALUE;
// if(HAL_TIM_OC_ConfigChannel(&TimHandle, &tsConfig, TIM_CHANNEL_1) != HAL_OK)
// {
// /* Initialization Error */
// //Error_Handler();
// doNothing();
// }
//
// /*##-4- Start the Output Compare mode in interrupt mode ####################*/
// /* Start Channel1 */
// if(HAL_TIM_OC_Start_IT(&TimHandle, TIM_CHANNEL_1) != HAL_OK)
// {
// /* Initialization Error */
// //Error_Handler();
// doNothing();
// }
//
//}
}
/////**
//// * @brief Configures the TIM IRQ Handler.
//// * @param None
//// * @retval None
//// */
//void TIM_Config(void)
//{
// NVIC_InitTypeDef NVIC_InitStructure;
//
// /* TIM3 clock enable */
// //RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// __TIM3_CLK_ENABLE();
//
// /* Enable the TIM3 gloabal Interrupt */
// NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
//
//
//}
TIM_TypeDef timTimBase;
//TIM_HandleTypeDef timHandle;
@ -1009,6 +1177,7 @@ void TIM_Try(void)
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
__TIM3_CLK_ENABLE();
TimHandle.Instance = TIM3;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TimHandle.Init.Period = 1050;
@ -1016,6 +1185,8 @@ void TIM_Try(void)
TimHandle.Init.ClockDivision = 0;
HAL_TIM_Base_Init(&TimHandle);
HAL_TIM_Base_Start_IT(&TimHandle);
/*##-2- Configure the NVIC for TIMx #########################################*/
@ -1026,6 +1197,27 @@ void TIM_Try(void)
HAL_NVIC_EnableIRQ(TIMx_IRQn);
__TIM4_CLK_ENABLE();
TimHandle4.Instance = TIM4;
TimHandle4.Init.CounterMode = TIM_COUNTERMODE_UP;
TimHandle4.Init.Period = 1050;
TimHandle4.Init.Prescaler = uwPrescalerValue;
TimHandle4.Init.ClockDivision = 0;
HAL_TIM_Base_Init(&TimHandle4);
HAL_TIM_Base_Start_IT(&TimHandle4);
/*##-2- Configure the NVIC for TIMx #########################################*/
/* Set the TIMx priority */
HAL_NVIC_SetPriority(TIM4_IRQn, 2, 4);
/* Enable the TIMx global Interrupt */
HAL_NVIC_EnableIRQ(TIM4_IRQn);
// int tim3;
// while(1)
// {

View file

@ -9,63 +9,23 @@
#include <hal.h>
#include <stm32f4xx_hal_spi.h>
#include <stm32f4xx_hal_gpio.h>
//#include <stm32f415xx.h>
#include <stm32f4xx_hal.h>
//static int spi2Semaphore;
//SPI_HandleTypeDef SpiHandle;
void spi_init(void)
{
// set up the used SPI (SPI2) and pins
SPI_InitTypeDef spiInitStructure;
GPIO_InitTypeDef gpioInitStructure;
HAL_SPI_MspInit(&SpiHandle);
__SPI1_CLK_ENABLE();
// // SPI2 SCK and MOSI
// gpioInitStructure.GPIO_Pin = SPI1_SCK.pin;
// gpioInitStructure.GPIO_Speed = GPIO_Speed_2MHz;
// gpioInitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_Init(SPI1_SCK.port, &gpioInitStructure);
//
// gpioInitStructure.GPIO_Pin = SPI1_MOSI.pin;
// gpioInitStructure.GPIO_Speed = GPIO_Speed_2MHz;
// gpioInitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_Init(SPI1_MOSI.port, &gpioInitStructure);
//
// // SPI2 MISO
// gpioInitStructure.GPIO_Pin = SPI1_MISO.pin;
// gpioInitStructure.GPIO_Speed = GPIO_Speed_2MHz;
// gpioInitStructure.GPIO_Mode = GPIO_Mode_IPU;
// GPIO_Init(SPI1_MISO.port, &gpioInitStructure);
//
// // RFID NSS
// gpioInitStructure.GPIO_Pin = LCD_NSS.pin;
// gpioInitStructure.GPIO_Speed = GPIO_Speed_2MHz;
// gpioInitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_Init(LCD_NSS.port, &gpioInitStructure);
// GPIO_WriteBit(LCD_NSS.port, LCD_NSS.pin, (BitAction)1); // TBD - should this be before init?
// SPI2 SCK and MOSI
gpioInitStructure.Pin = SPI1_SCK.pin;
gpioInitStructure.Speed = GPIO_SPEED_FAST;
gpioInitStructure.Mode = GPIO_MODE_AF_PP;
gpioInitStructure.Alternate = GPIO_AF5_SPI1;
//gpioInitStructure.Mode = GPIO_MODE_OUTPUT_PP;
gpioInitStructure.Pull = GPIO_NOPULL;
//gpioInitStructure.Alternate = 1;
HAL_GPIO_Init(SPI1_SCK.port, &gpioInitStructure);
@ -73,7 +33,6 @@ void spi_init(void)
gpioInitStructure.Pin = SPI1_MOSI.pin;
gpioInitStructure.Speed = GPIO_SPEED_FAST;
gpioInitStructure.Mode = GPIO_MODE_AF_PP;
//gpioInitStructure.Mode = GPIO_MODE_OUTPUT_PP;
gpioInitStructure.Pull = GPIO_NOPULL;
gpioInitStructure.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(SPI1_MOSI.port, &gpioInitStructure);
@ -95,36 +54,26 @@ void spi_init(void)
HAL_GPIO_Init(LCD_NSS.port, &gpioInitStructure);
HAL_GPIO_WritePin(LCD_NSS.port, LCD_NSS.pin, 1); // TBD - should this be before init?
// gpioInitStructure.Pin = LCD_NSS.pin;
// gpioInitStructure.Speed = GPIO_SPEED_FAST;
// gpioInitStructure.Mode = GPIO_MODE_AF_PP;
// gpioInitStructure.Pull = GPIO_NOPULL;
// gpioInitStructure.Alternate = GPIO_AF5_SPI1;
// HAL_GPIO_Init(LCD_NSS.port, &gpioInitStructure);
// //HAL_GPIO_WritePin(LCD_NSS.port, LCD_NSS.pin, 1); // TBD - should this be before init?
// Accelerometer NSS
// gpioInitStructure.GPIO_Pin = ACCEL_NSS.pin;
// gpioInitStructure.GPIO_Speed = GPIO_Speed_2MHz;
// gpioInitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_Init(ACCEL_NSS.port, &gpioInitStructure);
// GPIO_WriteBit(ACCEL_NSS.port, ACCEL_NSS.pin, (BitAction)1); // TBD - should this be before init?
// init semaphore
// spi2Semaphore = 1;
//GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE); //So I can use the other SPI1 pins? (To keep the DACs availble)
//GPIO_Remap_SPI1
// SPI 1
// SPI_StructInit(&spiInitStructure);
//spiInitStructure.
//HAL_SPI_
SpiHandle.Instance = SPI1;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;// SPI_Direction_2Lines_FullDuplex;
SpiHandle.Init.Mode = SPI_MODE_MASTER; // SPI_Mode_Master;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; // SPI_DataSize_8b;
SpiHandle.Init.CLKPolarity /*CPOL*/ = SPI_POLARITY_HIGH; // SPI_C SPI_CPOL_High;
SpiHandle.Init.CLKPhase /*CPHA*/ = SPI_PHASE_2EDGE; // SPI_CPHA_2Edge;
SpiHandle.Init.NSS = SPI_NSS_SOFT; // SPI_NSS_Soft;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; //SPI_BaudRatePrescaler_2;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; // SPI_FirstBit_MSB;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED;
SpiHandle.Instance = SPI1;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
SpiHandle.Init.Mode = SPI_MODE_MASTER;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_HIGH;
SpiHandle.Init.CLKPhase = SPI_PHASE_2EDGE;
SpiHandle.Init.NSS = SPI_NSS_SOFT; //SPI_NSS_SOFT;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED;
SpiHandle.Init.CRCPolynomial = 7;
if(HAL_SPI_Init(&SpiHandle) != HAL_OK)
@ -132,9 +81,6 @@ void spi_init(void)
/* Initialization Error */
//Error_Handler();
}
//HAL_SPI_TransmitReceive();
//SPI_Cmd(SPI2, ENABLE);
}

View file

@ -160,6 +160,21 @@ void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&TimHandle);
}
/**
* @brief This function handles TIM4 global interrupt request.
* @param None
* @retval None
*/
void TIM4_IRQHandler(void)
{
//HAL_TIM_IRQHandler(&TimHandle);
// HAL_TIM_IRQHandler(&TimHandle);
processStream();
//clearTimUpdateFlag(&TimHandle);
//__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
}
//void TIM3_IRQHandler(void)
//{
// __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);

View file

@ -2885,6 +2885,11 @@ void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
}
}
void clearTimUpdateFlag(TIM_HandleTypeDef *htim)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
}
/**
* @}
*/