blob: 5d10a15c186d83a737a77fc11bc3c48e1ea852ff (
plain)
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
|
/*****************************************************************************
# #
# KVMD - The main PiKVM daemon. #
# #
# Copyright (C) 2018-2021 Maxim Devaev <[email protected]> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
# #
*****************************************************************************/
#include "spi.h"
#include <Arduino.h>
#include <SPI.h>
static volatile uint8_t _spi_in[8] = {0};
static volatile uint8_t _spi_in_index = 0;
static volatile uint8_t _spi_out[8] = {0};
static volatile uint8_t _spi_out_index = 0;
void spiBegin() {
pinMode(MISO, OUTPUT);
SPCR = (1 << SPE) | (1 << SPIE); // Slave, SPI En, IRQ En
}
bool spiReady() {
return (!_spi_out[0] && _spi_in_index == 8);
}
const uint8_t *spiGet() {
return (const uint8_t *)_spi_in;
}
void spiWrite(const uint8_t *data) {
// Меджик в нулевом байте разрешает начать ответ
for (int index = 7; index >= 0; --index) {
_spi_out[index] = data[index];
}
}
ISR(SPI_STC_vect) {
uint8_t in = SPDR;
if (_spi_out[0] && _spi_out_index < 8) {
SPDR = _spi_out[_spi_out_index];
if (!(SPSR & (1 << WCOL))) {
++_spi_out_index;
if (_spi_out_index == 8) {
_spi_out_index = 0;
_spi_in_index = 0;
_spi_out[0] = 0;
}
}
} else {
static bool receiving = false;
if (!receiving && in != 0) {
receiving = true;
}
if (receiving && _spi_in_index < 8) {
_spi_in[_spi_in_index] = in;
++_spi_in_index;
}
if (_spi_in_index == 8) {
receiving = false;
}
SPDR = 0;
}
}
|