Trying to read ADC through DMA

Started by souj...@gmail.com September 2, 2006
hi

i am using TMS320vc5502 processor.I need to read the ADC which has 12 bit resolution through DMA.The source port is configured as external while dest port is DARAMPORT 0. But when i try to read the data stored in DST buffer i get 16 bit data.The below Configuration doesnt enable the DMA.i am placing my configuration below can u help me out where i have gone wrong in the Confuguring the DMA.

the Dma configuration:

/* Define transmit and receive buffers */
#pragma DATA_SECTION(xmt,"adc")
Uint16 xmt[N];
#pragma DATA_SECTION(rcv,"dmaMem")
Uint16 rcv[N];
extern GPIO_Handle myGpio0;
extern unsigned long *ADC_CE1,*DDS_CE2;
void ADC_Write(void);

DMA_Config dmaRcvConfig = {
DMA_DMACSDP_RMK(
DMA_DMACSDP_DSTBEN_NOBURST,
DMA_DMACSDP_DSTPACK_OFF,
DMA_DMACSDP_DST_DARAMPORT0,
DMA_DMACSDP_SRCBEN_NOBURST,
DMA_DMACSDP_SRCPACK_OFF,
DMA_DMACSDP_SRC_EMIF,
DMA_DMACSDP_DATATYPE_16BIT
), // DMACSDP
DMA_DMACCR_RMK(
DMA_DMACCR_DSTAMODE_POSTINC,
DMA_DMACCR_SRCAMODE_CONST,
DMA_DMACCR_ENDPROG_ON,
DMA_DMACCR_WP_DEFAULT,
DMA_DMACCR_REPEAT_OFF,
DMA_DMACCR_AUTOINIT_OFF,
DMA_DMACCR_EN_STOP,
DMA_DMACCR_PRIO_LOW,
DMA_DMACCR_FS_DISABLE,
DMA_DMACCR_SYNC_REVT1
), // DMACCR
DMA_DMACICR_RMK(
DMA_DMACICR_AERRIE_OFF,
DMA_DMACICR_BLOCKIE_OFF,
DMA_DMACICR_LASTIE_OFF,
DMA_DMACICR_FRAMEIE_ON,
DMA_DMACICR_FIRSTHALFIE_OFF,
DMA_DMACICR_DROPIE_OFF,
DMA_DMACICR_TIMEOUTIE_OFF
), // DMACICR
(DMA_AdrPtr)&xmt, // DMACSSAL
0, // DMACSSAU
(DMA_AdrPtr)&rcv, // DMACDSAL
0, // DMACDSAU
N, // DMACEN
1, // DMACFN
0, // DMACFI
0, // DMACEI
0,
0
};

DMA_Config dmaXmtConfig = {
DMA_DMACSDP_RMK(
DMA_DMACSDP_DSTBEN_NOBURST,
DMA_DMACSDP_DSTPACK_OFF,
DMA_DMACSDP_DST_EMIF,
DMA_DMACSDP_SRCBEN_NOBURST,
DMA_DMACSDP_SRCPACK_OFF,
DMA_DMACSDP_SRC_DARAMPORT0,
DMA_DMACSDP_DATATYPE_16BIT
), // DMACSDP
DMA_DMACCR_RMK(
DMA_DMACCR_DSTAMODE_CONST,
DMA_DMACCR_SRCAMODE_POSTINC,
DMA_DMACCR_ENDPROG_ON,
DMA_DMACCR_WP_DEFAULT,
DMA_DMACCR_REPEAT_ON,
DMA_DMACCR_AUTOINIT_OFF,
DMA_DMACCR_EN_STOP,
DMA_DMACCR_PRIO_LOW,
DMA_DMACCR_FS_DISABLE,
DMA_DMACCR_SYNC_NONE
), // DMACCR
DMA_DMACICR_RMK(
DMA_DMACICR_AERRIE_OFF,
DMA_DMACICR_BLOCKIE_OFF,
DMA_DMACICR_LASTIE_OFF,
DMA_DMACICR_FRAMEIE_ON,
DMA_DMACICR_FIRSTHALFIE_OFF,
DMA_DMACICR_DROPIE_OFF,
DMA_DMACICR_TIMEOUTIE_OFF
), // DMACICR
(DMA_AdrPtr)&xmt[1], // DMACSSAL
0, // DMACSSAU
(DMA_AdrPtr)&rcv, // DMACDSAL
0, // DMACDSAU
N, // DMACEN
1, // DMACFN
0, // DMACFI
0 // DMACEI
};

// Define a DMA_Handle object to be used with DMA_open function
DMA_Handle hDmaRcv, hDmaXmt;

volatile Uint16 transferComplete = FALSE;
Uint16 err = 0;
Uint16 old_intm;
Uint16 xmtEventId, rcvEventId;

//---------Function prototypes---------

// Reference the start of the interrupt vector table
// This symbol is defined in file vectors.s55
extern void VECSTART(void);

// Protoype for interrupt functions
interrupt void dmaRcvIsr(void);
void taskFxn(void);

//---------main routine---------
void DMA_INIT(void)
{
Uint16 i;

// Initialize CSL library - This is REQUIRED !!!
CSL_init();

// Set IVPH/IVPD to start of interrupt vector table
IRQ_setVecs((Uint32)(&VECSTART));

/* for (i = 0; i <= N - 1; i++) {
xmt[i] = i + 1;
rcv[i] = 0;
}
*/

ADC_Write();

// Call function to effect transfer
taskFxn();
}

void taskFxn(void)
{
Uint16 srcAddrHi, srcAddrLo;
Uint16 dstAddrHi, dstAddrLo;
Uint16 i;

/* By default, the TMS320C55xx compiler assigns all data symbols word
addresses. The DMA however, expects all addresses to be byte
addresses. Therefore, we must shift the address by 2 in order to
change the word address to a byte address for the DMA transfer. */
srcAddrHi = (Uint16)(((Uint32)(0x0000)) >> 15) & 0xFFFFu;
srcAddrLo = (Uint16)(((Uint32)(0x0020)) << 1) & 0xFFFFu;
dstAddrHi = (Uint16)(((Uint32)(&rcv)) >> 15) & 0xFFFFu;
dstAddrLo = (Uint16)(((Uint32)(&rcv)) << 1) & 0xFFFFu;

dmaRcvConfig.dmacssal = (DMA_AdrPtr)srcAddrLo;
dmaRcvConfig.dmacssau = srcAddrHi;
dmaRcvConfig.dmacdsal = (DMA_AdrPtr)dstAddrLo;
dmaRcvConfig.dmacdsau = dstAddrHi;

srcAddrHi = (Uint16)(((Uint32)(&xmt[0])) >> 15) & 0xFFFFu;
srcAddrLo = (Uint16)(((Uint32)(&xmt[0])) << 1) & 0xFFFFu;
dstAddrHi = (Uint16)(((Uint32)(0x0000)) >> 15) & 0xFFFFu;
dstAddrLo = (Uint16)(((Uint32)(0x0020)) << 1) & 0xFFFFu;

dmaXmtConfig.dmacssal = (DMA_AdrPtr)srcAddrLo;
dmaXmtConfig.dmacssau = srcAddrHi;
dmaXmtConfig.dmacdsal = (DMA_AdrPtr)dstAddrLo;
dmaXmtConfig.dmacdsau = dstAddrHi;

// Open DMA channels 4 & 2 and set regs to power on defaults
hDmaRcv = DMA_open(DMA_CHA4,DMA_OPEN_RESET);
hDmaXmt = DMA_open(DMA_CHA2,DMA_OPEN_RESET);

// Get interrupt event associated with DMA receive
rcvEventId = DMA_getEventId(hDmaRcv);

/* Temporarily disable interrupts and clear any pending
interrupts for MCBSP transmit */
old_intm = IRQ_globalDisable();

// Clear any pending interrupts for DMA channels
IRQ_clear(rcvEventId);

// Enable DMA interrupt in IER register
IRQ_enable(rcvEventId);

// Place DMA interrupt service addresses at associate vector
IRQ_plug(rcvEventId,&dmaRcvIsr);

// Write values from configuration structure to DMA control regs
DMA_config(hDmaRcv,&dmaRcvConfig);
DMA_config(hDmaXmt,&dmaXmtConfig);

// Enable all maskable interrupts
IRQ_globalEnable();

// Enable DMA
DMA_start(hDmaRcv);
DMA_start(hDmaXmt);
// Wait for DMA transfer to be complete

/* while (!transferComplete)
{
;
}
*/
// Compare values

/* for(i = 0; i <= N - 1; i++){
if (rcv[i] != xmt[i]){
++err;
break;
}
}

*/
/* for(i = 0; i <= N - 1; i++){
rcv[i]= xmt[i];}*/

printf ("%s\n",err?"TEST FAILED" : "TEST PASSED");

// Restore status of global interrupt enable flag
IRQ_globalRestore(old_intm);
DMA_config(hDmaRcv,&dmaRcvConfig);

//We're done with DMA , so close them
DMA_close(hDmaRcv);
DMA_close(hDmaXmt);
}

interrupt void dmaRcvIsr(void) {
DMA_stop(hDmaRcv);
IRQ_disable(rcvEventId);
transferComplete = TRUE;
DMA_reset(hDmaRcv);
}
void ADC_Write(void)
{

*ADC_CE1=0x0401; //reset bit 1 in ctrl_reg1
*ADC_CE1=0x0400; //clear reset bit 0 in ctrl_reg1
*ADC_CE1=0x0000; // in ctrl_reg0,internal ref vol,adc active,single,ch0,
*ADC_CE1=0x04B2; //in ctrl_reg1,clear reset,over flow(read only),Active High

GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN7,1);
GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN0,1);
GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN1,1);
GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN2,1);
GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN4,1);

GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN7,0);
}
hi

i am using TMS320vc5502 processor.I need to read the ADC which has 12 bit resolution through DMA.The source port is configured as external while dest port is DARAMPORT 0. But when i try to read the data stored in DST buffer i get 16 bit data.The below Configuration doesnt enable the DMA.i am placing my configuration below can u help me out where i have gone wrong in the Confuguring the DMA.

the Dma configuration:

/* Define transmit and receive buffers */
#pragma DATA_SECTION(xmt,"adc")
Uint16 xmt[N];
#pragma DATA_SECTION(rcv,"dmaMem")
Uint16 rcv[N];
extern GPIO_Handle myGpio0;
extern unsigned long *ADC_CE1,*DDS_CE2;
void ADC_Write(void);

DMA_Config dmaRcvConfig = {
DMA_DMACSDP_RMK(
DMA_DMACSDP_DSTBEN_NOBURST,
DMA_DMACSDP_DSTPACK_OFF,
DMA_DMACSDP_DST_DARAMPORT0,
DMA_DMACSDP_SRCBEN_NOBURST,
DMA_DMACSDP_SRCPACK_OFF,
DMA_DMACSDP_SRC_EMIF,
DMA_DMACSDP_DATATYPE_16BIT
), // DMACSDP
DMA_DMACCR_RMK(
DMA_DMACCR_DSTAMODE_POSTINC,
DMA_DMACCR_SRCAMODE_CONST,
DMA_DMACCR_ENDPROG_ON,
DMA_DMACCR_WP_DEFAULT,
DMA_DMACCR_REPEAT_OFF,
DMA_DMACCR_AUTOINIT_OFF,
DMA_DMACCR_EN_STOP,
DMA_DMACCR_PRIO_LOW,
DMA_DMACCR_FS_DISABLE,
DMA_DMACCR_SYNC_REVT1
), // DMACCR
DMA_DMACICR_RMK(
DMA_DMACICR_AERRIE_OFF,
DMA_DMACICR_BLOCKIE_OFF,
DMA_DMACICR_LASTIE_OFF,
DMA_DMACICR_FRAMEIE_ON,
DMA_DMACICR_FIRSTHALFIE_OFF,
DMA_DMACICR_DROPIE_OFF,
DMA_DMACICR_TIMEOUTIE_OFF
), // DMACICR
(DMA_AdrPtr)&xmt, // DMACSSAL
0, // DMACSSAU
(DMA_AdrPtr)&rcv, // DMACDSAL
0, // DMACDSAU
N, // DMACEN
1, // DMACFN
0, // DMACFI
0, // DMACEI
0,
0
};

DMA_Config dmaXmtConfig = {
DMA_DMACSDP_RMK(
DMA_DMACSDP_DSTBEN_NOBURST,
DMA_DMACSDP_DSTPACK_OFF,
DMA_DMACSDP_DST_EMIF,
DMA_DMACSDP_SRCBEN_NOBURST,
DMA_DMACSDP_SRCPACK_OFF,
DMA_DMACSDP_SRC_DARAMPORT0,
DMA_DMACSDP_DATATYPE_16BIT
), // DMACSDP
DMA_DMACCR_RMK(
DMA_DMACCR_DSTAMODE_CONST,
DMA_DMACCR_SRCAMODE_POSTINC,
DMA_DMACCR_ENDPROG_ON,
DMA_DMACCR_WP_DEFAULT,
DMA_DMACCR_REPEAT_ON,
DMA_DMACCR_AUTOINIT_OFF,
DMA_DMACCR_EN_STOP,
DMA_DMACCR_PRIO_LOW,
DMA_DMACCR_FS_DISABLE,
DMA_DMACCR_SYNC_NONE
), // DMACCR
DMA_DMACICR_RMK(
DMA_DMACICR_AERRIE_OFF,
DMA_DMACICR_BLOCKIE_OFF,
DMA_DMACICR_LASTIE_OFF,
DMA_DMACICR_FRAMEIE_ON,
DMA_DMACICR_FIRSTHALFIE_OFF,
DMA_DMACICR_DROPIE_OFF,
DMA_DMACICR_TIMEOUTIE_OFF
), // DMACICR
(DMA_AdrPtr)&xmt[1], // DMACSSAL
0, // DMACSSAU
(DMA_AdrPtr)&rcv, // DMACDSAL
0, // DMACDSAU
N, // DMACEN
1, // DMACFN
0, // DMACFI
0 // DMACEI
};

// Define a DMA_Handle object to be used with DMA_open function
DMA_Handle hDmaRcv, hDmaXmt;

volatile Uint16 transferComplete = FALSE;
Uint16 err = 0;
Uint16 old_intm;
Uint16 xmtEventId, rcvEventId;

//---------Function prototypes---------

// Reference the start of the interrupt vector table
// This symbol is defined in file vectors.s55
extern void VECSTART(void);

// Protoype for interrupt functions
interrupt void dmaRcvIsr(void);
void taskFxn(void);

//---------main routine---------
void DMA_INIT(void)
{
Uint16 i;

// Initialize CSL library - This is REQUIRED !!!
CSL_init();

// Set IVPH/IVPD to start of interrupt vector table
IRQ_setVecs((Uint32)(&VECSTART));

/* for (i = 0; i <= N - 1; i++) {
xmt[i] = i + 1;
rcv[i] = 0;
}
*/

ADC_Write();

// Call function to effect transfer
taskFxn();
}

void taskFxn(void)
{
Uint16 srcAddrHi, srcAddrLo;
Uint16 dstAddrHi, dstAddrLo;
Uint16 i;

/* By default, the TMS320C55xx compiler assigns all data symbols word
addresses. The DMA however, expects all addresses to be byte
addresses. Therefore, we must shift the address by 2 in order to
change the word address to a byte address for the DMA transfer. */
srcAddrHi = (Uint16)(((Uint32)(0x0000)) >> 15) & 0xFFFFu;
srcAddrLo = (Uint16)(((Uint32)(0x0020)) << 1) & 0xFFFFu;
dstAddrHi = (Uint16)(((Uint32)(&rcv)) >> 15) & 0xFFFFu;
dstAddrLo = (Uint16)(((Uint32)(&rcv)) << 1) & 0xFFFFu;

dmaRcvConfig.dmacssal = (DMA_AdrPtr)srcAddrLo;
dmaRcvConfig.dmacssau = srcAddrHi;
dmaRcvConfig.dmacdsal = (DMA_AdrPtr)dstAddrLo;
dmaRcvConfig.dmacdsau = dstAddrHi;

srcAddrHi = (Uint16)(((Uint32)(&xmt[0])) >> 15) & 0xFFFFu;
srcAddrLo = (Uint16)(((Uint32)(&xmt[0])) << 1) & 0xFFFFu;
dstAddrHi = (Uint16)(((Uint32)(0x0000)) >> 15) & 0xFFFFu;
dstAddrLo = (Uint16)(((Uint32)(0x0020)) << 1) & 0xFFFFu;

dmaXmtConfig.dmacssal = (DMA_AdrPtr)srcAddrLo;
dmaXmtConfig.dmacssau = srcAddrHi;
dmaXmtConfig.dmacdsal = (DMA_AdrPtr)dstAddrLo;
dmaXmtConfig.dmacdsau = dstAddrHi;

// Open DMA channels 4 & 2 and set regs to power on defaults
hDmaRcv = DMA_open(DMA_CHA4,DMA_OPEN_RESET);
hDmaXmt = DMA_open(DMA_CHA2,DMA_OPEN_RESET);

// Get interrupt event associated with DMA receive
rcvEventId = DMA_getEventId(hDmaRcv);

/* Temporarily disable interrupts and clear any pending
interrupts for MCBSP transmit */
old_intm = IRQ_globalDisable();

// Clear any pending interrupts for DMA channels
IRQ_clear(rcvEventId);

// Enable DMA interrupt in IER register
IRQ_enable(rcvEventId);

// Place DMA interrupt service addresses at associate vector
IRQ_plug(rcvEventId,&dmaRcvIsr);

// Write values from configuration structure to DMA control regs
DMA_config(hDmaRcv,&dmaRcvConfig);
DMA_config(hDmaXmt,&dmaXmtConfig);

// Enable all maskable interrupts
IRQ_globalEnable();

// Enable DMA
DMA_start(hDmaRcv);
DMA_start(hDmaXmt);
// Wait for DMA transfer to be complete

/* while (!transferComplete)
{
;
}
*/
// Compare values

/* for(i = 0; i <= N - 1; i++){
if (rcv[i] != xmt[i]){
++err;
break;
}
}

*/
/* for(i = 0; i <= N - 1; i++){
rcv[i]= xmt[i];}*/

printf ("%s\n",err?"TEST FAILED" : "TEST PASSED");

// Restore status of global interrupt enable flag
IRQ_globalRestore(old_intm);
DMA_config(hDmaRcv,&dmaRcvConfig);

//We're done with DMA , so close them
DMA_close(hDmaRcv);
DMA_close(hDmaXmt);
}

interrupt void dmaRcvIsr(void) {
DMA_stop(hDmaRcv);
IRQ_disable(rcvEventId);
transferComplete = TRUE;
DMA_reset(hDmaRcv);
}
void ADC_Write(void)
{

*ADC_CE1=0x0401; //reset bit 1 in ctrl_reg1
*ADC_CE1=0x0400; //clear reset bit 0 in ctrl_reg1
*ADC_CE1=0x0000; // in ctrl_reg0,internal ref vol,adc active,single,ch0,
*ADC_CE1=0x04B2; //in ctrl_reg1,clear reset,over flow(read only),Active High

GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN7,1);
GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN0,1);
GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN1,1);
GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN2,1);
GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN4,1);

GPIO_pinWrite(myGpio0,GPIO_GPIO_PIN7,0);
}