uC chip interface arduino  0.9.0
A interface for async and neuromrphic IC testing
Loading...
Searching...
No Matches
interface_spi.cpp
Go to the documentation of this file.
1/*
2 This file is part of the Firmware project to interface with small Async or Neuromorphic chips
3 Copyright (C) 2022-2023 Ole Richter - University of Groningen
4 Copyright (C) 2022 Benjamin Hucko
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20#include "interface_spi.h"
21#include "uc_boards.h"
22
29
30#pragma pack(push,1)
32 uint8_t bytes[4];
33 uint32_t data;
34};
35#pragma pack(pop)
36
37void Interface_spi::configure(uint8_t id, uint8_t config_option, uint8_t data){
38
39 if (id >= SPI_NUMBER_OF_INTERFACES) {
41 return;
42 }
43 uint8_t interface;
44 switch (id){
45 default:
46 case 0: interface = IN_CONF_SPI0; break;
47 case 1: interface = IN_CONF_SPI1; break;
48 case 2: interface = IN_CONF_SPI2; break;
49 }
50 if (Interface_spi::active[id] == 1) error_message(OUT_ERROR_INTERFACE_ALREADY_ACTIVE,interface,config_option);
51 else {
52 switch (config_option){
53 case CONF_ACTIVE:
59 send_config(interface,config_option,1);
60 return;
61 case CONF_WIDTH:
62 if (data > 4 || data <=0) {
63 error_message(OUT_ERROR_CONFIGURATION_OUT_OF_BOUNDS,interface,data,config_option);
64 return;
65 }
66 Interface_spi::width[id] = data;
67 send_config(interface,config_option,data);
68 return;
69 case CONF_BYTE_ORDER:
70 if (data > 0){
72 send_config(interface,config_option,1);
73 }
74 else{
75 Interface_spi::byte_order[id] = false;
76 send_config(interface,config_option,0);
77 }
78 return;
80 switch (data){
81 case 0:
82 Interface_spi::frequency[id] = 10000U;
83 break;
84 case 1:
85 Interface_spi::frequency[id] = 50000U;
86 break;
87 default:
88 case 2:
89 Interface_spi::frequency[id] = 100000U;
90 send_config(interface,config_option,2);
91 return;
92 case 3:
93 Interface_spi::frequency[id] = 500000U;
94 break;
95 case 4:
96 Interface_spi::frequency[id] = 1000000U;
97 break;
98 case 5:
99 Interface_spi::frequency[id] = 2000000U;
100 break;
101 case 6:
102 Interface_spi::frequency[id] = 4000000U;
103 break;
104 case 7:
105 Interface_spi::frequency[id] = 8000000U;
106 break;
107 case 8:
108 Interface_spi::frequency[id] = 12000000U;
109 break;
110 }
111 send_config(interface,config_option,data);
112 return;
113
114 case CONF_TYPE:
115 switch (data){
116 default:
117 case 0:
118 Interface_spi::mode[id] = SPI_MODE0;
119 send_config(interface,config_option,0);
120 return;
121 case 1:
122 Interface_spi::mode[id] = SPI_MODE1;
123 break;
124 case 2:
125 Interface_spi::mode[id] = SPI_MODE2;
126 break;
127 case 3:
128 Interface_spi::mode[id] = SPI_MODE3;
129 break;
130 }
131 send_config(interface,config_option,data);
132 return;
133
134 default:
136 return;
137 }
138 }
139}
140
141Interface_spi::Interface_spi(uint8_t id, uint32_t frequency, uint8_t width, uint8_t mode, bool byte_order){
142 if (id >= SPI_NUMBER_OF_INTERFACES) {
144 return;
145 }
146 uint8_t interface;
147 switch (id){
148 default:
149 case 0: interface = IN_CONF_SPI0; break;
150 case 1: interface = IN_CONF_SPI1; break;
151 case 2: interface = IN_CONF_SPI2; break;
152 }
153 _id=id;
155 if (width == 0) {
156 _width = 1;
157 send_config(interface,CONF_WIDTH,1);
158 }
159 else _width=width;
160 if (mode != SPI_MODE0 ||mode != SPI_MODE1 ||mode != SPI_MODE2 ||mode != SPI_MODE3 ) {
161 _mode = SPI_MODE0;
162 send_config(interface,CONF_TYPE,0);
163 }
164 else _mode=mode;
166 switch (_id){
167 default:
168 case 0:
170 _spi = &SPI;
171 _spi->begin();
173 // send confimation
174 send_config(interface,CONF_ACTIVE,1);
175 }
176 break;
177 #if (SPI_NUMBER_OF_INTERFACES > 1)
178 case 1:
179 if (reserve_input_pin(SPI_SCK1_PORT) && reserve_output_pin(SPI_CIPO1_PORT) && reserve_output_pin(SPI_COPI1_PORT)){
180 _spi = &SPI1;
181 _spi->begin();
183 // send confimation
184 send_config(interface,CONF_ACTIVE,1);
185 }
186 break;
187 #endif
188 #if (SPI_NUMBER_OF_INTERFACES > 2)
189 case 2:
190 if (reserve_input_pin(SPI_SCK2_PORT) && reserve_output_pin(SPI_CIPO2_PORT) && reserve_output_pin(SPI_COPI2_PORT)){
191 _spi = &SPI2;
192 _spi->begin();
194 // send confimation
195 send_config(interface,CONF_ACTIVE,1);
196 }
197 break;
198 #endif
199 }
200}
201void Interface_spi::send_packet(uint8_t id, uint32_t data){
202 if (id >= SPI_NUMBER_OF_INTERFACES) {
204 return;
205 }
206 else if (!Interface_spi::active[id]){
207 switch (id){
208 default:
212 }
213 }
214 else{
215 Interface_spi::inst[id]->write(data);
216 }
217}
218
219void Interface_spi::write(uint32_t data) volatile {
220 bytepack_t buffer;
221 uint8_t interface_in, interface_out;
222 //@TODO class var
223 switch (_id){
224 default:
225 case 0: interface_in = IN_SPI0; interface_out = OUT_SPI0; break;
226 case 1: interface_in = IN_SPI1; interface_out = OUT_SPI1; break;
227 case 2: interface_in = IN_SPI2; interface_out = OUT_SPI2; break;
228 }
229 if (data >= pow(2,(8*Interface_spi::width[_id]))){
231 return;
232 }
233 buffer.data = data;
234 _spi->beginTransaction(SPISettings(Interface_spi::frequency[_id],
235 Interface_spi::byte_order[_id] ? MSBFIRST : LSBFIRST,
236 (Interface_spi::mode[_id] == 3) ? SPI_MODE3 :
237 ((Interface_spi::mode[_id] == 2) ? SPI_MODE2 :
238 ((Interface_spi::mode[_id] == 1) ? SPI_MODE1 : SPI_MODE0))));
239 _spi->transfer(buffer.bytes,Interface_spi::width[_id]);
240 _spi->endTransaction();
241
242 send_data32(interface_in,data,true);
243 send_data32(interface_out,buffer.data);
244}
static volatile bool byte_order[SPI_NUMBER_OF_INTERFACES]
Definition: interface_spi.h:51
uint32_t _frequency
Definition: interface_spi.h:79
Interface_spi(uint8_t id, uint32_t frequency=100000U, uint8_t width=1, uint8_t mode=0, bool byte_order=false)
static void send_packet(uint8_t id, uint32_t data)
static void configure(uint8_t id, uint8_t config_option, uint8_t data)
static volatile uint8_t mode[SPI_NUMBER_OF_INTERFACES]
Definition: interface_spi.h:50
arduino::SPIClass * _spi
Definition: interface_spi.h:83
uint8_t _width
Definition: interface_spi.h:77
void write(uint32_t data) volatile
static volatile Interface_spi * inst[SPI_NUMBER_OF_INTERFACES]
Definition: interface_spi.h:57
static volatile uint32_t frequency[SPI_NUMBER_OF_INTERFACES]
Definition: interface_spi.h:49
static volatile bool active[SPI_NUMBER_OF_INTERFACES]
Definition: interface_spi.h:52
static volatile uint8_t width[SPI_NUMBER_OF_INTERFACES]
Definition: interface_spi.h:48
void error_message(uint8_t error_header, uint8_t source_header, uint32_t value, uint8_t sub_source_header)
void send_data32(uint8_t header, uint32_t value, bool is_confirmation)
void send_config(uint8_t header, uint8_t config_header, uint8_t value)
@ IN_CONF_SPI2
Definition: datatypes.h:213
@ IN_CONF_SPI1
Definition: datatypes.h:206
@ IN_SPI1
Definition: datatypes.h:101
@ IN_SPI2
Definition: datatypes.h:107
@ IN_CONF_SPI0
Definition: datatypes.h:199
@ IN_SPI0
Definition: datatypes.h:95
@ CONF_TYPE
Definition: datatypes.h:669
@ CONF_SPEED_CLASS
Definition: datatypes.h:664
@ CONF_ACTIVE
Definition: datatypes.h:618
@ CONF_WIDTH
Definition: datatypes.h:649
@ CONF_BYTE_ORDER
Definition: datatypes.h:660
@ OUT_ERROR_INTERFACE_NOT_ACTIVE
Definition: datatypes.h:557
@ OUT_SPI1
Definition: datatypes.h:432
@ OUT_SPI2
Definition: datatypes.h:439
@ OUT_ERROR_UNKNOWN_CONFIGURATION
Definition: datatypes.h:562
@ OUT_ERROR_INTERFACE_ALREADY_ACTIVE
Definition: datatypes.h:547
@ OUT_SPI0
Definition: datatypes.h:425
@ OUT_ERROR_DATA_OUT_OF_BOUNDS
Definition: datatypes.h:585
@ OUT_ERROR_CONFIGURATION_OUT_OF_BOUNDS
Definition: datatypes.h:579
bool reserve_output_pin(uint8_t id, uint8_t from_instruction)
bool reserve_input_pin(uint8_t id, uint8_t from_instruction)
@ SPI_SCK_PORT
Definition: uc_boards.h:119
@ SPI_COPI_PORT
Definition: uc_boards.h:120
@ SPI_CIPO_PORT
Definition: uc_boards.h:121
#define SPI_NUMBER_OF_INTERFACES
Definition: uc_boards.h:117
uint32_t data
uint8_t bytes[4]