blob: 2e8a2fc2db7ddc46ceb6a6da053814f684427117 [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
Brian Silverman7be68ba2020-01-08 22:08:40 -080017#include "frc971/wpilib/ahal/DigitalSource.h"
18#include "frc971/wpilib/ahal/WPIErrors.h"
Parker Schuhd3b7a8872018-02-19 16:42:27 -080019
Brian Silverman7be68ba2020-01-08 22:08:40 -080020namespace frc {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080021
Brian Silverman7be68ba2020-01-08 22:08:40 -080022SPI::SPI(Port port) : m_port(static_cast<HAL_SPIPort>(port)) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080023 int32_t status = 0;
24 HAL_InitializeSPI(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080025 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080026}
27
Parker Schuhd3b7a8872018-02-19 16:42:27 -080028SPI::~SPI() { HAL_CloseSPI(m_port); }
29
Brian Silverman7be68ba2020-01-08 22:08:40 -080030void SPI::SetClockRate(int hz) { HAL_SetSPISpeed(m_port, hz); }
Parker Schuhd3b7a8872018-02-19 16:42:27 -080031
Parker Schuhd3b7a8872018-02-19 16:42:27 -080032void SPI::SetMSBFirst() {
33 m_msbFirst = true;
Brian Silverman7be68ba2020-01-08 22:08:40 -080034 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080035}
36
Parker Schuhd3b7a8872018-02-19 16:42:27 -080037void SPI::SetLSBFirst() {
38 m_msbFirst = false;
Brian Silverman7be68ba2020-01-08 22:08:40 -080039 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
40}
41
42void SPI::SetSampleDataOnLeadingEdge() {
43 m_sampleOnTrailing = false;
44 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
45}
46
47void SPI::SetSampleDataOnTrailingEdge() {
48 m_sampleOnTrailing = true;
49 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080050}
51
Parker Schuhd3b7a8872018-02-19 16:42:27 -080052void SPI::SetSampleDataOnFalling() {
53 m_sampleOnTrailing = true;
Brian Silverman7be68ba2020-01-08 22:08:40 -080054 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080055}
56
Parker Schuhd3b7a8872018-02-19 16:42:27 -080057void SPI::SetSampleDataOnRising() {
58 m_sampleOnTrailing = false;
Brian Silverman7be68ba2020-01-08 22:08:40 -080059 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080060}
61
Parker Schuhd3b7a8872018-02-19 16:42:27 -080062void SPI::SetClockActiveLow() {
Brian Silverman7be68ba2020-01-08 22:08:40 -080063 m_clockIdleHigh = true;
64 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080065}
66
Parker Schuhd3b7a8872018-02-19 16:42:27 -080067void SPI::SetClockActiveHigh() {
Brian Silverman7be68ba2020-01-08 22:08:40 -080068 m_clockIdleHigh = false;
69 HAL_SetSPIOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080070}
71
Parker Schuhd3b7a8872018-02-19 16:42:27 -080072void SPI::SetChipSelectActiveHigh() {
73 int32_t status = 0;
74 HAL_SetSPIChipSelectActiveHigh(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080075 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080076}
77
Parker Schuhd3b7a8872018-02-19 16:42:27 -080078void SPI::SetChipSelectActiveLow() {
79 int32_t status = 0;
80 HAL_SetSPIChipSelectActiveLow(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080081 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080082}
83
Brian Silverman7be68ba2020-01-08 22:08:40 -080084int SPI::Write(uint8_t* data, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080085 int retVal = 0;
86 retVal = HAL_WriteSPI(m_port, data, size);
87 return retVal;
88}
89
Brian Silverman7be68ba2020-01-08 22:08:40 -080090int SPI::Read(bool initiate, uint8_t* dataReceived, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080091 int retVal = 0;
92 if (initiate) {
Austin Schuhf6b94632019-02-02 22:11:27 -080093 wpi::SmallVector<uint8_t, 32> dataToSend;
Parker Schuhd3b7a8872018-02-19 16:42:27 -080094 dataToSend.resize(size);
95 retVal = HAL_TransactionSPI(m_port, dataToSend.data(), dataReceived, size);
96 } else {
97 retVal = HAL_ReadSPI(m_port, dataReceived, size);
98 }
99 return retVal;
100}
101
Brian Silverman7be68ba2020-01-08 22:08:40 -0800102int SPI::Transaction(uint8_t* dataToSend, uint8_t* dataReceived, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -0800103 int retVal = 0;
104 retVal = HAL_TransactionSPI(m_port, dataToSend, dataReceived, size);
105 return retVal;
106}
Brian Silverman7be68ba2020-01-08 22:08:40 -0800107
108void SPI::InitAuto(int bufferSize) {
109 int32_t status = 0;
110 HAL_InitSPIAuto(m_port, bufferSize, &status);
111 wpi_setHALError(status);
112}
113
114void SPI::FreeAuto() {
115 int32_t status = 0;
116 HAL_FreeSPIAuto(m_port, &status);
117 wpi_setHALError(status);
118}
119
120void SPI::SetAutoTransmitData(wpi::ArrayRef<uint8_t> dataToSend, int zeroSize) {
121 int32_t status = 0;
122 HAL_SetSPIAutoTransmitData(m_port, dataToSend.data(), dataToSend.size(),
123 zeroSize, &status);
124 wpi_setHALError(status);
125}
126
127void SPI::StartAutoRate(double period) {
128 int32_t status = 0;
129 HAL_StartSPIAutoRate(m_port, period, &status);
130 wpi_setHALError(status);
131}
132
133void SPI::StartAutoTrigger(DigitalSource& source, bool rising, bool falling) {
134 int32_t status = 0;
135 HAL_StartSPIAutoTrigger(
136 m_port, source.GetPortHandleForRouting(),
137 (HAL_AnalogTriggerType)source.GetAnalogTriggerTypeForRouting(), rising,
138 falling, &status);
139 wpi_setHALError(status);
140}
141
142void SPI::StopAuto() {
143 int32_t status = 0;
144 HAL_StopSPIAuto(m_port, &status);
145 wpi_setHALError(status);
146}
147
148void SPI::ForceAutoRead() {
149 int32_t status = 0;
150 HAL_ForceSPIAutoRead(m_port, &status);
151 wpi_setHALError(status);
152}
153
154int SPI::ReadAutoReceivedData(uint32_t *buffer, int numToRead, double timeout) {
155 int32_t status = 0;
156 int32_t val = HAL_ReadSPIAutoReceivedData(m_port, buffer, numToRead,
157 timeout, &status);
158 wpi_setHALError(status);
159 return val;
160}
161
162int SPI::GetAutoDroppedCount() {
163 int32_t status = 0;
164 int32_t val = HAL_GetSPIAutoDroppedCount(m_port, &status);
165 wpi_setHALError(status);
166 return val;
167}
168
169void SPI::ConfigureAutoStall(HAL_SPIPort /*port*/, int csToSclkTicks,
170 int stallTicks, int pow2BytesPerRead) {
171 int32_t status = 0;
172 HAL_ConfigureSPIAutoStall(m_port, csToSclkTicks, stallTicks, pow2BytesPerRead,
173 &status);
174 wpi_setHALError(status);
175}
176
177} // namespace frc