Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@1:df1ae6d3fd03, 2018-11-13 (annotated)
- Committer:
- lukofsky
- Date:
- Tue Nov 13 19:27:58 2018 +0000
- Revision:
- 1:df1ae6d3fd03
- Parent:
- 0:15495bc2362a
Memulator;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lukofsky | 1:df1ae6d3fd03 | 1 | /////////////////////////////////////////////////////////////////////////// |
lukofsky | 1:df1ae6d3fd03 | 2 | /** FS & SS EMULATOR CODE |
lukofsky | 1:df1ae6d3fd03 | 3 | * |
lukofsky | 1:df1ae6d3fd03 | 4 | * Version: 1.0 |
lukofsky | 1:df1ae6d3fd03 | 5 | * Author: Rachel Yang (Adapted by Patrick Doyle) |
lukofsky | 1:df1ae6d3fd03 | 6 | * Last Date Modified: 2018.10.2 |
lukofsky | 1:df1ae6d3fd03 | 7 | * |
lukofsky | 1:df1ae6d3fd03 | 8 | * Target Device: STM32F413 |
lukofsky | 1:df1ae6d3fd03 | 9 | * |
lukofsky | 1:df1ae6d3fd03 | 10 | * Description: |
lukofsky | 1:df1ae6d3fd03 | 11 | * digital filter for SS (2nd order) and FS (main peak only) |
lukofsky | 1:df1ae6d3fd03 | 12 | * |
lukofsky | 1:df1ae6d3fd03 | 13 | * Notes: |
lukofsky | 1:df1ae6d3fd03 | 14 | * uses 2 external ADCs (e.g. LTC1992) for FS & SS inputs |
lukofsky | 1:df1ae6d3fd03 | 15 | * uses internal TIM2 to precisely control sampling rate (fs) |
lukofsky | 1:df1ae6d3fd03 | 16 | * uses internal DACs to output single-ended FS & SS outputs |
lukofsky | 1:df1ae6d3fd03 | 17 | */ |
lukofsky | 1:df1ae6d3fd03 | 18 | /////////////////////////////////////////////////////////////////////////// |
lukofsky | 1:df1ae6d3fd03 | 19 | |
lukofsky | 1:df1ae6d3fd03 | 20 | #include "mbed.h" |
lukofsky | 1:df1ae6d3fd03 | 21 | |
lukofsky | 1:df1ae6d3fd03 | 22 | #ifdef __cplusplus |
lukofsky | 1:df1ae6d3fd03 | 23 | extern "C" |
lukofsky | 1:df1ae6d3fd03 | 24 | #endif |
lukofsky | 1:df1ae6d3fd03 | 25 | |
lukofsky | 1:df1ae6d3fd03 | 26 | #define TIM_USR TIM2 |
lukofsky | 1:df1ae6d3fd03 | 27 | #define TIM_USR_IRQ TIM2_IRQn |
lukofsky | 1:df1ae6d3fd03 | 28 | |
lukofsky | 1:df1ae6d3fd03 | 29 | // initialize serial debug (UART)?? |
lukofsky | 1:df1ae6d3fd03 | 30 | //Serial pc(PB_6, PB_8); // USBTX, USBRX |
lukofsky | 1:df1ae6d3fd03 | 31 | |
lukofsky | 1:df1ae6d3fd03 | 32 | // initialize SPI |
lukofsky | 1:df1ae6d3fd03 | 33 | SPI spi(NC, PA_12_ALT0, PB_0); // mosi, miso, sclk (corresponds to SPI5, default hardware connection) |
lukofsky | 1:df1ae6d3fd03 | 34 | //SPI spi(NC, PA_6, PB_3); // mosi, miso, sclk (corresponds to SPI1) |
lukofsky | 1:df1ae6d3fd03 | 35 | DigitalOut cs_fs(PB_1); // FS chip select |
lukofsky | 1:df1ae6d3fd03 | 36 | DigitalOut cs_ss(PA_9); // SS chip select |
lukofsky | 1:df1ae6d3fd03 | 37 | |
lukofsky | 1:df1ae6d3fd03 | 38 | // initialize LED (used as indicator to confirm code uploaded) |
lukofsky | 1:df1ae6d3fd03 | 39 | DigitalOut myled1(PB_9); // corresponds to LED1 (red on display emulator) |
lukofsky | 1:df1ae6d3fd03 | 40 | |
lukofsky | 1:df1ae6d3fd03 | 41 | // pin declarations |
lukofsky | 1:df1ae6d3fd03 | 42 | //AnalogIn input_pin(PC_0); // corresponds to A1 (A0 on F413ZH DISCO) |
lukofsky | 1:df1ae6d3fd03 | 43 | AnalogOut output_pin_n(PA_4); // HPZR SE output from MCU |
lukofsky | 1:df1ae6d3fd03 | 44 | AnalogOut output_pin_p(PA_5); // VPZR SE output from MCU |
lukofsky | 1:df1ae6d3fd03 | 45 | |
lukofsky | 1:df1ae6d3fd03 | 46 | // for internal input read |
lukofsky | 1:df1ae6d3fd03 | 47 | int outputimpulse = 1; |
lukofsky | 1:df1ae6d3fd03 | 48 | |
lukofsky | 1:df1ae6d3fd03 | 49 | // --- constants and global variables for SS --- |
lukofsky | 1:df1ae6d3fd03 | 50 | |
lukofsky | 1:df1ae6d3fd03 | 51 | // constants for transfer function for SS |
lukofsky | 1:df1ae6d3fd03 | 52 | // note: when extracting constants, having more decimal places is more accurate |
lukofsky | 1:df1ae6d3fd03 | 53 | // H(z) = a0 + a1*z^-1 + a2*z^-2 + a3*z^-3 + a4*z^-4 + a5*z^-5 |
lukofsky | 1:df1ae6d3fd03 | 54 | // ------------------------------------------------------ |
lukofsky | 1:df1ae6d3fd03 | 55 | // b0 + b1*z^-1 + b2*z^-2 + b3*z^-3 + b4*z^-4 + b5*z^-5 |
lukofsky | 1:df1ae6d3fd03 | 56 | |
lukofsky | 1:df1ae6d3fd03 | 57 | // for fs = 198 kHz: (samp_period = 20 with prescaler = 23) |
lukofsky | 1:df1ae6d3fd03 | 58 | //const float a0 = 2.347062E-05; |
lukofsky | 1:df1ae6d3fd03 | 59 | //const float a1 = 2.442144E-05; |
lukofsky | 1:df1ae6d3fd03 | 60 | //const float a2 = -4.408877E-05; |
lukofsky | 1:df1ae6d3fd03 | 61 | //const float a3 = -4.408877E-05; |
lukofsky | 1:df1ae6d3fd03 | 62 | //const float a4 = 2.442144E-05; |
lukofsky | 1:df1ae6d3fd03 | 63 | //const float a5 = 2.347062E-05; |
lukofsky | 1:df1ae6d3fd03 | 64 | //const float b0 = 1.0; |
lukofsky | 1:df1ae6d3fd03 | 65 | //const float b1 = -3.065112; |
lukofsky | 1:df1ae6d3fd03 | 66 | //const float b2 = 2.320246; |
lukofsky | 1:df1ae6d3fd03 | 67 | //const float b3 = 1.468017; |
lukofsky | 1:df1ae6d3fd03 | 68 | //const float b4 = -2.636283; |
lukofsky | 1:df1ae6d3fd03 | 69 | //const float b5 = 9.131404E-01; |
lukofsky | 1:df1ae6d3fd03 | 70 | |
lukofsky | 1:df1ae6d3fd03 | 71 | const float gain_adj_ss=-.4; //set gain adjustment to lock mirrors |
lukofsky | 1:df1ae6d3fd03 | 72 | |
lukofsky | 1:df1ae6d3fd03 | 73 | // for fs = 182 kHz: (samp_period = 21 with prescaler = 24) |
lukofsky | 1:df1ae6d3fd03 | 74 | float a0 = 2.790071E-5; |
lukofsky | 1:df1ae6d3fd03 | 75 | float a1 = 2.923599E-5; |
lukofsky | 1:df1ae6d3fd03 | 76 | float a2 = -5.179560E-5; |
lukofsky | 1:df1ae6d3fd03 | 77 | float a3 = -5.179560E-5; |
lukofsky | 1:df1ae6d3fd03 | 78 | float a4 = 2.923599E-5; |
lukofsky | 1:df1ae6d3fd03 | 79 | float a5 = 2.790071E-5; |
lukofsky | 1:df1ae6d3fd03 | 80 | float b0 = 1.0; |
lukofsky | 1:df1ae6d3fd03 | 81 | float b1 = -3.054730; |
lukofsky | 1:df1ae6d3fd03 | 82 | float b2 = 2.289613; |
lukofsky | 1:df1ae6d3fd03 | 83 | float b3 = 1.504730; |
lukofsky | 1:df1ae6d3fd03 | 84 | float b4 = -2.659329; |
lukofsky | 1:df1ae6d3fd03 | 85 | float b5 = 0.919726; |
lukofsky | 1:df1ae6d3fd03 | 86 | |
lukofsky | 1:df1ae6d3fd03 | 87 | // filter's input and output arrays |
lukofsky | 1:df1ae6d3fd03 | 88 | |
lukofsky | 1:df1ae6d3fd03 | 89 | int x_ss0 = 0; |
lukofsky | 1:df1ae6d3fd03 | 90 | int x_ss1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 91 | int x_ss2 = 0; |
lukofsky | 1:df1ae6d3fd03 | 92 | int x_ss3 = 0; |
lukofsky | 1:df1ae6d3fd03 | 93 | int x_ss4 = 0; |
lukofsky | 1:df1ae6d3fd03 | 94 | int x_ss5 = 0; |
lukofsky | 1:df1ae6d3fd03 | 95 | |
lukofsky | 1:df1ae6d3fd03 | 96 | |
lukofsky | 1:df1ae6d3fd03 | 97 | float y_ss0 = 0; |
lukofsky | 1:df1ae6d3fd03 | 98 | float y_ss1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 99 | float y_ss2 = 0; |
lukofsky | 1:df1ae6d3fd03 | 100 | float y_ss3 = 0; |
lukofsky | 1:df1ae6d3fd03 | 101 | float y_ss4 = 0; |
lukofsky | 1:df1ae6d3fd03 | 102 | float y_ss5 = 0; |
lukofsky | 1:df1ae6d3fd03 | 103 | |
lukofsky | 1:df1ae6d3fd03 | 104 | int i2 =0; |
lukofsky | 1:df1ae6d3fd03 | 105 | |
lukofsky | 1:df1ae6d3fd03 | 106 | // --- constants and global variables for FS --- |
lukofsky | 1:df1ae6d3fd03 | 107 | |
lukofsky | 1:df1ae6d3fd03 | 108 | // constants for transfer function for FS |
lukofsky | 1:df1ae6d3fd03 | 109 | // note: when extracting constants, having more decimal places is more accurate |
lukofsky | 1:df1ae6d3fd03 | 110 | // H(z) = c0 + c1*z^-1 + c2*z^-2 |
lukofsky | 1:df1ae6d3fd03 | 111 | // ------------------------ |
lukofsky | 1:df1ae6d3fd03 | 112 | // d0 + d1*z^-1 + d2*z^-2 |
lukofsky | 1:df1ae6d3fd03 | 113 | |
lukofsky | 1:df1ae6d3fd03 | 114 | // for fs = 198 kHz prewarped & scaled: (samp_period = 20 with prescaler = 23) |
lukofsky | 1:df1ae6d3fd03 | 115 | //const float c0 = 1.216980E-02; |
lukofsky | 1:df1ae6d3fd03 | 116 | //const float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 117 | //const float c2 = -1.216980E-02; |
lukofsky | 1:df1ae6d3fd03 | 118 | //const float d0 = 1.0; |
lukofsky | 1:df1ae6d3fd03 | 119 | //const float d1 = -1.366137; |
lukofsky | 1:df1ae6d3fd03 | 120 | //const float d2 = 9.997566E-01; |
lukofsky | 1:df1ae6d3fd03 | 121 | |
lukofsky | 1:df1ae6d3fd03 | 122 | |
lukofsky | 1:df1ae6d3fd03 | 123 | //198kHz, Q = 1000 |
lukofsky | 1:df1ae6d3fd03 | 124 | //float c0 = 3.650050e-02; |
lukofsky | 1:df1ae6d3fd03 | 125 | //float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 126 | //float c2 = -3.650050e-02; |
lukofsky | 1:df1ae6d3fd03 | 127 | //float d0 = 1; |
lukofsky | 1:df1ae6d3fd03 | 128 | //float d1 = -1.365804e+00; |
lukofsky | 1:df1ae6d3fd03 | 129 | //float d2 = 9.992700e-01; |
lukofsky | 1:df1ae6d3fd03 | 130 | |
lukofsky | 1:df1ae6d3fd03 | 131 | //198kHz, Q = 500 |
lukofsky | 1:df1ae6d3fd03 | 132 | //float c0 = 7.297437e-02; |
lukofsky | 1:df1ae6d3fd03 | 133 | //float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 134 | //float c2 = -7.297437e-02; |
lukofsky | 1:df1ae6d3fd03 | 135 | //float d0 = 1; |
lukofsky | 1:df1ae6d3fd03 | 136 | //float d1 = -1.365306e+00; |
lukofsky | 1:df1ae6d3fd03 | 137 | //float d2 = 9.985405e-01; |
lukofsky | 1:df1ae6d3fd03 | 138 | |
lukofsky | 1:df1ae6d3fd03 | 139 | //198kHz, Q = 100 |
lukofsky | 1:df1ae6d3fd03 | 140 | //float c0 = 3.638099e-01; |
lukofsky | 1:df1ae6d3fd03 | 141 | //float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 142 | //float c2 = -3.638099e-01; |
lukofsky | 1:df1ae6d3fd03 | 143 | //float d0 = 1; |
lukofsky | 1:df1ae6d3fd03 | 144 | //float d1 = -1.361332e+00; |
lukofsky | 1:df1ae6d3fd03 | 145 | //float d2 = 9.927238e-01; |
lukofsky | 1:df1ae6d3fd03 | 146 | |
lukofsky | 1:df1ae6d3fd03 | 147 | //198kHz, Q = 10 |
lukofsky | 1:df1ae6d3fd03 | 148 | //float c0 = 3.522754e+00; |
lukofsky | 1:df1ae6d3fd03 | 149 | //float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 150 | //float c2 = -3.522754e+00; |
lukofsky | 1:df1ae6d3fd03 | 151 | //float d0 = 1; |
lukofsky | 1:df1ae6d3fd03 | 152 | //float d1 = -1.318172e+00; |
lukofsky | 1:df1ae6d3fd03 | 153 | //float d2 = 9.295449e-01; |
lukofsky | 1:df1ae6d3fd03 | 154 | |
lukofsky | 1:df1ae6d3fd03 | 155 | |
lukofsky | 1:df1ae6d3fd03 | 156 | //265kHz, Q = 3000 |
lukofsky | 1:df1ae6d3fd03 | 157 | //float c0 = 9.570427e-03; |
lukofsky | 1:df1ae6d3fd03 | 158 | //float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 159 | //float c2 = -9.570427e-03; |
lukofsky | 1:df1ae6d3fd03 | 160 | //float d0 = 1; |
lukofsky | 1:df1ae6d3fd03 | 161 | //float d1 = -1.637160e+00; |
lukofsky | 1:df1ae6d3fd03 | 162 | //float d2 = 9.998086e-01; |
lukofsky | 1:df1ae6d3fd03 | 163 | |
lukofsky | 1:df1ae6d3fd03 | 164 | //265kHz, Q = 1000 |
lukofsky | 1:df1ae6d3fd03 | 165 | //float c0 = 2.870579e-02; |
lukofsky | 1:df1ae6d3fd03 | 166 | //float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 167 | //float c2 = -2.870579e-02; |
lukofsky | 1:df1ae6d3fd03 | 168 | //float d0 = 1; |
lukofsky | 1:df1ae6d3fd03 | 169 | //float d1 = -1.636847e+00; |
lukofsky | 1:df1ae6d3fd03 | 170 | //float d2 = 9.994259e-01; |
lukofsky | 1:df1ae6d3fd03 | 171 | |
lukofsky | 1:df1ae6d3fd03 | 172 | //265kHz, Q = 500 |
lukofsky | 1:df1ae6d3fd03 | 173 | //float c0 = 5.739510e-02; |
lukofsky | 1:df1ae6d3fd03 | 174 | //float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 175 | //float c2 = -5.739510e-02; |
lukofsky | 1:df1ae6d3fd03 | 176 | //float d0 = 1; |
lukofsky | 1:df1ae6d3fd03 | 177 | //float d1 = -1.636377e+00; |
lukofsky | 1:df1ae6d3fd03 | 178 | //float d2 = 9.988521e-01; |
lukofsky | 1:df1ae6d3fd03 | 179 | |
lukofsky | 1:df1ae6d3fd03 | 180 | //Elena's |
lukofsky | 1:df1ae6d3fd03 | 181 | // fr=2.8kHz, Q=1000, fs=277,778 z |
lukofsky | 1:df1ae6d3fd03 | 182 | //float c0 = 0.08273001473594155; |
lukofsky | 1:df1ae6d3fd03 | 183 | // |
lukofsky | 1:df1ae6d3fd03 | 184 | //float c1 = 0.16546002947188265; |
lukofsky | 1:df1ae6d3fd03 | 185 | // |
lukofsky | 1:df1ae6d3fd03 | 186 | //float c2 = 0.08273001473594155; |
lukofsky | 1:df1ae6d3fd03 | 187 | // |
lukofsky | 1:df1ae6d3fd03 | 188 | //float d0 = 1.0; |
lukofsky | 1:df1ae6d3fd03 | 189 | // |
lukofsky | 1:df1ae6d3fd03 | 190 | //float d1 = -1.6685290763800154; |
lukofsky | 1:df1ae6d3fd03 | 191 | // |
lukofsky | 1:df1ae6d3fd03 | 192 | //float d2 = 0.9994491353237815; |
lukofsky | 1:df1ae6d3fd03 | 193 | |
lukofsky | 1:df1ae6d3fd03 | 194 | |
lukofsky | 1:df1ae6d3fd03 | 195 | //@277,778 Hz Fs |
lukofsky | 1:df1ae6d3fd03 | 196 | //float c0 = 0.08274520854011191; |
lukofsky | 1:df1ae6d3fd03 | 197 | // |
lukofsky | 1:df1ae6d3fd03 | 198 | //float c1 = 0.16549041708022338; |
lukofsky | 1:df1ae6d3fd03 | 199 | // |
lukofsky | 1:df1ae6d3fd03 | 200 | //float c2 = 0.08274520854011225; |
lukofsky | 1:df1ae6d3fd03 | 201 | // |
lukofsky | 1:df1ae6d3fd03 | 202 | //float d0 = 1.0; |
lukofsky | 1:df1ae6d3fd03 | 203 | // |
lukofsky | 1:df1ae6d3fd03 | 204 | //float d1 = -1.6688355105577437; |
lukofsky | 1:df1ae6d3fd03 | 205 | // |
lukofsky | 1:df1ae6d3fd03 | 206 | //float d2 = 0.999816344718191; |
lukofsky | 1:df1ae6d3fd03 | 207 | |
lukofsky | 1:df1ae6d3fd03 | 208 | float gain_adj_fs= 2*2*(.25*(.5*(.5*(.25*.29))))/5;// (1/atteunation relative to 10x)(multiplier)(starting point) ///.9*.029; //set final gain adjustment to lock mirrors. Targets In/Out ratio of .82 @26kHz (to match Prototype) |
lukofsky | 1:df1ae6d3fd03 | 209 | //most stable prior to hpzr attenuator addition 2*(.25*(.5*(.5*(.25*.29))))/5; |
lukofsky | 1:df1ae6d3fd03 | 210 | //most stable in general, w/ attenuator 2*2*(.25*(.5*(.5*(.25*.29))))/5; |
lukofsky | 1:df1ae6d3fd03 | 211 | |
lukofsky | 1:df1ae6d3fd03 | 212 | //float gain_adj_fs=.002; |
lukofsky | 1:df1ae6d3fd03 | 213 | |
lukofsky | 1:df1ae6d3fd03 | 214 | // for fs = 182 kHz, Q=3000 prewarped & scaled: (samp_period = 21 with prescaler = 24) |
lukofsky | 1:df1ae6d3fd03 | 215 | //float c0 = 0.0129569; |
lukofsky | 1:df1ae6d3fd03 | 216 | //float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 217 | //float c2 = -0.0129569; |
lukofsky | 1:df1ae6d3fd03 | 218 | //float d0 = 1.0; |
lukofsky | 1:df1ae6d3fd03 | 219 | //float d1 = -1.257566; |
lukofsky | 1:df1ae6d3fd03 | 220 | //float d2 = 0.999741; |
lukofsky | 1:df1ae6d3fd03 | 221 | |
lukofsky | 1:df1ae6d3fd03 | 222 | |
lukofsky | 1:df1ae6d3fd03 | 223 | // for fs = 182000, Q=100 |
lukofsky | 1:df1ae6d3fd03 | 224 | float c0 = 3.872520e-01; |
lukofsky | 1:df1ae6d3fd03 | 225 | float c1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 226 | float c2 = -3.872520e-01; |
lukofsky | 1:df1ae6d3fd03 | 227 | float d0 = 1; |
lukofsky | 1:df1ae6d3fd03 | 228 | float d1 = -1.252858e+00; |
lukofsky | 1:df1ae6d3fd03 | 229 | float d2 = 9.922550e-01; |
lukofsky | 1:df1ae6d3fd03 | 230 | |
lukofsky | 1:df1ae6d3fd03 | 231 | |
lukofsky | 1:df1ae6d3fd03 | 232 | // filter's input and output arrays |
lukofsky | 1:df1ae6d3fd03 | 233 | int x_fs0 = 0; |
lukofsky | 1:df1ae6d3fd03 | 234 | int x_fs1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 235 | int x_fs2 = 0; |
lukofsky | 1:df1ae6d3fd03 | 236 | int x_fs3 = 0; |
lukofsky | 1:df1ae6d3fd03 | 237 | |
lukofsky | 1:df1ae6d3fd03 | 238 | float y_fs0 = 0; |
lukofsky | 1:df1ae6d3fd03 | 239 | float y_fs1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 240 | float y_fs2 = 0; |
lukofsky | 1:df1ae6d3fd03 | 241 | float y_fs3 = 0; |
lukofsky | 1:df1ae6d3fd03 | 242 | |
lukofsky | 1:df1ae6d3fd03 | 243 | // --- FUNCTIONS --- |
lukofsky | 1:df1ae6d3fd03 | 244 | |
lukofsky | 1:df1ae6d3fd03 | 245 | // --- functions for handling TIM2 initialization to control sampling rate --- |
lukofsky | 1:df1ae6d3fd03 | 246 | |
lukofsky | 1:df1ae6d3fd03 | 247 | //void SysTick_Handler(void) |
lukofsky | 1:df1ae6d3fd03 | 248 | //{ |
lukofsky | 1:df1ae6d3fd03 | 249 | // HAL_IncTick(); |
lukofsky | 1:df1ae6d3fd03 | 250 | // HAL_SYSTICK_IRQHandler(); |
lukofsky | 1:df1ae6d3fd03 | 251 | //} |
lukofsky | 1:df1ae6d3fd03 | 252 | // |
lukofsky | 1:df1ae6d3fd03 | 253 | //// --- end functions for TIM2 --- |
lukofsky | 1:df1ae6d3fd03 | 254 | |
lukofsky | 1:df1ae6d3fd03 | 255 | |
lukofsky | 1:df1ae6d3fd03 | 256 | |
lukofsky | 1:df1ae6d3fd03 | 257 | /** reads external ADC from SPI |
lukofsky | 1:df1ae6d3fd03 | 258 | * @param cs (chip select pin) |
lukofsky | 1:df1ae6d3fd03 | 259 | * @returns ADC input value (range from -2048 to 2047) |
lukofsky | 1:df1ae6d3fd03 | 260 | */ |
lukofsky | 1:df1ae6d3fd03 | 261 | |
lukofsky | 1:df1ae6d3fd03 | 262 | int input = 0; |
lukofsky | 1:df1ae6d3fd03 | 263 | int read_adc(DigitalOut cs){ |
lukofsky | 1:df1ae6d3fd03 | 264 | input = 0; |
lukofsky | 1:df1ae6d3fd03 | 265 | |
lukofsky | 1:df1ae6d3fd03 | 266 | // select external adc |
lukofsky | 1:df1ae6d3fd03 | 267 | cs = 0; |
lukofsky | 1:df1ae6d3fd03 | 268 | |
lukofsky | 1:df1ae6d3fd03 | 269 | // send dummy byte to receive ADC read |
lukofsky | 1:df1ae6d3fd03 | 270 | uint16_t adc_read = spi.write(0x0); |
lukofsky | 1:df1ae6d3fd03 | 271 | // pc.printf("ADC = %X ", adc_read); // for debug |
lukofsky | 1:df1ae6d3fd03 | 272 | |
lukofsky | 1:df1ae6d3fd03 | 273 | // deselect external adc |
lukofsky | 1:df1ae6d3fd03 | 274 | cs = 1; |
lukofsky | 1:df1ae6d3fd03 | 275 | |
lukofsky | 1:df1ae6d3fd03 | 276 | // bit shift adc_input for 12-bit resolution |
lukofsky | 1:df1ae6d3fd03 | 277 | uint16_t input_temp = adc_read >> 3; |
lukofsky | 1:df1ae6d3fd03 | 278 | |
lukofsky | 1:df1ae6d3fd03 | 279 | // convert uint16_t to int using two's complement for Differential ADC (not used anymore) |
lukofsky | 1:df1ae6d3fd03 | 280 | // if ((input_temp & 0x800) == 0x800) { // check if sign bit is raised (i.e. neg value) |
lukofsky | 1:df1ae6d3fd03 | 281 | // input_temp = ~(input_temp-1); // convert from two's complement form |
lukofsky | 1:df1ae6d3fd03 | 282 | // input = -1*(input_temp^0xF000); // mask input_temp for 12 bits & add sign back in |
lukofsky | 1:df1ae6d3fd03 | 283 | // } else { |
lukofsky | 1:df1ae6d3fd03 | 284 | // input = input_temp; // no action if sign bit is not raised (i.e. pos value) |
lukofsky | 1:df1ae6d3fd03 | 285 | // } |
lukofsky | 1:df1ae6d3fd03 | 286 | |
lukofsky | 1:df1ae6d3fd03 | 287 | |
lukofsky | 1:df1ae6d3fd03 | 288 | //Assuming non-differential ADC (AD7046) |
lukofsky | 1:df1ae6d3fd03 | 289 | input = input_temp; // no action if sign bit is not raised (i.e. pos value) |
lukofsky | 1:df1ae6d3fd03 | 290 | |
lukofsky | 1:df1ae6d3fd03 | 291 | return input; |
lukofsky | 1:df1ae6d3fd03 | 292 | } |
lukofsky | 1:df1ae6d3fd03 | 293 | |
lukofsky | 1:df1ae6d3fd03 | 294 | /** computes and writes SS output to DAC based on SS difference eqn using ADC input |
lukofsky | 1:df1ae6d3fd03 | 295 | * @returns none |
lukofsky | 1:df1ae6d3fd03 | 296 | */ |
lukofsky | 1:df1ae6d3fd03 | 297 | void compute_ss_output(){ |
lukofsky | 1:df1ae6d3fd03 | 298 | |
lukofsky | 1:df1ae6d3fd03 | 299 | // shift inputs for new time step |
lukofsky | 1:df1ae6d3fd03 | 300 | x_ss5 = x_ss4; // x[n-4] --> x[n-5] |
lukofsky | 1:df1ae6d3fd03 | 301 | x_ss4 = x_ss3; // x[n-3] --> x[n-4] |
lukofsky | 1:df1ae6d3fd03 | 302 | x_ss3 = x_ss2; // x[n-2] --> x[n-3] |
lukofsky | 1:df1ae6d3fd03 | 303 | x_ss2 = x_ss1; // x[n-1] --> x[n-2] |
lukofsky | 1:df1ae6d3fd03 | 304 | x_ss1 = x_ss0; // x[n] --> x[n-1] |
lukofsky | 1:df1ae6d3fd03 | 305 | |
lukofsky | 1:df1ae6d3fd03 | 306 | //shift outputs for new time step |
lukofsky | 1:df1ae6d3fd03 | 307 | y_ss5 = y_ss4; // y[n-4] --> y[n-5] |
lukofsky | 1:df1ae6d3fd03 | 308 | y_ss4 = y_ss3; // y[n-3] --> y[n-4] |
lukofsky | 1:df1ae6d3fd03 | 309 | y_ss3 = y_ss2; // y[n-2] --> y[n-3] |
lukofsky | 1:df1ae6d3fd03 | 310 | y_ss2 = y_ss1; // y[n-1] --> y[n-2] |
lukofsky | 1:df1ae6d3fd03 | 311 | y_ss1 = y_ss0; // y[n] --> y[n-1] |
lukofsky | 1:df1ae6d3fd03 | 312 | |
lukofsky | 1:df1ae6d3fd03 | 313 | // read input x[n] from SS DRV P |
lukofsky | 1:df1ae6d3fd03 | 314 | x_ss0 = read_adc(cs_ss); // value from 0 to 4095 for 12-bit ADC |
lukofsky | 1:df1ae6d3fd03 | 315 | // pc.printf("ADC = %d ", x_ss[0]); // for debug |
lukofsky | 1:df1ae6d3fd03 | 316 | |
lukofsky | 1:df1ae6d3fd03 | 317 | // for verifying impulse response |
lukofsky | 1:df1ae6d3fd03 | 318 | // "read" input x[n] (internal input read) |
lukofsky | 1:df1ae6d3fd03 | 319 | // if (outputimpulse > 0) { |
lukofsky | 1:df1ae6d3fd03 | 320 | // x_ss[0] = 2047; |
lukofsky | 1:df1ae6d3fd03 | 321 | // outputimpulse = outputimpulse - 1; |
lukofsky | 1:df1ae6d3fd03 | 322 | // } else { |
lukofsky | 1:df1ae6d3fd03 | 323 | // x_ss[0] = 0; |
lukofsky | 1:df1ae6d3fd03 | 324 | // } |
lukofsky | 1:df1ae6d3fd03 | 325 | |
lukofsky | 1:df1ae6d3fd03 | 326 | // calculate output y[n] (need intermediary computations to prevent overflow) |
lukofsky | 1:df1ae6d3fd03 | 327 | float xterms = a0*x_ss0+a1*x_ss1+a2*x_ss2+a3*x_ss3+a4*x_ss4+a5*x_ss5; |
lukofsky | 1:df1ae6d3fd03 | 328 | float yterms = b1*y_ss1+b2*y_ss2+b3*y_ss3+b4*y_ss4+b5*y_ss5; |
lukofsky | 1:df1ae6d3fd03 | 329 | y_ss0 = (xterms - yterms); // *1/b0 |
lukofsky | 1:df1ae6d3fd03 | 330 | |
lukofsky | 1:df1ae6d3fd03 | 331 | // pc.printf("xterms = %f ", xterms); |
lukofsky | 1:df1ae6d3fd03 | 332 | // pc.printf("yterms = %f ", yterms); |
lukofsky | 1:df1ae6d3fd03 | 333 | // pc.printf("y[0] = %f ", y[0]); |
lukofsky | 1:df1ae6d3fd03 | 334 | |
lukofsky | 1:df1ae6d3fd03 | 335 | // --- for writing DAC output directly to register --- |
lukofsky | 1:df1ae6d3fd03 | 336 | |
lukofsky | 1:df1ae6d3fd03 | 337 | // scale y[n], then bias y[n] at VCC/2 = 1.25V and scale gain |
lukofsky | 1:df1ae6d3fd03 | 338 | uint16_t output = (uint16_t) (gain_adj_ss*y_ss0+2048); |
lukofsky | 1:df1ae6d3fd03 | 339 | // pc.printf(" %d ",output); |
lukofsky | 1:df1ae6d3fd03 | 340 | |
lukofsky | 1:df1ae6d3fd03 | 341 | // set DAC output by writing directly to register (pin PA_5) |
lukofsky | 1:df1ae6d3fd03 | 342 | // note: DAC register takes in unsigned 12-bit (i.e. 0 to 4096) |
lukofsky | 1:df1ae6d3fd03 | 343 | DAC->DHR12R2 = output; |
lukofsky | 1:df1ae6d3fd03 | 344 | |
lukofsky | 1:df1ae6d3fd03 | 345 | |
lukofsky | 1:df1ae6d3fd03 | 346 | |
lukofsky | 1:df1ae6d3fd03 | 347 | // - end - |
lukofsky | 1:df1ae6d3fd03 | 348 | // myled1 = !myled1; |
lukofsky | 1:df1ae6d3fd03 | 349 | } |
lukofsky | 1:df1ae6d3fd03 | 350 | |
lukofsky | 1:df1ae6d3fd03 | 351 | /** computes and writes FS output to DAC based on FS difference eqn using ADC input |
lukofsky | 1:df1ae6d3fd03 | 352 | * @returns none |
lukofsky | 1:df1ae6d3fd03 | 353 | */ |
lukofsky | 1:df1ae6d3fd03 | 354 | |
lukofsky | 1:df1ae6d3fd03 | 355 | uint16_t output=2048; |
lukofsky | 1:df1ae6d3fd03 | 356 | void compute_fs_output(){ |
lukofsky | 1:df1ae6d3fd03 | 357 | //myled1 = !myled1; |
lukofsky | 1:df1ae6d3fd03 | 358 | DAC->DHR12R1 = output; |
lukofsky | 1:df1ae6d3fd03 | 359 | // myled1 = !myled1; |
lukofsky | 1:df1ae6d3fd03 | 360 | // shift inputs for new time step |
lukofsky | 1:df1ae6d3fd03 | 361 | x_fs2 = x_fs1; // x[n-1] --> x[n-2] |
lukofsky | 1:df1ae6d3fd03 | 362 | x_fs1 = x_fs0; // x[n] --> x[n-1] |
lukofsky | 1:df1ae6d3fd03 | 363 | |
lukofsky | 1:df1ae6d3fd03 | 364 | //shift outputs for new time step |
lukofsky | 1:df1ae6d3fd03 | 365 | y_fs2 = y_fs1; // y[n-1] --> y[n-2] |
lukofsky | 1:df1ae6d3fd03 | 366 | y_fs1 = y_fs0; // y[n] --> y[n-1] |
lukofsky | 1:df1ae6d3fd03 | 367 | |
lukofsky | 1:df1ae6d3fd03 | 368 | // read input x[n] - ONLY READ FROM OUTPUT_P (not N) |
lukofsky | 1:df1ae6d3fd03 | 369 | x_fs0 = read_adc(cs_fs); // value from -2048 to 2047 for 12-bit ADC |
lukofsky | 1:df1ae6d3fd03 | 370 | // pc.printf("ADC = %d ", x_fs[0]); // for debug |
lukofsky | 1:df1ae6d3fd03 | 371 | //DAC->DHR12R1 = (uint16_t) (x_fs[0]); //debug |
lukofsky | 1:df1ae6d3fd03 | 372 | |
lukofsky | 1:df1ae6d3fd03 | 373 | |
lukofsky | 1:df1ae6d3fd03 | 374 | |
lukofsky | 1:df1ae6d3fd03 | 375 | // calculate output y[n] (need intermediary computations to prevent overflow) |
lukofsky | 1:df1ae6d3fd03 | 376 | // float xterms = c0*x_fs[0]+c1*x_fs[1]+c2*x_fs[2]; // explicit c1 = 0 |
lukofsky | 1:df1ae6d3fd03 | 377 | float xterms = c0*x_fs0+c2*x_fs2; // implicit c1 = 0 |
lukofsky | 1:df1ae6d3fd03 | 378 | float yterms = d1*y_fs1+d2*y_fs2; |
lukofsky | 1:df1ae6d3fd03 | 379 | y_fs0 = (xterms - yterms); // *1/d0 |
lukofsky | 1:df1ae6d3fd03 | 380 | |
lukofsky | 1:df1ae6d3fd03 | 381 | |
lukofsky | 1:df1ae6d3fd03 | 382 | |
lukofsky | 1:df1ae6d3fd03 | 383 | |
lukofsky | 1:df1ae6d3fd03 | 384 | // --- for writing DAC output directly to register --- |
lukofsky | 1:df1ae6d3fd03 | 385 | |
lukofsky | 1:df1ae6d3fd03 | 386 | // scale y[n], then bias y[n] at VCC/2 = 1.25V and scale gain |
lukofsky | 1:df1ae6d3fd03 | 387 | output = (uint16_t) (gain_adj_fs*y_fs0+2048); |
lukofsky | 1:df1ae6d3fd03 | 388 | // pc.printf(" %d ",output); |
lukofsky | 1:df1ae6d3fd03 | 389 | |
lukofsky | 1:df1ae6d3fd03 | 390 | |
lukofsky | 1:df1ae6d3fd03 | 391 | // set DAC output by writing directly to register (pin PA_4) |
lukofsky | 1:df1ae6d3fd03 | 392 | // note: DAC register takes in unsigned 12-bit (i.e. 0 to 4096) |
lukofsky | 1:df1ae6d3fd03 | 393 | //DAC->DHR12R1 = output; |
lukofsky | 1:df1ae6d3fd03 | 394 | |
lukofsky | 1:df1ae6d3fd03 | 395 | |
lukofsky | 1:df1ae6d3fd03 | 396 | } |
lukofsky | 1:df1ae6d3fd03 | 397 | |
lukofsky | 1:df1ae6d3fd03 | 398 | |
lukofsky | 1:df1ae6d3fd03 | 399 | |
lukofsky | 1:df1ae6d3fd03 | 400 | |
lukofsky | 1:df1ae6d3fd03 | 401 | TIM_HandleTypeDef mTimUserHandle; |
lukofsky | 1:df1ae6d3fd03 | 402 | int iteration1=0; |
lukofsky | 1:df1ae6d3fd03 | 403 | int iteration2=0; |
lukofsky | 1:df1ae6d3fd03 | 404 | extern "C" |
lukofsky | 1:df1ae6d3fd03 | 405 | void M_TIM_USR_Handler(void) { |
lukofsky | 1:df1ae6d3fd03 | 406 | //myled1 = 0;//!myled1; |
lukofsky | 1:df1ae6d3fd03 | 407 | |
lukofsky | 1:df1ae6d3fd03 | 408 | if (__HAL_TIM_GET_FLAG(&mTimUserHandle, TIM_FLAG_UPDATE) == SET) { |
lukofsky | 1:df1ae6d3fd03 | 409 | |
lukofsky | 1:df1ae6d3fd03 | 410 | myled1 = 1;//!myled1; |
lukofsky | 1:df1ae6d3fd03 | 411 | __HAL_TIM_CLEAR_FLAG(&mTimUserHandle, TIM_FLAG_UPDATE); |
lukofsky | 1:df1ae6d3fd03 | 412 | |
lukofsky | 1:df1ae6d3fd03 | 413 | //for(int i = 0; i < 17; i++){ |
lukofsky | 1:df1ae6d3fd03 | 414 | // myled1 = !myled1; |
lukofsky | 1:df1ae6d3fd03 | 415 | |
lukofsky | 1:df1ae6d3fd03 | 416 | |
lukofsky | 1:df1ae6d3fd03 | 417 | // } |
lukofsky | 1:df1ae6d3fd03 | 418 | |
lukofsky | 1:df1ae6d3fd03 | 419 | compute_fs_output(); |
lukofsky | 1:df1ae6d3fd03 | 420 | compute_ss_output(); |
lukofsky | 1:df1ae6d3fd03 | 421 | myled1=0; |
lukofsky | 1:df1ae6d3fd03 | 422 | |
lukofsky | 1:df1ae6d3fd03 | 423 | //if (__HAL_TIM_GET_FLAG(&mTimUserHandle, TIM_FLAG_UPDATE) == SET) { |
lukofsky | 1:df1ae6d3fd03 | 424 | // myled1 = !myled1; |
lukofsky | 1:df1ae6d3fd03 | 425 | // } |
lukofsky | 1:df1ae6d3fd03 | 426 | } |
lukofsky | 1:df1ae6d3fd03 | 427 | } |
lukofsky | 1:df1ae6d3fd03 | 428 | |
lukofsky | 1:df1ae6d3fd03 | 429 | |
lukofsky | 1:df1ae6d3fd03 | 430 | int main() |
lukofsky | 1:df1ae6d3fd03 | 431 | { |
lukofsky | 1:df1ae6d3fd03 | 432 | // set serial debug baud rate |
lukofsky | 1:df1ae6d3fd03 | 433 | // pc.baud(9600); |
lukofsky | 1:df1ae6d3fd03 | 434 | |
lukofsky | 1:df1ae6d3fd03 | 435 | // deselect external adcs |
lukofsky | 1:df1ae6d3fd03 | 436 | cs_ss = 1; |
lukofsky | 1:df1ae6d3fd03 | 437 | cs_fs = 1; |
lukofsky | 1:df1ae6d3fd03 | 438 | |
lukofsky | 1:df1ae6d3fd03 | 439 | // set up spi |
lukofsky | 1:df1ae6d3fd03 | 440 | spi.format(16,3); |
lukofsky | 1:df1ae6d3fd03 | 441 | spi.frequency(50000000); // 50MHz (fastest possible with ADC) |
lukofsky | 1:df1ae6d3fd03 | 442 | |
lukofsky | 1:df1ae6d3fd03 | 443 | // LED sequence to indicate code uploaded |
lukofsky | 1:df1ae6d3fd03 | 444 | for(int i = 0; i < 10; i++){ |
lukofsky | 1:df1ae6d3fd03 | 445 | myled1 = i & 0x1; |
lukofsky | 1:df1ae6d3fd03 | 446 | wait(0.1); |
lukofsky | 1:df1ae6d3fd03 | 447 | } |
lukofsky | 1:df1ae6d3fd03 | 448 | |
lukofsky | 1:df1ae6d3fd03 | 449 | |
lukofsky | 1:df1ae6d3fd03 | 450 | // initialize timer TIM2 |
lukofsky | 1:df1ae6d3fd03 | 451 | __HAL_RCC_TIM2_CLK_ENABLE(); |
lukofsky | 1:df1ae6d3fd03 | 452 | |
lukofsky | 1:df1ae6d3fd03 | 453 | mTimUserHandle.Instance = TIM_USR; |
lukofsky | 1:df1ae6d3fd03 | 454 | mTimUserHandle.Init.Prescaler = 0; |
lukofsky | 1:df1ae6d3fd03 | 455 | mTimUserHandle.Init.CounterMode = TIM_COUNTERMODE_UP; |
lukofsky | 1:df1ae6d3fd03 | 456 | mTimUserHandle.Init.Period = 549; //549 FOR 182KHz //504 for 198kHz, 359 for 277khz |
lukofsky | 1:df1ae6d3fd03 | 457 | mTimUserHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; |
lukofsky | 1:df1ae6d3fd03 | 458 | HAL_TIM_Base_Init(&mTimUserHandle); |
lukofsky | 1:df1ae6d3fd03 | 459 | HAL_TIM_Base_Start_IT(&mTimUserHandle); |
lukofsky | 1:df1ae6d3fd03 | 460 | |
lukofsky | 1:df1ae6d3fd03 | 461 | NVIC_SetVector(TIM_USR_IRQ, (uint32_t)M_TIM_USR_Handler); |
lukofsky | 1:df1ae6d3fd03 | 462 | NVIC_EnableIRQ(TIM_USR_IRQ); |
lukofsky | 1:df1ae6d3fd03 | 463 | |
lukofsky | 1:df1ae6d3fd03 | 464 | |
lukofsky | 1:df1ae6d3fd03 | 465 | //pc.printf("\nstarting ss_rlc\n"); |
lukofsky | 1:df1ae6d3fd03 | 466 | |
lukofsky | 1:df1ae6d3fd03 | 467 | // to read system clock (max at 100MHz) |
lukofsky | 1:df1ae6d3fd03 | 468 | // SystemCoreClock = 125000000; // set CPU clk (can overclock to 125MHz max) |
lukofsky | 1:df1ae6d3fd03 | 469 | //pc.printf("SystemCoreClock = %d", SystemCoreClock); |
lukofsky | 1:df1ae6d3fd03 | 470 | // |
lukofsky | 1:df1ae6d3fd03 | 471 | //uint16_t dac_out=0; |
lukofsky | 1:df1ae6d3fd03 | 472 | //uint16_t output = (uint16_t) (4000); |
lukofsky | 1:df1ae6d3fd03 | 473 | while(1) { |
lukofsky | 1:df1ae6d3fd03 | 474 | myled1 = 1; |
lukofsky | 1:df1ae6d3fd03 | 475 | myled1 = 0; |
lukofsky | 1:df1ae6d3fd03 | 476 | |
lukofsky | 1:df1ae6d3fd03 | 477 | |
lukofsky | 1:df1ae6d3fd03 | 478 | |
lukofsky | 1:df1ae6d3fd03 | 479 | //myled1=!myled1; |
lukofsky | 1:df1ae6d3fd03 | 480 | // DAC->DHR12R1 = output; |
lukofsky | 1:df1ae6d3fd03 | 481 | |
lukofsky | 1:df1ae6d3fd03 | 482 | |
lukofsky | 1:df1ae6d3fd03 | 483 | |
lukofsky | 1:df1ae6d3fd03 | 484 | |
lukofsky | 1:df1ae6d3fd03 | 485 | |
lukofsky | 1:df1ae6d3fd03 | 486 | } |
lukofsky | 1:df1ae6d3fd03 | 487 | |
lukofsky | 1:df1ae6d3fd03 | 488 | } |