blob: 85682100fa95d8bca65441fa1f6d16b3142ff6a0 [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>
11#include <wpi/SmallVector.h>
12#include <wpi/mutex.h>
Parker Schuhd3b7a8872018-02-19 16:42:27 -080013
James Kuszmaul9776b392023-01-14 14:08:08 -080014#include <cstring>
15#include <utility>
16
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
James Kuszmaul9776b392023-01-14 14:08:08 -080033void SPI::SetMode(Mode mode) {
34 m_mode = static_cast<HAL_SPIMode>(mode & 0x3);
35 HAL_SetSPIMode(m_port, m_mode);
Brian Silverman7be68ba2020-01-08 22:08:40 -080036}
37
38void SPI::SetSampleDataOnLeadingEdge() {
James Kuszmaul9776b392023-01-14 14:08:08 -080039 int mode = m_mode;
40 mode &= 2;
41 m_mode = static_cast<HAL_SPIMode>(mode);
42 HAL_SetSPIMode(m_port, m_mode);
Brian Silverman7be68ba2020-01-08 22:08:40 -080043}
44
45void SPI::SetSampleDataOnTrailingEdge() {
James Kuszmaul9776b392023-01-14 14:08:08 -080046 int mode = m_mode;
47 mode |= 2;
48 m_mode = static_cast<HAL_SPIMode>(mode);
49 HAL_SetSPIMode(m_port, m_mode);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080050}
51
Parker Schuhd3b7a8872018-02-19 16:42:27 -080052void SPI::SetClockActiveLow() {
James Kuszmaul9776b392023-01-14 14:08:08 -080053 int mode = m_mode;
54 mode |= 1;
55 m_mode = static_cast<HAL_SPIMode>(mode);
56 HAL_SetSPIMode(m_port, m_mode);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080057}
58
Parker Schuhd3b7a8872018-02-19 16:42:27 -080059void SPI::SetClockActiveHigh() {
James Kuszmaul9776b392023-01-14 14:08:08 -080060 int mode = m_mode;
61 mode &= 1;
62 m_mode = static_cast<HAL_SPIMode>(mode);
63 HAL_SetSPIMode(m_port, m_mode);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080064}
65
Parker Schuhd3b7a8872018-02-19 16:42:27 -080066void SPI::SetChipSelectActiveHigh() {
67 int32_t status = 0;
68 HAL_SetSPIChipSelectActiveHigh(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080069 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080070}
71
Parker Schuhd3b7a8872018-02-19 16:42:27 -080072void SPI::SetChipSelectActiveLow() {
73 int32_t status = 0;
74 HAL_SetSPIChipSelectActiveLow(m_port, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -080075 wpi_setHALError(status);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080076}
77
James Kuszmaul9776b392023-01-14 14:08:08 -080078int SPI::Write(uint8_t *data, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080079 int retVal = 0;
80 retVal = HAL_WriteSPI(m_port, data, size);
81 return retVal;
82}
83
James Kuszmaul9776b392023-01-14 14:08:08 -080084int SPI::Read(bool initiate, uint8_t *dataReceived, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080085 int retVal = 0;
86 if (initiate) {
Austin Schuhf6b94632019-02-02 22:11:27 -080087 wpi::SmallVector<uint8_t, 32> dataToSend;
Parker Schuhd3b7a8872018-02-19 16:42:27 -080088 dataToSend.resize(size);
89 retVal = HAL_TransactionSPI(m_port, dataToSend.data(), dataReceived, size);
90 } else {
91 retVal = HAL_ReadSPI(m_port, dataReceived, size);
92 }
93 return retVal;
94}
95
James Kuszmaul9776b392023-01-14 14:08:08 -080096int SPI::Transaction(uint8_t *dataToSend, uint8_t *dataReceived, int size) {
Parker Schuhd3b7a8872018-02-19 16:42:27 -080097 int retVal = 0;
98 retVal = HAL_TransactionSPI(m_port, dataToSend, dataReceived, size);
99 return retVal;
100}
Brian Silverman7be68ba2020-01-08 22:08:40 -0800101
102void SPI::InitAuto(int bufferSize) {
103 int32_t status = 0;
104 HAL_InitSPIAuto(m_port, bufferSize, &status);
105 wpi_setHALError(status);
106}
107
108void SPI::FreeAuto() {
109 int32_t status = 0;
110 HAL_FreeSPIAuto(m_port, &status);
111 wpi_setHALError(status);
112}
113
Austin Schuh9950f682021-11-06 15:27:58 -0700114void SPI::SetAutoTransmitData(absl::Span<const uint8_t> dataToSend,
115 int zeroSize) {
Brian Silverman7be68ba2020-01-08 22:08:40 -0800116 int32_t status = 0;
117 HAL_SetSPIAutoTransmitData(m_port, dataToSend.data(), dataToSend.size(),
118 zeroSize, &status);
119 wpi_setHALError(status);
120}
121
122void SPI::StartAutoRate(double period) {
123 int32_t status = 0;
124 HAL_StartSPIAutoRate(m_port, period, &status);
125 wpi_setHALError(status);
126}
127
James Kuszmaul9776b392023-01-14 14:08:08 -0800128void SPI::StartAutoTrigger(DigitalSource &source, bool rising, bool falling) {
Brian Silverman7be68ba2020-01-08 22:08:40 -0800129 int32_t status = 0;
130 HAL_StartSPIAutoTrigger(
131 m_port, source.GetPortHandleForRouting(),
132 (HAL_AnalogTriggerType)source.GetAnalogTriggerTypeForRouting(), rising,
133 falling, &status);
134 wpi_setHALError(status);
135}
136
137void SPI::StopAuto() {
138 int32_t status = 0;
139 HAL_StopSPIAuto(m_port, &status);
140 wpi_setHALError(status);
141}
142
143void SPI::ForceAutoRead() {
144 int32_t status = 0;
145 HAL_ForceSPIAutoRead(m_port, &status);
146 wpi_setHALError(status);
147}
148
149int SPI::ReadAutoReceivedData(uint32_t *buffer, int numToRead, double timeout) {
150 int32_t status = 0;
James Kuszmaul9776b392023-01-14 14:08:08 -0800151 int32_t val =
152 HAL_ReadSPIAutoReceivedData(m_port, buffer, numToRead, timeout, &status);
Brian Silverman7be68ba2020-01-08 22:08:40 -0800153 wpi_setHALError(status);
154 return val;
155}
156
157int SPI::GetAutoDroppedCount() {
158 int32_t status = 0;
159 int32_t val = HAL_GetSPIAutoDroppedCount(m_port, &status);
160 wpi_setHALError(status);
161 return val;
162}
163
James Kuszmaul47d07032020-01-18 17:58:49 -0800164void SPI::ConfigureAutoStall(int csToSclkTicks, int stallTicks,
165 int pow2BytesPerRead) {
Brian Silverman7be68ba2020-01-08 22:08:40 -0800166 int32_t status = 0;
167 HAL_ConfigureSPIAutoStall(m_port, csToSclkTicks, stallTicks, pow2BytesPerRead,
168 &status);
169 wpi_setHALError(status);
170}
171
172} // namespace frc