Sorry, you need to enable JavaScript to visit this website.

PS SPI Pmod JE7 Hardware system

Zedboard forums is currently read-only while it under goes maintenance.

12 posts / 0 new
PS SPI Pmod JE7 Hardware system

Hello everyone,

I'm in the process of interfacing my Avnet CC3000-Pmod Compatible Wi-Fi Adapter to the ZedBoard via the JE7 Pmod header, which is connected to the PS.

At first I thought this should be a simple thing, since creating a hardware system that includes SPI was so simple, but ...

When I try to use the SPI device (via the SpiPs device driver), I am stuck in the XSpiPs_PolledTransfer() function, waiting for the status register flag that indicates the transmission has finished (XSPIPS_IXR_TXOW_MASK). The reason that the flag never comes, is that I read nonsense values from the register (a 0x2 in this case).
Then I added the XSpiPs_SelfTest() function, which failed at the very first register read. So I'm guessing there is something wrong with my hardware design.

I got the Zynq IP setup & configured as follows:

| ZYNQ DDR +-----> DDR
| USBIND_0 +-
-+ TTC0_CLK0_IN M_AXI_GP0 +-
| | FCLK_CLK0 +--+
| | FCLK_RESET0_N +- |
| +--------------------------------+ |

SPI 1: MIO 10 .. 15
SS[1] IO MIO 14
SPI 1 MIO 10 mosi
SPI 1 MIO 11 miso
SPI 1 MIO 12 sclk
SPI 1 MIO 14 ss[1]

The clock is set to ca. 16MHz, which is the maximum the CC3000 can take.

Has anybody had any experience with the CC3000 Adapter, Pmod or SPI on the ZedBoard? I'd be very glad for any help, since I'm pretty much stuck here.

With best regards,

Hi Darius

Hi Darius

If you want to be able to work on the lowest level of SPI by bitbanging, then I can help!

I did not manage to get SPI 1 to talk to the JE7 pins, however I could do it by enabling GPIO.. I used this to enable writing to an SD card in SPI mode, over the GPIO pins 40-47 (SD card slot)

( )

#define MIO_09_JE8 9
#define MIO_10_JE2 10
#define MIO_11_JE3 11
#define MIO_12_JE4 12
#define MIO_13_JE1 13
#define MIO_14_JE9 14
#define MIO_15_JE10 15

#define PIN_HIGH 1
#define PIN_LOW 0

int main(void)
XGpioPs Gpio;
XGpioPs_Config * ConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);

//set JE1 to output -> pin high
XGpioPs_SetDirectionPin(&Gpio, MIO_13_JE1, MIO_OUTPUT);
XGpioPs_WritePin(&Gpio, MIO_13_JE1, PIN_HIGH);

//set JE1 to output -> pin low
XGpioPs_SetDirectionPin(&Gpio, MIO_13_JE1, MIO_OUTPUT);
XGpioPs_WritePin(&Gpio, MIO_13_JE1, PIN_LOW);

//set JE2 to input -> read pin
XGpioPs_SetDirectionPin(&Gpio, MIO_42_SD_P7_MISO, MIO_INPUT);

//etc etc...

return 0;

Does that help at all?


Pin Matching

When looking at several Pmods I have with the Maxim peripheral kit, I was surprised to see no standard for the SPI pins (or I2C pins) on the PMODs. The only pins that seem to be standard are power (Vcc on pins 6 and 12) and ground (pins 5 and 11)

As such, I took a quick look at the pins and matching them between the FPGA and schematics for the JE Pmod, the only one that connects directly to the PS through the MIO.

From the MIO pin SPI pin links, schematic for the FPGA on the Zedboard, and schematic for the CC3000-Pmod, I get the following:

CC3000 Pmod pin; JE pin; FPGA pin; MIO Pin using SP1
SPI_CS ; JE1 ; A6 ; PS_MIO13 ; ss0
SPI_DI ; JE2 ; G7 ; PS_MIO10 ; mosi
SPI_DO ; JE3 ; B4 ; PS_MIO11 ; miso
SPI_CLK ; JE4 ; C5 ; PS_MIO12 ; ck
SPI_IRQ ; JE7 ; G6 ; PS_MIO0 ; ???

So it looks like the IRQ needs to be connected to PS_MIO0, which isn't a normal SPI pin, and only listed as a cs1. I see in XPS that MIO0 can be mapped as a GPIO, and maybe it can connect that way? Or maybe you can find another way to map it to the IRQ directly in the MIO setup.

Personally, I'd use one of the PL Pmods that I can wire the way I want using the EMIO. But maybe you can figure out this last pin?


SPI Interface

Looking more at the Maxim Pmod implementation, I now note they do not use the MIO or EMIO for anything other than a single UART for communication (over the USB).

Rather than route the SPI through the MIO or EMIO, it's routed through the General Purpose Master AXI Interface, with the lines defined to have SPI properties.

Therefore, the MIO on JE doesn't work for the Maxim Pmods, as the Maxim Pmods only work on the PL side, with Pmod connectors JA, JB, JC, and JD. The MIO connected to JE is not used as it's too difficult to reconfigure depending on the module, which is best done with Verilog HDL in the PL logic side.

The point is that the GP Master AXI Interface may be the best way to configure this SPI interface as well, through one of the Pmods (JA, JB, JC, JD) connected to the PL side.

Alternatively, defining GP ports on the MIO pins connecting to JE, with software redefinition as suggested by kbarlee, could be another way to go if you're willing to do the line configuratiosn on the software PS side instead of the Verilog PL side. It could be you only need to reconfigure the IRQ on JE7 in software as the other pins look OK. (Hmmm, are mosi and miso reversed for the PMOD viewpoint?)

Furthermore, I just now noted the PMOD pin 1 for the CC3000 is ss0 or chip select enable, and connects to PS_MIO13 on the Zynq chip. However, you look to be manipulating PS_MIO14 (or ss[1]) instead of MIO13 (or ss[0]) that's actually connected to the PMOD on pin 1. This is an easy fix, connecting the IRQ is another matter.

Thank you for your helpful

Thank you for your helpful replies!

Hello Kenny,
Writing my own SPI implementation to work via GPIO would be a practicable solution. Thanks for the input! I will resort to this if I cannot find a different solution.

Hello Larry,
I am controlling the CS signal of the CC3000 via GPIO, because of this problem with ss[0]: I have connected IRQ and PWR_EN the same way and both are working as intended. I can initialize the CC3000 by setting CS and then PWR_EN high and it reacts as intended by pulling IRQ low, which is captured by an GPIO interrupt.

The real problem is that the registers cannot be read correctly. This manifests in the following symptoms:
a) The XGpioPs_SelfTest fails at the first register read.
b) When not performing the SelfTest and transmitting data, the status register reads 0x2, which cannot be right, comes up as all 0s on the memory monitor and the TX fifo empty flag is never set (or read).

My suspicion is that there is something wrong with the configuration of my hardware system, since my software is almost identical to the Xilinx examples and the problem is something with the registers, as described above. Also the docu of the self test function says it's there to check for errors in the hardware build.

I'd prefer to connect the Adapter to the PS, not the PL. I'm a bit under time pressure and not yet worked with Xilinx' FPGA tools (except for creating purely PS-based hardware systems).

Thank you both a lot for your replies!


Another Pin

Thanks for the link to AR47511. Very interesting. Looks like you're not using the suggested fix of connecting SS0 to EMIO instead of MIO, needed to tie the input side of SS0 to Vcc to prevent unwanted SPI interrupts. I gather you're instead bypassing that connection altogether by using an GPIO, which seems to be a good work around. Yet you're using the rest of the SPI interface. Doesn't that article say you'll still have interrupt reset and hang up problems using the SPI controller as long as that SS0 input isn't tied high (through the EMIO patch)? Do you do that?

I realized I left out the PWR_EN pin in my table above. So for future reference, I complete it below. From the schematic for the CC3000-Pmod, schematic for the FPGA on the Zedboard,and the MIO's pin definitions,I get the following line assignments:

CC3000 Pmod pin; JE pin; FPGA pin; MIO Pin using SP1
SPI_CS ; JE1 ; A6 ; PS_MIO13 ; ss0
SPI_DI ; JE2 ; G7 ; PS_MIO10 ; mosi
SPI_DO ; JE3 ; B4 ; PS_MIO11 ; miso
SPI_CLK ; JE4 ; C5 ; PS_MIO12 ; ck
SPI_IRQ ; JE7 ; G6 ; PS_MIO0 ; ???
PWR_EN ; JE10 ; E6 : PS_MIO15; ss2

I understand you're connecting three of the lines, CS (or SS0), IRQ, and PWR_EN by GPIO routing instead, and mapping those signals back into the SPI controller on the software driver side.

I suspect that you're getting close. It seems you only have one snag but a lot of other things are working.

At this point it's trial and error with the system you've got in hand, and not getting stuck into one mode of thinking, and look around other places. One time I had a UART interface I spent a week on debugging, thinking I had a wrong protocol. I finally found a wire was crossed. I had double checked the connection early on, but a tech had also crossed wires in the test cable I used to check! Things like that drive you nuts, but it taught me to don't fixate on one thing. Go back to the beginning and triple check absolutely everything carefully.

You are right, Larry. I have

You are right, Larry. I have not yet bound the ss[0] signal to vcc. This could definitively be the problem! I cannot figure out how to connect it to vcc, though.
I have routed it to the EMIO, but I don't know where to go from there. Can you give me hint how this is done in Vivado?

Continue to Step 2


The way to connect SS input to VCC is indicated in step 2 of the link you provided. (You already did step 1 in routing to EMIO.) You need to edit the hardware description *.mhs file with a simple text editor. Just double click on it in your project tree. Make a backup before adding the lines below. If you corrupt this file, it won't open your project. (Guess how I know.)

From :

When interfacing via MIO or EMIO:

1. Do not enable the SPI SS0 signal on any of the MIO pins.

2. Configure the EMIO SPI SS0 port signal in the MHS file so its an output and the SS input is tied to net_vcc:

PORT processing_system7_0_SPI0_SS_O_pin = processing_system7_0_SPI0_SS_O, DIR = O
PORT SPI0_SS_O = processing_system7_0_SPI0_SS_O
PORT SPI0_SS_I = net_vcc

Other checks

Oh, and check to make sure the above example MHS entry is the right syntax name for that SPI0 port as you created in your system.

Also check that the SS0 input and output are not already defined somewhere else in the MHS file before making a new entry. If so, just edit the existing entry instead.

Thanks for the thorough

Thanks for the thorough explanation, but I'm using Vivado 2013.2, which does not have an MHS file in the project directory.

I found one under C:\Xilinx\Vivado\2013.2\ids_lite\ISE\data\zynqconfig\ps7_internals\ps7_instance.mhs, but it says that it's the "Manually created PS7 Internal peripherals for ps7 instance mhs generation". I can't find any generated mhs files, except in ISE projects, which leads me to the conclusion that Vivado doesn't use MHS files.

I guess I'll switch back to ISE and report back.

Thank you very much for all your help, Larry!

any luck?

Hi, I'm having the same problem. So I was wondering if you managed to solve this issue?
I was originally using Vivado but changed to PlanAhead so that I could edit the MHS file.
I used the default Zynq 702 board settings, removed all peripherals except the SD, UART and SPI0. Then I edited the MHS file according and generated the hardware file.
In my software, the SPI status register is still 0x02. If you managed to get it to work, could you please tell me if you did anything differently?

Status update

Hi, i'm a coworker of Darius. He is currently working on another project and i got assigned to work on the CC3K. I just stumbled over this thread and thought i give you a little heads-up what's been happening in the last months.

In short: yes, we could solve our problems with the SPI, but not without swapping parts out.

Long version:
First try to fix the SPI was to pull the SPI_SS_I signal to high in the top-level HDL-file (because Vivado doesn't have this MHS anymore). With that we didn't experience any resets on the SPI anymore. After that we had the problem that apparently the Zynq-SPI could not handle the delays dictated by the CC3K first-write-sequence while the slave select is active the whole time. To fix this, we abandonned using the slave select of the SPI-Core and used GPIO instead as slave select. When we did this we were finally able to send commands to the CC3K via SPI, but ran into the next problem almost imediately: when the CC3K answers to the commands, we could see the correct answers going over the SPI wires but the RX FIFO of the SPI core contained just 0xFF, over and over again. That was the point where we decided to ditch the Zynq SPI and started using the AXI-SPI IP core from Xilinx. At the beginning this core gave us some troubles too, like not being able to provide a stable SPI clock, but we could fix that by changing the ref_clk settings (we now use a ~32 MHz ref clk for the core and that gives us a ~16MHz SPI clk). With the AXI-SPI and the GPIOs (for en, irq and ss) we were finally able to correctly communicate with the CC3K via SPI.

Current status:
Right now, bind(), listen(), accept() and recv() work and we're able to use the ZedBoard as a server. But we still can't use the ZedBoard as a client because connect() does not work. At the moment, we're trying to figure out what goes wrong there. We're using our own drivers, not the ones provided by TI, so maybe we still have a bug in there somewhere. But trying to use the CC3K with an LX9 board and the reference design by avnet (including the drivers by TI) resulted in the same situation: we were able to use it as a server but not as a client because connect() never returned. Any suggestions to fix this would be appreciated.

Well, that's it up to this point, hope i could help you out a little!

Best regards,