00001 //****************************************************************************** 00002 //THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR 00003 //REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY, 00004 //INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 00005 //FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR 00006 //COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE. 00007 //TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET 00008 //POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY 00009 //INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR 00010 //YOUR USE OF THE PROGRAM. 00011 // 00012 //IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL, 00013 //CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY 00014 //THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED 00015 //OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT 00016 //OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM. 00017 //EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF 00018 //REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS 00019 //OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF 00020 //USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S 00021 //AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF 00022 //YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS 00023 //(U.S.$500). 00024 // 00025 //Unless otherwise stated, the Program written and copyrighted 00026 //by Texas Instruments is distributed as "freeware". You may, 00027 //only under TI's copyright in the Program, use and modify the 00028 //Program without any charge or restriction. You may 00029 //distribute to third parties, provided that you transfer a 00030 //copy of this license to the third party and the third party 00031 //agrees to these terms by its first use of the Program. You 00032 //must reproduce the copyright notice and any other legend of 00033 //ownership on each copy or partial copy, of the Program. 00034 // 00035 //You acknowledge and agree that the Program contains 00036 //copyrighted material, trade secrets and other TI proprietary 00037 //information and is protected by copyright laws, 00038 //international copyright treaties, and trade secret laws, as 00039 //well as other intellectual property laws. To protect TI's 00040 //rights in the Program, you agree not to decompile, reverse 00041 //engineer, disassemble or otherwise translate any object code 00042 //versions of the Program to a human-readable form. You agree 00043 //that in no event will you alter, remove or destroy any 00044 //copyright notice included in the Program. TI reserves all 00045 //rights not specifically granted under this license. Except 00046 //as specifically provided herein, nothing in this agreement 00047 //shall be construed as conferring by implication, estoppel, 00048 //or otherwise, upon you, any license or other right under any 00049 //TI patents, copyrights or trade secrets. 00050 // 00051 //You may not use the Program in non-TI devices. 00063 // (c)2009 by Texas Instruments Incorporated, All Rights Reserved. 00064 /*----------------------------------------------------------------------------+ 00065 | | 00066 | Texas Instruments | 00067 | | 00068 | MSP430 USB-Example (HID/CDC Driver) | 00069 | | 00070 +-----------------------------------------------------------------------------+ 00071 | Source: dma.c, v1.18 2009/06/11 | 00072 | Author: RSTO | 00073 | | 00074 | WHO WHEN WHAT | 00075 | --- ---------- ------------------------------------------------ | 00076 | RSTO 2009/03/03 born | 00077 | RSTO 2009/04/08 Redefine memcpy() | 00078 | RSTO 2009/04/16 use 16 bit access to DMA regs | 00079 | RSTO 2009/09/18 fixed trigger selection for DMA with bit set | 00080 | RSTO 2009/11/03 do not transfer via DMA if length is zero | 00081 +----------------------------------------------------------------------------*/ 00082 00083 #include "MSP430.h" 00084 #include "..\Common\types.h" // Basic Type declarations 00085 #include "..\USB_Common\defMSP430USB.h" 00086 #include "..\USB_Common\descriptors.h" 00087 #include <string.h> 00088 00089 00090 //function pointers 00091 VOID *(*USB_TX_memcpy)(VOID * dest, const VOID * source, size_t count); 00092 VOID *(*USB_RX_memcpy)(VOID * dest, const VOID * source, size_t count); 00093 00094 VOID * memcpyDMA0(VOID * dest, const VOID * source, size_t count); 00095 VOID * memcpyDMA1(VOID * dest, const VOID * source, size_t count); 00096 VOID * memcpyDMA2(VOID * dest, const VOID * source, size_t count); 00097 00098 // NOTE: this functin works only with data in the area <64k (small memory model) 00099 VOID * memcpyV(VOID * dest, const VOID * source, size_t count) 00100 { 00101 WORD i; 00102 volatile BYTE bTmp; 00103 for (i=0; i<count; i++) 00104 { 00105 bTmp = *((BYTE*)source +i); 00106 *((BYTE*)dest +i) = bTmp; 00107 } 00108 return dest; 00109 } 00110 00111 00112 //this function inits the 00113 VOID USB_initMemcpy(VOID) 00114 { 00115 USB_TX_memcpy = memcpyV; 00116 USB_RX_memcpy = memcpyV; 00117 00118 switch (USB_DMA_TX) 00119 { 00120 case 0: 00121 DMACTL0 &= ~DMA0TSEL_31; // DMA0 is triggered by DMAREQ 00122 DMACTL0 |= DMA0TSEL_0; // DMA0 is triggered by DMAREQ 00123 DMA0CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source 00124 DMADSTINCR_3 ); // and destination address 00125 DMACTL4 |= ENNMI; // enable NMI interrupt 00126 USB_TX_memcpy = memcpyDMA0; 00127 break; 00128 case 1: 00129 DMACTL0 &= ~DMA1TSEL_31; // DMA1 is triggered by DMAREQ 00130 DMACTL0 |= DMA1TSEL_0; // DMA1 is triggered by DMAREQ 00131 DMA1CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source 00132 DMADSTINCR_3 ); // and destination address 00133 DMACTL4 |= ENNMI; // enable NMI interrupt 00134 USB_TX_memcpy = memcpyDMA1; 00135 break; 00136 case 2: 00137 DMACTL0 &= ~DMA2TSEL_31; // DMA2 is triggered by DMAREQ 00138 DMACTL0 |= DMA2TSEL_0; // DMA2 is triggered by DMAREQ 00139 DMA2CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source 00140 DMADSTINCR_3 ); // and destination address 00141 DMACTL4 |= ENNMI; // enable NMI interrupt 00142 USB_TX_memcpy = memcpyDMA2; 00143 break; 00144 } 00145 00146 switch (USB_DMA_RX) 00147 { 00148 case 0: 00149 DMACTL0 &= ~DMA0TSEL_31; // DMA0 is triggered by DMAREQ 00150 DMACTL0 |= DMA0TSEL_0; // DMA0 is triggered by DMAREQ 00151 DMA0CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source 00152 DMADSTINCR_3 ); // and destination address 00153 DMACTL4 |= ENNMI; // enable NMI interrupt 00154 USB_RX_memcpy = memcpyDMA0; 00155 break; 00156 case 1: 00157 DMACTL0 &= ~DMA1TSEL_31; // DMA1 is triggered by DMAREQ 00158 DMACTL0 |= DMA1TSEL_0; // DMA1 is triggered by DMAREQ 00159 DMA1CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source 00160 DMADSTINCR_3 ); // and destination address 00161 DMACTL4 |= ENNMI; // enable NMI interrupt 00162 USB_RX_memcpy = memcpyDMA1; 00163 break; 00164 case 2: 00165 DMACTL0 &= ~DMA2TSEL_31; // DMA2 is triggered by DMAREQ 00166 DMACTL0 |= DMA2TSEL_0; // DMA2 is triggered by DMAREQ 00167 DMA2CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source 00168 DMADSTINCR_3 ); // and destination address 00169 DMACTL4 |= ENNMI; // enable NMI interrupt 00170 USB_RX_memcpy = memcpyDMA2; 00171 break; 00172 } 00173 } 00174 00175 // this functions starts DMA transfer to/from USB memory into/from RAM 00176 // Using DMA0 00177 // Support only for data in <64k memory area. 00178 VOID * memcpyDMA0(VOID * dest, const VOID * source, size_t count) 00179 { 00180 if (count == 0) // do nothing if zero bytes to transfer 00181 { 00182 return dest; 00183 } 00184 00185 DMA0DAL = (WORD)dest; // set destination for DMAx 00186 DMA0SAL = (WORD)source; // set source for DMAx 00187 DMA0SZ = count; // how many bytes to transfer 00188 00189 DMA0CTL |= DMAEN; // enable DMAx 00190 DMA0CTL |= DMAREQ; // trigger DMAx 00191 00192 //wait for DMA transfer finished 00193 while (!(DMA0CTL & DMAIFG)); 00194 00195 DMA0CTL &= ~DMAEN; // disable DMAx 00196 return dest; 00197 } 00198 00199 // this functions starts DMA transfer to/from USB memory into/from RAM 00200 // Using DMA1 00201 // Support only for data in <64k memory area. 00202 VOID * memcpyDMA1(VOID * dest, const VOID * source, size_t count) 00203 { 00204 if (count == 0) // do nothing if zero bytes to transfer 00205 { 00206 return dest; 00207 } 00208 00209 DMA1DAL = (WORD)dest; // set destination for DMAx 00210 DMA1SAL = (WORD)source; // set source for DMAx 00211 DMA1SZ = count; // how many bytes to transfer 00212 00213 DMA1CTL |= DMAEN; // enable DMAx 00214 DMA1CTL |= DMAREQ; // trigger DMAx 00215 00216 //wait for DMA transfer finished 00217 while (!(DMA1CTL & DMAIFG)); 00218 00219 DMA1CTL &= ~DMAEN; // disable DMAx 00220 return dest; 00221 } 00222 00223 // this functions starts DMA transfer to/from USB memory into/from RAM 00224 // Using DMA2 00225 // Support only for data in <64k memory area. 00226 VOID * memcpyDMA2(VOID * dest, const VOID * source, size_t count) 00227 { 00228 if (count == 0) // do nothing if zero bytes to transfer 00229 { 00230 return dest; 00231 } 00232 00233 DMA2DAL = (WORD)dest; // set destination for DMAx 00234 DMA2SAL = (WORD)source; // set source for DMAx 00235 DMA2SZ = count; // how many bytes to transfer 00236 00237 DMA2CTL |= DMAEN; // enable DMAx 00238 DMA2CTL |= DMAREQ; // trigger DMAx 00239 00240 //wait for DMA transfer finished 00241 while (!(DMA2CTL & DMAIFG)); 00242 00243 DMA2CTL &= ~DMAEN; // disable DMAx 00244 return dest; 00245 } 00246 00247 /*----------------------------------------------------------------------------+ 00248 | End of source file | 00249 +----------------------------------------------------------------------------*/ 00250 /*------------------------ Nothing Below This Line --------------------------*/
1.7.1