Hideharu Tsunemoto
/
MBED_TestPulse_Xray_Cont_20180517
MBED_LPC1768_Test Pulse msec/usec Interval Output P29/P30 & Input P21 Status Send USB Serial Log
MODDMA/example3.h@0:47c1b6a0c166, 2018-05-29 (annotated)
- 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?
User | Revision | Line number | New contents of line |
---|---|---|---|
H_Tsunemoto | 0:47c1b6a0c166 | 1 | /* |
H_Tsunemoto | 0:47c1b6a0c166 | 2 | * Demonstrates capturing the GPIO P0.4 to P0.7 "nibble" to memory |
H_Tsunemoto | 0:47c1b6a0c166 | 3 | * using GPDMA. The transfers from port pins to memory buffer are |
H_Tsunemoto | 0:47c1b6a0c166 | 4 | * triggered using Timer1 MAT1.0 match compare. |
H_Tsunemoto | 0:47c1b6a0c166 | 5 | * |
H_Tsunemoto | 0:47c1b6a0c166 | 6 | * In this example all inputs have pullups. So with nothing connected |
H_Tsunemoto | 0:47c1b6a0c166 | 7 | * the P0.4/7 reads as 0xF. Connecting a wire from one or more of the four |
H_Tsunemoto | 0:47c1b6a0c166 | 8 | * inputs to ground will show up in the captured buffer sequence. |
H_Tsunemoto | 0:47c1b6a0c166 | 9 | */ |
H_Tsunemoto | 0:47c1b6a0c166 | 10 | |
H_Tsunemoto | 0:47c1b6a0c166 | 11 | #include "mbed.h" |
H_Tsunemoto | 0:47c1b6a0c166 | 12 | #include "MODDMA.h" |
H_Tsunemoto | 0:47c1b6a0c166 | 13 | #include "iomacros.h" // within MODDMA library. |
H_Tsunemoto | 0:47c1b6a0c166 | 14 | |
H_Tsunemoto | 0:47c1b6a0c166 | 15 | // How long between grabbing GPIO FIO0PIN register. |
H_Tsunemoto | 0:47c1b6a0c166 | 16 | // Value is in microseconds. (500000 is half a second). |
H_Tsunemoto | 0:47c1b6a0c166 | 17 | #define SAMPLE_PERIOD 500000 |
H_Tsunemoto | 0:47c1b6a0c166 | 18 | |
H_Tsunemoto | 0:47c1b6a0c166 | 19 | #define NUM_OF_SAMPLES 5 |
H_Tsunemoto | 0:47c1b6a0c166 | 20 | |
H_Tsunemoto | 0:47c1b6a0c166 | 21 | Serial pc(USBTX, USBRX); |
H_Tsunemoto | 0:47c1b6a0c166 | 22 | |
H_Tsunemoto | 0:47c1b6a0c166 | 23 | DigitalOut led1(LED1); |
H_Tsunemoto | 0:47c1b6a0c166 | 24 | DigitalOut led2(LED2); |
H_Tsunemoto | 0:47c1b6a0c166 | 25 | DigitalOut led3(LED3); |
H_Tsunemoto | 0:47c1b6a0c166 | 26 | |
H_Tsunemoto | 0:47c1b6a0c166 | 27 | uint32_t buffer[NUM_OF_SAMPLES]; |
H_Tsunemoto | 0:47c1b6a0c166 | 28 | |
H_Tsunemoto | 0:47c1b6a0c166 | 29 | bool dmaTransferComplete; |
H_Tsunemoto | 0:47c1b6a0c166 | 30 | |
H_Tsunemoto | 0:47c1b6a0c166 | 31 | MODDMA dma; |
H_Tsunemoto | 0:47c1b6a0c166 | 32 | MODDMA_Config *conf; |
H_Tsunemoto | 0:47c1b6a0c166 | 33 | |
H_Tsunemoto | 0:47c1b6a0c166 | 34 | void TC0_callback(void); |
H_Tsunemoto | 0:47c1b6a0c166 | 35 | void ERR0_callback(void); |
H_Tsunemoto | 0:47c1b6a0c166 | 36 | |
H_Tsunemoto | 0:47c1b6a0c166 | 37 | int main() { |
H_Tsunemoto | 0:47c1b6a0c166 | 38 | volatile int life_counter = 0; |
H_Tsunemoto | 0:47c1b6a0c166 | 39 | |
H_Tsunemoto | 0:47c1b6a0c166 | 40 | // Macros defined in iomacros.h, saves messing with DigitalIn |
H_Tsunemoto | 0:47c1b6a0c166 | 41 | p30_AS_INPUT; p30_MODE( PIN_PULLUP ); // P0.4 |
H_Tsunemoto | 0:47c1b6a0c166 | 42 | p29_AS_INPUT; p29_MODE( PIN_PULLUP ); // P0.5 |
H_Tsunemoto | 0:47c1b6a0c166 | 43 | p8_AS_INPUT; p8_MODE( PIN_PULLUP ); // P0.6 |
H_Tsunemoto | 0:47c1b6a0c166 | 44 | p7_AS_INPUT; p7_MODE( PIN_PULLUP ); // P0.7 |
H_Tsunemoto | 0:47c1b6a0c166 | 45 | |
H_Tsunemoto | 0:47c1b6a0c166 | 46 | // Clear the buffer. |
H_Tsunemoto | 0:47c1b6a0c166 | 47 | memset(buffer, 0, sizeof(buffer)); |
H_Tsunemoto | 0:47c1b6a0c166 | 48 | |
H_Tsunemoto | 0:47c1b6a0c166 | 49 | // Setup the serial port to print out results. |
H_Tsunemoto | 0:47c1b6a0c166 | 50 | pc.baud(115200); |
H_Tsunemoto | 0:47c1b6a0c166 | 51 | pc.printf("Starting up...\n"); |
H_Tsunemoto | 0:47c1b6a0c166 | 52 | |
H_Tsunemoto | 0:47c1b6a0c166 | 53 | // Set-up timer1 as a periodic timer. |
H_Tsunemoto | 0:47c1b6a0c166 | 54 | LPC_SC->PCONP |= (1UL << 2); // TIM1 On |
H_Tsunemoto | 0:47c1b6a0c166 | 55 | LPC_SC->PCLKSEL0 |= (3UL << 4); // CCLK/8 = 12MHz |
H_Tsunemoto | 0:47c1b6a0c166 | 56 | LPC_TIM1->PR = 11; // TC clocks at 1MHz. |
H_Tsunemoto | 0:47c1b6a0c166 | 57 | LPC_TIM1->MCR = 2; // Reset TCR to zero on match. |
H_Tsunemoto | 0:47c1b6a0c166 | 58 | LPC_TIM1->MR0 = SAMPLE_PERIOD; |
H_Tsunemoto | 0:47c1b6a0c166 | 59 | |
H_Tsunemoto | 0:47c1b6a0c166 | 60 | // Prepare the GPDMA system. |
H_Tsunemoto | 0:47c1b6a0c166 | 61 | conf = new MODDMA_Config; |
H_Tsunemoto | 0:47c1b6a0c166 | 62 | conf |
H_Tsunemoto | 0:47c1b6a0c166 | 63 | ->channelNum ( MODDMA::Channel_0 ) |
H_Tsunemoto | 0:47c1b6a0c166 | 64 | ->srcMemAddr ( (uint32_t)&LPC_GPIO0->FIOPIN ) |
H_Tsunemoto | 0:47c1b6a0c166 | 65 | ->dstMemAddr ( (uint32_t)&buffer[0] ) |
H_Tsunemoto | 0:47c1b6a0c166 | 66 | ->transferSize ( NUM_OF_SAMPLES ) |
H_Tsunemoto | 0:47c1b6a0c166 | 67 | ->transferType ( MODDMA::g2m ) // pseudo transfer code MODDMA understands. |
H_Tsunemoto | 0:47c1b6a0c166 | 68 | ->transferWidth ( MODDMA::word ) |
H_Tsunemoto | 0:47c1b6a0c166 | 69 | ->srcConn ( MODDMA::MAT1_0 ) |
H_Tsunemoto | 0:47c1b6a0c166 | 70 | ->dmacSync ( MODDMA::MAT1_0 ) |
H_Tsunemoto | 0:47c1b6a0c166 | 71 | ->attach_tc ( TC0_callback ) |
H_Tsunemoto | 0:47c1b6a0c166 | 72 | ->attach_err ( ERR0_callback ) |
H_Tsunemoto | 0:47c1b6a0c166 | 73 | ; // end conf. |
H_Tsunemoto | 0:47c1b6a0c166 | 74 | |
H_Tsunemoto | 0:47c1b6a0c166 | 75 | // Prepare configuration. |
H_Tsunemoto | 0:47c1b6a0c166 | 76 | if (!dma.Setup( conf )) { |
H_Tsunemoto | 0:47c1b6a0c166 | 77 | error("Doh!"); |
H_Tsunemoto | 0:47c1b6a0c166 | 78 | } |
H_Tsunemoto | 0:47c1b6a0c166 | 79 | |
H_Tsunemoto | 0:47c1b6a0c166 | 80 | // Enable GPDMA to be ready for the TIM1 "ticks". |
H_Tsunemoto | 0:47c1b6a0c166 | 81 | dma.Enable( conf ); |
H_Tsunemoto | 0:47c1b6a0c166 | 82 | |
H_Tsunemoto | 0:47c1b6a0c166 | 83 | // Begin. |
H_Tsunemoto | 0:47c1b6a0c166 | 84 | LPC_TIM1->TCR = 1; |
H_Tsunemoto | 0:47c1b6a0c166 | 85 | |
H_Tsunemoto | 0:47c1b6a0c166 | 86 | while (1) { |
H_Tsunemoto | 0:47c1b6a0c166 | 87 | if (life_counter++ > 1000000) { |
H_Tsunemoto | 0:47c1b6a0c166 | 88 | led1 = !led1; // Show some sort of life. |
H_Tsunemoto | 0:47c1b6a0c166 | 89 | life_counter = 0; |
H_Tsunemoto | 0:47c1b6a0c166 | 90 | } |
H_Tsunemoto | 0:47c1b6a0c166 | 91 | |
H_Tsunemoto | 0:47c1b6a0c166 | 92 | if (dmaTransferComplete) { |
H_Tsunemoto | 0:47c1b6a0c166 | 93 | dmaTransferComplete = false; |
H_Tsunemoto | 0:47c1b6a0c166 | 94 | for (int i = 0; i < NUM_OF_SAMPLES; i++) { |
H_Tsunemoto | 0:47c1b6a0c166 | 95 | int val = (buffer[i] >> 4) & 0xF; |
H_Tsunemoto | 0:47c1b6a0c166 | 96 | pc.printf("Buffer index %d = 0x%x\n", i, val); |
H_Tsunemoto | 0:47c1b6a0c166 | 97 | } |
H_Tsunemoto | 0:47c1b6a0c166 | 98 | pc.printf("Done.\n"); |
H_Tsunemoto | 0:47c1b6a0c166 | 99 | |
H_Tsunemoto | 0:47c1b6a0c166 | 100 | // Schedule another grab. |
H_Tsunemoto | 0:47c1b6a0c166 | 101 | if (dma.Setup( conf )) { |
H_Tsunemoto | 0:47c1b6a0c166 | 102 | dma.Enable( conf ); |
H_Tsunemoto | 0:47c1b6a0c166 | 103 | } |
H_Tsunemoto | 0:47c1b6a0c166 | 104 | } |
H_Tsunemoto | 0:47c1b6a0c166 | 105 | } |
H_Tsunemoto | 0:47c1b6a0c166 | 106 | } |
H_Tsunemoto | 0:47c1b6a0c166 | 107 | |
H_Tsunemoto | 0:47c1b6a0c166 | 108 | // Configuration callback on TC |
H_Tsunemoto | 0:47c1b6a0c166 | 109 | void TC0_callback(void) { |
H_Tsunemoto | 0:47c1b6a0c166 | 110 | |
H_Tsunemoto | 0:47c1b6a0c166 | 111 | // Just show sample sequence grab complete. |
H_Tsunemoto | 0:47c1b6a0c166 | 112 | led3 = !led3; |
H_Tsunemoto | 0:47c1b6a0c166 | 113 | |
H_Tsunemoto | 0:47c1b6a0c166 | 114 | // Get configuration pointer. |
H_Tsunemoto | 0:47c1b6a0c166 | 115 | MODDMA_Config *config = dma.getConfig(); |
H_Tsunemoto | 0:47c1b6a0c166 | 116 | |
H_Tsunemoto | 0:47c1b6a0c166 | 117 | // Finish the DMA cycle by shutting down the channel. |
H_Tsunemoto | 0:47c1b6a0c166 | 118 | dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); |
H_Tsunemoto | 0:47c1b6a0c166 | 119 | |
H_Tsunemoto | 0:47c1b6a0c166 | 120 | // Tell main() while(1) loop to print the results. |
H_Tsunemoto | 0:47c1b6a0c166 | 121 | dmaTransferComplete = true; |
H_Tsunemoto | 0:47c1b6a0c166 | 122 | |
H_Tsunemoto | 0:47c1b6a0c166 | 123 | // Clear DMA IRQ flags. |
H_Tsunemoto | 0:47c1b6a0c166 | 124 | if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); |
H_Tsunemoto | 0:47c1b6a0c166 | 125 | if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); |
H_Tsunemoto | 0:47c1b6a0c166 | 126 | } |
H_Tsunemoto | 0:47c1b6a0c166 | 127 | |
H_Tsunemoto | 0:47c1b6a0c166 | 128 | // Configuration callback on Error |
H_Tsunemoto | 0:47c1b6a0c166 | 129 | void ERR0_callback(void) { |
H_Tsunemoto | 0:47c1b6a0c166 | 130 | error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); |
H_Tsunemoto | 0:47c1b6a0c166 | 131 | } |