1 /*
2    Copyright (C) 1998,1999 T. Scott Dattalo
3 
4 This file is part of the libgpsim library of gpsim
5 
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10 
11 This library 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 GNU
14 Lesser General Public License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, see
18 <http://www.gnu.org/licenses/lgpl-2.1.html>.
19 */
20 
21 
22 #include "../config.h"
23 
24 #include "stimuli.h"
25 #include "packages.h"
26 #include "ui.h"
27 
28 #include <algorithm>
29 #include <iostream>
30 #include <math.h>
31 
Package()32 Package::Package()
33 {
34   pins = nullptr;
35   m_pinGeometry = nullptr;
36 }
37 
38 
Package(unsigned int _number_of_pins)39 Package::Package(unsigned int _number_of_pins)
40 {
41   create_pkg(_number_of_pins);
42 }
43 
44 
~Package()45 Package::~Package()
46 {
47   if (pins) {
48     destroy_pin(0);  // delete all of the pins
49   }
50 
51   delete [] pins;
52   delete [] m_pinGeometry;
53 }
54 
55 
create_pkg(unsigned int _number_of_pins)56 void Package::create_pkg(unsigned int _number_of_pins)
57 {
58   if (number_of_pins) {
59     std::cout << "error: Package::create_pkg. Package appears to already exist.\n";
60     return;
61   }
62 
63   number_of_pins = _number_of_pins;
64 
65   pins = new IOPIN *[number_of_pins];
66   std::fill_n(pins, number_of_pins, nullptr);
67 
68   m_pinGeometry =  new PinGeometry[number_of_pins];
69 
70   unsigned int pins_per_side = number_of_pins / 2;
71 
72   if (number_of_pins & 1) { // If odd number of pins
73     pins_per_side++;
74   }
75 
76   for (unsigned int i = 0; i < number_of_pins; i++) {
77     // Positions for DIL package
78     if (i < pins_per_side) {
79       m_pinGeometry[i].pin_position = (i) / ((float)(pins_per_side - 0.9999));
80 
81     } else {
82       m_pinGeometry[i].pin_position = (i - pins_per_side) / ((float)(pins_per_side - 0.9999)) + (float)2.0;
83     }
84   }
85 }
86 
87 
88 //-------------------------------------------------------------------
89 //-------------------------------------------------------------------
pin_existance(unsigned int pin_number)90 int Package::pin_existance(unsigned int pin_number)
91 {
92   if (!number_of_pins) {
93     std::cout << "error: Package::assign_pin. No package.\n";
94     return E_NO_PACKAGE;
95   }
96 
97   if ((pin_number > number_of_pins) || (pin_number == 0)) {
98     std::cout << "error: Package::assign_pin. Pin number is out of range.\n"
99                  "Max pins " << number_of_pins << ". Trying to add " << pin_number << ".\n";
100     return E_PIN_OUT_OF_RANGE;
101   }
102 
103   if (pins[pin_number - 1]) {
104     return E_PIN_EXISTS;
105   }
106 
107   return E_NO_PIN;
108 }
109 
110 
111 //-------------------------------------------------------------------
112 //-------------------------------------------------------------------
get_pin(unsigned int pin_number)113 IOPIN *Package::get_pin(unsigned int pin_number)
114 {
115   if (E_PIN_EXISTS == pin_existance(pin_number)) {
116     return pins[pin_number - 1];
117 
118   } else {
119     return nullptr;
120   }
121 }
122 
123 
124 //-------------------------------------------------------------------
125 //-------------------------------------------------------------------
get_pin_position(unsigned int pin_number)126 float Package::get_pin_position(unsigned int pin_number)
127 {
128   return (bIsValidPinNumber(pin_number) ? m_pinGeometry[pin_number - 1].pin_position : 0.0);
129 }
130 
131 
set_pin_position(unsigned int pin_number,float position)132 void Package::set_pin_position(unsigned int pin_number, float position)
133 {
134   if (bIsValidPinNumber(pin_number)) {
135     m_pinGeometry[pin_number - 1].bNew = false;
136     m_pinGeometry[pin_number - 1].pin_position = position;
137   }
138 }
139 
140 
setPinGeometry(unsigned int pin_number,float x,float y,int orientation,bool bShowName)141 void Package::setPinGeometry(unsigned int pin_number, float x, float y,
142                              int orientation, bool bShowName)
143 {
144   if (bIsValidPinNumber(pin_number)) {
145     m_pinGeometry[pin_number - 1].bNew = true;
146     m_pinGeometry[pin_number - 1].m_x = x;
147     m_pinGeometry[pin_number - 1].m_y = y;
148     m_pinGeometry[pin_number - 1].m_orientation = orientation;
149     m_pinGeometry[pin_number - 1].m_bShowPinname = bShowName;
150   }
151 }
152 
153 
getPinGeometry(unsigned int pin_number)154 PinGeometry *Package::getPinGeometry(unsigned int pin_number)
155 {
156   static PinGeometry BAD_PIN;
157 
158   if (bIsValidPinNumber(pin_number)) {
159     m_pinGeometry[pin_number - 1].convertToNew();
160     return &m_pinGeometry[pin_number - 1];
161   }
162 
163   return &BAD_PIN;
164 }
165 
166 
167 //-------------------------------------------------------------------
168 //-------------------------------------------------------------------
assign_pin(unsigned int pin_number,IOPIN * pin,bool warn)169 void Package::assign_pin(unsigned int pin_number, IOPIN *pin, bool warn)
170 {
171   switch (pin_existance(pin_number)) {
172   case E_PIN_EXISTS:
173     if (pins[pin_number - 1] && warn) {
174       std::cout << "warning: Package::assign_pin. Pin number " << pin_number << " already exists.\n";
175     }
176 
177   case E_NO_PIN:
178     pins[pin_number - 1] = pin;
179 
180     if ((bool)verbose && pin) {
181       std::cout << "assigned pin " << pin->name() << " to package pin number " << std::dec << pin_number << '\n';
182     }
183 
184     break;
185   }
186 }
187 
188 
189 //-------------------------------------------------------------------
destroy_pin(unsigned int pin_number,IOPIN *)190 void Package::destroy_pin(unsigned int pin_number, IOPIN *)
191 {
192   if (pin_number) {
193     if (pin_number <= number_of_pins) {
194       IOPIN *pPin = pins[pin_number - 1];
195 
196       delete pPin;
197 
198       pins[pin_number - 1] = nullptr;
199     }
200 
201   } else {
202     // Delete all pins
203     for (pin_number = 1; pin_number <= number_of_pins; pin_number++) {
204       destroy_pin(pin_number);
205     }
206 
207     number_of_pins = 0;
208   }
209 }
210 
211 
create_iopin_map()212 void Package::create_iopin_map()
213 {
214 }
215 
216 
217 //-------------------------------------------------------------------
218 //-------------------------------------------------------------------
219 
get_pin_name(unsigned int pin_number)220 std::string &Package::get_pin_name(unsigned int pin_number)
221 {
222   static std::string invalid;
223 
224   if (pin_existance(pin_number) == E_PIN_EXISTS) {
225     return pins[pin_number - 1]->name();
226 
227   } else {
228     return invalid;  //FIXME
229   }
230 }
231 
232 
233 //-------------------------------------------------------------------
234 //-------------------------------------------------------------------
get_pin_state(unsigned int pin_number)235 int Package::get_pin_state(unsigned int pin_number)
236 {
237   if (pin_existance(pin_number) == E_PIN_EXISTS) {
238     return pins[pin_number - 1]->getDrivingState();
239 
240   } else {
241     return 0;
242   }
243 }
244 
245 
246 //------------------------------------------------------------------------
convertToNew()247 void PinGeometry::convertToNew()
248 {
249   if (!bNew) {
250     m_orientation = (int) floor(pin_position);
251 
252     if (m_orientation) {
253       m_x = 0.0;
254       m_y = pin_position;
255 
256     } else {
257       m_x = pin_position - m_orientation;
258       m_y = 0.0;
259     }
260 
261     m_bShowPinname = true;
262   }
263 }
264 
265