uC chip interface arduino  0.9.0
A interface for async and neuromrphic IC testing
Loading...
Searching...
No Matches
interface_AER_to_chip.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 Matteo Cartiglia - University of Zurich
4 Copyright (C) 2022-2023 Ole Richter - University of Groningen
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*/
20#include "misc_functions.h"
21
22volatile uint8_t AER_to_chip::data_pins[8][32] = {};
23volatile uint8_t AER_to_chip::data_width[8] = {};
24volatile uint8_t AER_to_chip::req_pin[8] = {};
25volatile uint8_t AER_to_chip::ack_pin[8] = {};
26volatile uint8_t AER_to_chip::req_delay[8] = {};
27volatile uint8_t AER_to_chip::type[8] = {};
28volatile bool AER_to_chip::hs_lowactive[8] = {};
29volatile bool AER_to_chip::data_lowactive[8] = {};
30volatile bool AER_to_chip::active[8] = {};
31volatile AER_to_chip* AER_to_chip::inst[8] = {};
32
33void AER_to_chip::configure(uint8_t id, uint8_t config, uint8_t data){
34 if (id >= 8) {
36 return;
37 }
38
39 uint8_t interface;
40 switch(id){
41 case 0: interface = IN_CONF_ASYNC_TO_CHIP0; break;
42 case 1: interface = IN_CONF_ASYNC_TO_CHIP1; break;
43 case 2: interface = IN_CONF_ASYNC_TO_CHIP2; break;
44 case 3: interface = IN_CONF_ASYNC_TO_CHIP3; break;
45 case 4: interface = IN_CONF_ASYNC_TO_CHIP4; break;
46 case 5: interface = IN_CONF_ASYNC_TO_CHIP5; break;
47 case 6: interface = IN_CONF_ASYNC_TO_CHIP6; break;
48 case 7: interface = IN_CONF_ASYNC_TO_CHIP7; break;
49 default:interface = OUT_ERROR; break;
50 }
51
52
53 switch (config){
54 case CONF_ACTIVE:
55 AER_to_chip::inst[id] = new AER_to_chip(id,
62 if (AER_to_chip::active[id]){
63 // send confirmation
64 send_config(interface,config,AER_to_chip::active[id]);
65 }
66 return;
67 case CONF_REQ:
68 AER_to_chip::req_pin[id] = data;
69 // send confirmation
70 break;
71 case CONF_ACK:
72 AER_to_chip::ack_pin[id] = data;
73 break;
74 case CONF_WIDTH:
75 if (data > 32) {
78 // send confirmation
79 send_config(interface,config,32);
80 return;
81 }
82 else {
83 AER_to_chip::data_width[id] = data;
84 }
85 break;
86 case CONF_REQ_DELAY:
87 AER_to_chip::req_delay[id] = data;
88 break;
89 case CONF_TYPE:
90 // replace by class
92 AER_to_chip::type[id] = data;
93 break;
94 default:
95 if (config < 32){
96 AER_to_chip::data_pins[id][config] = data;
97 }
98 else {
100 return;
101 }
102 }
103 //send confirmation
104 send_config(interface,config,data);
105
106}
107
108void AER_to_chip::send_packet(uint8_t id, uint32_t data, uint8_t header){
109 if (AER_to_chip::active[id]){
110 if (AER_to_chip::inst[id]->dataWrite(data)){
111 // send confimation
112 send_data32(header,data,true);
113 }
114 }
115 else {
117 }
118}
119
120
121
122//---------------------------------------------------------------------------------------------------------------------------------------
123// Class constructor; initialises the AER_to_chip object and sets up the relevant pins on Teensy
124//---------------------------------------------------------------------------------------------------------------------------------------
125
126AER_to_chip::AER_to_chip(uint8_t id, uint8_t reqPin, uint8_t ackPin, volatile uint8_t dataPins[], uint8_t numDataPins, uint8_t delay, bool activeLow)
127{
128 _reqPin = reqPin;
129 _ackPin = ackPin;
130 _dataPins = dataPins;
131 _numDataPins = numDataPins;
132 _delay = delay;
133 _activeLow = activeLow;
134 _id = id;
135 if (id >= 8) {
137 return;
138 }
139 AER_to_chip::active[id] = setupPins();
140}
141
142//---------------------------------------------------------------------------------------------------------------------------------------
143// dataWrite: Executes REQ/ACK handshake and writes to chip
144//---------------------------------------------------------------------------------------------------------------------------------------
145
146bool AER_to_chip::dataWrite(uint32_t data) volatile
147{
148 unsigned long t0 = micros();
149 bool handshakeStatus = true;
150
151 setData(data);
152 interrupts();
153 reqWrite(1);
154
155 while(!ackRead()) {
156 //
157 if (micros() > t0 + AER_HANDSHAKE_TIMEOUT*1000) {
158 handshakeStatus = false;
159 uint8_t interface;
160 switch(_id){
161 case 0: interface = IN_ASYNC_TO_CHIP0; break;
162 case 1: interface = IN_ASYNC_TO_CHIP1; break;
163 case 2: interface = IN_ASYNC_TO_CHIP2; break;
164 case 3: interface = IN_ASYNC_TO_CHIP3; break;
165 case 4: interface = IN_ASYNC_TO_CHIP4; break;
166 case 5: interface = IN_ASYNC_TO_CHIP5; break;
167 case 6: interface = IN_ASYNC_TO_CHIP6; break;
168 case 7: interface = IN_ASYNC_TO_CHIP7; break;
169 default:interface = IN_ASYNC_TO_CHIP0; break; //should never happen
170 }
172 break;
173 }
174 }
175
176 reqWrite(0);
177
178 return handshakeStatus;
179}
180
181//---------------------------------------------------------------------------------------------------------------------------------------
182// setupPins: Sets up the relevant pins for communication
183//---------------------------------------------------------------------------------------------------------------------------------------
184
185bool AER_to_chip::setupPins() {
186 if (reserve_input_pin(_ackPin)) pinMode(_ackPin, INPUT);
187 else return false;
188 if (reserve_output_pin(_reqPin)) pinMode(_reqPin, OUTPUT);
189 else return false;
190
191 for(int i = 0; i < _numDataPins; i++) {
192 if (reserve_output_pin(_dataPins[i])) pinMode(_dataPins[i], OUTPUT);
193 else return false;
194 }
195 return true;
196}
197
198
199//---------------------------------------------------------------------------------------------------------------------------------------
200// ackRead: Reads ACK pin state
201//---------------------------------------------------------------------------------------------------------------------------------------
202
203bool AER_to_chip::ackRead() volatile
204{
205 #if defined(TEENSYDUINO)
206 return digitalReadFast(_ackPin)^_activeLow;
207 #else
208 return digitalRead(_ackPin)^_activeLow;
209 #endif
210}
211
212
213//---------------------------------------------------------------------------------------------------------------------------------------
214// reqWrite: Writes to REQ pin
215//---------------------------------------------------------------------------------------------------------------------------------------
216
217void AER_to_chip::reqWrite(bool val) volatile
218{
219 if (_delay)
220 {
221 delay20ns(_delay);
222 }
223 #if defined(TEENSYDUINO)
224 digitalWriteFast(_reqPin, val^_activeLow);
225 #else
226 digitalWrite(_reqPin, val^_activeLow);
227 #endif
228
229}
230
231
232//---------------------------------------------------------------------------------------------------------------------------------------
233// setData: Write data to pins
234//---------------------------------------------------------------------------------------------------------------------------------------
235
236void AER_to_chip::setData(uint32_t data) volatile {
237 for (int i=0; i<_numDataPins; i++) {
238 bool bit = bitRead(data, i)^_activeLow;
239 #if defined(TEENSYDUINO)
240 digitalWriteFast(_dataPins[i], bit);
241 #else
242 digitalWrite(_dataPins[i], bit);
243 #endif
244
245 }
246}
AER_to_chip(uint8_t id, uint8_t reqPin, uint8_t ackPin, volatile uint8_t dataPins[], uint8_t numDataPins, uint8_t delay=0, bool activeLow=false)
static void send_packet(uint8_t id, uint32_t data, uint8_t header)
static volatile bool data_lowactive[8]
static volatile uint8_t data_width[8]
static volatile bool hs_lowactive[8]
static volatile uint8_t data_pins[8][32]
static volatile AER_to_chip * inst[8]
static void configure(uint8_t id, uint8_t config, uint8_t data)
static volatile bool active[8]
static volatile uint8_t type[8]
bool dataWrite(uint32_t data) volatile
static volatile uint8_t req_delay[8]
static volatile uint8_t req_pin[8]
static volatile uint8_t ack_pin[8]
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_ASYNC_TO_CHIP6
Definition: datatypes.h:179
@ IN_ASYNC_TO_CHIP4
Definition: datatypes.h:167
@ IN_CONF_ASYNC_TO_CHIP2
Definition: datatypes.h:256
@ IN_ASYNC_TO_CHIP1
Definition: datatypes.h:149
@ IN_CONF_ASYNC_TO_CHIP0
Definition: datatypes.h:242
@ IN_ASYNC_TO_CHIP7
Definition: datatypes.h:185
@ IN_CONF_ASYNC_TO_CHIP5
Definition: datatypes.h:277
@ IN_ASYNC_TO_CHIP3
Definition: datatypes.h:161
@ IN_ASYNC_TO_CHIP0
Definition: datatypes.h:143
@ IN_CONF_ASYNC_TO_CHIP3
Definition: datatypes.h:263
@ IN_ASYNC_TO_CHIP5
Definition: datatypes.h:173
@ IN_CONF_ASYNC_TO_CHIP4
Definition: datatypes.h:270
@ IN_CONF_ASYNC_TO_CHIP6
Definition: datatypes.h:284
@ IN_CONF_ASYNC_TO_CHIP1
Definition: datatypes.h:249
@ IN_CONF_ASYNC_TO_CHIP7
Definition: datatypes.h:291
@ IN_ASYNC_TO_CHIP2
Definition: datatypes.h:155
@ CONF_TYPE
Definition: datatypes.h:669
@ CONF_REQ
Definition: datatypes.h:637
@ CONF_REQ_DELAY
Definition: datatypes.h:655
@ CONF_ACTIVE
Definition: datatypes.h:618
@ CONF_WIDTH
Definition: datatypes.h:649
@ CONF_ACK
Definition: datatypes.h:643
@ OUT_ERROR_INTERFACE_NOT_ACTIVE
Definition: datatypes.h:557
@ OUT_ERROR
Definition: datatypes.h:522
@ OUT_ERROR_UNKNOWN_CONFIGURATION
Definition: datatypes.h:562
@ OUT_ERROR_ASYNC_HS_TIMEOUT
Definition: datatypes.h:567
@ OUT_ERROR_CONFIGURATION_OUT_OF_BOUNDS
Definition: datatypes.h:579
#define AER_HANDSHAKE_TIMEOUT
@ ASYNC_4Phase_Clow_Dhigh
bool reserve_output_pin(uint8_t id, uint8_t from_instruction)
bool reserve_input_pin(uint8_t id, uint8_t from_instruction)
void delay20ns(uint8_t clocks)
kinda accurate for CPU ferquencies from 400MHz-2GHz, below the resolution becomes more coarse as it m...