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.
Dependents: FirstTest WaveSim IO-dma-memmem DACDMAfuncgenlib ... more
Revision 12:1dfee7208043, committed 2011-03-13
- Comitter:
- AjK
- Date:
- Sun Mar 13 23:28:21 2011 +0000
- Parent:
- 11:19009be5a0e7
- Child:
- 13:846c8b6ffb7f
- Commit message:
- 1.8 See ChangeLog.c
Changed in this revision
--- a/ChangeLog.c Sun Mar 13 12:46:55 2011 +0000
+++ b/ChangeLog.c Sun Mar 13 23:28:21 2011 +0000
@@ -1,5 +1,12 @@
/* $Id:$
+1.8 - 13 Mar 2011
+
+ * Renamed example files to .h
+ * Added pseudo g2m and m2g transferTypes to support GPIO
+ "memory moves" but triggered by peripheral timer. To
+ support this new operating mode added example3.h
+
1.7 - 13 Mar 2011
* Remove the test at the beginning of the channel setup.
--- a/MODDMA.cpp Sun Mar 13 12:46:55 2011 +0000
+++ b/MODDMA.cpp Sun Mar 13 23:28:21 2011 +0000
@@ -37,7 +37,7 @@
bool
MODDMA::Enabled(CHANNELS ChannelNumber)
{
- LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef *)Channel_p( ChannelNumber );
+ LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef *)Channel_p( ChannelNumber );
return (bool)(pChannel->DMACCConfig & _E);
}
--- a/MODDMA.h Sun Mar 13 12:46:55 2011 +0000
+++ b/MODDMA.h Sun Mar 13 23:28:21 2011 +0000
@@ -64,6 +64,7 @@
uint32_t SrcConn; //!< Peripheral Source Connection type, used in case TransferType is chosen as
uint32_t DstConn; //!< Peripheral Destination Connection type, used in case TransferType is chosen as
uint32_t DMALLI; //!< Linker List Item structure data address if there's no Linker List, set as '0'
+ uint32_t DMACSync; //!< DMACSync if required.
// Mbed specifics.
@@ -81,6 +82,7 @@
SrcConn = 0;
DstConn = 0;
DMALLI = 0;
+ DMACSync = 0;
}
~MODDMA_Config() {
@@ -97,6 +99,7 @@
class MODDMA_Config * srcConn(uint32_t n) { SrcConn = n; return this; }
class MODDMA_Config * dstConn(uint32_t n) { DstConn = n; return this; }
class MODDMA_Config * dmaLLI(uint32_t n) { DMALLI = n; return this; }
+ class MODDMA_Config * dmacSync(uint32_t n) { DMACSync = n; return this; }
uint32_t channelNum(void) { return ChannelNum; }
uint32_t transferSize(void) { return TransferSize; }
@@ -107,7 +110,8 @@
uint32_t srcConn(void) { return SrcConn; }
uint32_t dstConn(void) { return DstConn; }
uint32_t dmaLLI(void) { return DMALLI; }
-
+ uint32_t dmacSync(void) { return DMACSync; }
+
/**
* Attach a callback to the TC IRQ configuration.
*
@@ -306,7 +310,9 @@
m2m = 0UL /*!< Memory to memory - DMA control */
, m2p = 1UL /*!< Memory to peripheral - DMA control */
, p2m = 2UL /*!< Peripheral to memory - DMA control */
- , p2p = 3UL /*!< Src peripheral to dest peripheral - DMA control */
+ , p2p = 3UL /*!< Src peripheral to dest peripheral - DMA control */
+ , g2m = 4UL /*!< Psuedo special case for reading "peripheral GPIO" that's memory mapped. */
+ , m2g = 5UL /*!< Psuedo Special case for writing "peripheral GPIO" that's memory mapped. */
};
//! Burst size in Source and Destination definitions */
@@ -651,13 +657,15 @@
*/
FunctionPointer isrIntErrStat;
+ uint32_t Channel_p(int channel);
+
protected:
// Data LUTs.
uint32_t LUTPerAddr(int n);
uint8_t LUTPerBurst(int n);
uint8_t LUTPerWid(int n);
- uint32_t Channel_p(int channel);
+ //uint32_t Channel_p(int channel);
CHANNELS IrqProcessingChannel;
--- a/SETUP.cpp Sun Mar 13 12:46:55 2011 +0000
+++ b/SETUP.cpp Sun Mar 13 23:28:21 2011 +0000
@@ -108,6 +108,38 @@
| CxControl_I();
break;
+ // GPIO to memory
+ case g2m:
+ // Assign GPIO source address
+ pChannel->DMACCSrcAddr = config->srcMemAddr();
+ // Assign memory destination address
+ pChannel->DMACCDestAddr = config->dstMemAddr();
+ pChannel->DMACCControl
+ = CxControl_TransferSize((uint32_t)config->transferSize())
+ | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn()))
+ | CxControl_DBSize((uint32_t)LUTPerBurst(config->srcConn()))
+ | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn()))
+ | CxControl_DWidth((uint32_t)LUTPerWid(config->srcConn()))
+ | CxControl_DI()
+ | CxControl_I();
+ break;
+
+ // Memory to GPIO
+ case m2g:
+ // Assign physical source
+ pChannel->DMACCSrcAddr = config->srcMemAddr();
+ // Assign peripheral destination address
+ pChannel->DMACCDestAddr = config->dstMemAddr();
+ pChannel->DMACCControl
+ = CxControl_TransferSize((uint32_t)config->transferSize())
+ | CxControl_SBSize((uint32_t)LUTPerBurst(config->dstConn()))
+ | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn()))
+ | CxControl_SWidth((uint32_t)LUTPerWid(config->dstConn()))
+ | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn()))
+ | CxControl_SI()
+ | CxControl_I();
+ break;
+
// Do not support any more transfer type, return ERROR
default:
return 0;
@@ -121,7 +153,7 @@
LPC_SC->RESERVED9 &= ~(1 << (config->srcConn() - 8));
}
- // Re-Configure DMA Request Select for Destination peripheral
+ // Re-Configure DMA Request Select for destination peripheral
if (config->dstConn() > 15) {
LPC_SC->RESERVED9 |= (1 << (config->dstConn() - 16));
}
@@ -137,11 +169,21 @@
uint32_t tmp1 = config->srcConn(); tmp1 = ((tmp1 > 15) ? (tmp1 - 8) : tmp1);
uint32_t tmp2 = config->dstConn(); tmp2 = ((tmp2 > 15) ? (tmp2 - 8) : tmp2);
+ if (config->dmacSync()) {
+ uint32_t tmp3 = config->dmacSync(); tmp3 = ((tmp3 > 15) ? (tmp3 - 8) : tmp3);
+ LPC_GPDMA->DMACSync |= Sync_Src( tmp3 );
+ }
+
+ uint32_t tfer_type = (uint32_t)config->transferType();
+ if (tfer_type == g2m || tfer_type == m2g) {
+ tfer_type -= 2; // Adjust psuedo transferType to a real transferType.
+ }
+
// Configure DMA Channel, enable Error Counter and Terminate counter
pChannel->DMACCConfig
= CxConfig_IE()
| CxConfig_ITC()
- | CxConfig_TransferType((uint32_t)config->transferType())
+ | CxConfig_TransferType(tfer_type)
| CxConfig_SrcPeripheral(tmp1)
| CxConfig_DestPeripheral(tmp2);
--- a/example1.cpp Sun Mar 13 12:46:55 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-#ifdef COMPILE_EXAMPLE1_CODE_MODDMA
-
-#include "mbed.h"
-#include "MODDMA.h"
-#include "MODSERIAL.h"
-
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-MODDMA dma;
-MODSERIAL pc(USBTX, USBRX);
-
-// Function prototypes for IRQ callbacks.
-// See definitions following main() below.
-void dmaTCCallback(void);
-void dmaERRCallback(void);
-void TC0_callback(void);
-void ERR0_callback(void);
-
-int main() {
- char s[] = "**DMA** ABCDEFGHIJKLMNOPQRSTUVWXYZ **DMA**";
-
- pc.baud(PC_BAUD);
-
- dma.attach_tc( &dmaTCCallback );
- dma.attach_err( &dmaERRCallback );
-
- MODDMA_Config *config = new MODDMA_Config;
- config
- ->channelNum ( MODDMA::Channel_0 )
- ->srcMemAddr ( (uint32_t) &s )
- ->dstMemAddr ( 0 )
- ->transferSize ( sizeof(s) )
- ->transferType ( MODDMA::m2p )
- ->transferWidth ( 0 )
- ->srcConn ( 0 )
- ->dstConn ( MODDMA::UART0_Tx )
- ->dmaLLI ( 0 )
- ->attach_tc ( &TC0_callback )
- ->attach_err ( &ERR0_callback )
- ; // config end
-
- // Setup the configuration.
- dma.Setup(config);
-
- //dma.Enable( MODDMA::Channel_0 );
- //dma.Enable( config->channelNum() );
- dma.Enable( config );
-
- while (1) {
- led1 = !led1;
- wait(0.25);
- }
-}
-
-// Main controller TC IRQ callback
-void dmaTCCallback(void) {
- led2 = 1;
-}
-
-// Main controller ERR IRQ callback
-void dmaERRCallback(void) {
- error("Oh no! My Mbed exploded! :( Only kidding, find the problem");
-}
-
-// Configuration callback on TC
-void TC0_callback(void) {
- MODDMA_Config *config = dma.getConfig();
- dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
- dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-
- // Configurations have two IRQ callbacks for TC and Err so you
- // know which you are processing. However, if you want to use
- // a single callback function you can tell what type of IRQ
- // is being processed thus:-
- if (dma.irqType() == MODDMA::TcIrq) {
- led3 = 1;
- dma.clearTcIrq();
- }
- if (dma.irqType() == MODDMA::ErrIrq) {
- led4 = 1;
- dma.clearErrIrq();
- }
-}
-
-// Configuration cakllback on Error
-void ERR0_callback(void) {
- error("Oh no! My Mbed exploded! :( Only kidding, find the problem");
-}
-
-#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/example1.h Sun Mar 13 23:28:21 2011 +0000
@@ -0,0 +1,89 @@
+#include "mbed.h"
+#include "MODDMA.h"
+#include "MODSERIAL.h"
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+MODDMA dma;
+MODSERIAL pc(USBTX, USBRX);
+
+// Function prototypes for IRQ callbacks.
+// See definitions following main() below.
+void dmaTCCallback(void);
+void dmaERRCallback(void);
+void TC0_callback(void);
+void ERR0_callback(void);
+
+int main() {
+ char s[] = "**DMA** ABCDEFGHIJKLMNOPQRSTUVWXYZ **DMA**";
+
+ pc.baud(PC_BAUD);
+
+ dma.attach_tc( &dmaTCCallback );
+ dma.attach_err( &dmaERRCallback );
+
+ MODDMA_Config *config = new MODDMA_Config;
+ config
+ ->channelNum ( MODDMA::Channel_0 )
+ ->srcMemAddr ( (uint32_t) &s )
+ ->dstMemAddr ( 0 )
+ ->transferSize ( sizeof(s) )
+ ->transferType ( MODDMA::m2p )
+ ->transferWidth ( 0 )
+ ->srcConn ( 0 )
+ ->dstConn ( MODDMA::UART0_Tx )
+ ->dmaLLI ( 0 )
+ ->attach_tc ( &TC0_callback )
+ ->attach_err ( &ERR0_callback )
+ ; // config end
+
+ // Setup the configuration.
+ dma.Setup(config);
+
+ //dma.Enable( MODDMA::Channel_0 );
+ //dma.Enable( config->channelNum() );
+ dma.Enable( config );
+
+ while (1) {
+ led1 = !led1;
+ wait(0.25);
+ }
+}
+
+// Main controller TC IRQ callback
+void dmaTCCallback(void) {
+ led2 = 1;
+}
+
+// Main controller ERR IRQ callback
+void dmaERRCallback(void) {
+ error("Oh no! My Mbed exploded! :( Only kidding, find the problem");
+}
+
+// Configuration callback on TC
+void TC0_callback(void) {
+ MODDMA_Config *config = dma.getConfig();
+ dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
+ dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
+
+ // Configurations have two IRQ callbacks for TC and Err so you
+ // know which you are processing. However, if you want to use
+ // a single callback function you can tell what type of IRQ
+ // is being processed thus:-
+ if (dma.irqType() == MODDMA::TcIrq) {
+ led3 = 1;
+ dma.clearTcIrq();
+ }
+ if (dma.irqType() == MODDMA::ErrIrq) {
+ led4 = 1;
+ dma.clearErrIrq();
+ }
+}
+
+// Configuration cakllback on Error
+void ERR0_callback(void) {
+ error("Oh no! My Mbed exploded! :( Only kidding, find the problem");
+}
+
--- a/example2.cpp Sun Mar 13 12:46:55 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-#ifdef COMPILE_EXAMPLE2_CODE_MODDMA
-
-/*
- * This example was provided to support Mbed forum thread:-
- * http://mbed.org/forum/mbed/topic/1798
- */
-
-#include "mbed.h"
-#include "MODDMA.h"
-
-#define SAMPLE_BUFFER_LENGTH 32
-
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-
-MODDMA dma;
-Serial pc(USBTX, USBRX);
-
-// ISR set's this when transfer complete.
-bool dmaTransferComplete = false;
-
-// Function prototypes for IRQ callbacks.
-// See definitions following main() below.
-void TC0_callback(void);
-void ERR0_callback(void);
-
-int main() {
-
- // Create a buffer to hold the ADC samples and clear it.
- // Note, we are going to sample two ADC inputs so they
- // end up in this buffer "interleaved". So you will want
- // a buffer twice this size to a real life given sample
- // frequency. See the printf() output for details.
- uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH];
- memset(adcInputBuffer, 0, sizeof(adcInputBuffer));
-
- // We use the ADC irq to trigger DMA and the manual says
- // that in this case the NVIC for ADC must be disabled.
- NVIC_DisableIRQ(ADC_IRQn);
-
- // Power up the ADC and set PCLK
- LPC_SC->PCONP |= (1UL << 12);
- LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz
-
- // Enable the ADC, 12MHz, ADC0.0 & .1
- LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0);
-
- // Set the pin functions to ADC
- LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */
- LPC_PINCON->PINSEL1 |= (1UL << 14);
- LPC_PINCON->PINSEL1 &= ~(3UL << 16); /* P0.24, Mbed p16. */
- LPC_PINCON->PINSEL1 |= (1UL << 16);
-
- // Setup the serial port to print out results.
- pc.baud(115200);
- pc.printf("ADC with DMA example\n");
- pc.printf("====================\n");
-
- // Prepare an ADC configuration.
- MODDMA_Config *conf = new MODDMA_Config;
- conf
- ->channelNum ( MODDMA::Channel_0 )
- ->srcMemAddr ( 0 )
- ->dstMemAddr ( (uint32_t)adcInputBuffer )
- ->transferSize ( SAMPLE_BUFFER_LENGTH )
- ->transferType ( MODDMA::p2m )
- ->transferWidth ( MODDMA::word )
- ->srcConn ( MODDMA::ADC )
- ->dstConn ( 0 )
- ->dmaLLI ( 0 )
- ->attach_tc ( &TC0_callback )
- ->attach_err ( &ERR0_callback )
- ; // end conf.
-
- // Prepare configuration.
- dma.Setup( conf );
-
- // Enable configuration.
- dma.Enable( conf );
-
- // Enable ADC irq flag (to DMA).
- // Note, don't set the individual flags,
- // just set the global flag.
- LPC_ADC->ADINTEN = 0x100;
-
- // Enable burst mode on inputs 0 and 1.
- LPC_ADC->ADCR |= (1UL << 16);
-
- while (1) {
- // When transfer complete do this block.
- if (dmaTransferComplete) {
- delete conf; // No memory leaks, delete the configuration.
- dmaTransferComplete = false;
- for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) {
- int channel = (adcInputBuffer[i] >> 24) & 0x7;
- int iVal = (adcInputBuffer[i] >> 4) & 0xFFF;
- double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v
- pc.printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal);
- }
- }
-
- // Just flash LED1 for something to do.
- led1 = !led1;
- wait(0.25);
- }
-}
-
-// Configuration callback on TC
-void TC0_callback(void) {
-
- MODDMA_Config *config = dma.getConfig();
-
- // Disbale burst mode and switch off the IRQ flag.
- LPC_ADC->ADCR &= ~(1UL << 16);
- LPC_ADC->ADINTEN = 0;
-
- // Finish the DMA cycle by shutting down the channel.
- dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
- dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-
- // Tell main() while(1) loop to print the results.
- dmaTransferComplete = true;
-
- // Switch on LED2 to show transfer complete.
- led2 = 1;
-
- // Clear DMA IRQ flags.
- if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
- if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
-}
-
-// Configuration callback on Error
-void ERR0_callback(void) {
- // Switch off burst conversions.
- LPC_ADC->ADCR |= ~(1UL << 16);
- LPC_ADC->ADINTEN = 0;
- error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
-}
-
-#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/example2.h Sun Mar 13 23:28:21 2011 +0000
@@ -0,0 +1,137 @@
+/*
+ * This example was provided to support Mbed forum thread:-
+ * http://mbed.org/forum/mbed/topic/1798
+ */
+
+#include "mbed.h"
+#include "MODDMA.h"
+
+#define SAMPLE_BUFFER_LENGTH 32
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+
+MODDMA dma;
+Serial pc(USBTX, USBRX);
+
+// ISR set's this when transfer complete.
+bool dmaTransferComplete = false;
+
+// Function prototypes for IRQ callbacks.
+// See definitions following main() below.
+void TC0_callback(void);
+void ERR0_callback(void);
+
+int main() {
+
+ // Create a buffer to hold the ADC samples and clear it.
+ // Note, we are going to sample two ADC inputs so they
+ // end up in this buffer "interleaved". So you will want
+ // a buffer twice this size to a real life given sample
+ // frequency. See the printf() output for details.
+ uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH];
+ memset(adcInputBuffer, 0, sizeof(adcInputBuffer));
+
+ // We use the ADC irq to trigger DMA and the manual says
+ // that in this case the NVIC for ADC must be disabled.
+ NVIC_DisableIRQ(ADC_IRQn);
+
+ // Power up the ADC and set PCLK
+ LPC_SC->PCONP |= (1UL << 12);
+ LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz
+
+ // Enable the ADC, 12MHz, ADC0.0 & .1
+ LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0);
+
+ // Set the pin functions to ADC
+ LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */
+ LPC_PINCON->PINSEL1 |= (1UL << 14);
+ LPC_PINCON->PINSEL1 &= ~(3UL << 16); /* P0.24, Mbed p16. */
+ LPC_PINCON->PINSEL1 |= (1UL << 16);
+
+ // Setup the serial port to print out results.
+ pc.baud(115200);
+ pc.printf("ADC with DMA example\n");
+ pc.printf("====================\n");
+
+ // Prepare an ADC configuration.
+ MODDMA_Config *conf = new MODDMA_Config;
+ conf
+ ->channelNum ( MODDMA::Channel_0 )
+ ->srcMemAddr ( 0 )
+ ->dstMemAddr ( (uint32_t)adcInputBuffer )
+ ->transferSize ( SAMPLE_BUFFER_LENGTH )
+ ->transferType ( MODDMA::p2m )
+ ->transferWidth ( MODDMA::word )
+ ->srcConn ( MODDMA::ADC )
+ ->dstConn ( 0 )
+ ->dmaLLI ( 0 )
+ ->attach_tc ( &TC0_callback )
+ ->attach_err ( &ERR0_callback )
+ ; // end conf.
+
+ // Prepare configuration.
+ dma.Setup( conf );
+
+ // Enable configuration.
+ dma.Enable( conf );
+
+ // Enable ADC irq flag (to DMA).
+ // Note, don't set the individual flags,
+ // just set the global flag.
+ LPC_ADC->ADINTEN = 0x100;
+
+ // Enable burst mode on inputs 0 and 1.
+ LPC_ADC->ADCR |= (1UL << 16);
+
+ while (1) {
+ // When transfer complete do this block.
+ if (dmaTransferComplete) {
+ delete conf; // No memory leaks, delete the configuration.
+ dmaTransferComplete = false;
+ for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) {
+ int channel = (adcInputBuffer[i] >> 24) & 0x7;
+ int iVal = (adcInputBuffer[i] >> 4) & 0xFFF;
+ double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v
+ pc.printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal);
+ }
+ }
+
+ // Just flash LED1 for something to do.
+ led1 = !led1;
+ wait(0.25);
+ }
+}
+
+// Configuration callback on TC
+void TC0_callback(void) {
+
+ MODDMA_Config *config = dma.getConfig();
+
+ // Disbale burst mode and switch off the IRQ flag.
+ LPC_ADC->ADCR &= ~(1UL << 16);
+ LPC_ADC->ADINTEN = 0;
+
+ // Finish the DMA cycle by shutting down the channel.
+ dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
+ dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
+
+ // Tell main() while(1) loop to print the results.
+ dmaTransferComplete = true;
+
+ // Switch on LED2 to show transfer complete.
+ led2 = 1;
+
+ // Clear DMA IRQ flags.
+ if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
+ if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
+}
+
+// Configuration callback on Error
+void ERR0_callback(void) {
+ // Switch off burst conversions.
+ LPC_ADC->ADCR |= ~(1UL << 16);
+ LPC_ADC->ADINTEN = 0;
+ error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/example3.h Sun Mar 13 23:28:21 2011 +0000
@@ -0,0 +1,125 @@
+/*
+ * Demonstrates capturing the GPIO P0.4 to P0.7 "nibble" to memory
+ * using GPDMA. The transfers from port pins to memory buffer are
+ * triggered using Timer1 MAT1.0 match compare.
+ *
+ * In this example all inputs have pullups. So with nothing connected
+ * the P0.4/7 reads as 0xF. Connecting a wire from one or more of the four
+ * inputs to ground will show up in the captured buffer sequence.
+ */
+
+#include "mbed.h"
+#include "MODDMA.h"
+#include "iomacros.h" // within MODDMA library.
+
+// How long between grabbing GPIO FIO0PIN register.
+// Value is in microseconds. (50000 is half a second).
+#define SAMPLE_PERIOD 500000
+
+#define NUM_OF_SAMPLES 5
+
+Serial pc(USBTX, USBRX);
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+
+uint32_t buffer[NUM_OF_SAMPLES];
+
+bool dmaTransferComplete;
+
+MODDMA dma;
+MODDMA_Config *conf;
+
+void TC0_callback(void);
+void ERR0_callback(void);
+
+int main() {
+
+ // Macros defined in iomacros.h, saves messing with DigitalIn
+ p30_AS_INPUT; p30_MODE( PIN_PULLUP ); // P0.4
+ p29_AS_INPUT; p29_MODE( PIN_PULLUP ); // P0.5
+ p8_AS_INPUT; p8_MODE( PIN_PULLUP ); // P0.6
+ p7_AS_INPUT; p7_MODE( PIN_PULLUP ); // P0.7
+
+ // Clear the buffer.
+ memset(buffer, 0, sizeof(buffer));
+
+ // Setup the serial port to print out results.
+ pc.baud(115200);
+ pc.printf("Starting up...\n");
+
+ // Set-up timer1 as a periodic timer.
+ LPC_SC->PCONP |= (1UL << 2); // TIM1 On
+ LPC_SC->PCLKSEL0 |= (3UL << 4); // CCLK/8 = 12MHz
+ LPC_TIM1->PR = 11; // TC clocks at 1MHz.
+ LPC_TIM1->MCR = 2; // Reset TCR to zero on match.
+ LPC_TIM1->MR0 = SAMPLE_PERIOD;
+
+ // Prepare the GPDMA system.
+ conf = new MODDMA_Config;
+ conf
+ ->channelNum ( MODDMA::Channel_0 )
+ ->srcMemAddr ( (uint32_t)&LPC_GPIO0->FIOPIN )
+ ->dstMemAddr ( (uint32_t)&buffer[0] )
+ ->transferSize ( NUM_OF_SAMPLES )
+ ->transferType ( MODDMA::g2m ) // pseudo transfer code MODDMA understands.
+ ->transferWidth ( MODDMA::word )
+ ->srcConn ( MODDMA::MAT1_0 )
+ ->dmacSync ( MODDMA::MAT1_0 )
+ ->attach_tc ( TC0_callback )
+ ->attach_err ( ERR0_callback )
+ ; // end conf.
+
+ // Prepare configuration.
+ if (!dma.Setup( conf )) {
+ error("Doh!");
+ }
+
+ // Enable GPDMA to be ready for the TIM1 "ticks".
+ dma.Enable( conf );
+
+ // Begin.
+ LPC_TIM1->TCR = 1;
+
+ while (1) {
+ led1 = !led1; // Show some sort of life.
+
+ if (dmaTransferComplete) {
+ dmaTransferComplete = false;
+ for (int i = 0; i < NUM_OF_SAMPLES; i++) {
+ int val = (buffer[i] >> 4) & 0xF;
+ pc.printf("Buffer index %d = 0x%x\n", i, val);
+ }
+ pc.printf("Done.\n");
+ }
+ }
+}
+
+// Configuration callback on TC
+void TC0_callback(void) {
+
+ // Just show sample sequence grab complete.
+ led3 = !led3;
+
+ // Disable firing timer.
+ LPC_TIM1->TCR = 0;
+
+ // Get configuration pointer.
+ MODDMA_Config *config = dma.getConfig();
+
+ // Finish the DMA cycle by shutting down the channel.
+ dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
+
+ // Tell main() while(1) loop to print the results.
+ dmaTransferComplete = true;
+
+ // Clear DMA IRQ flags.
+ if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
+ if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
+}
+
+// Configuration callback on Error
+void ERR0_callback(void) {
+ error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
+}
--- a/iomacros.h Sun Mar 13 12:46:55 2011 +0000 +++ b/iomacros.h Sun Mar 13 23:28:21 2011 +0000 @@ -71,6 +71,7 @@ /* p8 is P0.6 */ #define p8_SEL_MASK ~(3UL << 12) #define p8_SET_MASK (1UL << 6) +#define p8_CLR_MASK ~(p8_SET_MASK) #define p8_AS_OUTPUT LPC_PINCON->PINSEL0&=p8_SEL_MASK;LPC_GPIO0->FIODIR|=p8_SET_MASK #define p8_AS_INPUT LPC_GPIO0->FIOMASK &= p8_CLR_MASK; #define p8_SET LPC_GPIO0->FIOSET = p8_SET_MASK