TTT / Mbed 2 deprecated DDS_Playground

Dependencies:   mbed

Committer:
mdigman
Date:
Mon Apr 06 18:06:52 2015 +0000
Revision:
3:c2b09e28978a
Parent:
2:eb558d650b17
Child:
4:42262a293f60
Updated for 50MHz clock with new DDS on C003;

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
mdigman 0:4a6c8e7e8ea7 12 // These pins control the Phase register and the Frequency register, IF THE DDS IS CONFIGURED TO BE CONTROLLED BY THE PINS,
mdigman 0:4a6c8e7e8ea7 13 //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 14 // By toggling them after config, you can create PSK, FSK, BPSK...
mdigman 3:c2b09e28978a 15 DigitalOut CURRENT(p14); //if=1, output of CSM to input selector / switch 2
mdigman 3:c2b09e28978a 16 DigitalOut DDS_nCS(p15); //nCS line used for SPI on
mdigman 0:4a6c8e7e8ea7 17 DigitalOut DDS_PSEL(p16);
mdigman 0:4a6c8e7e8ea7 18 DigitalOut DDS_FSEL(p17);
mdigman 0:4a6c8e7e8ea7 19
mdigman 3:c2b09e28978a 20 DigitalOut SQUARE(p18); //if=1 closes switch to SQUARE path that is not populated
mdigman 0:4a6c8e7e8ea7 21 DigitalOut DDS(p19); //if=1, DDS output connected to TX_PORT
mdigman 0:4a6c8e7e8ea7 22 DigitalOut AFE(p20); //if=1, Electrode routed to Amplification Path
mdigman 0:4a6c8e7e8ea7 23
mdigman 0:4a6c8e7e8ea7 24 #define SSP_SR_TFE (1<<0)
mdigman 0:4a6c8e7e8ea7 25 #define SSP_SR_TNF (1<<1)
mdigman 0:4a6c8e7e8ea7 26 #define SSP_SR_RFE (1<<2)
mdigman 0:4a6c8e7e8ea7 27 #define SSP_SR_RFF (1<<3)
mdigman 0:4a6c8e7e8ea7 28 #define SSP_SR_BSY (1<<4)
mdigman 0:4a6c8e7e8ea7 29
mdigman 0:4a6c8e7e8ea7 30 void writeReg(uint16_t val){
mdigman 0:4a6c8e7e8ea7 31 __disable_irq();
mdigman 0:4a6c8e7e8ea7 32
mdigman 0:4a6c8e7e8ea7 33 DDS_nCS = 0;
mdigman 0:4a6c8e7e8ea7 34 //DDS_nCS0;
mdigman 0:4a6c8e7e8ea7 35
mdigman 0:4a6c8e7e8ea7 36 while ( !(LPC_SSP0->SR & SSP_SR_TNF) ); //while ssp is not writable
mdigman 0:4a6c8e7e8ea7 37 LPC_SSP0->DR = val; //write this out
mdigman 0:4a6c8e7e8ea7 38 while ( (LPC_SSP0->SR & SSP_SR_BSY) ); //wait until transmission is over to pull ncs up
mdigman 0:4a6c8e7e8ea7 39
mdigman 0:4a6c8e7e8ea7 40 DDS_nCS = 1;
mdigman 0:4a6c8e7e8ea7 41 //DDS_nCS1;
mdigman 0:4a6c8e7e8ea7 42
mdigman 0:4a6c8e7e8ea7 43 __enable_irq();
mdigman 0:4a6c8e7e8ea7 44 }
mdigman 0:4a6c8e7e8ea7 45
mdigman 0:4a6c8e7e8ea7 46 /******************
mdigman 0:4a6c8e7e8ea7 47 DDS Library ported from https://github.com/arachnidlabs/ad983x/blob/master/ad983x.cpp
mdigman 0:4a6c8e7e8ea7 48 ******************/
mdigman 0:4a6c8e7e8ea7 49 #define REG_OPBITEN 0x0020
mdigman 0:4a6c8e7e8ea7 50 #define REG_SIGNPIB 0x0010
mdigman 0:4a6c8e7e8ea7 51 #define REG_DIV2 0x0008
mdigman 0:4a6c8e7e8ea7 52 #define REG_MODE 0x0002
mdigman 0:4a6c8e7e8ea7 53 #define SIGN_OUTPUT_MASK (REG_OPBITEN | REG_SIGNPIB | REG_DIV2 | REG_MODE)
mdigman 0:4a6c8e7e8ea7 54
mdigman 0:4a6c8e7e8ea7 55 uint16_t m_reg;
mdigman 0:4a6c8e7e8ea7 56
mdigman 0:4a6c8e7e8ea7 57 enum SignOutput {
mdigman 0:4a6c8e7e8ea7 58 SIGN_OUTPUT_NONE = 0x0000,
mdigman 0:4a6c8e7e8ea7 59 SIGN_OUTPUT_MSB = 0x0028,
mdigman 0:4a6c8e7e8ea7 60 SIGN_OUTPUT_MSB_2 = 0x0020,
mdigman 0:4a6c8e7e8ea7 61 SIGN_OUTPUT_COMPARATOR = 0x0038,
mdigman 0:4a6c8e7e8ea7 62 };
mdigman 0:4a6c8e7e8ea7 63
mdigman 0:4a6c8e7e8ea7 64 void setSignOutput(SignOutput out) {
mdigman 0:4a6c8e7e8ea7 65 m_reg = (m_reg & ~SIGN_OUTPUT_MASK) | out;
mdigman 0:4a6c8e7e8ea7 66 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 67 }
mdigman 0:4a6c8e7e8ea7 68
mdigman 0:4a6c8e7e8ea7 69 enum OutputMode {
mdigman 0:4a6c8e7e8ea7 70 OUTPUT_MODE_SINE = 0x0000,
mdigman 0:4a6c8e7e8ea7 71 OUTPUT_MODE_TRIANGLE = 0x0002,
mdigman 0:4a6c8e7e8ea7 72 };
mdigman 0:4a6c8e7e8ea7 73
mdigman 0:4a6c8e7e8ea7 74 void setOutputMode(OutputMode out) {
mdigman 0:4a6c8e7e8ea7 75 if(out == OUTPUT_MODE_TRIANGLE) {
mdigman 0:4a6c8e7e8ea7 76 m_reg = (m_reg & ~SIGN_OUTPUT_MASK) | out;
mdigman 0:4a6c8e7e8ea7 77 } else {
mdigman 0:4a6c8e7e8ea7 78 m_reg &= ~REG_MODE;
mdigman 0:4a6c8e7e8ea7 79 }
mdigman 0:4a6c8e7e8ea7 80 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 81 }
mdigman 0:4a6c8e7e8ea7 82
mdigman 0:4a6c8e7e8ea7 83 #define REG_FREQ1 0x8000
mdigman 0:4a6c8e7e8ea7 84 #define REG_FREQ0 0x4000
mdigman 0:4a6c8e7e8ea7 85 void setFrequencyWord(bool reg, uint32_t frequency) {
brakova 2:eb558d650b17 86 writeReg(0x2000); // sets the PIN/SW D9 pin to high >> FSELECT pin can be used to use either FREQ0 or FREQ1
mdigman 0:4a6c8e7e8ea7 87 writeReg((reg?REG_FREQ1:REG_FREQ0) | (frequency & 0x3FFF));
mdigman 0:4a6c8e7e8ea7 88 writeReg((reg?REG_FREQ1:REG_FREQ0) | ((frequency >> 14) & 0x3FFF));
mdigman 0:4a6c8e7e8ea7 89 }
mdigman 0:4a6c8e7e8ea7 90
mdigman 0:4a6c8e7e8ea7 91 #define REG_PHASE0 0xC000
mdigman 0:4a6c8e7e8ea7 92 #define REG_PHASE1 0xE000
mdigman 0:4a6c8e7e8ea7 93 void setPhaseWord(bool reg, uint32_t phase) {
mdigman 0:4a6c8e7e8ea7 94 writeReg((reg?REG_PHASE1:REG_PHASE0) | (phase & 0x0FFF));
mdigman 0:4a6c8e7e8ea7 95 }
mdigman 0:4a6c8e7e8ea7 96
mdigman 0:4a6c8e7e8ea7 97 #define REG_FSEL 0x0800
mdigman 0:4a6c8e7e8ea7 98 void selectFrequency(bool reg) {
mdigman 0:4a6c8e7e8ea7 99 if(reg) {
mdigman 0:4a6c8e7e8ea7 100 m_reg |= REG_FSEL;
mdigman 0:4a6c8e7e8ea7 101 } else {
mdigman 0:4a6c8e7e8ea7 102 m_reg &= ~REG_FSEL;
mdigman 0:4a6c8e7e8ea7 103 }
mdigman 0:4a6c8e7e8ea7 104 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 105 }
mdigman 0:4a6c8e7e8ea7 106
mdigman 0:4a6c8e7e8ea7 107 #define REG_PSEL 0x0400
mdigman 0:4a6c8e7e8ea7 108 void selectPhase(bool reg) {
mdigman 0:4a6c8e7e8ea7 109 if(reg) {
mdigman 0:4a6c8e7e8ea7 110 m_reg |= REG_PSEL;
mdigman 0:4a6c8e7e8ea7 111 } else {
mdigman 0:4a6c8e7e8ea7 112 m_reg &= ~REG_PSEL;
mdigman 0:4a6c8e7e8ea7 113 }
mdigman 0:4a6c8e7e8ea7 114 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 115 }
mdigman 0:4a6c8e7e8ea7 116
mdigman 0:4a6c8e7e8ea7 117 #define REG_RESET 0x0100
mdigman 0:4a6c8e7e8ea7 118 void reset(bool in_reset) {
mdigman 0:4a6c8e7e8ea7 119 if(in_reset) {
mdigman 0:4a6c8e7e8ea7 120 m_reg |= REG_RESET;
mdigman 0:4a6c8e7e8ea7 121 } else {
mdigman 0:4a6c8e7e8ea7 122 m_reg &= ~REG_RESET;
mdigman 0:4a6c8e7e8ea7 123 }
mdigman 0:4a6c8e7e8ea7 124 writeReg(m_reg); //writes 16 bits over SPI
mdigman 0:4a6c8e7e8ea7 125 }
mdigman 0:4a6c8e7e8ea7 126
mdigman 0:4a6c8e7e8ea7 127 void begin(){
mdigman 0:4a6c8e7e8ea7 128 reset(true);
mdigman 0:4a6c8e7e8ea7 129 writeReg(m_reg);
mdigman 0:4a6c8e7e8ea7 130 // Initialize frequency and phase registers to 0
mdigman 0:4a6c8e7e8ea7 131 setFrequencyWord(0, 0);
mdigman 0:4a6c8e7e8ea7 132 setFrequencyWord(1, 0);
mdigman 0:4a6c8e7e8ea7 133 setPhaseWord(0, 0);
mdigman 0:4a6c8e7e8ea7 134 setPhaseWord(1, 0);
mdigman 0:4a6c8e7e8ea7 135 reset(false);
mdigman 0:4a6c8e7e8ea7 136 }
mdigman 0:4a6c8e7e8ea7 137
brakova 2:eb558d650b17 138 uint8_t Crc8(uint8_t *vptr, int len)
brakova 2:eb558d650b17 139 {
brakova 2:eb558d650b17 140 uint8_t *data = vptr;
brakova 2:eb558d650b17 141 unsigned crc = 0;
brakova 2:eb558d650b17 142 int i, j;
brakova 2:eb558d650b17 143 for (j = len; j; j--, data++) {
brakova 2:eb558d650b17 144 crc ^= (*data << 8);
brakova 2:eb558d650b17 145 for(i = 8; i; i--) {
brakova 2:eb558d650b17 146 if (crc & 0x8000)
brakova 2:eb558d650b17 147 crc ^= (0x1070 << 3);
brakova 2:eb558d650b17 148 crc <<= 1;
brakova 2:eb558d650b17 149 }
brakova 2:eb558d650b17 150 }
brakova 2:eb558d650b17 151 return (uint8_t)(crc >> 8);
brakova 2:eb558d650b17 152 }
brakova 2:eb558d650b17 153
mdigman 0:4a6c8e7e8ea7 154 /*******************
mdigman 0:4a6c8e7e8ea7 155 MAIN
mdigman 0:4a6c8e7e8ea7 156 *******************/
mdigman 0:4a6c8e7e8ea7 157 int main() {
mdigman 0:4a6c8e7e8ea7 158 //init pins
mdigman 0:4a6c8e7e8ea7 159 DDS_PSEL = 0;
mdigman 0:4a6c8e7e8ea7 160 DDS_FSEL = 0;
mdigman 0:4a6c8e7e8ea7 161 SQUARE = 0;
mdigman 0:4a6c8e7e8ea7 162 DDS = 0;
mdigman 0:4a6c8e7e8ea7 163 AFE = 0;
mdigman 0:4a6c8e7e8ea7 164 LED_3 = 1;
mdigman 0:4a6c8e7e8ea7 165
mdigman 0:4a6c8e7e8ea7 166 //nCS lines
mdigman 0:4a6c8e7e8ea7 167 DDS_nCS = 1;
mdigman 0:4a6c8e7e8ea7 168 ADC_nCS = 1;
mdigman 0:4a6c8e7e8ea7 169
mdigman 0:4a6c8e7e8ea7 170 //init spi
mdigman 0:4a6c8e7e8ea7 171 SPI_AFE_ADC_AND_DDS.format(16,2);
mdigman 0:4a6c8e7e8ea7 172 SPI_AFE_ADC_AND_DDS.frequency(33000000);
mdigman 0:4a6c8e7e8ea7 173
mdigman 0:4a6c8e7e8ea7 174 //make sure SPI is setup to mode 2, MSB first
mdigman 0:4a6c8e7e8ea7 175 //init DDS
mdigman 0:4a6c8e7e8ea7 176 begin();
mdigman 0:4a6c8e7e8ea7 177 //output calculation
mdigman 3:c2b09e28978a 178 //fOut = fMCLK / 2^28 * FREQREG = 50e6 / 2^28 * FREQREG
mdigman 3:c2b09e28978a 179 //FREQREG = fOut * 2^28 / 50e6 = fOut * 5.36870912
mdigman 3:c2b09e28978a 180 //1 MHz: 5368709, 2 MHz: 10737418, 3 MHz: 16106127, 4 MHz: 21474836, 8 MHz: 42949673 MHz, 20 MHz: 107374182, Max: 0x3FFF
mdigman 3:c2b09e28978a 181 setFrequencyWord(0, 42949673);
mdigman 3:c2b09e28978a 182 setFrequencyWord(1, 0x3FFF);
mdigman 3:c2b09e28978a 183 selectFrequency(0);
mdigman 0:4a6c8e7e8ea7 184
mdigman 3:c2b09e28978a 185 //setOutputMode(OUTPUT_MODE_SINE);
mdigman 0:4a6c8e7e8ea7 186 setSignOutput(SIGN_OUTPUT_MSB);
mdigman 3:c2b09e28978a 187 //setSignOutput(SIGN_OUTPUT_COMPARATOR); //max output freq appx 6.357 MHz?
mdigman 0:4a6c8e7e8ea7 188 //open the DDS output
mdigman 0:4a6c8e7e8ea7 189 SQUARE = 1;
brakova 2:eb558d650b17 190
brakova 2:eb558d650b17 191 #define bit_up_time 8 //8 for no logic
brakova 2:eb558d650b17 192 #define bit_guard_time 8 //8 for no logic
brakova 2:eb558d650b17 193 #define data_reset_time 16 //16 for no logic
brakova 2:eb558d650b17 194
brakova 2:eb558d650b17 195 //specify the data
brakova 2:eb558d650b17 196 #define data_len 9 //in bytes, remember to leave the last byte as 0 for the crc
brakova 2:eb558d650b17 197 uint8_t data[data_len] = {0xAA, 0xFF, 0xD0, 0x59, 0xE4, 0xCC, 0x1A, 0x2A, 0}; //bt mac format: header, type, data ... data, crc (crc should be 0x89 in this case)
brakova 2:eb558d650b17 198 data[data_len-1] = Crc8(&data[1], data_len-2); //crc includes everything except the header byte
brakova 2:eb558d650b17 199 uint8_t bytecount = 0, bitcount = 0;
brakova 2:eb558d650b17 200 int32_t freq = 0;
brakova 2:eb558d650b17 201 uint8_t freqRegister = 0;
brakova 2:eb558d650b17 202
mdigman 3:c2b09e28978a 203
brakova 2:eb558d650b17 204 __disable_irq();
brakova 2:eb558d650b17 205 while(1) {
brakova 2:eb558d650b17 206 for (bytecount=0; bytecount<data_len; bytecount++){
brakova 2:eb558d650b17 207 for(bitcount=0; bitcount<8; bitcount++){
brakova 2:eb558d650b17 208 if ( (( data[bytecount]>>bitcount ) & 0x01) == 0){ //send binary 0
brakova 2:eb558d650b17 209
brakova 2:eb558d650b17 210 selectFrequency(0);
brakova 2:eb558d650b17 211 SQUARE = 1;
brakova 2:eb558d650b17 212
brakova 2:eb558d650b17 213 wait_ms(bit_up_time);
brakova 2:eb558d650b17 214
brakova 2:eb558d650b17 215 SQUARE = 0;
brakova 2:eb558d650b17 216 //set_DDS(DDS_MCLK_SLEEP); //THIS CAUSES PROBLEMS - ENVELOPE ON DATA?
brakova 2:eb558d650b17 217 wait_ms(bit_guard_time);
brakova 2:eb558d650b17 218
brakova 2:eb558d650b17 219 } else { //send binary 1
brakova 2:eb558d650b17 220 selectFrequency(1);
brakova 2:eb558d650b17 221 SQUARE = 1;
brakova 2:eb558d650b17 222
brakova 2:eb558d650b17 223 wait_ms(bit_up_time);
brakova 2:eb558d650b17 224
brakova 2:eb558d650b17 225 SQUARE = 0;
brakova 2:eb558d650b17 226 //set_DDS(DDS_MCLK_SLEEP); //THIS CAUSES PROBLEMS - ENVELOPE ON DATA?
brakova 2:eb558d650b17 227 wait_ms(bit_guard_time);
brakova 2:eb558d650b17 228 }
brakova 2:eb558d650b17 229 }//end bitcount
brakova 2:eb558d650b17 230 }//end bytecount
brakova 2:eb558d650b17 231
brakova 2:eb558d650b17 232 wait_ms(data_reset_time); //all the data has been sent, delay for some time to reset
brakova 2:eb558d650b17 233
brakova 2:eb558d650b17 234 }//end while
brakova 2:eb558d650b17 235 __enable_irq();
brakova 2:eb558d650b17 236
mdigman 0:4a6c8e7e8ea7 237 }