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
//################################################################################################################################################################################################






