Function generator code modified to work on the Freescale KL25Z

Dependencies:   mbed

Fork of AD9850 function generator SPI driver by Liam G

This is an update to the original AD9850 SPI driver produced by Liam Goudge.

The main changes are to assign the appropriate pins and to send the 40-bit AD9850 programming word as five 8-bit packets. This is necessary because the KL25Z only supports 8-bit SPI transfers.

Committer:
liamg
Date:
Sat Sep 28 06:44:57 2013 +0000
Revision:
1:b0e6c82af2ef
Parent:
0:b5fb7b3adfe2
Child:
2:e9d2346ea1bb
Version 2 with updated commentary

Who changed what in which revision?

UserRevisionLine numberNew contents of line
liamg 0:b5fb7b3adfe2 1 // MBED driver for AD9850 digital synthesizer using hacked SPI interface
liamg 0:b5fb7b3adfe2 2 // Liam Goudge Sept 2013
liamg 0:b5fb7b3adfe2 3
liamg 0:b5fb7b3adfe2 4 #include "mbed.h"
liamg 0:b5fb7b3adfe2 5
liamg 0:b5fb7b3adfe2 6 SPI device (p5,p6,p7); // MOSI, MISO (not used), SCLK
liamg 0:b5fb7b3adfe2 7 DigitalOut CS(p8); // Use pin 8 as a fake Chip select
liamg 0:b5fb7b3adfe2 8 DigitalOut ADReset(p15); // Pin 15 is reset line for AD9850
liamg 0:b5fb7b3adfe2 9
liamg 0:b5fb7b3adfe2 10 Serial pc(USBTX, USBRX); // tx, rx for debug terminal
liamg 0:b5fb7b3adfe2 11
liamg 0:b5fb7b3adfe2 12 int reverseBits (int source)
liamg 0:b5fb7b3adfe2 13 {
liamg 0:b5fb7b3adfe2 14 // 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 AD9850
liamg 0:b5fb7b3adfe2 15 int mask=0;;
liamg 0:b5fb7b3adfe2 16 int i=0;
liamg 0:b5fb7b3adfe2 17 int target=0;
liamg 0:b5fb7b3adfe2 18 int bitTarget=0x80000000; // Hard-wired for 32-bit inversion
liamg 0:b5fb7b3adfe2 19
liamg 0:b5fb7b3adfe2 20 for (i=0;i<32;i++) { // ditto
liamg 0:b5fb7b3adfe2 21 mask=1<<i;
liamg 0:b5fb7b3adfe2 22 bitTarget=1<<(31-i); // ditto
liamg 0:b5fb7b3adfe2 23
liamg 0:b5fb7b3adfe2 24 if (source & mask)
liamg 0:b5fb7b3adfe2 25 target=target | bitTarget;
liamg 0:b5fb7b3adfe2 26 }
liamg 0:b5fb7b3adfe2 27 return target;
liamg 0:b5fb7b3adfe2 28 }
liamg 0:b5fb7b3adfe2 29
liamg 0:b5fb7b3adfe2 30 void writeSPI(int frq, int phase)
liamg 0:b5fb7b3adfe2 31 {
liamg 0:b5fb7b3adfe2 32 // Send the 40-bit packet. MBED only allows max 16-bit packets so we send 40-bits as 16, 16, 8
liamg 0:b5fb7b3adfe2 33 device.format(16,0); // 16-bits per packet, mode 0 (CPOL=0 CPHA=0)
liamg 0:b5fb7b3adfe2 34 device.frequency(1000000); //SPI clock set to 1MHz
liamg 0:b5fb7b3adfe2 35
liamg 0:b5fb7b3adfe2 36 wait_ms(5);
liamg 0:b5fb7b3adfe2 37
liamg 0:b5fb7b3adfe2 38 // 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
liamg 0:b5fb7b3adfe2 39 CS=1; // assert chip select (a.k.a FQ_UD frequency update input to AD9850)
liamg 0:b5fb7b3adfe2 40 wait_ms(5);
liamg 0:b5fb7b3adfe2 41 CS=0;
liamg 0:b5fb7b3adfe2 42
liamg 0:b5fb7b3adfe2 43 device.write(frq>>16); // Write upper 16-bits first starting with bit 31
liamg 0:b5fb7b3adfe2 44 device.write(frq); // Now lower 16 bits starting with bit 15
liamg 0:b5fb7b3adfe2 45
liamg 0:b5fb7b3adfe2 46 device.format(8,0); // Need to reset to 8-bit data since MBED only allows max 16-bit packets. For 40-bits we do 16, 16, 8
liamg 0:b5fb7b3adfe2 47 device.write(phase); // This is phase and factory settings byte
liamg 0:b5fb7b3adfe2 48
liamg 0:b5fb7b3adfe2 49 // Now pulse FQ_UD again to signal the end of the packet
liamg 0:b5fb7b3adfe2 50 CS=0;
liamg 0:b5fb7b3adfe2 51 wait_ms(5);
liamg 0:b5fb7b3adfe2 52 CS=1;
liamg 0:b5fb7b3adfe2 53 wait_ms(5);
liamg 0:b5fb7b3adfe2 54 CS=0;
liamg 0:b5fb7b3adfe2 55 }
liamg 0:b5fb7b3adfe2 56
liamg 0:b5fb7b3adfe2 57
liamg 0:b5fb7b3adfe2 58 int main()
liamg 0:b5fb7b3adfe2 59 {
liamg 0:b5fb7b3adfe2 60 int targetFrq=0x147AE148; // This is desired sine wave frequency for the AD9850, here set to 10MHz
liamg 0:b5fb7b3adfe2 61 int increment=0x346DC6; // This is a 100KHz frequency increment
liamg 0:b5fb7b3adfe2 62
liamg 0:b5fb7b3adfe2 63 // Reset the AD9850. Active high logic. Minimum reset period 5 clock cycles (5/125MHz)
liamg 0:b5fb7b3adfe2 64 ADReset=0;
liamg 0:b5fb7b3adfe2 65 wait_ms(5);
liamg 0:b5fb7b3adfe2 66 ADReset=1;
liamg 0:b5fb7b3adfe2 67 wait_ms(5);
liamg 0:b5fb7b3adfe2 68 ADReset=0;
liamg 0:b5fb7b3adfe2 69
liamg 0:b5fb7b3adfe2 70 while(1)
liamg 0:b5fb7b3adfe2 71 {
liamg 0:b5fb7b3adfe2 72
liamg 1:b0e6c82af2ef 73 while (targetFrq<0x28F5C28F) // up to 20MHz
liamg 0:b5fb7b3adfe2 74 {
liamg 1:b0e6c82af2ef 75 writeSPI(reverseBits(targetFrq),0); // Don't use phase so set to zero.
liamg 0:b5fb7b3adfe2 76 targetFrq=targetFrq+increment;
liamg 0:b5fb7b3adfe2 77 //wait_ms(100);
liamg 0:b5fb7b3adfe2 78 }
liamg 0:b5fb7b3adfe2 79
liamg 1:b0e6c82af2ef 80 while (targetFrq>0x147AE148) // down to 10MHz
liamg 0:b5fb7b3adfe2 81 {
liamg 0:b5fb7b3adfe2 82 writeSPI(reverseBits(targetFrq),0);
liamg 0:b5fb7b3adfe2 83 targetFrq=targetFrq-increment;
liamg 0:b5fb7b3adfe2 84 //wait_ms(100);
liamg 0:b5fb7b3adfe2 85 }
liamg 0:b5fb7b3adfe2 86
liamg 0:b5fb7b3adfe2 87 }
liamg 0:b5fb7b3adfe2 88
liamg 0:b5fb7b3adfe2 89
liamg 0:b5fb7b3adfe2 90 }