void hal2_1ktone(); void MakeTable(int *tab); void MakeTune(int *tunetab, int *sintab, int step, int nsamps); void PrintTune(int *tunetab,int nsamps); void PrintDescriptors(void); void SetupHAL2(void); void InitiateDMA(int); void WaitForOneDMA(int); #define PRINTFS /* #define CONSPUTC #define DUART_WRITE #define PROM_READ */ #include "sys/sbd.h" #include "sys/hal2.h" /* #include "sys/hpc3.h" */ #include "sys/IP22.h" #define STEP 1000 /* Generates a 1Khz tone */ #define NSAMPS 96000 /* 2 seconds of tune */ #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) #define MAX_DESCRIPTORS 1000 /*#define SPIN while (*isrp & HAL2_ISR_TSTATUS);*/ #define SPIN us_delay(10000) /*#define NOTYET 1*/ int sintab[48000]; int tunetab[NSAMPS*2]; /* the *2 is because it's stereo */ int inbuf[NSAMPS*2]; scdescr_t input_desc_list[MAX_DESCRIPTORS]; scdescr_t desc_list[MAX_DESCRIPTORS]; main() { volatile long *p6 = (volatile long *)PHYS_TO_K1(HPC3_PBUS_CFG_ADDR(6)); volatile long *p5 = (volatile long *)PHYS_TO_K1(HPC3_PBUS_CFG_ADDR(5)); volatile long *p4 = (volatile long *)PHYS_TO_K1(HPC3_PBUS_CFG_ADDR(4)); *p6=0x141b; *p5=0x40e07; *p4=0x0e07; stuff(); hal2_1ktone(); } void hal2_1ktone() { printf("HAL2 1k tone test entered\n"); hal2_configure_pbus_pio(); printf("pbus pio configured\n"); hal2_configure_pbus_dma(); printf("pbus dma configured\n"); MakeTable(sintab); printf("sin table configured\n"); MakeTune(tunetab,sintab,STEP,NSAMPS); printf("tune table configured\n"); PrintTune(tunetab,26); printf("build dma descriptors\n"); printf("inbuf(begin) = %x, inbuf(end) = %x\n", inbuf, &inbuf[NSAMPS*2]); printf("outbuf(begin) = %x, outbuf(end) = %x\n", tunetab, &tunetab[NSAMPS*2]); BuildDescriptors(input_desc_list, inbuf, NSAMPS*2*sizeof(int)); BuildDescriptors(desc_list, tunetab, NSAMPS*2*sizeof(int)); /* PrintDescriptors(); */ printf("Set Up HAL2\n"); SetupHAL2(); printf("Initiate DMA\n"); InitiateDMA(0); WaitForOutput(); InitiateDMA(1); printf("Wait for DMA\n"); WaitForOneDMA(1); printf("HAL2 1k tone test done\n"); } /* Make a 48000 element table containing one cycle of 32767*sin(x) */ void MakeTable(int *tab) { unsigned int theta,t2,t3,t4,t5,t6,t7; int *p1,*p2; int i; /* Compute the first quadrant */ p1=tab; p2=p1+12000; for(i=0;i<=6000;i++) { theta=i*51472; /* theta=i*.25*pi*65536 */ theta/=6000; /* theta=i*.25*pi*65536/6000 */ t2=(theta*theta)>>16; t3=(t2*theta)>>16; t4=(t2*t2)>>16; t5=(t2*t3)>>16; t6=(t3*t3)>>16; t7=(t3*t4)>>16; /*Use a taylor series for sin x to compute values in the first octant*/ *p1++=(5040*theta-840*t3+42*t5-t7)/5040; /*Use a taylor series for cos x to compute values in the second octant*/ *p2--= 65535-(t2>>1) + ( 30*t4 -t6)/720; } /* Scale and limit */ p1=tab; p2=p1+12000; while(p1<=p2) { t7 = (*p1>>1); if(t7>=32767) t7=32767; *p1=t7; p1++; } /* Reflect the first quadrant into the second quadrant */ p1=tab; p2=p1+24000; while(p1<=p2) { *p2 = *p1; p1++; p2--; } /* Reflect the first two quadrants int the last two quadrants */ p1=tab+1; p2=tab+47999; while(p1<=p2) { *p2 = -(*p1); p1++; p2--; } } #define NORMAL_TUNE #if defined NORMAL_TUNE void MakeTune(int *tunetab, int *sintab, int step, int nsamps) { int i,j,s; j=0; for(i=0;i=48000)j-=48000; } } #elif defined ALTERNATING void MakeTune(int *tunetab, int *sintab, int step, int nsamps) { int i,j,s; j=0; for(i=0;i=48000)j-=48000; } } #else void MakeTune(int *tunetab, int *sintab, int step, int nsamps) { int i,j,k,s,t; j=0; k=0; for(i=0;i>8)&0xff; t=(sintab[k]>>8)&0xff; #ifdef LATER *tunetab=(s<<24)+(s<<16)+(t<<8)+t; tunetab++; *tunetab=(s<<24)+(s<<16)+(t<<8)+t; tunetab++; #endif *tunetab=(s<<16)+s; tunetab++; *tunetab=(t<<16)+t; tunetab++; j+=step; if(j>=48000)j-=48000; k+=step+step; if(k>=48000)k-=48000; } } #endif void PrintTune(int *tunetab,int nsamps) { int i; for(i=0;icbp = K1_TO_PHYS(p); bytes_till_page_boundary = 4096-( (int)p & 0xfff); bytes_this_descriptor = MIN(bytes_till_page_boundary,nremaining); desc->bcnt = bytes_this_descriptor; desc->eox=0; desc->pad1=0; desc->xie=0; desc->pad0=0; desc->nbp = K1_TO_PHYS(desc+1); desc->word_pad = 0; nremaining -= bytes_this_descriptor; p+= bytes_this_descriptor; desc++; } desc--; desc->nbp = 0; desc->eox = 1; } void PrintDescriptors() { scdescr_t *desc; desc=desc_list; while(1) { printf( "0x%8x: eox 0x%x pad1 0x%x xie 0x%x pad0 0x%4x bc %d\n", desc, desc->eox, desc->pad1, desc->xie, desc->pad0, desc->bcnt); if(desc->eox)break; printf("Next address: 0x%8x, buffer address 0x%8x\n", desc->nbp, desc->cbp); desc++; } } /* ** InitiateDMA - initiates a transmit DMA on channel 0 of the descriptor ** chain starting at desc_list. */ void InitiateDMA(int direction) { pbus_control_write_t ctrlval; volatile pbus_control_write_t* ctrlptr= (pbus_control_write_t*)PHYS_TO_K1(HPC3_PBUS_CONTROL(direction)); volatile unsigned long *dpptr= (unsigned long *)PHYS_TO_K1(HPC3_PBUS_DP(direction)); ctrlval.pad0=0; ctrlval.fifo_end=2*direction+1; ctrlval.pad1=0; ctrlval.fifo_beg=2*direction; ctrlval.highwater=5; ctrlval.pad2=0; ctrlval.real_time=1; ctrlval.ch_act_ld=1; ctrlval.ch_act=1; ctrlval.flush=0; ctrlval.receive=direction; ctrlval.little=0; ctrlval.pad3=0; *dpptr=K1_TO_PHYS((direction) ? input_desc_list : desc_list); *ctrlptr=ctrlval; /* XXX pbus_control_write_t ctrlval; volatile pbus_control_write_t* ctrlptr= (pbus_control_write_t*)PHYS_TO_K1(HPC3_PBUS_CONTROL(0)); volatile unsigned long *dpptr=(unsigned long *)PHYS_TO_K1(HPC3_PBUS_DP(0)); ctrlval.pad0=0; #ifdef LATER ctrlval.fifo_end=47; #endif ctrlval.fifo_end=2; ctrlval.pad1=0; ctrlval.fifo_beg=0; ctrlval.highwater=4; ctrlval.pad2=0; ctrlval.real_time=1; ctrlval.ch_act_ld=1; ctrlval.ch_act=1; ctrlval.flush=0; ctrlval.receive=0; ctrlval.little=0; ctrlval.pad3=0; *dpptr=K1_TO_PHYS(desc_list); *ctrlptr=ctrlval; */ } void SetupHAL2(void) { volatile unsigned long *idr0p=(unsigned long *)PHYS_TO_K1(HAL2_IDR0); volatile unsigned long *idr1p=(unsigned long *)PHYS_TO_K1(HAL2_IDR1); volatile unsigned long *idr2p=(unsigned long *)PHYS_TO_K1(HAL2_IDR2); volatile unsigned long *idr3p=(unsigned long *)PHYS_TO_K1(HAL2_IDR3); volatile unsigned long *iarp=(unsigned long *)PHYS_TO_K1(HAL2_IAR); volatile unsigned long *isrp=(unsigned long *)PHYS_TO_K1(HAL2_ISR); int inc, mod, modctrl; /* Set up the ISR */ *isrp = 0; us_delay(50); *isrp = HAL2_ISR_CODEC_RESET_N|HAL2_ISR_GLOBAL_RESET_N; /* Clear DMA ENABLE */ *idr0p = 0x0; /* Disable all the devices */ *iarp = HAL2_DMA_ENABLE_W; SPIN; /* Set up DMA Endian */ *idr0p = 0; /* All ports are big endian */ *iarp = HAL2_DMA_ENDIAN_W; SPIN; /* Set up DMA DRIVE */ *idr0p = 3; /* Activate only port 0 */ *iarp = HAL2_DMA_DRIVE_W; SPIN; /* Set up CODEC A */ *idr0p = 0 /* Physical DMA channel */ +(1<<3) /* Bres Clock ID */ +(2<<8); /* Stereo Mode */ *iarp = HAL2_CODECA_CTRL1_W; SPIN; #ifdef LATER *idr0p = (0<<10)+(0x00<<7)+(0x00<<2); /* unmute, A/D gains == 0 */ #endif *idr0p = (1<<10)+(0x00<<7)+(0x00<<2); /* unmute, A/D gains == 0 */ *idr1p = (0x0<<7) /* Left D/A output atten */ +(0x0<<2) /* Right D/A output atten */ +(0<<1) /* Digital output port data bit 1 */ +(0); /* Digital output port data bit 0 */ *iarp = HAL2_CODECA_CTRL2_W; SPIN; /* Set up CODEC B */ *idr0p = 1 /* dma channel */ +(1<<3); /* bres clock */ /* Set up BRES CLOCK 1 */ *idr0p = 0; /* 48khz master */ *iarp = HAL2_BRES1_CTRL1_W; SPIN; inc=1; mod=1; modctrl = 0xffff & (inc-mod-1); *idr0p = inc; *idr1p = modctrl; *iarp = HAL2_BRES1_CTRL2_W; SPIN; /* Set up DMA ENABLE */ *idr0p = 0x8 + 0x10; /* Enable only DAC A*/ *iarp = HAL2_DMA_ENABLE_W; SPIN; } void WaitForOutput() { volatile pbus_control_read_t* ctrl0ptr= (pbus_control_read_t*)PHYS_TO_K1(HPC3_PBUS_CONTROL(0)); volatile unsigned long* bp0ptr= (unsigned long*)PHYS_TO_K1(HPC3_PBUS_BP(0)); pbus_control_read_t ctrl0val; int ntimes; int maxtimes=3000; long *prevbp = (long *)tunetab; long *newbp; volatile long *ptr=(long *)tunetab+1; volatile int garbage; long i,cr; int oldErr = -1, oldRev = -1, oldValid = -1, oldLClip=-1, oldRClip=-1; for(ntimes=0;ntimes newbp) printf("ptr = %x, newbp = %x\n", ptr, newbp); for (; ptr < newbp; ptr+=2) { i = *ptr; printf("v = %x\n", (i & HAL2_NAB_VALID)); if (oldErr != ((i & 0xf0000000) >> 28)) { oldErr = (i & 0xf0000000) >> 28; cr++; } if (oldRev != ((i & 0x0f000000) >> 24)) { oldRev = (i & 0x0f000000) >> 24; cr++; } if (oldValid != ((i & HAL2_NAB_VALID) >> 3)) { oldValid = (i & HAL2_NAB_VALID) >> 3; cr++; } if (oldLClip != ((i & HAL2_NAB_LEFT_CLIP) >> 2)) { oldLClip = (i & HAL2_NAB_LEFT_CLIP) >> 2; cr++; } if (oldRClip != ((i & HAL2_NAB_RIGHT_CLIP) >> 1)) { oldRClip = (i & HAL2_NAB_RIGHT_CLIP) >> 1; cr++; } } if (cr) { if (ptr > ((long *)inbuf+1)) printf("e: 0x%x rev: 0x%x val: 0x%x lc: 0x%x rc: 0x%x\n", oldErr, oldRev, oldValid, oldLClip, oldRClip); } us_delay(10000); } if(ntimes==maxtimes) { printf("Dma %d did not complete after %d*.01 seconds\n",which,ntimes); } else { printf("Dma %d complete after %d*.01 seconds\n",which,ntimes); } } stuff() { volatile unsigned char *ser1ptr=(unsigned char *)PHYS_TO_K1(0xbfbd9807); int i; printf("0x%x\n",ser1ptr); us_delay(100000); for(i=0;i<10;i++) { *ser1ptr='C'; us_delay(100000); } }