diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2012-10-29 23:06:01 +0200 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2012-10-29 23:06:01 +0200 |
| commit | 4ba8614c006f9828f0796c140bc3e13c9e67938c (patch) | |
| tree | ad204651c733250d27d20fce8820f9747c43c883 /utils/softssi.c | |
| parent | e018ceebed74b8223482bc9d1ed0b31c938381da (diff) | |
Added utils
Diffstat (limited to 'utils/softssi.c')
| -rw-r--r-- | utils/softssi.c | 1288 |
1 files changed, 1288 insertions, 0 deletions
diff --git a/utils/softssi.c b/utils/softssi.c new file mode 100644 index 0000000..e8c5c0b --- /dev/null +++ b/utils/softssi.c @@ -0,0 +1,1288 @@ +//*****************************************************************************
+//
+// softssi.c - Driver for the SoftSSI.
+//
+// Copyright (c) 2010-2012 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 9453 of the Stellaris Firmware Development Package.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! \addtogroup softssi_api
+//! @{
+//
+//*****************************************************************************
+
+#include "inc/hw_types.h"
+#include "driverlib/gpio.h"
+#include "driverlib/rom.h"
+#include "driverlib/rom_map.h"
+#include "utils/softssi.h"
+
+//*****************************************************************************
+//
+// The states in the SoftSSI state machine.
+//
+//*****************************************************************************
+#define SOFTSSI_STATE_IDLE 0
+#define SOFTSSI_STATE_START 1
+#define SOFTSSI_STATE_IN 2
+#define SOFTSSI_STATE_OUT 3
+#define SOFTSSI_STATE_STOP1 4
+#define SOFTSSI_STATE_STOP2 5
+
+//*****************************************************************************
+//
+// The flags in the SoftSSI ucFlags structure member.
+//
+//*****************************************************************************
+#define SOFTSSI_FLAG_ENABLE 0x80
+#define SOFTSSI_FLAG_SPH 0x02
+#define SOFTSSI_FLAG_SPO 0x01
+
+//*****************************************************************************
+//
+//! Sets the configuration of a SoftSSI module.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ucProtocol specifes the data transfer protocol.
+//! \param ucBits specifies the number of bits transferred per frame.
+//!
+//! This function configures the data format of a SoftSSI module. The
+//! \e ucProtocol parameter can be one of the following values:
+//! \b SOFTSSI_FRF_MOTO_MODE_0, \b SOFTSSI_FRF_MOTO_MODE_1,
+//! \b SOFTSSI_FRF_MOTO_MODE_2, or \b SOFTSSI_FRF_MOTO_MODE_3. These frame
+//! formats imply the following polarity and phase configurations:
+//!
+//! <pre>
+//! Polarity Phase Mode
+//! 0 0 SOFTSSI_FRF_MOTO_MODE_0
+//! 0 1 SOFTSSI_FRF_MOTO_MODE_1
+//! 1 0 SOFTSSI_FRF_MOTO_MODE_2
+//! 1 1 SOFTSSI_FRF_MOTO_MODE_3
+//! </pre>
+//!
+//! The \e ucBits parameter defines the width of the data transfers, and can be
+//! a value between 4 and 16, inclusive.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIConfigSet(tSoftSSI *pSSI, unsigned char ucProtocol,
+ unsigned char ucBits)
+{
+ //
+ // See if a GPIO pin has been set for Fss.
+ //
+ if(pSSI->ulFssGPIO != 0)
+ {
+ //
+ // Configure the Fss pin.
+ //
+ MAP_GPIOPinTypeGPIOOutput(pSSI->ulFssGPIO & 0xfffff000,
+ (pSSI->ulFssGPIO & 0x00000fff) >> 2);
+
+ //
+ // Set the Fss pin high.
+ //
+ HWREG(pSSI->ulFssGPIO) = 255;
+ }
+
+ //
+ // Configure the Clk pin.
+ //
+ MAP_GPIOPinTypeGPIOOutput(pSSI->ulClkGPIO & 0xfffff000,
+ (pSSI->ulClkGPIO & 0x00000fff) >> 2);
+
+ //
+ // Set the Clk pin high or low based on the configured clock polarity.
+ //
+ if((ucProtocol & SOFTSSI_FLAG_SPO) == 0)
+ {
+ HWREG(pSSI->ulClkGPIO) = 0;
+ }
+ else
+ {
+ HWREG(pSSI->ulClkGPIO) = 255;
+ }
+
+ //
+ // Configure the Tx pin and set it low.
+ //
+ MAP_GPIOPinTypeGPIOOutput(pSSI->ulTxGPIO & 0xfffff000,
+ (pSSI->ulTxGPIO & 0x00000fff) >> 2);
+ HWREG(pSSI->ulTxGPIO) = 0;
+
+ //
+ // See if a GPIO pin has been set for Rx.
+ //
+ if(pSSI->ulRxGPIO != 0)
+ {
+ //
+ // Configure the Rx pin.
+ //
+ MAP_GPIOPinTypeGPIOInput(pSSI->ulRxGPIO & 0xfffff000,
+ (pSSI->ulRxGPIO & 0x00000fff) >> 2);
+ }
+
+ //
+ // Make sure that the transmit and receive FIFOs are empty.
+ //
+ pSSI->usTxBufferRead = 0;
+ pSSI->usTxBufferWrite = 0;
+ pSSI->usRxBufferRead = 0;
+ pSSI->usRxBufferWrite = 0;
+
+ //
+ // Save the frame protocol.
+ //
+ pSSI->ucFlags = ucProtocol;
+
+ //
+ // Save the number of data bits.
+ //
+ pSSI->ucBits = ucBits;
+
+ //
+ // Since the FIFOs are empty, the transmit FIFO "interrupt" is asserted.
+ //
+ pSSI->ucIntStatus = SOFTSSI_TXFF;
+
+ //
+ // Reset the idle counter.
+ //
+ pSSI->ucIdleCount = 0;
+
+ //
+ // Disable the SoftSSI module.
+ //
+ pSSI->ucFlags &= ~(SOFTSSI_FLAG_ENABLE);
+
+ //
+ // Start the SoftSSI state machine in the idle state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_IDLE;
+}
+
+//*****************************************************************************
+//
+//! Handles the assertion/deassertion of the transmit FIFO ``interrupt''.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//!
+//! This function is used to determine when to assert or deassert the transmit
+//! FIFO ``interrupt''.
+//!
+//! \return None.
+//
+//*****************************************************************************
+static void
+SoftSSITxInt(tSoftSSI *pSSI)
+{
+ unsigned short usTemp;
+
+ //
+ // Determine the number of words left in the transmit FIFO.
+ //
+ if(pSSI->usTxBufferRead > pSSI->usTxBufferWrite)
+ {
+ usTemp = (pSSI->usTxBufferLen + pSSI->usTxBufferWrite -
+ pSSI->usTxBufferRead);
+ }
+ else
+ {
+ usTemp = pSSI->usTxBufferWrite - pSSI->usTxBufferRead;
+ }
+
+ //
+ // If the transmit FIFO is now half full or less, generate a transmit FIFO
+ // "interrupt". Otherwise, clear the transmit FIFO "interrupt".
+ //
+ if(usTemp <= (pSSI->usTxBufferLen / 2))
+ {
+ pSSI->ucIntStatus |= SOFTSSI_TXFF;
+ }
+ else
+ {
+ pSSI->ucIntStatus &= ~(SOFTSSI_TXFF);
+ }
+}
+
+//*****************************************************************************
+//
+//! Handles the assertion/deassertion of the receive FIFO ``interrupt''.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//!
+//! This function is used to determine when to assert or deassert the receive
+//! FIFO ``interrupt''.
+//!
+//! \return None.
+//
+//*****************************************************************************
+static void
+SoftSSIRxInt(tSoftSSI *pSSI)
+{
+ unsigned short usTemp;
+
+ //
+ // Determine the number of words in the receive FIFO.
+ //
+ if(pSSI->usRxBufferRead > pSSI->usRxBufferWrite)
+ {
+ usTemp = (pSSI->usRxBufferLen + pSSI->usRxBufferWrite -
+ pSSI->usRxBufferRead);
+ }
+ else
+ {
+ usTemp = pSSI->usRxBufferWrite - pSSI->usRxBufferRead;
+ }
+
+ //
+ // If the receive FIFO is now half full or more, generate a receive FIFO
+ // "interrupt". Otherwise, clear the receive FIFO "interrupt".
+ //
+ if(usTemp >= (pSSI->usRxBufferLen / 2))
+ {
+ pSSI->ucIntStatus |= SOFTSSI_RXFF;
+ }
+ else
+ {
+ pSSI->ucIntStatus &= ~(SOFTSSI_RXFF);
+ }
+}
+
+//*****************************************************************************
+//
+//! Performs the periodic update of the SoftSSI module.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//!
+//! This function performs the periodic, time-based updates to the SoftSSI
+//! module. The transmission and reception of data over the SoftSSI link is
+//! performed by the state machine in this function.
+//!
+//! This function must be called at twice the desired SoftSSI clock rate. For
+//! example, to run the SoftSSI clock at 10 KHz, this function must be called
+//! at a 20 KHz rate.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSITimerTick(tSoftSSI *pSSI)
+{
+ unsigned short usTemp;
+
+ //
+ // Determine the current state of the state machine.
+ //
+ switch(pSSI->ucState)
+ {
+ //
+ // The state machine is idle.
+ //
+ case SOFTSSI_STATE_IDLE:
+ {
+ //
+ // See if the SoftSSI module is enabled and there is data in the
+ // transmit FIFO.
+ //
+ if(((pSSI->ucFlags & SOFTSSI_FLAG_ENABLE) != 0) &&
+ (pSSI->usTxBufferRead != pSSI->usTxBufferWrite))
+ {
+ //
+ // Assert the Fss signal if it is configured.
+ //
+ if(pSSI->ulFssGPIO != 0)
+ {
+ HWREG(pSSI->ulFssGPIO) = 0;
+ }
+
+ //
+ // Move to the start state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_START;
+ }
+
+ //
+ // Otherwise, see if there is data in the receive FIFO.
+ //
+ else if((pSSI->usRxBufferRead != pSSI->usRxBufferWrite) &&
+ (pSSI->ucIdleCount != 64))
+ {
+ //
+ // Increment the idle counter.
+ //
+ pSSI->ucIdleCount++;
+
+ //
+ // See if the idle counter has become large enough to trigger
+ // a timeout "interrupt".
+ //
+ if(pSSI->ucIdleCount == 64)
+ {
+ //
+ // Trigger the receive timeout "interrupt".
+ //
+ pSSI->ucIntStatus |= SOFTSSI_RXTO;
+ }
+ }
+
+ //
+ // This state has been handled.
+ //
+ break;
+ }
+
+ //
+ // The start machine is in the transfer start state.
+ //
+ case SOFTSSI_STATE_START:
+ {
+ //
+ // Get the next word to transfer from the transmit FIFO.
+ //
+ pSSI->usTxData = (pSSI->pusTxBuffer[pSSI->usTxBufferRead] <<
+ (16 - pSSI->ucBits));
+
+ //
+ // Initialize the receive buffer to zero.
+ //
+ pSSI->usRxData = 0;
+
+ //
+ // Initialize the count of bits tranferred.
+ //
+ pSSI->ucCurrentBit = 0;
+
+ //
+ // Write the first bit of the transmit word to the Tx pin.
+ //
+ HWREG(pSSI->ulTxGPIO) =
+ (pSSI->usTxData & 0x8000) ? 255 : 0;
+
+ //
+ // Shift to the next bit of the transmit word.
+ //
+ pSSI->usTxData <<= 1;
+
+ //
+ // If in SPI mode 1 or 3, then the Clk signal needs to be toggled.
+ //
+ if((pSSI->ucFlags & SOFTSSI_FLAG_SPH) != 0)
+ {
+ HWREG(pSSI->ulClkGPIO) ^= 255;
+ }
+
+ //
+ // Move to the data input state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_IN;
+
+ //
+ // This state has been handled.
+ //
+ break;
+ }
+
+ //
+ // The state machine is in the data input state.
+ //
+ case SOFTSSI_STATE_IN:
+ {
+ //
+ // Read the next bit from the Rx signal if it is configured.
+ //
+ if(pSSI->ulRxGPIO != 0)
+ {
+ pSSI->usRxData = ((pSSI->usRxData << 1) |
+ (HWREG(pSSI->ulRxGPIO) ? 1 : 0));
+ }
+
+ //
+ // Toggle the Clk signal.
+ //
+ HWREG(pSSI->ulClkGPIO) ^= 255;
+
+ //
+ // Increment the number of bits transferred.
+ //
+ pSSI->ucCurrentBit++;
+
+ //
+ // See if the entire word has been transferred.
+ //
+ if(pSSI->ucCurrentBit != pSSI->ucBits)
+ {
+ //
+ // There are more bits to transfer, so move to the data output
+ // state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_OUT;
+ }
+ else
+ {
+ //
+ // Increment the transmit read pointer, removing the word that
+ // was just transferred from the transmit FIFO.
+ //
+ pSSI->usTxBufferRead++;
+ if(pSSI->usTxBufferRead == pSSI->usTxBufferLen)
+ {
+ pSSI->usTxBufferRead = 0;
+ }
+
+ //
+ // See if a transmit FIFO "interrupt" needs to be asserted.
+ //
+ SoftSSITxInt(pSSI);
+
+ //
+ // Determine the new value for the receive FIFO write pointer.
+ //
+ usTemp = pSSI->usRxBufferWrite + 1;
+ if(usTemp >= pSSI->usRxBufferLen)
+ {
+ usTemp = 0;
+ }
+
+ //
+ // See if there is space in the receive FIFO for the word that
+ // was just received.
+ //
+ if(usTemp == pSSI->usRxBufferRead)
+ {
+ //
+ // The receive FIFO is full, so generate a receive FIFO
+ // overrun "interrupt".
+ //
+ pSSI->ucIntStatus |= SOFTSSI_RXOR;
+ }
+ else
+ {
+ //
+ // Store the new word into the receive FIFO.
+ //
+ pSSI->pusRxBuffer[pSSI->usRxBufferWrite] = pSSI->usRxData;
+
+ //
+ // Save the new receive FIFO write pointer.
+ //
+ pSSI->usRxBufferWrite = usTemp;
+
+ //
+ // See if a receive FIFO "interrupt" needs to be asserted.
+ //
+ SoftSSIRxInt(pSSI);
+ }
+
+ //
+ // See if the next word should be transmitted immediately.
+ // This will occur when there is data in the transmit FIFO, the
+ // SoftSSI module is enabled, and the SoftSSI module is in SPI
+ // mode 1 or 3.
+ //
+ if(((pSSI->ucFlags & SOFTSSI_FLAG_ENABLE) != 0) &&
+ ((pSSI->ucFlags & SOFTSSI_FLAG_SPH) != 0) &&
+ (pSSI->usTxBufferRead != pSSI->usTxBufferWrite))
+ {
+ //
+ // Get the next word to transfer from the transmit FIFO.
+ //
+ pSSI->usTxData =
+ (pSSI->pusTxBuffer[pSSI->usTxBufferRead] <<
+ (16 - pSSI->ucBits));
+
+ //
+ // Initialize the receive buffer to zero.
+ //
+ pSSI->usRxData = 0;
+
+ //
+ // Initialize the count of bits tranferred.
+ //
+ pSSI->ucCurrentBit = 0;
+
+ //
+ // Move to the data output state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_OUT;
+ }
+ else
+ {
+ //
+ // The next word should not be transmitted immediately, so
+ // move to the first step of the stop state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_STOP1;
+ }
+ }
+
+ //
+ // This state has been handled.
+ //
+ break;
+ }
+
+ //
+ // The state machine is in the data output state.
+ //
+ case SOFTSSI_STATE_OUT:
+ {
+ //
+ // Write the next bit of the transmit word to the Tx pin.
+ //
+ HWREG(pSSI->ulTxGPIO) = (pSSI->usTxData & 0x8000) ? 255 : 0;
+
+ //
+ // Toggle the Clk signal.
+ //
+ HWREG(pSSI->ulClkGPIO) ^= 255;
+
+ //
+ // Shift to the next bit of the transmit word.
+ //
+ pSSI->usTxData <<= 1;
+
+ //
+ // Move to the data input state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_IN;
+
+ //
+ // This state has been handled.
+ //
+ break;
+ }
+
+ //
+ // The state machine is in the first step of the stop state.
+ //
+ case SOFTSSI_STATE_STOP1:
+ {
+ //
+ // Set the Tx pin low.
+ //
+ HWREG(pSSI->ulTxGPIO) = 0;
+
+ //
+ // If in SPI mode 1 or 3, then the Clk signal needs to be toggled.
+ //
+ if((pSSI->ucFlags & SOFTSSI_FLAG_SPH) == 0)
+ {
+ HWREG(pSSI->ulClkGPIO) ^= 255;
+ }
+
+ //
+ // Move to the second step of the stop state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_STOP2;
+
+ //
+ // This state has been handled.
+ //
+ break;
+ }
+
+ //
+ // The state machine is in the second step of the stop state.
+ //
+ case SOFTSSI_STATE_STOP2:
+ {
+ //
+ // Deassert the Fss signal if it is configured.
+ //
+ if(pSSI->ulFssGPIO != 0)
+ {
+ HWREG(pSSI->ulFssGPIO) = 255;
+ }
+
+ //
+ // Move to the idle state.
+ //
+ pSSI->ucState = SOFTSSI_STATE_IDLE;
+
+ //
+ // Reset the idle counter.
+ //
+ pSSI->ucIdleCount = 0;
+
+ //
+ // See if the end of transfer "interrupt" should be generated.
+ //
+ if(pSSI->usTxBufferRead == pSSI->usTxBufferWrite)
+ {
+ pSSI->ucIntStatus |= SOFTSSI_TXEOT;
+ }
+
+ //
+ // This state has been handled.
+ //
+ break;
+ }
+ }
+
+ //
+ // Call the "interrupt" callback while there are enabled "interrupts"
+ // asserted. By calling in a loop until the "interrupts" are no longer
+ // asserted, this mimics the behavior of a real hardware implementation of
+ // the SSI peripheral.
+ //
+ while(((pSSI->ucIntStatus & pSSI->ucIntMask) != 0) &&
+ (pSSI->pfnIntCallback != 0))
+ {
+ //
+ // Call the callback function.
+ //
+ pSSI->pfnIntCallback();
+ }
+}
+
+//*****************************************************************************
+//
+//! Enables the SoftSSI module.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//!
+//! This function enables operation of the SoftSSI module. The SoftSSI module
+//! must be configured before it is enabled.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIEnable(tSoftSSI *pSSI)
+{
+ //
+ // Enable the SoftSSI module.
+ //
+ pSSI->ucFlags |= SOFTSSI_FLAG_ENABLE;
+}
+
+//*****************************************************************************
+//
+//! Disables the SoftSSI module.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//!
+//! This function disables operation of the SoftSSI module. If a data transfer
+//! is in progress, it is finished before the module is fully disabled.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIDisable(tSoftSSI *pSSI)
+{
+ //
+ // Disable the SoftSSI module.
+ //
+ pSSI->ucFlags &= ~(SOFTSSI_FLAG_ENABLE);
+}
+
+//*****************************************************************************
+//
+//! Enables individual SoftSSI ``interrupt'' sources.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulIntFlags is a bit mask of the ``interrupt'' sources to be enabled.
+//!
+//! Enables the indicated SoftSSI ``interrupt'' sources. Only the sources that
+//! are enabled can be reflected to the callback function; disabled sources do
+//! not result in a callback. The \e ulIntFlags parameter can be any of the
+//! \b SOFTSSI_TXEOT, \b SOFTSSI_TXFF, \b SOFTSSI_RXFF, \b SOFTSSI_RXTO, or
+//! \b SOFTSSI_RXOR values.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIIntEnable(tSoftSSI *pSSI, unsigned long ulIntFlags)
+{
+ //
+ // Enable the specified "interrupts".
+ //
+ pSSI->ucIntMask |= ulIntFlags;
+}
+
+//*****************************************************************************
+//
+//! Disables individual SoftSSI ``interrupt'' sources.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulIntFlags is a bit mask of the ``interrupt'' sources to be
+//! disabled.
+//!
+//! Disables the indicated SoftSSI ``interrupt'' sources. The \e ulIntFlags
+//! parameter can be any of the \b SOFTSSI_TXEOT, \b SOFTSSI_TXFF,
+//! \b SOFTSSI_RXFF, \b SOFTSSI_RXTO, or \b SOFTSSI_RXOR values.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIIntDisable(tSoftSSI *pSSI, unsigned long ulIntFlags)
+{
+ //
+ // Disable the specified "interrupts".
+ //
+ pSSI->ucIntMask &= ~(ulIntFlags);
+}
+
+//*****************************************************************************
+//
+//! Gets the current ``interrupt'' status.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param bMasked is \b false if the raw ``interrupt'' status is required or
+//! \b true if the masked ``interrupt'' status is required.
+//!
+//! This function returns the ``interrupt'' status for the SoftSSI module.
+//! Either the raw ``interrupt'' status or the status of ``interrupts'' that
+//! are allowed to reflect to the callback can be returned.
+//!
+//! \return The current ``interrupt'' status, enumerated as a bit field of
+//! \b SOFTSSI_TXEOT, \b SOFTSSI_TXFF, \b SOFTSSI_RXFF, \b SOFTSSI_RXTO, and
+//! \b SOFTSSI_RXOR.
+//
+//*****************************************************************************
+unsigned long
+SoftSSIIntStatus(tSoftSSI *pSSI, tBoolean bMasked)
+{
+ //
+ // Return either the "interrupt" status or the raw "interrupt" status as
+ // requested.
+ //
+ if(bMasked)
+ {
+ return(pSSI->ucIntStatus & pSSI->ucIntMask);
+ }
+ else
+ {
+ return(pSSI->ucIntStatus);
+ }
+}
+
+//*****************************************************************************
+//
+//! Clears SoftSSI ``interrupt'' sources.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulIntFlags is a bit mask of the ``interrupt'' sources to be cleared.
+//!
+//! The specified SoftSSI ``interrupt'' sources are cleared so that they no
+//! longer assert. This function must be called in the ``interrupt'' handler
+//! to keep the ``interrupt'' from being recognized again immediately upon
+//! exit. The \e ulIntFlags parameter is the logical OR of any of the
+//! \b SOFTSSI_TXEOT, \b SOFTSSI_RXTO, and \b SOFTSSI_RXOR values.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIIntClear(tSoftSSI *pSSI, unsigned long ulIntFlags)
+{
+ //
+ // Clear the requested "interrupt" sources.
+ //
+ pSSI->ucIntStatus &= ~(ulIntFlags) | SOFTSSI_TXFF | SOFTSSI_RXFF;
+}
+
+//*****************************************************************************
+//
+//! Determines if there is any data in the receive FIFO.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//!
+//! This function determines if there is any data available to be read from the
+//! receive FIFO.
+//!
+//! \return Returns \b true if there is data in the receive FIFO or \b false
+//! if there is no data in the receive FIFO.
+//
+//*****************************************************************************
+tBoolean
+SoftSSIDataAvail(tSoftSSI *pSSI)
+{
+ //
+ // Return the availability of data.
+ //
+ return((pSSI->usRxBufferRead == pSSI->usRxBufferWrite) ? false : true);
+}
+
+//*****************************************************************************
+//
+//! Determines if there is any space in the transmit FIFO.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//!
+//! This function determines if there is space available in the transmit FIFO.
+//!
+//! \return Returns \b true if there is space available in the transmit FIFO or
+//! \b false if there is no space available in the transmit FIFO.
+//
+//*****************************************************************************
+tBoolean
+SoftSSISpaceAvail(tSoftSSI *pSSI)
+{
+ unsigned short usTemp;
+
+ //
+ // Determine the values of the write pointer once incremented.
+ //
+ usTemp = pSSI->usTxBufferWrite + 1;
+ if(usTemp == pSSI->usTxBufferLen)
+ {
+ usTemp = 0;
+ }
+
+ //
+ // Return the availability of space.
+ //
+ return((pSSI->usTxBufferRead == usTemp) ? false : true);
+}
+
+//*****************************************************************************
+//
+//! Puts a data element into the SoftSSI transmit FIFO.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulData is the data to be transmitted over the SoftSSI interface.
+//!
+//! This function places the supplied data into the transmit FIFO of the
+//! specified SoftSSI module.
+//!
+//! \note The upper 32 - N bits of the \e ulData are discarded, where N is the
+//! data width as configured by SoftSSIConfigSet(). For example, if the
+//! interface is configured for 8-bit data width, the upper 24 bits of
+//! \e ulData are discarded.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIDataPut(tSoftSSI *pSSI, unsigned long ulData)
+{
+ unsigned short usTemp;
+
+ //
+ // Wait until there is space.
+ //
+ usTemp = pSSI->usTxBufferWrite + 1;
+ if(usTemp == pSSI->usTxBufferLen)
+ {
+ usTemp = 0;
+ }
+ while(usTemp == *(volatile unsigned short *)(&(pSSI->usTxBufferRead)))
+ {
+ }
+
+ //
+ // Write the data to the SoftSSI.
+ //
+ pSSI->pusTxBuffer[pSSI->usTxBufferWrite] = ulData;
+ pSSI->usTxBufferWrite = usTemp;
+
+ //
+ // See if a transmit FIFO "interrupt" needs to be cleared.
+ //
+ SoftSSITxInt(pSSI);
+}
+
+//*****************************************************************************
+//
+//! Puts a data element into the SoftSSI transmit FIFO.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulData is the data to be transmitted over the SoftSSI interface.
+//!
+//! This function places the supplied data into the transmit FIFO of the
+//! specified SoftSSI module. If there is no space in the FIFO, then this
+//! function returns a zero.
+//!
+//! \note The upper 32 - N bits of the \e ulData are discarded, where N is the
+//! data width as configured by SoftSSIConfigSet(). For example, if the
+//! interface is configured for 8-bit data width, the upper 24 bits of
+//! \e ulData are discarded.
+//!
+//! \return Returns the number of elements written to the SSI transmit FIFO.
+//
+//*****************************************************************************
+long
+SoftSSIDataPutNonBlocking(tSoftSSI *pSSI, unsigned long ulData)
+{
+ unsigned short usTemp;
+
+ //
+ // Determine the values of the write pointer once incremented.
+ //
+ usTemp = pSSI->usTxBufferWrite + 1;
+ if(usTemp == pSSI->usTxBufferLen)
+ {
+ usTemp = 0;
+ }
+
+ //
+ // Check for space to write.
+ //
+ if(usTemp != pSSI->usTxBufferRead)
+ {
+ pSSI->pusTxBuffer[pSSI->usTxBufferWrite] = ulData;
+ pSSI->usTxBufferWrite = usTemp;
+ SoftSSITxInt(pSSI);
+ return(1);
+ }
+ else
+ {
+ return(0);
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets a data element from the SoftSSI receive FIFO.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param pulData is a pointer to a storage location for data that was
+//! received over the SoftSSI interface.
+//!
+//! This function gets received data from the receive FIFO of the specified
+//! SoftSSI module and places that data into the location specified by the
+//! \e pulData parameter.
+//!
+//! \note Only the lower N bits of the value written to \e pulData contain
+//! valid data, where N is the data width as configured by SoftSSIConfigSet().
+//! For example, if the interface is configured for 8-bit data width, only the
+//! lower 8 bits of the value written to \e pulData contain valid data.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIDataGet(tSoftSSI *pSSI, unsigned long *pulData)
+{
+ //
+ // Wait until there is data to be read.
+ //
+ while(pSSI->usRxBufferRead ==
+ *(volatile unsigned short *)(&(pSSI->usRxBufferWrite)))
+ {
+ }
+
+ //
+ // Read data from SoftSSI.
+ //
+ *pulData = pSSI->pusRxBuffer[pSSI->usRxBufferRead];
+ pSSI->usRxBufferRead++;
+ if(pSSI->usRxBufferRead == pSSI->usRxBufferLen)
+ {
+ pSSI->usRxBufferRead = 0;
+ }
+
+ //
+ // See if a receive FIFO "interrupt" needs to be cleared.
+ //
+ SoftSSIRxInt(pSSI);
+}
+
+//*****************************************************************************
+//
+//! Gets a data element from the SoftSSI receive FIFO.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param pulData is a pointer to a storage location for data that was
+//! received over the SoftSSI interface.
+//!
+//! This function gets received data from the receive FIFO of the specified
+//! SoftSSI module and places that data into the location specified by the
+//! \e ulData parameter. If there is no data in the FIFO, then this function
+//! returns a zero.
+//!
+//! \note Only the lower N bits of the value written to \e pulData contain
+//! valid data, where N is the data width as configured by SoftSSIConfigSet().
+//! For example, if the interface is configured for 8-bit data width, only the
+//! lower 8 bits of the value written to \e pulData contain valid data.
+//!
+//! \return Returns the number of elements read from the SoftSSI receive FIFO.
+//
+//*****************************************************************************
+long
+SoftSSIDataGetNonBlocking(tSoftSSI *pSSI, unsigned long *pulData)
+{
+ //
+ // Check for data to read.
+ //
+ if(pSSI->usRxBufferRead != pSSI->usRxBufferWrite)
+ {
+ *pulData = pSSI->pusRxBuffer[pSSI->usRxBufferRead];
+ pSSI->usRxBufferRead++;
+ if(pSSI->usRxBufferRead == pSSI->usRxBufferLen)
+ {
+ pSSI->usRxBufferRead = 0;
+ }
+ SoftSSIRxInt(pSSI);
+ return(1);
+ }
+ else
+ {
+ return(0);
+ }
+}
+
+//*****************************************************************************
+//
+//! Determines whether the SoftSSI transmitter is busy or not.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//!
+//! Allows the caller to determine whether all transmitted bytes have cleared
+//! the transmitter. If \b false is returned, then the transmit FIFO is empty
+//! and all bits of the last transmitted word have left the shift register.
+//!
+//! \return Returns \b true if the SoftSSI is transmitting or \b false if all
+//! transmissions are complete.
+//
+//*****************************************************************************
+tBoolean
+SoftSSIBusy(tSoftSSI *pSSI)
+{
+ //
+ // Determine if the SSI is busy.
+ //
+ return(((pSSI->ucState == SOFTSSI_STATE_IDLE) &&
+ (((pSSI->ucFlags & SOFTSSI_FLAG_ENABLE) == 0) ||
+ (pSSI->usTxBufferRead == pSSI->usTxBufferWrite))) ? false : true);
+}
+
+//*****************************************************************************
+//
+//! Sets the callback used by the SoftSSI module.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param pfnCallback is a pointer to the callback function.
+//!
+//! This function sets the address of the callback function that is called when
+//! there is an ``interrupt'' produced by the SoftSSI module.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSICallbackSet(tSoftSSI *pSSI, void (*pfnCallback)(void))
+{
+ //
+ // Save the callback function address.
+ //
+ pSSI->pfnIntCallback = pfnCallback;
+}
+
+//*****************************************************************************
+//
+//! Sets the GPIO pin to be used as the SoftSSI Fss signal.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulBase is the base address of the GPIO module.
+//! \param ucPin is the bit-packed representation of the pin to use.
+//!
+//! This function sets the GPIO pin that is used for the SoftSSI Fss signal.
+//! If there is not a GPIO pin allocated for Fss, the SoftSSI module does not
+//! assert/deassert the Fss signal, leaving it to the application either to do
+//! manually or to not do at all if the slave device has Fss tied to ground.
+//!
+//! The pin is specified using a bit-packed byte, where bit 0 of the byte
+//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIFssGPIOSet(tSoftSSI *pSSI, unsigned long ulBase, unsigned char ucPin)
+{
+ //
+ // Save the base address and pin for the Fss signal.
+ //
+ if(ulBase == 0)
+ {
+ pSSI->ulFssGPIO = 0;
+ }
+ else
+ {
+ pSSI->ulFssGPIO = ulBase + (ucPin << 2);
+ }
+}
+
+//*****************************************************************************
+//
+//! Sets the GPIO pin to be used as the SoftSSI Clk signal.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulBase is the base address of the GPIO module.
+//! \param ucPin is the bit-packed representation of the pin to use.
+//!
+//! This function sets the GPIO pin that is used for the SoftSSI Clk signal.
+//!
+//! The pin is specified using a bit-packed byte, where bit 0 of the byte
+//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIClkGPIOSet(tSoftSSI *pSSI, unsigned long ulBase, unsigned char ucPin)
+{
+ //
+ // Save the base address and pin for the Clk signal.
+ //
+ pSSI->ulClkGPIO = ulBase + (ucPin << 2);
+}
+
+//*****************************************************************************
+//
+//! Sets the GPIO pin to be used as the SoftSSI Tx signal.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulBase is the base address of the GPIO module.
+//! \param ucPin is the bit-packed representation of the pin to use.
+//!
+//! This function sets the GPIO pin that is used for the SoftSSI Tx signal.
+//!
+//! The pin is specified using a bit-packed byte, where bit 0 of the byte
+//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSITxGPIOSet(tSoftSSI *pSSI, unsigned long ulBase, unsigned char ucPin)
+{
+ //
+ // Save the base address and pin for the Tx signal.
+ //
+ pSSI->ulTxGPIO = ulBase + (ucPin << 2);
+}
+
+//*****************************************************************************
+//
+//! Sets the GPIO pin to be used as the SoftSSI Rx signal.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param ulBase is the base address of the GPIO module.
+//! \param ucPin is the bit-packed representation of the pin to use.
+//!
+//! This function sets the GPIO pin that is used for the SoftSSI Rx signal. If
+//! there is not a GPIO pin allocated for Rx, the SoftSSI module does not read
+//! data from the slave device.
+//!
+//! The pin is specified using a bit-packed byte, where bit 0 of the byte
+//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIRxGPIOSet(tSoftSSI *pSSI, unsigned long ulBase, unsigned char ucPin)
+{
+ //
+ // Save the base address and pin for the Rx signal.
+ //
+ if(ulBase == 0)
+ {
+ pSSI->ulRxGPIO = 0;
+ }
+ else
+ {
+ pSSI->ulRxGPIO = ulBase + (ucPin << 2);
+ }
+}
+
+//*****************************************************************************
+//
+//! Sets the transmit FIFO buffer for a SoftSSI module.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param pusTxBuffer is the address of the transmit FIFO buffer.
+//! \param usLen is the size, in 16-bit half-words, of the transmit FIFO
+//! buffer.
+//!
+//! This function sets the address and size of the transmit FIFO buffer and
+//! also resets the read and write pointers, marking the transmit FIFO as
+//! empty.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSITxBufferSet(tSoftSSI *pSSI, unsigned short *pusTxBuffer,
+ unsigned short usLen)
+{
+ //
+ // Save the transmit FIFO buffer address and length.
+ //
+ pSSI->pusTxBuffer = pusTxBuffer;
+ pSSI->usTxBufferLen = usLen;
+
+ //
+ // Reset the transmit FIFO read and write pointers.
+ //
+ pSSI->usTxBufferRead = 0;
+ pSSI->usTxBufferWrite = 0;
+}
+
+//*****************************************************************************
+//
+//! Sets the receive FIFO buffer for a SoftSSI module.
+//!
+//! \param pSSI specifies the SoftSSI data structure.
+//! \param pusRxBuffer is the address of the receive FIFO buffer.
+//! \param usLen is the size, in 16-bit half-words, of the receive FIFO buffer.
+//!
+//! This function sets the address and size of the receive FIFO buffer and also
+//! resets the read and write pointers, marking the receive FIFO as empty.
+//! When the buffer pointer and length are configured as zero, all data
+//! received from the slave device is discarded. This capability is useful
+//! when there is no GPIO pin allocated for the Rx signal.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SoftSSIRxBufferSet(tSoftSSI *pSSI, unsigned short *pusRxBuffer,
+ unsigned short usLen)
+{
+ //
+ // Save the receive FIFO buffer address and length.
+ //
+ pSSI->pusRxBuffer = pusRxBuffer;
+ pSSI->usRxBufferLen = usLen;
+
+ //
+ // Reset the receive FIFO read and write pointers.
+ //
+ pSSI->usRxBufferRead = 0;
+ pSSI->usRxBufferWrite = 0;
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
|
