注册 登录
亿加合和智能车制作 返回首页

huang91的个人空间 http://www.znczz.com/?82302 [收藏] [复制] [分享] [RSS]

日志

AN4590: Using DMA to Emulate ADC Flexible Scan Mode on Kinetis K Series

已有 1186 次阅读2013-6-3 00:30 | DMA

Introduction
The Kinetis K series of microcontrollers offers an analog-to-digital controller (ADC) that supports up to two input channels through its built-in Scan mode. The channel number is defined by the ADCx_SCA and ADCx_SCB registers, and the conversion results are available, after conversion, in the ADCx_RA and ADCx_RB registers. The Kinetis K series of microcontrollers also offers a powerful and complex DMA periphery (with up to 16 channels) that can be combined with the ADC to allow the scanning of more than two channels. This application note describes how to combine the ADC and DMA into a powerful and flexible periphery supplying a resultant data stream into SRAM from any ADC input.


Implementation detail

This section presents details of DMA transfer and the ADC Flexible Scan mode process.

DMA transfer terminology

The following terms are used in this application note's discussion of DMA transfers:

  • In a minor loop, one transfer group is started for each request. A minor loop can transfer from 1 to 4 GB of basic units. The basic transfer unit is 8 bits.So, for 16-bit data, one minor loop supports two transfers.
  • major loop chains multiple minor loops together. A major loop can modify source and destination addresses; it can also support a circular buffer mode after the major loop has finished. The end of a major loop transfer can be handled asynchronously by an interrupt request. A half transfer finish can also be handled by an interrupt. A combination of half-transfer and full-transfer finishes can be implemented using a double-buffer principle.
  • Linking is a special eDMA feature for chaining more than one DMA channel. Linking channels allows you to start more than one transfer with a single request by defining a sequence of channels to be converted. The request starts the transfer on one DMA channel, and when that channel finishes, the transfer on the next channel starts. Channel linking is defined separately for major and minor loop finishes.
Flexible Scan mode process

ADC Flexible Scan mode requires two DMA channels for one ADC converter. DMA channel 1, with a higher priority, transfers the resultant ADC data from the ADCx_RA register to a memory buffer in the SRAM. DMA channel 0, with a lower priority, transfers a future ADC channel setting (input multiplexer channel and single end/differential mode) from the constant buffer, which could be placed in SRAM or flash memory. The following steps occur in Flexible Scan mode:

  1. The conversion complete flag ADCxSC1A.COCO requests a DMA transfer for channel 1.
  2. The channel 1 transfer finishes and the resulting value is transferred to the SRAM buffer.
  3. Since channel 1 is linked to channel 0, the channel 1 finish requests a transfer start on channel 0.
Figure 1. Data flow between periphery and SRAM


DMA special settings

Channel priority

DMA channel priority settings are important because in ADC software trigger mode, conversion is started by a write to ADCn_SC1A; thus, the resultant data must be read first and then followed by a write of the next channel setting, because writing to the ADC starts the next conversion. DMA channel 1 is used to transfer ADC result data to the SRAM buffer. DMA channel 0 is used to change the ADC input mux.

Major and minor loop linking

Single scan mode (only one measurement from some ADC channels is required) should use only minor loop linking. This is defined in the DMA_TCDx_BITER_ELINKNO and DMA_TCDx_CITER_ELINKNO registers.

Continuous scan mode (circular measurement from some ADC channels is required) needs to use both major and minor loop linking. This is defined in the DMA_TCDx_BITER_ELINKNO, DMA_TCDx_CITER_ELINKNO, and DMA_TCD1_CSR registers. It is necessary for continuous scan mode to use both major and minor loop linking because there is no generation of a minor loop finish request after a major loop finish.



Example

This example uses the Freescale TRW-K60N512 development board and IAR Embedded Workbench® version 6.30.1.3142 as its test environment.

Example process flow

The example code that accompanies this application note demonstrates a continuous scan conversion from three ADC channels.

  • Each channel is measured four times, so the SRAM result buffer size is 3 × 4 = 12 (the real buffer size is 16, to demonstrate that only 12 data field parts are written).
  • The ADC works in hardware trigger mode, with the PDB timer serving as the trigger source.
  • Scanning is executed in continuous mode; thus, after a major loop has finished, the result buffer pointer address_0 is reloaded and the conversion begins again from the start buffer address.
Figure 1. Example process flow
Functions in the main file
SIM_InitInitialize clocks and oscillator
FLL_InitFLL periphery initialization
VREF_InitVoltage reference initialization
PDBCH0TRG0_InitPDB channel 0 initialization for hardware trigger ADC0
PDB_InitCommon PDB initialization
ADC_ExecCalibInternal calibration procedure for ADC0
ADC_InitADC0 initialization
DMACH0_CH1_initDMA channel 0 and channel 1 initialization

DMA channel initialization
Channel 1 transfers ADC0 result data from ADC0_RA to SRAM buffer. 
//***************************************************************
//**** DMA transfer request source – ADC0 conversion complete
//***************************************************************
DMAMUX_CHCFG1          = DMAMUX _CHCFG_ENBL|DMAMUX_CHCFG_SOURCE(28);
//***************************************************************
//**** Source address, ADC0_RA
//***************************************************************
DMA_TCD1_SADDR         = (uint32) &ADC0_RA;
//***************************************************************
//**** Source address increment; data is still read for the same address, no increment needed
//***************************************************************
DMA_TDC1_SOFF          = 0x00;

//***************************************************************
//**** Source address reload after major loop finishes, no reload needed
//***************************************************************
DMA_TDC1_SLAST         = 0x00;
//***************************************************************
//**** Destination address, SRAM buffer [0]
//***************************************************************
DMA_TDC1_DADDR         = (uint32)&ui_adc_result[0];
//***************************************************************
//**** Destination address increment in bytes, increment for next buffer address 
//**** 16 bit => 2 bytes
//***************************************************************
DMA_TDC1_DOFF          = 0x02;
//***************************************************************
//**** Destination address reload after major loop finishes, 
//**** must be subtracted from last pointer value, sample number is 12 each and 2 bytes long,
//**** 2 × 12 = 24 and must be subtract -24
//***************************************************************
DMA_TDC1_DLASTSGA       = -24;
//***************************************************************
//**** Number of bytes for minor loop (one data transfer), ADC0 result is 16 bits long, so 
//**** 2-byte transfer
//***************************************************************
DMA_TDC1_NBYTES_MLO     = 0x02;
//***************************************************************
//**** Channel linking and major loop setting, linking after minor loop is enabled to
//**** channel 0 (0x0000), major loop transfers number 12 (0x0C)
//***************************************************************
DMA_TDC1_BITER_ELONKNO  =  (DMA_BITER_ELINKNO_ELINK_MASK|0x0000|0x0C);

//***************************************************************
//**** Channel linking and major loop setting reload value after major loop finishes,
//**** linking after minor loop is enabled, major loop transfers number 12 (0x0C).
//***************************************************************
DMA_TDC1_CITER_ELONKNO  =  (DMA_CITER_ELINKNO_ELINK_MASK|0x0C);
//***************************************************************
//**** Source and destination data width specification, both source and destination is 16-bit
//***************************************************************
DMA_TDC1_ATTR           =  DMA_ATTR_SSIZE(1)| DMA_ATTR_SDIZE(1);
//***************************************************************
//**** Common channel setting, linking after major loop enable to channel 0, 
//**** IRQ request is generated after major loop complete
//***************************************************************
DMA_TDC1_CSR            = (DMA_CSR_MAJORLINKCH(0)|DMA_CSR_MAJORLINCH_MASK|
                           DMA_CSR_INTMAJOR_MASK);


Channel 0 transfers next ADC0 input setting from constant buffer to ADC0_SC1A.

//***************************************************************
//**** DMA transfer request source – always requestor
//***************************************************************
DMAMUX_CHCFG0           = DMAMUX _CHCFG_ENBL|DMAMUX_CHCFG_SOURCE(36) ;
//***************************************************************
//**** Source address, constant buffer in SRAM
//***************************************************************
DMA_TCD1_SADDR          = (uint32) &uc_adc_mux[0];
//***************************************************************
//**** Source address increment, data is 8-bit, 1 byte 
//***************************************************************
DMA_TDC1_SOFF           = 0x01;
//***************************************************************
//**** Source address reload after major loop finish, must be subtracted from last
//**** pointer value, sampling channel number is 3 each and 1 byte long, 1 × 3 = 3 
//**** and must be subtract -3
//***************************************************************
DMA_TDC1_SLAST          = -3;
//***************************************************************
//**** Destination address, ADC0 control register
//***************************************************************
DMA_TDC1_DADDR          = (uint32)&ADC0_SC1A;
//***************************************************************
//**** Destination address increment in bytes, no increment needed
//***************************************************************
DMA_TDC1_DOFF           = 0x00;

//***************************************************************
//**** Destination address reload after major loop finish, no address reload needed
//***************************************************************
DMA_TDC1_DLASTSGA       = 0x00;

//***************************************************************
//**** Number of bytes for minor loop (one data transfer), ADC0 input setting value is 
//**** 8 bits long, so 1-byte transfer
//***************************************************************
DMA_TDC1_NBYTES_MLO     = 0x01;

//***************************************************************
//**** Channel linking and major loop setting, no linking after minor loop, 
//**** major loop transfers number 0x03
//***************************************************************
DMA_TDC1_BITER_ELONKNO  = (DMA_BITER_ELINKNO_ELINK_MASK|0x0000|0x0C);

//***************************************************************
//**** Channel linking and major loop setting reload value after major loop finish, 
//**** no linking after minor loop, major loop transfers number 0x03
//***************************************************************
DMA_TDC1_CITER_ELONKNO  = (DMA_CITER_ELINKNO_ELINK_MASK|0x0C);

//***************************************************************
//**** Source and destination data width specification, both source and destination are 8-bit
//***************************************************************
DMA_TDC1_ATTR           = DMA_ATTR_SSIZE(1)| DMA_ATTR_SDIZE(1);

//***************************************************************
//**** Common channel setting, no linking after major loop, no IRQ request enable
//***************************************************************
DMA_TDC1_CSR            = 0x00;


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

关于我们|联系我们|小黑屋|亿加合和智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-5-4 18:58 , Processed in 0.038097 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

返回顶部