TTT / Mbed 2 deprecated DDS_Playground

Dependencies:   mbed

Committer:
mdigman
Date:
Fri Mar 20 20:56:43 2015 +0000
Revision:
1:25c850668cef
Parent:
0:4a6c8e7e8ea7
Child:
2:eb558d650b17
Known to work at outputting 8M, 4M, 1M, 300k, 150k. Does not work after rebooting!

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 1:25c850668cef 168 setFrequencyWord(0, 16777216);
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 }