Hi there,
I'm new to the M4 environment, and I'm trying to write modules for controlling the SSI module to carry out SPI function.
The goal is for me to know how to control the PGA116 through the SSI module.
I tried to modify the spi_master.c and ti_master.c from the examples given in Stellaris software, but I have a few questions which I hope someone can help me answer:-
1. In GPIOPinConfigure(), I was not able to call the macros for GPIO_PA2_SSI0CLK, GPIO_PA3_SSI0FSS, GPIO_PA4_SSI0RX, and GPIO_PA5_SSI0TX. The compiler couldn't find the definitions so I had to manually type in the hex digits from the pin_map.h
2. After enabling the SSI module, I do not observe the clock rate on the SSI0CLK pin. Is the clock rate not passed to the pin? Or did I miss out any API to set it?
If possible, could someone show me a sample working code for controlling the SSI module on M4? I've attached a copy of my code below for your reference. Thanks in advance!
/* Test_SSI
*
* A sample project to test out SSI API to control the SSI module
*
* main.c
*/
#include "inc/hw_memmap.h"
#include "inc/hw_ssi.h"
#include "inc/hw_types.h"
#include "driverlib/ssi.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#define NUM_SSI_DATA 3
// Configure SSI0 in master Freescale (SPI) mode. This example will send out
// 3 bytes of data. This will all be done using the polling method.
void main(void) {
unsigned long ulDataTx[NUM_SSI_DATA];
unsigned long ulDataRx[NUM_SSI_DATA];
unsigned long ulindex;
// Set the clocking to run directly from the external crystal/oscillator.
// TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
// crystal on your board.
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
// The SSI0 peripheral must be enabled for use.
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
// For this example SSI0 is used with PortA[5:2]. The actual port and pins
// used may be different on your part, consult the data sheet for more
// information. GPIO port A needs to be enabled so these pins can be used.
// TODO: change this to whichever GPIO port you are using.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5.
// This step is not necessary if your part does not support pin muxing.
// TODO: change this to select the port/pin you are using. (lookup pin_map.h)
GPIOPinConfigure(0x00000802);
GPIOPinConfigure(0x00000C02);
GPIOPinConfigure(0x00001002);
GPIOPinConfigure(0x00001402);
// Configure the GPIO settings for the SSI pins. This function also gives
// control of these pins to the SSI hardware. Consult the data sheet to
// see which functions are allocated per pin.
// The pins are assigned as follows:
// PA5 - SSI0Tx
// PA4 - SSI0Rx
// PA3 - SSI0Fss
// PA2 - SSI0CLK
// TODO: change this to select the port/pin you are using.
GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
// Configure and enable the SSI port for SPI master mode. Use SSI0,
// system clock supply, idle clock level low and active low clock in
// freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.
// For SPI mode, you can set the polarity of the SSI clock when the SSI
// unit is idle. You can also configure what clock edge you want to
// capture data on. Please reference the datasheet for more information on
// the different SPI modes.
SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8);
// Enable the SSI0 module.
SSIEnable(SSI0_BASE);
while(1){
// Read any residual data from the SSI port. This makes sure the receive
// FIFOs are empty, so we don't read any unwanted junk. This is done here
// because the SPI SSI mode is full-duplex, which allows you to send and
// receive at the same time. The SSIDataGetNonBlocking function returns
// "true" when data was returned, and "false" when no data was returned.
// The "non-blocking" function checks if there is any data in the receive
// FIFO and does not "hang" if there isn't.
while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]))
{
}
// Initialize the data to send.
ulDataTx[0] = 's';
ulDataTx[1] = 'p';
ulDataTx[2] = 'i';
// Send 3 bytes of data.
for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)
{
// Send the data using the "blocking" put function. This function
// will wait until there is room in the send FIFO before returning.
// This allows you to assure that all the data you send makes it into
// the send FIFO.
SSIDataPut(SSI0_BASE, ulDataTx[ulindex]);
}
// Wait until SSI0 is done transferring all the data in the transmit FIFO.
while(SSIBusy(SSI0_BASE))
{
}
}
}