uC chip interface arduino  0.9.0
A interface for async and neuromrphic IC testing
Loading...
Searching...
No Matches
interface_pin.py
Go to the documentation of this file.
2# This file is part of the Firmware project to interface with small Async or Neuromorphic chips
3# Copyright (C) 2023 Ole Richter - University of Groningen
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18
19from .header import ConfigMainHeader, PinHeader, ConfigSubHeader
20from .packet import ConfigPacket, PinPacket
21from time import sleep
22import logging
23
25 """ This exposes all the pin functionality for use,
26
27 for reading state and data please use the functions provided as they trigger an update of the internal state before returning values
28
29 at the moment it is limited to digital read and write
30 but is supposed to be extended to analog read and write and PWM functionality on first need / request
31 """
32 def __init__(self, api_object, interface_id):
33 self.__status = 0
34 """ 0 means not activated
35 1 means activation pending
36 2 means activted
37 -1 means error
38 """
39 self.__status_timestamp = 0
40 """
41 - "INPUT"
42 - "OUTPUT"
43 - "PWM" not implemented yet
44 - "ANALOG_INPUT" not implemented yet
45 - "ANALOG_OUTPUT" not implemented yet
46 """
47 self.__type = "NONE"
48 self.__type_pending = "NONE"
49 self.__type_timestamp = 0
50 self.__interval = 0
52 self.__data_from_chip = []
54 self.__data_to_chip = []
55 self.__data_to_chip_times = []
56 self.__errors = []
57 self.__pin_id = interface_id
58 self.__api = api_object
59 self.__header = [ConfigMainHeader.IN_CONF_PIN, PinHeader.IN_PIN, PinHeader.IN_PIN_READ, PinHeader.OUT_PIN_LOW, PinHeader.OUT_PIN_HIGH]
60
61 def header(self):
62 """header returns the packet headers associated whith this interface
63
64 :return: packet headers of this interface
65 :rtype: Header (IntEnum)
66 """
67 return self.__header
68
69 def status(self):
70 """status returns the state of this interface,
71
72 it can be:
73 - active - everything is working fine
74 - activation pending - the uC has not acknolaged the activation yet after the request to activate the interface
75 - not active - the interface has not been configured and activate
76 - error - there was an error during activation or during use, please consult the errors using the errors function
77
78 :return: the state of the interface and the timestamp in us
79 :rtype: (string, int)
80 """
81 self.update()
82 state_str = ("active" if self.__status == 2 else ("activation pending" if self.__status == 1 else ("not active" if self.__status == 0 else "error" )))
83 return (state_str,self.__status_timestamp)
84
85 def interface_type(self):
86 """interface_type returns the currently configured mode of the pin
87
88 :return: mode of the pin like "INPUT" or "OUTPUT"
89 :rtype: string
90 """
91 self.update()
92 return (self.__type,self.__type_timestamp)
93
94 def interval(self):
95 """interval not yet suported for PWM/analog read
96
97 :return: _description_
98 :rtype: _type_
99 """
100 self.update()
101 return (self.__interval,self.__interval_timestamp)
102
103 def data_from_chip(self):
104 """data_from_chip will retun the data recoded by the uC send from the device under test (DUT)
105
106 will retun 2 lists: one with the word recoded and one with the time when it was recorded, linked by index
107
108 :return: the words from the DUT and the times of those words
109 :rtype: ([int],[int])
110 """
111 self.update()
112 return (self.__data_from_chip, data_from_chip_times)
113
114 def data_to_chip(self):
115 """data_to_chip will retun the data send by the uC to the device under test (DUT)
116
117 will retun 2 lists: one with the word send and one with the exact time when it was send, linked by index
118
119 the time might differ slightly from the time you sheduled the send word,
120 as it is the time when it was send out and the uC can only send one word at a time
121
122 :return: the words send to the DUT and the times of those words
123 :rtype: ([int],[int])
124 """
125 self.update()
126 return (self.__data_to_chip, self.__data_to_chip_times)
127
129 self.update()
130 data = self.__data_from_chip
131 time = self.__data_from_chip_times
132 self.__data_from_chip = []
133 self.__data_from_chip_times = []
134 return (data, time)
135
137 self.update()
138 data = self.__data_to_chip
139 time = self.__data_to_chip_times
140 self.__data_to_chip = []
141 self.__data_to_chip_times = []
142 return (data, time)
143
144 def errors(self):
145 """errors all errors corresponding to this interface
146
147 :return: list of all errors
148 :rtype: [string]
149 """
150 self.update()
151 return self.__errors
152
153 def __str__(self):
154 self.update()
155 state_str = ("active" if self.__status == 2 else ("activation pending" if self.__status == 1 else ("not active" if self.__status == 0 else "error" )))
156 return "PIN_" + str(self.__pin_id) + \
157 "\nHeader: " + str(self.__header) + \
158 "\nStatus: " + state_str + " at " + str(self.__status_timestamp) + "us" + \
159 "\nType "+ str(self.__type) +" at " + str(self.__type_timestamp) + "us" + \
160 "\ninterval "+ str(self.__interval) +" at " + str(self.__interval_timestamp) + "us" + \
161 "\nSend: "+ str(self.__data_to_chip) +" at " + str(self.__data_to_chip_times) + "us" + \
162 "\nRecived: "+ str(self.__data_from_chip) +" at " + str(self.__data_from_chip_times) + "us" + \
163 "\nERRORS: "+str(self.__errors) + "\n"
164
165 def process_packet(self, packet):
166 """ process packets arriving for this interface, updates the internal state and stores the data
167 @param packet: the packet to process
168 """
169 if packet.header() in self.__header:
170 # configuration acknolagment
171 if packet.header() == self.__header[0]:
172 # input
173 if packet.config_header() == ConfigSubHeader.CONF_INPUT:
174 self.__status = 2
175 self.__status_timestamp = packet.time()
176 self.__type = "INPUT"
177 self.__type_timestamp = packet.time()
178 return
179 # output
180 elif packet.config_header() == ConfigSubHeader.CONF_OUTPUT:
181 self.__status = 2
182 self.__status_timestamp = packet.time()
183 self.__type = "OUTPUT"
184 self.__type_timestamp = packet.time()
185 return
186 # data to store
187 elif packet.header() == self.__header[1] and packet.pin_id() == self.__pin_id:
188 self.__data_to_chip.append(packet.value())
189 self.__data_to_chip_times.append(packet.time())
190 return
191 elif packet.header() == self.__header[2] and packet.pin_id() == self.__pin_id:
192 return
193 elif packet.header() == self.__header[3] and packet.pin_id() == self.__pin_id:
194 self.__data_from_chip.append(packet.value())
195 self.__data_from_chip_times.append(packet.time())
196 return
197 elif packet.header() == self.__header[4] and packet.pin_id() == self.__pin_id:
198 self.__data_from_chip.append(packet.value())
199 self.__data_from_chip_times.append(packet.time())
200 return
201 self.__errors.append(str(packet))
202 self.__status = -1
203
204
205 def activate(self, pin_mode="OUTPUT", interval=0, time=0):
206 """ activate the pin with the given mode and interval
207 @param pin_mode: the mode of the pin, can be "INPUT", "OUTPUT" and future "PWM", "ANALOG_INPUT", "ANALOG_OUTPUT"
208 @param interval: the interval for the pin, not yet implemented
209 @param time: the time when the activation should be done, 0 means as soon as possible
210 """
211 if self.__status >= 1:
212 logging.warning("Pin "+str(self.__pin_id)+" is already activated or waiting activation, doing nothing")
213 else:
214 if pin_mode == "OUTPUT":
215 self.__api.send_packet(ConfigPacket(header = self.__header[0], config_header = ConfigSubHeader.CONF_OUTPUT, value=self.__pin_id, time = time))
216 self.__status = 1
217 self.__type_pending = pin_mode
218 sleep(0.001)
219 return
220 elif pin_mode == "INPUT":
221 self.__api.send_packet(ConfigPacket(header = self.__header[0], config_header = ConfigSubHeader.CONF_INPUT, value=self.__pin_id,time = time))
222 self.__status = 1
223 self.__type_pending = pin_mode
224 sleep(0.001)
225 return
226 # in the future implement the following
227 elif pin_mode == "PWM":
228 logging.warning("pin mode not implmented yet")
229 elif pin_mode == "ANALOG_INPUT":
230 logging.warning("pin mode not implmented yet")
231 elif pin_mode == "ANALOG_OUPUT":
232 logging.warning("pin mode not implmented yet")
233 else:
234 logging.error("pin.activate got wrong type "+str(pin_mode)+" only INPUT, OUTPUT, PWM, ANALOG_INPUT, ANALOG_OUTPUT are allowed")
235
236
237
238 def send(self, value, time = 0):
239 """ set the corresponding pin to the given value at the given time
240 @param value: the value to set the pin to, 0 or 1
241 @param time: the time when the value should be set, 0 means as soon as possible
242 """
243
244 # we dont check the status here anymore as the uC will report the error anyway
245 self.__api.send_packet(PinPacket(header = self.__header[1],pin_id=self.__pin_id , value = value, time = time))
246
247
248
249 def update(self):
250 """ update the internal state representation of the pin object
251 """
252 self.__api.update_state()
This exposes all the pin functionality for use,.
def status(self)
status returns the state of this interface,
def process_packet(self, packet)
process packets arriving for this interface, updates the internal state and stores the data
def activate(self, pin_mode="OUTPUT", interval=0, time=0)
activate the pin with the given mode and interval
def update(self)
update the internal state representation of the pin object
def __init__(self, api_object, interface_id)
def interface_type(self)
interface_type returns the currently configured mode of the pin
def interval(self)
interval not yet suported for PWM/analog read
def send(self, value, time=0)
set the corresponding pin to the given value at the given time
def errors(self)
errors all errors corresponding to this interface
def data_from_chip(self)
data_from_chip will retun the data recoded by the uC send from the device under test (DUT)
def data_to_chip(self)
data_to_chip will retun the data send by the uC to the device under test (DUT)
The ConfigPacket is used to cumunicate configuration instructions with the uC all availible instructi...
Definition: packet.py:375
The PinPacket is used to comunicate pin instructions with the uC all availible instructions are defin...
Definition: packet.py:290