// sub source for Mouse.c void ClockUp(void) { // from dsPIC manual ex39-1 CLKDIVbits.PLLPRE=2; // N1=4 /4 20MHz->5MHz PLLFBD=30; // M=32 x32 5MHz -> 160MHz CLKDIVbits.PLLPOST=0; // N2=2 /2 160MHz -> 80MHz __builtin_write_OSCCONH(0x03); __builtin_write_OSCCONL(OSCCONL|0x01); //LATB=0x8000; // wait for switch while(OSCCONbits.COSC != 0b011) ; //LATB=0xc000; // wait for PLL stable while(OSCCONbits.LOCK!=1) ; // LATB=0; } void IORemapping(void) { // setting for UART port __builtin_write_OSCCONL(OSCCONL&(~0x40)); // unlock RP RPINR18bits.U1RXR=9; // UART 1 RX <- RP9 RPOR4bits.RP8R=3; // RP8 <- UART 1 TX TRISBbits.TRISB9=1; // RP9=input TRISBbits.TRISB8=0; // RP8=output __builtin_write_OSCCONL(OSCCONL|0x40); // lock RP } /* copied from lib src */ void SetMCPWM1DeadTimeAssignment(unsigned int config) { P1DTCON2 = config ; } void SetupMCPWM(void) { unsigned int period; // PWM cycle, Fcy -> prescaler -> count // 40M/20k=2000, centered PMW /2 period=999; // interrupt setting ConfigIntMCPWM1(PWM1_INT_EN & PWM1_INT_PR2 & PWM1_FLTA_DIS_INT & PWM1_FLTA_INT_PR7); /* dead time setting activate->A innactivate->B */ SetMCPWM1DeadTimeAssignment(PWM1_DTS1A_UA & PWM1_DTS1I_UB & PWM1_DTS2A_UA & PWM1_DTS2I_UB & PWM1_DTS3A_UA & PWM1_DTS3I_UB); /* deadtime : Fcy tick * DTxS * DTx */ SetMCPWM1DeadTimeGeneration(PWM1_DTAPS8 & PWM1_DTA0 & PWM1_DTBPS8 & PWM1_DTB0); /* fault sensitive */ /* only A, disabled , if need, remap io required */ SetMCPWM1FaultA(PWM1_FLTA1_DIS & PWM1_FLTA2_DIS & PWM1_FLTA3_DIS & PWM1_FLTA1_DIS); OpenMCPWM1(period, 0, /* special event trigger for ADC ->sec14 MC 70187, 14-15 */ PWM1_EN & PWM1_IDLE_STOP & PWM1_OP_SCALE1 & /* postscaler for interrupt */ PWM1_IPCLK_SCALE1 & PWM1_MOD_UPDN, /* prescaler 1:1, updown */ PWM1_MOD3_COMP & PWM1_MOD2_COMP & PWM1_MOD1_COMP & /* compli ope */ //PWM1_PEN3H & PWM1_PEN2H & PWM1_PEN1H & //PWM1_PEN3L & PWM1_PEN2L & PWM1_PEN1L, PWM1_PDIS3H & PWM1_PDIS2H & PWM1_PDIS1H & PWM1_PDIS3L & PWM1_PDIS2L & PWM1_PDIS1L, PWM1_SEVOPS1 & /* special, ADC */ PWM1_OSYNC_TCY & /* output override timming */ PWM1_UEN); /* PWM duty set eneble */ } void __attribute__((__interrupt__, no_auto_psv)) _MPWM1Interrupt(void) { IFS3bits.PWM1IF = 0; OnPWMCycle(); } void SetDutyCycle(unsigned int ph1,unsigned int ph2,unsigned int ph3) { SetDCMCPWM1(1,ph1,0); SetDCMCPWM1(2,ph2,0); SetDCMCPWM1(3,ph3,0); } void SetOutput(int ph1,int ph2,int ph3) { SetDCMCPWM1(1,(500-ph1)&0x7ff,0); SetDCMCPWM1(2,(500-ph2)&0x7ff,0); SetDCMCPWM1(3,(500-ph3)&0x7ff,0); LATBbits.LATB7=(ph1<0)?1:0; } void DisablePWM(void) { OverrideMCPWM1(PWM1_POUT_1H & PWM1_POUT_2H &PWM1_POUT_3H & PWM1_POUT_1L & PWM1_POUT_2L &PWM1_POUT_3L & PWM1_POUT1H_INACT & PWM1_POUT2H_INACT & PWM1_POUT3H_INACT & PWM1_POUT1L_INACT & PWM1_POUT2L_INACT & PWM1_POUT3L_INACT); } void EnablePWM(void) { OverrideMCPWM1(PWM1_GEN_1H & PWM1_GEN_2H &PWM1_GEN_3H & PWM1_GEN_1L & PWM1_GEN_2L &PWM1_GEN_3L & PWM1_POUT1H_INACT & PWM1_POUT2H_INACT & PWM1_POUT3H_INACT & PWM1_POUT1L_INACT & PWM1_POUT2L_INACT & PWM1_POUT3L_INACT); } unsigned int __attribute__((space(dma))) ADCbufferA[17],ADCbufferB[17]; // buffer[16]=phase // ========================== // ADConversion int SetupADC(void) { // setup DMA DMA0CONbits.AMODE = 0; // Configure DMA for Peripheral indirect mode DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode DMA0PAD = 0x0300; // Point DMA to ADC1BUF0 DMA0CNT = 3; // 4 DMA request DMA0REQ = 13; // Select ADC1 as DMA Request source DMA0STA = __builtin_dmaoffset(&ADCbufferA); DMA0STB = __builtin_dmaoffset(&ADCbufferB); // not need IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit IEC0bits.DMA0IE = 0; //Stop the DMA interrupt enable bit DMA0CONbits.CHEN=1; // Enable DMA // setup AD OpenADC1(ADC_MODULE_ON & ADC_IDLE_CONTINUE & ADC_ADDMABM_ORDER & ADC_AD12B_10BIT & ADC_FORMAT_INTG & ADC_CLK_MPWM & ADC_AUTO_SAMPLING_ON &// trigger source -> MCPWM ADC_SIMULTANEOUS & ADC_SAMP_ON , ADC_VREF_AVDD_AVSS & ADC_SCAN_ON & ADC_SELECT_CHAN_0123 & // ADC_CONVERT_CH0123 & ADC_DMA_ADD_INC_4 & ADC_ALT_BUF_OFF &// ########## need to check ADC_ALT_INPUT_ON, // note: ADC_DMA_ADD_INC_ (i.e. SMPI bits) decide number of blocks, at least number of scan // where as section DMA said they should be cleared(=1) // or, simply use register indirect mode in DMA.AMODE ADC_CONV_CLK_SYSTEM & ADC_CONV_CLK_3Tcy & // 40MHz=25ns -> 75ns ADC_SAMPLE_TIME_16, ADC_DMA_BUF_LOC_4, ENABLE_AN0_ANA & ENABLE_AN1_ANA & ENABLE_AN2_ANA & ENABLE_AN3_ANA & ENABLE_AN4_ANA & ENABLE_AN5_ANA, ENABLE_ALL_DIG_16_31, 0x0, 0x8 // scan setting for ch3,4 ); // set PWM driven timing P1SECMPbits.SEVTDIR = 1; // when count down PWM1CON2bits.SEVOPS = 0b0000; P1SECMPbits.SEVTCMP = 900; // 0-999 SetChanADC1(ADC_CH123_NEG_SAMPLEA_VREFN & ADC_CH123_POS_SAMPLEA_0_1_2 & // ch123= normal input AN012 ADC_CH123_NEG_SAMPLEB_VREFN & ADC_CH123_POS_SAMPLEB_3_4_5, // for setting B, not used ADC_CH0_POS_SAMPLEA_AN3 & ADC_CH0_NEG_SAMPLEA_VREFN & // (ch0 autoselect), default ch3 ADC_CH0_POS_SAMPLEB_AN3 & ADC_CH0_NEG_SAMPLEB_VREFN); // for setting B return 0; } // volatile unsigned int DMAbufferF = 0; void __attribute__((__interrupt__,no_auto_psv)) _DMA0Interrupt(void) { IFS0bits.DMA0IF = 0; //Clear the DMA0 Interrupt Flag /* if(DMAbufferF == 0) { // proc buffer A ADCbufferA[16]=phase; } else { // proc buffer B ADCbufferB[16]=phase; } DMAbufferF ^= 1; LATBbits.LATB4=(DMAbufferF)?1:0;*/ } // input 16bit output 16bit // cos=1-(79/64)x^2+(16/64)x^4-(1/64) int Cosine(int x) { // return x; int neg=0; long a,a2,r; if(x==0x8000) return -32767; if(x<0) x=-x; if(x==0x4000) return 0; if(x>0x4000) { neg=1; /* rev */ x=0x8000-x; } a=x; // a=x, 14Fp a = (a*a +0x1000)>>13; // x^2 ,15FP a2= (a*a +0x4000)>>15; // x^4 ,15FP r = (a*a2+0x4000)>>15; // x^6 ,15FP r+= 79*a; r-=(a2<<4); r=(r+0x20)>>6; // /64, 15fix if(r&0x8000) r=0x7fff; if(r<1) r=1; x=r; if(neg) return -(0x7fff-x); else return 0x7fff-x; }