steven niu / mDMA Featured

Dependents:   test_mDMA

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers dma.h Source File

dma.h

00001 //To be done, 
00002 // 1. think of inline
00003 // 2.
00004 // 3. TriggerType 
00005 
00006 
00007 //1. use method to get access to class memebers than access directly. It could help to reduce coupling 
00008 //2. use MIL to initialize variables
00009 //3. use const when necessary
00010 //4. check memcpy / strecpy, memcpy might not do the right thing
00011 //5. API design , what happens when some platform don;t need API. make sure the user code can be same across platform
00012 //6. check the user input
00013 
00014 #ifndef MBED_DMA_H
00015 #define MBED_DMA_H
00016 
00017 
00018 #include "dma_api.h"
00019 #include "platform.h"
00020 #include "FunctionPointer.h"
00021 #include "sleep_api.h"
00022 /** A generic DMA for transfer data without hanging the CPU.
00023  * It can be used for m2m, m2p, p2m, m2m transfer
00024  * It will choose the DMA with the priority you have set.
00025  * Lower number means higher prority.
00026  * If no prority is set, it will choose which ever free channel.
00027  * Example:
00028  * @code
00029  * // Send the memory data "Hello world" in source address to destination address via DMA
00030  * // attach a function to swtich LED on when the transfer finish
00031  *  char src[] = "Hello world\r\n";
00032  *  uint8_t size = sizeof (src);
00033  *  char *dst  = (char *) malloc(size);
00034  *  memset (dst, '\0', size);
00035  *  LPC_SC->PCONP |= (1 << 29);    // Enable LPC1768 GPDMA clock
00036  *  DMA dma1 (0) ;
00037  *  dma1.source (src,0,1);
00038  *  dma1.destination (dst,0,1);
00039  *  dma1.attach_TC(led_switchon) ;
00040  *  dma1.start(size);
00041  *  dma1.wait();
00042  *  printf("dst text: %s", dst);
00043  * @endcode
00044 */
00045 
00046 namespace mbed{
00047 class DMA
00048 {
00049 public:
00050     /** @brief  Create the DMA Channel according to the prority or choose whichever free if no prority given.
00051     *                     Initialize the number of channels in the device
00052     *   @param   priority: The DMA prority.
00053     *   @note    If prority has been given but that channel is not avaiable, it will wait until the channel avaiable.
00054     */
00055     DMA(int priority = -1);
00056 
00057     ~DMA ();
00058     /** @brief  Get source starting address, transfer width and setting auto increment.
00059      *  @param  src. The source starting address.
00060             * @param  inc. Set memory automatice increment.
00061      *  @param  width. The transfer data width
00062      *  @note   If width is not given, it will set the width automatically according to the data type in the memory
00063      */
00064     template<typename T>    // To be reviewd, should put the template into the cpp rather than the header?
00065     void source (T* src, bool inc, unsigned int width = sizeof(T)*8  ) {
00066         //inc = isMemory ((uint32_t)src); // To be reviewed. How to put this line into the arguments?
00067         uint32_t src_prt= (uint32_t) src;
00068         DMA_source(dma_init_struct, src_prt, width, inc);
00069     }
00070 
00071     /** @brief  Get destination starting address, transfer width and setting auto increment.
00072      *  @param  dst. The destination starting address.
00073          *  @param  inc. Set memory automatice increment.
00074      *  @param  width. The transfer data width
00075      *  @note   If width is not given, it will set the width automatically according to the data type in the memory
00076      *          
00077      */
00078     template<typename T>
00079     void destination (T* dst, bool inc, unsigned int width =sizeof(T)*8 ) {
00080         //inc = isMemory ((uint32_t) dst);
00081         uint32_t dst_ptr=(uint32_t) dst;
00082         DMA_destination(dma_init_struct, dst_ptr, width, inc);
00083     }
00084 
00085     /** @brief  Get source trigger type
00086      *  @param  trig. The source triggert type.
00087      *  @note   If the source is memory. The trigger type would be ALWAYS even you set it differently.
00088      */
00089     void TriggerSource(TriggerType trig = ALWAYS);
00090 
00091     /** @brief  Get destination trigger type
00092      *  @param  trig. The destination triggert type.
00093      *  @note   If the destination is memory. The trigger type would be ALWAYS even you set it differently.
00094      */
00095     void TriggerDestination(TriggerType trig = ALWAYS );
00096         
00097 
00098     /** @brief  Start the DMA to transfer data
00099      *  @param  lengh. Define how many data the DMA needs to transfer
00100      */
00101     void start(unsigned int len);
00102         
00103         /** @brief Get the address storing next linked list item 
00104          *  @param  src. Next transfer source address
00105          *  @param  dst. Next transfer destination address
00106          *  @param  size. Next transfer size         
00107          *  @retval None
00108         */
00109         //  void next(LLI* list);       
00110         void next(const uint32_t src, const uint32_t dst, uint32_t size);
00111 
00112     /** @brief  Wait for DMA transaction finishes or err interrupt happens
00113          *  @retval None
00114      */
00115     void wait();
00116         
00117         
00118         /** @brief  Check whether DMA transaction has finished or generated errors
00119          *  @retval 0 if not finished or 1 if finished 
00120      */
00121         bool finished();
00122 
00123     /** @brief  Attach a function to DMA IRQ handler. The attached function will be called when the transfer has completed successfully.
00124      *  @param  *fptr. The function pointer.
00125      */
00126     void attach_TC(func_ptr fptr) {
00127         DMA_IRQ_attach(chan, FINISH, fptr);
00128         NVIC_SetVector(DMA_IRQn, (uint32_t)&DMA_IRQ_handler);
00129         NVIC_EnableIRQ(DMA_IRQn);
00130     }
00131         
00132         
00133     /** @brief  Attach a function to DMA IRQ handler. The attached function will be called when the transfer has completed successfully.
00134      *  @param  *fptr. The function pointer.
00135      *  @note   There are two attach function attach_TC and attach_Err in case you want to attach different functions when tranfer finishs or fails
00136      */
00137     void attach_Err(func_ptr fptr) {
00138         DMA_IRQ_attach(chan, ERR, fptr);
00139         NVIC_SetVector(_DMA_IRQ, (uint32_t)&DMA_IRQ_handler);
00140         NVIC_EnableIRQ(_DMA_IRQ);
00141     }
00142         
00143     
00144 protected:
00145     int chan; // the chosen channel number
00146     int chooseFreeChannel(int channel);
00147     int channel_num;
00148     DMA_InitTypeDef* dma_init_struct;
00149 };
00150 
00151 }
00152 #endif