-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRHSPIDriver.cpp
More file actions
133 lines (114 loc) · 3.52 KB
/
Copy pathRHSPIDriver.cpp
File metadata and controls
133 lines (114 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// RHSPIDriver.cpp
//
// Copyright (C) 2014 Mike McCauley
// $Id: RHSPIDriver.cpp,v 1.13 2020/08/04 09:02:14 mikem Exp $
#include <RHSPIDriver.h>
RHSPIDriver::RHSPIDriver(uint8_t slaveSelectPin, RHGenericSPI& spi)
:
_spi(spi),
_slaveSelectPin(slaveSelectPin)
{
}
bool RHSPIDriver::init()
{
// start the SPI library with the default speeds etc:
// On Arduino Due this defaults to SPI1 on the central group of 6 SPI pins
_spi.begin();
#if (RH_PLATFORM == RH_PLATFORM_ARDUINO && defined(ARDUINO_LORA_E5_MINI))
SubGhz.setResetActive(false);
// while (SubGhz.isBusy()) ; // Wait for radio to wake up, hmm sometimes hangs forever!
#endif
// Initialise the slave select pin
// On Maple, this must be _after_ spi.begin
// Sometimes we dont want to work the _slaveSelectPin here
if (_slaveSelectPin != 0xff)
pinMode(_slaveSelectPin, OUTPUT);
deselectSlave();
// This delay is needed for ATMega and maybe some others, but
// 100ms is too long for STM32L0, and somehow can cause the USB interface to fail
// in some versions of the core.
#if (RH_PLATFORM == RH_PLATFORM_STM32L0) && (defined STM32L082xx || defined STM32L072xx)
delay(10);
#else
delay(100);
#endif
return true;
}
uint8_t RH_INTERRUPT_ATTR RHSPIDriver::spiRead(uint8_t reg)
{
uint8_t val = 0;
ATOMIC_BLOCK_START;
beginTransaction();
_spi.transfer(reg & ~RH_SPI_WRITE_MASK); // Send the address with the write mask off
val = _spi.transfer(0); // The written value is ignored, reg value is read
endTransaction();
ATOMIC_BLOCK_END;
return val;
}
uint8_t RH_INTERRUPT_ATTR RHSPIDriver::spiWrite(uint8_t reg, uint8_t val)
{
uint8_t status = 0;
ATOMIC_BLOCK_START;
beginTransaction();
status = _spi.transfer(reg | RH_SPI_WRITE_MASK); // Send the address with the write mask on
_spi.transfer(val); // New value follows
// Based on https://forum.pjrc.com/attachment.php?attachmentid=10948&d=1499109224
// Need this delay from some processors when running fast:
delayMicroseconds(1);
endTransaction();
ATOMIC_BLOCK_END;
return status;
}
uint8_t RH_INTERRUPT_ATTR RHSPIDriver::spiBurstRead(uint8_t reg, uint8_t* dest, uint8_t len)
{
uint8_t status = 0;
ATOMIC_BLOCK_START;
beginTransaction();
status = _spi.transfer(reg & ~RH_SPI_WRITE_MASK); // Send the start address with the write mask off
while (len--)
*dest++ = _spi.transfer(0);
endTransaction();
ATOMIC_BLOCK_END;
return status;
}
uint8_t RH_INTERRUPT_ATTR RHSPIDriver::spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len)
{
uint8_t status = 0;
ATOMIC_BLOCK_START;
beginTransaction();
status = _spi.transfer(reg | RH_SPI_WRITE_MASK); // Send the start address with the write mask on
while (len--)
_spi.transfer(*src++);
endTransaction();
ATOMIC_BLOCK_END;
return status;
}
void RHSPIDriver::setSlaveSelectPin(uint8_t slaveSelectPin)
{
_slaveSelectPin = slaveSelectPin;
}
void RHSPIDriver::spiUsingInterrupt(uint8_t interruptNumber)
{
_spi.usingInterrupt(interruptNumber);
}
void RHSPIDriver::beginTransaction()
{
_spi.beginTransaction();
selectSlave();
}
void RHSPIDriver::endTransaction()
{
deselectSlave();
_spi.endTransaction();
}
// Some platforms (ABZ) need to override just selectSlave and deselectSlave
void RHSPIDriver::selectSlave()
{
if (_slaveSelectPin != 0xff)
digitalWrite(_slaveSelectPin, LOW);
}
void RHSPIDriver::deselectSlave()
{
if (_slaveSelectPin != 0xff)
digitalWrite(_slaveSelectPin, HIGH);
}