blob: 874858b40eaa7f71f0a47980a545e3486a086855 [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
Brian Silverman7be68ba2020-01-08 22:08:40 -080010#include <hal/SPI.h>
Parker Schuhd3b7a8872018-02-19 16:42:27 -080011
James Kuszmaul9776b392023-01-14 14:08:08 -080012#include <cstring>
13#include <utility>
14
Austin Schuh9950f682021-11-06 15:27:58 -070015#include "absl/types/span.h"
Philipp Schrader790cb542023-07-05 21:06:52 -070016#include <wpi/SmallVector.h>
17#include <wpi/mutex.h>
18
Brian Silverman7be68ba2020-01-08 22:08:40 -080019#include "frc971/wpilib/ahal/DigitalSource.h"
20#include "frc971/wpilib/ahal/WPIErrors.h"
Parker Schuhd3b7a8872018-02-19 16:42:27 -080021
Brian Silverman7be68ba2020-01-08 22:08:40 -080022namespace frc {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080023
Brian Silverman7be68ba2020-01-08 22:08:40 -080024SPI::SPI(Port port) : m_port(static_cast<HAL_SPIPort>(port)) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080025 int32_t status = 0;
26 HAL_InitializeSPI(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080027 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080028}
29
Parker Schuhd3b7a8872018-02-19 16:42:27 -080030SPI::~SPI() { HAL_CloseSPI(m_port); }
31
Brian Silverman7be68ba2020-01-08 22:08:40 -080032void SPI::SetClockRate(int hz) { HAL_SetSPISpeed(m_port, hz); }
Parker Schuhd3b7a8872018-02-19 16:42:27 -080033
James Kuszmaul9776b392023-01-14 14:08:08 -080034void SPI::SetMode(Mode mode) {
35 m_mode = static_cast<HAL_SPIMode>(mode & 0x3);
36 HAL_SetSPIMode(m_port, m_mode);
Brian Silverman7be68ba2020-01-08 22:08:40 -080037}
38
39void SPI::SetSampleDataOnLeadingEdge() {
James Kuszmaul9776b392023-01-14 14:08:08 -080040 int mode = m_mode;
41 mode &= 2;
42 m_mode = static_cast<HAL_SPIMode>(mode);
43 HAL_SetSPIMode(m_port, m_mode);
Brian Silverman7be68ba2020-01-08 22:08:40 -080044}
45
46void SPI::SetSampleDataOnTrailingEdge() {
James Kuszmaul9776b392023-01-14 14:08:08 -080047 int mode = m_mode;
48 mode |= 2;
49 m_mode = static_cast<HAL_SPIMode>(mode);
50 HAL_SetSPIMode(m_port, m_mode);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080051}
52
Parker Schuhd3b7a8872018-02-19 16:42:27 -080053void SPI::SetClockActiveLow() {
James Kuszmaul9776b392023-01-14 14:08:08 -080054 int mode = m_mode;
55 mode |= 1;
56 m_mode = static_cast<HAL_SPIMode>(mode);
57 HAL_SetSPIMode(m_port, m_mode);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080058}
59
Parker Schuhd3b7a8872018-02-19 16:42:27 -080060void SPI::SetClockActiveHigh() {
James Kuszmaul9776b392023-01-14 14:08:08 -080061 int mode = m_mode;
62 mode &= 1;
63 m_mode = static_cast<HAL_SPIMode>(mode);
64 HAL_SetSPIMode(m_port, m_mode);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080065}
66
Parker Schuhd3b7a8872018-02-19 16:42:27 -080067void SPI::SetChipSelectActiveHigh() {
68 int32_t status = 0;
69 HAL_SetSPIChipSelectActiveHigh(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080070 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080071}
72
Parker Schuhd3b7a8872018-02-19 16:42:27 -080073void SPI::SetChipSelectActiveLow() {
74 int32_t status = 0;
75 HAL_SetSPIChipSelectActiveLow(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080076 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080077}
78
James Kuszmaul9776b392023-01-14 14:08:08 -080079int SPI::Write(uint8_t *data, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080080 int retVal = 0;
81 retVal = HAL_WriteSPI(m_port, data, size);
82 return retVal;
83}
84
James Kuszmaul9776b392023-01-14 14:08:08 -080085int SPI::Read(bool initiate, uint8_t *dataReceived, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080086 int retVal = 0;
87 if (initiate) {
Austin Schuhf6b94632019-02-02 22:11:27 -080088 wpi::SmallVector<uint8_t, 32> dataToSend;
Parker Schuhd3b7a8872018-02-19 16:42:27 -080089 dataToSend.resize(size);
90 retVal = HAL_TransactionSPI(m_port, dataToSend.data(), dataReceived, size);
91 } else {
92 retVal = HAL_ReadSPI(m_port, dataReceived, size);
93 }
94 return retVal;
95}
96
James Kuszmaul9776b392023-01-14 14:08:08 -080097int SPI::Transaction(uint8_t *dataToSend, uint8_t *dataReceived, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080098 int retVal = 0;
99 retVal = HAL_TransactionSPI(m_port, dataToSend, dataReceived, size);
100 return retVal;
101}
Brian Silverman7be68ba2020-01-08 22:08:40 -0800102
103void SPI::InitAuto(int bufferSize) {
104 int32_t status = 0;
105 HAL_InitSPIAuto(m_port, bufferSize, &status);
106 wpi_setHALError(status);
107}
108
109void SPI::FreeAuto() {
110 int32_t status = 0;
111 HAL_FreeSPIAuto(m_port, &status);
112 wpi_setHALError(status);
113}
114
Austin Schuh9950f682021-11-06 15:27:58 -0700115void SPI::SetAutoTransmitData(absl::Span<const uint8_t> dataToSend,
116 int zeroSize) {
Brian Silverman7be68ba2020-01-08 22:08:40 -0800117 int32_t status = 0;
118 HAL_SetSPIAutoTransmitData(m_port, dataToSend.data(), dataToSend.size(),
119 zeroSize, &status);
120 wpi_setHALError(status);
121}
122
123void SPI::StartAutoRate(double period) {
124 int32_t status = 0;
125 HAL_StartSPIAutoRate(m_port, period, &status);
126 wpi_setHALError(status);
127}
128
James Kuszmaul9776b392023-01-14 14:08:08 -0800129void SPI::StartAutoTrigger(DigitalSource &source, bool rising, bool falling) {
Brian Silverman7be68ba2020-01-08 22:08:40 -0800130 int32_t status = 0;
131 HAL_StartSPIAutoTrigger(
132 m_port, source.GetPortHandleForRouting(),
133 (HAL_AnalogTriggerType)source.GetAnalogTriggerTypeForRouting(), rising,
134 falling, &status);
135 wpi_setHALError(status);
136}
137
138void SPI::StopAuto() {
139 int32_t status = 0;
140 HAL_StopSPIAuto(m_port, &status);
141 wpi_setHALError(status);
142}
143
144void SPI::ForceAutoRead() {
145 int32_t status = 0;
146 HAL_ForceSPIAutoRead(m_port, &status);
147 wpi_setHALError(status);
148}
149
150int SPI::ReadAutoReceivedData(uint32_t *buffer, int numToRead, double timeout) {
151 int32_t status = 0;
James Kuszmaul9776b392023-01-14 14:08:08 -0800152 int32_t val =
153 HAL_ReadSPIAutoReceivedData(m_port, buffer, numToRead, timeout, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -0800154 wpi_setHALError(status);
155 return val;
156}
157
158int SPI::GetAutoDroppedCount() {
159 int32_t status = 0;
160 int32_t val = HAL_GetSPIAutoDroppedCount(m_port, &status);
161 wpi_setHALError(status);
162 return val;
163}
164
James Kuszmaul47d07032020-01-18 17:58:49 -0800165void SPI::ConfigureAutoStall(int csToSclkTicks, int stallTicks,
166 int pow2BytesPerRead) {
Brian Silverman7be68ba2020-01-08 22:08:40 -0800167 int32_t status = 0;
168 HAL_ConfigureSPIAutoStall(m_port, csToSclkTicks, stallTicks, pow2BytesPerRead,
169 &status);
170 wpi_setHALError(status);
171}
172
173} // namespace frc