DSP for under £50 Ron Taylor G4GXO www.cumbriadesigns.co.uk Signals to numbers – and back again Microprocessor Analogue Analogue to Digital Converter Digital Analogue Digital to Analogue Converter Analogue to Digital Conversion +ve Voltage 0V -ve Sampling points Analogue to Digital Conversion Amplitude of each sample above or below mid range is converted into a signed binary number +ve Number range 0 -ve 00010100 01110100 01110110 11100100 (sign bit sets –ve or +ve value) Each number sent serially from CODEC to processor Signals to numbers – and back again Microprocessor Analogue Analogue to Digital Converter Digital Analogue Digital to Analogue Converter The search for a suitable DSP development system • Low cost hardware • 16bits or more • Windows based supported development software (which should also be low cost or better still free!) • Capable of running a DSP IF scheme Juha Niinikoski, OH2NLT “Cheap DSP” dsPIC30F processor Juha Niinikoski, OH2NLT George Heron, N2APB “SDR Cube Transceiver” Direct Conversion Transceiver using a dsPIC33F processor A solution… • DSP only card with plenty of I/O for controls etc. • Microchip dsPIC33FJ64GP306 at 40MIPS (70MIPs with dsPIC33E)* (64 pin PTQF – not too difficult to solder) • Texas TLV320AIC23B stereo CODEC (28 pin SOP – easy to solder) • MPLAB IDE and the free version of the C30 compiler • Nominal 12V operation • I/O on 0.1” headers, optional pull up resistors, no analogue signal conditioning. *To be tested The Eden dsP Module Eden dsP Module CODEC Config and control L R Stereo Audio in/out Out L R TLV320AIC23 CODEC In +12V SPI I/F PSU (Regs) dsPIC33FJ64 AC97 Codec I/F I/O Ports LEDs (2) Audio data transfer I2C Bus for I2C Devices RS232 Ext Comms Serial Interfaces Indicators Controls (logic/switches etc) Eden dsP Module Eden dsP Module Eden dsP Module Eden dsP Module +12V PSU Programmer USB Connection Eden dsP MPLAB Development Software Programmer (MPLAB) Example programs Program is stored in the dsPIC33F flash memory Add the free C30 Compiler to edit the example Programs or start writing your own! Eden dsP Module Once programmed, the Eden dsP will run the software whenever it is power up – until it is overwritten with a new program. +12V Eden dsP Host equipment Receiver/Transceiver AF Filter Spectrum display etc., etc. The Eden dsP may be programmed whilst installed in its host equipment. What next?” Digital Filters Two most common types IIR “Infinite Impulse Response” input x output a b y FIR “Finite Impulse Response” input FIR Coeff Table output Digital Filters IIR - Infinite Impulse Response Filter – – – – • • • • Feedback system, similar to analogue Op Amp Filter Simple to code Little memory used input a x Very fast execution Roll off not spectacular Phase varies with frequency Potential for instability Useful for general non critical filtering e.g, microphone filters etc b output y Digital Filters Common filter program FIR - Finite Impulse Response Filter – – – – – – Based upon a delay line input Most commonly used filter type Convolution process (multiply, add “MAC”) Employs a table of constants to define filter Capable of phenomenal performance Fixed phase shift and delay • Memory and processor usage high FIR output Coeff Table Filter “Kernel” Sets filter parameters The FIR Filter 3 step “production line” process, similar to a conveyor belt in a factory… or a sushi bar? The FIR Filter 1. Load new sample into a delay line, shifting all current samples along one position. The FIR Filter 1. 2. Load new sample into a delay line, shifting all current samples along one position. Multiply each value on the delay line with a filter constant. ! axb=c The FIR Filter 1. 2. 3. Load new sample into a delay line, shifting all current samples along one position. Multiply each value on the delay line with a filter constant. Add all of the multiplication results together to make the output sample. FIR Filter Step 1. Values move along delay line with each new sample Input Delay Line (filter taps) Tap 1 a x Tap 7 b x c x d e x x f x g x Sum Step 2. Multiplication of each tap value by by a kernel constants (a, b, c, etc) Step 3. Accumulate (running sum of multiplications) Output One sample in, one sample out Last Value Discarded (overwritten) FIR Code Written in assembler for fast (efficient) execution ;********************************************************************************************* ; ; FIR Filter ; ; Universal FIR Filter code ; ;********************************************************************************************* Load input sample mov AF_in, w0 ; Get input and load into w0 mov mov mov mov mov dec #_fir_delay,w8 w8, XMODSRT _fir_delay_end, w8 w8, XMODEND _fir_n, w1 w1, w1 ; ; ; ; ; ; Load delay line start address into w8 XMODSRT = start address of delay line Load delay line end address XMODEND = end address of delay line Load number of taps (N) into w1 Decrement w1 = M (N-1) mov mov mov mov _fir_delay_ptr, w8 w0, [w8++] w8, _fir_delay_ptr _fir_coef_end, w10 ; ; ; ; Load delay line pointer into w8 Move new sample into position pointed to by w8 Update delay line pointer tap vector end to w10 clr A, [w8]+=2, w5, [w10]-+2, w6 repeat w1 ; Clear MAC Accumulator A, load w5 with sample pointed to by w8 and w6 ; with that at w10, post increment and decrement pointers ; Repeat MAC instruction w1 times = Number of taps - 1 mac w5*w6, A, [w8]+=2, w5, [w10]-=2, w6 sac.r a,w0 mov w0, _AF_out Prepare delay line Set up addresses For delay line and Kernel table Multiply and add each record Output result ; Round off result ; Copy output word to filter output ;********************************************************************************************* FIR Filter Kernel // FIR Filter Kernel // // Ron Taylor Cumbria Designs 2012 // // Filter Kernel 1 N=201 Fs=8000 F1=500 #define N 201 const int fir_4_data[N]={ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0001, 0xFFFF, 0xFFFD, 0xFFFC, 0x0000, 0xFFFE, 0xFFFE, 0x0001, 0x0006, 0xFFEB, 0xFFE0, 0xFFDF, 0xFFE9, 0xFFFB, 0x0000, 0x0006, 0x0016, 0x0028, 0x002D, 0xFF9C, 0xFFDD, 0x0030, 0x0075, 0x0093, 0x0000, 0x0026, 0x002A, 0xFFF5, 0xFF8C, 0x0153, 0x01E8, 0x01E8, 0x014B, 0x004D, 0x0000, 0xFFB3, 0xFEE8, 0xFE12, 0xFDD1, 0x0588, 0x0205, 0xFD15, 0xF845, 0xF54E, 0x0CCD, 0x0ADD, 0x05B5, 0xFF09, 0xF902, 0x0588, 0x06C6, 0x05CB, 0x0363, 0x00AE, 0x0000, 0xFFBC, 0xFF2A, 0xFEB6, 0xFEBA, 0x0153, 0x0068, 0xFF83, 0xFEF0, 0xFED1, 0x0000, 0xFFDF, 0xFFDF, 0x0008, 0x0048, 0xFF9C, 0xFF81, 0xFF90, 0xFFBD, 0xFFF2, 0x0000, 0x0005, 0x0010, 0x0019, 0x0018, 0xFFEB, 0xFFFA, 0x0007, 0x000F, 0x0010, 0x0000, 0x0001, 0x0001, 0x0000, 0xFFFE, 0x0002, 0x0002, 0x0001, 0x0001, 0x0000, 0x0000, }; F2=900 0x0000, 0xFFFD, 0x000C, 0x000D, 0x001B, 0x0080, 0xFF16, 0xFF51, 0xFEA9, 0xF576, 0xF576, 0xFEA9, 0xFF51, 0xFF16, 0x0080, 0x001B, 0x000D, 0x000C, 0xFFFD, 0x0000, // Set number // Tap data 0x0000, 0x0001, 0xFFFE, 0x0000, 0x0010, 0x000F, 0x0018, 0x0019, 0xFFF2, 0xFFBD, 0x0048, 0x0008, 0xFED1, 0xFEF0, 0xFEBA, 0xFEB6, 0x00AE, 0x0363, 0xF902, 0xFF09, 0xF54E, 0xF845, 0xFDD1, 0xFE12, 0x004D, 0x014B, 0xFF8C, 0xFFF5, 0x0093, 0x0075, 0x002D, 0x0028, 0xFFFB, 0xFFE9, 0x0006, 0x0001, 0xFFFC, 0xFFFD, 0x0000, 0x0000, of taps 0x0001, 0x0001, 0x0007, 0x0010, 0xFF90, 0xFFDF, 0xFF83, 0xFF2A, 0x05CB, 0x05B5, 0xFD15, 0xFEE8, 0x01E8, 0x002A, 0x0030, 0x0016, 0xFFDF, 0xFFFE, 0xFFFF, 0x0000, 0x0002, 0x0001, 0xFFFA, 0x0005, 0xFF81, 0xFFDF, 0x0068, 0xFFBC, 0x06C6, 0x0ADD, 0x0205, 0xFFB3, 0x01E8, 0x0026, 0xFFDD, 0x0006, 0xFFE0, 0xFFFE, 0x0001, 0x0000, FIR Designer A free FIR design program from those really nice people at; www.cumbriadesigns.co.uk Demonstration Designing a high performance audio CW Filter • • • • FIR Filter 300Hz Bandwidth centred on 700Hz Design and test filter in “FIR Designer” Demonstrate filter using an FT817 – AF input from headphone socket – External LM380 AF power amplifier ; Filter Kernel 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFF9, 0xFFFA, 0xFFFC, 0xFFFC, 0x0000, 0x000C, 0xFFE2, 0xFFF6, 0x0000, 0x0008, 0x004D, 0x0073, 0x0000, 0x003C, 0x0047, 0x001F, 0x0185, 0x0157, 0x00A0, 0x00A3, 0x0000, 0xFE5A, 0x053A, 0x01D1, 0x099A, 0x082A, 0x053A, 0x06C9, 0x0000, 0x0129, 0x00A0, 0x0040, 0x0185, 0x013D, 0x0047, 0x0043, 0x0000, 0xFFBA, 0x004D, 0x0017, 0x0000, 0xFFF9, 0xFFE2, 0xFFD7, 0x0000, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFF9, 0xFFFB, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, N=301 Fs=8000 F1=550 F2=850 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0003, 0xFFFC, 0x0001, 0x0005, 0x0008, 0xFFFE, 0x0000, 0x0000, 0xFFFE, 0x0017, 0x001D, 0x001A, 0x000D, 0x000D, 0x001E, 0x0024, 0x001F, 0x0009, 0xFFFE, 0xFFE8, 0xFFCF, 0x0078, 0x0056, 0x0016, 0xFFCA, 0x0059, 0x0053, 0x0034, 0x0010, 0xFFCC, 0xFF67, 0xFF19, 0xFF0B, 0x00BA, 0xFFE0, 0xFF10, 0xFE92, 0x0060, 0x0011, 0xFFF7, 0x0038, 0xFCC2, 0xFBE1, 0xFC42, 0xFE0B, 0xFD7C, 0xF98F, 0xF758, 0xF7AC, 0x0451, 0xFF43, 0xFA94, 0xF7AC, 0x0637, 0x03F2, 0x00E0, 0xFE0B, 0x0194, 0x0158, 0x00C4, 0x0038, 0xFF9E, 0xFEF4, 0xFE8B, 0xFE92, 0x009F, 0xFFE7, 0xFF52, 0xFF0B, 0x0024, 0x0006, 0xFFFD, 0x0010, 0xFF84, 0xFF72, 0xFF8C, 0xFFCA, 0xFFE5, 0xFFC6, 0xFFC1, 0xFFCF, 0xFFF9, 0x0002, 0x0011, 0x001F, 0xFFD9, 0xFFE6, 0xFFFA, 0x000D, 0xFFF5, 0xFFF7, 0xFFFB, 0xFFFE, 0x0002, 0x0006, 0x0008, 0x0008, 0xFFFD, 0x0000, 0x0003, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x0008, 0xFFFB, 0xFFFA, 0x0011, 0xFFC1, 0xFF8C, 0xFFFD, 0xFF52, 0xFE8B, 0x00C4, 0x00E0, 0xFA94, 0xF758, 0xFC42, 0xFFF7, 0xFF10, 0xFF19, 0x0034, 0x0016, 0xFFE8, 0x0024, 0x001A, 0x0000, 0x0005, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0xFFF7, 0xFFE6, 0x0002, 0xFFC6, 0xFF72, 0x0006, 0xFFE7, 0xFEF4, 0x0158, 0x03F2, 0xFF43, 0xF98F, 0xFBE1, 0x0011, 0xFFE0, 0xFF67, 0x0053, 0x0056, 0xFFFE, 0x001E, 0x001D, 0x0000, 0x0001, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFD, 0x0002, 0xFFF5, 0xFFD9, 0xFFF9, 0xFFE5, 0xFF84, 0x0024, 0x009F, 0xFF9E, 0x0194, 0x0637, 0x0451, 0xFD7C, 0xFCC2, 0x0060, 0x00BA, 0xFFCC, 0x0059, 0x0078, 0x0009, 0x000D, 0x0017, 0xFFFE, 0xFFFC, 0x0001, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFB, 0xFFFE, 0xFFF8, 0xFFD7, 0xFFF9, 0x0017, 0xFFBA, 0x0043, 0x013D, 0x0040, 0x0129, 0x06C9, 0x082A, 0x01D1, 0xFE5A, 0x00A3, 0x0157, 0x001F, 0x003C, 0x0073, 0x0008, 0xFFF6, 0x000C, 0xFFFC, 0xFFFA, 0x0000, 0x0000, 0x0000, Information header added and data formatted for use with C program // FIR Filter Kernel // // Ron Taylor Cumbria Designs 2012 // // Filter Kernel N=301 Fs=8000 F1=550 F2=850 #define N 301 const int fir_coeff[N]={ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0001, 0x0002, 0x0003, 0x0003, 0xFFF9, 0xFFFA, 0xFFFC, 0x0001, 0x0005, 0x0008, 0xFFFC, 0xFFFC, 0xFFFE, 0x0000, 0x0000, 0xFFFE, 0x0000, 0x000C, 0x0017, 0x001D, 0x001A, 0x000D, 0xFFE2, 0xFFF6, 0x000D, 0x001E, 0x0024, 0x001F, 0x0000, 0x0008, 0x0009, 0xFFFE, 0xFFE8, 0xFFCF, 0x004D, 0x0073, 0x0078, 0x0056, 0x0016, 0xFFCA, 0x0000, 0x003C, 0x0059, 0x0053, 0x0034, 0x0010, 0x0047, 0x001F, 0xFFCC, 0xFF67, 0xFF19, 0xFF0B, 0x0185, 0x0157, 0x00BA, 0xFFE0, 0xFF10, 0xFE92, 0x00A0, 0x00A3, 0x0060, 0x0011, 0xFFF7, 0x0038, 0x0000, 0xFE5A, 0xFCC2, 0xFBE1, 0xFC42, 0xFE0B, 0x053A, 0x01D1, 0xFD7C, 0xF98F, 0xF758, 0xF7AC, 0x099A, 0x082A, 0x0451, 0xFF43, 0xFA94, 0xF7AC, 0x053A, 0x06C9, 0x0637, 0x03F2, 0x00E0, 0xFE0B, 0x0000, 0x0129, 0x0194, 0x0158, 0x00C4, 0x0038, 0x00A0, 0x0040, 0xFF9E, 0xFEF4, 0xFE8B, 0xFE92, 0x0185, 0x013D, 0x009F, 0xFFE7, 0xFF52, 0xFF0B, 0x0047, 0x0043, 0x0024, 0x0006, 0xFFFD, 0x0010, 0x0000, 0xFFBA, 0xFF84, 0xFF72, 0xFF8C, 0xFFCA, 0x004D, 0x0017, 0xFFE5, 0xFFC6, 0xFFC1, 0xFFCF, 0x0000, 0xFFF9, 0xFFF9, 0x0002, 0x0011, 0x001F, 0xFFE2, 0xFFD7, 0xFFD9, 0xFFE6, 0xFFFA, 0x000D, 0x0000, 0xFFF8, 0xFFF5, 0xFFF7, 0xFFFB, 0xFFFE, 0xFFFC, 0xFFFE, 0x0002, 0x0006, 0x0008, 0x0008, 0xFFF9, 0xFFFB, 0xFFFD, 0x0000, 0x0003, 0x0003, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; 0x0000, 0x0000, 0x0003, 0x0008, 0xFFFB, 0xFFFA, 0x0011, 0xFFC1, 0xFF8C, 0xFFFD, 0xFF52, 0xFE8B, 0x00C4, 0x00E0, 0xFA94, 0xF758, 0xFC42, 0xFFF7, 0xFF10, 0xFF19, 0x0034, 0x0016, 0xFFE8, 0x0024, 0x001A, 0x0000, 0x0005, 0x0003, 0x0000, 0x0000, // Set number of taps // Tap data 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFD, 0xFFFB, 0x0006, 0x0002, 0xFFFE, 0xFFF7, 0xFFF5, 0xFFF8, 0xFFE6, 0xFFD9, 0xFFD7, 0x0002, 0xFFF9, 0xFFF9, 0xFFC6, 0xFFE5, 0x0017, 0xFF72, 0xFF84, 0xFFBA, 0x0006, 0x0024, 0x0043, 0xFFE7, 0x009F, 0x013D, 0xFEF4, 0xFF9E, 0x0040, 0x0158, 0x0194, 0x0129, 0x03F2, 0x0637, 0x06C9, 0xFF43, 0x0451, 0x082A, 0xF98F, 0xFD7C, 0x01D1, 0xFBE1, 0xFCC2, 0xFE5A, 0x0011, 0x0060, 0x00A3, 0xFFE0, 0x00BA, 0x0157, 0xFF67, 0xFFCC, 0x001F, 0x0053, 0x0059, 0x003C, 0x0056, 0x0078, 0x0073, 0xFFFE, 0x0009, 0x0008, 0x001E, 0x000D, 0xFFF6, 0x001D, 0x0017, 0x000C, 0x0000, 0xFFFE, 0xFFFC, 0x0001, 0xFFFC, 0xFFFA, 0x0002, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, Demonstration Headphone Socket AF Amplifier DSP Module AF In Speaker AF Out Demonstration Headphone Socket Signal path control AF Amplifier Speaker AF Out AF In Eden dsP card DSP in Radio DSP in Radio Two general architectures; Direct Conversion DSP IF System DSP Receiver Architecture Direct Conversion Receiver Filter Bank AF Out DDS Demod Digital phase shifter PC or DSP Unit High IP3 switching Mixers FST3125 etc AF Amplifier Speaker DSP Receiver Architecture DSP IF Dual Conversion, VLF 2nd IF Crystal Filter 2nd Mixer 6kHz IF Amplifier Preselector 2nd IF 15kHz 15kHz IF Out 1st IF 20MHz VFO Carrier oscillator 15kHz IF In AF Amplifier DSP Module (2nd IF) AF Out Speaker DSP Receiver Architecture Multirate DSP IF 48kHz Sampling Rate 9.6Hz Sampling Rate AF I Channel 3kHz Decimator 15kHz IF input to mixers DSP Module Phase shifting filters 5 Sin 15kHz IF In 15kHz quad CIO Cos Gain control 5 3kHz Decimator AF Q Channel AGC Demod Auto-notch De-noiser AF Out ;****************************************************************************************** ; ; I and Q Mixers ; ; ;****************************************************************************************** mixers: ; I mixer mov mov mul.ss mov ; Q mixer mov mov mul.ss mov return _I_mix_in, w1 _I_carrier,w0 w0, w1, w2 w3, _I_mix_out ; ; ; ; Get input signal and place in w1 Get carrier and place in w0 Signed 16bit x 16bit multiply, 32 bit result in w2 and w3 Save most significant word to mixer output _Q_mix_in, w1 _Q_carrier,w0 w0, w1, w2 w3, _Q_mix_out ; ; ; ; Get input signal and place in w1 Get carrier and place in w0 Signed 16bit x 16bit multiply, 32 bit result in w2 and w3 Save most significant word to mixer output DSP IF Demo 48kHz Sampling Rate 9.6Hz Sampling Rate AF I Channel 3kHz Decimator 15kHz IF input to mixers DSP Module Phase shifting filters 5 Sin 15kHz IF In 15kHz quad CIO Cos Gain control 5 3kHz Decimator AF Q Channel AGC Demod Auto-notch De-noiser AF Out Getting Started in DSP • • • • • “Eden dsP” Card, about £50 to build Software MPLAB, C30, FIR Designer, demo programs - all free! PIC programmer (PICkit 3 etc) Modest PC for programming Literature – Digital Signal Processing, Steven Smith – Digital Signal Processing Technology (ARRL), Doug Smith – ARRL/RSGB Handbooks – Beginners Guide to C, Greg Perry – The C Programming Language, Brian Kernigham and Dennis Ritchie