FFT using CMSIS for non mbed-os for smaller capacity chips with DAC output e.g. F303K8 to display FFT to an Oscilloscope with example to send to MAX7219 LED Array

Dependencies:   MAX7219 mbed-dsp mbed

Committer:
martinsimpson
Date:
Fri Apr 13 09:22:26 2018 +0000
Revision:
0:6daa40cd81ec
1st commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
martinsimpson 0:6daa40cd81ec 1 #include "mbed.h"
martinsimpson 0:6daa40cd81ec 2 /*ADAFruit 8x8 LED Array driver chip SPI */
martinsimpson 0:6daa40cd81ec 3 #include "max7219.h"
martinsimpson 0:6daa40cd81ec 4 /* Include arm_math.h mathematic functions */
martinsimpson 0:6daa40cd81ec 5 #include "arm_math.h"
martinsimpson 0:6daa40cd81ec 6 /* Include mbed-dsp libraries */
martinsimpson 0:6daa40cd81ec 7 #include "arm_common_tables.h"
martinsimpson 0:6daa40cd81ec 8 #include "arm_const_structs.h"
martinsimpson 0:6daa40cd81ec 9 #include "math_helper.h"
martinsimpson 0:6daa40cd81ec 10
martinsimpson 0:6daa40cd81ec 11 /* FFT settings */
martinsimpson 0:6daa40cd81ec 12 #define SAMPLES 512 /* 256 real party and 256 imaginary parts */
martinsimpson 0:6daa40cd81ec 13 #define FFT_SIZE SAMPLES / 2 /* FFT size is always the same size as we have samples, so 256 in our case */
martinsimpson 0:6daa40cd81ec 14
martinsimpson 0:6daa40cd81ec 15 /* Global variables */
martinsimpson 0:6daa40cd81ec 16 float32_t Input[SAMPLES];
martinsimpson 0:6daa40cd81ec 17 float32_t sampler[SAMPLES]={0};
martinsimpson 0:6daa40cd81ec 18 float32_t Output[FFT_SIZE];
martinsimpson 0:6daa40cd81ec 19 bool trig=0;
martinsimpson 0:6daa40cd81ec 20
martinsimpson 0:6daa40cd81ec 21 /*Function Prototypes */
martinsimpson 0:6daa40cd81ec 22 uint16_t convert_bar(uint16_t);
martinsimpson 0:6daa40cd81ec 23 void sample();
martinsimpson 0:6daa40cd81ec 24
martinsimpson 0:6daa40cd81ec 25 /* MBED class APIs */
martinsimpson 0:6daa40cd81ec 26 DigitalOut myled(LED1);
martinsimpson 0:6daa40cd81ec 27 AnalogIn myADC(A1);
martinsimpson 0:6daa40cd81ec 28 AnalogOut myDAC(A3);
martinsimpson 0:6daa40cd81ec 29 Ticker timer;
martinsimpson 0:6daa40cd81ec 30
martinsimpson 0:6daa40cd81ec 31 /* Other class APIs */
martinsimpson 0:6daa40cd81ec 32 Max7219 max7219(D11, D12, D13, D10);//SPI0_MOSI, SPI0_MISO, SPI0_SCK, SPI0_SS);
martinsimpson 0:6daa40cd81ec 33
martinsimpson 0:6daa40cd81ec 34 void sample(){
martinsimpson 0:6daa40cd81ec 35 trig=1;
martinsimpson 0:6daa40cd81ec 36 }
martinsimpson 0:6daa40cd81ec 37
martinsimpson 0:6daa40cd81ec 38 int main() {
martinsimpson 0:6daa40cd81ec 39
martinsimpson 0:6daa40cd81ec 40 uint8_t array[]={0x1F,0x14,0x10,0x00,0x1F,0x14,0x10,0x00,0x10,0x1F,0x10}; //text 'FFT'
martinsimpson 0:6daa40cd81ec 41 uint16_t array_size=sizeof(array);
martinsimpson 0:6daa40cd81ec 42 int16_t i,j;
martinsimpson 0:6daa40cd81ec 43 float maxValue; // Max FFT value is stored here
martinsimpson 0:6daa40cd81ec 44 uint32_t maxIndex; // Index in Output array where max value is
martinsimpson 0:6daa40cd81ec 45
martinsimpson 0:6daa40cd81ec 46 printf("FFT Example using 32F303K8 DAC output\r\n");
martinsimpson 0:6daa40cd81ec 47
martinsimpson 0:6daa40cd81ec 48 max7219_configuration_t cfg = {
martinsimpson 0:6daa40cd81ec 49 .device_number = 1,
martinsimpson 0:6daa40cd81ec 50 .decode_mode = 0,
martinsimpson 0:6daa40cd81ec 51 .intensity = Max7219::MAX7219_INTENSITY_4,
martinsimpson 0:6daa40cd81ec 52 .scan_limit = Max7219::MAX7219_SCAN_8
martinsimpson 0:6daa40cd81ec 53 };
martinsimpson 0:6daa40cd81ec 54
martinsimpson 0:6daa40cd81ec 55 max7219.init_device(cfg);
martinsimpson 0:6daa40cd81ec 56 max7219.enable_device(1);
martinsimpson 0:6daa40cd81ec 57 max7219.set_display_test();
martinsimpson 0:6daa40cd81ec 58 max7219.clear_display_test();
martinsimpson 0:6daa40cd81ec 59 max7219.display_all_off();
martinsimpson 0:6daa40cd81ec 60
martinsimpson 0:6daa40cd81ec 61 for(j=-8;j<=array_size;j++){
martinsimpson 0:6daa40cd81ec 62 for(i=1;i<=array_size;i++){
martinsimpson 0:6daa40cd81ec 63 max7219.write_digit(1,9-i+j,array[i-1]);
martinsimpson 0:6daa40cd81ec 64 }
martinsimpson 0:6daa40cd81ec 65 wait_ms(100);
martinsimpson 0:6daa40cd81ec 66 max7219.display_all_off();
martinsimpson 0:6daa40cd81ec 67 }
martinsimpson 0:6daa40cd81ec 68
martinsimpson 0:6daa40cd81ec 69 //arm_cfft_instance_f32 S; // ARM CFFT module
martinsimpson 0:6daa40cd81ec 70 //float maxValue; // Max FFT value is stored here
martinsimpson 0:6daa40cd81ec 71 //uint32_t maxIndex; // Index in Output array where max value is
martinsimpson 0:6daa40cd81ec 72
martinsimpson 0:6daa40cd81ec 73 while(1) {
martinsimpson 0:6daa40cd81ec 74 timer.attach_us(&sample,30); //30us 30,30 250KHz sampling rate ********
martinsimpson 0:6daa40cd81ec 75
martinsimpson 0:6daa40cd81ec 76 for (i = 0; i < SAMPLES; i += 2) {
martinsimpson 0:6daa40cd81ec 77 while (trig==0){}
martinsimpson 0:6daa40cd81ec 78 trig=0;
martinsimpson 0:6daa40cd81ec 79 Input[i] = myADC.read() - 0.5f; //Real part NB removing DC offset
martinsimpson 0:6daa40cd81ec 80 Input[i + 1] = 0; //Imaginary Part set to zero
martinsimpson 0:6daa40cd81ec 81 }
martinsimpson 0:6daa40cd81ec 82 timer.detach();
martinsimpson 0:6daa40cd81ec 83 // Init the Complex FFT module, intFlag = 0, doBitReverse = 1
martinsimpson 0:6daa40cd81ec 84 // NB using predefined arm_cfft_sR_f32_lenXXX, in this case XXX is 256
martinsimpson 0:6daa40cd81ec 85 arm_cfft_f32(&arm_cfft_sR_f32_len256, Input, 0, 1);
martinsimpson 0:6daa40cd81ec 86
martinsimpson 0:6daa40cd81ec 87 // Complex Magniture Module put results into Output(Half size of the Input)
martinsimpson 0:6daa40cd81ec 88 arm_cmplx_mag_f32(Input, Output, FFT_SIZE);
martinsimpson 0:6daa40cd81ec 89
martinsimpson 0:6daa40cd81ec 90 Output[0]=0;
martinsimpson 0:6daa40cd81ec 91
martinsimpson 0:6daa40cd81ec 92
martinsimpson 0:6daa40cd81ec 93 //Calculates maxValue and returns corresponding value
martinsimpson 0:6daa40cd81ec 94 arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex);
martinsimpson 0:6daa40cd81ec 95
martinsimpson 0:6daa40cd81ec 96
martinsimpson 0:6daa40cd81ec 97 myDAC=1.0f; //SYNC here!! for Oscillscope at max DAC output for triggering purposes
martinsimpson 0:6daa40cd81ec 98 wait_us(20);//All FFT values will be lower since max scaling is 0.9 as below
martinsimpson 0:6daa40cd81ec 99 myDAC=0.0f;//set trigger level on oscilloscope between 0.9 to 1.0 (*3.3Volts) i.e. 3.0 to 3.3Volts
martinsimpson 0:6daa40cd81ec 100
martinsimpson 0:6daa40cd81ec 101 for (i=2; i<FFT_SIZE/2 ; i++){
martinsimpson 0:6daa40cd81ec 102 myDAC=(Output[i]/maxValue)*0.9f; // All Values scaled to 0.0 to 0.9 for output to DAC
martinsimpson 0:6daa40cd81ec 103 // if (Output[i]>0.2){printf("%d %f\r\n",i,(Output[i]/maxValue)*0.9f);}
martinsimpson 0:6daa40cd81ec 104 wait_us(10);
martinsimpson 0:6daa40cd81ec 105 }
martinsimpson 0:6daa40cd81ec 106 myDAC=0.0f;
martinsimpson 0:6daa40cd81ec 107
martinsimpson 0:6daa40cd81ec 108 for (i=0; i<9;i++){
martinsimpson 0:6daa40cd81ec 109 max7219.write_digit(1,9-i,convert_bar((uint16_t)(Output[i*16]*2.9f)));// 5.8f
martinsimpson 0:6daa40cd81ec 110 }
martinsimpson 0:6daa40cd81ec 111 }
martinsimpson 0:6daa40cd81ec 112 }
martinsimpson 0:6daa40cd81ec 113
martinsimpson 0:6daa40cd81ec 114 // Will take a number (numVal) 0 to 255 and return (converted) the next (lower) 2^n-1 value
martinsimpson 0:6daa40cd81ec 115 // to light up all LEDS as a bar graph representation
martinsimpson 0:6daa40cd81ec 116 uint16_t convert_bar(uint16_t numVal){
martinsimpson 0:6daa40cd81ec 117 if (numVal>255){return 0;}
martinsimpson 0:6daa40cd81ec 118 uint16_t converted = 0;
martinsimpson 0:6daa40cd81ec 119 for (uint16_t i=1; i<=256 ; i*=2){
martinsimpson 0:6daa40cd81ec 120 if ((numVal/(i)) >= 1){converted = (i-1);}
martinsimpson 0:6daa40cd81ec 121 }
martinsimpson 0:6daa40cd81ec 122 return converted;
martinsimpson 0:6daa40cd81ec 123 }