lunduniversity.lu.se

Computer Science

Faculty of Engineering, LTH

Denna sida på svenska This page in English

Tips and Tricks

...Or the problems I ran into and my solutions to them, so you won't get frustrated going through these yourselves (by Flavius).

Careful with that I/O API

Recently I've been using the xps_gpio core in EDK 12.2 to drive and read signals offchip. It so happens that I used one channel to drive outputs and the second to read inputs. Nevertheless, the outputs also included a reset (active low) signal and some other controls that I intended to use bitwise. So I decided to use the drivers provided by Xilinx to set/clear individual output bits, something like this:

XGpio_DiscreteSet(pGPIO, CHAN, BITMASK);

which is supposed to only set (to 1) the bits given in the BITMASK (according to the API documentation). This looks like the perfect way to just operate on individual signals, and leave the rest untouched. The only problem was that whenever I would set one of them, the others (including my reset signal) were driven low (to 0). Imagine my surprize when I was driving one control pin high and my peripheral would reset!

The thing is, the IP core documentation says that outputs only cannot be read, but only written. Regardless what the current value is, a read will return 0, thus it is impossible to set individual bits using the above function! The effect is the same as writting the BITMASK to the channel using the more common:

XGpio_DiscreteWrite(pGPIO, CHAN, BITMASK);

To solve this you will need to keep the current value in a local variable, operate bitwise on it and the send the whole thing to the GPIO with the above function.

To conclude, the higher level API may sometimes behave strangely, and you must correlate the behavior with the IP core description. You might decide to use low level API, in order to have more control. And one more thing, using Chipscope to monitor signals on the board proved to be essential for this issue.

Your SPI is not my SPI

Usually, when one uses certain protocols, one assumes nothing can go wrong. In fact most protocols allow some degree of configurability that may result in two sides using the same protocol, but being unable to communicate.

We recently got from Digilent the PmodRF1 transceiver modules, and I decided to check whether they work properly with Nexys2. The problem was that the Digilent website provides a reference design for a CEROBOT board (with an AVR). I started rewriting the provided .c code for a Microblaze system using xps_spi core on Nexys2. After a moderate amount of work I got the code compiling for Nexys2, and apparently working properly, until it was time to communicate with the PmodRF1 module through SPI. A closer look at the PmodRF1 documentation showed that the SS (slave select) signal must be kept low for the duration of the SPI operation. My Chipscope trace showed that this did not happen, since after every time I would send a byte through SPI, the SS would go up. It took a bit of further digging to realize that this is the automatic setting, the default for the xps_spi core. Making sure that during the SPI initialization (in software) I would set the XSPI_CR_MANUAL_SSELECT bit in the control register, the problem disappeared and SPI started working. The design can be found here.

To summarize, having a detailed look at the protocol description for both sides in a communication setup is very important. A small mismatch in configuration can cause big problems. Chipscope again proves to be very useful, but serial protocols (SPI, IIC,...) are especially hard to debug due to the long sequences of numbers involved.