DSPI | |
---|---|
Quick Look | |
Hardware | (External hardware) |
Include | DSPI.h |
The DSPI library provides support for any number of hardware SPI ports.
The Digilent SPI (DSPI) library provides an alternative interface for accessing SPI ports to the standard chipKIT SPI library (SPI). The DSPI library provides access to all hardware SPI ports supported by the board in use and provides the ability to perform buffered and interrupt driven transfers.
The DSPI library only supports operation as an SPI master device and can’t be used to access SPI devices that require the data to be shifted to the right (least significant bit first). In shifting is required the SoftSPI library can be used instead.
The DSPI library uses hardware peripherals on the processor and therefore the MOSI (SDO), MISO (SDI), and SCK pins are defined in the Board_Defs.h for the processor you are using. A default SS value is also included in Board_Defs.h but this can be overridden with the overloaded begin(uint8_t pinT) function or setPinSelect(uint8_t pin) function. As with the other SPI libraries the MOSI, MISO and SCK pins are common across all devices and the SS pin allows the master to select the slave devices to communicate with.
Label | Name | Definition |
---|---|---|
MOSI (SDO) | Master Out Slave In | Used for sending data from the master to the slave |
MISO (SDI) | Master In Slave Out | Used for sending data from the slave to the master |
SCK | Serial Clock | Syncronizes data transmission. |
SS | Slave Select | A pin to signal to a chip that the master is trying to communcate with it. |
This demo blinks LED3 and LED4 on boards that have four LEDs, and at the same time, blinks the two LEDs on the PmodJSTK (2-axis joystick). It reads the state of the two buttons on the PmodJSTK, and turns LED1 and LED2 on and off based on the button state. The X and Y joystick position is read and placed into global variables, but not used by the demo itself.
/************************************************************************/
/* */
/* PmodJSTKDspi -- Illustrate Use of DSPI Library with PmodJSTK */
/* */
/************************************************************************/
/* Author: Gene Apperson */
/* Copyright 2011, Digilent Inc, All rights reserved. */
/************************************************************************/
/*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/************************************************************************/
/* Module Description: */
/* */
/* This example illustrates using the Digilent DSPI library to */
/* communicate with a PmodJSTK from a Cerebot MX4cK. */
/* */
/* This demo blinks LED3 and LED4 on boards that have four LEDs, and at */
/* the same time, blinks the two LEDs on the PmodJSTK. It reads the */
/* state of the two buttons on the PmodJSTK, and turns LED1 and LED2 on */
/* and off based on the button state. The X and Y joystick position is */
/* read and placed into global variables, but not used by the demo */
/* itself. */
/* */
/************************************************************************/
/* Revision History: */
/* */
/* 10/27/2011(GeneApperson): Created */
/* */
/************************************************************************/
/* ------------------------------------------------------------ */
/* Include File Definitions */
/* ------------------------------------------------------------ */
/* Pull in the DSPI library
*/
#include <DSPI.h>
/* ------------------------------------------------------------ */
/* Local Type Definitions */
/* ------------------------------------------------------------ */
#define cntBlinkInit 50000
/* ------------------------------------------------------------ */
/* Global Variables */
/* ------------------------------------------------------------ */
int cntBtnBlink;
uint8_t fbLedPmod;
uint8_t fbBtnPmod;
int xcoPmod;
int ycoPmod;
int fLed3;
int fLed4;
/* Unlike many chipKIT/Arduino libraries, the DSPI library doesn't
** automatically instantiate any interface objects. It is necessary
** to declare an instance of one of the interface objects in the
** sketch. This creates an object to talk to SPI port 0. Similarly,
** declaring a variable of type DSPI1, DSPI2, DSPI3, etc. will create
** an object to talk to DSPI port 1, 2, or 3.
*/
DSPI0 spi;
/* ------------------------------------------------------------ */
/* Local Variables */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* Forward Declarations */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* Procedure Definitions */
/* ------------------------------------------------------------ */
/*** setup
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Initialize the system.
*/
void setup() {
DeviceInit();
AppInit();
}
/* ------------------------------------------------------------ */
/*** loop
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Main application loop.
*/
void loop() {
AppTask();
}
/* ------------------------------------------------------------ */
/*** DeviceInit
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Perform basic board/device level initialization.
*/
void DeviceInit() {
/* Set the LED pins to be outputs. Some boards support more
** than two LEDs. On those boards, also blink the additional
** LEDs.
*/
pinMode(PIN_LED1, OUTPUT);
pinMode(PIN_LED2, OUTPUT);
#if defined(PIN_LED3)
pinMode(PIN_LED3, OUTPUT);
#endif
#if defined(PIN_LED4)
pinMode(PIN_LED4, OUTPUT);
#endif
/* Initialize the SPI port.
** Setting the SPI clock speed to 250khz will satisfy the
** PmodJSTK requirement of having at least 6us of delay between
** bytes sent.
*/
spi.begin();
spi.setSpeed(250000);
}
/* ------------------------------------------------------------ */
/*** AppInit
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Perform application level initialization. Call the various
** init functions to initalize the application subsystems.
*/
void AppInit() {
/* Init program state variables.
*/
cntBtnBlink = cntBlinkInit;
fbLedPmod = 0x01;
fbBtnPmod = 0;
xcoPmod = 0;
ycoPmod = 0;
/* Start with LED3 on and LED4 off
*/
fLed3 = HIGH;
fLed4 = LOW;
}
/* ------------------------------------------------------------ */
/*** AppTask
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Perform main application functions. This is called once
** each time through the main program loop.
*/
void AppTask() {
unsigned int dwBtn;
/* Check the state of button 1 and set LED 1 accordingly
*/
dwBtn = fbBtnPmod & 0x01;
if (dwBtn == 0) {
digitalWrite(PIN_LED1, LOW);
} else {
digitalWrite(PIN_LED1, HIGH);
}
/* Check the state of button 2 and set LED 2 accordingly
*/
dwBtn = fbBtnPmod & 0x02;
if (dwBtn == 0) {
digitalWrite(PIN_LED2, LOW);
} else {
digitalWrite(PIN_LED2, HIGH);
}
/* Check if it is time to blink LED3 & LED4 and update
** the joystick.
*/
cntBtnBlink -= 1;
if (cntBtnBlink == 0) {
#if defined(PIN_LED3)
digitalWrite(PIN_LED3, fLed3);
fLed3 = (fLed3 == HIGH) ? LOW : HIGH;
#endif
#if defined(PIN_LED4)
digitalWrite(PIN_LED4, fLed4);
fLed4 = (fLed4 == HIGH) ? LOW : HIGH;
#endif
/* Toggle the setting for the LEDs on the joystick.
*/
fbLedPmod ^= 0x03;
/* Update the joystick.
*/
ReadJoystick(fbLedPmod, &fbBtnPmod, &xcoPmod, &ycoPmod);
cntBtnBlink = cntBlinkInit;
}
}
/* ------------------------------------------------------------ */
/*** ReadJoystick
**
** Parameters:
** fbLed - LED state to set
** pfbBtn - variable to receive button state
** pxco - pointer to var to receive x coordinate
** pyco - pointer to var to receive y coordinate
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Read the current position of the joystick and buttons.
*/
void ReadJoystick(uint8_t fbLed, uint8_t * pfbBtn, int * pxco, int * pyco) {
uint8_t rgbSnd[5];
uint8_t rgbRcv[5];
int ib;
/* Initialize the transmit buffer.
*/
for (ib = 0; ib < 5; ib++) {
rgbSnd[ib] = 0x50 + ib;
}
rgbSnd[0] = fbLedPmod + 0x80; //first byte sent sets the LEDs
/* Bring SS low to begin the transaction.
*/
spi.setSelect(LOW);
/* Wait 10us for Pmod to become ready
*/
Delay10us();
/* Send the data to the Pmod and get the response.
*/
spi.transfer(5, rgbSnd, rgbRcv);
/* Bring SS high to end the transaction.
*/
spi.setSelect(HIGH);
/* Set up the return values.
*/
*pfbBtn = rgbRcv[4] >> 1;
*pxco = (uint16_t)((rgbRcv[1] << 8) + rgbRcv[0]);
*pyco = (uint16_t)((rgbRcv[3] << 8) + rgbRcv[2]);
}
/* ------------------------------------------------------------ */
/*** Delay10us
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Delay loop for ~10uS
*/
void Delay10us() {
volatile int cnt;
for (cnt = 0; cnt < 100; cnt++) {
}
}
/* ------------------------------------------------------------ */
/************************************************************************/
DGSPI is an Abstract base class (interface) so DSPI and SoftSPI can implement a generic interface.
// Initialization and setup functions.
virtual bool begin() = 0;
virtual void end() = 0;
virtual void setSpeed(uint32_t spd) = 0;
virtual void setMode(uint16_t mod) = 0;
// Data transfer functions
virtual void setSelect(uint8_t sel) = 0;
virtual uint8_t transfer(uint8_t bVal) = 0;
virtual void transfer(uint16_t cbReq, uint8_t * pbSnd, uint8_t * pbRcv) = 0;
virtual void transfer(uint16_t cbReq, uint8_t * pbSnd) = 0;
virtual void transfer(uint16_t cbReq, uint8_t bPad, uint8_t * pbRcv) = 0;
Parent class: DGSPI
Name | Value | Clock Polarity (CPOL/CKP) |
Clock Edge (CKE/NCPHA) |
---|---|---|---|
DSPI_MODE0 | CKP = 0 CKE = 1 | 0 | 1 |
DSPI_MODE1 | CKP = 0 CKE = 0 | 0 | 0 |
DSPI_MODE2 | CKP = 1 CKE = 1 | 1 | 1 |
DSPI_MODE3 | CKP = 1 CKE = 0 | 1 | 0 |
Name | Value |
---|---|
DSPI_8BIT | 8 |
DSPI_16BIT | 16 |
DSPI_32BIT | 32 |
Name | Value |
---|---|
_DSPI_SPD_DEFAULT | 1000000L |
bool begin();
Initialize the SPI port with all default values.
bool begin(uint8_t pin);
Initialize the SPI port with the default values. This will set the clock rate to the default speed and the pin for SS to the specified pin
bool begin(uint8_t miso, uint8_t mosi);
Defined for PIC32MX1XX, PIC32MX2XX, PIC32MZXX, and PIC32MX47X only. Initialize the SPI port with new PPS mappings.
bool begin(uint8_t miso, uint8_t mosi, uint8_t pin);
Defined for PIC32MX1XX, PIC32MX2XX, PIC32MZXX, and PIC32MX47X only. Initialize the SPI port with new PPS mappings.
void end();
Return the object to the uninitialized state and disable the SPI controller.
void setSpeed(uint32_t spd);
This sets the SPI clock speed to the highest supported frequency that doesn't exceed the requested value. It computes the appropriate value to load into the SPI baud register based on requested clock speed and peripheral bus frequency.
void unsetSpeed();
Undo the last setSpeed() call to restore the previous baud rate.
void setMode(uint16_t mod);
Set the SPI controller to the requested data mode. This should be one of the values: DSPI_MODE0, DSPI_MODE1, DSPI_MODE2, DSPI_MODE3
void unsetMode();
Undo the last setMode call.
void setPinSelect(uint8_t pin);
This sets the pin used for slave select. It will make the pin be an output driving high. This pin will then be use by the setSelect method.
void setTransferSize(uint8_t txsize);
Sets the transfer packet size. Options: DSPI_8BIT / DSPI_16BIT / DSPI_32BIT
void setSelect(uint8_t sel) { digitalWrite(pinSS, sel); };
Sets the state of the Slave Select (SS) pin. HIGH / LOW
uint32_t transfer(uint32_t bVal);
Send the specified byte to the SPI slave device, returning the byte received from the slave device.
uint8_t transfer(uint8_t bVal) { return((uint8_t) transfer((uint32_t) bVal)); }
Send the specified byte to the SPI slave device, returning the byte received from the slave device.
void transfer(uint16_t cbReq, uint8_t * pbSnd, uint8_t * pbRcv);
This function will send the requested bytes to the SPI slave device, simultaneously saving the bytes received from the slave device.
cbReq - number of bytes to transfer
pbSnd - pointer to buffer to bytes to send
pbRcv - pointer to hold received bytes
void transfer(uint16_t cbReq, uint8_t * pbSnd);
This function will send the requested bytes to the SPI slave device, discarding the bytes received from the slave.
cbReq - number of bytes to transfer
pbSnd - pointer to buffer to bytes to send
void transfer(uint16_t cbReq, uint8_t bPad, uint8_t * pbRcv);
This function will receive the specified number of bytes from the slave. The given pad byte will be sent to the slave to cause the received bytes to be sent.
-cbReq - number of bytes to receive from the slave
-bPad - pad byte to send to slave
-pbRcv - buffer to hold received bytes
void enableInterruptTransfer();
Sets up the interrupt controller and enables interrupts for this SPI port.
void disableInterruptTransfer();
Turns off SPI interrupts for this SPI port.
void intTransfer(uint16_t cbReq, uint8_t * pbSnd, uint8_t * pbRcv);
This function will set up and begin an interrupt driven transfer where the received bytes are stored into a receive buffer.
cbReq - number of bytes to transfer
pbSnd - pointer to buffer to bytes to send
pbRcv - pointer to hold received bytes
void intTransfer(uint16_t cbReq, uint8_t * pbSnd);
This function will set up and begin an interrupt driven transfer where the received bytes are discarded.
cbReq - number of bytes to transfer
pbSnd - pointer to buffer to bytes to send
void intTransfer(uint16_t cbReq, uint8_t bPadT, uint8_t * pbRcv);
This function will set up and begin an interrupt driven transfer where there is no transmit buffer but the returned bytes are stored. The given pad byte is sent to the slave to cause the returned bytes to be sent by the slave.
-cbReq - number of bytes to receive from the slave
-bPad - pad byte to send to slave
-pbRcv - buffer to hold received bytes
void cancelIntTransfer();
This will cancel an interrupt driven transfer. It is still the caller's responsibility to drive SS high to release the slave device.
uint16_t transCount() { return cbCur; };
Count of bytes left to transfer
int isOverflow() { return fRov; };
Overrun error interrupt triggered.
void clearOverflow() { fRov = 0; };
Clear the receive overflow error flag.
Parent class: DSPI
Available only if NUM_DSI_PORTS is greater than 1.
void enableInterruptTransfer();
Sets up the interrupt controller and enables interrupts for this SPI port.
void disableInterruptTransfer();
Turns off SPI interrupts for this SPI port.
Parent class: DSPI
Available only if NUM_DSI_PORTS is greater than 1.
void enableInterruptTransfer();
Sets up the interrupt controller and enables interrupts for this SPI port.
void disableInterruptTransfer();
Turns off SPI interrupts for this SPI port.
Parent class: DSPI
Available only if NUM_DSI_PORTS is greater than 2.
void enableInterruptTransfer();
Sets up the interrupt controller and enables interrupts for this SPI port.
void disableInterruptTransfer();
Turns off SPI interrupts for this SPI port.
Parent class: DSPI
Available only if NUM_DSI_PORTS is greater than 3.
void enableInterruptTransfer();
Sets up the interrupt controller and enables interrupts for this SPI port.
void disableInterruptTransfer();
Turns off SPI interrupts for this SPI port.