├── FPGA ├── README.md └── rxadc_2 │ ├── README.md │ ├── matlab │ ├── README.md │ ├── freq_plot.m │ └── sync_am.m │ ├── python │ ├── README.md │ ├── ddc.py │ ├── fir8dec_coeff.memh │ ├── gen_8coeffs.py │ ├── gen_sine.py │ ├── sine_table_1k.memh │ ├── tst_cic.py │ ├── tst_ddc.py │ ├── write_memh.py │ └── write_meminit.py │ └── verilog │ ├── README.md │ ├── modelsim │ ├── README.md │ ├── comp.do │ ├── comp.f │ ├── load.do │ ├── run.do │ └── wave.do │ ├── rxadc_2 │ ├── README.md │ ├── rxadc_2_sbt.project │ └── rxadc_2_syn.prj │ ├── src │ ├── README.md │ ├── cic_dec_2.v │ ├── cic_dec_3.v │ ├── clkgen.v │ ├── ddc_2.v │ ├── fir8dec.v │ ├── fir8dec_coeff.memh │ ├── i2s_out.v │ ├── rxadc.pcf │ ├── rxadc.sdc │ ├── rxadc_2.v │ ├── sat.v │ ├── sine_table.memh │ ├── sine_table_1k.memh │ ├── spi_slave.v │ ├── tuner_2.v │ ├── tuner_slice.v │ └── tuner_slice_1k.v │ └── tb │ ├── README.md │ ├── tb_rxadc.v │ └── tb_rxadc_2.v ├── LICENSE ├── MCU ├── README.md └── f303_ice5_rxadc │ ├── .gdbinit │ ├── CMSIS │ ├── arm_math.h │ ├── core_cm4.h │ ├── core_cm4_simd.h │ ├── core_cmFunc.h │ ├── core_cmInstr.h │ ├── startup_stm32f30x.s │ ├── system_stm32f30x.c │ └── system_stm32f30x.h │ ├── Makefile │ ├── README.md │ ├── STM32_FLASH.ld │ ├── StdPeriph │ ├── stm32f30x.h │ ├── stm32f30x_adc.c │ ├── stm32f30x_adc.h │ ├── stm32f30x_can.c │ ├── stm32f30x_can.h │ ├── stm32f30x_comp.h │ ├── stm32f30x_conf.h │ ├── stm32f30x_crc.h │ ├── stm32f30x_dac.c │ ├── stm32f30x_dac.h │ ├── stm32f30x_dbgmcu.c │ ├── stm32f30x_dbgmcu.h │ ├── stm32f30x_dma.c │ ├── stm32f30x_dma.h │ ├── stm32f30x_exti.c │ ├── stm32f30x_exti.h │ ├── stm32f30x_flash.c │ ├── stm32f30x_flash.h │ ├── stm32f30x_fmc.c │ ├── stm32f30x_fmc.h │ ├── stm32f30x_gpio.c │ ├── stm32f30x_gpio.h │ ├── stm32f30x_hrtim.c │ ├── stm32f30x_hrtim.h │ ├── stm32f30x_i2c.c │ ├── stm32f30x_i2c.h │ ├── stm32f30x_iwdg.c │ ├── stm32f30x_iwdg.h │ ├── stm32f30x_misc.c │ ├── stm32f30x_misc.h │ ├── stm32f30x_opamp.c │ ├── stm32f30x_opamp.h │ ├── stm32f30x_pwr.c │ ├── stm32f30x_pwr.h │ ├── stm32f30x_rcc.c │ ├── stm32f30x_rcc.h │ ├── stm32f30x_rtc.c │ ├── stm32f30x_rtc.h │ ├── stm32f30x_spi.c │ ├── stm32f30x_spi.h │ ├── stm32f30x_syscfg.c │ ├── stm32f30x_syscfg.h │ ├── stm32f30x_tim.c │ ├── stm32f30x_tim.h │ ├── stm32f30x_usart.c │ ├── stm32f30x_usart.h │ ├── stm32f30x_wwdg.c │ └── stm32f30x_wwdg.h │ ├── adc.c │ ├── adc.h │ ├── audio.c │ ├── audio.h │ ├── audio_lib.c │ ├── audio_lib.h │ ├── bitmap.bin │ ├── cmd.c │ ├── cmd.h │ ├── cyclesleep.c │ ├── cyclesleep.h │ ├── debounce.c │ ├── debounce.h │ ├── ff9a │ ├── 00readme.txt │ ├── diskio.c │ ├── diskio.h │ ├── ff.c │ ├── ff.h │ ├── ffconf.h │ ├── integer.h │ └── option │ │ ├── cc932.c │ │ ├── cc936.c │ │ ├── cc949.c │ │ ├── cc950.c │ │ ├── ccsbcs.c │ │ ├── syscall.c │ │ └── unicode.c │ ├── flash_cmd.gdb │ ├── font_8x8.h │ ├── i2s.c │ ├── i2s.h │ ├── ice5.c │ ├── ice5.h │ ├── iir.c │ ├── iir.h │ ├── iir_coeffs.h │ ├── led.c │ ├── led.h │ ├── main.c │ ├── menu.c │ ├── menu.h │ ├── openocd.cfg │ ├── openocd_j-link.cfg │ ├── openocd_stlinkv2.1.cfg │ ├── rxadc.c │ ├── rxadc.h │ ├── rxadc_21.bin │ ├── rxadc_22.bin │ ├── rxadc_23.bin │ ├── rxadc_4.bin │ ├── rxadc_bitmap.bin │ ├── shared_spi.c │ ├── shared_spi.h │ ├── st7735.c │ ├── st7735.h │ ├── stubs.c │ ├── systick.c │ ├── systick.h │ ├── usart.c │ └── usart.h └── README.md /FPGA/README.md: -------------------------------------------------------------------------------- 1 | # iceRadio FPGA 2 | Verilog sources and support material for the STM32F303 + iCE5LP4K Software 3 | Defined Radio 4 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/README.md: -------------------------------------------------------------------------------- 1 | # rxadc_2 project 2 | Verilog sources and support material for the rxadc_2 iCE5LP4K DDC. This is a 3 | simple FPGA-based Digital Downconverter which tunes, filters and downsamples 4 | from 40MSPS 10-bit real ADC data to 19kSPS 16-bit I & Q in I2S format. 5 | 6 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/matlab/README.md: -------------------------------------------------------------------------------- 1 | # rxadc_2 Matlab support scripts 2 | Matlab scripts for testing out syncronous AM operation. 3 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/matlab/freq_plot.m: -------------------------------------------------------------------------------- 1 | % freq_plot.m - frequency plot 2 | % E. Brombaugh 08-03-16 3 | function freq_plot(x, Fs, title_str) 4 | sz = length(x); 5 | f = Fs * (((0:sz-1)/sz)-0.5); 6 | plot(f, 20*log10(abs(fftshift(fft(x)/sz)))); 7 | grid on; 8 | title(title_str); 9 | xlabel('Freq'); 10 | ylabel('dB'); 11 | end 12 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/matlab/sync_am.m: -------------------------------------------------------------------------------- 1 | % sync_am.m - synchronous AM testbed 2 | % 08-03-16 E. Brombaugh 3 | 4 | % setup some stuff 5 | Fs = 40e6/2048; % sample rate 6 | Fc = 30; % carrier freq 7 | Fm = 1000; % modulation freq 8 | Mod_ratio = 0.5; % modulation ratio 9 | sz = 2^16; % signal length 10 | SNR_dB = 20; % 11 | 12 | % amplitude modulate a tone onto the complex carrier 13 | Fc_dyn = ones(1,sz)*Fc; 14 | Fc_dyn(floor(end/2):end) = -Fc_dyn(floor(end/2):end); 15 | t = (0:sz-1)/Fs; 16 | Sig = (1.0 + Mod_ratio*sin(2*pi*Fm*t)).*exp(1i*2*pi*Fc_dyn.*t); 17 | 18 | % add some noise 19 | RX_Sig = awgn(Sig, SNR_dB, 'measured'); 20 | 21 | % plot RX 22 | figure(1); 23 | freq_plot(RX_Sig, Fs, 'RX Sig'); 24 | figure(2) 25 | plot(t, real(RX_Sig),'r'); 26 | hold on; 27 | plot(t, imag(RX_Sig),'g'); 28 | hold off; 29 | title('RX Sig'); 30 | xlabel('time'); 31 | ylabel('value'); 32 | xlim([0 0.1]); 33 | 34 | % set up the PLL 35 | bb = zeros(1,sz); 36 | dc_est = zeros(1,sz); 37 | out = zeros(1,sz); 38 | err = zeros(1,sz); 39 | lf_int = zeros(1,sz); 40 | frq = zeros(1,sz); 41 | phs = zeros(1,sz); 42 | lo = zeros(1,sz); 43 | dc_coeff = 1e-3; 44 | BWSel = 1; 45 | P_coeff = [1e-3 5e-4 5e-6 ]; 46 | I_coeff = [1e-6 1e-7 1e-8 ]; 47 | timer_st = 0; 48 | timer_ct = 0; 49 | 50 | % iterate over the full signal 51 | for i=1:sz-1 52 | % check for DC estimate ramp up after PLL lock 53 | if (timer_st == 0) && (dc_est(i) > 0.5) 54 | % Start timer 55 | timer_st = 1; 56 | timer_ct = 5000; 57 | end 58 | 59 | % Reset BW if lost lock 60 | if (timer_st == 2) && (dc_est(i) < 0.5) 61 | BWSel = 1; 62 | timer_st = 0; 63 | end 64 | 65 | % timeout? 66 | if (timer_st == 1) 67 | if timer_ct == 0 68 | timer_st = 2; 69 | BWSel = 3; 70 | else 71 | timer_ct = timer_ct - 1; 72 | end 73 | end 74 | 75 | % conjugate LO and mixer 76 | lo(i) = exp(-1i*2*pi*phs(i)); 77 | bb(i) = lo(i) * RX_Sig(i); 78 | 79 | % Raw AM is real component of baseband - DC block it 80 | out(i) = real(bb(i)) - dc_est(i); 81 | dc_est(i+1) = dc_est(i) + out(i)*dc_coeff; 82 | 83 | % Error is angle of baseband 84 | err(i) = angle(bb(i)); 85 | 86 | % Loop Filter set up so BW changes don't disturb it 87 | lf_int(i+1) = lf_int(i) + I_coeff(BWSel) * err(i); 88 | frq(i) = lf_int(i) + P_coeff(BWSel) * err(i); 89 | 90 | % Update phase of LO 91 | phs(i+1) = mod(phs(i) + frq(i), 1.0); 92 | end 93 | 94 | % Plot PLL 95 | figure(3) 96 | plot(t, err,'r'); 97 | hold on; 98 | plot(t, 100*frq, 'g'); 99 | hold off; 100 | title('PLL'); 101 | xlabel('time'); 102 | ylabel('value'); 103 | legend('err', 'frq'); 104 | %xlim([0 0.1]); 105 | 106 | % plot Phase 107 | figure(4) 108 | plot(t, phs,'r'); 109 | title('Phs'); 110 | xlabel('time'); 111 | ylabel('value'); 112 | xlim([0.38 0.4]); 113 | 114 | % plot LO 115 | figure(5) 116 | plot(t, real(RX_Sig),'r'); 117 | hold on; 118 | plot(t, real(lo), 'g'); 119 | hold off; 120 | title('LO'); 121 | xlabel('time'); 122 | ylabel('value'); 123 | legend('RX Sig', 'LO'); 124 | %xlim([0.38 0.4]); 125 | 126 | % plot baseband 127 | figure(6) 128 | plot(t, real(bb),'r'); 129 | hold on; 130 | plot(t, imag(bb), 'g'); 131 | plot(t, dc_est, 'k'); 132 | plot(t, out, 'b'); 133 | hold off; 134 | title('Baseband'); 135 | xlabel('time'); 136 | ylabel('value'); 137 | legend('I', 'Q', 'DC', 'Out'); 138 | %xlim([0.39 0.4]); 139 | 140 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/README.md: -------------------------------------------------------------------------------- 1 | # rxadc_2 Python simulations 2 | This directory contains Python simulations for designing the architecture of 3 | the DDC as well as scripts for generating filter coefficients and DDS lookup 4 | tables in Verilog .memh format. 5 | 6 | 7 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/ddc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # Digital DownConverter and support functions 4 | # 5 | # 07-23-2015 E. Brombaugh 6 | 7 | import numpy as np 8 | import matplotlib as mpl 9 | import matplotlib.pyplot as plt 10 | import scipy.signal as signal 11 | from scipy.fftpack import fft, ifft, fftfreq, fftshift 12 | from write_meminit import write_meminit 13 | 14 | # tuner function - IF real to baseband complex 15 | class tuner: 16 | # init an instance of the model 17 | def __init__(self, tune_bits, lut_bits, lo_bits): 18 | self.tune_bits = tune_bits 19 | self.lut_bits = lut_bits 20 | self.lo_scl = 2**(lo_bits-1) 21 | self.ftune = 0 22 | 23 | # set the tuner frequency 24 | def set_ftune(self, Ft): 25 | self.ftune = -np.floor((2**self.tune_bits)*Ft) 26 | 27 | # compute the model 28 | def calc(self, x): 29 | # phase accumulator with fixed bitwidth 30 | accum = (np.arange(len(x))*self.ftune) % 2**self.tune_bits 31 | 32 | # truncate phase to LUT address bits 33 | addr = np.floor(accum/(2**(self.tune_bits-self.lut_bits))) 34 | 35 | # look up sine table 36 | phs = addr / (2**self.lut_bits); 37 | lo = (self.lo_scl-1)*np.exp(2*np.pi*phs*1j) 38 | lo_i = np.floor(np.real(lo)+0.5) 39 | lo_q = np.floor(np.imag(lo)+0.5) 40 | lo = lo_i + lo_q * 1j 41 | 42 | # complex multiply 43 | y = (lo * x)/self.lo_scl 44 | y_i = np.floor(np.real(y)+0.5) 45 | y_q = np.floor(np.imag(y)+0.5) 46 | y = y_i + y_q * 1j 47 | return y 48 | 49 | # CIC decimator 50 | class cic_dec: 51 | # init an instance 52 | def __init__(self, num_stages, dec_rate, x_bits): 53 | self.num_stages = num_stages 54 | self.dec_rate = dec_rate 55 | acc_bits = x_bits + self.num_stages * np.log2(self.dec_rate) 56 | self.sat_val = 2**acc_bits 57 | 58 | # compute the model 59 | def calc(self, x): 60 | # setup 61 | y_len = np.floor(len(x)/self.dec_rate) 62 | new_intg = np.zeros(self.num_stages, dtype=np.int) 63 | intg = np.zeros(self.num_stages, dtype=np.int) 64 | comb = np.zeros(self.num_stages, dtype=np.int) 65 | y = np.zeros(y_len, dtype=np.int) 66 | 67 | # iterate over output samples 68 | for y_idx in np.arange(y_len): 69 | # Integrators 70 | for x_idx in np.arange(self.dec_rate): 71 | new_intg[0] = ((intg[0] + x[(y_idx * self.dec_rate) + x_idx] + self.sat_val/2) % self.sat_val) - self.sat_val/2 72 | 73 | for stage in np.arange(1,self.num_stages): 74 | new_intg[stage] = (intg[stage] + intg[stage-1]) % self.sat_val 75 | 76 | intg = 1*new_intg # copy, don't just set the pointer! 77 | 78 | # Combs 79 | temp = intg[self.num_stages-1] 80 | for stage in np.arange(self.num_stages): 81 | diff = ((temp - comb[stage]+self.sat_val/2) % self.sat_val) - self.sat_val/2 82 | comb[stage] = temp 83 | temp = 1*diff 84 | 85 | # output sample 86 | y[y_idx] = temp 87 | 88 | # done 89 | return y 90 | 91 | # FIR decimator 92 | class fir4dec: 93 | # init an instance 94 | def __init__(self, fir_len, fir_bits, tb_width): 95 | tb_ctr = 1/(2*4) 96 | pass_corner = tb_ctr - (tb_ctr*tb_width/2) 97 | stop_corner = tb_ctr + (tb_ctr*tb_width/2) 98 | fir_bands = [0, pass_corner, stop_corner, 0.5] 99 | b = signal.remez(fir_len, fir_bands, [1, 0]) 100 | coeff_scl = 2**(fir_bits-1) 101 | self.fir_coeff = np.floor(b*coeff_scl + 0.5) 102 | 103 | # Dump Coefficients? 104 | if 1: 105 | write_meminit("fir4dec_coeff.v", self.fir_coeff) 106 | 107 | self.fir_coeff = self.fir_coeff/coeff_scl; 108 | 109 | # plot FIR response? 110 | if 1: 111 | W, H = signal.freqz(self.fir_coeff) 112 | plt.figure() 113 | plt.plot(W/(2*np.pi), 20*np.log10(np.abs(H))) 114 | plt.grid() 115 | plt.xlabel("Freq (normalized)") 116 | plt.ylabel("dB") 117 | plt.title("fir4dec response (close to continue sim)") 118 | plt.show() 119 | 120 | # compute the model 121 | def calc(self, x): 122 | # filter & quantize 123 | full_out = signal.lfilter(self.fir_coeff, 1, x) 124 | 125 | # Decimate by 4 126 | out = full_out[::4] 127 | 128 | # convert back to complex 129 | out_i = np.floor(np.real(out)+0.5) 130 | out_q = np.floor(np.imag(out)+0.5) 131 | out = out_i + out_q * 1j 132 | 133 | # done 134 | return out 135 | 136 | # DDC class 137 | class ddc: 138 | # init an instance 139 | def __init__(self, data_bits): 140 | self.x_bits = data_bits 141 | 142 | # Tuner setup 143 | self.tuner_inst = tuner(24, 8, data_bits) 144 | 145 | # CIC setup 146 | self.cic_i_inst = cic_dec(4, 256, data_bits) 147 | self.cic_q_inst = cic_dec(4, 256, data_bits) 148 | self.cic_scl = 2**(self.cic_i_inst.num_stages * np.ceil(np.log2(self.cic_i_inst.dec_rate)) - 149 | 1 - np.floor(np.log2(self.cic_i_inst.dec_rate)/2)) 150 | 151 | # FIR setup 152 | self.fir_inst = fir4dec(250, 18, 0.2) 153 | 154 | # set the tuner frequency 155 | def set_ftune(self, Ft): 156 | self.tuner_inst.set_ftune(Ft) 157 | 158 | # compute the model 159 | def calc(self, x): 160 | # tune input 161 | tuner_out = self.tuner_inst.calc(x) 162 | 163 | # First decimation stage 164 | cic_i = self.cic_i_inst.calc(np.real(tuner_out)) 165 | cic_q = self.cic_i_inst.calc(np.imag(tuner_out)) 166 | cic_out = cic_i + cic_q * 1j 167 | 168 | # scale back the CIC output 169 | cic_scaled_raw = cic_out / self.cic_scl 170 | cic_scaled_i = np.floor(np.real(cic_scaled_raw) + 0.5) 171 | cic_scaled_q = np.floor(np.imag(cic_scaled_raw) + 0.5) 172 | cic_scaled = cic_scaled_i + cic_scaled_q * 1j 173 | 174 | # FIR cleanup filter 175 | fir_out = self.fir_inst.calc(cic_scaled) 176 | 177 | # done 178 | #return cic_scaled 179 | return fir_out 180 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/fir8dec_coeff.memh: -------------------------------------------------------------------------------- 1 | // memory init data 2 | // Auto-generated by write_memh.py 3 | ffff 4 | 0000 5 | 0000 6 | 0000 7 | 0001 8 | 0002 9 | 0003 10 | 0003 11 | 0003 12 | 0003 13 | 0001 14 | ffff 15 | fffd 16 | fffa 17 | fff7 18 | fff6 19 | fff6 20 | fff8 21 | fffd 22 | 0003 23 | 0009 24 | 0010 25 | 0016 26 | 0018 27 | 0017 28 | 0011 29 | 0007 30 | fffa 31 | ffeb 32 | ffdc 33 | ffd2 34 | ffcd 35 | ffd0 36 | ffdd 37 | fff2 38 | 000d 39 | 002a 40 | 0046 41 | 005a 42 | 0062 43 | 005a 44 | 0042 45 | 001a 46 | ffe8 47 | ffb2 48 | ff82 49 | ff5f 50 | ff53 51 | ff62 52 | ff8e 53 | ffd3 54 | 002a 55 | 0085 56 | 00d6 57 | 010f 58 | 0121 59 | 0106 60 | 00bb 61 | 0048 62 | ffbb 63 | ff28 64 | fea6 65 | fe4e 66 | fe33 67 | fe61 68 | fed9 69 | ff8f 70 | 006d 71 | 0152 72 | 021a 73 | 029f 74 | 02c5 75 | 027c 76 | 01c2 77 | 00aa 78 | ff59 79 | fdff 80 | fcd3 81 | fc0d 82 | fbd6 83 | fc47 84 | fd60 85 | ff03 86 | 00fb 87 | 02ff 88 | 04bc 89 | 05e2 90 | 0631 91 | 0588 92 | 03e6 93 | 0176 94 | fe87 95 | fb85 96 | f8eb 97 | f72f 98 | f6b2 99 | f7ab 100 | fa1c 101 | fdca 102 | 0244 103 | 06e7 104 | 0afb 105 | 0dc6 106 | 0eab 107 | 0d45 108 | 097d 109 | 0399 110 | fc37 111 | f44a 112 | ecfe 113 | e794 114 | e540 115 | e6fc 116 | ed67 117 | f8a3 118 | 084d 119 | 1b7c 120 | 30d2 121 | 469d 122 | 5b05 123 | 6c3b 124 | 78ae 125 | 7f36 126 | 7f36 127 | 78ae 128 | 6c3b 129 | 5b05 130 | 469d 131 | 30d2 132 | 1b7c 133 | 084d 134 | f8a3 135 | ed67 136 | e6fc 137 | e540 138 | e794 139 | ecfe 140 | f44a 141 | fc37 142 | 0399 143 | 097d 144 | 0d45 145 | 0eab 146 | 0dc6 147 | 0afb 148 | 06e7 149 | 0244 150 | fdca 151 | fa1c 152 | f7ab 153 | f6b2 154 | f72f 155 | f8eb 156 | fb85 157 | fe87 158 | 0176 159 | 03e6 160 | 0588 161 | 0631 162 | 05e2 163 | 04bc 164 | 02ff 165 | 00fb 166 | ff03 167 | fd60 168 | fc47 169 | fbd6 170 | fc0d 171 | fcd3 172 | fdff 173 | ff59 174 | 00aa 175 | 01c2 176 | 027c 177 | 02c5 178 | 029f 179 | 021a 180 | 0152 181 | 006d 182 | ff8f 183 | fed9 184 | fe61 185 | fe33 186 | fe4e 187 | fea6 188 | ff28 189 | ffbb 190 | 0048 191 | 00bb 192 | 0106 193 | 0121 194 | 010f 195 | 00d6 196 | 0085 197 | 002a 198 | ffd3 199 | ff8e 200 | ff62 201 | ff53 202 | ff5f 203 | ff82 204 | ffb2 205 | ffe8 206 | 001a 207 | 0042 208 | 005a 209 | 0062 210 | 005a 211 | 0046 212 | 002a 213 | 000d 214 | fff2 215 | ffdd 216 | ffd0 217 | ffcd 218 | ffd2 219 | ffdc 220 | ffeb 221 | fffa 222 | 0007 223 | 0011 224 | 0017 225 | 0018 226 | 0016 227 | 0010 228 | 0009 229 | 0003 230 | fffd 231 | fff8 232 | fff6 233 | fff6 234 | fff7 235 | fffa 236 | fffd 237 | ffff 238 | 0001 239 | 0003 240 | 0003 241 | 0003 242 | 0003 243 | 0002 244 | 0001 245 | 0000 246 | 0000 247 | 0000 248 | ffff 249 | 0000 250 | 0000 251 | 0000 252 | 0000 253 | 0000 254 | 0000 255 | 0000 256 | 0000 257 | 0000 258 | 0000 259 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/gen_8coeffs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # FIR coeffs for 8x decimator 4 | # 5 | # 07-17-2016 E. Brombaugh 6 | 7 | # Test out the DDC 8 | import numpy as np 9 | import matplotlib as mpl 10 | import matplotlib.pyplot as plt 11 | import scipy.signal as signal 12 | from scipy.fftpack import fft, ifft, fftfreq, fftshift 13 | from write_meminit import write_meminit 14 | from write_memh import write_memh 15 | 16 | # fixed params 17 | fir_len = 246 18 | fir_bits = 19 # leave @ 19 for better quant - correct in HW scaling 19 | Fs = 40e6 / 256 20 | LUT = np.zeros(256, dtype=np.int) 21 | 22 | # per-filter params 23 | tb_Fctr = [ Fs/16, 4000, 2800, 500 ] 24 | tb_width = [ 0.4, 0.8, 1.5, 3] 25 | coeff_scl = 2**(fir_bits-1) 26 | 27 | # pick one filter for this pass 28 | i = 0 # Fs/16 for 8x decimation = 9765Hz 29 | 30 | tb_ctr = tb_Fctr[i]/Fs 31 | pass_corner = tb_ctr - (tb_ctr*tb_width[i]/2) 32 | stop_corner = tb_ctr + (tb_ctr*tb_width[i]/2) 33 | fir_bands = [0, pass_corner, stop_corner, 0.5] 34 | b = signal.remez(fir_len, fir_bands, [1, 0]) 35 | fir_coeff = np.floor(b*coeff_scl + 0.5) 36 | 37 | # compute coeff word size 38 | coeff_bits = 1+np.ceil(np.log2(np.max(np.abs(fir_coeff)))) 39 | print('Max coeff bits = ', coeff_bits) 40 | 41 | # compute worst-case sum for hardware sizing 42 | acc_sum = np.sum(32768*np.abs(fir_coeff)) 43 | acc_bits = 1+np.ceil(np.log2(acc_sum)) 44 | print('Max accumulator bits = ', acc_bits) 45 | 46 | # plot FIR response? 47 | if 1: 48 | W, H = signal.freqz(fir_coeff) 49 | passband_max = np.max(np.abs(H)) 50 | stopband_idx = np.nonzero(W/np.pi > (stop_corner+0.1)) 51 | stopband_max = np.max(np.abs(H[stopband_idx])) 52 | print('Stopband Atten = ', 20*np.log10(passband_max/stopband_max), 'dB') 53 | plt.figure() 54 | plt.plot((Fs)*W/(2*np.pi), 20*np.log10(np.abs(H))) 55 | plt.grid() 56 | plt.xlabel("Freq (Hz)") 57 | plt.ylabel("dB") 58 | plt.title("fir4dec response (close to continue)") 59 | plt.show() 60 | 61 | # stuff into array 62 | LUT[0:fir_len] = fir_coeff 63 | 64 | # Plot combined coeffs 65 | if 1: 66 | plt.figure() 67 | plt.plot(LUT) 68 | plt.grid() 69 | plt.xlabel("index") 70 | plt.ylabel("value") 71 | plt.title("Combined coeffs (close to continue)") 72 | plt.show() 73 | 74 | # Dump Coefficients to FPGA mem file 75 | if 0: 76 | # Xilinx mem init file 77 | write_meminit("fir8dec_coeff.v", LUT) 78 | else: 79 | # Verilog readmemh file 80 | write_memh("fir8dec_coeff.memh", LUT) 81 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/gen_sine.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # 1/4-cycle sine table 4 | # 5 | # 07-11-2016 E. Brombaugh 6 | 7 | import numpy as np 8 | import math as math 9 | import matplotlib as mpl 10 | import matplotlib.pyplot as plt 11 | import scipy.signal as signal 12 | from write_meminit import write_meminit 13 | from write_memh import write_memh 14 | 15 | # fixed params 16 | sine_len = 1024 17 | sine_bits = 16 18 | scl = 2**(sine_bits-1)-1 19 | LUT = np.zeros(sine_len, dtype=np.int) 20 | 21 | # stuff into array 22 | for i in np.arange(sine_len): 23 | LUT[i] = np.floor(math.sin((i+0.5)*math.pi/(2*sine_len))*scl + 0.5) 24 | 25 | # Plot combined coeffs 26 | if 1: 27 | wave = np.zeros(4*sine_len, dtype=np.int) 28 | wave[0:sine_len] = LUT; 29 | wave[sine_len:sine_len*2] = LUT[np.arange(sine_len-1,-1,-1)]; 30 | wave[sine_len*2:sine_len*3] = -LUT; 31 | wave[sine_len*3:sine_len*4] = -LUT[np.arange(sine_len-1,-1,-1)]; 32 | plt.figure() 33 | plt.plot(wave) 34 | plt.grid() 35 | plt.xlabel("index") 36 | plt.ylabel("value") 37 | plt.title("Sine Table (close to continue)") 38 | plt.show() 39 | 40 | # Dump Coefficients to FPGA mem file 41 | if 0: 42 | # Xilinx mem init file 43 | write_meminit("sine_table_1k.v", LUT) 44 | else: 45 | # Verilog readmemh file 46 | write_memh("sine_table_1k.memh", LUT) 47 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/tst_cic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # CIC decimator test bench 4 | # 5 | # 07-23-2015 E. Brombaugh 6 | 7 | import numpy as np 8 | import matplotlib as mpl 9 | import matplotlib.pyplot as plt 10 | import scipy.signal as signal 11 | from scipy.fftpack import fft, ifft, fftfreq, fftshift 12 | from ddc import cic_dec 13 | 14 | # generate a signal 15 | data_len = 2**16 16 | Fs = 40e6 17 | Fc = 20e3 18 | data_bits = 12 19 | data_scl = 2**(data_bits-1)-1 20 | t = np.arange(data_len)/Fs 21 | data_in = np.floor(data_scl * np.sin(2*np.pi*Fc*t) + 0.5) 22 | 23 | # set system parameters and create an instance of the cic 24 | cic_stages = 4; 25 | cic_rate = 256; 26 | uut = cic_dec(cic_stages, cic_rate, data_bits) 27 | 28 | # run the model 29 | cic_out = uut.calc(data_in) 30 | 31 | # prepare to plot 32 | if 0: 33 | data = data_in 34 | rate = Fs 35 | else: 36 | data = cic_out 37 | rate = Fs/cic_rate 38 | 39 | data_len = len(data) 40 | t = np.arange(data_len)/rate 41 | 42 | # plot of time 43 | fig = plt.figure(1) 44 | plt.plot(t, np.real(data)) 45 | plt.grid() 46 | plt.xlabel("Time") 47 | plt.ylabel("data") 48 | plt.title("sinusoid - time") 49 | 50 | # plot of frequency 51 | fig = plt.figure(2) 52 | f = rate * fftshift(fftfreq(data_len))/1e6 53 | win = signal.blackmanharris(data_len) 54 | data_bhwin = data * win 55 | bh_gain = sum(win)/data_len 56 | data_dB = 20*np.log10(np.abs(fftshift(fft(data_bhwin)))/ 57 | (data_len*(data_scl/2)*bh_gain)) 58 | plt.plot(f, data_dB) 59 | plt.grid() 60 | plt.xlabel("Frequency (MHz)") 61 | plt.ylabel("dB") 62 | plt.title("sinusoid - freq") 63 | plt.xlim((0, (rate/1e6)/2)) 64 | plt.show() 65 | 66 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/tst_ddc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # Digital DownConverter testbench 4 | # 5 | # 07-23-2015 E. Brombaugh 6 | 7 | # Test out the DDC 8 | import numpy as np 9 | import matplotlib as mpl 10 | import matplotlib.pyplot as plt 11 | import scipy.signal as signal 12 | from scipy.fftpack import fft, ifft, fftfreq, fftshift 13 | from ddc import ddc 14 | 15 | # generate a signal 16 | data_len = 2**18 17 | Fs = 20e6 18 | Ft = 7.125e6 19 | data_bits = 10 20 | data_scl = 2**(data_bits-1)-1 21 | t = np.arange(data_len)/Fs 22 | data_in = np.floor(data_scl/2 * (np.sin(2*np.pi*(Ft+1000)*t) + np.sin(2*np.pi*(Ft+25000)*t)) + 0.5) 23 | 24 | # init the model 25 | uut = ddc(data_bits) 26 | uut.set_ftune(Ft/Fs) 27 | 28 | # run the ddc 29 | ddc_out = uut.calc(data_in) 30 | 31 | # prepare to plot 32 | data = ddc_out 33 | rate = Fs/(uut.cic_i_inst.dec_rate*4) 34 | data_len = len(data) 35 | t = np.arange(data_len)/rate 36 | 37 | # plot of time 38 | fig = plt.figure(1) 39 | plt.plot(t, np.real(data), label="real") 40 | plt.plot(t, np.imag(data), label="imag") 41 | plt.grid() 42 | plt.xlabel("Time") 43 | plt.ylabel("data") 44 | plt.title("sinusoid - time") 45 | plt.legend() 46 | 47 | # plot of frequency 48 | fig = plt.figure(2) 49 | f = rate * fftshift(fftfreq(data_len))/1e3 50 | win = signal.blackmanharris(data_len) 51 | data_bhwin = data * win 52 | bh_gain = sum(win)/data_len 53 | data_dB = 20*np.log10(np.abs(fftshift(fft(data_bhwin)))/ 54 | (data_len*(data_scl/2)*bh_gain)) 55 | plt.plot(f, data_dB) 56 | plt.grid() 57 | plt.xlabel("Frequency (kHz)") 58 | plt.ylabel("dB") 59 | plt.title("sinusoid - freq") 60 | #plt.xlim((0, (rate/1e3)/2)) 61 | plt.show() 62 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/write_memh.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # Verilog $readmemh() file output 4 | # 5 | # 07-23-2015 E. Brombaugh 6 | 7 | import numpy as np 8 | 9 | def write_memh(fname, data): 10 | # open output file and add header 11 | fh = open(fname, "w", encoding="utf-8") 12 | fh.write("// memory init data\n") 13 | fh.write("// Auto-generated by write_memh.py\n") 14 | 15 | # dump data as hex 16 | for value in data: 17 | value = value&0xffff 18 | fh.write("{0:0=4x}\n".format(value)) 19 | 20 | fh.close() 21 | 22 | 23 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/python/write_meminit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # Xilinx Memory INIT file output 4 | # 5 | # 07-23-2015 E. Brombaugh 6 | 7 | import numpy as np 8 | 9 | def write_meminit(fname, data): 10 | # open output file and add header 11 | fh = open(fname, "w", encoding="utf-8") 12 | fh.write("// dec_coeff_init.v: memory init data\n") 13 | fh.write("// Auto-generated by write_meminit.py\n") 14 | 15 | # Set up memory array 16 | mem = np.zeros(1024, dtype=np.int) 17 | i = 0 18 | for coeff in data: 19 | mem[i] = coeff 20 | i+=1 21 | 22 | # iterate over 64 lines of regular data bits 23 | for i in np.arange(64): 24 | fh.write(".INIT_{0:0=2X}(256'h".format(i)) 25 | 26 | for j in np.arange(15,-1,-1): 27 | value = mem[i*16+j]&0xffff 28 | fh.write("{0:0=4x}".format(value)) 29 | fh.write("),\n") 30 | 31 | # iterate over 8 lines of parity bits 32 | for i in np.arange(8): 33 | fh.write(".INITP_{0:0=2X}(256'h".format(i)) 34 | 35 | for j in np.arange(63,-1,-1): 36 | value = (mem[(i<<7)|(j<<1)]>>16)&3 37 | value = value | (((mem[(i<<7)|(j<<1)|1]>>16)&3)<<2) 38 | fh.write("{0:1x}".format(value)) 39 | 40 | if(i==7): 41 | fh.write(")\n") 42 | else: 43 | fh.write("),\n") 44 | 45 | fh.close() 46 | 47 | 48 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/README.md: -------------------------------------------------------------------------------- 1 | # rxadc_2 Verilog design 2 | Verilog sources, testbenches and FPGA build projects for the rxadc_2 iCE5LP4K 3 | DDC. 4 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/modelsim/README.md: -------------------------------------------------------------------------------- 1 | # rxadc_2 Modelsim directory 2 | This directory contains Modelsim support scripts for simulation of the rxadc_2 3 | Verilog design. -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/modelsim/comp.do: -------------------------------------------------------------------------------- 1 | # create the work directory 2 | vlib work 3 | 4 | # compile the design 5 | vlog -work work -f comp.f -timescale "1 ns / 1 ps" 6 | 7 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/modelsim/comp.f: -------------------------------------------------------------------------------- 1 | // rxadc source files 2 | ../src/sat.v 3 | ../src/clkgen.v 4 | ../src/i2s_out.v 5 | ../src/fir8dec.v 6 | ../src/cic_dec_3.v 7 | ../src/tuner_slice_1k.v 8 | ../src/tuner_2.v 9 | ../src/ddc_2.v 10 | ../src/spi_slave.v 11 | ../src/rxadc_2.v 12 | 13 | // the testbench 14 | ../tb/tb_rxadc_2.v 15 | 16 | // Lattice library 17 | // /opt/lscc/iCEcube2.2016.02/verilog/sb_ice_syn.v 18 | // /opt/lscc/iCEcube2.2016.02/verilog/sb_ice_ipenc_modelsim.v -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/modelsim/load.do: -------------------------------------------------------------------------------- 1 | # run simulator 2 | vsim -t ps work.tb_rxadc_2 3 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/modelsim/run.do: -------------------------------------------------------------------------------- 1 | # run.do: Modelsim do file to execute the ddc testbench 2 | 3 | # compile the design 4 | do comp.do 5 | 6 | # simulate the design 7 | do load.do 8 | 9 | # add some waves 10 | do wave.do 11 | 12 | # run it 13 | run 100us 14 | #run 1ms 15 | #run 100ms 16 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/rxadc_2/README.md: -------------------------------------------------------------------------------- 1 | # iCECube2 rxadc_2 project 2 | This is the Lattice iCECube2 build directory for the rxadc_2 project. Run the 3 | Lattice FPGA toolchain using these project files to build the bitstream. -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/rxadc_2/rxadc_2_sbt.project: -------------------------------------------------------------------------------- 1 | [Project] 2 | ProjectVersion=2.0 3 | Version=Lattice Semiconductor Corporation iCEcube - Release: 2016.02.27810 - Build Date: Jan 28 2016 18:12:42 4 | ProjectName=rxadc_2 5 | Vendor=SiliconBlue 6 | Synthesis=synplify 7 | ProjectVFiles=../src/clkgen.v=work,../src/ddc_2.v=work,../src/fir8dec.v=work,../src/i2s_out.v=work,../src/rxadc_2.v=work,../src/sat.v=work,../src/spi_slave.v=work,../src/tuner_2.v=work,../src/cic_dec_3.v=work,../src/tuner_slice_1k.v 8 | ProjectCFiles=../src/rxadc.sdc 9 | CurImplementation=rxadc_2_Implmnt 10 | Implementations=rxadc_2_Implmnt 11 | StartFromSynthesis=yes 12 | IPGeneration=false 13 | 14 | [lse options] 15 | CarryChain=True 16 | CarryChainLength=0 17 | CommandLineOptions= 18 | EBRUtilization=100.00 19 | FSMEncodingStyle=Auto 20 | FixGatedClocks=True 21 | I/OInsertion=True 22 | IntermediateFileDump=False 23 | LoopLimit=1950 24 | MaximalFanout=10000 25 | MemoryInitialValueFileSearchPath= 26 | NumberOfCriticalPaths=3 27 | OptimizationGoal=Area 28 | PropagateConstants=True 29 | RAMStyle=Auto 30 | ROMStyle=Auto 31 | RWCheckOnRam=False 32 | RemoveDuplicateRegisters=True 33 | ResolvedMixedDrivers=False 34 | ResourceSharing=True 35 | TargetFrequency= 36 | TopLevelUnit= 37 | UseIORegister=Auto 38 | VHDL2008=False 39 | VerilogIncludeSearchPath= 40 | 41 | [rxadc_2_Implmnt] 42 | DeviceFamily=iCE5LP 43 | Device=4K 44 | DevicePackage=SG48 45 | DevicePower= 46 | NetlistFile=rxadc_2_Implmnt/rxadc_2.edf 47 | AdditionalEDIFFile= 48 | IPEDIFFile= 49 | DesignLib=rxadc_2_Implmnt/sbt/netlist/oadb-rxadc_2 50 | DesignView=_rt 51 | DesignCell=rxadc_2 52 | SynthesisSDCFile=rxadc_2_Implmnt/rxadc_2.scf 53 | UserPinConstraintFile= 54 | UserSDCFile= 55 | PhysicalConstraintFile=../src/rxadc.pcf 56 | BackendImplPathName= 57 | Devicevoltage=1.14 58 | DevicevoltagePerformance=+/-5%(datasheet default) 59 | DeviceTemperature=85 60 | TimingAnalysisBasedOn=Worst 61 | OperationRange=Commercial 62 | TypicalCustomTemperature=25 63 | WorstCustomTemperature=85 64 | BestCustomTemperature=0 65 | IOBankVoltages=topBank,2.5 bottomBank,2.5 66 | derValue=1.32445 67 | TimingPathNumberStick=0 68 | 69 | [tool options] 70 | PlacerEffortLevel=std 71 | PlacerAutoLutCascade=yes 72 | PlacerAutoRamCascade=yes 73 | PlacerPowerDriven=no 74 | RouteWithTimingDriven=yes 75 | RouteWithPinPermutation=yes 76 | BitmapSPIFlashMode=yes 77 | BitmapRAM4KInit=yes 78 | BitmapInitRamBank=1111 79 | BitmapOscillatorFR=low 80 | BitmapEnableWarmBoot=yes 81 | BitmapDisableHeader=no 82 | BitmapSetSecurity=no 83 | BitmapSetNoUsedIONoPullup=no 84 | FloorPlannerShowFanInNets=yes 85 | FloorPlannerShowFanOutNets=yes 86 | HookTo3rdPartyTextEditor= 87 | 88 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/rxadc_2/rxadc_2_syn.prj: -------------------------------------------------------------------------------- 1 | #-- Synopsys, Inc. 2 | #-- Project file C:\Users\ericb\KBADC\KBADC\lattice\rxadc_2\verilog\rxadc_2\rxadc_2\rxadc_2_syn.prj 3 | #project files 4 | 5 | add_file -verilog -lib work "../src/clkgen.v" 6 | add_file -verilog -lib work "../src/ddc_2.v" 7 | add_file -verilog -lib work "../src/fir8dec.v" 8 | add_file -verilog -lib work "../src/i2s_out.v" 9 | add_file -verilog -lib work "../src/rxadc_2.v" 10 | add_file -verilog -lib work "../src/sat.v" 11 | add_file -verilog -lib work "../src/spi_slave.v" 12 | add_file -verilog -lib work "../src/tuner_2.v" 13 | add_file -verilog -lib work "../src/cic_dec_3.v" 14 | add_file -verilog -lib work "../src/tuner_slice_1k.v" 15 | add_file -constraint -lib work "../src/rxadc.sdc" 16 | #implementation: "rxadc_2_Implmnt" 17 | impl -add rxadc_2_Implmnt -type fpga 18 | 19 | #implementation attributes 20 | set_option -vlog_std v2001 21 | set_option -project_relative_includes 1 22 | 23 | #device options 24 | set_option -technology SBTiCE5LP 25 | set_option -part iCE5LP4K 26 | set_option -package SG48 27 | set_option -speed_grade 28 | set_option -part_companion "" 29 | 30 | #compilation/mapping options 31 | 32 | # mapper_options 33 | set_option -frequency auto 34 | set_option -write_verilog 0 35 | set_option -write_vhdl 0 36 | 37 | # Silicon Blue iCE5LP 38 | set_option -maxfan 10000 39 | set_option -disable_io_insertion 0 40 | set_option -pipe 1 41 | set_option -retiming 0 42 | set_option -update_models_cp 0 43 | set_option -fixgatedclocks 2 44 | set_option -fixgeneratedclocks 0 45 | 46 | # NFilter 47 | set_option -popfeed 0 48 | set_option -constprop 0 49 | set_option -createhierarchy 0 50 | 51 | # sequential_optimization_options 52 | set_option -symbolic_fsm_compiler 1 53 | 54 | # Compiler Options 55 | set_option -compiler_compatible 0 56 | set_option -resource_sharing 1 57 | 58 | #automatic place and route (vendor) options 59 | set_option -write_apr_constraint 1 60 | 61 | #set result format/file last 62 | project -result_format "edif" 63 | project -result_file ./rxadc_2_Implmnt/rxadc_2.edf 64 | project -log_file "./rxadc_2_Implmnt/rxadc_2.srr" 65 | impl -active rxadc_2_Implmnt 66 | project -run synthesis -clean 67 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/README.md: -------------------------------------------------------------------------------- 1 | # rxadc_2 Verilog source 2 | Verilog sourcesfor the rxadc_2 iCE5LP4K DDC. 3 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/cic_dec_2.v: -------------------------------------------------------------------------------- 1 | // cic_dec_2.v: CIC Decimator - single 2 | // 2016-07-17 E. Brombaugh 3 | 4 | module cic_dec_2 #( 5 | parameter NUM_STAGES = 4, // Stages of int / comb 6 | STG_GSZ = 8, // Bit growth per stage 7 | ISZ = 10, // Input word size 8 | OSZ = (ISZ + (NUM_STAGES * STG_GSZ)) // Output word size 9 | ) 10 | ( 11 | input clk, // System clock 12 | input reset, // System POR 13 | input ena_out, // Decimated output rate (2 clks wide) 14 | input signed [ISZ-1:0] x, // Input data 15 | output signed [OSZ-1:0] y, // Output data 16 | output valid // Output Valid 17 | ); 18 | // sign-extend input 19 | wire signed [OSZ-1:0] x_sx = {{OSZ-ISZ{x[ISZ-1]}},x}; 20 | 21 | // Integrators 22 | reg signed [OSZ-1:0] integrator[0:NUM_STAGES-1]; 23 | always @(posedge clk) 24 | begin 25 | if(reset == 1'b1) 26 | begin 27 | integrator[0] <= {OSZ{1'b0}}; 28 | end 29 | else 30 | begin 31 | integrator[0] <= integrator[0] + x_sx; 32 | end 33 | end 34 | generate 35 | genvar i; 36 | for(i=1;i>>(ASZ-OSZ); 70 | comb_dly[0] <= comb_diff[0]; 71 | end 72 | comb_ena <= {comb_ena[NUM_STAGES:0],ena_out}; 73 | end 74 | end 75 | generate 76 | genvar j; 77 | for(j=1;j<=NUM_STAGES;j=j+1) 78 | begin 79 | always @(posedge clk) 80 | begin 81 | if(reset == 1'b1) 82 | begin 83 | comb_diff[j] <= {OSZ{1'b0}}; 84 | comb_dly[j] <= {OSZ{1'b0}}; 85 | end 86 | else if(comb_ena[j-1] == 1'b1) 87 | begin 88 | comb_diff[j] <= comb_diff[j-1] - comb_dly[j-1]; 89 | comb_dly[j] <= comb_diff[j]; 90 | end 91 | end 92 | end 93 | endgenerate 94 | 95 | // assign output 96 | assign y = comb_diff[NUM_STAGES]; 97 | assign valid = comb_ena[NUM_STAGES]; 98 | endmodule 99 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/clkgen.v: -------------------------------------------------------------------------------- 1 | // 2 | // clkgen: Clock generation for I2S serializer 3 | // 4 | // mclk = clk/4. 5 | // @ 48MHz => 12MHz master rate 6 | // rate = mclk/256. 7 | // @ 48MHz => 46.875 kHz sample rate 8 | // 9 | module clkgen(clk, reset, mclk, mclk_ena, rate); 10 | parameter div = 8; // 2, 4, 8 clk / mclk ratio 11 | 12 | input clk; // 48MHz system clock 13 | input reset; // POR 14 | output mclk; // 256x master clock output (50% duty cycle) 15 | output mclk_ena;// 256x master clock enable output (25% duty cycle) 16 | output rate; // Sample rate clock output 17 | 18 | // master clock divider (4x) 19 | wire [2:0] cnt_mask = div-1; 20 | reg [2:0] mclk_cnt; 21 | reg mclk_ena; 22 | always @(posedge clk) 23 | if(reset) 24 | begin 25 | mclk_cnt <= 3'b111; 26 | mclk_ena <= 1'b1; 27 | end 28 | else 29 | begin 30 | mclk_cnt <= mclk_cnt - 1; 31 | if((mclk_cnt & cnt_mask) == 3'b000) 32 | mclk_ena <= 1'b1; 33 | else 34 | mclk_ena <= 1'b0; 35 | end 36 | 37 | assign mclk = mclk_cnt[1]; 38 | 39 | // rate counter 40 | reg rate; 41 | reg [7:0] rate_cnt; 42 | always @(posedge clk) 43 | if(reset | rate) 44 | rate_cnt <= 8'd255; 45 | else if(mclk_ena) 46 | rate_cnt <= rate_cnt - 1; 47 | 48 | // detect end condition for one cycle pulse in sync with mclk_ena 49 | always @(posedge clk) 50 | rate <= ((rate_cnt == 8'd0) && ((mclk_cnt & cnt_mask) == 3'b000)); 51 | endmodule 52 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/ddc_2.v: -------------------------------------------------------------------------------- 1 | // ddc_2.v - decimating downconverter V2 - runs at full 40MSPS 2 | // 07-17-16 E. Brombaugh 3 | 4 | module ddc_2 #( 5 | parameter isz = 10, 6 | fsz = 26, 7 | osz = 16 8 | ) 9 | ( 10 | input clk, reset, 11 | input [isz-1:0] in, 12 | input [fsz-1:0] frq, 13 | input ns_ena, 14 | output reg valid, 15 | output reg signed [osz-1:0] i_out, q_out 16 | ); 17 | //------------------------------ 18 | // clock divider 19 | //------------------------------ 20 | reg [7:0] dcnt; 21 | reg ena_cic; 22 | always @(posedge clk) 23 | begin 24 | if(reset == 1'b1) 25 | begin 26 | dcnt <= 8'b0; 27 | ena_cic <= 1'b0; 28 | end 29 | else 30 | begin 31 | dcnt <= dcnt + 1; 32 | ena_cic <= &dcnt; 33 | end 34 | end 35 | 36 | //------------------------------ 37 | // convert to signed 38 | //------------------------------ 39 | reg signed [isz-1:0] ddat; 40 | always @(posedge clk) 41 | begin 42 | if(reset) 43 | begin 44 | ddat <= {isz{1'b0}}; 45 | end 46 | else 47 | begin 48 | ddat <= in ^ {1'b1,{isz-1{1'b0}}}; 49 | end 50 | end 51 | 52 | //------------------------------ 53 | // tuner instance 54 | //------------------------------ 55 | wire signed [isz-1:0] tuner_i, tuner_q; 56 | tuner_2 #( 57 | .dsz(isz), 58 | .fsz(fsz) 59 | ) 60 | u_tuner( 61 | .clk(clk), 62 | .reset(reset), 63 | .in(ddat), 64 | .frq(frq), 65 | .ns_ena(ns_ena), 66 | .i_out(tuner_i), 67 | .q_out(tuner_q) 68 | ); 69 | 70 | // testing - zero out one of the TDM samples on the tuner output 71 | //wire signed [isz-1:0] tuner_iq_tst = (tuner_v==1'b1) ? tuner_iq : 10'h000; 72 | 73 | //`define FULL_CIC 74 | `ifdef FULL_CIC 75 | //------------------------------ 76 | // Full precision CICs 77 | //------------------------------ 78 | 79 | //------------------------------ 80 | // I cic decimator instance 81 | //------------------------------ 82 | wire cic_v; 83 | wire signed [32+isz-1:0] cic_i; 84 | cic_dec_2 #( 85 | .NUM_STAGES(4), // Stages of int / comb 86 | .STG_GSZ(8), // Bit growth per stage 87 | .ISZ(isz) // input word size 88 | ) 89 | u_cic_i( 90 | .clk(clk), // System clock 91 | .reset(reset), // System POR 92 | .ena_out(ena_cic), // Decimated output rate (2 clks wide) 93 | .x(tuner_i), // Input data 94 | .y(cic_i), // Output data 95 | .valid(cic_v) // Output Valid 96 | ); 97 | 98 | //------------------------------ 99 | // Q cic decimator instance 100 | //------------------------------ 101 | wire signed [32+isz-1:0] cic_q; 102 | cic_dec_2 #( 103 | .NUM_STAGES(4), // Stages of int / comb 104 | .STG_GSZ(8), // Bit growth per stage 105 | .ISZ(isz) // input word size 106 | ) 107 | u_cic_q( 108 | .clk(clk), // System clock 109 | .reset(reset), // System POR 110 | .ena_out(ena_cic), // Decimated output rate (2 clks wide) 111 | .x(tuner_q), // Input data 112 | .y(cic_q), // Output data 113 | .valid() // Output Valid (unused) 114 | ); 115 | 116 | // trim cic output to 16 bits 117 | wire signed [osz-1:0] cic_i_trim = cic_i[32+isz-1:32+isz-osz]; 118 | wire signed [osz-1:0] cic_q_trim = cic_q[32+isz-1:32+isz-osz]; 119 | 120 | `else 121 | //------------------------------ 122 | // Full precision CICs 123 | //------------------------------ 124 | parameter cicsz = 21; 125 | 126 | //------------------------------ 127 | // I cic decimator instance 128 | //------------------------------ 129 | wire cic_v; 130 | wire signed [cicsz-1:0] cic_i; 131 | cic_dec_3 #( 132 | .NUM_STAGES(4), // Stages of int / comb 133 | .STG_GSZ(8), // Bit growth per stage 134 | .ISZ(isz), // input word size 135 | .OSZ(cicsz) // output word size 136 | ) 137 | u_cic_i( 138 | .clk(clk), // System clock 139 | .reset(reset), // System POR 140 | .ena_out(ena_cic), // Decimated output rate (2 clks wide) 141 | .x(tuner_i), // Input data 142 | .y(cic_i), // Output data 143 | .valid(cic_v) // Output Valid 144 | ); 145 | 146 | //------------------------------ 147 | // Q cic decimator instance 148 | //------------------------------ 149 | wire signed [cicsz-1:0] cic_q; 150 | cic_dec_3 #( 151 | .NUM_STAGES(4), // Stages of int / comb 152 | .STG_GSZ(8), // Bit growth per stage 153 | .ISZ(isz), // input word size 154 | .OSZ(cicsz) // output word size 155 | ) 156 | u_cic_q( 157 | .clk(clk), // System clock 158 | .reset(reset), // System POR 159 | .ena_out(ena_cic), // Decimated output rate (2 clks wide) 160 | .x(tuner_q), // Input data 161 | .y(cic_q), // Output data 162 | .valid() // Output Valid (unused) 163 | ); 164 | 165 | // trim cic output to 16 bits 166 | wire signed [osz-1:0] cic_i_trim = cic_i[cicsz-1:cicsz-osz]; 167 | wire signed [osz-1:0] cic_q_trim = cic_q[cicsz-1:cicsz-osz]; 168 | `endif 169 | 170 | //------------------------------ 171 | // Mux CIC outputs into single stream 172 | //------------------------------ 173 | reg cic_v_d, cic_iq_v; 174 | reg signed [osz-1:0] cic_iq_mux; 175 | always @(posedge clk) 176 | begin 177 | if(reset == 1'b1) 178 | begin 179 | cic_v_d <= 1'b0; 180 | cic_iq_v <= 1'b0; 181 | cic_iq_mux <= {osz{1'b0}}; 182 | end 183 | else 184 | begin 185 | cic_v_d <= cic_v; 186 | if((cic_v_d == 1'b0) & (cic_v == 1'b1)) 187 | begin 188 | cic_iq_v <= 1'b1; 189 | cic_iq_mux <= cic_i_trim; 190 | end 191 | else if((cic_v_d == 1'b1) & (cic_v == 1'b0)) 192 | begin 193 | cic_iq_v <= 1'b1; 194 | cic_iq_mux <= cic_q_trim; 195 | end 196 | else 197 | begin 198 | cic_iq_v <= 1'b0; 199 | end 200 | end 201 | end 202 | 203 | //------------------------------ 204 | // 8x FIR decimator instance 205 | //------------------------------ 206 | wire fir_v; 207 | wire signed [osz-1:0] fir_qi; 208 | fir8dec #( 209 | .isz(osz), // input data size 210 | .osz(osz) // output data size 211 | ) 212 | u_fir( 213 | .clk(clk), // System clock 214 | .reset(reset), // System POR 215 | .ena(cic_iq_v), // New sample available on input 216 | .iq_in(cic_iq_mux), // Input data 217 | .valid(fir_v), // New output sample ready 218 | .qi_out(fir_qi) // Decimated Output data 219 | ); 220 | 221 | //------------------------------ 222 | // demux outputs (fir output order is reversed) 223 | //------------------------------ 224 | reg p_valid; 225 | always @(posedge clk) 226 | begin 227 | if(reset == 1'b1) 228 | begin 229 | p_valid <= 1'b0; 230 | valid <= 1'b0; 231 | i_out <= {osz{1'b0}}; 232 | q_out <= {osz{1'b0}}; 233 | end 234 | else 235 | begin 236 | p_valid <= fir_v; 237 | if((p_valid == 1'b1) & (fir_v == 1'b1)) 238 | i_out <= fir_qi; 239 | if((p_valid == 1'b0) & (fir_v == 1'b1)) 240 | begin 241 | q_out <= fir_qi; 242 | valid <= 1'b1; 243 | end 244 | else 245 | valid <= 1'b0; 246 | end 247 | end 248 | 249 | endmodule 250 | 251 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/fir8dec.v: -------------------------------------------------------------------------------- 1 | // fir8dec.v: 8x FIR decimator with TDM I/Q I/O 2 | // 07-17-16 E. Brombaugh 3 | 4 | module fir8dec #( 5 | parameter isz = 16, // input data size 6 | osz = 16, // output data size 7 | psz = 8, // pointer size 8 | csz = 16, // coeff data size 9 | clen = 246, // coeff data length 10 | agrw = 3 // accumulator growth 11 | ) 12 | ( 13 | input clk, // System clock 14 | input reset, // System POR 15 | input ena, // New sample available on input 16 | input signed [isz-1:0] iq_in, // Input data 17 | output reg valid, // New output sample ready 18 | output reg signed [osz-1:0] qi_out // Output data - reverse order 19 | ); 20 | 21 | //------------------------------ 22 | // write address generator 23 | //------------------------------ 24 | reg [psz:0] w_addr; 25 | always @(posedge clk) 26 | begin 27 | if(reset == 1'b1) 28 | begin 29 | w_addr <= {psz+1{1'd0}}; 30 | end 31 | else 32 | begin 33 | if(ena == 1'b1) 34 | begin 35 | w_addr <= w_addr + 1; 36 | end 37 | end 38 | end 39 | 40 | //------------------------------ 41 | // MAC control state machine 42 | //------------------------------ 43 | `define sm_wait 3'b000 44 | `define sm_macq 3'b001 45 | `define sm_maci 3'b010 46 | `define sm_dmpq 3'b011 47 | `define sm_dmpi 3'b100 48 | 49 | reg [2:0] state; 50 | reg mac_ena, dump; 51 | reg [psz:0] r_addr; 52 | reg [psz-1:0] c_addr; 53 | always @(posedge clk) 54 | begin 55 | if(reset == 1'b1) 56 | begin 57 | state <= `sm_wait; 58 | mac_ena <= 1'b0; 59 | dump <= 1'b0; 60 | r_addr <= {psz+1{1'd0}}; 61 | c_addr <= {psz{1'd0}}; 62 | end 63 | else 64 | begin 65 | case(state) 66 | `sm_wait : 67 | begin 68 | // halt and hold 69 | if(w_addr[3:0] == 4'b1111) 70 | begin 71 | // start a MAC sequence every 16 entries (8 samples) 72 | state <= `sm_macq; 73 | mac_ena <= 1'b1; 74 | r_addr <= w_addr; 75 | c_addr <= {psz{1'd0}}; 76 | end 77 | end 78 | 79 | `sm_macq : 80 | begin 81 | // Accumulate Q and advance to I 82 | state <= `sm_maci; 83 | r_addr <= r_addr - 1; 84 | end 85 | 86 | `sm_maci : 87 | begin 88 | // Accumulate I 89 | if(c_addr != clen) 90 | begin 91 | // advance to next coeff 92 | state <= `sm_macq; 93 | r_addr <= r_addr - 1; 94 | c_addr <= c_addr + 1; 95 | end 96 | else 97 | begin 98 | // finish mac and advance to dump Q 99 | state <= `sm_dmpq; 100 | mac_ena <= 1'b0; 101 | dump <= 1'b1; 102 | end 103 | end 104 | 105 | `sm_dmpq : 106 | begin 107 | // advance to dump 1 108 | state <= `sm_dmpi; 109 | end 110 | 111 | `sm_dmpi : 112 | begin 113 | // finish dump and return to wait 114 | state <= `sm_wait; 115 | dump <= 1'b0; 116 | end 117 | 118 | default : 119 | begin 120 | state <= `sm_wait; 121 | mac_ena <= 1'b0; 122 | dump <= 1'b0; 123 | end 124 | endcase 125 | end 126 | end 127 | 128 | //------------------------------ 129 | // input buffer memory 130 | //------------------------------ 131 | reg signed [isz-1:0] buf_mem [511:0]; 132 | reg signed [isz-1:0] r_data; 133 | always @(posedge clk) // Write memory. 134 | begin 135 | if(ena == 1'b1) 136 | begin 137 | buf_mem[w_addr] <= iq_in; 138 | end 139 | end 140 | 141 | always @(posedge clk) // Read memory. 142 | begin 143 | r_data <= buf_mem[r_addr]; 144 | end 145 | 146 | //------------------------------ 147 | // coeff ROM 148 | //------------------------------ 149 | reg signed [csz-1:0] coeff_rom[0:255]; 150 | reg signed [csz-1:0] c_data; 151 | initial 152 | begin 153 | $readmemh("../src/fir8dec_coeff.memh", coeff_rom); 154 | end 155 | always @(posedge clk) 156 | begin 157 | c_data <= coeff_rom[c_addr]; 158 | end 159 | 160 | //------------------------------ 161 | // MAC 162 | //------------------------------ 163 | reg [2:0] mac_ena_pipe; 164 | reg [2:0] dump_pipe; 165 | reg signed [csz+isz-1:0] mult; 166 | reg signed [csz+isz+agrw-1:0] acc_a, acc_b; 167 | wire signed [csz+isz+agrw-1:0] rnd_const = 1<<(csz+1); 168 | wire signed [osz-1:0] qi_sat; 169 | // Saturate accum output 170 | sat #(.isz(agrw+osz-2), .osz(osz)) 171 | u_sat(.in(acc_b[csz+isz+agrw-1:csz+2]), .out(qi_sat)); 172 | 173 | always @(posedge clk) 174 | begin 175 | if(reset == 1'b1) 176 | begin 177 | mac_ena_pipe <= 3'b000; 178 | dump_pipe <= 3'b000; 179 | mult <= {csz+isz{1'b0}}; 180 | acc_a <= rnd_const; 181 | acc_b <= rnd_const; 182 | valid <= 1'b0; 183 | qi_out <= {osz{1'b0}}; 184 | end 185 | else 186 | begin 187 | // shift pipes 188 | mac_ena_pipe <= {mac_ena_pipe[1:0],mac_ena}; 189 | dump_pipe <= {dump_pipe[1:0],dump}; 190 | 191 | // multiplier always runs 192 | mult <= r_data * c_data; 193 | 194 | // accumulator 195 | if(mac_ena_pipe[1] == 1'b1) 196 | begin 197 | // two-term accumulate 198 | acc_a <= acc_b + {{agrw{mult[csz+isz-1]}},mult}; 199 | acc_b <= acc_a; 200 | end 201 | else 202 | begin 203 | // clear to round constant 204 | acc_a <= rnd_const; 205 | acc_b <= acc_a; 206 | end 207 | 208 | // output 209 | if(dump_pipe[1] == 1'b1) 210 | begin 211 | qi_out <= qi_sat; 212 | end 213 | 214 | // valid 215 | valid <= dump_pipe[1]; 216 | end 217 | end 218 | 219 | endmodule 220 | 221 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/fir8dec_coeff.memh: -------------------------------------------------------------------------------- 1 | // memory init data 2 | // Auto-generated by write_memh.py 3 | ffff 4 | 0000 5 | 0000 6 | 0000 7 | 0001 8 | 0002 9 | 0003 10 | 0003 11 | 0003 12 | 0003 13 | 0001 14 | ffff 15 | fffd 16 | fffa 17 | fff7 18 | fff6 19 | fff6 20 | fff8 21 | fffd 22 | 0003 23 | 0009 24 | 0010 25 | 0016 26 | 0018 27 | 0017 28 | 0011 29 | 0007 30 | fffa 31 | ffeb 32 | ffdc 33 | ffd2 34 | ffcd 35 | ffd0 36 | ffdd 37 | fff2 38 | 000d 39 | 002a 40 | 0046 41 | 005a 42 | 0062 43 | 005a 44 | 0042 45 | 001a 46 | ffe8 47 | ffb2 48 | ff82 49 | ff5f 50 | ff53 51 | ff62 52 | ff8e 53 | ffd3 54 | 002a 55 | 0085 56 | 00d6 57 | 010f 58 | 0121 59 | 0106 60 | 00bb 61 | 0048 62 | ffbb 63 | ff28 64 | fea6 65 | fe4e 66 | fe33 67 | fe61 68 | fed9 69 | ff8f 70 | 006d 71 | 0152 72 | 021a 73 | 029f 74 | 02c5 75 | 027c 76 | 01c2 77 | 00aa 78 | ff59 79 | fdff 80 | fcd3 81 | fc0d 82 | fbd6 83 | fc47 84 | fd60 85 | ff03 86 | 00fb 87 | 02ff 88 | 04bc 89 | 05e2 90 | 0631 91 | 0588 92 | 03e6 93 | 0176 94 | fe87 95 | fb85 96 | f8eb 97 | f72f 98 | f6b2 99 | f7ab 100 | fa1c 101 | fdca 102 | 0244 103 | 06e7 104 | 0afb 105 | 0dc6 106 | 0eab 107 | 0d45 108 | 097d 109 | 0399 110 | fc37 111 | f44a 112 | ecfe 113 | e794 114 | e540 115 | e6fc 116 | ed67 117 | f8a3 118 | 084d 119 | 1b7c 120 | 30d2 121 | 469d 122 | 5b05 123 | 6c3b 124 | 78ae 125 | 7f36 126 | 7f36 127 | 78ae 128 | 6c3b 129 | 5b05 130 | 469d 131 | 30d2 132 | 1b7c 133 | 084d 134 | f8a3 135 | ed67 136 | e6fc 137 | e540 138 | e794 139 | ecfe 140 | f44a 141 | fc37 142 | 0399 143 | 097d 144 | 0d45 145 | 0eab 146 | 0dc6 147 | 0afb 148 | 06e7 149 | 0244 150 | fdca 151 | fa1c 152 | f7ab 153 | f6b2 154 | f72f 155 | f8eb 156 | fb85 157 | fe87 158 | 0176 159 | 03e6 160 | 0588 161 | 0631 162 | 05e2 163 | 04bc 164 | 02ff 165 | 00fb 166 | ff03 167 | fd60 168 | fc47 169 | fbd6 170 | fc0d 171 | fcd3 172 | fdff 173 | ff59 174 | 00aa 175 | 01c2 176 | 027c 177 | 02c5 178 | 029f 179 | 021a 180 | 0152 181 | 006d 182 | ff8f 183 | fed9 184 | fe61 185 | fe33 186 | fe4e 187 | fea6 188 | ff28 189 | ffbb 190 | 0048 191 | 00bb 192 | 0106 193 | 0121 194 | 010f 195 | 00d6 196 | 0085 197 | 002a 198 | ffd3 199 | ff8e 200 | ff62 201 | ff53 202 | ff5f 203 | ff82 204 | ffb2 205 | ffe8 206 | 001a 207 | 0042 208 | 005a 209 | 0062 210 | 005a 211 | 0046 212 | 002a 213 | 000d 214 | fff2 215 | ffdd 216 | ffd0 217 | ffcd 218 | ffd2 219 | ffdc 220 | ffeb 221 | fffa 222 | 0007 223 | 0011 224 | 0017 225 | 0018 226 | 0016 227 | 0010 228 | 0009 229 | 0003 230 | fffd 231 | fff8 232 | fff6 233 | fff6 234 | fff7 235 | fffa 236 | fffd 237 | ffff 238 | 0001 239 | 0003 240 | 0003 241 | 0003 242 | 0003 243 | 0002 244 | 0001 245 | 0000 246 | 0000 247 | 0000 248 | ffff 249 | 0000 250 | 0000 251 | 0000 252 | 0000 253 | 0000 254 | 0000 255 | 0000 256 | 0000 257 | 0000 258 | 0000 259 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/i2s_out.v: -------------------------------------------------------------------------------- 1 | // 2 | // i2s_out: I2S serializer 3 | // 4 | module i2s_out(clk, reset, 5 | l_data, r_data, 6 | mclk, sdout, sclk, lrclk, 7 | load); 8 | 9 | input clk; // System clock 10 | input reset; // System POR 11 | input signed [15:0] l_data, r_data; // inputs 12 | output mclk; // I2S master clock (256x) 13 | output sdout; // I2S serial data 14 | output sclk; // I2S serial clock 15 | output lrclk; // I2S Left/Right clock 16 | output load; // Sample rate enable output 17 | 18 | // Sample rate generation 19 | wire mclk_ena; 20 | clkgen 21 | uclk(.clk(clk), .reset(reset), 22 | .mclk(mclk), .mclk_ena(mclk_ena), .rate(load)); 23 | 24 | // Serial Clock divider (/8 for 48MHz -> 48kHz) 25 | reg [2:0] scnt; // serial clock divide register 26 | always @(posedge clk) 27 | if(reset) 28 | scnt <= 0; 29 | else if(load) 30 | scnt <= 0; 31 | else if(mclk_ena) 32 | scnt <= scnt + 1; 33 | 34 | // generate serial clock pulse 35 | reg p_sclk; // 1 cycle wide copy of serial clock 36 | always @(posedge clk) 37 | if (mclk_ena) 38 | p_sclk <= (scnt==3'b000); 39 | 40 | // Shift register advances on serial clock 41 | reg [31:0] sreg; 42 | always @(posedge clk) 43 | if(load) 44 | sreg <= {l_data,r_data}; 45 | else if(p_sclk & mclk_ena) 46 | sreg <= {sreg[30:0],1'b0}; 47 | 48 | // 1 serial clock cycle delay on data relative to LRCLK 49 | reg sdout; 50 | always @(posedge clk) 51 | if(p_sclk & mclk_ena) 52 | sdout <= sreg[31]; 53 | 54 | // Generate LR clock 55 | reg [3:0] lrcnt; 56 | reg lrclk; 57 | always @(posedge clk) 58 | if(reset | load) 59 | begin 60 | lrcnt <= 0; 61 | lrclk <= 0; 62 | end 63 | else if(p_sclk & mclk_ena) 64 | begin 65 | if(lrcnt == 4'd15) 66 | begin 67 | lrcnt <= 0; 68 | lrclk <= ~lrclk; 69 | end 70 | else 71 | lrcnt <= lrcnt + 1; 72 | end 73 | 74 | // align everything 75 | reg sclk_p0, sclk; 76 | always @(posedge clk) 77 | begin 78 | sclk_p0 <= scnt[2]; 79 | sclk <= sclk_p0; 80 | end 81 | endmodule 82 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/rxadc.pcf: -------------------------------------------------------------------------------- 1 | # ############################################################################## 2 | 3 | # iCEcube PCF 4 | 5 | # Version: 2016.02.27810 6 | 7 | # File Generated: May 3 2016 09:34:27 8 | 9 | # Family & Device: iCE5LP4K 10 | 11 | # Package: SG48 12 | 13 | # ############################################################################## 14 | 15 | ###IOSet List 17 16 | set_io SPI_MISO 14 17 | set_io SPI_SCLK 15 18 | set_io SPI_CSL 16 19 | set_io SPI_MOSI 17 20 | set_io rxadc_clk 20 21 | set_io rxadc_dfs 19 22 | set_io rxadc_otr 23 23 | set_io rxadc_dat[0] 37 24 | set_io rxadc_dat[1] 34 25 | set_io rxadc_dat[2] 35 26 | set_io rxadc_dat[3] 31 27 | set_io rxadc_dat[4] 32 28 | set_io rxadc_dat[5] 27 29 | set_io rxadc_dat[6] 28 30 | set_io rxadc_dat[7] 25 31 | set_io rxadc_dat[8] 26 32 | set_io rxadc_dat[9] 21 33 | set_io dac_lrck 48 34 | set_io dac_mclk 3 35 | set_io dac_sclk 46 36 | set_io dac_sdout 43 37 | set_io mcu_lrck 11 38 | set_io mcu_sclk 10 39 | set_io mcu_sdout 9 40 | set_io mcu_sdin 6 41 | 42 | ###ProDemote List 1 43 | demote_signal_unbuffered u_ddc.ena_cic_g 44 | 45 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/rxadc.sdc: -------------------------------------------------------------------------------- 1 | # ############################################################################## 2 | 3 | # iCEcube SDC 4 | 5 | # Version: 2016.02.27810 6 | 7 | # File Generated: Jul 8 2016 15:53:44 8 | 9 | # ############################################################################## 10 | 11 | ####---- CreateClock list ----1 12 | create_clock -period 50.00 -waveform {0.00 25.00} -name {SPI_SCLK} [get_ports {SPI_SCLK}] 13 | create_clock -period 25.00 -waveform {0.00 12.50} -name {rxadc_clk} [get_ports {rxadc_clk}] 14 | 15 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/sat.v: -------------------------------------------------------------------------------- 1 | // sat.v: saturate isz to osz for signed data 2 | // 2005-06-15 E. Brombaugh 3 | // 2005-09-07 E. Brombaugh - backported FPGA architecture changes 4 | 5 | module sat(in, out); 6 | parameter isz = 17; // input data width 7 | parameter osz = 12; // output data width 8 | parameter warn = 1; // enable runtime warnings 9 | 10 | input signed [isz-1:0] in; // input data to be saturated 11 | output signed [osz-1:0] out; // output data after saturation 12 | 13 | // Check low & high saturation conditions 14 | wire min = in[isz-1] & ~&in[isz-2:osz-1]; 15 | wire max = ~in[isz-1] & |in[isz-2:osz-1]; 16 | 17 | reg [osz-1:0] out; 18 | 19 | // select output 20 | always @(min or max or in) 21 | case({max,min}) 22 | 2'b01: out = {1'b1,{osz-1{1'b0}}}; // max neg 23 | 2'b10: out = {1'b0,{osz-1{1'b1}}}; // max pos 24 | default: out = in[osz-1:0]; // pass thru 25 | endcase 26 | 27 | // runtime warnings 28 | // synthesis translate_off 29 | always @(min or max) 30 | if(warn & (min | max)) 31 | $display("%m: saturation @ time %d (%d <> %d)", $time, in, (1<<(osz-1))); 32 | // synthesis translate_on 33 | endmodule 34 | 35 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/sine_table.memh: -------------------------------------------------------------------------------- 1 | // memory init data 2 | // Auto-generated by write_memh.py 3 | 0065 4 | 012e 5 | 01f7 6 | 02c0 7 | 0389 8 | 0452 9 | 051b 10 | 05e3 11 | 06ac 12 | 0775 13 | 083e 14 | 0906 15 | 09cf 16 | 0a97 17 | 0b5f 18 | 0c28 19 | 0cf0 20 | 0db8 21 | 0e80 22 | 0f47 23 | 100f 24 | 10d6 25 | 119d 26 | 1264 27 | 132b 28 | 13f2 29 | 14b9 30 | 157f 31 | 1645 32 | 170b 33 | 17d0 34 | 1896 35 | 195b 36 | 1a20 37 | 1ae5 38 | 1ba9 39 | 1c6d 40 | 1d31 41 | 1df5 42 | 1eb8 43 | 1f7b 44 | 203e 45 | 2100 46 | 21c2 47 | 2284 48 | 2346 49 | 2407 50 | 24c8 51 | 2588 52 | 2648 53 | 2708 54 | 27c7 55 | 2886 56 | 2944 57 | 2a02 58 | 2ac0 59 | 2b7d 60 | 2c3a 61 | 2cf7 62 | 2db3 63 | 2e6e 64 | 2f2a 65 | 2fe4 66 | 309e 67 | 3158 68 | 3211 69 | 32ca 70 | 3383 71 | 343a 72 | 34f2 73 | 35a8 74 | 365f 75 | 3715 76 | 37ca 77 | 387e 78 | 3933 79 | 39e6 80 | 3a99 81 | 3b4c 82 | 3bfe 83 | 3caf 84 | 3d60 85 | 3e10 86 | 3ebf 87 | 3f6e 88 | 401d 89 | 40ca 90 | 4177 91 | 4224 92 | 42d0 93 | 437b 94 | 4425 95 | 44cf 96 | 4578 97 | 4621 98 | 46c9 99 | 4770 100 | 4816 101 | 48bc 102 | 4961 103 | 4a06 104 | 4aa9 105 | 4b4c 106 | 4bee 107 | 4c90 108 | 4d31 109 | 4dd1 110 | 4e70 111 | 4f0e 112 | 4fac 113 | 5049 114 | 50e5 115 | 5181 116 | 521b 117 | 52b5 118 | 534e 119 | 53e7 120 | 547e 121 | 5515 122 | 55aa 123 | 563f 124 | 56d3 125 | 5767 126 | 57f9 127 | 588b 128 | 591c 129 | 59ac 130 | 5a3b 131 | 5ac9 132 | 5b56 133 | 5be2 134 | 5c6e 135 | 5cf9 136 | 5d82 137 | 5e0b 138 | 5e93 139 | 5f1a 140 | 5fa0 141 | 6025 142 | 60aa 143 | 612d 144 | 61af 145 | 6231 146 | 62b1 147 | 6331 148 | 63af 149 | 642d 150 | 64aa 151 | 6525 152 | 65a0 153 | 661a 154 | 6693 155 | 670a 156 | 6781 157 | 67f7 158 | 686c 159 | 68e0 160 | 6952 161 | 69c4 162 | 6a35 163 | 6aa4 164 | 6b13 165 | 6b81 166 | 6bed 167 | 6c59 168 | 6cc3 169 | 6d2d 170 | 6d95 171 | 6dfd 172 | 6e63 173 | 6ec8 174 | 6f2c 175 | 6f90 176 | 6ff2 177 | 7053 178 | 70b2 179 | 7111 180 | 716f 181 | 71cb 182 | 7227 183 | 7281 184 | 72db 185 | 7333 186 | 738a 187 | 73e0 188 | 7435 189 | 7488 190 | 74db 191 | 752d 192 | 757d 193 | 75cc 194 | 761a 195 | 7667 196 | 76b3 197 | 76fe 198 | 7747 199 | 778f 200 | 77d7 201 | 781d 202 | 7862 203 | 78a5 204 | 78e8 205 | 7929 206 | 796a 207 | 79a9 208 | 79e6 209 | 7a23 210 | 7a5f 211 | 7a99 212 | 7ad2 213 | 7b0a 214 | 7b41 215 | 7b77 216 | 7bab 217 | 7bde 218 | 7c10 219 | 7c41 220 | 7c71 221 | 7c9f 222 | 7ccd 223 | 7cf9 224 | 7d24 225 | 7d4d 226 | 7d76 227 | 7d9d 228 | 7dc3 229 | 7de8 230 | 7e0b 231 | 7e2e 232 | 7e4f 233 | 7e6f 234 | 7e8d 235 | 7eab 236 | 7ec7 237 | 7ee2 238 | 7efc 239 | 7f15 240 | 7f2c 241 | 7f42 242 | 7f57 243 | 7f6b 244 | 7f7d 245 | 7f8f 246 | 7f9f 247 | 7fad 248 | 7fbb 249 | 7fc7 250 | 7fd2 251 | 7fdc 252 | 7fe5 253 | 7fec 254 | 7ff3 255 | 7ff7 256 | 7ffb 257 | 7ffe 258 | 7fff 259 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/spi_slave.v: -------------------------------------------------------------------------------- 1 | // spi_slave.v: SPI Bus interface for 128 x 32 2 | // 2009-02-28 E. Brombaugh 3 | // 2009-03-22 E. Brombaugh - backported early read logic 4 | // 5 | // This is a simple SPI (serial peripheral interface) slave module. 6 | // These SPI parameters are used in this module: 7 | // CPOL = 0 (spiclk idles low) 8 | // CPHA = 0 (data clocked in on rising edge when CPOL is 1) 9 | // 10 | // Note: addr/wdat are synchronous to the SPI clock. we & re are synchronized 11 | // 12 | // A SPI transfer consists of 40 bits, MSB first. 13 | // The first bit is read/write_n. 14 | // The next 7 are address bits. 15 | // The last 32 are data bits 16 | // Read data is sent in current transfer based on early address/direction 17 | 18 | `timescale 1 ns/1 ps 19 | 20 | module spi_slave(clk, reset, 21 | spiclk, spimosi, spimiso, spicsl, 22 | we, re, wdat, addr, rdat); 23 | parameter asz = 7; // address size 24 | parameter dsz = 32; // databus word size 25 | 26 | input clk; // System clock 27 | input reset; // System POR 28 | input spiclk; // ARM SPI Clock output 29 | input spimosi; // ARM SPI Master Out Slave In 30 | output spimiso; // ARM SPI Master In Slave Out 31 | input spicsl; // ARM SPI Chip Select Low 32 | output we; // Write Enable 33 | output re; // Read enable 34 | output [dsz-1:0] wdat; // write databus 35 | output [asz-1:0] addr; // address 36 | input [dsz-1:0] rdat; // read databus 37 | 38 | // SPI Posedge Process 39 | reg [5:0] mosi_cnt; // input bit counter 40 | reg [dsz-1:0] mosi_shift; // shift reg 41 | reg rd; // direction flag 42 | reg [asz-1:0] addr; // address bits 43 | reg eoa; // end of address flag 44 | reg re; // read flag 45 | reg [dsz-1:0] wdat; // write data reg 46 | reg eot; // end of transfer flag 47 | wire spi_reset = reset | spicsl; // combined reset 48 | always@(posedge spiclk or posedge spi_reset) 49 | if (spi_reset) 50 | begin 51 | mosi_cnt <= 'b0; 52 | mosi_shift <= 32'h0; 53 | eoa <= 'b0; 54 | rd <= 'b0; 55 | eot <= 'b0; 56 | end 57 | else 58 | begin 59 | // Counter keeps track of bits received 60 | mosi_cnt <= mosi_cnt + 1; 61 | 62 | // Shift register grabs incoming data 63 | mosi_shift <= {mosi_shift[dsz-2:0], spimosi}; 64 | 65 | // Grab Read bit 66 | if(mosi_cnt == 0) 67 | rd <= spimosi; 68 | 69 | // Grab Address 70 | if(mosi_cnt == asz) 71 | begin 72 | addr <= {mosi_shift[asz-2:0],spimosi}; 73 | eoa <= 1'b1; 74 | end 75 | 76 | // Generate Read pulse 77 | re <= rd & (mosi_cnt == asz); 78 | 79 | if(mosi_cnt == (asz+dsz)) 80 | begin 81 | // Grab data 82 | wdat <= {mosi_shift[dsz-2:0],spimosi}; 83 | 84 | // End-of-transmission (used to generate Write pulse) 85 | eot <= 1'b1; 86 | end 87 | end 88 | 89 | // outgoing shift register is clocked on falling edge 90 | reg [dsz-1:0] miso_shift; 91 | always @(negedge spiclk or posedge spi_reset) 92 | if (spi_reset) 93 | begin 94 | miso_shift <= 32'h0; 95 | end 96 | else 97 | begin 98 | if(re) 99 | miso_shift <= rdat; 100 | else 101 | miso_shift <= {miso_shift[dsz-2:0],1'b0}; 102 | end 103 | 104 | // MISO is just msb of shift reg 105 | assign spimiso = eoa ? miso_shift[dsz-1] : 1'b0; 106 | 107 | // Delay/Sync & edge detect on eot to generate we 108 | reg [2:0] we_dly; 109 | reg we; 110 | always @(posedge clk) 111 | if(reset) 112 | begin 113 | we_dly <= 0; 114 | we <= 0; 115 | end 116 | else 117 | begin 118 | we_dly <= {we_dly[1:0],eot}; 119 | we <= ~we_dly[2] & we_dly[1] & ~rd; 120 | end 121 | endmodule 122 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/tuner_2.v: -------------------------------------------------------------------------------- 1 | // tuner_2.v - real -> complex tuner V2 2 | // 07-17-16 E. Brombaugh 3 | 4 | module tuner_2 #( 5 | parameter dsz = 10, 6 | fsz = 26, 7 | psz = 12 8 | ) 9 | ( 10 | input clk, reset, 11 | input signed [dsz-1:0] in, 12 | input [fsz-1:0] frq, 13 | input ns_ena, 14 | output signed [dsz-1:0] i_out, q_out 15 | ); 16 | // phase accumulator 17 | reg [fsz-1:0] acc; 18 | always @(posedge clk) 19 | begin 20 | if(reset == 1'b1) 21 | begin 22 | acc <= {fsz{1'b0}}; 23 | end 24 | else 25 | begin 26 | acc <= acc + frq; 27 | end 28 | end 29 | 30 | // noise shaping 31 | reg [fsz-1:0] ns_acc; 32 | wire [psz-1:0] phs = ns_acc[fsz-1:fsz-psz]; 33 | wire [fsz-1:0] res = ns_acc[fsz-psz-1:0]; 34 | always @(posedge clk) 35 | begin 36 | if(reset == 1'b1) 37 | begin 38 | ns_acc <= {fsz{1'b0}}; 39 | end 40 | else 41 | begin 42 | ns_acc <= acc + (ns_ena ? {{psz{res[fsz-psz-1]}},res} : 0); 43 | end 44 | end 45 | 46 | //------------------------------ 47 | // I slice instance 48 | //------------------------------ 49 | tuner_slice_1k #( 50 | .dsz(dsz), 51 | .psz(psz) 52 | ) 53 | u_slice_i( 54 | .clk(clk), 55 | .reset(reset), 56 | .shf_90(1'b1), 57 | .in(in), 58 | .phs(phs), 59 | .out(i_out) 60 | ); 61 | 62 | //------------------------------ 63 | // Q slice instance 64 | //------------------------------ 65 | tuner_slice_1k #( 66 | .dsz(dsz), 67 | .psz(psz) 68 | ) 69 | u_slice_q( 70 | .clk(clk), 71 | .reset(reset), 72 | .shf_90(1'b0), 73 | .in(in), 74 | .phs(phs), 75 | .out(q_out) 76 | ); 77 | 78 | endmodule 79 | 80 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/tuner_slice.v: -------------------------------------------------------------------------------- 1 | // tuner_slice.v - one leg of real->complex tuner 2 | // 07-17-16 E. Brombaugh 3 | 4 | module tuner_slice #( 5 | parameter dsz = 10, 6 | psz = 10 7 | ) 8 | ( 9 | input clk, reset, shf_90, 10 | input signed [dsz-1:0] in, 11 | input [psz-1:0] phs, 12 | output reg signed [dsz-1:0] out 13 | ); 14 | // split acc into quadrant and address and delay sign bit 15 | wire [1:0] p_quad = phs[psz-1:psz-2] + {1'b0,shf_90}; 16 | reg [1:0] quad; 17 | reg [psz-3:0] addr; 18 | reg sincos_sign; 19 | always @(posedge clk) 20 | begin 21 | if(reset == 1'b1) 22 | begin 23 | quad <= 2'b0; 24 | addr <= 8'b0; 25 | sincos_sign <= 1'b0; 26 | end 27 | else 28 | begin 29 | quad <= p_quad; 30 | addr <= phs[psz-3:0] ^ {8{p_quad[0]}}; 31 | sincos_sign <= quad[1]; 32 | end 33 | end 34 | 35 | // look up 8-bit 1/4 cycle sine 36 | reg signed [15:0] sine_lut[0:255]; 37 | reg signed [15:0] sincos_raw; 38 | initial 39 | begin 40 | $readmemh("../src/sine_table.memh", sine_lut); 41 | end 42 | always @(posedge clk) 43 | begin 44 | sincos_raw <= sine_lut[addr]; 45 | end 46 | 47 | // invert sign of lut output and delay to align 48 | reg signed [15:0] sincos_p, sincos; 49 | always @(posedge clk) 50 | begin 51 | if(reset == 1'b1) 52 | begin 53 | sincos_p <= 16'h0000; 54 | sincos <= 16'h0000; 55 | end 56 | else 57 | begin 58 | sincos_p <= sincos_sign ? -sincos_raw : sincos_raw; 59 | sincos <= sincos_p; 60 | end 61 | end 62 | 63 | // multiply, round, saturate 64 | reg signed [dsz+16-1:0] mult; 65 | wire signed [dsz+1:0] out_rnd = mult[dsz+16-1:14] + 12'd1; 66 | wire signed [dsz-1:0] out_sat; 67 | 68 | sat #(.isz(dsz+1),.osz(dsz)) 69 | u_sat(.in(out_rnd[dsz+1:1]),.out(out_sat)); 70 | 71 | always @(posedge clk) 72 | begin 73 | if(reset == 1'b1) 74 | begin 75 | mult <= {dsz+16{1'b0}}; 76 | out <= {dsz{1'b0}}; 77 | end 78 | else 79 | begin 80 | mult <= in * sincos; 81 | out <= out_sat; 82 | end 83 | end 84 | endmodule 85 | 86 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/src/tuner_slice_1k.v: -------------------------------------------------------------------------------- 1 | // tuner_slice_1k.v - one leg of real->complex tuner with 4k sine cycle 2 | // 07-18-16 E. Brombaugh 3 | 4 | module tuner_slice_1k #( 5 | parameter dsz = 10, 6 | psz = 12 7 | ) 8 | ( 9 | input clk, reset, shf_90, 10 | input signed [dsz-1:0] in, 11 | input [psz-1:0] phs, 12 | output reg signed [dsz-1:0] out 13 | ); 14 | // split acc into quadrant and address and delay sign bit 15 | wire [1:0] p_quad = phs[psz-1:psz-2] + {1'b0,shf_90}; 16 | reg [1:0] quad; 17 | reg [psz-3:0] addr; 18 | reg sincos_sign; 19 | always @(posedge clk) 20 | begin 21 | if(reset == 1'b1) 22 | begin 23 | quad <= 2'b0; 24 | addr <= 8'b0; 25 | sincos_sign <= 1'b0; 26 | end 27 | else 28 | begin 29 | quad <= p_quad; 30 | addr <= phs[psz-3:0] ^ {psz-2{p_quad[0]}}; 31 | sincos_sign <= quad[1]; 32 | end 33 | end 34 | 35 | // look up 10-bit 1/4 cycle sine 36 | reg signed [15:0] sine_lut[0:1023]; 37 | reg signed [15:0] sincos_raw; 38 | initial 39 | begin 40 | $readmemh("../src/sine_table_1k.memh", sine_lut); 41 | end 42 | always @(posedge clk) 43 | begin 44 | sincos_raw <= sine_lut[addr]; 45 | end 46 | 47 | // invert sign of lut output and delay to align 48 | reg signed [15:0] sincos_p, sincos; 49 | always @(posedge clk) 50 | begin 51 | if(reset == 1'b1) 52 | begin 53 | sincos_p <= 16'h0000; 54 | sincos <= 16'h0000; 55 | end 56 | else 57 | begin 58 | sincos_p <= sincos_sign ? -sincos_raw : sincos_raw; 59 | sincos <= sincos_p; 60 | end 61 | end 62 | 63 | // multiply, round, saturate 64 | reg signed [dsz+16-1:0] mult; 65 | wire signed [dsz+1:0] out_rnd = mult[dsz+16-1:14] + 12'd1; 66 | wire signed [dsz-1:0] out_sat; 67 | 68 | sat #(.isz(dsz+1),.osz(dsz)) 69 | u_sat(.in(out_rnd[dsz+1:1]),.out(out_sat)); 70 | 71 | always @(posedge clk) 72 | begin 73 | if(reset == 1'b1) 74 | begin 75 | mult <= {dsz+16{1'b0}}; 76 | out <= {dsz{1'b0}}; 77 | end 78 | else 79 | begin 80 | mult <= in * sincos; 81 | out <= out_sat; 82 | end 83 | end 84 | endmodule 85 | 86 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/tb/README.md: -------------------------------------------------------------------------------- 1 | # rxadc_2 Verilog testbench files 2 | Verilog top-level testbenches for simulating the rxadc_2 FPGA design in 3 | Modelsim. 4 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/tb/tb_rxadc.v: -------------------------------------------------------------------------------- 1 | // tb_top.v: top-level testbench for FM generator in Lattice iCE40-Ultra 2 | // 2016-06-02 E. Brombaugh 3 | 4 | module tb_rxadc; 5 | // SPI slave port 6 | reg SPI_CSL; 7 | reg SPI_MOSI; 8 | wire SPI_MISO; 9 | reg SPI_SCLK; 10 | 11 | // rxadc board interface 12 | reg rxadc_clk; 13 | wire rxadc_dfs; 14 | reg rxadc_otr; 15 | reg [9:0] rxadc_dat; 16 | 17 | // DAC I2S output 18 | wire dac_mclk; 19 | wire dac_sdout; 20 | wire dac_sclk; 21 | wire dac_lrck; 22 | 23 | // MCU I2S output 24 | reg mcu_sdin; 25 | wire mcu_sdout; 26 | wire mcu_sclk; 27 | wire mcu_lrck; 28 | 29 | // RGB output 30 | wire o_red; 31 | wire o_green; 32 | wire o_blue; 33 | 34 | // ADC NCO source 35 | real rxadc_phs; 36 | 37 | // spi shift 38 | reg [39:0] sr; 39 | reg [31:0] read_data; 40 | 41 | // spi transaction task 42 | task spi_rxtx 43 | ( 44 | input rw, 45 | input [6:0] addr, 46 | input [31:0] wdata 47 | ); 48 | begin: spi_task 49 | 50 | sr = {rw,addr,wdata}; 51 | SPI_CSL = 1'b0; 52 | SPI_SCLK = 1'b0; 53 | SPI_MOSI = sr[39]; 54 | 55 | repeat(40) 56 | begin 57 | #100 58 | SPI_SCLK = 1'b1; 59 | #100 60 | SPI_SCLK = 1'b0; 61 | sr = {sr[38:0],SPI_MISO}; 62 | SPI_MOSI = sr[39]; 63 | end 64 | 65 | #100 66 | SPI_CSL = 1'b1; 67 | #100 68 | read_data = sr[31:0]; 69 | end 70 | endtask 71 | 72 | rxadc 73 | uut( 74 | // SPI slave port 75 | .SPI_CSL(SPI_CSL), 76 | .SPI_MOSI(SPI_MOSI), 77 | .SPI_MISO(SPI_MISO), 78 | .SPI_SCLK(SPI_SCLK), 79 | 80 | // rxadc board interface 81 | .rxadc_clk(rxadc_clk), 82 | .rxadc_dfs(rxadc_dfs), 83 | .rxadc_otr(rxadc_otr), 84 | .rxadc_dat(rxadc_dat), 85 | 86 | // I2S DAC output 87 | .dac_mclk(dac_mclk), 88 | .dac_sdout(dac_sdout), 89 | .dac_sclk(dac_sclk), 90 | .dac_lrck(dac_lrck), 91 | 92 | // I2S MCU interface 93 | .mcu_sdin(mcu_sdin), 94 | .mcu_sdout(mcu_sdout), 95 | .mcu_sclk(mcu_sclk), 96 | .mcu_lrck(mcu_lrck), 97 | 98 | // RGB output 99 | .o_red(o_red), 100 | .o_green(o_green), 101 | .o_blue(o_blue) 102 | ); 103 | 104 | // test setup 105 | initial 106 | begin 107 | // initial SPI setting 108 | SPI_CSL = 1'b1; 109 | SPI_MOSI = 1'b0; 110 | SPI_SCLK = 1'b0; 111 | 112 | // initialize RXADC 113 | rxadc_clk = 1'b0; 114 | rxadc_otr = 1'b0; 115 | 116 | // initialize MCU SDIN 117 | mcu_sdin = 1'b0; 118 | 119 | // wait for chip to init 120 | #4000 121 | 122 | // read ID 123 | spi_rxtx(1'b1, 7'd00, 32'd0); 124 | 125 | // write params - assume the defaults are good 126 | spi_rxtx(1'b0, 7'd1, 32'd1000); // cnt_reg 127 | spi_rxtx(1'b0, 7'h10, 32'h00001000); // freq 128 | spi_rxtx(1'b0, 7'h11, 32'd0); // DAC mux 129 | spi_rxtx(1'b0, 7'd3, 32'd1); // trig 130 | spi_rxtx(1'b0, 7'd3, 32'd0); // untrig 131 | end 132 | 133 | // ADC clock source 134 | always 135 | #12.5 rxadc_clk <= ~rxadc_clk; 136 | 137 | // ADC data source 138 | always @(posedge rxadc_clk) 139 | begin 140 | rxadc_phs <= rxadc_phs + 3*3.14159/64; 141 | //rxadc_dat <= 10'd512 + 511*$sin(rxadc_phs); 142 | rxadc_dat <= 10'd950; 143 | end 144 | 145 | endmodule 146 | 147 | -------------------------------------------------------------------------------- /FPGA/rxadc_2/verilog/tb/tb_rxadc_2.v: -------------------------------------------------------------------------------- 1 | // tb_rxadc_2.v: top-level testbench for rxadc v2 in Lattice iCE40-Ultra 2 | // 07-17-2016 E. Brombaugh 3 | 4 | module tb_rxadc_2; 5 | // SPI slave port 6 | reg SPI_CSL; 7 | reg SPI_MOSI; 8 | wire SPI_MISO; 9 | reg SPI_SCLK; 10 | 11 | // rxadc board interface 12 | reg rxadc_clk; 13 | wire rxadc_dfs; 14 | reg rxadc_otr; 15 | reg [9:0] rxadc_dat; 16 | 17 | // DAC I2S output 18 | wire dac_mclk; 19 | wire dac_sdout; 20 | wire dac_sclk; 21 | wire dac_lrck; 22 | 23 | // MCU I2S output 24 | reg mcu_sdin; 25 | wire mcu_sdout; 26 | wire mcu_sclk; 27 | wire mcu_lrck; 28 | 29 | // RGB output 30 | wire o_red; 31 | wire o_green; 32 | wire o_blue; 33 | 34 | // ADC NCO source 35 | real rxadc_phs; 36 | 37 | // spi shift 38 | reg [39:0] sr; 39 | reg [31:0] read_data; 40 | 41 | // spi transaction task 42 | task spi_rxtx 43 | ( 44 | input rw, 45 | input [6:0] addr, 46 | input [31:0] wdata 47 | ); 48 | begin: spi_task 49 | 50 | sr = {rw,addr,wdata}; 51 | SPI_CSL = 1'b0; 52 | SPI_SCLK = 1'b0; 53 | SPI_MOSI = sr[39]; 54 | 55 | repeat(40) 56 | begin 57 | #100 58 | SPI_SCLK = 1'b1; 59 | #100 60 | SPI_SCLK = 1'b0; 61 | sr = {sr[38:0],SPI_MISO}; 62 | SPI_MOSI = sr[39]; 63 | end 64 | 65 | #100 66 | SPI_CSL = 1'b1; 67 | #100 68 | read_data = sr[31:0]; 69 | end 70 | endtask 71 | 72 | rxadc_2 73 | uut( 74 | // SPI slave port 75 | .SPI_CSL(SPI_CSL), 76 | .SPI_MOSI(SPI_MOSI), 77 | .SPI_MISO(SPI_MISO), 78 | .SPI_SCLK(SPI_SCLK), 79 | 80 | // rxadc board interface 81 | .rxadc_clk(rxadc_clk), 82 | .rxadc_dfs(rxadc_dfs), 83 | .rxadc_otr(rxadc_otr), 84 | .rxadc_dat(rxadc_dat), 85 | 86 | // I2S DAC output 87 | .dac_mclk(dac_mclk), 88 | .dac_sdout(dac_sdout), 89 | .dac_sclk(dac_sclk), 90 | .dac_lrck(dac_lrck), 91 | 92 | // I2S MCU interface 93 | .mcu_sdin(mcu_sdin), 94 | .mcu_sdout(mcu_sdout), 95 | .mcu_sclk(mcu_sclk), 96 | .mcu_lrck(mcu_lrck), 97 | 98 | // RGB output 99 | .o_red(o_red), 100 | .o_green(o_green), 101 | .o_blue(o_blue) 102 | ); 103 | 104 | // test setup 105 | initial 106 | begin 107 | // initial SPI setting 108 | SPI_CSL = 1'b1; 109 | SPI_MOSI = 1'b0; 110 | SPI_SCLK = 1'b0; 111 | 112 | // initialize RXADC 113 | rxadc_clk = 1'b0; 114 | rxadc_otr = 1'b0; 115 | 116 | // initialize MCU SDIN 117 | mcu_sdin = 1'b0; 118 | 119 | // wait for chip to init 120 | #4000 121 | 122 | // read ID 123 | spi_rxtx(1'b1, 7'd00, 32'd0); 124 | 125 | // write params - assume the defaults are good 126 | spi_rxtx(1'b0, 7'd1, 32'd1000); // cnt_reg 127 | spi_rxtx(1'b0, 7'h10, 32'h00000800); // freq 128 | spi_rxtx(1'b0, 7'h11, 32'd0); // DAC mux 129 | spi_rxtx(1'b0, 7'h12, 32'd1); // noise shaping 130 | spi_rxtx(1'b0, 7'd3, 32'd1); // trig 131 | spi_rxtx(1'b0, 7'd3, 32'd0); // untrig 132 | end 133 | 134 | // ADC clock source 135 | always 136 | #12.5 rxadc_clk <= ~rxadc_clk; 137 | 138 | // ADC data source 139 | always @(posedge rxadc_clk) 140 | begin 141 | rxadc_phs <= rxadc_phs + 3*3.14159/64; 142 | //rxadc_dat <= 10'd512 + 511*$sin(rxadc_phs); 143 | rxadc_dat <= 10'd1000; 144 | end 145 | 146 | endmodule 147 | 148 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Eric Brombaugh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MCU/README.md: -------------------------------------------------------------------------------- 1 | # iceRadio MCU 2 | STM32F303 source for the iceRadio SDR project. 3 | 4 | This directory contains C code projects which run on the STM32F303 MCU portion 5 | of the iceRadio project. 6 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/.gdbinit: -------------------------------------------------------------------------------- 1 | define flash 2 | file main.elf 3 | load 4 | end 5 | 6 | define restart 7 | run 8 | end 9 | 10 | define attach_swd 11 | mon swdp_scan 12 | attach 1 13 | end 14 | 15 | file main.elf 16 | target extended-remote /dev/ttyACM0 17 | 18 | set mem inaccessible-by-default off 19 | 20 | attach_swd 21 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/CMSIS/system_stm32f30x.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f30x.h 4 | * @author MCD Application Team 5 | * @version V1.2.2 6 | * @date 27-February-2015 7 | * @brief CMSIS Cortex-M4 Device System Source File for STM32F30x devices. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2015 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /** @addtogroup CMSIS 29 | * @{ 30 | */ 31 | 32 | /** @addtogroup stm32f30x_system 33 | * @{ 34 | */ 35 | 36 | /** 37 | * @brief Define to prevent recursive inclusion 38 | */ 39 | #ifndef __SYSTEM_STM32F30X_H 40 | #define __SYSTEM_STM32F30X_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* Exported types ------------------------------------------------------------*/ 47 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 48 | /* Exported constants --------------------------------------------------------*/ 49 | /* Exported macro ------------------------------------------------------------*/ 50 | /* Exported functions ------------------------------------------------------- */ 51 | 52 | /** @addtogroup STM32F30x_System_Exported_Functions 53 | * @{ 54 | */ 55 | 56 | extern void SystemInit(void); 57 | extern void SystemCoreClockUpdate(void); 58 | 59 | /** 60 | * @} 61 | */ 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif /*__SYSTEM_STM32F30X_H */ 68 | 69 | /** 70 | * @} 71 | */ 72 | 73 | /** 74 | * @} 75 | */ 76 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 77 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for STM32F30x 2 | # 01-28-2013 E. Brombaugh 3 | 4 | # sub directories 5 | VPATH = .:CMSIS:StdPeriph:ff9a 6 | 7 | # Object files 8 | OBJECTS = startup_stm32f30x.o system_stm32f30x.o main.o cyclesleep.o \ 9 | systick.o usart.o stubs.o led.o ice5.o cmd.o bitmap.o \ 10 | adc.o shared_spi.o st7735.o ff.o diskio.o i2s.o audio.o \ 11 | audio_lib.o iir.o rxadc.o menu.o debounce.o \ 12 | stm32f30x_gpio.o stm32f30x_misc.o stm32f30x_rcc.o \ 13 | stm32f30x_usart.o stm32f30x_spi.o stm32f30x_adc.o \ 14 | stm32f30x_dma.o 15 | 16 | 17 | # Linker script 18 | LDSCRIPT = STM32_FLASH.ld 19 | 20 | CFLAGS = -g -O3 -mlittle-endian -mthumb -ffunction-sections -std=c99 21 | CFLAGS += -Wall -Wno-strict-aliasing 22 | CFLAGS += -I. -ICMSIS -IStdPeriph -Iff9a 23 | CFLAGS += -DARM_MATH_CM4 -D'__FPU_PRESENT=1' -DUSE_STDPERIPH_DRIVER 24 | CFLAGS += -DSTM32F303xC -D'HSE_VALUE=((uint32_t)8000000)' 25 | CFLAGS += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 26 | AFLAGS = -mlittle-endian -mthumb -mcpu=cortex-m4 27 | LFLAGS = $(CFLAGS) -nostartfiles -T $(LDSCRIPT) -Wl,-Map=main.map 28 | LFLAGS += -Wl,--gc-sections 29 | #LFLAGS += --specs=nano.specs 30 | CPFLAGS = --output-target=binary 31 | ODFLAGS = -x --syms 32 | 33 | # Executables 34 | ARCH = arm-none-eabi 35 | CC = $(ARCH)-gcc 36 | CPP = $(ARCH)-g++ 37 | LD = $(ARCH)-ld -v 38 | AS = $(ARCH)-as 39 | OBJCPY = $(ARCH)-objcopy 40 | OBJDMP = $(ARCH)-objdump 41 | GDB = $(ARCH)-gdb 42 | OPENOCD = openocd 43 | DFU = dfu-util 44 | 45 | #CPFLAGS = --output-target=binary -j .text -j .data 46 | CPFLAGS = --output-target=binary 47 | ODFLAGS = -x --syms 48 | 49 | # Targets 50 | all: main.bin 51 | 52 | clean: 53 | -rm -f $(OBJECTS) *.lst *.elf *.map *.dmp main.bin 54 | 55 | flash: gdb_flash 56 | #flash: openocd_flash 57 | #flash: openocd_v2.1_flash 58 | 59 | gdb_flash: main.elf 60 | $(GDB) -x flash_cmd.gdb -batch 61 | stty sane 62 | 63 | openocd_flash: main.elf 64 | $(OPENOCD) -f openocd.cfg -c "program main.elf verify reset exit" 65 | 66 | openocd_jlink_flash: main.elf 67 | $(OPENOCD) -f openocd_j-link.cfg -c "program main.elf verify reset exit" 68 | 69 | openocd_v2.1_flash: main.elf 70 | $(OPENOCD) -f openocd_stlinkv2.1.cfg -c "program main.elf verify reset exit" 71 | 72 | dfu: main.bin 73 | $(DFU) -a 0 -d 0483:df11 -s 0x8000000 -D main.bin 74 | 75 | disassemble: main.elf 76 | $(OBJDMP) -dS main.elf > main.dis 77 | 78 | dist: 79 | tar -c *.h *.c *.s Makefile *.cmd *.cfg openocd_doflash | gzip > minimal_hello_world.tar.gz 80 | 81 | main.ihex: main.elf 82 | $(OBJCPY) --output-target=ihex main.elf main.ihex 83 | 84 | main.bin: main.elf 85 | $(OBJCPY) $(CPFLAGS) main.elf main.bin 86 | $(OBJDMP) $(ODFLAGS) main.elf > main.dmp 87 | ls -l main.elf main.bin 88 | 89 | main.elf: $(OBJECTS) $(LDSCRIPT) 90 | $(CC) $(LFLAGS) -o main.elf $(OBJECTS) -lnosys -lm 91 | 92 | bitmap.o: bitmap.bin 93 | $(OBJCPY) -I binary -O elf32-littlearm -B arm --rename-section .data=.rodata bitmap.bin bitmap.o 94 | 95 | %.o: %.c %.h 96 | $(CC) $(CFLAGS) -c -o $@ $< 97 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/README.md: -------------------------------------------------------------------------------- 1 | # iceRadio MCU - f303_ice5_rxadc 2 | STM32F303 C source for the iceRadio SDR project. 3 | 4 | This directory contains C code which runs on the STM32F303 MCU portion of the 5 | iceRadio project in support of a basic HF (0 - 20MHz) reciever. The project 6 | requires an LCD display and a rotary encoder w/ pushbutton to navigate a 7 | GUI with radio control features. 8 | 9 | 10 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/STM32_FLASH.ld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/STM32_FLASH.ld -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/StdPeriph/stm32f30x.h -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Lib_DEBUG/Lib_DEBUG_Example/stm32f30x_conf.h 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 23-October-2012 7 | * @brief Library configuration file. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2012 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __STM32F30X_CONF_H 30 | #define __STM32F30X_CONF_H 31 | 32 | /* Includes ------------------------------------------------------------------*/ 33 | /* Comment the line below to disable peripheral header file inclusion */ 34 | #include "stm32f30x_adc.h" 35 | //#include "stm32f30x_can.h" 36 | //#include "stm32f30x_crc.h" 37 | //#include "stm32f30x_comp.h" 38 | //#include "stm32f30x_dac.h" 39 | //#include "stm32f30x_dbgmcu.h" 40 | #include "stm32f30x_dma.h" 41 | //#include "stm32f30x_exti.h" 42 | //#include "stm32f30x_flash.h" 43 | #include "stm32f30x_gpio.h" 44 | //#include "stm32f30x_syscfg.h" 45 | //#include "stm32f30x_i2c.h" 46 | //#include "stm32f30x_iwdg.h" 47 | //#include "stm32f30x_opamp.h" 48 | //#include "stm32f30x_pwr.h" 49 | #include "stm32f30x_rcc.h" 50 | //#include "stm32f30x_rtc.h" 51 | #include "stm32f30x_spi.h" 52 | //#include "stm32f30x_tim.h" 53 | #include "stm32f30x_usart.h" 54 | //#include "stm32f30x_wwdg.h" 55 | #include "stm32f30x_misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ 56 | 57 | /* Exported types ------------------------------------------------------------*/ 58 | /* Exported constants --------------------------------------------------------*/ 59 | /* Uncomment the line below to expanse the "assert_param" macro in the 60 | Standard Peripheral Library drivers code */ 61 | #define USE_FULL_ASSERT 1 62 | 63 | /* Exported macro ------------------------------------------------------------*/ 64 | #ifdef USE_FULL_ASSERT 65 | 66 | /** 67 | * @brief The assert_param macro is used for function's parameters check. 68 | * @param expr: If expr is false, it calls assert_failed function which reports 69 | * the name of the source file and the source line number of the call 70 | * that failed. If expr is true, it returns no value. 71 | * @retval None 72 | */ 73 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) 74 | /* Exported functions ------------------------------------------------------- */ 75 | void assert_failed(uint8_t* file, uint32_t line); 76 | #else 77 | #define assert_param(expr) ((void)0) 78 | #endif /* USE_FULL_ASSERT */ 79 | 80 | #endif /* __STM32F30X_CONF_H */ 81 | 82 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 83 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_crc.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f30x_crc.h 4 | * @author MCD Application Team 5 | * @version V1.2.2 6 | * @date 27-February-2015 7 | * @brief This file contains all the functions prototypes for the CRC firmware 8 | * library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2015 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F30x_CRC_H 31 | #define __STM32F30x_CRC_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /*!< Includes ----------------------------------------------------------------*/ 38 | #include "stm32f30x.h" 39 | 40 | /** @addtogroup STM32F30x_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup CRC 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | /* Exported constants --------------------------------------------------------*/ 50 | 51 | /** @defgroup CRC_ReverseInputData 52 | * @{ 53 | */ 54 | #define CRC_ReverseInputData_No ((uint32_t)0x00000000) /*!< No reverse operation of Input Data */ 55 | #define CRC_ReverseInputData_8bits CRC_CR_REV_IN_0 /*!< Reverse operation of Input Data on 8 bits */ 56 | #define CRC_ReverseInputData_16bits CRC_CR_REV_IN_1 /*!< Reverse operation of Input Data on 16 bits */ 57 | #define CRC_ReverseInputData_32bits CRC_CR_REV_IN /*!< Reverse operation of Input Data on 32 bits */ 58 | 59 | #define IS_CRC_REVERSE_INPUT_DATA(DATA) (((DATA) == CRC_ReverseInputData_No) || \ 60 | ((DATA) == CRC_ReverseInputData_8bits) || \ 61 | ((DATA) == CRC_ReverseInputData_16bits) || \ 62 | ((DATA) == CRC_ReverseInputData_32bits)) 63 | 64 | /** 65 | * @} 66 | */ 67 | 68 | /** @defgroup CRC_PolynomialSize 69 | * @{ 70 | */ 71 | #define CRC_PolSize_7 CRC_CR_POLSIZE /*!< 7-bit polynomial for CRC calculation */ 72 | #define CRC_PolSize_8 CRC_CR_POLSIZE_1 /*!< 8-bit polynomial for CRC calculation */ 73 | #define CRC_PolSize_16 CRC_CR_POLSIZE_0 /*!< 16-bit polynomial for CRC calculation */ 74 | #define CRC_PolSize_32 ((uint32_t)0x00000000)/*!< 32-bit polynomial for CRC calculation */ 75 | 76 | #define IS_CRC_POL_SIZE(SIZE) (((SIZE) == CRC_PolSize_7) || \ 77 | ((SIZE) == CRC_PolSize_8) || \ 78 | ((SIZE) == CRC_PolSize_16) || \ 79 | ((SIZE) == CRC_PolSize_32)) 80 | 81 | /** 82 | * @} 83 | */ 84 | 85 | /* Exported macro ------------------------------------------------------------*/ 86 | /* Exported functions ------------------------------------------------------- */ 87 | /* Configuration of the CRC computation unit **********************************/ 88 | void CRC_DeInit(void); 89 | void CRC_ResetDR(void); 90 | void CRC_PolynomialSizeSelect(uint32_t CRC_PolSize); 91 | void CRC_ReverseInputDataSelect(uint32_t CRC_ReverseInputData); 92 | void CRC_ReverseOutputDataCmd(FunctionalState NewState); 93 | void CRC_SetInitRegister(uint32_t CRC_InitValue); 94 | void CRC_SetPolynomial(uint32_t CRC_Pol); 95 | 96 | /* CRC computation ************************************************************/ 97 | uint32_t CRC_CalcCRC(uint32_t CRC_Data); 98 | uint32_t CRC_CalcCRC16bits(uint16_t CRC_Data); 99 | uint32_t CRC_CalcCRC8bits(uint8_t CRC_Data); 100 | uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); 101 | uint32_t CRC_GetCRC(void); 102 | 103 | /* Independent register (IDR) access (write/read) *****************************/ 104 | void CRC_SetIDRegister(uint8_t CRC_IDValue); 105 | uint8_t CRC_GetIDRegister(void); 106 | 107 | #ifdef __cplusplus 108 | } 109 | #endif 110 | 111 | #endif /* __STM32F30x_CRC_H */ 112 | 113 | /** 114 | * @} 115 | */ 116 | 117 | /** 118 | * @} 119 | */ 120 | 121 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 122 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_dbgmcu.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f30x_dbgmcu.c 4 | * @author MCD Application Team 5 | * @version V1.2.2 6 | * @date 27-February-2015 7 | * @brief This file provides firmware functions to manage the following 8 | * functionalities of the Debug MCU (DBGMCU) peripheral: 9 | * + Device and Revision ID management 10 | * + Peripherals Configuration 11 | ****************************************************************************** 12 | * @attention 13 | * 14 | *

© COPYRIGHT 2015 STMicroelectronics

15 | * 16 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 17 | * You may not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at: 19 | * 20 | * http://www.st.com/software_license_agreement_liberty_v2 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an "AS IS" BASIS, 24 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | * 28 | ****************************************************************************** 29 | */ 30 | 31 | /* Includes ------------------------------------------------------------------*/ 32 | #include "stm32f30x_dbgmcu.h" 33 | 34 | /** @addtogroup STM32F30x_StdPeriph_Driver 35 | * @{ 36 | */ 37 | 38 | /** @defgroup DBGMCU 39 | * @brief DBGMCU driver modules 40 | * @{ 41 | */ 42 | 43 | /* Private typedef -----------------------------------------------------------*/ 44 | /* Private define ------------------------------------------------------------*/ 45 | #define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) 46 | 47 | /* Private macro -------------------------------------------------------------*/ 48 | /* Private variables ---------------------------------------------------------*/ 49 | /* Private function prototypes -----------------------------------------------*/ 50 | /* Private functions ---------------------------------------------------------*/ 51 | 52 | /** @defgroup DBGMCU_Private_Functions 53 | * @{ 54 | */ 55 | 56 | /** @defgroup DBGMCU_Group1 Device and Revision ID management functions 57 | * @brief Device and Revision ID management functions 58 | * 59 | @verbatim 60 | ============================================================================== 61 | ##### Device and Revision ID management functions ##### 62 | ============================================================================== 63 | 64 | @endverbatim 65 | * @{ 66 | */ 67 | 68 | /** 69 | * @brief Returns the device revision identifier. 70 | * @param None 71 | * @retval Device revision identifier 72 | */ 73 | uint32_t DBGMCU_GetREVID(void) 74 | { 75 | return(DBGMCU->IDCODE >> 16); 76 | } 77 | 78 | /** 79 | * @brief Returns the device identifier. 80 | * @param None 81 | * @retval Device identifier 82 | */ 83 | uint32_t DBGMCU_GetDEVID(void) 84 | { 85 | return(DBGMCU->IDCODE & IDCODE_DEVID_MASK); 86 | } 87 | 88 | /** 89 | * @} 90 | */ 91 | 92 | /** @defgroup DBGMCU_Group2 Peripherals Configuration functions 93 | * @brief Peripherals Configuration 94 | * 95 | @verbatim 96 | ============================================================================== 97 | ##### Peripherals Configuration functions ##### 98 | ============================================================================== 99 | 100 | @endverbatim 101 | * @{ 102 | */ 103 | 104 | /** 105 | * @brief Configures low power mode behavior when the MCU is in Debug mode. 106 | * @param DBGMCU_Periph: specifies the low power mode. 107 | * This parameter can be any combination of the following values: 108 | * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode. 109 | * @arg DBGMCU_STOP: Keep debugger connection during STOP mode. 110 | * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode. 111 | * @param NewState: new state of the specified low power mode in Debug mode. 112 | * This parameter can be: ENABLE or DISABLE. 113 | * @retval None 114 | */ 115 | void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) 116 | { 117 | /* Check the parameters */ 118 | assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); 119 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 120 | if (NewState != DISABLE) 121 | { 122 | DBGMCU->CR |= DBGMCU_Periph; 123 | } 124 | else 125 | { 126 | DBGMCU->CR &= ~DBGMCU_Periph; 127 | } 128 | } 129 | 130 | /** 131 | * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode. 132 | * @param DBGMCU_Periph: specifies the APB1 peripheral. 133 | * This parameter can be any combination of the following values: 134 | * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted. 135 | * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted. 136 | * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted. 137 | * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted. 138 | * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted. 139 | * @arg DBGMCU_RTC_STOP: RTC Calendar and Wakeup counter are stopped when 140 | * Core is halted. 141 | * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted. 142 | * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted. 143 | * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when 144 | * Core is halted. 145 | * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when 146 | * Core is halted. 147 | * @arg DBGMCU_CAN1_STOP: Debug CAN2 stopped when Core is halted. 148 | * @arg DBGMCU_I2C3_SMBUS_TIMEOUT: I2C3 SMBUS timeout mode stopped when 149 | * Core is halted. 150 | * @param NewState: new state of the specified APB1 peripheral in Debug mode. 151 | * This parameter can be: ENABLE or DISABLE. 152 | * @retval None 153 | */ 154 | void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) 155 | { 156 | /* Check the parameters */ 157 | assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph)); 158 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 159 | 160 | if (NewState != DISABLE) 161 | { 162 | DBGMCU->APB1FZ |= DBGMCU_Periph; 163 | } 164 | else 165 | { 166 | DBGMCU->APB1FZ &= ~DBGMCU_Periph; 167 | } 168 | } 169 | 170 | /** 171 | * @brief Configures APB2 peripheral behavior when the MCU is in Debug mode. 172 | * @param DBGMCU_Periph: specifies the APB2 peripheral. 173 | * This parameter can be any combination of the following values: 174 | * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted. 175 | * @arg DBGMCU_TIM8_STOP: TIM8 counter stopped when Core is halted. 176 | * @arg DBGMCU_TIM15_STOP: TIM15 counter stopped when Core is halted. 177 | * @arg DBGMCU_TIM16_STOP: TIM16 counter stopped when Core is halted. 178 | * @arg DBGMCU_TIM17_STOP: TIM17 counter stopped when Core is halted. 179 | * @arg DBGMCU_TIM20_STOP: TIM20 counter stopped when Core is halted. 180 | * @param NewState: new state of the specified APB2 peripheral in Debug mode. 181 | * This parameter can be: ENABLE or DISABLE. 182 | * @retval None 183 | */ 184 | void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) 185 | { 186 | /* Check the parameters */ 187 | assert_param(IS_DBGMCU_APB2PERIPH(DBGMCU_Periph)); 188 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 189 | 190 | if (NewState != DISABLE) 191 | { 192 | DBGMCU->APB2FZ |= DBGMCU_Periph; 193 | } 194 | else 195 | { 196 | DBGMCU->APB2FZ &= ~DBGMCU_Periph; 197 | } 198 | } 199 | 200 | /** 201 | * @} 202 | */ 203 | 204 | /** 205 | * @} 206 | */ 207 | 208 | /** 209 | * @} 210 | */ 211 | 212 | /** 213 | * @} 214 | */ 215 | 216 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 217 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_dbgmcu.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f30x_dbgmcu.h 4 | * @author MCD Application Team 5 | * @version V1.2.2 6 | * @date 27-February-2015 7 | * @brief This file contains all the functions prototypes for the DBGMCU firmware library. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2015 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __STM32F30x_DBGMCU_H 30 | #define __STM32F30x_DBGMCU_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /* Includes ------------------------------------------------------------------*/ 37 | #include "stm32f30x.h" 38 | 39 | /** @addtogroup STM32F30x_StdPeriph_Driver 40 | * @{ 41 | */ 42 | 43 | /** @addtogroup DBGMCU 44 | * @{ 45 | */ 46 | 47 | /* Exported types ------------------------------------------------------------*/ 48 | /* Exported constants --------------------------------------------------------*/ 49 | 50 | /** @defgroup DBGMCU_Exported_Constants 51 | * @{ 52 | */ 53 | #define DBGMCU_SLEEP ((uint32_t)0x00000001) 54 | #define DBGMCU_STOP ((uint32_t)0x00000002) 55 | #define DBGMCU_STANDBY ((uint32_t)0x00000004) 56 | #define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF8) == 0x00) && ((PERIPH) != 0x00)) 57 | 58 | #define DBGMCU_TIM2_STOP ((uint32_t)0x00000001) 59 | #define DBGMCU_TIM3_STOP ((uint32_t)0x00000002) 60 | #define DBGMCU_TIM4_STOP ((uint32_t)0x00000004) 61 | #define DBGMCU_TIM6_STOP ((uint32_t)0x00000010) 62 | #define DBGMCU_TIM7_STOP ((uint32_t)0x00000020) 63 | #define DBGMCU_RTC_STOP ((uint32_t)0x00000400) 64 | #define DBGMCU_WWDG_STOP ((uint32_t)0x00000800) 65 | #define DBGMCU_IWDG_STOP ((uint32_t)0x00001000) 66 | #define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00200000) 67 | #define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00400000) 68 | #define DBGMCU_CAN1_STOP ((uint32_t)0x02000000) 69 | #define DBGMCU_I2C3_SMBUS_TIMEOUT ((uint32_t)0x40000000) 70 | 71 | #define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xBD9FE3C8) == 0x00) && ((PERIPH) != 0x00)) 72 | 73 | #define DBGMCU_TIM1_STOP ((uint32_t)0x00000001) 74 | #define DBGMCU_TIM8_STOP ((uint32_t)0x00000002) 75 | #define DBGMCU_TIM15_STOP ((uint32_t)0x00000004) 76 | #define DBGMCU_TIM16_STOP ((uint32_t)0x00000008) 77 | #define DBGMCU_TIM17_STOP ((uint32_t)0x00000010) 78 | #define DBGMCU_TIM20_STOP ((uint32_t)0x00000020) 79 | #define IS_DBGMCU_APB2PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFC0) == 0x00) && ((PERIPH) != 0x00)) 80 | 81 | /** 82 | * @} 83 | */ 84 | 85 | /* Exported macro ------------------------------------------------------------*/ 86 | /* Exported functions --------------------------------------------------------*/ 87 | /* Device and Revision ID management functions ********************************/ 88 | uint32_t DBGMCU_GetREVID(void); 89 | uint32_t DBGMCU_GetDEVID(void); 90 | 91 | /* Peripherals Configuration functions ****************************************/ 92 | void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); 93 | void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); 94 | void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); 95 | 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | 100 | #endif /* __STM32F30x_DBGMCU_H */ 101 | 102 | /** 103 | * @} 104 | */ 105 | 106 | /** 107 | * @} 108 | */ 109 | 110 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 111 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_hrtim.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_hrtim.h -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_iwdg.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f30x_iwdg.h 4 | * @author MCD Application Team 5 | * @version V1.2.2 6 | * @date 27-February-2015 7 | * @brief This file contains all the functions prototypes for the IWDG 8 | * firmware library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2015 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F30x_IWDG_H 31 | #define __STM32F30x_IWDG_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f30x.h" 39 | 40 | /** @addtogroup STM32F30x_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup IWDG 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | /* Exported constants --------------------------------------------------------*/ 50 | 51 | /** @defgroup IWDG_Exported_Constants 52 | * @{ 53 | */ 54 | 55 | /** @defgroup IWDG_WriteAccess 56 | * @{ 57 | */ 58 | 59 | #define IWDG_WriteAccess_Enable ((uint16_t)0x5555) 60 | #define IWDG_WriteAccess_Disable ((uint16_t)0x0000) 61 | #define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ 62 | ((ACCESS) == IWDG_WriteAccess_Disable)) 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @defgroup IWDG_prescaler 68 | * @{ 69 | */ 70 | 71 | #define IWDG_Prescaler_4 ((uint8_t)0x00) 72 | #define IWDG_Prescaler_8 ((uint8_t)0x01) 73 | #define IWDG_Prescaler_16 ((uint8_t)0x02) 74 | #define IWDG_Prescaler_32 ((uint8_t)0x03) 75 | #define IWDG_Prescaler_64 ((uint8_t)0x04) 76 | #define IWDG_Prescaler_128 ((uint8_t)0x05) 77 | #define IWDG_Prescaler_256 ((uint8_t)0x06) 78 | #define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ 79 | ((PRESCALER) == IWDG_Prescaler_8) || \ 80 | ((PRESCALER) == IWDG_Prescaler_16) || \ 81 | ((PRESCALER) == IWDG_Prescaler_32) || \ 82 | ((PRESCALER) == IWDG_Prescaler_64) || \ 83 | ((PRESCALER) == IWDG_Prescaler_128)|| \ 84 | ((PRESCALER) == IWDG_Prescaler_256)) 85 | /** 86 | * @} 87 | */ 88 | 89 | /** @defgroup IWDG_Flag 90 | * @{ 91 | */ 92 | 93 | #define IWDG_FLAG_PVU ((uint16_t)0x0001) 94 | #define IWDG_FLAG_RVU ((uint16_t)0x0002) 95 | #define IWDG_FLAG_WVU ((uint16_t)0x0002) 96 | #define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU) || \ 97 | ((FLAG) == IWDG_FLAG_WVU)) 98 | /** 99 | * @} 100 | */ 101 | 102 | /** @defgroup IWDG_Reload_Value 103 | * @{ 104 | */ 105 | #define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) 106 | 107 | /** 108 | * @} 109 | */ 110 | 111 | /** @defgroup IWDG_CounterWindow_Value 112 | * @{ 113 | */ 114 | #define IS_IWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0xFFF) 115 | /** 116 | * @} 117 | */ 118 | 119 | /** 120 | * @} 121 | */ 122 | 123 | /* Exported macro ------------------------------------------------------------*/ 124 | /* Exported functions --------------------------------------------------------*/ 125 | 126 | /* Prescaler and Counter configuration functions ******************************/ 127 | void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); 128 | void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); 129 | void IWDG_SetReload(uint16_t Reload); 130 | void IWDG_ReloadCounter(void); 131 | void IWDG_SetWindowValue(uint16_t WindowValue); 132 | 133 | /* IWDG activation function ***************************************************/ 134 | void IWDG_Enable(void); 135 | 136 | /* Flag management function ***************************************************/ 137 | FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); 138 | 139 | #ifdef __cplusplus 140 | } 141 | #endif 142 | 143 | #endif /* __STM32F30x_IWDG_H */ 144 | 145 | /** 146 | * @} 147 | */ 148 | 149 | /** 150 | * @} 151 | */ 152 | 153 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 154 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_pwr.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f30x_pwr.h 4 | * @author MCD Application Team 5 | * @version V1.2.2 6 | * @date 27-February-2015 7 | * @brief This file contains all the functions prototypes for the PWR firmware 8 | * library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2015 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F30x_PWR_H 31 | #define __STM32F30x_PWR_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f30x.h" 39 | 40 | /** @addtogroup STM32F30x_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup PWR 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | /* Exported constants --------------------------------------------------------*/ 50 | 51 | /** @defgroup PWR_Exported_Constants 52 | * @{ 53 | */ 54 | 55 | /** @defgroup PWR_PVD_detection_level 56 | * @{ 57 | */ 58 | 59 | #define PWR_PVDLevel_0 PWR_CR_PLS_LEV0 60 | #define PWR_PVDLevel_1 PWR_CR_PLS_LEV1 61 | #define PWR_PVDLevel_2 PWR_CR_PLS_LEV2 62 | #define PWR_PVDLevel_3 PWR_CR_PLS_LEV3 63 | #define PWR_PVDLevel_4 PWR_CR_PLS_LEV4 64 | #define PWR_PVDLevel_5 PWR_CR_PLS_LEV5 65 | #define PWR_PVDLevel_6 PWR_CR_PLS_LEV6 66 | #define PWR_PVDLevel_7 PWR_CR_PLS_LEV7 67 | 68 | #define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_0) || ((LEVEL) == PWR_PVDLevel_1)|| \ 69 | ((LEVEL) == PWR_PVDLevel_2) || ((LEVEL) == PWR_PVDLevel_3)|| \ 70 | ((LEVEL) == PWR_PVDLevel_4) || ((LEVEL) == PWR_PVDLevel_5)|| \ 71 | ((LEVEL) == PWR_PVDLevel_6) || ((LEVEL) == PWR_PVDLevel_7)) 72 | /** 73 | * @} 74 | */ 75 | 76 | /** @defgroup PWR_WakeUp_Pins 77 | * @{ 78 | */ 79 | 80 | #define PWR_WakeUpPin_1 PWR_CSR_EWUP1 81 | #define PWR_WakeUpPin_2 PWR_CSR_EWUP2 82 | #define PWR_WakeUpPin_3 PWR_CSR_EWUP3 83 | #define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WakeUpPin_1) || \ 84 | ((PIN) == PWR_WakeUpPin_2) || \ 85 | ((PIN) == PWR_WakeUpPin_3)) 86 | /** 87 | * @} 88 | */ 89 | 90 | 91 | /** @defgroup PWR_Regulator_state_is_Sleep_STOP_mode 92 | * @{ 93 | */ 94 | 95 | #define PWR_Regulator_ON ((uint32_t)0x00000000) 96 | #define PWR_Regulator_LowPower PWR_CR_LPSDSR 97 | #define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ 98 | ((REGULATOR) == PWR_Regulator_LowPower)) 99 | /** 100 | * @} 101 | */ 102 | 103 | /** @defgroup PWR_SLEEP_mode_entry 104 | * @{ 105 | */ 106 | 107 | #define PWR_SLEEPEntry_WFI ((uint8_t)0x01) 108 | #define PWR_SLEEPEntry_WFE ((uint8_t)0x02) 109 | #define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPEntry_WFI) || ((ENTRY) == PWR_SLEEPEntry_WFE)) 110 | 111 | /** 112 | * @} 113 | */ 114 | 115 | /** @defgroup PWR_STOP_mode_entry 116 | * @{ 117 | */ 118 | 119 | #define PWR_STOPEntry_WFI ((uint8_t)0x01) 120 | #define PWR_STOPEntry_WFE ((uint8_t)0x02) 121 | #define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) 122 | 123 | /** 124 | * @} 125 | */ 126 | 127 | /** @defgroup PWR_Flag 128 | * @{ 129 | */ 130 | 131 | #define PWR_FLAG_WU PWR_CSR_WUF 132 | #define PWR_FLAG_SB PWR_CSR_SBF 133 | #define PWR_FLAG_PVDO PWR_CSR_PVDO 134 | #define PWR_FLAG_VREFINTRDY PWR_CSR_VREFINTRDYF 135 | 136 | #define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ 137 | ((FLAG) == PWR_FLAG_PVDO) || ((FLAG) == PWR_FLAG_VREFINTRDY)) 138 | 139 | #define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) 140 | /** 141 | * @} 142 | */ 143 | 144 | /** 145 | * @} 146 | */ 147 | 148 | /* Exported macro ------------------------------------------------------------*/ 149 | /* Exported functions ------------------------------------------------------- */ 150 | 151 | /* Function used to set the PWR configuration to the default reset state ******/ 152 | void PWR_DeInit(void); 153 | 154 | /* Backup Domain Access function **********************************************/ 155 | void PWR_BackupAccessCmd(FunctionalState NewState); 156 | 157 | /* PVD configuration functions ************************************************/ 158 | void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); 159 | void PWR_PVDCmd(FunctionalState NewState); 160 | 161 | /* WakeUp pins configuration functions ****************************************/ 162 | void PWR_WakeUpPinCmd(uint32_t PWR_WakeUpPin, FunctionalState NewState); 163 | 164 | /* Low Power modes configuration functions ************************************/ 165 | void PWR_EnterSleepMode(uint8_t PWR_SLEEPEntry); 166 | void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); 167 | void PWR_EnterSTANDBYMode(void); 168 | 169 | /* Flags management functions *************************************************/ 170 | FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); 171 | void PWR_ClearFlag(uint32_t PWR_FLAG); 172 | 173 | #ifdef __cplusplus 174 | } 175 | #endif 176 | 177 | #endif /* __STM32F30x_PWR_H */ 178 | 179 | /** 180 | * @} 181 | */ 182 | 183 | /** 184 | * @} 185 | */ 186 | 187 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 188 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/StdPeriph/stm32f30x_wwdg.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f30x_wwdg.h 4 | * @author MCD Application Team 5 | * @version V1.2.2 6 | * @date 27-February-2015 7 | * @brief This file contains all the functions prototypes for the WWDG 8 | * firmware library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2015 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F30x_WWDG_H 31 | #define __STM32F30x_WWDG_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f30x.h" 39 | 40 | /** @addtogroup STM32F30x_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup WWDG 45 | * @{ 46 | */ 47 | /* Exported types ------------------------------------------------------------*/ 48 | /* Exported constants --------------------------------------------------------*/ 49 | 50 | /** @defgroup WWDG_Exported_Constants 51 | * @{ 52 | */ 53 | 54 | /** @defgroup WWDG_Prescaler 55 | * @{ 56 | */ 57 | 58 | #define WWDG_Prescaler_1 ((uint32_t)0x00000000) 59 | #define WWDG_Prescaler_2 ((uint32_t)0x00000080) 60 | #define WWDG_Prescaler_4 ((uint32_t)0x00000100) 61 | #define WWDG_Prescaler_8 ((uint32_t)0x00000180) 62 | #define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ 63 | ((PRESCALER) == WWDG_Prescaler_2) || \ 64 | ((PRESCALER) == WWDG_Prescaler_4) || \ 65 | ((PRESCALER) == WWDG_Prescaler_8)) 66 | #define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) 67 | #define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) 68 | 69 | /** 70 | * @} 71 | */ 72 | 73 | /** 74 | * @} 75 | */ 76 | 77 | /* Exported macro ------------------------------------------------------------*/ 78 | /* Exported functions ------------------------------------------------------- */ 79 | /* Function used to set the WWDG configuration to the default reset state ****/ 80 | void WWDG_DeInit(void); 81 | 82 | /* Prescaler, Refresh window and Counter configuration functions **************/ 83 | void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); 84 | void WWDG_SetWindowValue(uint8_t WindowValue); 85 | void WWDG_EnableIT(void); 86 | void WWDG_SetCounter(uint8_t Counter); 87 | 88 | /* WWDG activation functions **************************************************/ 89 | void WWDG_Enable(uint8_t Counter); 90 | 91 | /* Interrupts and flags management functions **********************************/ 92 | FlagStatus WWDG_GetFlagStatus(void); 93 | void WWDG_ClearFlag(void); 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif /* __STM32F30x_WWDG_H */ 100 | 101 | /** 102 | * @} 103 | */ 104 | 105 | /** 106 | * @} 107 | */ 108 | 109 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 110 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/adc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * adc.c - adc setup & isr for stm32f303 3 | * 07-04-2013 E. Brombaugh 4 | */ 5 | 6 | #include "adc.h" 7 | #include "cyclesleep.h" 8 | 9 | __IO uint16_t ADC_Buffer[ADC_BUFSZ]; 10 | __IO uint16_t ADC_Channels[ADC_CHANNELS]; 11 | __IO uint16_t calibration_value_1 = 0; 12 | 13 | void setup_adc(void) 14 | { 15 | GPIO_InitTypeDef GPIO_InitStructure; 16 | DMA_InitTypeDef DMA_InitStructure; 17 | ADC_InitTypeDef ADC_InitStructure; 18 | 19 | /* Configure the ADC clock */ 20 | RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1); 21 | 22 | /* Enable ADC1 clock */ 23 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE); 24 | 25 | /* Enable GPIOA,C Periph clock */ 26 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); 27 | 28 | /* Configure ADC1/2 Channel1-4 as analog input */ 29 | //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0; 30 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 31 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 32 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; 33 | GPIO_Init(GPIOA, &GPIO_InitStructure); 34 | 35 | /* Configure PC13 as 50MHz pp for diag pulse */ 36 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); 37 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; 38 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 39 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 40 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 41 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; 42 | GPIO_Init(GPIOC, &GPIO_InitStructure); 43 | 44 | /* Enable DMA1 clock */ 45 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 46 | 47 | /* DMA1 Channel1 Init */ 48 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; 49 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Buffer; 50 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 51 | DMA_InitStructure.DMA_BufferSize = ADC_BUFSZ; 52 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 53 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 54 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 55 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 56 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 57 | DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 58 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 59 | 60 | DMA_Init(DMA1_Channel1, &DMA_InitStructure); 61 | 62 | /* DMA interrupts */ 63 | DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); 64 | 65 | /* enable DMA IRQ */ 66 | NVIC_EnableIRQ(DMA1_Channel1_IRQn); 67 | 68 | /* ADC Calibration procedure */ 69 | ADC_VoltageRegulatorCmd(ADC1, ENABLE); 70 | 71 | /* Insert delay equal to 10 ms */ 72 | delay(10); 73 | 74 | ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single); 75 | 76 | ADC_SelectCalibrationMode(ADC2, ADC_CalibrationMode_Single); 77 | 78 | while(ADC_GetCalibrationStatus(ADC1) != RESET ); 79 | calibration_value_1 = ADC_GetCalibrationValue(ADC1); 80 | 81 | /* ADC setup */ 82 | ADC_StructInit(&ADC_InitStructure); 83 | ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable; 84 | ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; 85 | ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0; 86 | ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None; 87 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 88 | ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable; 89 | ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable; 90 | ADC_InitStructure.ADC_NbrOfRegChannel = ADC_CHANNELS; 91 | ADC_Init(ADC1, &ADC_InitStructure); 92 | 93 | /* ADC1 regular channel configuration */ 94 | ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_601Cycles5); 95 | //ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_601Cycles5); 96 | //ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_601Cycles5); 97 | //ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_601Cycles5); 98 | 99 | /* Configures the ADC DMA */ 100 | ADC_DMAConfig(ADC1, ADC_DMAMode_Circular); 101 | 102 | /* Enable the ADC DMA */ 103 | ADC_DMACmd(ADC1, ENABLE); 104 | 105 | /* Enable ADC1 */ 106 | ADC_Cmd(ADC1, ENABLE); 107 | 108 | /* wait for ADC1 ADRDY */ 109 | while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY)); 110 | 111 | /* Enable the DMA channel */ 112 | DMA_Cmd(DMA1_Channel1, ENABLE); 113 | 114 | /* Start ADC1 Software Conversion */ 115 | ADC_StartConversion(ADC1); 116 | 117 | } 118 | 119 | /* Handles DMA1_Channel1 (ADC Buffer) interrupt request */ 120 | void DMA1_Channel1_IRQHandler(void) 121 | { 122 | uint32_t accum[ADC_CHANNELS]; 123 | int16_t i, j; 124 | 125 | /* Active ISR */ 126 | GPIOC->BSRR |= (1<<13); 127 | 128 | /* Transfer Complete? */ 129 | if(DMA1->ISR & DMA1_IT_TC1) 130 | { 131 | #if 1 132 | /* clear accumulators */ 133 | for(j=0;j>4); 146 | #else 147 | /* copy samples */ 148 | for(i=0;iIFCR = DMA_IFCR_CGIF1; 157 | 158 | /* Inactive ISR */ 159 | GPIOC->BRR |= (1<<13); 160 | } 161 | 162 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/adc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * adc.h - adc setup & isr for stm32f303 3 | * 01-28-2013 E. Brombaugh 4 | */ 5 | 6 | #ifndef __adc__ 7 | #define __adc__ 8 | 9 | #include "stm32f30x.h" 10 | 11 | #define ADC_CHANNELS 4 12 | #define ADC_SAMPLES 16 13 | #define ADC_BUFSZ (ADC_CHANNELS*ADC_SAMPLES) 14 | 15 | extern __IO uint16_t ADC_Channels[ADC_CHANNELS]; 16 | 17 | void setup_adc(void); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/audio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * audio.h - audio processing routines 3 | */ 4 | 5 | #ifndef __audio__ 6 | #define __audio__ 7 | 8 | #include "stm32f30x.h" 9 | #include "arm_math.h" 10 | 11 | #define DMA_BUFFSZ 128 12 | 13 | void Audio_Init(void); 14 | void Audio_SetFilter(uint8_t filter); 15 | uint8_t Audio_GetFilter(void); 16 | int16_t Audio_GetRSSI(void); 17 | void Audio_SetDemod(uint8_t demod); 18 | int8_t Audio_GetDemod(void); 19 | void Audio_SetMute(uint8_t State); 20 | uint16_t Audio_GetMute(void); 21 | int16_t Audio_GetParam(void); 22 | int16_t Audio_GetSyncFrq(void); 23 | int16_t Audio_GetSyncSt(void); 24 | void Audio_Proc(int16_t *src, int16_t *dst); 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/audio_lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * audio_lib.c - miscellaneous audio processing functions 3 | */ 4 | 5 | #include "audio_lib.h" 6 | #include "stdlib.h" 7 | 8 | /** 9 | * @brief Split interleaved stereo into two separate buffers 10 | * @param sz - samples per input buffer (divisible by 2) 11 | * @param src - pointer to source buffer 12 | * @param ldst - pointer to left dest buffer (even samples) 13 | * @param rdst - pointer to right dest buffer (odd samples) 14 | * @retval none 15 | */ 16 | void audio_split_stereo(int16_t sz, int16_t *src, int16_t *ldst, int16_t *rdst) 17 | { 18 | while(sz) 19 | { 20 | *ldst++ = *src++; 21 | sz--; 22 | *rdst++ = *src++; 23 | sz--; 24 | } 25 | } 26 | 27 | /** 28 | * @brief sums left and right into left and right with saturation 29 | * @param sz - samples per input buffer (divisible by 2) 30 | * @param lsrc - pointer to left source/dest buffer 31 | * @param rsrc - pointer to right source/dest buffer 32 | * @retval none 33 | */ 34 | void audio_sum_stereo(int16_t sz, int16_t *lsrc, int16_t *rsrc) 35 | { 36 | int32_t sum; 37 | 38 | while(sz) 39 | { 40 | sum = *lsrc + *rsrc; 41 | int16_t sat = audio_sat(sum); 42 | *rsrc++ = sat; 43 | *lsrc++ = sat; 44 | sz--; 45 | } 46 | } 47 | 48 | /** 49 | * @brief copies src to dst 50 | * @param sz - samples per input buffer (divisible by 2) 51 | * @param dst - pointer to dest buffer 52 | * @param src - pointer to source buffer 53 | * @retval none 54 | */ 55 | void audio_copy(int16_t sz, int16_t *dst, int16_t *src) 56 | { 57 | while(sz) 58 | { 59 | *dst++ = *src++; 60 | sz--; 61 | } 62 | } 63 | 64 | /** 65 | * @brief computes dst = dst*g0 + src1*g1 + src2*g2 66 | * @param sz - samples per input buffer (divisible by 2) 67 | * @param dst - pointer to dest buffer 68 | * @param src1 - pointer to source1 buffer 69 | * @param src2 - pointer to source2 buffer 70 | * @param g0 - gain for dst 71 | * @param g1 - gain for src1 72 | * @param g2 - gain for src2 73 | * @retval none 74 | */ 75 | void audio_sop3(int16_t sz, int16_t *dst, int16_t *src1, int16_t *src2, float32_t g0, 76 | float32_t g1, float32_t g2) 77 | { 78 | float32_t f_sum; 79 | 80 | while(sz) 81 | { 82 | f_sum = (float32_t)*dst * g0; 83 | f_sum += (float32_t)*src1++ * g1; 84 | f_sum += (float32_t)*src2++ * g2; 85 | *dst++ = audio_sat(f_sum); 86 | sz--; 87 | } 88 | } 89 | 90 | /** 91 | * @brief computes dst = dst*g0 + src1*g1 92 | * @param sz - samples per input buffer (divisible by 2) 93 | * @param dst - pointer to dest buffer 94 | * @param src1 - pointer to source1 buffer 95 | * @param g0 - gain for dst 96 | * @param g1 - gain for src1 97 | * @retval none 98 | */ 99 | void audio_sop2(int16_t sz, int16_t *dst, int16_t *src1, float32_t g0, float32_t g1) 100 | { 101 | float32_t f_sum; 102 | 103 | while(sz) 104 | { 105 | f_sum = (float32_t)*dst * g0; 106 | f_sum += (float32_t)*src1++ * g1; 107 | *dst++ = audio_sat(f_sum); 108 | sz--; 109 | } 110 | } 111 | 112 | /** 113 | * @brief check a buffer for clipping 114 | * @param sz - samples per input buffer (divisible by 2) 115 | * @param src - pointer to source buffer 116 | * @retval 1 if clipping detected 117 | */ 118 | uint8_t audio_clip(int16_t sz, int16_t *src, int16_t thresh) 119 | { 120 | uint8_t clip = 0; 121 | 122 | while(sz) 123 | { 124 | if(abs(*src++)>thresh) 125 | clip = 1; 126 | sz--; 127 | } 128 | 129 | return clip; 130 | } 131 | 132 | /** 133 | * @brief copy src to dst with gain 134 | * @param sz - samples per buffer 135 | * @param dst - pointer to source buffer 136 | * @param src - pointer to dest buffer 137 | * @param gain - float gain coeff. 138 | * @retval none 139 | */ 140 | void audio_gain(int16_t sz, int16_t *dst, int16_t *src, float32_t gain) 141 | { 142 | float32_t f_sum; 143 | 144 | while(sz--) 145 | { 146 | /* apply gain */ 147 | f_sum = (float32_t)*src++ * gain; 148 | 149 | /* saturate and save to destination */ 150 | *dst++ = audio_sat(f_sum); 151 | } 152 | } 153 | 154 | /** 155 | * @brief sum src to dst with gain 156 | * @param sz - samples per buffer 157 | * @param dst - pointer to source buffer 158 | * @param src - pointer to dest buffer 159 | * @param gain - float gain coeff. 160 | * @retval none 161 | */ 162 | void audio_gain_sum(int16_t sz, int16_t *dst, int16_t *src, float32_t gain) 163 | { 164 | float32_t f_sum; 165 | 166 | while(sz--) 167 | { 168 | f_sum = (float32_t)*src++ * gain + (float32_t)*dst; 169 | 170 | /* saturate and save to destination */ 171 | *dst++ = audio_sat(f_sum); 172 | } 173 | } 174 | 175 | /** 176 | * @brief combine two separate buffers into interleaved stereo 177 | * @param sz - samples per output buffer (divisible by 2) 178 | * @param dst - pointer to source buffer 179 | * @param lsrc - pointer to left dest buffer (even samples) 180 | * @param rsrc - pointer to right dest buffer (odd samples) 181 | * @retval none 182 | */ 183 | void audio_comb_stereo(int16_t sz, int16_t *dst, int16_t *lsrc, int16_t *rsrc) 184 | { 185 | while(sz) 186 | { 187 | *dst++ = *lsrc++; 188 | sz--; 189 | *dst++ = *rsrc++; 190 | sz--; 191 | } 192 | } 193 | 194 | /** 195 | * @brief morph a to b into destination 196 | * @param sz - samples per buffer 197 | * @param dst - pointer to source buffer 198 | * @param asrc - pointer to dest buffer 199 | * @param bsrc - pointer to dest buffer 200 | * @param morph - float morph coeff. 0 = a, 1 = b 201 | * @retval none 202 | */ 203 | void audio_morph(int16_t sz, int16_t *dst, int16_t *asrc, int16_t *bsrc, 204 | float32_t morph) 205 | { 206 | float32_t morph_inv = 1.0F - morph, f_sum; 207 | 208 | while(sz--) 209 | { 210 | f_sum = (float32_t)*asrc++ * morph_inv + (float32_t)*bsrc++ * morph; 211 | 212 | /* save to destination */ 213 | *dst++ = audio_sat(f_sum); 214 | } 215 | } 216 | 217 | #if 0 218 | /** 219 | * @brief constant power mix a & b into destination 220 | * @param sz - samples per buffer 221 | * @param dst - pointer to source buffer 222 | * @param asrc - pointer to dest buffer 223 | * @param bsrc - pointer to dest buffer 224 | * @param morph - 0-4095 mix index 0 = a, 4095 = b 225 | * @retval none 226 | */ 227 | void audio_cpmix(int16_t sz, int16_t *dst, int16_t *asrc, int16_t *bsrc, 228 | int16_t mix) 229 | { 230 | float32_t morph, morph_inv, f_sum; 231 | 232 | /* get gain coeffs from pre-computed table */ 233 | morph = gaintab[mix]; 234 | morph_inv = gaintab[4095-mix]; 235 | 236 | while(sz--) 237 | { 238 | f_sum = (float32_t)*asrc++ * morph_inv + (float32_t)*bsrc++ * morph; 239 | 240 | /* save to destination */ 241 | *dst++ = audio_sat(f_sum); 242 | } 243 | } 244 | #endif 245 | 246 | /** 247 | * @brief approximate constant power mix a & b into destination 248 | * @param sz - samples per buffer 249 | * @param dst - pointer to source buffer 250 | * @param asrc - pointer to dest buffer 251 | * @param bsrc - pointer to dest buffer 252 | * @param mix - float mix value 0 = a, 1.0 = b 253 | * @retval none 254 | */ 255 | void audio_cp2mix(int16_t sz, int16_t *dst, int16_t *asrc, int16_t *bsrc, 256 | float32_t mix) 257 | { 258 | float32_t morph, morph_inv, f_sum; 259 | 260 | /* get gain coeffs with approx function */ 261 | morph = 1.0F-((1.0F-mix)*(1.0F-mix)); 262 | morph_inv = 1.0F-(mix*mix); 263 | 264 | while(sz--) 265 | { 266 | f_sum = (float32_t)*asrc++ * morph_inv + (float32_t)*bsrc++ * morph; 267 | 268 | /* save to destination */ 269 | *dst++ = audio_sat(f_sum); 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/audio_lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * audio_lib.h - miscellaneous audio processing functions 3 | */ 4 | 5 | #ifndef __audio_lib__ 6 | #define __audio_lib__ 7 | 8 | #include "stm32f30x.h" 9 | #include "arm_math.h" 10 | 11 | /** 12 | * @brief saturate 32 bits down to 16 bits 13 | * @param in - 32-bit signed int 14 | * @retval 16-bit signed int 15 | */ 16 | inline int16_t audio_sat(int32_t in) 17 | { 18 | #if 1 19 | /* manual saturation */ 20 | in = in > 32767 ? 32767 : in; 21 | in = in < -32768 ? -32768 : in; 22 | #else 23 | /* using ARM Cortex M4 signed saturation instruction */ 24 | asm("ssat %[dst], #16, %[src]" : [dst] "=r" (in) : [src] "r" (in)); 25 | #endif 26 | return in; 27 | } 28 | 29 | void audio_split_stereo(int16_t sz, int16_t *src, int16_t *ldst, int16_t *rdst); 30 | uint8_t audio_clip(int16_t sz, int16_t *src, int16_t thresh); 31 | void audio_sum_stereo(int16_t sz, int16_t *lsrc, int16_t *rsrc); 32 | void audio_copy(int16_t sz, int16_t *dst, int16_t *src); 33 | void audio_sop3(int16_t sz, int16_t *dst, int16_t *src1, int16_t *src2, float32_t g0, 34 | float32_t g1, float32_t g2); 35 | void audio_sop2(int16_t sz, int16_t *dst, int16_t *src1, float32_t g0, float32_t g1); 36 | void audio_gain(int16_t sz, int16_t *dst, int16_t *src, float32_t gain); 37 | void audio_gain_sum(int16_t sz, int16_t *dst, int16_t *src, float32_t gain); 38 | void audio_comb_stereo(int16_t sz, int16_t *dst, int16_t *lsrc, int16_t *rsrc); 39 | void audio_morph(int16_t sz, int16_t *dst, int16_t *asrc, int16_t *bsrc, 40 | float32_t morph); 41 | //void audio_cpmix(int16_t sz, int16_t *dst, int16_t *asrc, int16_t *bsrc, 42 | // int16_t mix); 43 | void audio_cp2mix(int16_t sz, int16_t *dst, int16_t *asrc, int16_t *bsrc, 44 | float32_t mix); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/bitmap.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/bitmap.bin -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/cmd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cmd.h - Command parsing routines for STM32F303 breakout SPI to ice5 FPGA 3 | * 05-11-16 E. Brombaugh 4 | */ 5 | 6 | #ifndef __cmd__ 7 | #define __cmd__ 8 | 9 | void init_cmd(void); 10 | void cmd_parse(char ch); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/cyclesleep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cyclesleep.c - zyp's cycle counter sleep routines 3 | * 12-20-12 E. Brombaugh 4 | */ 5 | 6 | #include "cyclesleep.h" 7 | 8 | volatile uint32_t* demcr = (uint32_t*)0xE000EDFC; 9 | volatile uint32_t* dwt_ctrl = (uint32_t*)0xe0001000; 10 | volatile uint32_t* dwt_cyccnt = (uint32_t*)0xe0001004; 11 | uint32_t DelayCyc1s; 12 | 13 | /* get sysclock freq */ 14 | uint32_t get_sysclk(void) 15 | { 16 | RCC_ClocksTypeDef RCC_Clocks; 17 | 18 | /* Compute Delay amount */ 19 | RCC_GetClocksFreq(&RCC_Clocks); 20 | return RCC_Clocks.SYSCLK_Frequency; 21 | } 22 | 23 | // turn on cycle counter 24 | void cyccnt_enable() 25 | { 26 | *demcr |= (1<<24); 27 | *dwt_ctrl |= 1; 28 | DelayCyc1s = get_sysclk(); 29 | } 30 | 31 | uint32_t cyclegoal(uint32_t cycles) 32 | { 33 | return cycles + *dwt_cyccnt; 34 | } 35 | 36 | uint32_t cyclegoal_ms(uint32_t ms) 37 | { 38 | return ms*(DelayCyc1s/1000) + *dwt_cyccnt; 39 | } 40 | 41 | uint32_t cyclecheck(uint32_t goal) 42 | { 43 | return *dwt_cyccnt < goal; 44 | } 45 | 46 | // sleep for a certain number of cycles 47 | void cyclesleep(uint32_t cycles) 48 | { 49 | uint32_t goal = cyclegoal(cycles); 50 | 51 | while(cyclecheck(goal)); 52 | } 53 | 54 | // sleep for a certain number of milliseconds 55 | void delay(uint32_t ms) 56 | { 57 | cyclesleep(ms*(DelayCyc1s/1000)); 58 | } 59 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/cyclesleep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cyclesleep.h - zyp's cycle counter sleep routines 3 | * 12-20-12 E. Brombaugh 4 | */ 5 | 6 | #ifndef __cyclesleep__ 7 | #define __cyclesleep__ 8 | 9 | #include "stm32f30x.h" 10 | 11 | #define CYCLES_PER_SEC 0x044aa200 12 | 13 | void cyccnt_enable(); 14 | void cyclesleep(uint32_t cycles); 15 | uint32_t cyclegoal(uint32_t cycles); 16 | uint32_t cyclegoal_ms(uint32_t ms); 17 | uint32_t cyclecheck(uint32_t goal); 18 | void delay(uint32_t ms); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/debounce.c: -------------------------------------------------------------------------------- 1 | /* 2 | * debounce.c - simple button debouncer. 3 | */ 4 | 5 | #include "debounce.h" 6 | 7 | void init_debounce(debounce_state *dbs, uint8_t len) 8 | { 9 | dbs->pipe = 0; 10 | dbs->state = 0; 11 | dbs->prev_state = 0; 12 | dbs->re = 0; 13 | dbs->fe = 0; 14 | dbs->mask = (1<pipe = (dbs->pipe << 1) | (in & 1); 21 | 22 | /* update old state */ 23 | dbs->prev_state = dbs->state; 24 | 25 | /* update current state */ 26 | if(dbs->state) 27 | { 28 | /* 1 state - look for all zero in the pipe */ 29 | if((dbs->pipe & dbs->mask) == 0) 30 | dbs->state = 0; 31 | } 32 | else 33 | { 34 | /* 0 state - look for all one in the pipe */ 35 | if((dbs->pipe & dbs->mask) == dbs->mask) 36 | dbs->state = 1; 37 | } 38 | 39 | /* detect rising edge (button pushed) */ 40 | if(dbs->prev_state == 0 && dbs->state == 1) 41 | dbs->re = 1; 42 | else 43 | dbs->re = 0; 44 | 45 | /* detect falling edge (button released) */ 46 | if(dbs->prev_state == 1 && dbs->state == 0) 47 | dbs->fe = 1; 48 | else 49 | dbs->fe = 0; 50 | } 51 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/debounce.h: -------------------------------------------------------------------------------- 1 | /* 2 | * debounce.h - simple button debouncer 3 | */ 4 | 5 | #ifndef __debounce__ 6 | #define __debounce__ 7 | 8 | #include "stm32f30x.h" 9 | 10 | typedef struct 11 | { 12 | uint16_t pipe; 13 | uint8_t state; 14 | uint8_t prev_state; 15 | uint8_t re; 16 | uint8_t fe; 17 | uint16_t mask; 18 | } debounce_state; 19 | 20 | void init_debounce(debounce_state *dbs, uint8_t len); 21 | void debounce(debounce_state *dbs, uint32_t in); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/ff9a/00readme.txt: -------------------------------------------------------------------------------- 1 | FatFs Module Source Files R0.09a (C)ChaN, 2012 2 | 3 | 4 | FILES 5 | 6 | ffconf.h Configuration file for FatFs module. 7 | ff.h Common include file for FatFs and application module. 8 | ff.c FatFs module. 9 | diskio.h Common include file for FatFs and disk I/O module. 10 | diskio.c An example of glue function to attach existing disk I/O module to FatFs. 11 | integer.h Integer type definitions for FatFs. 12 | option Optional external functions. 13 | 14 | Low level disk I/O module is not included in this archive because the FatFs 15 | module is only a generic file system layer and not depend on any specific 16 | storage device. You have to provide a low level disk I/O module that written 17 | to control your storage device. 18 | 19 | 20 | 21 | AGREEMENTS 22 | 23 | FatFs module is an open source software to implement FAT file system to 24 | small embedded systems. This is a free software and is opened for education, 25 | research and commercial developments under license policy of following trems. 26 | 27 | Copyright (C) 2012, ChaN, all right reserved. 28 | 29 | * The FatFs module is a free software and there is NO WARRANTY. 30 | * No restriction on use. You can use, modify and redistribute it for 31 | personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. 32 | * Redistributions of source code must retain the above copyright notice. 33 | 34 | 35 | 36 | REVISION HISTORY 37 | 38 | Feb 26, 2006 R0.00 Prototype 39 | 40 | Apr 29, 2006 R0.01 First release. 41 | 42 | Jun 01, 2006 R0.02 Added FAT12. 43 | Removed unbuffered mode. 44 | Fixed a problem on small (<32M) patition. 45 | 46 | Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM. 47 | 48 | Sep 22, 2006 R0.03 Added f_rename. 49 | Changed option _FS_MINIMUM to _FS_MINIMIZE. 50 | 51 | Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast. 52 | Fixed f_mkdir creates incorrect directory on FAT32. 53 | 54 | Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs) 55 | Changed some APIs for multiple drive system. 56 | Added f_mkfs. (FatFs) 57 | Added _USE_FAT32 option. (Tiny-FatFs) 58 | 59 | Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs) 60 | Fixed an endian sensitive code in f_mkfs. (FatFs) 61 | Added a capability of extending the file size to f_lseek. 62 | Added minimization level 3. 63 | Fixed a problem that can collapse a sector when recreate an 64 | existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs) 65 | 66 | May 05, 2007 R0.04b Added _USE_NTFLAG option. 67 | Added FSInfo support. 68 | Fixed some problems corresponds to FAT32. (Tiny-FatFs) 69 | Fixed DBCS name can result FR_INVALID_NAME. 70 | Fixed short seek (0 < ofs <= csize) collapses the file object. 71 | 72 | Aug 25, 2007 R0.05 Changed arguments of f_read, f_write. 73 | Changed arguments of f_mkfs. (FatFs) 74 | Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) 75 | Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) 76 | 77 | Feb 03, 2008 R0.05a Added f_truncate(). 78 | Added f_utime(). 79 | Fixed off by one error at FAT sub-type determination. 80 | Fixed btr in f_read() can be mistruncated. 81 | Fixed cached sector is not flushed when create and close without write. 82 | 83 | Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs) 84 | Added string functions: fputc(), fputs(), fprintf() and fgets(). 85 | Improved performance of f_lseek() on move to the same or following cluster. 86 | 87 | Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option. 88 | Added long file name support. 89 | Added multiple code page support. 90 | Added re-entrancy for multitask operation. 91 | Added auto cluster size selection to f_mkfs(). 92 | Added rewind option to f_readdir(). 93 | Changed result code of critical errors. 94 | Renamed string functions to avoid name collision. 95 | 96 | Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg. 97 | Added multiple sector size support. 98 | 99 | Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error. 100 | Fixed wrong cache control in f_lseek(). 101 | Added relative path feature. 102 | Added f_chdir(). 103 | Added f_chdrive(). 104 | Added proper case conversion for extended characters. 105 | 106 | Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h. 107 | Added a configuration option, _LFN_UNICODE. 108 | Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. 109 | Fixed name matching error on the 13 char boundary. 110 | Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. 111 | 112 | May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN) 113 | Added file lock feature. (_FS_SHARE) 114 | Added fast seek feature. (_USE_FASTSEEK) 115 | Changed some types on the API, XCHAR->TCHAR. 116 | Changed fname member in the FILINFO structure on Unicode cfg. 117 | String functions support UTF-8 encoding files on Unicode cfg. 118 | 119 | Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2) 120 | Added sector erase feature. (_USE_ERASE) 121 | Moved file lock semaphore table from fs object to the bss. 122 | Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'. 123 | Fixed f_mkfs() creates wrong FAT32 volume. 124 | 125 | Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). 126 | f_lseek() reports required table size on creating CLMP. 127 | Extended format syntax of f_printf function. 128 | Ignores duplicated directory separators in given path names. 129 | 130 | Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature. 131 | Added f_fdisk(). (_MULTI_PARTITION = 2) 132 | 133 | Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16. 134 | Changed f_open() and f_opendir() reject null object pointer to avoid crash. 135 | Changed option name _FS_SHARE to _FS_LOCK. 136 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/ff9a/diskio.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------- 2 | / Low level disk interface modlue include file (C)ChaN, 2012 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #define _USE_WRITE 1 /* 1: Enable disk_write function */ 13 | #define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */ 14 | 15 | #include "integer.h" 16 | 17 | 18 | /* Status of Disk Functions */ 19 | typedef BYTE DSTATUS; 20 | 21 | /* Results of Disk Functions */ 22 | typedef enum { 23 | RES_OK = 0, /* 0: Successful */ 24 | RES_ERROR, /* 1: R/W Error */ 25 | RES_WRPRT, /* 2: Write Protected */ 26 | RES_NOTRDY, /* 3: Not Ready */ 27 | RES_PARERR /* 4: Invalid Parameter */ 28 | } DRESULT; 29 | 30 | 31 | /*---------------------------------------*/ 32 | /* Prototypes for disk control functions */ 33 | 34 | 35 | DSTATUS disk_initialize (BYTE); 36 | DSTATUS disk_status (BYTE); 37 | DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); 38 | DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); 39 | DRESULT disk_ioctl (BYTE, BYTE, void*); 40 | 41 | 42 | /* Disk Status Bits (DSTATUS) */ 43 | #define STA_NOINIT 0x01 /* Drive not initialized */ 44 | #define STA_NODISK 0x02 /* No medium in the drive */ 45 | #define STA_PROTECT 0x04 /* Write protected */ 46 | 47 | 48 | /* Command code for disk_ioctrl fucntion */ 49 | 50 | /* Generic command (used by FatFs) */ 51 | #define CTRL_SYNC 0 /* Flush disk cache (for write functions) */ 52 | #define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */ 53 | #define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */ 54 | #define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */ 55 | #define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */ 56 | 57 | /* Generic command (not used by FatFs) */ 58 | #define CTRL_POWER 5 /* Get/Set power status */ 59 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 60 | #define CTRL_EJECT 7 /* Eject media */ 61 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 62 | 63 | /* MMC/SDC specific ioctl command */ 64 | #define MMC_GET_TYPE 10 /* Get card type */ 65 | #define MMC_GET_CSD 11 /* Get CSD */ 66 | #define MMC_GET_CID 12 /* Get CID */ 67 | #define MMC_GET_OCR 13 /* Get OCR */ 68 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 69 | 70 | /* ATA/CF specific ioctl command */ 71 | #define ATA_GET_REV 20 /* Get F/W revision */ 72 | #define ATA_GET_MODEL 21 /* Get model name */ 73 | #define ATA_GET_SN 22 /* Get serial number */ 74 | 75 | 76 | /* MMC card type flags (MMC_GET_TYPE) */ 77 | #define CT_MMC 0x01 /* MMC ver 3 */ 78 | #define CT_SD1 0x02 /* SD ver 1 */ 79 | #define CT_SD2 0x04 /* SD ver 2 */ 80 | #define CT_SDC (CT_SD1|CT_SD2) /* SD */ 81 | #define CT_BLOCK 0x08 /* Block addressing */ 82 | 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/ff9a/ffconf.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------/ 2 | / FatFs - FAT file system module configuration file R0.09a (C)ChaN, 2012 3 | /----------------------------------------------------------------------------/ 4 | / 5 | / CAUTION! Do not forget to make clean the project after any changes to 6 | / the configuration options. 7 | / 8 | /----------------------------------------------------------------------------*/ 9 | #ifndef _FFCONF 10 | #define _FFCONF 4004 /* Revision ID */ 11 | 12 | 13 | /*---------------------------------------------------------------------------/ 14 | / Functions and Buffer Configurations 15 | /----------------------------------------------------------------------------*/ 16 | 17 | #define _FS_TINY 0 /* 0:Normal or 1:Tiny */ 18 | /* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system 19 | / object instead of the sector buffer in the individual file object for file 20 | / data transfer. This reduces memory consumption 512 bytes each file object. */ 21 | 22 | 23 | #define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */ 24 | /* Setting _FS_READONLY to 1 defines read only configuration. This removes 25 | / writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, 26 | / f_truncate and useless f_getfree. */ 27 | 28 | 29 | #define _FS_MINIMIZE 1 /* 0 to 3 */ 30 | /* The _FS_MINIMIZE option defines minimization level to remove some functions. 31 | / 32 | / 0: Full function. 33 | / 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename 34 | / are removed. 35 | / 2: f_opendir and f_readdir are removed in addition to 1. 36 | / 3: f_lseek is removed in addition to 2. */ 37 | 38 | 39 | #define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */ 40 | /* To enable string functions, set _USE_STRFUNC to 1 or 2. */ 41 | 42 | 43 | #define _USE_MKFS 0 /* 0:Disable or 1:Enable */ 44 | /* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ 45 | 46 | 47 | #define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ 48 | /* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ 49 | 50 | 51 | #define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ 52 | /* To enable fast seek feature, set _USE_FASTSEEK to 1. */ 53 | 54 | 55 | 56 | /*---------------------------------------------------------------------------/ 57 | / Locale and Namespace Configurations 58 | /----------------------------------------------------------------------------*/ 59 | 60 | #define _CODE_PAGE 1 61 | /* The _CODE_PAGE specifies the OEM code page to be used on the target system. 62 | / Incorrect setting of the code page can cause a file open failure. 63 | / 64 | / 932 - Japanese Shift-JIS (DBCS, OEM, Windows) 65 | / 936 - Simplified Chinese GBK (DBCS, OEM, Windows) 66 | / 949 - Korean (DBCS, OEM, Windows) 67 | / 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) 68 | / 1250 - Central Europe (Windows) 69 | / 1251 - Cyrillic (Windows) 70 | / 1252 - Latin 1 (Windows) 71 | / 1253 - Greek (Windows) 72 | / 1254 - Turkish (Windows) 73 | / 1255 - Hebrew (Windows) 74 | / 1256 - Arabic (Windows) 75 | / 1257 - Baltic (Windows) 76 | / 1258 - Vietnam (OEM, Windows) 77 | / 437 - U.S. (OEM) 78 | / 720 - Arabic (OEM) 79 | / 737 - Greek (OEM) 80 | / 775 - Baltic (OEM) 81 | / 850 - Multilingual Latin 1 (OEM) 82 | / 858 - Multilingual Latin 1 + Euro (OEM) 83 | / 852 - Latin 2 (OEM) 84 | / 855 - Cyrillic (OEM) 85 | / 866 - Russian (OEM) 86 | / 857 - Turkish (OEM) 87 | / 862 - Hebrew (OEM) 88 | / 874 - Thai (OEM, Windows) 89 | / 1 - ASCII only (Valid for non LFN cfg.) 90 | */ 91 | 92 | 93 | #define _USE_LFN 0 /* 0 to 3 */ 94 | #define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ 95 | /* The _USE_LFN option switches the LFN support. 96 | / 97 | / 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect. 98 | / 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant. 99 | / 2: Enable LFN with dynamic working buffer on the STACK. 100 | / 3: Enable LFN with dynamic working buffer on the HEAP. 101 | / 102 | / The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN, 103 | / Unicode handling functions ff_convert() and ff_wtoupper() must be added 104 | / to the project. When enable to use heap, memory control functions 105 | / ff_memalloc() and ff_memfree() must be added to the project. */ 106 | 107 | 108 | #define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ 109 | /* To switch the character code set on FatFs API to Unicode, 110 | / enable LFN feature and set _LFN_UNICODE to 1. */ 111 | 112 | 113 | #define _FS_RPATH 0 /* 0 to 2 */ 114 | /* The _FS_RPATH option configures relative path feature. 115 | / 116 | / 0: Disable relative path feature and remove related functions. 117 | / 1: Enable relative path. f_chdrive() and f_chdir() are available. 118 | / 2: f_getcwd() is available in addition to 1. 119 | / 120 | / Note that output of the f_readdir fnction is affected by this option. */ 121 | 122 | 123 | 124 | /*---------------------------------------------------------------------------/ 125 | / Physical Drive Configurations 126 | /----------------------------------------------------------------------------*/ 127 | 128 | #define _VOLUMES 1 129 | /* Number of volumes (logical drives) to be used. */ 130 | 131 | 132 | #define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ 133 | /* Maximum sector size to be handled. 134 | / Always set 512 for memory card and hard disk but a larger value may be 135 | / required for on-board flash memory, floppy disk and optical disk. 136 | / When _MAX_SS is larger than 512, it configures FatFs to variable sector size 137 | / and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */ 138 | 139 | 140 | #define _MULTI_PARTITION 0 /* 0:Single partition, 1/2:Enable multiple partition */ 141 | /* When set to 0, each volume is bound to the same physical drive number and 142 | / it can mount only first primaly partition. When it is set to 1, each volume 143 | / is tied to the partitions listed in VolToPart[]. */ 144 | 145 | 146 | #define _USE_ERASE 0 /* 0:Disable or 1:Enable */ 147 | /* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command 148 | / should be added to the disk_ioctl functio. */ 149 | 150 | 151 | 152 | /*---------------------------------------------------------------------------/ 153 | / System Configurations 154 | /----------------------------------------------------------------------------*/ 155 | 156 | #define _WORD_ACCESS 0 /* 0 or 1 */ 157 | /* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS 158 | / option defines which access method is used to the word data on the FAT volume. 159 | / 160 | / 0: Byte-by-byte access. 161 | / 1: Word access. Do not choose this unless following condition is met. 162 | / 163 | / When the byte order on the memory is big-endian or address miss-aligned word 164 | / access results incorrect behavior, the _WORD_ACCESS must be set to 0. 165 | / If it is not the case, the value can also be set to 1 to improve the 166 | / performance and code size. 167 | */ 168 | 169 | 170 | /* A header file that defines sync object types on the O/S, such as 171 | / windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */ 172 | 173 | #define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ 174 | #define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ 175 | #define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ 176 | 177 | /* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module. 178 | / 179 | / 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. 180 | / 1: Enable reentrancy. Also user provided synchronization handlers, 181 | / ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj 182 | / function must be added to the project. */ 183 | 184 | 185 | #define _FS_LOCK 0 /* 0:Disable or >=1:Enable */ 186 | /* To enable file lock control feature, set _FS_LOCK to 1 or greater. 187 | The value defines how many files can be opened simultaneously. */ 188 | 189 | 190 | #endif /* _FFCONFIG */ 191 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/ff9a/integer.h: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------*/ 2 | /* Integer type definitions for FatFs module */ 3 | /*-------------------------------------------*/ 4 | 5 | #ifndef _INTEGER 6 | #define _INTEGER 7 | 8 | #ifdef _WIN32 /* FatFs development platform */ 9 | 10 | #include 11 | #include 12 | 13 | #else /* Embedded platform */ 14 | 15 | /* These types must be 16-bit, 32-bit or larger integer */ 16 | typedef int INT; 17 | typedef unsigned int UINT; 18 | 19 | /* These types must be 8-bit integer */ 20 | typedef char CHAR; 21 | typedef unsigned char UCHAR; 22 | typedef unsigned char BYTE; 23 | 24 | /* These types must be 16-bit integer */ 25 | typedef short SHORT; 26 | typedef unsigned short USHORT; 27 | typedef unsigned short WORD; 28 | typedef unsigned short WCHAR; 29 | 30 | /* These types must be 32-bit integer */ 31 | typedef long LONG; 32 | typedef unsigned long ULONG; 33 | typedef unsigned long DWORD; 34 | 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/ff9a/option/syscall.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------*/ 2 | /* Sample code of OS dependent controls for FatFs */ 3 | /* (C)ChaN, 2012 */ 4 | /*------------------------------------------------------------------------*/ 5 | 6 | #include /* ANSI memory controls */ 7 | #include /* ANSI memory controls */ 8 | 9 | #include "../ff.h" 10 | 11 | 12 | #if _FS_REENTRANT 13 | /*------------------------------------------------------------------------*/ 14 | /* Create a Synchronization Object 15 | /*------------------------------------------------------------------------*/ 16 | /* This function is called in f_mount function to create a new 17 | / synchronization object, such as semaphore and mutex. When a zero is 18 | / returned, the f_mount function fails with FR_INT_ERR. 19 | */ 20 | 21 | int ff_cre_syncobj ( /* TRUE:Function succeeded, FALSE:Could not create due to any error */ 22 | BYTE vol, /* Corresponding logical drive being processed */ 23 | _SYNC_t *sobj /* Pointer to return the created sync object */ 24 | ) 25 | { 26 | int ret; 27 | 28 | *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */ 29 | ret = (*sobj != INVALID_HANDLE_VALUE); 30 | 31 | // *sobj = SyncObjects[vol]; /* uITRON (give a static sync object) */ 32 | // ret = 1; /* The initial value of the semaphore must be 1. */ 33 | 34 | // *sobj = OSMutexCreate(0, &err); /* uC/OS-II */ 35 | // ret = (err == OS_NO_ERR); 36 | 37 | // *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */ 38 | // ret = (*sobj != NULL); 39 | 40 | return ret; 41 | } 42 | 43 | 44 | 45 | /*------------------------------------------------------------------------*/ 46 | /* Delete a Synchronization Object */ 47 | /*------------------------------------------------------------------------*/ 48 | /* This function is called in f_mount function to delete a synchronization 49 | / object that created with ff_cre_syncobj function. When a zero is 50 | / returned, the f_mount function fails with FR_INT_ERR. 51 | */ 52 | 53 | int ff_del_syncobj ( /* TRUE:Function succeeded, FALSE:Could not delete due to any error */ 54 | _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ 55 | ) 56 | { 57 | BOOL ret; 58 | 59 | ret = CloseHandle(sobj); /* Win32 */ 60 | 61 | // ret = 1; /* uITRON (nothing to do) */ 62 | 63 | // OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */ 64 | // ret = (err == OS_NO_ERR); 65 | 66 | // ret = 1; /* FreeRTOS (nothing to do) */ 67 | 68 | return ret; 69 | } 70 | 71 | 72 | 73 | /*------------------------------------------------------------------------*/ 74 | /* Request Grant to Access the Volume */ 75 | /*------------------------------------------------------------------------*/ 76 | /* This function is called on entering file functions to lock the volume. 77 | / When a zero is returned, the file function fails with FR_TIMEOUT. 78 | */ 79 | 80 | int ff_req_grant ( /* TRUE:Got a grant to access the volume, FALSE:Could not get a grant */ 81 | _SYNC_t sobj /* Sync object to wait */ 82 | ) 83 | { 84 | int ret; 85 | 86 | ret = (WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */ 87 | 88 | // ret = (wai_sem(sobj) == E_OK); /* uITRON */ 89 | 90 | // OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */ 91 | // ret = (err == OS_NO_ERR); 92 | 93 | // ret = (xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */ 94 | 95 | return ret; 96 | } 97 | 98 | 99 | 100 | /*------------------------------------------------------------------------*/ 101 | /* Release Grant to Access the Volume */ 102 | /*------------------------------------------------------------------------*/ 103 | /* This function is called on leaving file functions to unlock the volume. 104 | */ 105 | 106 | void ff_rel_grant ( 107 | _SYNC_t sobj /* Sync object to be signaled */ 108 | ) 109 | { 110 | ReleaseMutex(sobj); /* Win32 */ 111 | 112 | // sig_sem(sobj); /* uITRON */ 113 | 114 | // OSMutexPost(sobj); /* uC/OS-II */ 115 | 116 | // xSemaphoreGive(sobj); /* FreeRTOS */ 117 | 118 | } 119 | 120 | #endif 121 | 122 | 123 | 124 | 125 | #if _USE_LFN == 3 /* LFN with a working buffer on the heap */ 126 | /*------------------------------------------------------------------------*/ 127 | /* Allocate a memory block */ 128 | /*------------------------------------------------------------------------*/ 129 | /* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE. 130 | */ 131 | 132 | void* ff_memalloc ( /* Returns pointer to the allocated memory block */ 133 | UINT size /* Number of bytes to allocate */ 134 | ) 135 | { 136 | return malloc(size); 137 | } 138 | 139 | 140 | /*------------------------------------------------------------------------*/ 141 | /* Free a memory block */ 142 | /*------------------------------------------------------------------------*/ 143 | 144 | void ff_memfree( 145 | void* mblock /* Pointer to the memory block to free */ 146 | ) 147 | { 148 | free(mblock); 149 | } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/ff9a/option/unicode.c: -------------------------------------------------------------------------------- 1 | #include "../ff.h" 2 | 3 | #if _USE_LFN != 0 4 | 5 | #if _CODE_PAGE == 932 6 | #include "cc932.c" 7 | #elif _CODE_PAGE == 936 8 | #include "cc936.c" 9 | #elif _CODE_PAGE == 949 10 | #include "cc949.c" 11 | #elif _CODE_PAGE == 950 12 | #include "cc950.c" 13 | #else 14 | #include "ccsbcs.c" 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/flash_cmd.gdb: -------------------------------------------------------------------------------- 1 | attach_swd 2 | 3 | flash 4 | 5 | quit 6 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/font_8x8.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/font_8x8.h -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/i2s.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i2s.h - generic I2S full-duplex slave 3 | * 07-16-16 E. Brombaugh 4 | */ 5 | 6 | #ifndef __i2s__ 7 | #define __i2s__ 8 | 9 | #include "stm32f30x.h" 10 | 11 | void i2s_init(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/ice5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ice5.c - interface routines for STM32F303 SPI to ice5 FPGA 3 | * 07-02-16 E. Brombaugh 4 | */ 5 | 6 | #ifndef __ICE5__ 7 | #define __ICE5__ 8 | 9 | #include "stm32f30x.h" 10 | #include "ff.h" 11 | 12 | void ICE5_Init(void); 13 | uint8_t ICE5_FPGA_Config(uint8_t *bitmap, uint32_t size); 14 | uint8_t ICE5_FPGA_Config_File(FIL *File); 15 | void ICE5_FPGA_Slave_Write(uint8_t Reg, uint32_t Data); 16 | void ICE5_FPGA_Slave_Read(uint8_t Reg, uint32_t *Data); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/iir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * iir.c - Cascaded Infinite Impulse Response filter routine 3 | * 07-14-2015 E. Brombaugh 4 | */ 5 | 6 | #include "iir.h" 7 | 8 | /* 9 | * initialize the iir structure 10 | */ 11 | void iir_init(iir *is, bq_state *s, bq_coeffs *c, uint8_t n) 12 | { 13 | uint8_t i; 14 | 15 | /* set up the structure */ 16 | is->num_bq = n; 17 | is->bqs = s; 18 | is->bqc = c; 19 | 20 | /* clear the state */ 21 | for(i=0;istate[0] = 0; 24 | s->state[1] = 0; 25 | s++; 26 | } 27 | } 28 | 29 | /* 30 | * compute the iir 31 | */ 32 | float32_t iir_calc(iir *is, float32_t input) 33 | { 34 | uint8_t i; 35 | float32_t xin = input, yout; 36 | bq_state *s = is->bqs; 37 | bq_coeffs *c = is->bqc; 38 | 39 | /* iterate over the number of biquads */ 40 | for(i=0;inum_bq;++i) 41 | { 42 | /* transpose direct form II biquad */ 43 | yout = c->num[0]*xin + s->state[0]; 44 | s->state[0] = s->state[1] + c->num[1] * xin - c->den[1] * yout; 45 | s->state[1] = c->num[2] * xin - c->den[2] * yout; 46 | 47 | /* ouput of the previous biquad is input to next, with gain applied */ 48 | xin = yout * c->gain; 49 | 50 | /* update pointers */ 51 | s++; 52 | c++; 53 | } 54 | return xin; 55 | } 56 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/iir.h: -------------------------------------------------------------------------------- 1 | /* 2 | * iir.c - Cascaded Infinite Impulse Response filter routine 3 | * 07-14-2015 E. Brombaugh 4 | */ 5 | 6 | #ifndef __iir__ 7 | #define __iir__ 8 | 9 | #include 10 | 11 | /* define this for linux */ 12 | typedef float float32_t; 13 | 14 | /* iir types */ 15 | typedef struct 16 | { 17 | float32_t state[2]; /* pipeline for input signal */ 18 | } bq_state; 19 | 20 | typedef struct 21 | { 22 | float32_t num[3]; /* Num coef in order of ze-1 */ 23 | float32_t den[3]; /* Denom coef in order of ze-1 */ 24 | float32_t gain; /* Overall filter gain */ 25 | } bq_coeffs; 26 | 27 | typedef struct 28 | { 29 | uint8_t num_bq; /* Number of biquad sections in a filter */ 30 | bq_state *bqs; /* pointer to array of biquad states */ 31 | bq_coeffs *bqc; /* pointer to array of biquad coeffs */ 32 | } iir; 33 | 34 | /* iir functions */ 35 | void iir_init(iir *is, bq_state *s, bq_coeffs *c, uint8_t n); 36 | float32_t iir_calc(iir *is, float32_t input); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/iir_coeffs.h: -------------------------------------------------------------------------------- 1 | /* iir coefficients for various filters */ 2 | const bq_coeffs c[] = 3 | { 4 | /* 8000 Hz */ 5 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, 1.6065, 0.7936}, 0.8500}, 6 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, 1.3629, 0.5216}, 0.7211}, 7 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, 1.2532, 0.3991}, 0.6631}, 8 | 9 | /* 6000 Hz */ 10 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, 0.6900, 0.6205}, 0.5776}, 11 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, 0.5193, 0.2197}, 0.4347}, 12 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, 0.4544, 0.0672}, 0.3804}, 13 | 14 | /* 4000 Hz */ 15 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -0.3648, 0.5975}, 0.3082}, 16 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -0.2705, 0.1845}, 0.2285}, 17 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -0.2354, 0.0307}, 0.1988}, 18 | 19 | /* 2000 Hz */ 20 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -1.3503, 0.7230}, 0.0932}, 21 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -1.0891, 0.3896}, 0.0751}, 22 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -0.9796, 0.2500}, 0.0676}, 23 | 24 | /* 1000 Hz */ 25 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -1.7406, 0.8431}, 0.0256}, 26 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -1.5324, 0.6227}, 0.0226}, 27 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -1.4334, 0.5178}, 0.0211}, 28 | 29 | /* 500 Hz */ 30 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -1.8904, 0.9172}, 0.0067}, 31 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -1.7640, 0.7890}, 0.0063}, 32 | {{ 1.0000, 2.0000, 1.0000}, { 1.0000, -1.6984, 0.7225}, 0.0060}, 33 | 34 | }; 35 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/led.c: -------------------------------------------------------------------------------- 1 | /* 2 | * led.c - F303_ice5 LED setup 3 | */ 4 | 5 | #include "led.h" 6 | 7 | /* 8 | * Initialize the breakout board LED 9 | */ 10 | void LEDInit(void) 11 | { 12 | GPIO_InitTypeDef GPIO_InitStructure; 13 | 14 | /* Enable GPIO A Clock */ 15 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); 16 | 17 | /* Enable PA9 for output */ 18 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 19 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 20 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 21 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 22 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; 23 | GPIO_Init(GPIOA, &GPIO_InitStructure); 24 | } 25 | 26 | /* 27 | * Turn on LED 28 | */ 29 | void LEDOn(void) 30 | { 31 | GPIOA->BSRR = (1<<9); 32 | } 33 | 34 | /* 35 | * Turn off LED 36 | */ 37 | void LEDOff(void) 38 | { 39 | GPIOA->BRR = (1<<9); 40 | } 41 | 42 | /* 43 | * Toggle LED 44 | */ 45 | void LEDToggle(void) 46 | { 47 | GPIOA->ODR ^= (1<<9); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/led.h: -------------------------------------------------------------------------------- 1 | /* 2 | * led.h - F303_ice5 LED setup 3 | */ 4 | 5 | #ifndef __led__ 6 | #define __led__ 7 | 8 | #include "stm32f30x.h" 9 | 10 | void LEDInit(void); 11 | void LEDOn(void); 12 | void LEDOff(void); 13 | void LEDToggle(void); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | main.c 3 | 4 | Part of f303_ice5 - stm32f303 & ice5lp4k FPGA 5 | Copyright 07-02-2016 E. Brombaugh 6 | */ 7 | #include 8 | #include 9 | #include "stm32f30x.h" 10 | #include "cyclesleep.h" 11 | #include "systick.h" 12 | #include "usart.h" 13 | #include "led.h" 14 | #include "adc.h" 15 | #include "ice5.h" 16 | #include "cmd.h" 17 | #include "shared_spi.h" 18 | #include "st7735.h" 19 | #include "diskio.h" 20 | #include "ff.h" 21 | #include "audio.h" 22 | #include "i2s.h" 23 | #include "rxadc.h" 24 | #include "menu.h" 25 | 26 | /* uncomment this line for FPGA bitstream in flash */ 27 | //#define FLASH_FPGA 28 | 29 | /* uncomment this line for serial command line */ 30 | //#define SERIAL_CMD 31 | 32 | #ifdef FLASH_FPGA 33 | /* FPGA bitstream */ 34 | extern uint8_t _binary_bitmap_bin_start; 35 | extern uint8_t _binary_bitmap_bin_end; 36 | #endif 37 | 38 | /* 39 | * start 40 | */ 41 | int main(void) 42 | { 43 | #ifdef FLASH_FPGA 44 | uint32_t bitmap_size = &_binary_bitmap_bin_end - &_binary_bitmap_bin_start; 45 | #else 46 | char *bitmap_name = "rxadc_23.bin"; 47 | #endif 48 | int rxchar, i; 49 | uint32_t delaygoal; 50 | uint8_t result; 51 | uint8_t buffer[17]; 52 | 53 | /* start cycle counter */ 54 | cyccnt_enable(); 55 | 56 | /* init LEDs & Switches */ 57 | SysTick_Init(); 58 | LEDInit(); 59 | 60 | /* init the adc */ 61 | setup_adc(); 62 | 63 | /* Setup USART diag output */ 64 | setup_usart1(); 65 | printf("\niceRadio\n"); 66 | 67 | /* enable shared spi */ 68 | setup_shared_spi(); 69 | printf("Shared SPI configured\n"); 70 | 71 | /* init LCD */ 72 | ST7735_init(); 73 | ST7735_fillScreen(ST7735_BLACK); 74 | ST7735_drawstr(0, 0, (uint8_t *)"Hello World!", ST7735_WHITE, ST7735_BLACK); 75 | printf("LCD initialized\n"); 76 | 77 | /* Setup FPGA */ 78 | ICE5_Init(); 79 | #ifdef FLASH_FPGA 80 | printf("Configuring %d bytes....", (unsigned int)bitmap_size); 81 | result = ICE5_FPGA_Config(&_binary_bitmap_bin_start, bitmap_size); 82 | if(result) 83 | printf("FPGA configure error: %d.\n", result); 84 | else 85 | { 86 | uint32_t Data; 87 | printf("FPGA configured.\n"); 88 | ICE5_FPGA_Slave_Read(0, &Data); 89 | printf("ID = 0x%08X\n", (int)Data); 90 | } 91 | #else 92 | printf("Configuring FPGA from %s...\n", bitmap_name); 93 | { 94 | FRESULT fres; 95 | FATFS Fatfs; 96 | FIL File; 97 | uint32_t Data; 98 | 99 | /* mount the SD card */ 100 | fres = f_mount(0, &Fatfs); 101 | 102 | /* try to open the file */ 103 | fres = f_open(&File, bitmap_name, FA_READ); 104 | if(!fres) 105 | { 106 | /* try to configure FPGA */ 107 | result = ICE5_FPGA_Config_File(&File); 108 | 109 | if(result) 110 | printf("ERROR - ICE5_FPGA_Config_File returned %d\r\n", result); 111 | else 112 | { 113 | printf("FPGA configured.\n"); 114 | ICE5_FPGA_Slave_Read(0, &Data); 115 | printf("ID = 0x%08X\n", (int)Data); 116 | } 117 | } 118 | else 119 | { 120 | printf("ERROR - Can't open file %s\r\n", bitmap_name); 121 | } 122 | } 123 | #endif 124 | 125 | /* init the audio handler */ 126 | Audio_Init(); 127 | printf("Audio initialized\n"); 128 | 129 | /* init the I2S slave port -- AFTER FPGA is running ! */ 130 | i2s_init(); 131 | printf("I2S initialized\n"); 132 | 133 | #ifdef SERIAL_CMD 134 | printf("Initializing Serial Command Processor...\n"); 135 | init_cmd(); 136 | #else 137 | /* init the GUI menu */ 138 | delay(100); 139 | menu_init(); 140 | printf("Menu initialized...\n"); 141 | #endif 142 | 143 | /* loop forever */ 144 | delaygoal = cyclegoal_ms(100); 145 | while(1) 146 | { 147 | /* Blink the heartbeat LED */ 148 | if(!cyclecheck(delaygoal)) 149 | { 150 | LEDToggle(); 151 | 152 | #ifdef SERIAL_CMD 153 | /* dump out ADC channels to LCD */ 154 | for(i=0;i>26; 20 | } 21 | 22 | /* 23 | * lo write 24 | */ 25 | uint32_t rxadc_set_lo(uint32_t freq) 26 | { 27 | uint64_t temp = ((uint64_t)freq)<<26; 28 | temp = temp / 40000000; 29 | freq = temp; 30 | ICE5_FPGA_Slave_Write(16, freq); 31 | return freq; 32 | } 33 | 34 | /* 35 | * audio mux read 36 | */ 37 | uint8_t rxadc_get_mux(void) 38 | { 39 | uint32_t mux; 40 | ICE5_FPGA_Slave_Read(17, &mux); 41 | return mux & 1; 42 | } 43 | 44 | /* 45 | * audio mux write 46 | */ 47 | void rxadc_set_mux(uint8_t mux) 48 | { 49 | ICE5_FPGA_Slave_Write(17, mux); 50 | } 51 | 52 | /* 53 | * noise_shape write 54 | */ 55 | void rxadc_set_ns(uint8_t ns) 56 | { 57 | ICE5_FPGA_Slave_Write(18, ns); 58 | } -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/rxadc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rxadc.h - low level interfaces to rxadc FPGA design 3 | * 07-19-14 E. Brombaugh 4 | */ 5 | 6 | #ifndef __rxadc__ 7 | #define __rxadc__ 8 | 9 | uint32_t rxadc_get_lo(void); 10 | uint32_t rxadc_set_lo(uint32_t freq); 11 | uint8_t rxadc_get_mux(void); 12 | void rxadc_set_mux(uint8_t mux); 13 | void rxadc_set_ns(uint8_t ns); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/rxadc_21.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/rxadc_21.bin -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/rxadc_22.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/rxadc_22.bin -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/rxadc_23.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/rxadc_23.bin -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/rxadc_4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/rxadc_4.bin -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/rxadc_bitmap.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emeb/iceRadio/632f8c14400ebfe5f82beb154f6df6d3e4bafd4e/MCU/f303_ice5_rxadc/rxadc_bitmap.bin -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/shared_spi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * shared_spi.c - interface routines for F303_ICE5 SPI 3 | * 07-05-16 E. Brombaugh 4 | */ 5 | 6 | #include "shared_spi.h" 7 | 8 | /* fool the compiler */ 9 | #define UNUSED(x) ((void)(x)) 10 | 11 | void setup_shared_spi(void) 12 | { 13 | GPIO_InitTypeDef GPIO_InitStructure; 14 | SPI_InitTypeDef SPI_InitStructure; 15 | 16 | /* GPIO Periph clock enables */ 17 | RCC_AHBPeriphClockCmd(LCD_CS_GPIO_CLK | LCD_DC_GPIO_CLK | 18 | LCD_LITE_GPIO_CLK | SD_CS_GPIO_CLK | SD_SPI_MOSI_GPIO_CLK | 19 | SD_SPI_MISO_GPIO_CLK | SD_SPI_SCK_GPIO_CLK, ENABLE); 20 | 21 | /* SD_SPI Periph clock enable */ 22 | RCC_APB1PeriphClockCmd(SD_SPI_CLK, ENABLE); 23 | 24 | /* Configure SD_SPI pins: SCK */ 25 | GPIO_InitStructure.GPIO_Pin = SD_SPI_SCK_PIN; 26 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 27 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 28 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 29 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 30 | GPIO_Init(SD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); 31 | 32 | /* Configure SD_SPI pins: MISO */ 33 | GPIO_InitStructure.GPIO_Pin = SD_SPI_MISO_PIN; 34 | GPIO_Init(SD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); 35 | 36 | /* Configure SD_SPI pins: MOSI */ 37 | GPIO_InitStructure.GPIO_Pin = SD_SPI_MOSI_PIN; 38 | GPIO_Init(SD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); 39 | 40 | /* Configure SD_SPI_CS_PIN pin: SD Card CS pin */ 41 | GPIO_InitStructure.GPIO_Pin = SD_CS_PIN; 42 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 43 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 44 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 45 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 46 | GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStructure); 47 | SD_CS_HIGH(); 48 | 49 | /* Configure LCD_CS_PIN pin: LCD CS pin */ 50 | GPIO_InitStructure.GPIO_Pin = LCD_CS_PIN; 51 | GPIO_Init(LCD_CS_GPIO_PORT, &GPIO_InitStructure); 52 | LCD_CS_HIGH(); 53 | 54 | /* Configure LCD_DC_PIN pin: LCD D/C pin */ 55 | GPIO_InitStructure.GPIO_Pin = LCD_DC_PIN; 56 | GPIO_Init(LCD_DC_GPIO_PORT, &GPIO_InitStructure); 57 | LCD_DC_CMD(); 58 | 59 | /* Configure LCD_RST_PIN pin: LCD Reset pin */ 60 | GPIO_InitStructure.GPIO_Pin = LCD_RST_PIN; 61 | GPIO_Init(LCD_RST_GPIO_PORT, &GPIO_InitStructure); 62 | LCD_RST_HIGH(); 63 | 64 | /* Configure LCD_LITE_PIN pin: LCD Lite pin */ 65 | GPIO_InitStructure.GPIO_Pin = LCD_LITE_PIN; 66 | GPIO_Init(LCD_LITE_GPIO_PORT, &GPIO_InitStructure); 67 | LCD_LITE_HIGH(); 68 | 69 | /* Connect PXx to SD_SPI_SCK */ 70 | GPIO_PinAFConfig(SD_SPI_SCK_GPIO_PORT, SD_SPI_SCK_SOURCE, SD_SPI_SCK_AF); 71 | 72 | /* Connect PXx to SD_SPI_MISO */ 73 | GPIO_PinAFConfig(SD_SPI_MISO_GPIO_PORT, SD_SPI_MISO_SOURCE, SD_SPI_MISO_AF); 74 | 75 | /* Connect PXx to SD_SPI_MOSI */ 76 | GPIO_PinAFConfig(SD_SPI_MOSI_GPIO_PORT, SD_SPI_MOSI_SOURCE, SD_SPI_MOSI_AF); 77 | 78 | /* SD_SPI Config */ 79 | SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 80 | SPI_InitStructure.SPI_Mode = SPI_Mode_Master; 81 | SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; 82 | #if 0 83 | // original setup from ST eval code - works 84 | SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; 85 | SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; 86 | #else 87 | // Martin Thomas setup - works too 88 | SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; 89 | SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; 90 | #endif 91 | SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; 92 | SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; 93 | 94 | SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; 95 | SPI_InitStructure.SPI_CRCPolynomial = 7; 96 | SPI_Init(SD_SPI, &SPI_InitStructure); 97 | 98 | SPI_RxFIFOThresholdConfig(SD_SPI, SPI_RxFIFOThreshold_QF); 99 | 100 | SPI_Cmd(SD_SPI, ENABLE); /* SD_SPI enable */ 101 | 102 | SPI_InitDMA(); /* setup DMA structure for fast ops */ 103 | } 104 | 105 | void SPI_WriteByte(uint8_t Data) 106 | { 107 | /* Wait until the transmit buffer is empty */ 108 | //while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET) 109 | while((SD_SPI->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET) 110 | { 111 | } 112 | 113 | /* Send the byte */ 114 | //SPI_SendData8(SD_SPI, Data); 115 | //SD_SPI->DR = (uint16_t)Data; 116 | *(__IO uint8_t *) ((uint32_t)SD_SPI+0x0C) = Data; 117 | 118 | /*!< Wait to receive a byte*/ 119 | //while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET) 120 | while((SD_SPI->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET) 121 | { 122 | } 123 | 124 | /* Return the byte read from the SPI bus */ 125 | //return SPI_ReceiveData8(SD_SPI); 126 | //return *(__IO uint8_t *) ((uint32_t)SD_SPI+0x0C); 127 | uint8_t dummy = *(__IO uint8_t *) ((uint32_t)SD_SPI+0x0C); 128 | UNUSED(dummy); /* To avoid GCC warning */ 129 | 130 | } 131 | 132 | uint8_t SPI_WriteReadByte(uint8_t Data) 133 | { 134 | /* Wait until the transmit buffer is empty */ 135 | //while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET) 136 | while((SD_SPI->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET) 137 | { 138 | } 139 | 140 | /*!< Send the byte */ 141 | //SPI_SendData8(SD_SPI, Data); 142 | //SD_SPI->DR = (uint16_t)Data; 143 | *(__IO uint8_t *) ((uint32_t)SD_SPI+0x0C) = Data; 144 | 145 | /* Wait to receive a byte*/ 146 | //while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET) 147 | while((SD_SPI->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET) 148 | { 149 | } 150 | 151 | /* Return the byte read from the SPI bus */ 152 | //return SPI_ReceiveData8(SD_SPI); 153 | return *(__IO uint8_t *) ((uint32_t)SD_SPI+0x0C); 154 | } 155 | 156 | uint8_t SPI_ReadByte(void) 157 | { 158 | uint8_t Data = 0; 159 | 160 | /* Wait until the transmit buffer is empty */ 161 | while (SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET) 162 | { 163 | } 164 | /* Send the byte */ 165 | SPI_SendData8(SD_SPI, SD_DUMMY_BYTE); 166 | 167 | /* Wait until a data is received */ 168 | while (SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET) 169 | { 170 | } 171 | /* Get the received data */ 172 | Data = SPI_ReceiveData8(SD_SPI); 173 | 174 | /* Return the shifted data */ 175 | return Data; 176 | } 177 | 178 | DMA_InitTypeDef DMA_InitStructure; 179 | 180 | void SPI_InitDMA(void) 181 | { 182 | // turn on DMA1 clock 183 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); 184 | 185 | DMA_Cmd(DMA2_Channel2, DISABLE); 186 | DMA_DeInit(DMA2_Channel2); 187 | 188 | // Common 189 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(SD_SPI->DR); 190 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 191 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 192 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 193 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 194 | DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte; 195 | DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 196 | DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 197 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 198 | } 199 | 200 | void SPI_start_DMA_WriteBytes(uint8_t *buffer, uint16_t len) 201 | { 202 | /* Setup buffer loc / len */ 203 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buffer; 204 | DMA_InitStructure.DMA_BufferSize = len; 205 | DMA_Init(DMA2_Channel2, &DMA_InitStructure); 206 | 207 | /* Enable SPI_DMA_TX */ 208 | DMA_Cmd(DMA2_Channel2, ENABLE); 209 | 210 | /* Enable SPI_DMA TX request */ 211 | SPI_I2S_DMACmd(SD_SPI, SPI_I2S_DMAReq_Tx, ENABLE); 212 | } 213 | 214 | void SPI_end_DMA_WriteBytes(void) 215 | { 216 | /* Wait until SPI_DMA_TX Complete */ 217 | while (DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET); 218 | 219 | /* DISABLE SPI_DMA_TX */ 220 | DMA_Cmd(DMA2_Channel2, DISABLE); 221 | SPI_I2S_DMACmd(SD_SPI, SPI_I2S_DMAReq_Tx, DISABLE); 222 | 223 | /* Clear DMA TransferComplete Flag */ 224 | DMA_ClearFlag(DMA2_FLAG_TC2); 225 | //DMA_ClearITPendingBit(DMA1_IT_TC3); 226 | 227 | /* Wait to receive a byte */ 228 | while (SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET); 229 | } 230 | 231 | void SPI_real_DMA_WriteBytes(uint8_t *buffer, uint16_t len) 232 | { 233 | SPI_start_DMA_WriteBytes(buffer, len); 234 | SPI_end_DMA_WriteBytes(); 235 | } 236 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/shared_spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shared_spi.c - interface routines for F303_ICE5 SPI 3 | * 07-05-16 E. Brombaugh 4 | */ 5 | 6 | #ifndef __SHARED_SPI__ 7 | #define __SHARED_SPI_ 8 | 9 | #include "stm32f30x.h" 10 | 11 | /* 12 | * SPI Interface pins 13 | */ 14 | #define SD_SPI SPI3 15 | #define SD_SPI_CLK RCC_APB1Periph_SPI3 16 | #define SD_SPI_SCK_PIN GPIO_Pin_3 17 | #define SD_SPI_SCK_GPIO_PORT GPIOB 18 | #define SD_SPI_SCK_GPIO_CLK RCC_AHBPeriph_GPIOB 19 | #define SD_SPI_SCK_SOURCE GPIO_PinSource3 20 | #define SD_SPI_SCK_AF GPIO_AF_6 21 | 22 | #define SD_SPI_MISO_PIN GPIO_Pin_4 23 | #define SD_SPI_MISO_GPIO_PORT GPIOB 24 | #define SD_SPI_MISO_GPIO_CLK RCC_AHBPeriph_GPIOB 25 | #define SD_SPI_MISO_SOURCE GPIO_PinSource4 26 | #define SD_SPI_MISO_AF GPIO_AF_6 27 | 28 | #define SD_SPI_MOSI_PIN GPIO_Pin_5 29 | #define SD_SPI_MOSI_GPIO_PORT GPIOB 30 | #define SD_SPI_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOB 31 | #define SD_SPI_MOSI_SOURCE GPIO_PinSource5 32 | #define SD_SPI_MOSI_AF GPIO_AF_6 33 | 34 | #define SD_CS_PIN GPIO_Pin_15 35 | #define SD_CS_GPIO_PORT GPIOA 36 | #define SD_CS_GPIO_CLK RCC_AHBPeriph_GPIOA 37 | 38 | #define LCD_LITE_PIN GPIO_Pin_8 39 | #define LCD_LITE_GPIO_PORT GPIOB 40 | #define LCD_LITE_GPIO_CLK RCC_AHBPeriph_GPIOB 41 | 42 | #define LCD_CS_PIN GPIO_Pin_9 43 | #define LCD_CS_GPIO_PORT GPIOB 44 | #define LCD_CS_GPIO_CLK RCC_AHBPeriph_GPIOB 45 | 46 | #define LCD_DC_PIN GPIO_Pin_14 47 | #define LCD_DC_GPIO_PORT GPIOC 48 | #define LCD_DC_GPIO_CLK RCC_AHBPeriph_GPIOC 49 | 50 | #define LCD_RST_PIN GPIO_Pin_15 51 | #define LCD_RST_GPIO_PORT GPIOC 52 | #define LCD_RST_GPIO_CLK RCC_AHBPeriph_GPIOC 53 | 54 | #define SD_CS_LOW() GPIO_ResetBits(SD_CS_GPIO_PORT, SD_CS_PIN) 55 | #define SD_CS_HIGH() GPIO_SetBits(SD_CS_GPIO_PORT, SD_CS_PIN) 56 | #define LCD_CS_LOW() GPIO_ResetBits(LCD_CS_GPIO_PORT, LCD_CS_PIN) 57 | #define LCD_CS_HIGH() GPIO_SetBits(LCD_CS_GPIO_PORT, LCD_CS_PIN) 58 | #define LCD_DC_CMD() GPIO_ResetBits(LCD_DC_GPIO_PORT, LCD_DC_PIN) 59 | #define LCD_DC_DATA() GPIO_SetBits(LCD_DC_GPIO_PORT, LCD_DC_PIN) 60 | #define LCD_RST_LOW() GPIO_ResetBits(LCD_RST_GPIO_PORT, LCD_RST_PIN) 61 | #define LCD_RST_HIGH() GPIO_SetBits(LCD_RST_GPIO_PORT, LCD_RST_PIN) 62 | #define LCD_LITE_LOW() GPIO_ResetBits(LCD_LITE_GPIO_PORT, LCD_LITE_PIN) 63 | #define LCD_LITE_HIGH() GPIO_SetBits(LCD_LITE_GPIO_PORT, LCD_LITE_PIN) 64 | #define SD_DUMMY_BYTE 0xFF 65 | 66 | void setup_shared_spi(void); 67 | void SPI_WriteByte(uint8_t Data); 68 | uint8_t SPI_WriteReadByte(uint8_t Data); 69 | uint8_t SPI_ReadByte(void); 70 | void SPI_fake_DMA_WriteBytes(uint8_t *buffer, uint16_t len); 71 | void SPI_InitDMA(void); 72 | void SPI_start_DMA_WriteBytes(uint8_t *buffer, uint16_t len); 73 | void SPI_end_DMA_WriteBytes(void); 74 | void SPI_real_DMA_WriteBytes(uint8_t *buffer, uint16_t len); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/st7735.h: -------------------------------------------------------------------------------- 1 | /* 2 | * st7735.h - interface routines for ST7735 LCD. 3 | * shamelessly ganked from Adafruit_ST7735 library 4 | * 12-20-12 E. Brombaugh 5 | */ 6 | 7 | 8 | #ifndef __ST7735__ 9 | #define __ST7735__ 10 | 11 | #include 12 | 13 | // some flags for initR() :( 14 | #define INITR_GREENTAB 0x0 15 | #define INITR_REDTAB 0x1 16 | 17 | #define ST7735_TFTWIDTH 128 18 | #define ST7735_TFTHEIGHT 160 19 | 20 | #define ST7735_NOP 0x00 21 | #define ST7735_SWRESET 0x01 22 | #define ST7735_RDDID 0x04 23 | #define ST7735_RDDST 0x09 24 | 25 | #define ST7735_SLPIN 0x10 26 | #define ST7735_SLPOUT 0x11 27 | #define ST7735_PTLON 0x12 28 | #define ST7735_NORON 0x13 29 | 30 | #define ST7735_INVOFF 0x20 31 | #define ST7735_INVON 0x21 32 | #define ST7735_DISPOFF 0x28 33 | #define ST7735_DISPON 0x29 34 | #define ST7735_CASET 0x2A 35 | #define ST7735_RASET 0x2B 36 | #define ST7735_RAMWR 0x2C 37 | #define ST7735_RAMRD 0x2E 38 | 39 | #define ST7735_PTLAR 0x30 40 | #define ST7735_COLMOD 0x3A 41 | #define ST7735_MADCTL 0x36 42 | 43 | #define ST7735_FRMCTR1 0xB1 44 | #define ST7735_FRMCTR2 0xB2 45 | #define ST7735_FRMCTR3 0xB3 46 | #define ST7735_INVCTR 0xB4 47 | #define ST7735_DISSET5 0xB6 48 | 49 | #define ST7735_PWCTR1 0xC0 50 | #define ST7735_PWCTR2 0xC1 51 | #define ST7735_PWCTR3 0xC2 52 | #define ST7735_PWCTR4 0xC3 53 | #define ST7735_PWCTR5 0xC4 54 | #define ST7735_VMCTR1 0xC5 55 | 56 | #define ST7735_RDID1 0xDA 57 | #define ST7735_RDID2 0xDB 58 | #define ST7735_RDID3 0xDC 59 | #define ST7735_RDID4 0xDD 60 | 61 | #define ST7735_PWCTR6 0xFC 62 | 63 | #define ST7735_GMCTRP1 0xE0 64 | #define ST7735_GMCTRN1 0xE1 65 | 66 | // Color definitions 67 | #define ST7735_BLACK 0x0000 68 | #define ST7735_RED 0x001F 69 | #define ST7735_BLUE 0xF800 70 | #define ST7735_GREEN 0x07E0 71 | #define ST7735_YELLOW 0x07FF 72 | #define ST7735_MAGENTA 0xF81F 73 | #define ST7735_CYAN 0xFFE0 74 | #define ST7735_WHITE 0xFFFF 75 | 76 | void ST7735_write(uint16_t dat); 77 | void ST7735_init(void); 78 | void ST7735_setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1); 79 | void ST7735_fillScreen(uint16_t color); 80 | void ST7735_pushColor(uint16_t color); 81 | void ST7735_drawPixel(int16_t x, int16_t y, uint16_t color); 82 | void ST7735_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); 83 | void ST7735_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); 84 | void ST7735_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 85 | uint16_t color); 86 | uint16_t ST7735_Color565(uint8_t r, uint8_t g, uint8_t b); 87 | void ST7735_drawchar(int16_t x, int16_t y, uint8_t chr, 88 | uint16_t fg, uint16_t bg); 89 | void ST7735_drawstr(int16_t x, int16_t y, uint8_t *str, 90 | uint16_t fg, uint16_t bg); 91 | void ST7735_setRotation(uint8_t m); 92 | void ST7735_draw_framebuffer(uint8_t *buffer, uint8_t w, uint8_t h); 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/stubs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libstubs.c - stubs that the library wants since libnosys doesn't do anything 3 | */ 4 | 5 | #include 6 | #include 7 | #include "usart.h" 8 | 9 | /* _end is set in the linker command file 10 | extern caddr_t _end;*/ 11 | 12 | /* just in case, most boards have at least some memory */ 13 | #ifndef RAMSIZE 14 | # define RAMSIZE (caddr_t)0x100000 15 | #endif 16 | 17 | /* 18 | * sbrk -- changes heap size size. Get nbytes more 19 | * RAM. We just increment a pointer in what's 20 | * left of memory on the board. 21 | */ 22 | caddr_t 23 | _sbrk(nbytes) 24 | int nbytes; 25 | { 26 | static caddr_t heap_ptr = NULL; 27 | caddr_t base; 28 | 29 | if (heap_ptr == NULL) { 30 | heap_ptr = (caddr_t)0x20007fff; 31 | } 32 | 33 | if ((RAMSIZE - heap_ptr) >= 0) { 34 | base = heap_ptr; 35 | heap_ptr += nbytes; 36 | return (base); 37 | } else { 38 | errno = ENOMEM; 39 | return ((caddr_t)-1); 40 | } 41 | } 42 | 43 | /* 44 | * isatty -- returns 1 if connected to a terminal device, 45 | * returns 0 if not. Since we're hooked up to a 46 | * serial port, we'll say yes and return a 1. 47 | */ 48 | int 49 | _isatty(fd) 50 | int fd; 51 | { 52 | return (1); 53 | } 54 | 55 | /* 56 | * getpid -- only one process, so just return 1. 57 | */ 58 | #define __MYPID 1 59 | int 60 | _getpid() 61 | { 62 | return __MYPID; 63 | } 64 | 65 | /* 66 | * exit 67 | */ 68 | void 69 | _exit(int val) 70 | { 71 | while(1); 72 | } 73 | 74 | /* 75 | * kill -- go out via exit... 76 | */ 77 | int 78 | _kill(pid, sig) 79 | int pid; 80 | int sig; 81 | { 82 | if(pid == __MYPID) 83 | _exit(sig); 84 | return 0; 85 | } 86 | 87 | /* 88 | * read -- read bytes from the serial port. Ignore fd, since 89 | * we only have stdin. 90 | */ 91 | int 92 | _read(fd, buf, nbytes) 93 | int fd; 94 | char *buf; 95 | int nbytes; 96 | { 97 | int i = 0; 98 | 99 | for (i = 0; i < nbytes; i++) { 100 | *(buf + i) = inbyte(); 101 | if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { 102 | (*(buf + i)) = 0; 103 | break; 104 | } 105 | } 106 | return (i); 107 | } 108 | 109 | /* 110 | * write -- write bytes to the serial port. Ignore fd, since 111 | * stdout and stderr are the same. Since we have no filesystem, 112 | * open will only return an error. 113 | */ 114 | int 115 | _write(fd, buf, nbytes) 116 | int fd; 117 | char *buf; 118 | int nbytes; 119 | { 120 | int i; 121 | 122 | for (i = 0; i < nbytes; i++) { 123 | if (*(buf + i) == '\n') { 124 | outbyte ('\r'); 125 | } 126 | outbyte (*(buf + i)); 127 | } 128 | return (nbytes); 129 | } 130 | 131 | 132 | /* 133 | * close -- close a file descriptor. We don't need 134 | * to do anything, but pretend we did. 135 | */ 136 | int 137 | _close(fd) 138 | int fd; 139 | { 140 | return (0); 141 | } 142 | 143 | /* 144 | * lseek -- move read/write pointer. Since a serial port 145 | * is non-seekable, we return an error. 146 | */ 147 | off_t 148 | _lseek(fd, offset, whence) 149 | int fd; 150 | off_t offset; 151 | int whence; 152 | { 153 | errno = ESPIPE; 154 | return ((off_t)-1); 155 | } 156 | 157 | /* 158 | * fstat -- get status of a file. Since we have no file 159 | * system, we just return an error. 160 | */ 161 | int 162 | _fstat(fd, buf) 163 | int fd; 164 | struct stat *buf; 165 | { 166 | errno = EIO; 167 | return (-1); 168 | } 169 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/systick.c: -------------------------------------------------------------------------------- 1 | /* 2 | * systick.c - 1ms system tick timer & related services. 3 | * - also handles switches, encoder and button debounce 4 | */ 5 | 6 | #include "systick.h" 7 | #include "debounce.h" 8 | 9 | uint32_t SysTick_Counter; 10 | int16_t enc_val; 11 | debounce_state dbs_btn, dbs_enc_A, dbs_enc_B; 12 | 13 | /* 14 | * encoder details: 15 | * Phase A is GPIO PA1 - 0 state roughly centered between detents 16 | * Phase B is GPIO PA2 - edge closest to detent 17 | * Button is GPIO PA3 18 | * B = 1 on A^ -> CW 19 | * B = 0 on A^ -> CCW 20 | */ 21 | 22 | /* 23 | * SysTick_Init - sets up all the System Tick and UI state 24 | */ 25 | void SysTick_Init(void) 26 | { 27 | GPIO_InitTypeDef GPIO_InitStructure; 28 | 29 | /* GPIOA & GPIOF Periph clock enable */ 30 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); 31 | 32 | /* set up GPIO for encoder phase input */ 33 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ; 34 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; 35 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; 36 | GPIO_Init(GPIOA, &GPIO_InitStructure); 37 | 38 | /* set up debounce objects for buttons & phases */ 39 | init_debounce(&dbs_btn, 15); 40 | init_debounce(&dbs_enc_A, 2); 41 | init_debounce(&dbs_enc_B, 2); 42 | enc_val = 0; 43 | 44 | /* Init tick counter */ 45 | SysTick_Counter = 0; 46 | 47 | /* start Tick IRQ */ 48 | if(SysTick_Config(SystemCoreClock/1000)) 49 | { 50 | /* Hang here to capture error */ 51 | while(1); 52 | } 53 | } 54 | 55 | /* 56 | * SysTick_Handler - Called by System Tick IRQ @ 1ms intervals to update UI elements 57 | */ 58 | void SysTick_Handler(void) 59 | { 60 | /* debounce button */ 61 | debounce(&dbs_btn, (((~GPIOA->IDR) >> 3)&1)); 62 | 63 | /* debounce encoder */ 64 | debounce(&dbs_enc_A, (((GPIOA->IDR) >> 1)&1)); 65 | debounce(&dbs_enc_B, (((GPIOA->IDR) >> 2)&1)); 66 | 67 | /* if rising edge of clock then sample alternate phase for count dir */ 68 | if(dbs_enc_A.re) 69 | { 70 | if(dbs_enc_B.state) 71 | { 72 | /* B = 1 on A^ -> CW */ 73 | enc_val++; 74 | } 75 | else 76 | { 77 | /* B = 0 on A^ -> CCW */ 78 | enc_val--; 79 | } 80 | } 81 | 82 | /* Update SysTick Counter */ 83 | SysTick_Counter++; 84 | } 85 | 86 | /* 87 | * get state of encoder button 88 | */ 89 | uint8_t SysTick_get_button(void) 90 | { 91 | return dbs_btn.state; 92 | } 93 | 94 | /* 95 | * get state of encoder shaft 96 | */ 97 | int16_t SysTick_get_encoder(void) 98 | { 99 | int16_t result = enc_val; 100 | enc_val = 0; 101 | return result; 102 | } 103 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/systick.h: -------------------------------------------------------------------------------- 1 | /* 2 | * systick.h - 1ms system tick setup 3 | */ 4 | 5 | #ifndef __systick__ 6 | #define __systick__ 7 | 8 | #include "stm32f30x.h" 9 | 10 | void SysTick_Init(void); 11 | uint8_t SysTick_get_button(void); 12 | int16_t SysTick_get_encoder(void); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/usart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * usart.c - serial i/o routines 3 | * 12-24-12 E. Brombaugh 4 | */ 5 | 6 | #include 7 | #include "stm32f30x.h" 8 | 9 | uint8_t RX_buffer[256]; 10 | uint8_t *RX_wptr, *RX_rptr; 11 | 12 | /* USART1 setup */ 13 | void setup_usart1(void) 14 | { 15 | GPIO_InitTypeDef GPIO_InitStructure; 16 | USART_InitTypeDef USART_InitStructure; 17 | NVIC_InitTypeDef NVIC_InitStructure; 18 | 19 | /* init RX buffer write/read pointers*/ 20 | RX_wptr = &RX_buffer[0]; 21 | RX_rptr = &RX_buffer[0]; 22 | 23 | /* Setup USART */ 24 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); 25 | 26 | /* Connect PB6 to USARTx_Tx */ 27 | GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_7); 28 | 29 | /* Connect PB7 to USARTx_Rx */ 30 | GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_7); 31 | 32 | /* Configure USART Tx as alternate function push-pull */ 33 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 34 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 35 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 36 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 37 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 38 | GPIO_Init(GPIOB, &GPIO_InitStructure); 39 | 40 | /* Configure USART Rx as alternate function push-pull */ 41 | /* RX not used */ 42 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 43 | GPIO_Init(GPIOB, &GPIO_InitStructure); 44 | 45 | /* USART configuration */ 46 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 47 | 48 | /* USART = 115k-8-N-1 */ 49 | USART_InitStructure.USART_BaudRate = 115200; 50 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 51 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 52 | USART_InitStructure.USART_Parity = USART_Parity_No; 53 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 54 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 55 | USART_Init(USART1, &USART_InitStructure); 56 | 57 | /* Enable RX interrupt */ 58 | USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 59 | 60 | /* Enable the USART6 Interrupt */ 61 | NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 62 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 63 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 64 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 65 | NVIC_Init(&NVIC_InitStructure); 66 | 67 | /* Enable USART */ 68 | USART_Cmd(USART1, ENABLE); 69 | } 70 | 71 | int get_usart(void) 72 | { 73 | #if 0 74 | /* Non-interrupt version */ 75 | if(USART_GetFlagStatus(USART6, USART_FLAG_RXNE) == SET) 76 | return USART_ReceiveData(USART6); 77 | else 78 | return EOF; 79 | #else 80 | /* interrupt version */ 81 | int retval; 82 | 83 | /* check if there's data in the buffer */ 84 | if(RX_rptr != RX_wptr) 85 | { 86 | /* get the data */ 87 | retval = *RX_rptr++; 88 | 89 | /* wrap the pointer */ 90 | if((RX_rptr - &RX_buffer[0])>=256) 91 | RX_rptr = &RX_buffer[0]; 92 | } 93 | else 94 | retval = EOF; 95 | 96 | return retval; 97 | #endif 98 | } 99 | 100 | /** 101 | * @brief Retargets the C library printf function to the USART. 102 | * @param None 103 | * @retval None 104 | */ 105 | int outbyte(int ch) 106 | { 107 | /* Place your implementation of fputc here */ 108 | /* e.g. write a character to the USART */ 109 | USART_SendData(USART1, (uint8_t) ch); 110 | 111 | /* Loop until transmit data register is empty */ 112 | while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) 113 | {} 114 | 115 | return ch; 116 | } 117 | 118 | /** 119 | * @brief Retargets the C library printf function to the USART. 120 | * @param None 121 | * @retval None 122 | */ 123 | int inbyte(void) 124 | { 125 | /* nothing happening yet */ 126 | return 0; 127 | } 128 | 129 | /* 130 | * USART IRQ handler - used only for Rx for now 131 | */ 132 | void USART1_IRQHandler(void) 133 | { 134 | if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 135 | { 136 | /* get the character */ 137 | uint8_t rxchar = USART_ReceiveData(USART1); 138 | 139 | /* check if there's room in the buffer */ 140 | if((RX_wptr != RX_rptr-1) && 141 | (RX_wptr - RX_rptr != 255)) 142 | { 143 | /* Yes - Queue the new char */ 144 | *RX_wptr++ = rxchar; 145 | 146 | /* Wrap pointer */ 147 | if((RX_wptr - &RX_buffer[0])>=256) 148 | RX_wptr = &RX_buffer[0]; 149 | } 150 | } 151 | 152 | if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) 153 | { 154 | } 155 | } -------------------------------------------------------------------------------- /MCU/f303_ice5_rxadc/usart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * usart.h - usart printf stuff 3 | * 12-24-12 E. Brombaugh 4 | */ 5 | 6 | #ifndef __usart__ 7 | #define __usart__ 8 | 9 | void setup_usart1(void); 10 | int get_usart(void); 11 | int outbyte(int ch); 12 | int inbyte(void); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iceRadio 2 | C and Verilog sources for STM32F303 + iCE5LP4K Software Defined Radio project. 3 | 4 | See http://ebrombaugh.studionebula.com/radio/iceRadio/index.html for more 5 | information. 6 | --------------------------------------------------------------------------------