TTT / Mbed 2 deprecated DDS_Playground

Dependencies:   mbed

Committer:
mdigman
Date:
Fri Mar 20 18:04:55 2015 +0000
Revision:
0:4a6c8e7e8ea7
Child:
1:25c850668cef
Ported DDS library. Sets output frequency of IOUT and IOUTB, turns on the MSB output. Square waves based on MSB are working!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mdigman 0:4a6c8e7e8ea7 1 #include "mbed.h"
mdigman 0:4a6c8e7e8ea7 2
mdigman 0:4a6c8e7e8ea7 3 DigitalOut LED_3(LED3);
mdigman 0:4a6c8e7e8ea7 4
mdigman 0:4a6c8e7e8ea7 5 /******
mdigman 0:4a6c8e7e8ea7 6 PIN + SPI CONFIG
mdigman 0:4a6c8e7e8ea7 7 ******/
mdigman 0:4a6c8e7e8ea7 8
mdigman 0:4a6c8e7e8ea7 9 SPI SPI_AFE_ADC_AND_DDS(p5, p6, p7); //SPI0: MOSI, MISO, SCLK
mdigman 0:4a6c8e7e8ea7 10 DigitalOut ADC_nCS(p8); //ADC_!CS
mdigman 0:4a6c8e7e8ea7 11 DigitalOut DDS_nCS(p15); //DDS_!CS
mdigman 0:4a6c8e7e8ea7 12
mdigman 0:4a6c8e7e8ea7 13 SPI SPI_CUR_ADC(p11, p12, p13); //SPI1 - see page 601 of 947
mdigman 0:4a6c8e7e8ea7 14 DigitalOut CUR_nCS(p14); //DDS_!CS
mdigman 0:4a6c8e7e8ea7 15
mdigman 0:4a6c8e7e8ea7 16 // These pins control the Phase register and the Frequency register, IF THE DDS IS CONFIGURED TO BE CONTROLLED BY THE PINS,
mdigman 0:4a6c8e7e8ea7 17 //BY DEFAULT, AND HOW I HAVE IT CONFIGURED IS TO NOT USE THESE PINS, REPEAT, it does NOT USE THE PINS, instead uses the SPI bus.
mdigman 0:4a6c8e7e8ea7 18 // By toggling them after config, you can create PSK, FSK, BPSK...
mdigman 0:4a6c8e7e8ea7 19 DigitalOut DDS_PSEL(p16);
mdigman 0:4a6c8e7e8ea7 20 DigitalOut DDS_FSEL(p17);
mdigman 0:4a6c8e7e8ea7 21
mdigman 0:4a6c8e7e8ea7 22 DigitalOut SQUARE(p18); //currently does nothing, =1 closes switch to SQUARE path that is not populated
mdigman 0:4a6c8e7e8ea7 23 DigitalOut DDS(p19); //if=1, DDS output connected to TX_PORT
mdigman 0:4a6c8e7e8ea7 24 DigitalOut AFE(p20); //if=1, Electrode routed to Amplification Path
mdigman 0:4a6c8e7e8ea7 25
mdigman 0:4a6c8e7e8ea7 26
mdigman 0:4a6c8e7e8ea7 27 #define SSP_SR_TFE (1<<0)
mdigman 0:4a6c8e7e8ea7 28 #define SSP_SR_TNF (1<<1)
mdigman 0:4a6c8e7e8ea7 29 #define SSP_SR_RFE (1<<2)
mdigman 0:4a6c8e7e8ea7 30 #define SSP_SR_RFF (1<<3)
mdigman 0:4a6c8e7e8ea7 31 #define SSP_SR_BSY (1<<4)
mdigman 0:4a6c8e7e8ea7 32
mdigman 0:4a6c8e7e8ea7 33 void writeReg(uint16_t val){
mdigman 0:4a6c8e7e8ea7 34 __disable_irq();
mdigman 0:4a6c8e7e8ea7 35
mdigman 0:4a6c8e7e8ea7 36 DDS_nCS = 0;
mdigman 0:4a6c8e7e8ea7 37 //DDS_nCS0;
mdigman 0:4a6c8e7e8ea7 38
mdigman 0:4a6c8e7e8ea7 39 while ( !(LPC_SSP0->SR & SSP_SR_TNF) ); //while ssp is not writable
mdigman 0:4a6c8e7e8ea7 40 LPC_SSP0->DR = val; //write this out
mdigman 0:4a6c8e7e8ea7 41 while ( (LPC_SSP0->SR & SSP_SR_BSY) ); //wait until transmission is over to pull ncs up
mdigman 0:4a6c8e7e8ea7 42
mdigman 0:4a6c8e7e8ea7 43 DDS_nCS = 1;
mdigman 0:4a6c8e7e8ea7 44 //DDS_nCS1;
mdigman 0:4a6c8e7e8ea7 45
mdigman 0:4a6c8e7e8ea7 46 __enable_irq();
mdigman 0:4a6c8e7e8ea7 47 }
mdigman 0:4a6c8e7e8ea7 48
mdigman 0:4a6c8e7e8ea7 49 /******************
mdigman 0:4a6c8e7e8ea7 50 DDS Library ported from https://github.com/arachnidlabs/ad983x/blob/master/ad983x.cpp
mdigman 0:4a6c8e7e8ea7 51 ******************/
mdigman 0:4a6c8e7e8ea7 52 #define REG_OPBITEN 0x0020
mdigman 0:4a6c8e7e8ea7 53 #define REG_SIGNPIB 0x0010
mdigman 0:4a6c8e7e8ea7 54 #define REG_DIV2 0x0008
mdigman 0:4a6c8e7e8ea7 55 #define REG_MODE 0x0002
mdigman 0:4a6c8e7e8ea7 56 #define SIGN_OUTPUT_MASK (REG_OPBITEN | REG_SIGNPIB | REG_DIV2 | REG_MODE)
mdigman 0:4a6c8e7e8ea7 57
mdigman 0:4a6c8e7e8ea7 58 uint16_t m_reg;
mdigman 0:4a6c8e7e8ea7 59
mdigman 0:4a6c8e7e8ea7 60 enum SignOutput {
mdigman 0:4a6c8e7e8ea7 61 SIGN_OUTPUT_NONE = 0x0000,
mdigman 0:4a6c8e7e8ea7 62 SIGN_OUTPUT_MSB = 0x0028,
mdigman 0:4a6c8e7e8ea7 63 SIGN_OUTPUT_MSB_2 = 0x0020,
mdigman 0:4a6c8e7e8ea7 64 SIGN_OUTPUT_COMPARATOR = 0x0038,
mdigman 0:4a6c8e7e8ea7 65 };
mdigman 0:4a6c8e7e8ea7 66
mdigman 0:4a6c8e7e8ea7 67 void setSignOutput(SignOutput out) {
mdigman 0:4a6c8e7e8ea7 68 m_reg = (m_reg & ~SIGN_OUTPUT_MASK) | out;
mdigman 0:4a6c8e7e8ea7 69 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 70 }
mdigman 0:4a6c8e7e8ea7 71
mdigman 0:4a6c8e7e8ea7 72 enum OutputMode {
mdigman 0:4a6c8e7e8ea7 73 OUTPUT_MODE_SINE = 0x0000,
mdigman 0:4a6c8e7e8ea7 74 OUTPUT_MODE_TRIANGLE = 0x0002,
mdigman 0:4a6c8e7e8ea7 75 };
mdigman 0:4a6c8e7e8ea7 76
mdigman 0:4a6c8e7e8ea7 77 void setOutputMode(OutputMode out) {
mdigman 0:4a6c8e7e8ea7 78 if(out == OUTPUT_MODE_TRIANGLE) {
mdigman 0:4a6c8e7e8ea7 79 m_reg = (m_reg & ~SIGN_OUTPUT_MASK) | out;
mdigman 0:4a6c8e7e8ea7 80 } else {
mdigman 0:4a6c8e7e8ea7 81 m_reg &= ~REG_MODE;
mdigman 0:4a6c8e7e8ea7 82 }
mdigman 0:4a6c8e7e8ea7 83 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 84 }
mdigman 0:4a6c8e7e8ea7 85
mdigman 0:4a6c8e7e8ea7 86 #define REG_FREQ1 0x8000
mdigman 0:4a6c8e7e8ea7 87 #define REG_FREQ0 0x4000
mdigman 0:4a6c8e7e8ea7 88 void setFrequencyWord(bool reg, uint32_t frequency) {
mdigman 0:4a6c8e7e8ea7 89 writeReg(0x2000);
mdigman 0:4a6c8e7e8ea7 90 writeReg((reg?REG_FREQ1:REG_FREQ0) | (frequency & 0x3FFF));
mdigman 0:4a6c8e7e8ea7 91 writeReg((reg?REG_FREQ1:REG_FREQ0) | ((frequency >> 14) & 0x3FFF));
mdigman 0:4a6c8e7e8ea7 92 }
mdigman 0:4a6c8e7e8ea7 93
mdigman 0:4a6c8e7e8ea7 94 #define REG_PHASE0 0xC000
mdigman 0:4a6c8e7e8ea7 95 #define REG_PHASE1 0xE000
mdigman 0:4a6c8e7e8ea7 96 void setPhaseWord(bool reg, uint32_t phase) {
mdigman 0:4a6c8e7e8ea7 97 writeReg((reg?REG_PHASE1:REG_PHASE0) | (phase & 0x0FFF));
mdigman 0:4a6c8e7e8ea7 98 }
mdigman 0:4a6c8e7e8ea7 99
mdigman 0:4a6c8e7e8ea7 100 #define REG_FSEL 0x0800
mdigman 0:4a6c8e7e8ea7 101 void selectFrequency(bool reg) {
mdigman 0:4a6c8e7e8ea7 102 if(reg) {
mdigman 0:4a6c8e7e8ea7 103 m_reg |= REG_FSEL;
mdigman 0:4a6c8e7e8ea7 104 } else {
mdigman 0:4a6c8e7e8ea7 105 m_reg &= ~REG_FSEL;
mdigman 0:4a6c8e7e8ea7 106 }
mdigman 0:4a6c8e7e8ea7 107 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 108 }
mdigman 0:4a6c8e7e8ea7 109
mdigman 0:4a6c8e7e8ea7 110 #define REG_PSEL 0x0400
mdigman 0:4a6c8e7e8ea7 111 void selectPhase(bool reg) {
mdigman 0:4a6c8e7e8ea7 112 if(reg) {
mdigman 0:4a6c8e7e8ea7 113 m_reg |= REG_PSEL;
mdigman 0:4a6c8e7e8ea7 114 } else {
mdigman 0:4a6c8e7e8ea7 115 m_reg &= ~REG_PSEL;
mdigman 0:4a6c8e7e8ea7 116 }
mdigman 0:4a6c8e7e8ea7 117 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 118 }
mdigman 0:4a6c8e7e8ea7 119
mdigman 0:4a6c8e7e8ea7 120 #define REG_RESET 0x0100
mdigman 0:4a6c8e7e8ea7 121 void reset(bool in_reset) {
mdigman 0:4a6c8e7e8ea7 122 if(in_reset) {
mdigman 0:4a6c8e7e8ea7 123 m_reg |= REG_RESET;
mdigman 0:4a6c8e7e8ea7 124 } else {
mdigman 0:4a6c8e7e8ea7 125 m_reg &= ~REG_RESET;
mdigman 0:4a6c8e7e8ea7 126 }
mdigman 0:4a6c8e7e8ea7 127 writeReg(m_reg); //writes 16 bits over SPI
mdigman 0:4a6c8e7e8ea7 128 }
mdigman 0:4a6c8e7e8ea7 129
mdigman 0:4a6c8e7e8ea7 130 void begin(){
mdigman 0:4a6c8e7e8ea7 131 reset(true);
mdigman 0:4a6c8e7e8ea7 132 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 133 // Initialize frequency and phase registers to 0
mdigman 0:4a6c8e7e8ea7 134 setFrequencyWord(0, 0);
mdigman 0:4a6c8e7e8ea7 135 setFrequencyWord(1, 0);
mdigman 0:4a6c8e7e8ea7 136 setPhaseWord(0, 0);
mdigman 0:4a6c8e7e8ea7 137 setPhaseWord(1, 0);
mdigman 0:4a6c8e7e8ea7 138 reset(false);
mdigman 0:4a6c8e7e8ea7 139 }
mdigman 0:4a6c8e7e8ea7 140
mdigman 0:4a6c8e7e8ea7 141 /*******************
mdigman 0:4a6c8e7e8ea7 142 MAIN
mdigman 0:4a6c8e7e8ea7 143 *******************/
mdigman 0:4a6c8e7e8ea7 144 int main() {
mdigman 0:4a6c8e7e8ea7 145 //init pins
mdigman 0:4a6c8e7e8ea7 146 DDS_PSEL = 0;
mdigman 0:4a6c8e7e8ea7 147 DDS_FSEL = 0;
mdigman 0:4a6c8e7e8ea7 148 SQUARE = 0;
mdigman 0:4a6c8e7e8ea7 149 DDS = 0;
mdigman 0:4a6c8e7e8ea7 150 AFE = 0;
mdigman 0:4a6c8e7e8ea7 151 LED_3 = 1;
mdigman 0:4a6c8e7e8ea7 152
mdigman 0:4a6c8e7e8ea7 153 //nCS lines
mdigman 0:4a6c8e7e8ea7 154 DDS_nCS = 1;
mdigman 0:4a6c8e7e8ea7 155 CUR_nCS = 1;
mdigman 0:4a6c8e7e8ea7 156 ADC_nCS = 1;
mdigman 0:4a6c8e7e8ea7 157
mdigman 0:4a6c8e7e8ea7 158 //init spi
mdigman 0:4a6c8e7e8ea7 159 SPI_AFE_ADC_AND_DDS.format(16,2);
mdigman 0:4a6c8e7e8ea7 160 SPI_AFE_ADC_AND_DDS.frequency(33000000);
mdigman 0:4a6c8e7e8ea7 161
mdigman 0:4a6c8e7e8ea7 162 //make sure SPI is setup to mode 2, MSB first
mdigman 0:4a6c8e7e8ea7 163 //init DDS
mdigman 0:4a6c8e7e8ea7 164 begin();
mdigman 0:4a6c8e7e8ea7 165 //output calculation
mdigman 0:4a6c8e7e8ea7 166 //fOut = fMCLK / 2^28 * FREQREG = 16e6 / 2^28 * FREQREG
mdigman 0:4a6c8e7e8ea7 167 //FREQREG = fOut * 2^28 / 16e6 = fOut * 16.777216
mdigman 0:4a6c8e7e8ea7 168 setFrequencyWord(0, 134217728);
mdigman 0:4a6c8e7e8ea7 169 selectFrequency(0);
mdigman 0:4a6c8e7e8ea7 170
mdigman 0:4a6c8e7e8ea7 171 setSignOutput(SIGN_OUTPUT_MSB);
mdigman 0:4a6c8e7e8ea7 172 //open the DDS output
mdigman 0:4a6c8e7e8ea7 173 SQUARE = 1;
mdigman 0:4a6c8e7e8ea7 174
mdigman 0:4a6c8e7e8ea7 175
mdigman 0:4a6c8e7e8ea7 176 }