Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
main.cpp@1:25c850668cef, 2015-03-20 (annotated)
- 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?
User | Revision | Line number | New 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 | } |