Showing posts with label mcu. Show all posts
Showing posts with label mcu. Show all posts

Sunday, April 05, 2009

2440 dma

/*****************************************
NAME: dma.c
DESC: DMA memory2memory test
*****************************************/

#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"

static void __irq Dma0Done(void);
static void __irq Dma1Done(void);
static void __irq Dma2Done(void);
static void __irq Dma3Done(void);
void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst);

typedef struct tagDMA
{
volatile U32 DISRC; //0x0
volatile U32 DISRCC; //0x4
volatile U32 DIDST; //0x8
volatile U32 DIDSTC; //0xc
volatile U32 DCON; //0x10
volatile U32 DSTAT; //0x14
volatile U32 DCSRC; //0x18
volatile U32 DCDST; //0x1c
volatile U32 DMASKTRIG; //0x20
}DMA;

static volatile int dmaDone;

void Test_DMA(void)
{
DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst
//DMA Ch 0
DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x80000,0,0); //byte,single
DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x40000,1,0); //halfword,single
DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,2,0); //word,single
DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,0,1); //byte,burst
DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x10000,1,1); //halfword,burst
DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst

//DMA Ch 1
DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x80000,0,0); //byte,single
DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x40000,1,0); //halfword,single
DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,2,0); //word,single
DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,0,1); //byte,burst
DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x10000,1,1); //halfword,burst
DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst

//DMA Ch 2
DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x80000,0,0); //byte,single
DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x40000,1,0); //halfword,single
DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,2,0); //word,single
DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,0,1); //byte,burst
DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x10000,1,1); //halfword,burst
DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst

//DMA Ch 3
DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x80000,0,0); //byte,single
DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x40000,1,0); //halfword,single
DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,2,0); //word,single
DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,0,1); //byte,burst
DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x10000,1,1); //halfword,burst
DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst

}

void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst)
{
int i,time;
volatile U32 memSum0=0,memSum1=0;
DMA *pDMA;
int length;
length=tc*(burst ? 4:1)*((dsz==0)+(dsz==1)*2+(dsz==2)*4);
Uart_Printf("[DMA%d MEM2MEM Test]\n",ch);

switch(ch)
{
case 0:
pISR_DMA0=(int)Dma0Done;
rINTMSK&=~(BIT_DMA0);
pDMA=(void *)0x4b000000;
break;
case 1:
pISR_DMA1=(int)Dma1Done;
rINTMSK&=~(BIT_DMA1);
pDMA=(void *)0x4b000040;
break;
case 2:
pISR_DMA2=(int)Dma2Done;
rINTMSK&=~(BIT_DMA2);
pDMA=(void *)0x4b000080;
break;
case 3:
pISR_DMA3=(int)Dma3Done;
rINTMSK&=~(BIT_DMA3);
pDMA=(void *)0x4b0000c0;
break;
}
Uart_Printf("DMA%d %8xh->%8xh,size=%xh(tc=%xh),dsz=%d,burst=%d\n",ch, srcAddr,dstAddr,length,tc,dsz,burst);

Uart_Printf("Initialize the src.\n");
for(i=srcAddr;i<(srcAddr+length);i+=4)
{
*((U32 *)i)=i^0x55aa5aa5;
memSum0+=i^0x55aa5aa5;
}

Uart_Printf("DMA%d start\n",ch);
dmaDone=0;
pDMA->DISRC=srcAddr;
pDMA->DISRCC=(0<<1)(0<<0); // inc,AHB
pDMA->DIDST=dstAddr;
pDMA->DIDSTC=(0<<2) (0<<1)(0<<0); // inc,AHB
pDMA->DCON=tc((unsigned int)1<<31)(1<<30)(1<<29)(burst<<28)(1<<27)\
(0<<23)(1<<22)(dsz<<20)(tc);
//HS,AHB,TC interrupt,whole, SW request mode,relaod off
pDMA->DMASKTRIG=(1<<1)1; //DMA on, SW_TRIG

Timer_Start(3);//128us resolution
while(dmaDone==0);
time=Timer_Stop();
Uart_Printf("DMA transfer done. time=%f, %fMB/S\n",(float)time/ONESEC3, length/((float)time/ONESEC3)/1000000.);
rINTMSK=BIT_ALLMSK;
for(i=dstAddr;i<dstAddr+length;i+=4)
{
memSum1+=*((U32 *)i)=i^0x55aa5aa5;
}
Uart_Printf("memSum0=%x,memSum1=%x\n",memSum0,memSum1);
if(memSum0==memSum1)
Uart_Printf("DMA test result--------------------------------------O.K.\n");
else
Uart_Printf("DMA test result--------------------------------------ERROR!!!\n");

}

static void __irq Dma0Done(void)
{
ClearPending(BIT_DMA0);
dmaDone=1;
}

static void __irq Dma1Done(void)
{
ClearPending(BIT_DMA1);
dmaDone=1;
}

static void __irq Dma2Done(void)
{
ClearPending(BIT_DMA2);
dmaDone=1;
}

static void __irq Dma3Done(void)
{
ClearPending(BIT_DMA3);
dmaDone=1;
}

Saturday, March 14, 2009

ad da

1. AD轉換器的分類
下面簡要介紹常用的幾種類型的基本原理及特點:積分型、逐次逼近型、並行比較型/串並行型、Σ-Δ調製型、電容陣列逐次比較型及壓頻變換型。
    1)積分型(如TLC7135)
積分型AD工作原理是將輸入電壓轉換成時間(脈衝寬度信號)或頻率(脈衝頻率),然後由計時器/計數器獲得數字值。其優點是用簡單電路就能獲得高解析度,但缺點是由於轉換精度依賴於積分時間,因此轉換速率極低。初期的單片AD轉換器大多採用積分型,現在逐次比較型已逐步成為主流。
    2)逐次比較型(如TLC0831)
逐次比較型AD由一個比較器和DA轉換器通過逐次比較邏輯構成,從MSB開始,順序地對每一位元將輸入電壓與內置DA轉換器輸出進行比較,經n次比較而輸出數位值。其電路規模屬於中等。其優點是速度較高、功耗低,在低分辨率(<12位)時價格便宜,但高精度(>12位)時價格很高。
    3)並行比較型/串並行比較型(如TLC5510)
並行比較型AD採用多個比較器,僅作一次比較而實行轉換,又稱FLash(快速)型。由於轉換速率極高,n位元的轉換需要2n-1個比較器,因此電路規模也極大,價格也高,只適用於視頻AD轉換器等速度特別高的領域。
串並行比較型AD結構上介於並行型和逐次比較型之間,最典型的是由2個n/2位的並行型AD轉換器配合DA轉換器組成,用兩次比較實行轉換,所以稱為 Half flash(半快速)型。還有分成三步或多步實現AD轉換的叫做分級(Multistep/Subrangling)型AD,而從轉換時序角度又可稱為流水線(Pipelined)型AD,現代的分級型AD中還加入了對多次轉換結果作數位運算而修正特性等功能。這類AD速度比逐次比較型高,電路規模比並行型小。
    4)Σ-Δ(Sigma?/FONT>delta)調製型(如AD7705)
    Σ-Δ型AD由積分器、比較器、1位元DA轉換器和數位濾波器等組成。原理上近似於積分型,將輸入電壓轉換成時間(脈衝寬度)信號,用數位濾波器處理後得到數位值。電路的數位部分基本上容易單片化,因此容易做到高解析度。主要用於音頻和測量。
    5)電容陣列逐次比較型
電容陣列逐次比較型AD在內置DA轉換器中採用電容矩陣方式,也可稱為電荷再分配型。一般的電阻陣列DA轉換器中多數電阻的值必須一致,在單晶片上生成高精度的電阻並不容易。如果用電容陣列取代電阻陣列,可以用低廉成本製成高精度單片AD轉換器。最近的逐次比較型AD轉換器大多為電容陣列式的。
    6)壓頻變換型(如AD650)
壓頻變換型(Voltage-Frequency Converter)是通過間接轉換方式實現模數轉換的。其原理是首先將輸入的類比信號轉換成頻率,然後用計數器將頻率轉換成數位量。從理論上講這種AD 的解析度幾乎可以無限增加,只要採樣的時間能夠滿足輸出頻率解析度要求的累積脈衝個數的寬度。其優點是分辨率高、功耗低、價格低,但是需要外部計數電路共同完成AD轉換。
2. AD轉換器的主要技術指標
    1)分辨率(Resolution) 指數字量變化一個最小量時類比信號的變化量,定義為滿刻度與2n的比值。分辨率又稱精度,通常以數位信號的位元數來表示。
    2)轉換速率(Conversion Rate)是指完成一次從類比轉換到數位的AD轉換所需的時間的倒數。積分型AD的轉換時間是毫秒級屬低速AD,逐次比較型AD是微秒級屬中速AD,全並行/串並行型AD可達到納秒級。採樣時間則是另外一個概念,是指兩次轉換的間隔。為了保證轉換的正確完成,採樣速率(Sample Rate)必須小於或等於轉換速率。因此有人習慣上將轉換速率在數值上等同於採樣速率也是可以接受的。常用單位是ksps和Msps,表示每秒採樣千/百萬次(kilo / Million Samples per Second)。
    3)量化誤差(Quantizing Error) 由於AD的有限分辨率而引起的誤差,即有限分辨率AD的階梯狀轉移特性曲線與無限分辨率AD(理想AD)的轉移特性曲線(直線)之間的最大偏差。通常是1 個或半個最小數位量的類比變化量,表示為1LSB、1/2LSB。
    4)偏移誤差(Offset Error) 輸入信號為零時輸出信號不為零的值,可外接電位器調至最小。
    5)滿刻度誤差(Full Scale Error) 滿度輸出時對應的輸入信號與理想輸入信號值之差。
    6)線性度(Linearity) 實際轉換器的轉移函數與理想直線的最大偏移,不包括以上三種誤差。
其他指標還有:絕對精度(Absolute Accuracy) ,相對精度(Relative Accuracy),微分非線性,單調性和無錯碼,總諧波失真(Total Harmonic Distotortion縮寫THD)和積分非線性。
3. DA轉換器
DA轉換器的內部電路構成無太大差異,一般按輸出是電流還是電壓、能否作乘法運算等進行分類。大多數DA轉換器由電阻陣列和n個電流開關(或電壓開關)構成。按數位輸入值切換開關,產生比例於輸入的電流(或電壓)。此外,也有為了改善精度而把恒流源放入器件內部的。一般說來,由於電流開關的切換誤差小,大多採用電流開關型電路,電流開關型電路如果直接輸出生成的電流,則為電流輸出型DA轉換器,如果經電流椀繆棺緩笫涑觶蛭繆故涑魴? /FONT>DA轉換器。此外,電壓開關型電路為直接輸出電壓型DA轉換器。
    1)電壓輸出型(如TLC5620)
電壓輸出型DA轉換器雖有直接從電阻陣列輸出電壓的,但一般採用內置輸出放大器以低阻抗輸出。直接輸出電壓的器件僅用於高阻抗負載,由於無輸出放大器部分的延遲,故常作為高速DA轉換器使用。
    2)電流輸出型(如THS5661A)
電流輸出型DA轉換器很少直接利用電流輸出,大多外接電流—電壓轉換電路得到電壓輸出,後者有兩種方法:一是只在輸出引腳上接負載電阻而進行電流—電壓轉換,二是外接運算放大器。用負載電阻進行電流—電壓轉換的方法,雖可在電流輸出引腳上出現電壓,但必須在規定的輸出電壓範圍內使用,而且由於輸出阻抗高,所以一般外接運算放大器使用。此外,大部分CMOS DA轉換器當輸出電壓不為零時不能正確動作,所以必須外接運算放大器。
當外接運算放大器進行電流電壓轉換時,則電路構成基本上與內置放大器的電壓輸出型相同,這時由於在DA轉換器的電流建立時間上加入了達算放入器的延遲,使回應變慢。此外,這種電路中運算放大器因輸出引腳的內部電容而容易起振,有時必須作相位補償。
    3)乘算型(如AD7533)
DA轉換器中有使用恒定基準電壓的,也有在基準電壓輸入上加交流信號的,後者由於能得到數位輸入和基準電壓輸入相乘的結果而輸出,因而稱為乘算型DA轉換器。乘算型DA轉換器一般不僅可以進行乘法運算,而且可以作為使輸入信號數位化地衰減的衰減器及對輸入信號進行調製的調製器使用。
    4)一位DA轉換器
一位元DA轉換器與前述轉換方式全然不同,它將數位值轉換為脈衝寬度調製或頻率調製的輸出,然後用數位濾波器作平均化而得到一般的電壓輸出(又稱位元流方式),用於音頻等場合。
4. DA轉換器的主要技術指標:
    1)分辨率(Resolution) 指最小類比輸出量(對應數位量僅最低位元為‘1’)與最大量
(對應數字量所有有效位元為‘1’)之比。
    2)建立時間(Setting Time) 是將一個數位量轉換為穩定類比信號所需的時間,也可以認為是轉換時間。DA中常用建立時間來描述其速度,而不是AD中常用的轉換速率。一般地,電流輸出 DA建立時間較短,電壓輸出DA則較長。
其他指標還有線性度(Linearity),轉換精度,溫度係數/漂移。

Tuesday, May 09, 2006

vdsp ldf out of memory fix:

vdsp ldf out of memory fix:

sample problem:

[Error li1040] "libmpeg2.ldf":450 Out of memory in output section 'l1_code' in processor 'P0'
Total of 0x7b2 word(s) were not mapped.
For more details, see 'linker_log.xml' in the output directory.


solution:

If u are using vdsp++ 4.0 then in ur [project options] use

-MDUSE_SDRAM flag to the linker at link time.