I'm trying to communicate with a digtal POT AD5292 and I'm new to SPI and I am having trouble writing to the digital POT. My code seems to get stuck on the first while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } loop
any help would be much appreciated.
my code is attached.
//########################################################################### // // FILE: C1S01710.c // // TITLE: CyberWand II Software //################################################################################################################################################################################################ // Ver | dd mmm yyyy | Who | Description of changes // =====|=============|======|=============================================== // XA | 26 Feb 2012 | S.R. | New File //################################################################################################################################################################################################ #include "DSP2833x_Device.h" //################################################################################################################################################################################################ // Prototype statements for functions found within this file. //################################################################################################################################################################################################ void Gpio_select(void); void InitFlash(void); void ADCconfig(void); void Setup_ePWM(void); void spi_xmit(Uint16 a); void spi_init(void); interrupt void cpu_timer0_isr(void); interrupt void adc_isr(void); // ADC End of Sequence ISR extern unsigned int RamfuncsLoadStart; extern unsigned int RamfuncsLoadEnd; extern unsigned int RamfuncsRunStart; extern void InitSysCtrl(void); extern void InitPieCtrl(void); extern void InitPieVectTable(void); extern void InitCpuTimers(void); extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float); extern void InitAdc(void); //################################################################################################################################################################################################ // Global Variables //################################################################################################################################################################################################ unsigned int ADCIN4A; unsigned int ADCIN5A; //################################################################################################################################################################################################ // main code //################################################################################################################################################################################################ void main(void) { Uint16 sdata; // SPI send data Uint16 rdata; // SPI receive data InitSysCtrl(); // Basic Core Initialization EALLOW; SysCtrlRegs.WDCR = 0x00AF; //0x00AF = Enable Watchdog 0x0068 = Disable Watchdog EDIS; DINT; // Disable all interrupts memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, &RamfuncsLoadEnd - &RamfuncsLoadStart); // Setup program to run in flash InitFlash(); #define BUTTON GpioDataRegs.GPBDAT.bit.GPIO61 DINT; // Disable all interrupts Gpio_select(); // Setup GPIO's Setup_ePWM(); //Setup ePWM signals InitPieCtrl(); // Basic setup of PIE table; from DSP2833x_PieCtrl.c InitPieVectTable(); // Default ISR's in PIE InitAdc(); // Initialize Analog to Digital converter ADCconfig(); //Configure the ADC EALLOW; //Enable access to protected register PieVectTable.TINT0 = &cpu_timer0_isr; PieVectTable.ADCINT = &adc_isr; EDIS; // Disable access to protected register InitCpuTimers(); // Basic setup CPU Timer0, 1 and 2 ConfigCpuTimer(&CpuTimer0, 150, 100); // Initialize Timer0 to 100ms (150 = speed of DSP, 100000 = 100ms, 100 = 100us) PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable interrupt masks, Timer0 connected to group INT1, Bit7 PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // Enable interrupt masks, ADC connected to group INT1, Bit6 IER |= 1; // Enable interrupt core line 1 (INT 1), modify register IER acc EINT; // Enable control interrupts ERTM; // Enable debug interrupts CpuTimer0Regs.TCR.bit.TSS = 0; // Start Timer0 Interrupt sdata = 0x1802; // Send Control Register info to AD5292, Enable update of RDAC GpioDataRegs.GPBSET.bit.GPIO57 = 1; spi_xmit(sdata); // Transmit data while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } // Wait until data is received GpioDataRegs.GPBCLEAR.bit.GPIO57 = 1; rdata = SpiaRegs.SPIRXBUF; // Read sent back data //if(rdata != sdata) // Check against sent data //sdata++; sdata = 0x0500; // Set wiper position of AD5292 to 1/4 scale (256) GpioDataRegs.GPBSET.bit.GPIO57 = 1; spi_xmit(sdata); while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } // Wait until data is received GpioDataRegs.GPBCLEAR.bit.GPIO57 = 1; rdata = SpiaRegs.SPIRXBUF; // Read sent back data int LargeStone_PWM = 0; double LargeStone; while(1) { while(CpuTimer0.InterruptCount == 0); CpuTimer0.InterruptCount = 0; AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // Start ADC conversion EALLOW; SysCtrlRegs.WDKEY = 0x55; // service WD #1 EDIS; LargeStone = ADCIN4A*9.2025; LargeStone += 0.5; LargeStone_PWM = (int)LargeStone; EPwm1Regs.CMPA.half.CMPA = LargeStone_PWM; // Update Duty Cycle based on ADCIN4A } } //################################################################################################################################################################################################ // End of main code //################################################################################################################################################################################################ //################################################################################################################################################################################################ // Timer 0 (100ms) //################################################################################################################################################################################################ void cpu_timer0_isr() { CpuTimer0.InterruptCount++; GpioDataRegs.GPBTOGGLE.bit.GPIO39 = 1; EALLOW; SysCtrlRegs.WDKEY = 0xAA; // service WD #2 EDIS; PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } //################################################################################################################################################################################################ // End Timer 0 (100ms) //################################################################################################################################################################################################ //################################################################################################################################################################################################ // ADC Interrupt //################################################################################################################################################################################################ interrupt void adc_isr(void) { ADCIN4A = AdcMirror.ADCRESULT0; ADCIN5A = AdcMirror.ADCRESULT1; AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //Reset ADC Seq 1 AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //Clear interrupt flag ADC Seq 1 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } //################################################################################################################################################################################################ // End of ADC Interrupt //################################################################################################################################################################################################ //################################################################################################################################################################################################ // GPIO Setup //################################################################################################################################################################################################ void Gpio_select(void) { EALLOW; GpioCtrlRegs.GPAMUX1.all = 0; // GPIO0 ... GPIO15 = General Purpose I/O GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Set GPIO 0 as EPWM1A (PWM for R1 of 4046 Chip) //GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // Set GPIO 1 as EPWM1B (PWM for AGC_START_LEVEL)(not used) GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // Set GPIO 2 as EPWM2A (PWM for R2 of 4046 Chip) GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // Set GPIO 3 as EPWM2B (PWM for AGC_MIN_LEVEL_PWM) GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; // Set GPIO 4 as EPWM3A (PWM for PHASE_COMND_PWM) GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1; // Set GPIO 6 as EPWM4A (PWM for DIG_FREQ_PWM) GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 1; // Set GPIO 8 as EPWM5A (PWM for AGC_COMMAND_PWM) GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 1; // Set GPIO 10 as EPWM6A (PWM for DIG_AGC_PWM) GpioCtrlRegs.GPAMUX2.all = 0; // GPIO16 ... GPIO31 = General Purpose I/O GpioCtrlRegs.GPBMUX1.all = 0; // GPIO32 ... GPIO47 = General Purpose I/O GpioCtrlRegs.GPBMUX2.all = 0; // GPIO48 ... GPIO63 = General Purpose I/O GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 1; // Set GPIO54 as SPISIMOA GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 1; // Set GPIO55 as SPISOMIA GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 1; // Set GPIO56 as SPICLKA GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 1; // Set GPIO57 as SPISTEA GpioCtrlRegs.GPCMUX1.all = 0; // GPIO64 ... GPIO79 = General Purpose I/O GpioCtrlRegs.GPCMUX2.all = 0; // GPIO80 ... GPIO87 = General Purpose I/O GpioCtrlRegs.GPADIR.all = 0; // GPIO0 ... GPIO31 as inputs GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // Set GPIO 11 as output (SYS_ON_3.3) GpioCtrlRegs.GPADIR.bit.GPIO12 = 1; // Set GPIO 12 as output (WD_BONE) GpioCtrlRegs.GPADIR.bit.GPIO22 = 1; // Set GPIO 22 as output (ANA_OR_DIG_AGC) GpioCtrlRegs.GPADIR.bit.GPIO23 = 1; // Set GPIO 23 as output (ANA_OR_DIG_FREQ) GpioCtrlRegs.GPBDIR.all = 0; // GPIO32 ... GPIO63 as inputs /* LED Nets not used, needed more lines so J28A is being used GpioCtrlRegs.GPBDIR.bit.GPIO40 = 1; // Set GPIO 40 as output (LED1) GpioCtrlRegs.GPBDIR.bit.GPIO41 = 1; // Set GPIO 41 as output (LED2) GpioCtrlRegs.GPBDIR.bit.GPIO42 = 1; // Set GPIO 42 as output (LED3) GpioCtrlRegs.GPBDIR.bit.GPIO43 = 1; // Set GPIO 43 as output (LED4) GpioCtrlRegs.GPBDIR.bit.GPIO44 = 1; // Set GPIO 44 as output (LED5) GpioCtrlRegs.GPBDIR.bit.GPIO45 = 1; // Set GPIO 45 as output (LED6) GpioCtrlRegs.GPBDIR.bit.GPIO46 = 1; // Set GPIO 46 as output (LED7) GpioCtrlRegs.GPBDIR.bit.GPIO47 = 1; // Set GPIO 47 as output (LED8) */ GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1; // Set GPIO 52 as output (DSP_RESET_PA) GpioCtrlRegs.GPBDIR.bit.GPIO58 = 1; // Set GPIO 58 as output (DSP_40KHz_ON)(not used on power board C1E01608) GpioCtrlRegs.GPBDIR.bit.GPIO59 = 1; // Set GPIO 59 as output (DSP_20KHz_ON)(not used on power board C1E01608) GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1; // Set GPIO 61 as output (USB_PROG) GpioCtrlRegs.GPBDIR.bit.GPIO37 = 1; // Test point for debugging GpioCtrlRegs.GPBDIR.bit.GPIO39 = 1; // Test point for debugging GpioCtrlRegs.GPCDIR.all = 0; // GPIO64 ... GPIO87 as inputs GpioCtrlRegs.GPCDIR.bit.GPIO64 = 1; // Set GPIO 64 as output (TRCON RED)(Possible Detect Bad Transducer) GpioCtrlRegs.GPCDIR.bit.GPIO65 = 1; // Set GPIO 65 as output (TRCON GRN)(Transducer Connected) // Clear both GPIO 64 and 65 (TRCON RED & TRCON GRN) for Transducer Not Connected (yellow) GpioCtrlRegs.GPCDIR.bit.GPIO66 = 1; // Set GPIO 66 as output (CHKPRB WHT) Check Probe White Light GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1; // Set GPIO 67 as output (CHKPRB RED) Check Probe Error (Red) Light GpioCtrlRegs.GPCDIR.bit.GPIO68 = 1; // Set GPIO 68 as output (FTSW WHT) Footswitch Not Connected White Light GpioCtrlRegs.GPCDIR.bit.GPIO69 = 1; // Set GPIO 69 as output (FTSW GRN) Footswitch Connected Green Light GpioCtrlRegs.GPCDIR.bit.GPIO70 = 1; // Set GPIO 70 as output (LGSTN WHT) Large Stone Not Activated White Light GpioCtrlRegs.GPCDIR.bit.GPIO71 = 1; // Set GPIO 71 as output (LGSTN GRN) Large Stone Activated Green Light GpioCtrlRegs.GPCDIR.bit.GPIO72 = 1; // Set GPIO 72 as output (SMSTN WHT) Small Stone Not Activated White Light GpioCtrlRegs.GPCDIR.bit.GPIO73 = 1; // Set GPIO 73 as output (SMSTN GRN) Small Stone Activated Green Light GpioCtrlRegs.GPCDIR.bit.GPIO74 = 1; // Set GPIO 74 as output (ERROR WHT) Error Not Active White Light GpioCtrlRegs.GPCDIR.bit.GPIO75 = 1; // Set GPIO 75 as output (ERROR RED) Error Active Red Light GpioCtrlRegs.GPCDIR.bit.GPIO76 = 1; // Set GPIO 76 as output (LBLS WHT) White Light for Labels (Always On) /* LED Nets not used, needed more lines so J28A is being used GpioCtrlRegs.GPCDIR.bit.GPIO80 = 1; // Set GPIO 80 as output (LED9) */ EDIS; } //################################################################################################################################################################################################ // End of GPIO Setup //################################################################################################################################################################################################ //################################################################################################################################################################################################ // Setup ePWM //################################################################################################################################################################################################ void Setup_ePWM(void) { //ePWM1A Setup - Sets PWM for R1 on 4046 Chip EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = /1 ->default EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = /2 ->default EPwm1Regs.TBCTL.bit.CTRMODE = 2; // Count up/down mode EPwm1Regs.TBPRD = 37500; // 1 Khz - PWM Signal = TBPRD = .5*fsysclockout/(fpwm*CLKDIV*HSPCLKDIV) // TBPRD = .5*150e6/(1e3*1*2), CLKDIV and HSPCLKDIV are the divisor numbers EPwm1Regs.AQCTLA.all = 0x0060; // Set ePWM1A on CMPA up // Clear ePWM1A on CMPA down. EPwm1Regs.CMPA.half.CMPA = 0; // 100% duty cycle first //ePWM2A Setup - Sets PWM for R2 on 4046 Chip EPwm2Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = /1 ->default EPwm2Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = /2 ->default EPwm2Regs.TBCTL.bit.CTRMODE = 2; // Count up/down mode EPwm2Regs.TBPRD = 37500; // 1 Khz - PWM Signal = TBPRD = .5*fsysclockout/(fpwm*CLKDIV*HSPCLKDIV) // TBPRD = .5*150e6/(1e3*1*2), CLKDIV and HSPCLKDIV are the divisor numbers EPwm2Regs.AQCTLA.all = 0x0060; // Set ePWM2A on CMPA up // Clear ePWM2A on CMPA down. EPwm2Regs.CMPA.half.CMPA = 18750; // 50% duty cycle first //ePWM2B Setup - Sets PWM for AGC Min Level EPwm2Regs.AQCTLB.all = 0x0600; // Set ePWM2B on CMPB up // Clear ePWMBA on CMPB down. EPwm2Regs.CMPB = 18750; // 50% duty cycle first //ePWM3A Setup - Sets PWM for Phase Command EPwm3Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = /1 ->default EPwm3Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = /2 ->default EPwm3Regs.TBCTL.bit.CTRMODE = 2; // Count up/down mode EPwm3Regs.TBPRD = 37500; // 1 Khz - PWM Signal = TBPRD = .5*fsysclockout/(fpwm*CLKDIV*HSPCLKDIV) // TBPRD = .5*150e6/(1e3*1*2), CLKDIV and HSPCLKDIV are the divisor numbers EPwm3Regs.AQCTLA.all = 0x0060; // Set ePWM3A on CMPA up // Clear ePWM3A on CMPA down. EPwm3Regs.CMPA.half.CMPA = 18750; // 50% duty cycle first //ePWM4A Setup - Sets PWM for Digital Frequency EPwm4Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = /1 ->default EPwm4Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = /2 ->default EPwm4Regs.TBCTL.bit.CTRMODE = 2; // Count up/down mode EPwm4Regs.TBPRD = 37500; // 1 Khz - PWM Signal = TBPRD = .5*fsysclockout/(fpwm*CLKDIV*HSPCLKDIV) // TBPRD = .5*150e6/(1e3*1*2), CLKDIV and HSPCLKDIV are the divisor numbers EPwm4Regs.AQCTLA.all = 0x0060; // Set ePWM4A on CMPA up // Clear ePWM4A on CMPA down. EPwm4Regs.CMPA.half.CMPA = 18750; // 500% duty cycle first //ePWM5A Setup - Sets PWM for AGC Command EPwm5Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = /1 ->default EPwm5Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = /2 ->default EPwm5Regs.TBCTL.bit.CTRMODE = 2; // Count up/down mode EPwm5Regs.TBPRD = 37500; // 1 Khz - PWM Signal = TBPRD = .5*fsysclockout/(fpwm*CLKDIV*HSPCLKDIV) // TBPRD = .5*150e6/(1e3*1*2), CLKDIV and HSPCLKDIV are the divisor numbers EPwm5Regs.AQCTLA.all = 0x0060; // Set ePWM5A on CMPA up // Clear ePWM5A on CMPA down. EPwm5Regs.CMPA.half.CMPA = 18750; // 50% duty cycle first //ePWM6A Setup - Sets PWM for AGC Command EPwm6Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = /1 ->default EPwm6Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = /2 ->default EPwm6Regs.TBCTL.bit.CTRMODE = 2; // Count up/down mode EPwm6Regs.TBPRD = 37500; // 1 Khz - PWM Signal = TBPRD = .5*fsysclockout/(fpwm*CLKDIV*HSPCLKDIV) // TBPRD = .5*150e6/(1e3*1*2), CLKDIV and HSPCLKDIV are the divisor numbers EPwm6Regs.AQCTLA.all = 0x0060; // Set ePWM6A on CMPA up // Clear ePWM6A on CMPA down. EPwm6Regs.CMPA.half.CMPA = 18750; // 50% duty cycle first } //################################################################################################################################################################################################ // End ePWM Setup //################################################################################################################################################################################################ //################################################################################################################################################################################################ // ADC Config //################################################################################################################################################################################################ void ADCconfig() { AdcRegs.ADCTRL1.all = 0; AdcRegs.ADCTRL1.bit.ACQ_PS = 7; // 8 x ADC-Clock AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 0 = Dual Sequencer Mode, 1 = cascaded sequencer AdcRegs.ADCTRL1.bit.CPS = 0; // divide by 1 AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Single Run Mode AdcRegs.ADCTRL2.all = 0; AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt //AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // Start by ePWM trigger - use software start instead AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0; // Interrupt after every EOS (end of sequency) AdcRegs.ADCTRL3.bit.ADCCLKPS = 6; // ADC clock: FCLK = HSPCLK / 2 * ADCCLKPS // HSPCLK = 150MHz (see DSP2833x_SysCtrl.c) // FCLK = 12.5 MHz AdcRegs.ADCMAXCONV.all = 1; // Two conversions from Sequencer 1 (Number of conversions minus 1) AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 4; // ADCINA4 - Temp ADC in for AGC adjustment (large stone) AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 5; // ADCINA5 - Temp ADC in for AGC adjustment (small stone) /*Can't use because all ePWM units are being used EPwm2Regs.TBCTL.bit.CLKDIV = 0; // Divide by 1 EPwm2Regs.TBCTL.bit.FREE_SOFT = 2; // Ignore emulation suspend EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // Divide by 1 EPwm2Regs.TBCTL.bit.SWFSYNC = 0; // No action EPwm2Regs.TBCTL.bit.SYNCOSEL = 3; // Sync out disabled EPwm2Regs.TBCTL.bit.PHSEN = 0; // No phase EPwm2Regs.TBCTL.bit.PRDLD = 0; // Load on CTR = 0 EPwm2Regs.TBCTL.bit.CTRMODE = 0; // Count up mode EPwm2Regs.TBPRD = 2999; // TBPRD = Tpwm/(HSPCLKDIV * CLKDIV * Tsysclk) = 50e3/(1*1*150e3^-1) EPwm2Regs.ETPS.all = 0; // Clear all bits EPwm2Regs.ETPS.bit.SOCAPRD = 1; // Enable SOCA on first event EPwm2Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA EPwm2Regs.ETSEL.bit.SOCASEL = 2; // Generate SOCA on PRD event */ } //################################################################################################################################################################################################ // End ADC Config //################################################################################################################################################################################################ //################################################################################################################################################################################################ // SPI Init //################################################################################################################################################################################################ void spi_init() { SpiaRegs.SPICCR.all =0x004F; // Reset on, falling edge, 16-bit char bits SpiaRegs.SPICTL.all =0x0006; // Enable master mode, normal phase, // enable talk, and SPI int disabled. SpiaRegs.SPIBRR =0x007F; SpiaRegs.SPICCR.all =0x00CF; // Relinquish SPI from Reset SpiaRegs.SPIPRI.bit.FREE = 1; // Set so breakpoints don't disturb xmission } //################################################################################################################################################################################################ // End SPI Init //################################################################################################################################################################################################ //################################################################################################################################################################################################ // SPI Transmit //################################################################################################################################################################################################ void spi_xmit(Uint16 a) { SpiaRegs.SPITXBUF=a; } //################################################################################################################################################################################################ // End SPI Transmit //################################################################################################################################################################################################