TTT / Mbed 2 deprecated DDS_Playground

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 DigitalOut LED_3(LED3);
00004 
00005 /******
00006 PIN + SPI CONFIG
00007 ******/
00008 
00009 SPI SPI_AFE_ADC_AND_DDS(p5, p6, p7); //SPI0: MOSI, MISO, SCLK
00010 DigitalOut ADC_nCS(p8);  //ADC_!CS
00011 
00012 //  These pins control the Phase register and the Frequency register, IF THE DDS IS CONFIGURED TO BE CONTROLLED BY THE PINS,
00013 //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.
00014 //  By toggling them after config, you can create PSK, FSK, BPSK...
00015 DigitalOut CURRENT(p14); //if=1, output of CSM to input selector / switch 2
00016 DigitalOut DDS_nCS(p15); //nCS line used for SPI on 
00017 DigitalOut DDS_PSEL(p16);    
00018 DigitalOut DDS_FSEL(p17);  
00019 
00020 DigitalOut SQUARE(p18); //if=1 closes switch to SQUARE path that is not populated
00021 DigitalOut DDS(p19); //if=1, DDS output connected to TX_PORT
00022 DigitalOut AFE(p20); //if=1, Electrode routed to Amplification Path
00023 
00024 #define SSP_SR_TFE (1<<0)
00025 #define SSP_SR_TNF (1<<1)
00026 #define SSP_SR_RFE (1<<2)
00027 #define SSP_SR_RFF (1<<3)
00028 #define SSP_SR_BSY (1<<4)
00029 
00030 void writeReg(uint16_t val){
00031     __disable_irq();
00032 
00033     DDS_nCS = 0;
00034     //DDS_nCS0;
00035     
00036     while ( !(LPC_SSP0->SR & SSP_SR_TNF) ); //while ssp is not writable
00037     LPC_SSP0->DR = val;                //write this out 
00038     while ( (LPC_SSP0->SR & SSP_SR_BSY) ); //wait until transmission is over to pull ncs up
00039     
00040     DDS_nCS = 1;
00041     //DDS_nCS1;
00042     
00043     __enable_irq();
00044 }
00045 
00046 /******************
00047 DDS Library ported from https://github.com/arachnidlabs/ad983x/blob/master/ad983x.cpp
00048 ******************/
00049 #define REG_OPBITEN 0x0020
00050 #define REG_SIGNPIB 0x0010
00051 #define REG_DIV2    0x0008
00052 #define REG_MODE    0x0002
00053 #define SIGN_OUTPUT_MASK (REG_OPBITEN | REG_SIGNPIB | REG_DIV2 | REG_MODE)
00054 
00055 uint16_t m_reg;
00056 
00057 enum SignOutput {
00058   SIGN_OUTPUT_NONE        = 0x0000,
00059   SIGN_OUTPUT_MSB         = 0x0028,
00060   SIGN_OUTPUT_MSB_2       = 0x0020,
00061   SIGN_OUTPUT_COMPARATOR  = 0x0038,
00062 };
00063 
00064 void setSignOutput(SignOutput out) {
00065   m_reg = (m_reg & ~SIGN_OUTPUT_MASK) | out;
00066   writeReg(m_reg);
00067 }
00068 
00069 enum OutputMode {
00070   OUTPUT_MODE_SINE        = 0x0000,
00071   OUTPUT_MODE_TRIANGLE    = 0x0002,
00072 };
00073 
00074 void setOutputMode(OutputMode out) {
00075   if(out == OUTPUT_MODE_TRIANGLE) {
00076     m_reg = (m_reg & ~SIGN_OUTPUT_MASK) | out;
00077   } else {
00078     m_reg &= ~REG_MODE;
00079   }
00080   writeReg(m_reg);
00081 }
00082 
00083 #define REG_FREQ1   0x8000
00084 #define REG_FREQ0   0x4000
00085 void setFrequencyWord(bool reg, uint32_t frequency) {
00086   writeReg(0x2000);                                                             // sets the PIN/SW D9 pin to high >> FSELECT pin can be used to use either FREQ0 or FREQ1
00087   writeReg((reg?REG_FREQ1:REG_FREQ0) | (frequency & 0x3FFF));
00088   writeReg((reg?REG_FREQ1:REG_FREQ0) | ((frequency >> 14) & 0x3FFF));
00089 }
00090 
00091 #define REG_PHASE0  0xC000
00092 #define REG_PHASE1  0xE000
00093 void setPhaseWord(bool reg, uint32_t phase) {
00094   writeReg((reg?REG_PHASE1:REG_PHASE0) | (phase & 0x0FFF));
00095 }
00096 
00097 #define REG_FSEL    0x0800
00098 void selectFrequency(bool reg) {
00099   if(reg) {
00100     m_reg |= REG_FSEL;
00101   } else {
00102     m_reg &= ~REG_FSEL;
00103   }
00104   writeReg(m_reg);
00105 }
00106 
00107 #define REG_PSEL    0x0400
00108 void selectPhase(bool reg) {
00109   if(reg) {
00110     m_reg |= REG_PSEL;
00111   } else {
00112     m_reg &= ~REG_PSEL;
00113   }
00114   writeReg(m_reg);
00115 }
00116 
00117 #define REG_RESET   0x0100
00118 void reset(bool in_reset) {
00119   if(in_reset) {
00120     m_reg |= REG_RESET; // the reset pin goes up
00121   } else {
00122     m_reg &= ~REG_RESET; // the reset pin goes down
00123   }
00124   writeReg(m_reg); //writes 16 bits over SPI
00125 }
00126 
00127 void begin(){
00128     reset(true);
00129     writeReg(m_reg);
00130     // Initialize frequency and phase registers to 0
00131     setFrequencyWord(0, 0);
00132     setFrequencyWord(1, 0);
00133     setPhaseWord(0, 0);
00134     setPhaseWord(1, 0);
00135     reset(false);
00136 }
00137 
00138 uint8_t Crc8(uint8_t *vptr, int len)
00139 {
00140     uint8_t *data = vptr;
00141     unsigned crc = 0;
00142     int i, j;
00143     for (j = len; j; j--, data++) {
00144         crc ^= (*data << 8);
00145         for(i = 8; i; i--) {
00146             if (crc & 0x8000)
00147                 crc ^= (0x1070 << 3);
00148             crc <<= 1;
00149         }
00150     }
00151     return (uint8_t)(crc >> 8);
00152 }
00153 
00154 /*******************
00155 MAIN
00156 *******************/
00157 int main() {
00158     //init pins
00159     DDS_PSEL = 0;
00160     DDS_FSEL = 0;
00161     SQUARE = 0;
00162     DDS = 0;
00163     AFE = 0;
00164     LED_3 = 1;
00165     
00166     //nCS lines
00167     DDS_nCS = 1;
00168     ADC_nCS = 1;
00169     CURRENT = 0;
00170     
00171     //init spi
00172     SPI_AFE_ADC_AND_DDS.format(16,2);
00173     SPI_AFE_ADC_AND_DDS.frequency(30000000);
00174     
00175     //make sure SPI is setup to mode 2, MSB first
00176     //init DDS
00177     begin();
00178     //output calculation
00179     //fOut = fMCLK / 2^28 * FREQREG = 50e6 / 2^28 * FREQREG
00180     //FREQREG = fOut * 2^28 / 50e6 = fOut * 5.36870912
00181     //100K: 536870, 1 MHz: 5368709, 2 MHz: 10737418, 3 MHz: 16106127, 4 MHz: 21474836, 8 MHz: 42949673 MHz, 20 MHz: 107374182, Max: 0x3FFF
00182     setFrequencyWord(0, 536871); // freq 100kHz - period 1 us
00183     setFrequencyWord(1, 0x3FFF);
00184     selectFrequency(0);
00185               
00186     
00187     setPhaseWord(0, 0); // 0 degrees
00188     setPhaseWord(1, 2048); // 180 degrees
00189     selectPhase(0);
00190               
00191    
00192     
00193     setSignOutput(SIGN_OUTPUT_MSB);
00194     SQUARE = 1;
00195     
00196     
00197     
00198     
00199     // BPSK test
00200     
00201     while(1){
00202         
00203         selectPhase(0);
00204         wait_us(100); // send a symbol during 10 T; T = 1/fc; T = 10us = 1/100kHz
00205         
00206         selectPhase(1);
00207         wait_us(100);
00208                
00209         
00210         }
00211       
00212     
00213 }