diff --git a/Hardware/PSDR.sch b/Hardware/PSDR.sch index 8057e6b..1784859 100644 Binary files a/Hardware/PSDR.sch and b/Hardware/PSDR.sch differ diff --git a/Source/include/images.h b/Source/include/images.h index 9cb8d21..f237724 100644 --- a/Source/include/images.h +++ b/Source/include/images.h @@ -12,3 +12,19 @@ extern const unsigned short psdrLogo[]; extern const unsigned short bitmapMode[]; +extern const unsigned short bitmapLSB[]; +extern const unsigned short bitmapUSB[]; +extern const unsigned short bitmapAM[]; +extern const unsigned short bitmapPeriod[]; +extern const unsigned short bitmapOne[]; +extern const unsigned short bitmapTwo[]; +extern const unsigned short bitmapThree[]; +extern const unsigned short bitmapFour[]; +extern const unsigned short bitmapFive[]; +extern const unsigned short bitmapSix[]; +extern const unsigned short bitmapSeven[]; +extern const unsigned short bitmapEight[]; +extern const unsigned short bitmapNine[]; +extern const unsigned short bitmapZero[]; +extern const unsigned short bitmapIronGradient[]; +extern const unsigned short bitmapWebSdrGradient[]; diff --git a/Source/include/main.h b/Source/include/main.h index 33b4cc8..cd5c576 100644 --- a/Source/include/main.h +++ b/Source/include/main.h @@ -33,3 +33,11 @@ TIM_HandleTypeDef TimHandle; TIM_HandleTypeDef TimHandle4; + +#define MASKRED 0b1111100000000000 +#define MASKGREEN 0b0000011111100000 +#define MASKBLUE 0b0000000000011111 +#define MASKYELLOW 0b1111111111100000 +#define MASKTEAL 0b0000011111111111 +#define MASKWHITE 0b1111111111111111 +#define MASKBLACK 0b0000000000000000 diff --git a/Source/src/Adafruit_GFX.c b/Source/src/Adafruit_GFX.c index 2bcb117..2521114 100644 --- a/Source/src/Adafruit_GFX.c +++ b/Source/src/Adafruit_GFX.c @@ -372,13 +372,14 @@ void Adafruit_GFX_drawBitmap(int16_t x, int16_t y, } } -void Adafruit_GFX_drawColorBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) +void Adafruit_GFX_drawColorBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h, uint16_t tintMask) { - int16_t i, j; + int16_t i, j, bmIndex; for(j=0; j fftMax) fftMax = mags; - if(mags < fftMin) fftMin = mags; - } - //logMax = log2(fftMax); - - if(fftMax > fftMaxMax) fftMaxMax += fftMax * 0.1; - logMax = log2(fftMaxMax); - fftMaxMax *= 0.99; - -// 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; //Log needs to be at least 1 right? We could do a + (1-fftMin) maybe? Worth it? - //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; -// } + drawWaterfall(); if(vfoAFrequency != vfoALastFreq) { @@ -963,45 +790,36 @@ main(int argc, char* argv[]) if(freqChar[0] != lastFreqChar[0]) { - Adafruit_GFX_setCursor(freqHOffset + 18*0, freqVOffset + 0); - Adafruit_GFX_write(freqChar[0]); + drawNumber(freqChar[0], freqHOffset + 16*0, freqVOffset + 0, getMenuPos() == 0 ? MASKRED : MASKWHITE); } if(freqChar[1] != lastFreqChar[1]) { - Adafruit_GFX_setCursor(freqHOffset + 18*1, freqVOffset + 0); - Adafruit_GFX_write(freqChar[1]); + drawNumber(freqChar[1], freqHOffset + 16*1, freqVOffset + 0, getMenuPos() == 0 ? MASKRED : MASKWHITE); } if(freqChar[2] != lastFreqChar[2]) { - Adafruit_GFX_setCursor(freqHOffset + 18*3, freqVOffset + 0); - Adafruit_GFX_write(freqChar[2]); + drawNumber(freqChar[2], freqHOffset + 16*3, freqVOffset + 0, getMenuPos() == 1 ? MASKRED : MASKWHITE); } if(freqChar[3] != lastFreqChar[3]) { - Adafruit_GFX_setCursor(freqHOffset + 18*4, freqVOffset + 0); - Adafruit_GFX_write(freqChar[3]); + drawNumber(freqChar[3], freqHOffset + 16*4, freqVOffset + 0, getMenuPos() == 2 ? MASKRED : MASKWHITE); } if(freqChar[4] != lastFreqChar[4]) { - Adafruit_GFX_setCursor(freqHOffset + 18*5, freqVOffset + 0); - Adafruit_GFX_write(freqChar[4]); + drawNumber(freqChar[4], freqHOffset + 16*5, freqVOffset + 0, getMenuPos() == 3 ? MASKRED : MASKWHITE); } - if(freqChar[5] != lastFreqChar[5]) { - Adafruit_GFX_setCursor(freqHOffset + 18*7, freqVOffset + 0); - Adafruit_GFX_write(freqChar[5]); + drawNumber(freqChar[5], freqHOffset + 16*7, freqVOffset + 0, getMenuPos() == 4 ? MASKRED : MASKWHITE); } if(freqChar[6] != lastFreqChar[6]) { - Adafruit_GFX_setCursor(freqHOffset + 18*8, freqVOffset + 0); - Adafruit_GFX_write(freqChar[6]); + drawNumber(freqChar[6], freqHOffset + 16*8, freqVOffset + 0, getMenuPos() == 5 ? MASKRED : MASKWHITE); } if(freqChar[7] != lastFreqChar[7]) { - Adafruit_GFX_setCursor(freqHOffset + 18*9, freqVOffset + 0); - Adafruit_GFX_write(freqChar[7]); + drawNumber(freqChar[7], freqHOffset + 16*9, freqVOffset + 0, getMenuPos() == 6 ? MASKRED : MASKWHITE); } vfoALastFreq = vfoAFrequency; @@ -1013,16 +831,62 @@ main(int argc, char* argv[]) } } +void drawWaterfall() +{ + static float magnitudes[FFT_SIZE]; + static float mags; + static uint8_t waterfallScanLine = 0; + + arm_cmplx_mag_f32(samplesDisplay, magnitudes, FFT_SIZE); + + float fftMax = 0; //AH! These are being reset each time! Static makes them persistant right? Does it also ensure they are + float fftMin = 100; //only initialized once? Have to try it when I get home. It would certainly be nice if the waterfall + static float fftMaxMax = 0; //didn't change in brightness so much. Later, I may want to fix these values, or at least, make them + static float logMax; //manually controllable, sorta, you know? + uint8_t i; + for(i = 1; i < 255; i++) //If bin 0 is the DC offset, should we skip it in this calculation? + { + float mags = magnitudes[i]; + if(mags > fftMax) fftMax = mags; + if(mags < fftMin) fftMin = mags; + } + //logMax = log2(fftMax); + + if(fftMax > fftMaxMax) fftMaxMax += fftMax * 0.1; + logMax = log2(fftMaxMax); + fftMaxMax *= 0.99; + if (fftMaxMax > fftMaxMaxMax) fftMaxMax = fftMaxMaxMax; + if (fftMaxMax < fftMaxMaxMin) fftMaxMax = fftMaxMaxMin; + + + // 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 * 100; //Log needs to be at least 1 right? We could do a + (1-fftMin) maybe? Worth it? + //mags = magnitudes[i] / fftMaxMax * 32; + Adafruit_ILI9340_drawPixel(waterfallScanLine, (120 - i), bitmapWebSdrGradient[(uint8_t) mags]); + } + + for(i = 135; i < 255; i++) + { + mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 100; + //mags = magnitudes[i] / fftMaxMax * 32; + Adafruit_ILI9340_drawPixel(waterfallScanLine, 359 - (i - 15), bitmapWebSdrGradient[(uint8_t) mags]); + } + + waterfallScanLine++; + if(waterfallScanLine > 119) waterfallScanLine = 0; + Adafruit_ILI9340_setVertialScrollStartAddress((119 - waterfallScanLine) + 200); +} + 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); @@ -1032,9 +896,6 @@ void processStream() 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) @@ -1043,9 +904,6 @@ void processStream() 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, ifShift); @@ -1073,7 +931,6 @@ void processStream() 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. @@ -1131,45 +988,6 @@ void processStream() 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; } @@ -1200,6 +1018,48 @@ void updateVfo() } } +void drawNumber(char c, uint16_t x, uint16_t y, uint16_t tintMask) +{ + switch(c) + { + case '.': + Adafruit_GFX_drawColorBitmap(x, y, bitmapPeriod, 15, 19, tintMask); + break; + case '1': + Adafruit_GFX_drawColorBitmap(x, y, bitmapOne, 15, 19, tintMask); + break; + case '2': + Adafruit_GFX_drawColorBitmap(x, y, bitmapTwo, 15, 19, tintMask); + break; + case '3': + Adafruit_GFX_drawColorBitmap(x, y, bitmapThree, 15, 19, tintMask); + break; + case '4': + Adafruit_GFX_drawColorBitmap(x, y, bitmapFour, 15, 19, tintMask); + break; + case '5': + Adafruit_GFX_drawColorBitmap(x, y, bitmapFive, 15, 19, tintMask); + break; + case '6': + Adafruit_GFX_drawColorBitmap(x, y, bitmapSix, 15, 19, tintMask); + break; + case '7': + Adafruit_GFX_drawColorBitmap(x, y, bitmapSeven, 15, 19, tintMask); + break; + case '8': + Adafruit_GFX_drawColorBitmap(x, y, bitmapEight, 15, 19, tintMask); + break; + case '9': + Adafruit_GFX_drawColorBitmap(x, y, bitmapNine, 15, 19,tintMask); + break; + case '0': + Adafruit_GFX_drawColorBitmap(x, y, bitmapZero, 15, 19, tintMask); + break; + default: + Adafruit_GFX_fillRect(x, y, 15, 19, ILI9340_BLACK); + } +} + //TIM_TimeBaseInitTypeDef timeBaseStructure; // //TIM_OC_InitTypeDef tsConfig; @@ -1309,7 +1169,7 @@ TIM_TypeDef timTimBase; void TIM_Try(void) { - uwPrescalerValue = (uint32_t) ((SystemCoreClock/2) / 21000000) - 1; + uwPrescalerValue = (uint32_t) ((SystemCoreClock/2) / 17500000) - 1; //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); __TIM3_CLK_ENABLE();