[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [microblaze-uclinux] spi and spidev usage
Hi everyone,
There are three different parts to my email.
First, I finally got my SPI device working! I want to thank Carsten for providing me with the final bit of debug help that helped me find the issue.
I removed my SPI DAC and concentrated solely on my SPI that was mapped to three pins, which are easier to debug the SCLK, MOSI, and SS lines using a scope.
Based on Carsten's advice, I took a copy of my Petalinux reference design, stripped out the software needed to run linux but kept the hardware. That way, I could test the hardware to make sure it was set up correctly without having to always redo the kernel image and upload it to my board.
Doing this, I found that I was missing a CLK and RST signal on my SPI module. I missed these because my connection filter in EDK wasn't set to show all connection. After fixing this and testing it with my code with petalinux, I made the same change in the Petalinux reference design and tried booting Petalinux.
Success! I got nothing at first again (SCLK low and SS/MOSI high). However, using my code that I posted in my last email, my SPI initialized correctly and I could see the clock, data, and SS on the scope! I switched the constants in my code shown with those in linux/autoconf.h.
Second, my next issue is the DAC. It refuses to turn on, even in my reference design that doesn't use Petalinux software, so it must be a hardware problem. Does anybody have experience with contention issues with SPI? I noticed that I need to disable the flash PROM on my Spartan 3E when trying to access the DAC. That didn't seem to help. I also added the DAC CLR pin and tied it to ground, but that usually causes PAR to fail. Either way, I'm guessing I can't be disabling the flash when using Petalinux, since u-boot needs it.
My third question is for Dr. Williams. I found a document on creating a custom uCLinux design in the EDK here:
http://www.itee.uq.edu.au/~wu/downloads/uClinux_ready_Microblaze_design.pdf
Is there an updated version of this? I figured I try to make a custom design since I seem to be having timing and PAR issues when I simply add the DAC CLR pin.
Thanks everyone for all the help.
Matt
On Thu, Apr 2, 2009 at 22:55, Matt Staniszewski <matt.staniszewski@xxxxxxxxx> wrote:
>
> Hi Carsten,
>
> 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)
>
> void initSPI(void);
> void clearSPI(void);
> int readSPI(unsigned int numBytes);
> void writeSPI(unsigned int device, unsigned int value, unsigned int numBytes);
>
> ...
>
> void
> initSPI(void)
> {
> int i;
> 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
> }
>
>
> ...
>
> void
> writeSPI(unsigned int device, unsigned int value, unsigned int numBytes)
> {
> int i;
>
> if(numBytes>4) // Maximum send width
> numBytes=4;
>
> 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
> {
> SPIDTR=(value>>((numBytes-1)*8))&0xFF;
> }
> for(;;)
> {
> if(SPISR & 0x04)
> break;
> }
> 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.
>
> Thanks.
>
> Matt