blob: dbac4aedcd38ae15dfb7fd89a71b15c2590d6c63 [file] [log] [blame]
Parker Schuhd3b7a8872018-02-19 16:42:27 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008-2017. All Rights Reserved. */
3/* 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
8#pragma once
9
10#include "HAL/SPI.h"
11
12namespace frc {
13
14class DigitalOutput;
15class DigitalInput;
16
17/**
18 * SPI bus interface class.
19 *
20 * This class is intended to be used by sensor (and other SPI device) drivers.
21 * It probably should not be used directly.
22 *
23 */
24class SPI {
25 public:
26 enum Port : int32_t {
27 kOnboardCS0 = 0,
28 kOnboardCS1,
29 kOnboardCS2,
30 kOnboardCS3,
31 kMXP
32 };
33 explicit SPI(Port SPIport);
34 virtual ~SPI();
35
36 SPI(const SPI &) = delete;
37 SPI &operator=(const SPI &) = delete;
38
Brian Silverman4f731492019-02-23 20:53:00 -080039 // Configure the rate of the generated clock signal.
40 //
41 // The claimed default value is 500,000Hz, and the claimed maximum value is
42 // 4,000,000Hz.
43 //
44 // This appears to have a very inflexible clocking setup. You can get 0.781MHz
45 // or 1.563MHz, but nothing in between. At least it rounds down the requested
46 // value like it should... 0.781MHz also appears to be the minimum.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080047 void SetClockRate(double hz);
48
Brian Silverman4f731492019-02-23 20:53:00 -080049 // Configure the order that bits are sent and received on the wire
50 // to be most significant bit first.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080051 void SetMSBFirst();
Brian Silverman4f731492019-02-23 20:53:00 -080052 // Configure the order that bits are sent and received on the wire
53 // to be least significant bit first.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080054 void SetLSBFirst();
55
Brian Silverman4f731492019-02-23 20:53:00 -080056 // Configure that the data is stable on the falling edge and the data
57 // changes on the rising edge.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080058 void SetSampleDataOnFalling();
Brian Silverman4f731492019-02-23 20:53:00 -080059 // Configure that the data is stable on the rising edge and the data
60 // changes on the falling edge.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080061 void SetSampleDataOnRising();
62
Brian Silverman4f731492019-02-23 20:53:00 -080063 // Configure the clock output line to be active low.
64 // This is sometimes called clock polarity high or clock idle high.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080065 void SetClockActiveLow();
Brian Silverman4f731492019-02-23 20:53:00 -080066 // Configure the clock output line to be active high.
67 // This is sometimes called clock polarity low or clock idle low.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080068 void SetClockActiveHigh();
69
Brian Silverman4f731492019-02-23 20:53:00 -080070 // Configure the chip select line to be active high.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080071 void SetChipSelectActiveHigh();
Brian Silverman4f731492019-02-23 20:53:00 -080072 // Configure the chip select line to be active low.
Parker Schuhd3b7a8872018-02-19 16:42:27 -080073 void SetChipSelectActiveLow();
74
Brian Silverman4f731492019-02-23 20:53:00 -080075 // Write data to the slave device. Blocks until there is space in the
76 // output FIFO.
77 //
78 // If not running in output only mode, also saves the data received
79 // on the MISO input during the transfer into the receive FIFO.
80 int Write(uint8_t *data, int size);
81 // Read a word from the receive FIFO.
82 //
83 // Waits for the current transfer to complete if the receive FIFO is empty.
84 //
85 // If the receive FIFO is empty, there is no active transfer, and initiate
86 // is false, errors.
87 //
88 // @param initiate If true, this function pushes "0" into the transmit buffer
89 // and initiates a transfer. If false, this function assumes
90 // that data is already in the receive FIFO from a previous
91 // write.
92 int Read(bool initiate, uint8_t *dataReceived, int size);
93 // Perform a simultaneous read/write transaction with the device
94 //
95 // @param dataToSend The data to be written out to the device
96 // @param dataReceived Buffer to receive data from the device
97 // @param size The length of the transaction, in bytes
98 int Transaction(uint8_t *dataToSend, uint8_t *dataReceived, int size);
Parker Schuhd3b7a8872018-02-19 16:42:27 -080099
100 protected:
101#ifdef WPILIB2017
102 int m_port;
103#else
104 HAL_SPIPort m_port;
105#endif
106 bool m_msbFirst = false; // default little-endian
107 bool m_sampleOnTrailing = false; // default data updated on falling edge
108 bool m_clk_idle_high = false; // default clock active high
109
110 private:
111 void Init();
112};
113
114} // namespace frc