9 #include "ChipObject/tSPI.h"
10 #include "DigitalModule.h"
11 #include "DigitalInput.h"
12 #include "DigitalOutput.h"
13 #include "NetworkCommunication/UsageReporting.h"
14 #include "Synchronized.h"
15 #include "WPIErrors.h"
20 SEM_ID SPI::m_semaphore = NULL;
33 Init(&clk, &mosi, &miso);
47 Init(clk, mosi, miso);
59 Init(&clk, &mosi, NULL);
71 Init(clk, mosi, NULL);
83 Init(&clk, NULL, &miso);
95 Init(clk, NULL, miso);
117 if (m_semaphore == NULL)
119 m_semaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
122 tRioStatusCode localStatus = NiFpga_Status_Success;
123 m_spi = tSPI::create(&localStatus);
124 wpi_setError(localStatus);
126 m_config.BusBitWidth = 8;
127 m_config.ClockHalfPeriodDelay = 0;
128 m_config.MSBfirst = 0;
129 m_config.DataOnFalling = 0;
130 m_config.LatchFirst = 0;
131 m_config.LatchLast = 0;
132 m_config.FramePolarity = 0;
133 m_config.WriteOnly = miso ? 0 : 1;
134 m_config.ClockPolarity = 0;
138 m_channels.SS_Channel = 0;
139 m_channels.SS_Module = 0;
148 m_channels.MOSI_Channel = 0;
149 m_channels.MOSI_Module = 0;
159 m_channels.MISO_Channel = 0;
160 m_channels.MISO_Module = 0;
165 static int32_t instances = 0;
167 nUsageReporting::report(nUsageReporting::kResourceType_SPI, instances);
178 m_config.BusBitWidth = bits;
189 return m_config.BusBitWidth;
201 tRioStatusCode localStatus = NiFpga_Status_Success;
203 wpi_setError(localStatus);
204 double v = (1.0 / hz) / (2 * loopTiming / (kSystemClockTicksPerMicrosecond * 1e6));
206 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"SPI Clock too high");
208 delay = (int) (v + .5);
210 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"SPI Clock too low");
213 m_config.ClockHalfPeriodDelay = delay;
222 m_config.MSBfirst = 1;
231 m_config.MSBfirst = 0;
240 m_config.DataOnFalling = 1;
249 m_config.DataOnFalling = 0;
272 m_channels.SS_Channel = 0;
273 m_channels.SS_Module = 0;
280 m_config.LatchFirst = 0;
281 m_config.LatchLast = 0;
284 m_config.LatchFirst = 1;
285 m_config.LatchLast = 0;
287 case kPostLatchPulse:
288 m_config.LatchFirst = 0;
289 m_config.LatchLast = 1;
291 case kPreAndPostLatchPulse:
292 m_config.LatchFirst = 1;
293 m_config.LatchLast = 1;
297 m_config.FramePolarity = activeLow ? 1 : 0;
331 *mode = (tFrameMode) (m_config.LatchFirst | (m_config.LatchLast << 1));
333 if (activeLow != NULL)
335 *activeLow = m_config.FramePolarity != 0;
346 m_config.ClockPolarity = 1;
355 m_config.ClockPolarity = 0;
365 tRioStatusCode localStatus = NiFpga_Status_Success;
366 m_spi->writeConfig(m_config, &localStatus);
367 m_spi->writeChannels(m_channels, &localStatus);
368 m_spi->strobeReset(&localStatus);
369 wpi_setError(localStatus);
380 tRioStatusCode localStatus = NiFpga_Status_Success;
381 uint16_t result = m_spi->readAvailableToLoad(&localStatus);
382 wpi_setError(localStatus);
394 tRioStatusCode localStatus = NiFpga_Status_Success;
395 uint16_t result = m_spi->readReceivedElements(&localStatus);
396 wpi_setError(localStatus);
407 tRioStatusCode localStatus = NiFpga_Status_Success;
408 bool result = m_spi->readStatus_Idle(&localStatus);
409 wpi_setError(localStatus);
421 tRioStatusCode localStatus = NiFpga_Status_Success;
422 bool result = m_spi->readStatus_ReceivedDataOverflow(&localStatus);
423 wpi_setError(localStatus);
436 if (m_channels.MOSI_Channel == 0 && m_channels.MOSI_Module == 0)
438 wpi_setWPIError(SPIWriteNoMOSI);
447 tRioStatusCode localStatus = NiFpga_Status_Success;
448 m_spi->writeDataToLoad(data, &localStatus);
449 m_spi->strobeLoad(&localStatus);
450 wpi_setError(localStatus);
468 if (m_channels.MISO_Channel == 0 && m_channels.MISO_Module == 0)
470 wpi_setWPIError(SPIReadNoMISO);
474 tRioStatusCode localStatus = NiFpga_Status_Success;
481 m_spi->writeDataToLoad(0, &localStatus);
482 m_spi->strobeLoad(&localStatus);
491 wpi_setWPIError(SPIReadNoData);
500 m_spi->strobeReadReceivedData(&localStatus);
501 data = m_spi->readReceivedData(&localStatus);
503 wpi_setError(localStatus);
513 tRioStatusCode localStatus = NiFpga_Status_Success;
514 m_spi->strobeReset(&localStatus);
515 wpi_setError(localStatus);
523 tRioStatusCode localStatus = NiFpga_Status_Success;
524 m_spi->strobeClearReceivedData(&localStatus);
525 wpi_setError(localStatus);
uint32_t GetBitsPerWord()
void SetSampleDataOnFalling()
SPI(DigitalOutput &clk, DigitalOutput &mosi, DigitalInput &miso)
virtual uint16_t GetNumReceived()
void SetClockActiveHigh()
virtual uint32_t GetModuleForRouting()
void SetSlaveSelect(DigitalOutput *ss, tFrameMode mode=kChipSelect, bool activeLow=false)
void SetSampleDataOnRising()
virtual uint32_t Read(bool initiate=false)
bool HadReceiveOverflow()
virtual void ClearReceivedData()
virtual void Write(uint32_t data)
void SetBitsPerWord(uint32_t bits)
virtual uint32_t GetChannelForRouting()
static DigitalModule * GetInstance(uint8_t moduleNumber)
void SetClockRate(double hz)
virtual void ApplyConfig()
virtual uint16_t GetOutputFIFOAvailable()
DigitalOutput * GetSlaveSelect(tFrameMode *mode=NULL, bool *activeLow=NULL)