blob: d51b20f00b6772615aed16c6ab5db9a5284b2485 [file] [log] [blame]
Parker Schuhd3b7a8872018-02-19 16:42:27 -08001/*----------------------------------------------------------------------------*/
Brian Silverman7be68ba2020-01-08 22:08:40 -08002/* Copyright (c) 2008-2019 FIRST. All Rights Reserved. */
Parker Schuhd3b7a8872018-02-19 16:42:27 -08003/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
Parker Schuhd3b7a8872018-02-19 16:42:27 -08008#include "frc971/wpilib/ahal/SPI.h"
9
10#include <cstring>
Brian Silverman7be68ba2020-01-08 22:08:40 -080011#include <utility>
Parker Schuhd3b7a8872018-02-19 16:42:27 -080012
Brian Silverman7be68ba2020-01-08 22:08:40 -080013#include <hal/SPI.h>
14#include <wpi/SmallVector.h>
15#include <wpi/mutex.h>
Parker Schuhd3b7a8872018-02-19 16:42:27 -080016
Austin Schuh9950f682021-11-06 15:27:58 -070017#include "absl/types/span.h"
Brian Silverman7be68ba2020-01-08 22:08:40 -080018#include "frc971/wpilib/ahal/DigitalSource.h"
19#include "frc971/wpilib/ahal/WPIErrors.h"
Parker Schuhd3b7a8872018-02-19 16:42:27 -080020
Brian Silverman7be68ba2020-01-08 22:08:40 -080021namespace frc {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080022
Brian Silverman7be68ba2020-01-08 22:08:40 -080023SPI::SPI(Port port) : m_port(static_cast<HAL_SPIPort>(port)) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080024 int32_t status = 0;
25 HAL_InitializeSPI(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080026 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080027}
28
Parker Schuhd3b7a8872018-02-19 16:42:27 -080029SPI::~SPI() { HAL_CloseSPI(m_port); }
30
Brian Silverman7be68ba2020-01-08 22:08:40 -080031void SPI::SetClockRate(int hz) { HAL_SetSPISpeed(m_port, hz); }
Parker Schuhd3b7a8872018-02-19 16:42:27 -080032
Parker Schuhd3b7a8872018-02-19 16:42:27 -080033void SPI::SetMSBFirst() {
34 m_msbFirst = true;
Brian Silverman7be68ba2020-01-08 22:08:40 -080035 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080036}
37
Parker Schuhd3b7a8872018-02-19 16:42:27 -080038void SPI::SetLSBFirst() {
39 m_msbFirst = false;
Brian Silverman7be68ba2020-01-08 22:08:40 -080040 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
41}
42
43void SPI::SetSampleDataOnLeadingEdge() {
44 m_sampleOnTrailing = false;
45 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
46}
47
48void SPI::SetSampleDataOnTrailingEdge() {
49 m_sampleOnTrailing = true;
50 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080051}
52
Parker Schuhd3b7a8872018-02-19 16:42:27 -080053void SPI::SetSampleDataOnFalling() {
54 m_sampleOnTrailing = true;
Brian Silverman7be68ba2020-01-08 22:08:40 -080055 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080056}
57
Parker Schuhd3b7a8872018-02-19 16:42:27 -080058void SPI::SetSampleDataOnRising() {
59 m_sampleOnTrailing = false;
Brian Silverman7be68ba2020-01-08 22:08:40 -080060 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080061}
62
Parker Schuhd3b7a8872018-02-19 16:42:27 -080063void SPI::SetClockActiveLow() {
Brian Silverman7be68ba2020-01-08 22:08:40 -080064 m_clockIdleHigh = true;
65 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080066}
67
Parker Schuhd3b7a8872018-02-19 16:42:27 -080068void SPI::SetClockActiveHigh() {
Brian Silverman7be68ba2020-01-08 22:08:40 -080069 m_clockIdleHigh = false;
70 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080071}
72
Parker Schuhd3b7a8872018-02-19 16:42:27 -080073void SPI::SetChipSelectActiveHigh() {
74 int32_t status = 0;
75 HAL_SetSPIChipSelectActiveHigh(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080076 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080077}
78
Parker Schuhd3b7a8872018-02-19 16:42:27 -080079void SPI::SetChipSelectActiveLow() {
80 int32_t status = 0;
81 HAL_SetSPIChipSelectActiveLow(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080082 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080083}
84
Brian Silverman7be68ba2020-01-08 22:08:40 -080085int SPI::Write(uint8_t* data, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080086 int retVal = 0;
87 retVal = HAL_WriteSPI(m_port, data, size);
88 return retVal;
89}
90
Brian Silverman7be68ba2020-01-08 22:08:40 -080091int SPI::Read(bool initiate, uint8_t* dataReceived, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080092 int retVal = 0;
93 if (initiate) {
Austin Schuhf6b94632019-02-02 22:11:27 -080094 wpi::SmallVector<uint8_t, 32> dataToSend;
Parker Schuhd3b7a8872018-02-19 16:42:27 -080095 dataToSend.resize(size);
96 retVal = HAL_TransactionSPI(m_port, dataToSend.data(), dataReceived, size);
97 } else {
98 retVal = HAL_ReadSPI(m_port, dataReceived, size);
99 }
100 return retVal;
101}
102
Brian Silverman7be68ba2020-01-08 22:08:40 -0800103int SPI::Transaction(uint8_t* dataToSend, uint8_t* dataReceived, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -0800104 int retVal = 0;
105 retVal = HAL_TransactionSPI(m_port, dataToSend, dataReceived, size);
106 return retVal;
107}
Brian Silverman7be68ba2020-01-08 22:08:40 -0800108
109void SPI::InitAuto(int bufferSize) {
110 int32_t status = 0;
111 HAL_InitSPIAuto(m_port, bufferSize, &status);
112 wpi_setHALError(status);
113}
114
115void SPI::FreeAuto() {
116 int32_t status = 0;
117 HAL_FreeSPIAuto(m_port, &status);
118 wpi_setHALError(status);
119}
120
Austin Schuh9950f682021-11-06 15:27:58 -0700121void SPI::SetAutoTransmitData(absl::Span<const uint8_t> dataToSend,
122 int zeroSize) {
Brian Silverman7be68ba2020-01-08 22:08:40 -0800123 int32_t status = 0;
124 HAL_SetSPIAutoTransmitData(m_port, dataToSend.data(), dataToSend.size(),
125 zeroSize, &status);
126 wpi_setHALError(status);
127}
128
129void SPI::StartAutoRate(double period) {
130 int32_t status = 0;
131 HAL_StartSPIAutoRate(m_port, period, &status);
132 wpi_setHALError(status);
133}
134
135void SPI::StartAutoTrigger(DigitalSource& source, bool rising, bool falling) {
136 int32_t status = 0;
137 HAL_StartSPIAutoTrigger(
138 m_port, source.GetPortHandleForRouting(),
139 (HAL_AnalogTriggerType)source.GetAnalogTriggerTypeForRouting(), rising,
140 falling, &status);
141 wpi_setHALError(status);
142}
143
144void SPI::StopAuto() {
145 int32_t status = 0;
146 HAL_StopSPIAuto(m_port, &status);
147 wpi_setHALError(status);
148}
149
150void SPI::ForceAutoRead() {
151 int32_t status = 0;
152 HAL_ForceSPIAutoRead(m_port, &status);
153 wpi_setHALError(status);
154}
155
156int SPI::ReadAutoReceivedData(uint32_t *buffer, int numToRead, double timeout) {
157 int32_t status = 0;
158 int32_t val = HAL_ReadSPIAutoReceivedData(m_port, buffer, numToRead,
159 timeout, &status);
160 wpi_setHALError(status);
161 return val;
162}
163
164int SPI::GetAutoDroppedCount() {
165 int32_t status = 0;
166 int32_t val = HAL_GetSPIAutoDroppedCount(m_port, &status);
167 wpi_setHALError(status);
168 return val;
169}
170
James Kuszmaul47d07032020-01-18 17:58:49 -0800171void SPI::ConfigureAutoStall(int csToSclkTicks, int stallTicks,
172 int pow2BytesPerRead) {
Brian Silverman7be68ba2020-01-08 22:08:40 -0800173 int32_t status = 0;
174 HAL_ConfigureSPIAutoStall(m_port, csToSclkTicks, stallTicks, pow2BytesPerRead,
175 &status);
176 wpi_setHALError(status);
177}
178
179} // namespace frc