[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [microblaze-uclinux] spi and spidev usage
I came up with another way to test out my hardware, since that seems to be where the issue is coming from. Instead of using the _example.c file, I found a lab project that I built for this board that uses SPI.
I took the reference design I'm using for Petalinux, gutted the software project portion, but left the hardware intact. I then added in my software project from the other working design. This way, I could test my Petalinux hardware setup against a known working set of code.
I started with the DAC first. I noticed right away that I didn't have all the filters turned on for my port System Assembly View. I didn't have a OPB_Clk specified for my two OPB SPI devices, so I hooked those into sys_clk_s. That was a major find. However, I couldn't get the DAC to output with my code. I recieved a lot of errors regarding port conflicts with the FLASH and SDRAM components in the design, so I imagine that there's something shared between the DAC and those devices that might be causing the DAC to not work.
I switched to the 3 header pins that I specified for the second SPI interface. After adding delays between the SS lines and MOSI lines in my code, I can see the SS line going low and high! I'm going to scope the SCK and MOSI lines to see if those are working properly as well.
So, I think the missing clk line may fix my Petalinux build as well.
However, now that I look at my code, could I use my code instead of building a new program using xspi.h functions as my Petalinux user application? My code uses the BASEADDR values for each of the SPI registers and I declare each register as a volatile so that I can write directly to the memory. Here are some of my variables and functions:
#define SPICR (*(volatile unsigned long *)(XPAR_OPB_SPI_0_BASEADDR+0x60))
#define SPISR (*(volatile unsigned long *)(XPAR_OPB_SPI_0_BASEADDR+0x64))
#define SPIDTR (*(volatile unsigned long *)(XPAR_OPB_SPI_0_BASEADDR+0x68))
#define SPIDRR (*(volatile unsigned long *)(XPAR_OPB_SPI_0_BASEADDR+0x6C))
#define SPISSR (*(volatile unsigned long *)(XPAR_OPB_SPI_0_BASEADDR+0x70))
#define SPIGIE (*(volatile unsigned long *)(XPAR_OPB_SPI_0_BASEADDR+0x1C))
#define SPIISR (*(volatile unsigned long *)(XPAR_OPB_SPI_0_BASEADDR+0x20))
#define SPIIER (*(volatile unsigned long *)(XPAR_OPB_SPI_0_BASEADDR+0x28))
#define SPI_DAC 0x01
#define SPI_AMP 0x02
#define SPI_ADC 0x04
#define DAC_A 0x00
#define DAC_B 0x01
#define DAC_C 0x02
#define DAC_D 0x03
#define DAC_ALL 0x0F
#define sendDAC(n,val) writeSPI(SPI_DAC, 0x00300000 | (((n)&0x0F)<<16) | (((val)&0x0FFF)<<4), 4)
#define sendAmp(a,b) writeSPI(SPI_AMP, (((b)&0x07)<<4) | ((a)&0x07), 1)
#define readADC() readSPI(2)
int readSPI(unsigned int numBytes);
void writeSPI(unsigned int device, unsigned int value, unsigned int numBytes);
SPISSR=~0; // All Slave Select lines high
SPICR=0x086; // Setup SPI control
SPIGIE=~0; // Enable SPI Interrupts but no specific ones
deviceMask=SPISSR; // Setup device mask = state when all SS lines are high
SIE=XPAR_OPB_SPI_0_IP2INTC_IRPT_MASK; // Enable Interrupt in Intc
writeSPI(unsigned int device, unsigned int value, unsigned int numBytes)
if(numBytes>4) // Maximum send width
while(SPISSR!=deviceMask); // Must wait for last transaction to finish
SPISSR&=~device; // Lower SS line for device
for(; numBytes; --numBytes) // Put bytes into Tx FIFO MSB first
if(SPISR & 0x04)
SPISSR=~0; // Raise SS lines
For some reason I feel that it's been written before on this mailing list that you shouldn't use BASEADDR entries in your user applications for Petalinux, but I can't remember.