MBED_LPC1768_Test Pulse msec/usec Interval Output P29/P30 & Input P21 Status Send USB Serial Log

Dependencies:   mbed

Committer:
H_Tsunemoto
Date:
Tue May 29 02:41:54 2018 +0000
Revision:
0:47c1b6a0c166
Pulse On/OFF OutPut P29/P30 & Rep Input P21 Status Output USBSerial;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
H_Tsunemoto 0:47c1b6a0c166 1 /*
H_Tsunemoto 0:47c1b6a0c166 2 * Demonstrates sending a buffer repeatedly to the DAC using DMA.
H_Tsunemoto 0:47c1b6a0c166 3 * Connect an oscilloscope to Mbed pin 18. This example doesn't
H_Tsunemoto 0:47c1b6a0c166 4 * output anything else (nothing on any serial ports).
H_Tsunemoto 0:47c1b6a0c166 5 */
H_Tsunemoto 0:47c1b6a0c166 6 #include "mbed.h"
H_Tsunemoto 0:47c1b6a0c166 7 #include "MODDMA.h"
H_Tsunemoto 0:47c1b6a0c166 8
H_Tsunemoto 0:47c1b6a0c166 9 // Make the buffer size match the number of degrees
H_Tsunemoto 0:47c1b6a0c166 10 // in a circle since we are going to output a sinewave.
H_Tsunemoto 0:47c1b6a0c166 11 #define BUFFER_SIZE 360
H_Tsunemoto 0:47c1b6a0c166 12
H_Tsunemoto 0:47c1b6a0c166 13 // Set DAC output power mode.
H_Tsunemoto 0:47c1b6a0c166 14 #define DAC_POWER_MODE (1 << 16)
H_Tsunemoto 0:47c1b6a0c166 15
H_Tsunemoto 0:47c1b6a0c166 16 DigitalOut led1(LED1);
H_Tsunemoto 0:47c1b6a0c166 17 DigitalOut led3(LED3);
H_Tsunemoto 0:47c1b6a0c166 18 DigitalOut led4(LED4);
H_Tsunemoto 0:47c1b6a0c166 19
H_Tsunemoto 0:47c1b6a0c166 20 int buffer[2][BUFFER_SIZE];
H_Tsunemoto 0:47c1b6a0c166 21
H_Tsunemoto 0:47c1b6a0c166 22 AnalogOut signal(p18);
H_Tsunemoto 0:47c1b6a0c166 23
H_Tsunemoto 0:47c1b6a0c166 24 MODDMA dma;
H_Tsunemoto 0:47c1b6a0c166 25 MODDMA_Config *conf0, *conf1;
H_Tsunemoto 0:47c1b6a0c166 26
H_Tsunemoto 0:47c1b6a0c166 27 void TC0_callback(void);
H_Tsunemoto 0:47c1b6a0c166 28 void ERR0_callback(void);
H_Tsunemoto 0:47c1b6a0c166 29
H_Tsunemoto 0:47c1b6a0c166 30 void TC1_callback(void);
H_Tsunemoto 0:47c1b6a0c166 31 void ERR1_callback(void);
H_Tsunemoto 0:47c1b6a0c166 32
H_Tsunemoto 0:47c1b6a0c166 33 int main() {
H_Tsunemoto 0:47c1b6a0c166 34 volatile int life_counter = 0;
H_Tsunemoto 0:47c1b6a0c166 35
H_Tsunemoto 0:47c1b6a0c166 36 // Create a sinewave buffer for testing.
H_Tsunemoto 0:47c1b6a0c166 37 for (int i = 0; i <= 90; i++) buffer[0][i] = (512 * sin(3.14159/180.0 * i)) + 512;
H_Tsunemoto 0:47c1b6a0c166 38 for (int i = 91; i <= 180; i++) buffer[0][i] = buffer[0][180 - i];
H_Tsunemoto 0:47c1b6a0c166 39 for (int i = 181; i <= 270; i++) buffer[0][i] = 512 - (buffer[0][i - 180] - 512);
H_Tsunemoto 0:47c1b6a0c166 40 for (int i = 271; i < 360; i++) buffer[0][i] = 512 - (buffer[0][360 - i] - 512);
H_Tsunemoto 0:47c1b6a0c166 41
H_Tsunemoto 0:47c1b6a0c166 42 // Adjust the sinewave buffer for use with DAC hardware.
H_Tsunemoto 0:47c1b6a0c166 43 for (int i = 0; i < 360; i++) {
H_Tsunemoto 0:47c1b6a0c166 44 buffer[0][i] = DAC_POWER_MODE | ((buffer[0][i] << 6) & 0xFFC0);
H_Tsunemoto 0:47c1b6a0c166 45 buffer[1][i] = buffer[0][i]; // Just create a copy of buffer0 to continue sinewave.
H_Tsunemoto 0:47c1b6a0c166 46 }
H_Tsunemoto 0:47c1b6a0c166 47
H_Tsunemoto 0:47c1b6a0c166 48 // Prepare the GPDMA system for buffer0.
H_Tsunemoto 0:47c1b6a0c166 49 conf0 = new MODDMA_Config;
H_Tsunemoto 0:47c1b6a0c166 50 conf0
H_Tsunemoto 0:47c1b6a0c166 51 ->channelNum ( MODDMA::Channel_0 )
H_Tsunemoto 0:47c1b6a0c166 52 ->srcMemAddr ( (uint32_t) &buffer[0] )
H_Tsunemoto 0:47c1b6a0c166 53 ->dstMemAddr ( MODDMA::DAC )
H_Tsunemoto 0:47c1b6a0c166 54 ->transferSize ( 360 )
H_Tsunemoto 0:47c1b6a0c166 55 ->transferType ( MODDMA::m2p )
H_Tsunemoto 0:47c1b6a0c166 56 ->dstConn ( MODDMA::DAC )
H_Tsunemoto 0:47c1b6a0c166 57 ->attach_tc ( &TC0_callback )
H_Tsunemoto 0:47c1b6a0c166 58 ->attach_err ( &ERR0_callback )
H_Tsunemoto 0:47c1b6a0c166 59 ; // config end
H_Tsunemoto 0:47c1b6a0c166 60
H_Tsunemoto 0:47c1b6a0c166 61
H_Tsunemoto 0:47c1b6a0c166 62 // Prepare the GPDMA system for buffer1.
H_Tsunemoto 0:47c1b6a0c166 63 conf1 = new MODDMA_Config;
H_Tsunemoto 0:47c1b6a0c166 64 conf1
H_Tsunemoto 0:47c1b6a0c166 65 ->channelNum ( MODDMA::Channel_1 )
H_Tsunemoto 0:47c1b6a0c166 66 ->srcMemAddr ( (uint32_t) &buffer[1] )
H_Tsunemoto 0:47c1b6a0c166 67 ->dstMemAddr ( MODDMA::DAC )
H_Tsunemoto 0:47c1b6a0c166 68 ->transferSize ( 360 )
H_Tsunemoto 0:47c1b6a0c166 69 ->transferType ( MODDMA::m2p )
H_Tsunemoto 0:47c1b6a0c166 70 ->dstConn ( MODDMA::DAC )
H_Tsunemoto 0:47c1b6a0c166 71 ->attach_tc ( &TC1_callback )
H_Tsunemoto 0:47c1b6a0c166 72 ->attach_err ( &ERR1_callback )
H_Tsunemoto 0:47c1b6a0c166 73 ; // config end
H_Tsunemoto 0:47c1b6a0c166 74
H_Tsunemoto 0:47c1b6a0c166 75
H_Tsunemoto 0:47c1b6a0c166 76 // Calculating the transfer frequency:
H_Tsunemoto 0:47c1b6a0c166 77 // By default, the Mbed library sets the PCLK_DAC clock value
H_Tsunemoto 0:47c1b6a0c166 78 // to 24MHz. One complete sinewave cycle in each buffer is 360
H_Tsunemoto 0:47c1b6a0c166 79 // points long. So, for a 1Hz wave we would need to transfer 360
H_Tsunemoto 0:47c1b6a0c166 80 // values per second. That would be 24000000/360 which is approx
H_Tsunemoto 0:47c1b6a0c166 81 // 66,666. But that's no good! The count val is only 16bits in size
H_Tsunemoto 0:47c1b6a0c166 82 // so bare this in mind. If you need to go slower you will need to
H_Tsunemoto 0:47c1b6a0c166 83 // alter PCLK_DAC from CCLK/4 to CCLK/8.
H_Tsunemoto 0:47c1b6a0c166 84 // For our demo we are going to have the sinewave run at 1kHz.
H_Tsunemoto 0:47c1b6a0c166 85 // That's 24000000/360000 which is approx 66. Experimentation
H_Tsunemoto 0:47c1b6a0c166 86 // however showed 65 to get closer to 1kHz (on my Mbed and scope
H_Tsunemoto 0:47c1b6a0c166 87 // at least).
H_Tsunemoto 0:47c1b6a0c166 88 LPC_DAC->DACCNTVAL = 65; // 6500 for 10Hz
H_Tsunemoto 0:47c1b6a0c166 89
H_Tsunemoto 0:47c1b6a0c166 90 // Prepare first configuration.
H_Tsunemoto 0:47c1b6a0c166 91 if (!dma.Prepare( conf0 )) {
H_Tsunemoto 0:47c1b6a0c166 92 error("Doh!");
H_Tsunemoto 0:47c1b6a0c166 93 }
H_Tsunemoto 0:47c1b6a0c166 94
H_Tsunemoto 0:47c1b6a0c166 95 // Begin (enable DMA and counter). Note, don't enable
H_Tsunemoto 0:47c1b6a0c166 96 // DBLBUF_ENA as we are using DMA double buffering.
H_Tsunemoto 0:47c1b6a0c166 97 LPC_DAC->DACCTRL |= (3UL << 2);
H_Tsunemoto 0:47c1b6a0c166 98
H_Tsunemoto 0:47c1b6a0c166 99 while (1) {
H_Tsunemoto 0:47c1b6a0c166 100 // There's not a lot to do as DMA and interrupts are
H_Tsunemoto 0:47c1b6a0c166 101 // now handling the buffer transfers. So we'll just
H_Tsunemoto 0:47c1b6a0c166 102 // flash led1 to show the Mbed is alive and kicking.
H_Tsunemoto 0:47c1b6a0c166 103 if (life_counter++ > 1000000) {
H_Tsunemoto 0:47c1b6a0c166 104 led1 = !led1; // Show some sort of life.
H_Tsunemoto 0:47c1b6a0c166 105 life_counter = 0;
H_Tsunemoto 0:47c1b6a0c166 106 }
H_Tsunemoto 0:47c1b6a0c166 107 }
H_Tsunemoto 0:47c1b6a0c166 108 }
H_Tsunemoto 0:47c1b6a0c166 109
H_Tsunemoto 0:47c1b6a0c166 110 // Configuration callback on TC
H_Tsunemoto 0:47c1b6a0c166 111 void TC0_callback(void) {
H_Tsunemoto 0:47c1b6a0c166 112
H_Tsunemoto 0:47c1b6a0c166 113 // Just show sending buffer0 complete.
H_Tsunemoto 0:47c1b6a0c166 114 led3 = !led3;
H_Tsunemoto 0:47c1b6a0c166 115
H_Tsunemoto 0:47c1b6a0c166 116 // Get configuration pointer.
H_Tsunemoto 0:47c1b6a0c166 117 MODDMA_Config *config = dma.getConfig();
H_Tsunemoto 0:47c1b6a0c166 118
H_Tsunemoto 0:47c1b6a0c166 119 // Finish the DMA cycle by shutting down the channel.
H_Tsunemoto 0:47c1b6a0c166 120 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
H_Tsunemoto 0:47c1b6a0c166 121
H_Tsunemoto 0:47c1b6a0c166 122 // Swap to buffer1
H_Tsunemoto 0:47c1b6a0c166 123 dma.Prepare( conf1 );
H_Tsunemoto 0:47c1b6a0c166 124
H_Tsunemoto 0:47c1b6a0c166 125 // Clear DMA IRQ flags.
H_Tsunemoto 0:47c1b6a0c166 126 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
H_Tsunemoto 0:47c1b6a0c166 127 }
H_Tsunemoto 0:47c1b6a0c166 128
H_Tsunemoto 0:47c1b6a0c166 129 // Configuration callback on Error
H_Tsunemoto 0:47c1b6a0c166 130 void ERR0_callback(void) {
H_Tsunemoto 0:47c1b6a0c166 131 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
H_Tsunemoto 0:47c1b6a0c166 132 }
H_Tsunemoto 0:47c1b6a0c166 133
H_Tsunemoto 0:47c1b6a0c166 134 // Configuration callback on TC
H_Tsunemoto 0:47c1b6a0c166 135 void TC1_callback(void) {
H_Tsunemoto 0:47c1b6a0c166 136
H_Tsunemoto 0:47c1b6a0c166 137 // Just show sending buffer1 complete.
H_Tsunemoto 0:47c1b6a0c166 138 led4 = !led4;
H_Tsunemoto 0:47c1b6a0c166 139
H_Tsunemoto 0:47c1b6a0c166 140 // Get configuration pointer.
H_Tsunemoto 0:47c1b6a0c166 141 MODDMA_Config *config = dma.getConfig();
H_Tsunemoto 0:47c1b6a0c166 142
H_Tsunemoto 0:47c1b6a0c166 143 // Finish the DMA cycle by shutting down the channel.
H_Tsunemoto 0:47c1b6a0c166 144 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
H_Tsunemoto 0:47c1b6a0c166 145
H_Tsunemoto 0:47c1b6a0c166 146 // Swap to buffer0
H_Tsunemoto 0:47c1b6a0c166 147 dma.Prepare( conf0 );
H_Tsunemoto 0:47c1b6a0c166 148
H_Tsunemoto 0:47c1b6a0c166 149 // Clear DMA IRQ flags.
H_Tsunemoto 0:47c1b6a0c166 150 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
H_Tsunemoto 0:47c1b6a0c166 151 }
H_Tsunemoto 0:47c1b6a0c166 152
H_Tsunemoto 0:47c1b6a0c166 153 // Configuration callback on Error
H_Tsunemoto 0:47c1b6a0c166 154 void ERR1_callback(void) {
H_Tsunemoto 0:47c1b6a0c166 155 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
H_Tsunemoto 0:47c1b6a0c166 156 }