DSPRelated.com
Forums

ADSP21161N SPI issue

Started by cron...@ananzi.co.za August 28, 2009
Hi All,
I have read the previous posts stating that SPTINT and SPRINT need to be initialised to work as well as requiring a dummy read for every write but my SPI still seems to not be working. I am trying to program the AD1836 codec through SPI on my ADSP21161N EZ KIT Lite, has anyone managed to do this before? I cant use the SPI emulation with the SPORTs in my application so I require SPI. Analog Devices has sample code that comes with EE-194 for SPI programing but its terribly buggy (no dummy reads), I wrote my own code that should work, infact when I measure on an oscilloscope I get what im expecting but the codec refuses to work. The codec works fine with SPI emulation so its still working. Im also trying to program a SPI LCD that refuses to work so Im assuming im making the same mistake between both of them, if someone could please browse through my code and tell me if they spot anything wrong it would be greatly appreciated! or if someone has done this before some help would be great, thanks in advance. heres my SPI function I call to setup the codec:

.segment /pm seg_dmda;

.var powerdown_AD1836[4] = DAC_CONTROL1 | WRITE_REG | 0x004,
DAC_CONTROL1 | WRITE_REG | 0x004,
ADC_CONTROL1 | WRITE_REG | 0x080,
ADC_CONTROL1 | WRITE_REG | 0x080;

.var spi_tx_buf[21] DAC_CONTROL1 | WRITE_REG | 0x000,
DAC_CONTROL1 | WRITE_REG | 0x000,
DAC_CONTROL2 | WRITE_REG | 0x000,
DAC_VOLUME0 | WRITE_REG | 0x3FF,
DAC_VOLUME1 | WRITE_REG | 0x3FF,
DAC_VOLUME2 | WRITE_REG | 0x3FF,
DAC_VOLUME3 | WRITE_REG | 0x3FF,
DAC_VOLUME4 | WRITE_REG | 0x3FF,
DAC_VOLUME5 | WRITE_REG | 0x3FF,
ADC_CONTROL1 | WRITE_REG | 0x000,
ADC_CONTROL1 | WRITE_REG | 0x000,
ADC_CONTROL3 | WRITE_REG | 0x000,
ADC_CONTROL2 | WRITE_REG | 0x380,
ADC_CONTROL2 | WRITE_REG | 0x380,
ADC0_PEAK_LEVEL | READ_REG | 0x000,
ADC1_PEAK_LEVEL | READ_REG | 0x000,
ADC2_PEAK_LEVEL | READ_REG | 0x000,
ADC3_PEAK_LEVEL | READ_REG | 0x000,
ADC_CONTROL1 | READ_REG | 0x000,
ADC_CONTROL2 | READ_REG | 0x000,
ADC_CONTROL3 | READ_REG | 0x000;

// variable to hold the AD1836 value
.var value;
// dummy variable to hold the data received from the SPI receiver.
.var dummy;

.segment /pm seg_pmco;

// Initializes the AD1836A using SPI port and Flag 0.
_Program_AD1836_regs_via_SPI:

// Setup the SPI port to access AD1836A
// Flush the SPI transceive FIFOs
r0 = 0;
dm(SPICTL) = r0;

// Configure the Flag 0 as output.
bit set mode2 FLG0O;
nop;

// Now configure the SPI control register
r0 = SPIEN|SPI_MS|FLS0|BAUDR8|WL16|CPHASE|DCPH0|CP|DF|SPTINT|SPRINT|NSMLS;
dm(SPICTL) = r0;

nop;
nop;
nop;

// Store the address of the array which holds the data being sent to the AD1836A
// and the values needed to be initialized to the DAG registers

i0 = powerdown_AD1836;
m0 = 1;
l0 = 0;

// Write the value to the specific address in the loop.
lcntr = 4, do init_loop1 until lce;

r0 = dm(i0,m0);
dm(value) = r0;

call _WriteAD1836A;
nop;
nop;
nop;
init_loop1: nop;

// Flush the SPI transceive FIFOs and temporarily disable SPI
r0 = 0;
dm(SPICTL) = r0;

Wait_Approx_1s:
lcntr = 30000, do waitloop until lce;
nop;
nop;
nop;
waitloop: nop;

// Now configure the SPI control register
r0 = SPIEN|SPI_MS|FLS0|BAUDR8|WL16|CPHASE|DCPH0|CP|DF|SPTINT|SPRINT|NSMLS;
dm(SPICTL) = r0;

nop;
nop;
nop;

// Store the address of the arrays which hold the register address and the
// values need to be initialized to the DAG registers

i0 = spi_tx_buf;
m0 = 1;
l0 = 0;

// Write the value to the specific address in the loop.
lcntr = 21, do init_loop2 until lce;

r0 = dm(i0,m0);
dm(value) = r0;

call _WriteAD1836A;
nop;
nop;
nop;
init_loop2: nop;

// Disable the SPI Port and flush the transceive FIFOs
r0 = 0;
dm(SPICTL) = r0;

leaf_exit;
_Program_AD1836_regs_via_SPI.end: rts;

_WriteAD1836A:

// clear flag 0 to select the SPI slave port.
bit clr FLAGS FLG0;
nop;

// send the value to the AD1836
r0 = dm(value);
call _TxAD1836SPI;
// set flag 0 to deselect the SPI slave port.
bit set FLAGS FLG0;
nop;

rts;

// Transmits the data available on r0 to the AD1836 using SPI port
_TxAD1836SPI:
//write to the SPITX register to start transfer
dm(SPITX) = r0;

//wait for 100 cycles
lcntr = 100, do delay until lce;
delay: nop;

// poll the SPIF bit of the SPISTAT register and wait for the transfer to complete.
r2 = SPIF;
poll_spistatus:
r1 = dm(SPISTAT);
r1 = r1 and r2;
if eq jump poll_spistatus;

//wait for 100 cycles
lcntr = 100, do delay1 until lce;
delay1: nop;

// dummy read to receive the data on the SPI receiver.
r2 = dm(SPIRX);
dm(dummy) = r2;

rts;
On Fri, 28 Aug 2009, c...@ananzi.co.za wrote:

> Hi All,
> I have read the previous posts stating that SPTINT and SPRINT need to
>be initialised to work as well as requiring a dummy read for every write
>but my SPI still seems to not be working. I am trying to program the
>AD1836 codec through SPI on my ADSP21161N EZ KIT Lite, has anyone managed
>to do this before? I cant use the SPI emulation with the SPORTs in my
>application so I require SPI. Analog Devices has sample code that comes
>with EE-194 for SPI programing but its terribly buggy (no dummy reads), I
>wrote my own code that should work, infact when I measure on an
>oscilloscope I get what im expecting but the codec refuses to work. The
>codec works fine with SPI emulation so its still working. Im also trying

Use the scope and compare the differences between what works and what
doesn't. Your code may be fine, but there might be timing tolerances that
the simulation can't even come close to but the SPI is just running too
fast for the codec.

Patience, persistence, truth,
Dr. mike
Hi Dr. Mike,

Thanks for the response, I measured the other method of programing the codec on the oscilloscope as you suggested and it worked well, I was able to exactly replicate the signals to the codec. The codec still refused to work! I then searched on the analog site and found that there was an SPI anomally for the earlier releases of the codec and I replaced the IC with a newer released codec and now its working.

Regards,
Allan