Simple driver for programming the Analogue Devices AD8951 Direct Digital Synthesizer using the cheap KL25Z board

Dependencies:   mbed

Committer:
ptamike
Date:
Sat Oct 26 18:22:46 2013 +0000
Revision:
0:21d4a8e3d6be
Tidied up code and comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ptamike 0:21d4a8e3d6be 1 // MBED driver for AD9851 digital synthesizer using hacked SPI interface
ptamike 0:21d4a8e3d6be 2 // Original code for AD9850 by Liam Goudge Sept 2013
ptamike 0:21d4a8e3d6be 3 // Modified for AD9851 and KL25Z by Mike Richards Oct 2013
ptamike 0:21d4a8e3d6be 4
ptamike 0:21d4a8e3d6be 5 #include "mbed.h"
ptamike 0:21d4a8e3d6be 6
ptamike 0:21d4a8e3d6be 7
ptamike 0:21d4a8e3d6be 8 SPI device (PTD2, PTD3, PTD1); // Set the KL25Z SPI pins
ptamike 0:21d4a8e3d6be 9 DigitalOut CS(PTD0); // Use pin PTD0 as a fake Chip select (AD9851's FQ_UD line)
ptamike 0:21d4a8e3d6be 10 DigitalOut ADReset(PTA13); // Use Pin PTA13 as the reset line for AD9851
ptamike 0:21d4a8e3d6be 11 int targetFrq; // 32-bit frequency word for the AD9851
ptamike 0:21d4a8e3d6be 12 int phase; // Phase and multiplier word for AD9851
ptamike 0:21d4a8e3d6be 13
ptamike 0:21d4a8e3d6be 14 Serial pc(USBTX, USBRX); // tx, rx for debug terminal
ptamike 0:21d4a8e3d6be 15
ptamike 0:21d4a8e3d6be 16 int reverseBits (int source)
ptamike 0:21d4a8e3d6be 17 {
ptamike 0:21d4a8e3d6be 18 // Unfortunately need to invert bit order of the desired frequency setting since MBED only allows for MSB first from SPI. We need LSB first for AD9851
ptamike 0:21d4a8e3d6be 19 int mask=0;;
ptamike 0:21d4a8e3d6be 20 int i=0;
ptamike 0:21d4a8e3d6be 21 int target=0;
ptamike 0:21d4a8e3d6be 22 int bitTarget=0x80000000; // Hard-wired for 32-bit inversion
ptamike 0:21d4a8e3d6be 23
ptamike 0:21d4a8e3d6be 24 for (i=0;i<32;i++) { // ditto
ptamike 0:21d4a8e3d6be 25 mask=1<<i;
ptamike 0:21d4a8e3d6be 26 bitTarget=1<<(31-i); // ditto
ptamike 0:21d4a8e3d6be 27
ptamike 0:21d4a8e3d6be 28 if (source & mask)
ptamike 0:21d4a8e3d6be 29 target=target | bitTarget;
ptamike 0:21d4a8e3d6be 30 }
ptamike 0:21d4a8e3d6be 31 return target;
ptamike 0:21d4a8e3d6be 32 }
ptamike 0:21d4a8e3d6be 33
ptamike 0:21d4a8e3d6be 34 void writeSPI(int frq, int phase)
ptamike 0:21d4a8e3d6be 35 {
ptamike 0:21d4a8e3d6be 36 // Send the 40-bit packet. NB: KL25Z only supports 8-bit SPI so send five 8-bit packets
ptamike 0:21d4a8e3d6be 37
ptamike 0:21d4a8e3d6be 38 device.format(8,0); // 8-bits per packet, mode 0 (CPOL=0 CPHA=0)
ptamike 0:21d4a8e3d6be 39 device.frequency(1000000); //SPI clock set to 1MHz
ptamike 0:21d4a8e3d6be 40
ptamike 0:21d4a8e3d6be 41 wait_ms(1);
ptamike 0:21d4a8e3d6be 42
ptamike 0:21d4a8e3d6be 43 // First do chip select. Need to use a GPIO to fake the chip select since MBED doesn't allow to set positive logic CS signal
ptamike 0:21d4a8e3d6be 44 CS=1; // assert chip select (a.k.a FQ_UD frequency update input to AD9851)
ptamike 0:21d4a8e3d6be 45 wait_ms(1);
ptamike 0:21d4a8e3d6be 46 CS=0;
ptamike 0:21d4a8e3d6be 47
ptamike 0:21d4a8e3d6be 48 // Write 5 x 8-bit packets for the frequency word
ptamike 0:21d4a8e3d6be 49 device.write(frq>>24); // Packet 1
ptamike 0:21d4a8e3d6be 50 device.write(frq>>16); // Packet 2
ptamike 0:21d4a8e3d6be 51 device.write(frq>>8); // Packet 3
ptamike 0:21d4a8e3d6be 52 device.write(frq); // Packet 4
ptamike 0:21d4a8e3d6be 53 device.write(phase); // Packet 5 - Finish with the phase, multiplier and factory settings byte
ptamike 0:21d4a8e3d6be 54
ptamike 0:21d4a8e3d6be 55 // Now pulse FQ_UD again to load the word into the DDS
ptamike 0:21d4a8e3d6be 56 CS=0;
ptamike 0:21d4a8e3d6be 57 wait_ms(1);
ptamike 0:21d4a8e3d6be 58 CS=1;
ptamike 0:21d4a8e3d6be 59 wait_ms(1);
ptamike 0:21d4a8e3d6be 60 CS=0;
ptamike 0:21d4a8e3d6be 61 }
ptamike 0:21d4a8e3d6be 62
ptamike 0:21d4a8e3d6be 63
ptamike 0:21d4a8e3d6be 64 int main()
ptamike 0:21d4a8e3d6be 65 {
ptamike 0:21d4a8e3d6be 66
ptamike 0:21d4a8e3d6be 67
ptamike 0:21d4a8e3d6be 68 int DesFrq = 5000000; // Set the desired output frequency in Hz
ptamike 0:21d4a8e3d6be 69 float Mult = 23.86093; // Multiplier for boards using a 30MHz clock oscillator and 6x multiplier
ptamike 0:21d4a8e3d6be 70 targetFrq= DesFrq * Mult ; // targetFrq is the 32-bit frequency word for the AD9851
ptamike 0:21d4a8e3d6be 71 phase = 0x80; // Set the 6x clock multiplier for systems with 30MHz reference oscillator.
ptamike 0:21d4a8e3d6be 72
ptamike 0:21d4a8e3d6be 73 // Reset the AD9851. Active high logic. Minimum reset period 5 clock cycles
ptamike 0:21d4a8e3d6be 74 ADReset=0;
ptamike 0:21d4a8e3d6be 75 wait_ms(5);
ptamike 0:21d4a8e3d6be 76 ADReset=1;
ptamike 0:21d4a8e3d6be 77 wait_ms(5);
ptamike 0:21d4a8e3d6be 78 ADReset=0;
ptamike 0:21d4a8e3d6be 79
ptamike 0:21d4a8e3d6be 80
ptamike 0:21d4a8e3d6be 81 while(1)
ptamike 0:21d4a8e3d6be 82 {
ptamike 0:21d4a8e3d6be 83
ptamike 0:21d4a8e3d6be 84 writeSPI(reverseBits(targetFrq),phase); // Transfer the frequency settings to the AD9851
ptamike 0:21d4a8e3d6be 85
ptamike 0:21d4a8e3d6be 86
ptamike 0:21d4a8e3d6be 87
ptamike 0:21d4a8e3d6be 88 }
ptamike 0:21d4a8e3d6be 89
ptamike 0:21d4a8e3d6be 90
ptamike 0:21d4a8e3d6be 91 }