├── 2019-02-10-223525.jpg ├── Hardware ├── CSGBLAST.BOM ├── CSGBLAST.PDF ├── CSGBLAST.PS ├── CSGBLAST_1902.zip ├── CSGSCK20.BOM ├── CSGSCK20.PDF ├── CSGSCK20.PS ├── CSGSCK20_190929.zip ├── CSGSCK24.BOM ├── CSGSCK24.PDF ├── CSGSCK24.PS ├── CSGSCK24_190929.zip ├── CSGSOCK2_190705.zip └── README.md ├── LICENSE ├── README.md ├── README2 ├── perlblast └── software ├── README.md └── perlblast_nh /2019-02-10-223525.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kees1948/perlblast/849246b54276f19f877fd4428e5055d79bb3ad41/2019-02-10-223525.jpg -------------------------------------------------------------------------------- /Hardware/CSGBLAST.BOM: -------------------------------------------------------------------------------- 1 | 2 | B I L L O F M A T E R I A L S 3 | 4 | Project name: H:\PK\CSGBLAST\SCH\CSGBLAST 5 | Time & date: 17:35 Sep. 29, 2019 6 | 7 | # Device Value Package type Refdes 8 | ------------------------------------------------------------------------------- 9 | 10 | 3 74HC1G 74HC1G00 SOT23-5 U11 11 | U12 12 | U13 13 | 2 74HC1G 74HC1G32 SOT23-5 U6 14 | U7 15 | 2 74HC07 74HC07 SO14 U9 16 | U10 17 | 1 74HC573 SOL20 U4 18 | 1 74LS273 SOL20 U5 19 | 1 AD7801 AD7801 SOIC20 U8 20 | 1 BAXXXC BAT54C SOT23 D2 21 | 10 C0603X7R 100N X7R0603 C1 22 | C2 23 | C3 24 | C4 25 | C5 26 | C6 27 | C7 28 | C10 29 | C12 30 | C13 31 | 1 DELTA_25HM DB25B$ J1 32 | 1 DIODE 1N4001 SMA D1 33 | 2 FEM20P ? SOCK2X8 CON2 34 | CON3 35 | 4 HOLE3 HOLE3 H1 36 | H2 37 | H3 38 | H4 39 | 1 L78L05 L78L05 SOT89 U1 40 | 1 LED0603 green LED0603 LED1 41 | 2 LT3080 LT3080 SOT223 U2 42 | U3 43 | 3 MFET.N 2N7002 SOT23_F T1 44 | T2 45 | T3 46 | 1 PWRCON ? PWRCON CON1 47 | 2 RES0603 10K mct0603 R24 48 | R25 49 | 4 RES0603 47K mct0603 R6 50 | R7 51 | R8 52 | R21 53 | 1 RES0603 200K mct0603 R4 54 | 2 RES0603 300K mct0603 R2 55 | R26 56 | 1 RES0603 910K mct0603 R1 57 | 1 RES0603 2K2 mct0603 R5 58 | 1 RES0603 3K3 mct0603 R20 59 | 13 RES0603 4K7 mct0603 R3 60 | R9 61 | R10 62 | R11 63 | R12 64 | R13 65 | R14 66 | R15 67 | R16 68 | R17 69 | R18 70 | R19 71 | R23 72 | 1 RES_1W 680R $R2010 R22 73 | 2 SCHOTTKY BAT54 SOT23 D6 74 | D8 75 | 3 TANTAAL 10U/35V CAP_D C8 76 | C9 77 | C11 78 | 1 TOGGLE SWITCH TOGGLE SW1 79 | -------------------------------------------------------------------------------- /Hardware/CSGBLAST.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kees1948/perlblast/849246b54276f19f877fd4428e5055d79bb3ad41/Hardware/CSGBLAST.PDF -------------------------------------------------------------------------------- /Hardware/CSGBLAST_1902.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kees1948/perlblast/849246b54276f19f877fd4428e5055d79bb3ad41/Hardware/CSGBLAST_1902.zip -------------------------------------------------------------------------------- /Hardware/CSGSCK20.BOM: -------------------------------------------------------------------------------- 1 | 2 | B I L L O F M A T E R I A L S 3 | 4 | Project name: H:\PK\CSGSCK20\SCH\CSGSCK20 5 | Time & date: 17:24 Sep. 29, 2019 6 | 7 | # Device Value Package type Refdes 8 | ------------------------------------------------------------------------------- 9 | 10 | 1 C0603X7R 100N X7R0603 C1 11 | 2 FEM20P ? HDR2X8 CON1 12 | CON4 13 | 1 LED0603 blue LED0603 LED1 14 | 1 LED0603 green LED0603 LED3 15 | 1 LED0603 yellow LED0603 LED2 16 | 2 RES0603 1K mct0603 R6 17 | R7 18 | 1 RES0603 10K mct0603 R9 19 | 6 RES0603 4K7 mct0603 R1 20 | R2 21 | R3 22 | R4 23 | R5 24 | R8 25 | 1 ZIF20 ? ZIF20P ZIF2 -------------------------------------------------------------------------------- /Hardware/CSGSCK20.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kees1948/perlblast/849246b54276f19f877fd4428e5055d79bb3ad41/Hardware/CSGSCK20.PDF -------------------------------------------------------------------------------- /Hardware/CSGSCK20_190929.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kees1948/perlblast/849246b54276f19f877fd4428e5055d79bb3ad41/Hardware/CSGSCK20_190929.zip -------------------------------------------------------------------------------- /Hardware/CSGSCK24.BOM: -------------------------------------------------------------------------------- 1 | 2 | B I L L O F M A T E R I A L S 3 | 4 | Project name: H:\PK\CSGSCK24\SCH\CSGSCK24 5 | Time & date: 17:24 Sep. 29, 2019 6 | 7 | # Device Value Package type Refdes 8 | ------------------------------------------------------------------------------- 9 | 10 | 1 C0603X7R 100N X7R0603 C2 11 | 2 FEM20P ? HDR2X8 CON2 12 | CON3 13 | 1 LED0603 blue LED0603 LED4 14 | 1 LED0603 green LED0603 LED6 15 | 1 LED0603 yellow LED0603 LED5 16 | 1 RES0603 19K mct0603 R20 17 | 10 RES0603 4K7 mct0603 R10 18 | R11 19 | R12 20 | R13 21 | R14 22 | R15 23 | R16 24 | R17 25 | R18 26 | R19 27 | 1 ZIF24 ? ZIF24P ZIF1 -------------------------------------------------------------------------------- /Hardware/CSGSCK24.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kees1948/perlblast/849246b54276f19f877fd4428e5055d79bb3ad41/Hardware/CSGSCK24.PDF -------------------------------------------------------------------------------- /Hardware/CSGSCK24_190929.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kees1948/perlblast/849246b54276f19f877fd4428e5055d79bb3ad41/Hardware/CSGSCK24_190929.zip -------------------------------------------------------------------------------- /Hardware/CSGSOCK2_190705.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kees1948/perlblast/849246b54276f19f877fd4428e5055d79bb3ad41/Hardware/CSGSOCK2_190705.zip -------------------------------------------------------------------------------- /Hardware/README.md: -------------------------------------------------------------------------------- 1 | This is the programming hardware as I use it now. It has a base board with a LPT connector. It needs to be used 2 | with a LPT on the motherboard or with a USB<->LPT dongle BUT A SPECIAL ONE!. You need one with a Lucent compatible chip. 3 | There exits a few chip versions that are suitable. 4 | 5 | I tried to minimize the chance that hazardous voltages could leave the board into the LPT port, probably 6 | you blow up local components first in case of incident. 7 | 8 | The base board has connectors to hold a programming board. The programming board holds the ZIF socket and signal LED's. 9 | 10 | There exist one programming board for 20 pin ZIF's and one for 24 pin ZIF's. 11 | 12 | 'perlblast_nh' will run smootly with this hardware. 13 | 14 | I will upload the details for the programming boards soon (2019-09-29) 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # perlblast 2 | a Perl-Tk implementation of galblast/atfblast that uses the parport device (even via USB!) 3 | 4 | I came to write it because I wanted to be able to program GAL's a simple way in Linux. galblast.exe and atfblast.exe are both 5 | running on Windows only. 'perlblast' runs unmodified on Linux and Windows, provided that Perl is installed. 6 | 7 | The file README2 is the main information about the project. As said I am neither a (very) good Perl programmer or very fluent in English. So help on both area's will be grateful. 8 | 9 | 'perlblast' at this moment still has some rough ends but I like to add refinements from myself and others over time. The basic functionality is there. 10 | 11 | Known issues's: 12 | - some values after user edit are not applied to the programming itself 13 | 14 | The fuse checksum is generated and checked correctly. As is the file checksum now. 15 | 16 | For use on Windows: install StrawBerry Perl. 17 | with cpan: install Tk and install Time::HiRes 18 | 19 | The 'parport' access method works without any problem on Windows XP. You need to have an LPT port on your system of course. 20 | -------------------------------------------------------------------------------- /README2: -------------------------------------------------------------------------------- 1 | This is the README file for perlblast. 2 | 3 | 'perlblast' is a Perl-Tk implementation of 'galblast' (by Manfred Winterhoff) and 4 | 'atfblast' (http://www.bhabbott.net.nz/atfblast.html). 5 | 6 | The main drive for 'perlblast' is that it does run on Linux. I tried 'galblast' under Windows XP in 7 | a virtual machine but always the parallel port access was troublesome, Some other programs to access the parallel 8 | port from a virtual machine worked very well.... 9 | 10 | I learned and tested also the use via an usb<->parallel dongle, that turned out to function very well too :-) 11 | 12 | As the code is now it interfaces to the simplified hardware GAL/ATF Blaster v2.1 as found on 13 | http://www.bhabbott.net.nz/atfblast.html 14 | 15 | I am working on another hardware project for GAL/ATF programming that can handle various VPP and VCC settings. 16 | In that design I took some more measures to block any dangerous voltage from the GAL back to the parport. 17 | If anything goes wrong here, you may fry your motherboard in an instant. (I did so by doing something VERY stupid). 18 | 19 | When ready, the design will come available on GitHub as I did for this software. 20 | 21 | I believe I prefer the use of an USB<->LPT dongle and that is very well possible. On Linux you need to blacklist 22 | the modules 'usblp' and load 'uss720'. Initially the uss720 module did not recognize my usb dongle. It turned out 23 | that the table in uss720.c did not hold the usb-ID for my dongle. 24 | 25 | lsusb -v gave me: Bus 001 Device 019: ID 0711:0302 Magic Control Technology Corp. Parallel Port 26 | 27 | After editing drivers/usb/misc/uss720.c in my Linxu source tree and adding the values to the table near to the end 28 | of the uss720.c file. 29 | 30 | /* table of cables that work through this driver */ 31 | static const struct usb_device_id uss720_table[] = { 32 | { USB_DEVICE(0x047e, 0x1001) }, 33 | { USB_DEVICE(0x0557, 0x2001) }, 34 | { USB_DEVICE(0x0729, 0x1284) }, 35 | { USB_DEVICE(0x1293, 0x0002) }, 36 | { USB_DEVICE(0x050d, 0x0002) }, 37 | { USB_DEVICE(0x0711, 0x0302) }, /* lucent chip */ <<< I added this one 38 | { } /* Terminating entry */ 39 | }; 40 | 41 | Now after: make modules and make modules_install, rmmod uss720 and modprobe uss720, and re-inserting 42 | te usb<->lpt dongle, it worked. I found that after use, the reference count stays at '1', so rmmod would not remove 43 | the uss720 module. I don't know why that is at this moment. 44 | 45 | From dmesg: 46 | usb 1-12.3: new full-speed USB device number 19 using xhci_hcd 47 | usb 1-12.3: New USB device found, idVendor=0711, idProduct=0302 48 | usb 1-12.3: New USB device strings: Mfr=0, Product=0, SerialNumber=0 49 | parport1: fix this legacy no-device port driver! 50 | lp1: using parport1 (polling). 51 | 52 | ls -l /dev/parport* shows 53 | 54 | crw-rw-r-- 1 root lp 99, 0 Oct 23 11:54 /dev/parport0 << LPT port on motherboard >> 55 | crw-rw-r-- 1 root lp 99, 1 Oct 23 12:02 /dev/parport1 << LPT port via USB dongle >> 56 | 57 | Make sure that you are in the group 'lp'. If not, add yourself to it. You need to (re)login to make it having effect. 58 | 59 | As for Perl, I had to add some modules with 'cpan'. 60 | 61 | cpan[1]> install Perl::Tk 62 | cpan[1]> install Tk::ListBox 63 | cpan[1]> install Tk::LabEntry 64 | cpan[1]> install Tk::Optionmenu 65 | cpan[1]> install Device::ParallelPort 66 | cpan[1]> install Device::ParallelPort::drv::parport 67 | cpan[1[> install Device::ParallelPort::drv::linux 68 | 69 | The documentation on the Internet as on https://ubuntuforums.org/showthread.php?t=1246312 70 | show how the most essential parport modules are added. 71 | For me the third module (Device::ParallelPort::drv::linux), I could not have it done the way described. 72 | After modifying the "linux.xs" file and "install Device::ParallelPort::drv::linux" it would fail as it 73 | loaded a fresh copy again with a higher number. I solved my struggle by adding temporarely a symbolic link 74 | between /usr/include/sys/io.h and /usr/include/asm/io.h. 75 | After a succesful "install Device::ParallelPort::drv::linux" in cpan, I removed the link again. 76 | 77 | _EXTRA REMARK_: some LPT dongles work, other may not. I bought a second USB<->LPT dongle that turned out not to work. 78 | It has an CH340S chip inside amd does not fulfill the requirements for the USS720 module. So be careful! 79 | Consulting www.the-sz.com for working variants gives: 80 | 0x047E 0x1001 Agere Systems, Inc. (Lucent) USS720 Parallel Port 81 | 0x0557 0x2001 ATEN International Co., Ltd UC-1284 Printer Port 82 | 0x1293 0x0002 Belkin Components [hex] F5U002 Parallel Port [uss720] 83 | 0x0711 0x0302 Magic Control Technology Corp. Parallel Port 84 | 85 | While the Perl-Tk implementation tries to mimmic the galblast version as best as I could, there are some differences. 86 | I am not a 'fluent' Perl programmer, but I can get most things done as I want in Perl. If someone more capable 87 | in Perl has hints and/or improvements I am happy to apply these. 88 | 89 | As I don't have all the GAL types that the program would support I could not test every corner yet. Bugs may 90 | hide in the code. But as it is now, it does it work for me. The same for the English grammar, 91 | it is not my native tongue, so words may look strange sometimes, help me. 92 | 93 | Kees Schoenmakers, keesgpl at gmail dot com 94 | -------------------------------------------------------------------------------- /perlblast: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use Tk; 4 | use Tk::Listbox; 5 | use Tk::LabEntry; 6 | use Tk::Optionmenu; 7 | use Getopt::Std; 8 | 9 | use POSIX qw( strftime ); 10 | use enum qw(UNKNOWN GAL16V8 GAL18V10 GAL20V8 GAL20RA10 GAL20XV10 GAL22V10 GAL26CV12 GAL6001 GAL6002 ATF16V8B ATF22V10B ATF22V10C); 11 | use enum qw(FALSE TRUE); # boolean 12 | use enum qw(NONE READGAL READPES VERIFYGAL SCLKTEST WRITEGAL ERASEGAL ERASEALL CHECKBURNSEC BURNSECURITY CHECKPES WRITEPES VPPTEST TESTGAL); # actions 13 | use enum qw(ISNONE MSG_OK MSG_ALERT MSG_WARNING MSG_ASSURE); # msg types 14 | use enum qw(OFF ON); # signals, levels 15 | 16 | use Device::ParallelPort; 17 | use Time::HiRes qw( usleep ); 18 | ##################################################################################################################### 19 | # 20 | # perlblast, a GAL programming utility written in Perl. By C.Schoenmakers Copyright (C) 2018 21 | # 22 | # This version uses (/dev/)parport? access to the programming hardware, this way you _can_ use even 23 | # usb<->parallel dongles but that may require some edit of drivers/usb/misc/uss720.c in your Linux source tree to 24 | # add the usb id (mmmm:dddd) to the table near the bottom of the uss720.c file, like 25 | # Bus 001 Device 033: ID 0711:0302 Magic Control Technology Corp. Parallel Port 26 | # in my case. 27 | # 28 | # This is a Perl-Tk implementation of GAL programming software 29 | # based on various work from other people 30 | # GALBLAST: by Manfred Winterhoff 31 | # atblast: http://www.bhabbott.net.nz/atfblast.html up to 2017-11-19 V0.31 32 | # 33 | # 34 | # This program is free software: you can redistribute it and/or modify 35 | # it under the terms of the GNU General Public License as published by 36 | # the Free Software Foundation, either version 3 of the License, or 37 | # (at your option) any later version. 38 | # 39 | # This program is distributed in the hope that it will be useful, 40 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 41 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 42 | # GNU General Public License for more details. 43 | # 44 | # You should have received a copy of the GNU General Public License 45 | # along with this program. If not, see . 46 | # 47 | ##################################################################################################################### 48 | # 49 | # see also the README 50 | # 51 | # usage: perlblast [<-p port# >] 52 | # 53 | # default port is (/dev/)parport0 higher numbers are possibe 54 | # 55 | # example: perlblast -p4 uses (/dev/)parport4 56 | # 57 | # 58 | 59 | 60 | $geometry = "600x800"; 61 | my %options=(); 62 | 63 | $ThisVersion = "Rev: 0.4.1 2018-10-22 C.S."; 64 | 65 | # parport control bits 66 | $STROBE = 1; # 1, invert 67 | $LNFEED = 2; # 14, invert 68 | $INIT = 4; # 16 69 | $SELCTP = 8; # 17, invert 70 | # status 71 | $ERROR = 8; # 15 72 | $SELECT = 16; # 13 73 | $PAPOUT = 32; # 12 74 | $ACK = 64; # 10 75 | $BUSY = 128; # 11, invert 76 | 77 | # SET initial port 78 | $portnum = 0; # 0=parport0, 1=parport1, 2=parport2 etc 79 | 80 | ### manufacturer ID 81 | $LATTICE = 0xA1; 82 | $NATIONAL = 0x8F; 83 | $SGSTHOMSON = 0x20; 84 | 85 | ################################################################################################################### 86 | # 87 | # GAL information 88 | # 89 | ################################################################################################################### 90 | # type,id0|id1,name,fuses,pins,rows,bits,uesrow,uesfuse,uesbytes,eraserow,eraseallrow,pesrow,pesbytes,cfgrow,config,vpp,progtime,erasetime,vcc 91 | # | | | | | | | | | | | | | | | | | | | | | 92 | # | | | | | | | | | | | | | | | | | | | | | 93 | # | | | | | | | | | | | | | | | | | | | | | 94 | # | | | | | | | | | | | | | | +---+ | | | | | | 95 | # | | | | | | | | | | | | | +------+ | | | | | | | 96 | # | | | | | | | | | | | | +-----------+ | | | | | | | | 97 | # | | | | | | | | | | | +------------------+ | | | | | | | | | 98 | # | | | | | | | | | | +-----------------------+ | | | | ++ | ++ | | | 99 | # | | | | | | | | | *---------------------------+ | | | | | | | | | | | 100 | # | | | | | | | | +-----------------------------+ | | | | | | | | | | +---+ | 101 | # | | | | | | | +-------------------------------+ | | | | | | | | | | | | | 102 | # | | | | | | +-------------------------------+ | | | | | | | | | | | | | +------+ 103 | # | | | | | +--------------------------------+ | | | | | | | | | | | | | | | 104 | # | | | | +---------------------------------+ | | | | | | | | | | | | | | | | 105 | # | | | +--------------------------+ | | | | | | | | | | | | | | | | | 106 | # | | +-----------------------+ | | | | | | | | | | | | | | | | | | 107 | # | +---------------------+ | | | | | | | | | | | | | | | | | | | 108 | # +-----------------v v v v v v v v v v v v v v v v v v v v v 109 | # 110 | { 111 | no warnings 'once'; 112 | 113 | %galinfo = (0 => [UNKNOWN, 0x00, 0x00, "unknown" , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, cfgNone , 00, 000, 000, 5.0], 114 | 1 => [GAL16V8, 0x00, 0x1A, "GAL16V8" , 2194, 20, 32, 64, 32, 2056, 8, 63, 54, 58, 8, 60, cfg16V8, 63, 100, 100, 5.0], 115 | 2 => [GAL18V10, 0x50, 0x51, "GAL18V10" , 3540, 20, 36, 96, 36, 3476, 8, 61, 60, 58, 10, 16, cfg18V10, 00, 000, 000, 5.0], 116 | 3 => [GAL20V8, 0x20, 0x3A, "GAL20V8" , 2706, 24, 40, 64, 40, 2568, 8, 63, 59, 58, 8, 60, cfg20V8AB, 63, 100, 100, 5.0], 117 | 4 => [GAL20RA10, 0x60, 0x61, "GAL20RA10", 3274, 24, 40, 80, 40, 3210, 8, 61, 60, 58, 10, 16, cfg20RA10, 00, 000, 000, 5.0], 118 | 5 => [GAL20XV10, 0x65, 0x66, "GAL20XV10", 1671, 24, 40, 40, 44, 1631, 5, 61, 60, 58, 5, 16 ,cfg20XV10, 00, 000, 000, 5.0], #/* 4,5,6,29,36,37 macht was,38,44,46,52 CLEARALL,53 macht was,60 CLEARALL */ 119 | 6 => [GAL22V10, 0x48, 0x49, "GAL22V10" , 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, cfg22V10 , 56, 40, 100, 5.0], 120 | 7 => [GAL26CV12, 0x58, 0x59, "GAL26CV12", 6432, 28, 52, 122, 52, 6368, 8, 61, 60, 58, 12, 16, cfg26CV12, 00, 000, 000, 5.0], 121 | 8 => [GAL6001, 0x40, 0x41, "GAL6001" , 8294, 24, 78, 75, 97, 8222, 9, 63, 62, 96, 8, 8, cfg6001, 00, 000, 000, 5.0], 122 | 9 => [GAL6002, 0x44, 0x44, "GAL6002" , 8330, 24, 78, 75, 97, 8258, 9, 63, 62, 96, 8, 8, cfg6002, 00, 000, 000, 5.0], 123 | 10 => [ATF16V8B, 0x00, 0x00," ATF16V8B" , 2194, 20, 32, 64, 32, 2056, 8, 63, 54, 58, 8, 60, cfg16V8AB, 48, 10, 100, 3.3], 124 | 11 => [ATF22V10B, 0x00, 0x00," ATF22V10B", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, cfg22V10 , 48, 10, 100, 3.3], 125 | 12 => [ATF22V10C, 0x00, 0x00," ATF22V10C", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, cfg22V10 , 48, 10, 100, 3.3], 126 | ); 127 | 128 | @cfgNone = (); 129 | 130 | @cfg16V8 = ( 131 | 2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140,2141,2142,2143, 132 | 2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,2155,2156,2157,2158,2159, 133 | 2048,2049,2050,2051,2193,2120,2121,2122,2123,2124,2125,2126,2127,2192,2052,2053, 134 | 2054,2055,2160,2161,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173, 135 | 2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2188,2189, 136 | 2190,2191 137 | ); 138 | 139 | @cfg16V8AB = ( 140 | 2048,2049,2050,2051,2193,2120,2121,2122,2123,2128,2129,2130,2131,2132,2133,2134, 141 | 2135,2136,2137,2138,2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150, 142 | 2151,2152,2153,2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166, 143 | 2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182, 144 | 2183,2184,2185,2186,2187,2188,2189,2190,2191,2124,2125,2126,2127,2192,2052,2053, 145 | 2054,2055 146 | ); 147 | 148 | @cfg18V10 = ( 149 | 3457,3456,3459,3458,3461,3460,3463,3462,3465,2464,3467,3466,3469,3468,3471,3470,3473,3472,3475,3474 150 | ); 151 | 152 | @cfg20V8 = ( 153 | 2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655, 154 | 2656,2657,2658,2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671, 155 | 2560,2561,2562,2563,2705,2632,2633,2634,2635,2636,2637,2638,2639,2704,2564,2565, 156 | 2566,2567,2672,2673,2674,2675,2676,2677,2678,2679,2680,2681,2682,2683,2684,2685, 157 | 2686,2687,2688,2689,2690,2691,2692,2693,2694,2695,2696,2697,2698,2699,2700,2701, 158 | 2702,2703 159 | ); 160 | 161 | @cfg20V8AB = ( 162 | 2560,2561,2562,2563,2705,2632,2633,2634,2635,2640,2641,2642,2643,2644,2645,2646, 163 | 2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662, 164 | 2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678, 165 | 2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690,2691,2692,2693,2694, 166 | 2695,2696,2697,2698,2699,2700,2701,2702,2703,2636,2637,2638,2639,2704,2564,2565, 167 | 2566,2567 168 | ); 169 | 170 | @cfg20RA10 = ( 171 | 3200,3201,3202,3203,3204,3205,3206,3207,3208,3209 172 | ); 173 | 174 | @cfg20XV10 = ( 175 | 1630,1628,1629,1620,1621,1622,1610,1611,1612,1613,1614,1600,1601,1602,1603,1604, 176 | 1627,1626,1623,1624,1625,1619,1618,1617,1616,1615,1609,1608,1607,1606,1605 177 | ); 178 | 179 | @cfg22V10 = ( 180 | 5809,5808,5811,5810,5813,5812,5815,5814,5817,5816,5819,5818,5821,5820,5823,5822, 181 | 5825,5824,5827,5826 182 | ); 183 | 184 | @cfg26CV12 = ( 185 | 6345,6344,6347,6346,6349,6348,6351,6350,6353,6352,6355,6354,6357,6356,6359,6358, 186 | 6361,6360,6363,6362,6365,6364,6367,6366 187 | ); 188 | 189 | @cfg6001 = ( 190 | 8221,8220,8179,8183,8187,8191,8195,8199,8203,8207,8211,8215,8214,8210,8206,8202, 191 | 8198,8194,8190,8186,8182,8178,8216,8217,8212,8213,8208,8209,8204,8205,8200,8201, 192 | 8196,8197,8192,8193,8188,8189,8184,8185,8180,8181,8156,8159,8162,8165,8168,8171, 193 | 8174,8177,8154,8157,8160,8163,8166,8169,8172,8175,8176,8173,8170,8167,8164,8161, 194 | 8158,8155,8218,8219 195 | ); 196 | 197 | @cfg6002 = ( 198 | 8257,8256,8179,8183,8187,8191,8195,8199,8203,8207,8211,8215,8214,8210,8206,8202, 199 | 8198,8194,8190,8186,8182,8178,8216,8217,8212,8213,8208,8209,8204,8205,8200,8201, 200 | 8196,8197,8192,8193,8188,8189,8184,8185,8180,8181,8255,8254,8253,8252,8251,8250, 201 | 8249,8248,8247,8246,8245,8244,8243,8242,8241,8240,8239,8238,8220,8221,8222,8223, 202 | 8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8156,8159, 203 | 8162,8165,8168,8171,8174,8177,8154,8157,8160,8163,8166,8169,8172,8175,8176,8173, 204 | 8170,8167,8164,8161,8158,8155,8218,8219 205 | ); 206 | 207 | } # end off suppressed 'once' warnings 208 | 209 | ################################################################################################################### 210 | my @fuses; # DUT fuses 211 | my @ffuses; # file fuses 212 | my @pes = (0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); 213 | my $vpp = 0; 214 | my $erasetime = 0; 215 | my $progtime = 0; 216 | my $read12v = 48; # 12V 217 | my $galvcc = 0.0; 218 | 219 | my $galtype; 220 | my $galname; 221 | 222 | # hardware register copies 223 | my $ls273shadow = 0; 224 | my $dacvalueshadow = 0; 225 | 226 | my $portname = ""; 227 | my $portid = 'auto:0'; 228 | my $parport = -1; 229 | 230 | #================================================================================================ 231 | # 232 | # create main window 233 | # 234 | #================================================================================================ 235 | my $mw = MainWindow->new(-title => "PerlBlast", -relief => 'raised', -borderwidth => 5, -background => 'darkgrey'); 236 | $mw->geometry($geometry); 237 | $mw->protocol('WM_DELETE_WINDOW' => \&MyExit); # called when window is closed 238 | 239 | # create window top drop down menu's 240 | $mw->configure(-menu => my $menubar = $mw->Menu); 241 | my $file = $menubar->cascade(-label => '~File'); 242 | my $galm = $menubar->cascade(-label => '~GAL'); 243 | # my $typm = $menubar->cascade(-label => '~Type'); 244 | my $help = $menubar->cascade(-label => '~Help'); 245 | # 246 | $file->command( 247 | -label => 'Open JEDEC', 248 | -accelerator => 'Ctrl-o', 249 | -underline => 0, 250 | -command => \&OpenJedec, 251 | ); 252 | $file->separator; 253 | $file->command( 254 | -label => 'Save JEDEC', 255 | -accelerator => 'Ctrl-s', 256 | -underline => 0, 257 | -command => \&SaveJedec, 258 | ); 259 | $file->separator; 260 | $file->command( 261 | -label => "Exit Program", 262 | -accelerator => 'Ctrl-q', 263 | -underline => 0, 264 | -command => \&MyExit, 265 | ); 266 | # 267 | $galm->command( 268 | -label => 'Read GAL', 269 | -command => \&ReadGal, 270 | ); 271 | $galm->command( 272 | -label => 'Write GAL', 273 | -command => \&WriteGal, 274 | ); 275 | 276 | # 277 | $help->command(-label => 'Version', -command => \&PrintVersion); ###sub {print "Version\n"}); 278 | $help->separator; 279 | $help->command(-label => 'About', -command => \&PrintAbout); ###sub {print "$ThisVersion\n"}); 280 | # 281 | # create frame to position the selections and buttons 282 | # 283 | $tp = $mw->Frame ( 284 | -height => 90, 285 | )->pack(-side => 'top', -fill => 'x'); 286 | # show port, fixed for now 287 | $tp->LabEntry ( 288 | -label => 'Port:', 289 | -labelPack => [-side => 'left', -anchor => 'w'], 290 | -textvariable => \$portname, 291 | -font => ['courier', '12', 'bold'], 292 | -width => 10, 293 | -relief => 'sunken', 294 | )->place(-x => 0, -y => 0); 295 | # show device Type: text 296 | $tp->Label ( 297 | -text => 'Type:', 298 | )->place(-x => 150, -y => 2); 299 | # 300 | # create a drop down menu 301 | my $opt = $tp->Optionmenu( 302 | -options => [ 303 | [UNKNOWN => 0], [GAL16V8 => 1], [GAL18V10 => 2], [GAL20V8 => 3], [GAL20RA10 => 4],[GAL20XV10 => 5],[GAL22V10 => 6], 304 | [GAL26CV12 => 7],[GAL6001 => 8],[GAL6002 => 9],[ATF16V8B => 10],[ATF22V10B => 11],[ATF22V10C => 12] 305 | ], 306 | -command => sub { \&SetGalParms(shift) }, 307 | -variable => $galtype, 308 | -textvariable => $galname, 309 | -width => 10, 310 | )->place(-x => 210, -y => 0); 311 | # 312 | $wp= $tp->Button ( 313 | -text => "Write PES", 314 | -width => 10, 315 | -command => \&WritePes, 316 | )->place(-x => 330, -y => 0); 317 | # 318 | $lj = $tp->Button ( 319 | -text => "Load JEDEC", 320 | -width => 10, 321 | -command => \&OpenJedec, 322 | )->place(-x => 0, -y => 30); 323 | # 324 | $rg = $tp->Button ( 325 | -text => "Read GAL", 326 | -width => 10, 327 | -command => \&ReadGal, 328 | )->place(-x => 110, -y => 30); 329 | # 330 | $vg = $tp->Button ( 331 | -text => "Verify GAL", 332 | -width => 10, 333 | -command => \&VerifyGal, 334 | )->place( -x => 220, -y => 30); 335 | # 336 | $se = $tp->Button ( 337 | -text => "SECURITY", 338 | -width => 10, 339 | -command => \&BurnSecurity, 340 | )->place(-x => 330, -y => 30); 341 | # 342 | $sj = $tp->Button ( 343 | -text => "Save JEDEC", 344 | -width => 10, 345 | -command => \&SaveJedec, 346 | )->place( -x => 0, -y => 60); 347 | # 348 | $wg = $tp->Button ( 349 | -text => "Write GAL", 350 | -width => 10, 351 | -command => \&WriteGal, 352 | )->place(-x => 110, -y => 60); 353 | # 354 | $eg = $tp->Button ( 355 | -text => "Erase GAL", 356 | -width => 10, 357 | -command => \&EraseGal, 358 | )->place(-x => 220, -y => 60); 359 | # 360 | $ea = $tp->Button ( 361 | -text => "Erase ALL", 362 | -width => 10, 363 | -command => \&EraseAll, 364 | )->place(-x => 330, -y => 60); 365 | # 366 | $lp = $tp->Button ( 367 | -text => "Load PES", 368 | -width => 10, 369 | -command => \&LoadPes, 370 | )->place(-x => 440, -y => 0); 371 | # 372 | $lp = $tp->Button ( 373 | -text => "Save PES", 374 | -width => 10, 375 | -command => \&SavePes, 376 | )->place(-x => 440, -y => 30); 377 | # 378 | # 379 | # listbox for jedec file data 380 | # 381 | $blg = $mw->Scrolled ('Listbox', 382 | -scrollbars => 'se', 383 | -width => 580, 384 | -height => 780, 385 | )-> pack(-side => 'bottom'); 386 | 387 | #================================================================================================ 388 | # 389 | # end of GUI definitions 390 | # 391 | # program runs through this too 392 | # 393 | #================================================================================================ 394 | #################################################################################################### 395 | # 396 | # parse command line args 397 | # 398 | #################################################################################################### 399 | getopts("p:", \%options); 400 | 401 | if (defined $options{p}) 402 | { 403 | $portnum = $options{p}; 404 | } 405 | 406 | &InitAll; # put interface and variables in decent state 407 | 408 | if ($portname ne "") 409 | { 410 | ($parport = Device::ParallelPort->new($portid)) || die "Can't open the choosen port $portname!\n"; 411 | } 412 | else 413 | { 414 | printf "perlblast: device $portname does not exist!\n"; 415 | exit (-1); # does not return 416 | } 417 | 418 | &HardwareInit; # setup programming hardware to a known state 419 | 420 | MainLoop(); 421 | 422 | #================================================================================================ 423 | # 424 | # here we start all functions 425 | # 426 | #================================================================================================ 427 | 428 | # read all settings for this kind of GAL 429 | # and SET all the variables to the correct name 430 | sub SetGalParms 431 | { 432 | # type,id0|id1,name,fuses,pins,rows,bits,uesrow,uesfuse,uesbytes,eraserow,eraseallrow,pesrow,pesbytes,cfgrow,config,vpp,progtime,erasetime 433 | @gal_setting = @{$galinfo{$_[0]}}; # return array 434 | s{^\s+|\s+$}{}g foreach @gal_setting; 435 | 436 | ($galtype,$galid0,$galid1,$galname,$galfuses,$galpins,$galrows,$galbits,$galuesrow,$galuesfuse,$galuesbytes,$galeraserow,$galeraseallrow, 437 | $galpesrow,$galpesbytes,$galcfgrow,$galconfig,$galvpp,$galprogtime,$galerasetime,$galvcc) = @gal_setting; # split up array 438 | } 439 | 440 | ################################################################################################# 441 | # 442 | # disable all buttons for now 443 | # 444 | ################################################################################################# 445 | sub KeysOff 446 | { 447 | $wp->configure(-state => 'disabled'); 448 | $lj->configure(-state => 'disabled'); 449 | $rg->configure(-state => 'disabled'); 450 | $vg->configure(-state => 'disabled'); 451 | $se->configure(-state => 'disabled'); 452 | $sj->configure(-state => 'disabled'); 453 | $wg->configure(-state => 'disabled'); 454 | $eg->configure(-state => 'disabled'); 455 | $ea->configure(-state => 'disabled'); 456 | $opt->configure(-state => 'disabled'); 457 | } 458 | 459 | ################################################################################################# 460 | # 461 | # re-enable the buttons 462 | # 463 | ################################################################################################# 464 | sub KeysOn 465 | { 466 | $wp->configure(-state => 'normal'); 467 | $lj->configure(-state => 'normal'); 468 | $rg->configure(-state => 'normal'); 469 | $vg->configure(-state => 'normal'); 470 | $se->configure(-state => 'normal'); 471 | $sj->configure(-state => 'normal'); 472 | $wg->configure(-state => 'normal'); 473 | $eg->configure(-state => 'normal'); 474 | $ea->configure(-state => 'normal'); 475 | $opt->configure(-state => 'normal'); 476 | } 477 | 478 | ################################################################################################# 479 | # 480 | # 481 | # 482 | ################################################################################################# 483 | sub ToListBox 484 | { 485 | my $string = $_[0]; 486 | $blg->insert('end', $string); 487 | } 488 | 489 | ################################################################################################# 490 | # 491 | # 492 | # 493 | ################################################################################################# 494 | sub ClrListBox 495 | { 496 | $blg->delete(0, 'end'); 497 | } 498 | 499 | ################################################################################################# 500 | # 501 | # 502 | # 503 | ################################################################################################# 504 | sub GetSetup 505 | { 506 | 507 | if ($portname eq "") 508 | { 509 | &DialogHandler(MSG_ALERT, "Can't open the given parport", 0); 510 | return FALSE; 511 | } 512 | 513 | if ($galtype == UNKNOWN) 514 | { 515 | &DialogHandler(MSG_ALERT, "Select a GAL first", 0); 516 | return FALSE; 517 | } 518 | return TRUE; 519 | } 520 | 521 | ################################################################################################# 522 | # 523 | # Load the JEDEC file 524 | # 525 | ################################################################################################# 526 | sub OpenJedec 527 | { 528 | if (&LoadFile) 529 | { 530 | DialogHandler(MSG_ALERT,"Filechecksum in error !!", 0); 531 | } 532 | } 533 | 534 | ################################################################################################# 535 | # 536 | # Save a JEDEC file 537 | # 538 | ################################################################################################# 539 | sub SaveJedec 540 | { 541 | &SaveFile; 542 | } 543 | 544 | ################################################################################################# 545 | # 546 | # Load PES from file 547 | # 548 | ################################################################################################# 549 | sub LoadPes 550 | { 551 | &LoadPESFile; 552 | &ParsePES; 553 | } 554 | 555 | ################################################################################################# 556 | # 557 | # Save PES to file 558 | # 559 | ################################################################################################# 560 | sub SavePes 561 | { 562 | &SavePESFile; 563 | } 564 | 565 | ################################################################################################# 566 | # 567 | # Read GAL info from DUT 568 | # 569 | ################################################################################################# 570 | sub ReadGal 571 | { 572 | if (&TestProperGAL == FALSE) 573 | { 574 | return; 575 | } 576 | @fuses = &ReadGAL(); 577 | &FormatJEDEC; 578 | } 579 | 580 | ################################################################################################# 581 | # 582 | # Write fusebuffer to DUT 583 | # 584 | ################################################################################################# 585 | sub WriteGal 586 | { 587 | if ($#fuses < 1) 588 | { 589 | &DialogHandler(MSG_ALERT, "Load a JEDEC fuse map first", 0); 590 | return; 591 | } 592 | if (!&CheckJEDEC(@fuses)) 593 | { 594 | RETURN true; 595 | } 596 | if (!&TestProperGAL) 597 | { 598 | return TRUE; 599 | } 600 | &WriteGAL(\@fuses); 601 | 602 | } 603 | 604 | ################################################################################################# 605 | # 606 | # Erase the DUT normal fuses 607 | # 608 | ################################################################################################# 609 | sub EraseGal 610 | { 611 | &EraseGAL; 612 | } 613 | 614 | ################################################################################################# 615 | # 616 | # Erase EVERYTHING from the DUT 617 | # 618 | ################################################################################################# 619 | sub EraseAll 620 | { 621 | &EraseALL; 622 | } 623 | 624 | ################################################################################################# 625 | # 626 | # Write the PES bytes to the DUT 627 | # 628 | ################################################################################################# 629 | sub WritePes 630 | { 631 | 632 | $vpp = $galvpp; 633 | $progtime = $galprogtime; 634 | $erasetime = $galerasetime; 635 | 636 | if (&GetSetup == FALSE) 637 | { 638 | # return FALSE; 639 | } 640 | if (&DialogHandler(MSG_ASSURE, "WritePES", CHECKPES) == TRUE) 641 | { 642 | &WritePES; 643 | } 644 | } 645 | 646 | ################################################################################################# 647 | # 648 | # program the security fuse 649 | # 650 | ################################################################################################# 651 | sub BurnSecurity 652 | { 653 | 654 | if(! &TestProperGAL) 655 | { 656 | return TRUE; 657 | } 658 | 659 | if (&DialogHandler(MSG_WARNING, "Programming the security fuse will prohibit the readout and verification of the GAL. Do you want to continue ?" ,CHECKBURNSEC) != TRUE) 660 | { 661 | return TRUE; 662 | } 663 | &BurnSECURITY; 664 | } 665 | 666 | ################################################################################################# 667 | # 668 | # Verify the DUT with the fuse buffer 669 | # 670 | ################################################################################################# 671 | sub VerifyGal 672 | { 673 | if ($#fuses < 1) 674 | { 675 | &DialogHandler(MSG_ALERT, "Load a JEDEC fuse map first", 0); 676 | return; 677 | } 678 | &VerifyGAL; 679 | } 680 | 681 | ################################################################################################# 682 | # 683 | # 684 | # 685 | ################################################################################################# 686 | sub SetPort 687 | { 688 | 689 | $portid = sprintf "auto:%1d", $portnum; 690 | $portname = sprintf "parport%1d", $portnum; 691 | } 692 | 693 | ################################################################################################# 694 | # 695 | # 696 | # 697 | ################################################################################################# 698 | sub PrintAbout 699 | { 700 | &DialogHandler(MSG_ALERT, "PerlBlast. An in Perl-Tk written version of GalBlast/ATFBlast", 0); 701 | 702 | } 703 | 704 | ################################################################################################# 705 | # 706 | # 707 | # 708 | ################################################################################################# 709 | sub PrintVersion 710 | { 711 | &DialogHandler(MSG_ALERT, "$ThisVersion", 0); 712 | } 713 | 714 | #================================================================================================ 715 | # 716 | # here the real action is done 717 | # 718 | #================================================================================================ 719 | sub ReadGAL 720 | { 721 | my @rfuses; 722 | my $bit; 723 | my $row; 724 | 725 | if (&TurnOn(READGAL)) 726 | { 727 | if(($galtype == GAL16V8) || ($galtype == GAL20V8)) 728 | { 729 | # read fuse rows 730 | for ($row = 0; $row < $galrows; $row++) 731 | { 732 | &StrobeRow($row); 733 | for ($bit = 0; $bit < $galbits; $bit++) 734 | { 735 | $rfuses[$galrows * $bit + $row] = &ReceiveBit; 736 | } 737 | } 738 | # read UES 739 | &StrobeRow($galuesrow); 740 | for ($bit = 0; $bit < $galuesbytes * 8; $bit++) 741 | { 742 | $rfuses[$galuesfuse + $bit] = &ReceiveBit; 743 | } 744 | # read CFG 745 | &StrobeRow($galcfgrow); 746 | for ($bit = 0; $bit < $#{$galconfig}+1 ; $bit++) 747 | { 748 | if ($pes[2] == 0x1A) 749 | { 750 | $rfuses[$cfg16V8AB[$bit]] = &ReceiveBit; 751 | } 752 | elsif ($pes[2] == 0x20) 753 | { 754 | $rfuses[$cfg20V8[$bit]] = &ReceiveBit; 755 | } 756 | elsif ($pes[2] == 0x3A) 757 | { 758 | $rfuses[$cfg20V8AB[$bit]] = &ReceiveBit; 759 | } 760 | else 761 | { 762 | # pes[2] = 0 or pes[2] is invalid 763 | $rfuses[$cfg16V8[$bit]] = &ReceiveBit; 764 | } 765 | } 766 | } 767 | elsif (($galtype == GAL6001) || ($galtype == GAL6002)) 768 | { 769 | for ($row = 0; $row < 78; $row++) 770 | { 771 | &StrobeRow($row); 772 | &DiscardBits(20); 773 | for ($bit = 0; $bit < 11 ; $bit++) 774 | { 775 | $rfuses[7296 + 78 * $bit + $row] = &ReceiveBit; 776 | } 777 | for ($bit = 0; $bit < 64 ; $bit++) 778 | { 779 | $rfuses[114 * $bit + $row] = &ReceiveBit; 780 | } 781 | &DiscardBits(24); 782 | } 783 | for ($row = 0; $row < 64; $row++) 784 | { 785 | &SendBits(31, 0); 786 | for ($bit = 0 ; $bit < 64; $bit++) 787 | { 788 | &SendBit(($bit != $row) ? 1 : 0); 789 | } 790 | &SendBits(24, 0); 791 | &SetSDIN(OFF); #? 792 | &Strobe(2); 793 | for ($bit = 0; $bit < 20; $bit++) 794 | { 795 | $rfuses[78 + 114 * $row + $bit] = &ReceiveBit; 796 | } 797 | &DiscardBits(83); 798 | for ($bit = 0; $bit < 16; $bit++) 799 | { 800 | $rfuses[98 + 114 * $row + $bit] = &ReceiveBit; 801 | } 802 | } 803 | # read UES 804 | &StrobeRow($galuesrow); 805 | &DiscardBits(20); 806 | for ($bit = 0; $bit < 72; $bit++) 807 | { 808 | $rfuses[$galuesbits + $bit] = &ReceiveBit; 809 | } 810 | # read CFG 811 | &SetRow($galcfgrow); 812 | &Strobe(2); 813 | for ($bit = 0; $bit < $#{$galconfig}+1; $bit++) 814 | { 815 | $rfuses[@{$galconfig}[$bit]] = &ReceiveBit; 816 | } 817 | } 818 | elsif ($galtype == ATF16V8B) 819 | { 820 | for ($row = 0; $row < $galrows; $row++) 821 | { 822 | &StrobeRow($row); 823 | for ($bit = 0; $ bit < $galbits; $bit++) 824 | { 825 | $rfuses[$galrows * $bit + $row] = &ReceiveBit; 826 | } 827 | } 828 | # read UES STF16V8 829 | &StrobeRow($galuesrow); 830 | for ($bit = 0; $bit < $galuesbytes * 8; $bit++) 831 | { 832 | $rfuses[$galuesfuse + $bit] = &ReceiveBit; 833 | } 834 | # read CFG ATF16V8 835 | &StrobeRow($galcfgrow); 836 | for ($bit = 0; $bit < $#{$galconfig} + 1; $bit++) 837 | { 838 | $rfuses[@{$galconfig}[$bit]] = &ReceiveBit; 839 | } 840 | } 841 | elsif (($galtype == GAL22V10) || ($galtype == ATF22V10B) || ($galtype == ATF22V10C)) 842 | { 843 | for ($row = 0; $row < $galrows; $row++) 844 | { 845 | &StrobeRow($row); 846 | for ($bit = 0; $bit < $galbits; $bit++) 847 | { 848 | $rfuses[$galrows * $bit + $row] = &ReceiveBit; 849 | } 850 | &Delay(1); 851 | } 852 | # read UES 853 | &StrobeRow($galuesrow); 854 | if ($galtype != GAL22V10) 855 | { 856 | &DiscardBits(68); # ATF22V10X 857 | } 858 | # common for all 859 | for ($bit = 0; $bit < ($galuesbytes * 8); $bit++) 860 | { 861 | $rfuses[$galuesfuse + $bit] = &ReceiveBit; # bug 2019-02-08 862 | } 863 | &Delay(1); 864 | # read CFG 865 | &SetRow($galcfgrow); 866 | &Strobe(2); 867 | for ($bit = 0; $bit < $#{$galconfig}+1; $bit++) 868 | { 869 | $rfuses[@{$galconfig}[$bit]] = &ReceiveBit; 870 | } 871 | } 872 | &GetPES; 873 | &TurnOff; 874 | } 875 | return @rfuses; 876 | } 877 | 878 | 879 | ################################################################################################# 880 | # 881 | # 882 | # 883 | ################################################################################################# 884 | sub VerifyGAL 885 | { 886 | my @vfuses = @fuses; # filled by CheckJEDEC 887 | my @rfuses; 888 | my $i; 889 | 890 | if (!&TestProperGAL) 891 | { 892 | return TRUE; 893 | } 894 | @rfuses = &ReadGAL; 895 | 896 | if ($#vfuses != $#rfuses) 897 | { 898 | &DialogHandler(MSG_ALERT,"Fusemap mismatch!", 0); 899 | return TRUE; 900 | } 901 | for ($i = 0; $i < $#rfuses; $i++) 902 | { 903 | if ($rfuses[$i] != $vfuses[$i]) 904 | { 905 | &DialogHandler(MSG_ALERT,"Fusemap mismatch!", 0); 906 | return TRUE; 907 | } 908 | } 909 | &DialogHandler(MSG_ALERT,"Fusemap correct match", 0); 910 | return TRUE; 911 | } 912 | 913 | ################################################################################################# 914 | # 915 | # 916 | # 917 | ################################################################################################# 918 | sub ReadPES 919 | { 920 | &TurnOn(READPES); 921 | &GetPES($_[0]); 922 | &TurnOff; 923 | } 924 | 925 | ################################################################################################# 926 | # 927 | # 928 | # 929 | ################################################################################################# 930 | sub GetPES 931 | { 932 | my $bitmask; 933 | my $byte; 934 | 935 | &StrobeRow($galpesrow); 936 | if (($galtype == GAL6001) || ($galtype == GAL6002)) 937 | { 938 | &DiscardBits(20); 939 | } 940 | for ($byte = 0; $byte < $galpesbytes; $byte++) 941 | { 942 | $pes[$byte] = 0; 943 | for ($bitmask = 0x01; $bitmask <= 0x80; $bitmask <<= 1) 944 | { 945 | if (&ReceiveBit) 946 | { 947 | $pes[$byte] |= $bitmask; 948 | } 949 | } 950 | } 951 | } 952 | 953 | 954 | ################################################################################################# 955 | # 956 | # 957 | # 958 | ################################################################################################# 959 | sub TestProperGAL 960 | { 961 | my $type = 1; 962 | my $galtypetmp = $galtype; 963 | 964 | if (&GetSetup == FALSE) 965 | { 966 | return FALSE; 967 | } 968 | &ReadPES; 969 | # 970 | if (($pes[7] eq 'F') && ($pes[5] eq '1') && ($pes[4] eq 'V') && ($pes[3] eq '1') && ($pes[2] eq '0')) 971 | { 972 | if ($pes[1] == 'B') 973 | { 974 | $galtype = ATF22V10B; 975 | } 976 | else 977 | { 978 | $galtype = ATF22V10C; 979 | } 980 | } 981 | elsif (($pes[6] eq 'F') && ($pes[5] eq '1') && ($pes[4] eq '6') && ($pes[3] eq 'V') && ($pes[2] eq '8')) 982 | { 983 | $galtype = ATF16V8B; 984 | } 985 | elsif (($pes[2] != 0) && ($pes[2] != 0xFF)) 986 | { 987 | for ($type = (keys %galinfo) - 1; $type; $type--) 988 | { 989 | &SetGalParms($type); 990 | if (($pes[2] == $galid0) || ($pes[2] == $galid1)) 991 | { 992 | goto TPG1; 993 | } 994 | } 995 | } 996 | TPG1: 997 | # 998 | # 999 | # 1000 | if ($type == 0) 1001 | { 1002 | if (&DialogHandler(MSG_WARNING, "Unknown or illegal PES, continue?", 0) == FALSE) 1003 | { 1004 | $galtype = $galtypetmp; 1005 | return FALSE; 1006 | } 1007 | } 1008 | else 1009 | { 1010 | if ($type != $galtypetmp) 1011 | { 1012 | my $return = &DialogHandler(MSG_WARNING, "PES indicates a different GAL type than selected, Change to detected GAL type?", TESTGAL); 1013 | if ($return == FALSE) 1014 | { 1015 | return FALSE; 1016 | } 1017 | else 1018 | { 1019 | $galtype = $galtypetmp; 1020 | } 1021 | } 1022 | } 1023 | &ParsePES; 1024 | return TRUE; 1025 | } 1026 | 1027 | ################################################################################################# 1028 | # 1029 | # 1030 | # 1031 | ################################################################################################# 1032 | sub ParsePES 1033 | { 1034 | my $algo; 1035 | my @duration = (1,2,5,10,20,30,40,50,60,70,80,90,100,200,0,0); 1036 | 1037 | $vpp = $galvpp; 1038 | $progtime = $galprogtime; 1039 | $erasetime = $galerasetime; 1040 | 1041 | if (($galtype == ATF16V8B) || ($galtype == ATF22V10B) || ($galtype == ATF22V10C)) 1042 | { 1043 | # already set all 1044 | return; 1045 | } 1046 | $algo = $pes[1] & 0x0F; 1047 | # i.e. Lattice 22V10 1048 | if ($algo == 5) 1049 | { 1050 | $erasetime = (25 << (($pes[4] >> 2) & 7))/ 2; 1051 | $progtime = @duration[((($pes[5] << 8) | $pes[4]) >> 5) & 0x0F]; 1052 | $vpp = 2 *(($pes[5] >> 1) & 0x1F) + 20; 1053 | return; 1054 | } 1055 | else 1056 | { 1057 | if(($galtype == GAL16V8) || ($galtype == GAL20V8)) 1058 | { 1059 | # 1060 | if ($algo == 0) 1061 | { 1062 | $vpp = 63; # 15.75V (3.75V dac) 1063 | return; 1064 | } 1065 | elsif ($algo == 1) 1066 | { 1067 | $vpp = 63; 1068 | $progtime = 80; 1069 | return; 1070 | } 1071 | elsif ($algo == 2) 1072 | { 1073 | $vpp = 66; # 16.5 V (4.5V dac) 1074 | $progtime = 10; 1075 | return; 1076 | } 1077 | elsif ($algo == 3) 1078 | { 1079 | $vpp = ($pes[3] == 0x8F) ? 60 : 58; # NATIONAL 15.0 or 14.5V 1080 | $progtime = 40; 1081 | return; 1082 | } 1083 | elsif ($algo == 4) 1084 | { 1085 | $vpp = 56; # 14V 1086 | return; 1087 | } 1088 | else 1089 | { 1090 | return; 1091 | } 1092 | } 1093 | else 1094 | { 1095 | $erasetime = ($pes[3] == 0x8F) ? 50 : 100; # NATIONAL 1096 | if ($algo == 0) 1097 | { 1098 | $vpp = 66; # 16.5V 1099 | $progtime = 10; 1100 | return; 1101 | } 1102 | elsif ($algo == 1) 1103 | { 1104 | $vpp = 63; # 15.75V 1105 | $progtime = 1000; 1106 | return; 1107 | } 1108 | elsif ($algo == 2) 1109 | { 1110 | $vpp = ($pes[3] == 0x8F) ? 60 : 58; # NATIONAL 15.0V or 14.5V 1111 | $progtime = 40; 1112 | return; 1113 | } 1114 | elsif ($algo == 3) 1115 | { 1116 | $vpp = 56; # 14V 1117 | $progtime = 100; 1118 | return; 1119 | } 1120 | } 1121 | } 1122 | &DialogHandler(MSG_ALERT, (sprintf "PES info unknown, check it!", $pos), 0); 1123 | $erasetime = 0; 1124 | $progtime = 0; 1125 | $vpp = 0; 1126 | } 1127 | 1128 | ################################################################################################# 1129 | # 1130 | # 1131 | # 1132 | ################################################################################################# 1133 | sub WritePES 1134 | { 1135 | my $byte; 1136 | my $bitmask; 1137 | if ($galtype == UNKNOWN) 1138 | { 1139 | &DialogHandler(MSG_ALERT, (sprintf "WritePES: unknown GAL type, don't know how to write!", $pos), 0); 1140 | return; 1141 | } 1142 | 1143 | if (&TurnOn(WRITEPES) == TRUE) 1144 | { 1145 | if(($galtype == GAL16V8) || ($galtype == GAL20V8) || ($galtype == ATF16V8B)) 1146 | { 1147 | usleep(10); 1148 | &SetRow($galpesrow); 1149 | for ($byte = 0; $byte < $galpesbytes; $byte++) 1150 | { 1151 | for($bitmask = 0x01; $bitmask <= 0x80; $bitmask <<= 1) 1152 | { 1153 | &SendBit(($pes[$byte] & $bitmask) ? 1 : 0); 1154 | } 1155 | } 1156 | &SetSDIN(OFF); 1157 | usleep(10); 1158 | &Strobe($progtime); 1159 | usleep(10); 1160 | } 1161 | elsif (($galtype == GAL6001) || ($galtype == GAL6002)) 1162 | { 1163 | &SetRow(0); 1164 | &SendBits( 20, 0); 1165 | for ($byte = 0; $byte < $galpesbytes; $byte++) 1166 | { 1167 | for ($bitmask = 0x01; $bitmask <= 0x80; $bitmask <<= 1) # bug 2019-02-08 1168 | { 1169 | &SendBit(($pes[$byte] & $bitmask) ? 1 : 0); 1170 | } 1171 | } 1172 | if (($galpesbytes * 8) < $galbits) 1173 | { 1174 | &SendBits(($galbits - ($galpesbytes * 8)), 0); 1175 | } 1176 | &SendBit(ON); 1177 | &SendAddress(7, $galpesrow); 1178 | &SendBits(16, 0); 1179 | &SetSDIN(OFF); 1180 | } 1181 | elsif (($galtype == GAL22V10) || ($galtype == ATF22V10B) || ($galtype == ATF22V10C)) 1182 | { 1183 | &SetRow(0); 1184 | for ($byte = 0; $byte < $galpesbytes; $byte++) 1185 | { 1186 | for ($bitmask = 0x01; $bitmask <= 0x80; $bitmask <<= 1) # bug 2019-02-08 1187 | { 1188 | &SendBit(($pes[$byte] & $bitmask) ? 1 : 0); 1189 | } 1190 | } 1191 | if (($galpesbytes * 8) < $galbits) 1192 | { 1193 | &SendBits(($galbits - ($galpesbytes * 8)), 0); 1194 | } 1195 | &SendAddress(6, $galpesrow); # bug 2019-02-08 1196 | &SetSDIN(OFF); 1197 | &Strobe($progtime); 1198 | } 1199 | else 1200 | { 1201 | &SetRow(0); 1202 | usleep(10); 1203 | for ($byte = 0; $byte < $galpesbytes; $byte++) 1204 | { 1205 | for($bitmask = 0x01; $bitmask <= 0x80; $bitmask <<= 1) 1206 | { 1207 | SendBit(($pes[$byte] & $bitmask) ? 1 : 0); 1208 | } 1209 | } 1210 | &SetSDIN(OFF); 1211 | &SendAddress( 6, $galpesrow); 1212 | usleep(10); 1213 | &Strobe($progtime); 1214 | usleep(10); 1215 | } 1216 | &TurnOff; 1217 | } 1218 | } 1219 | 1220 | ################################################################################################# 1221 | # 1222 | # 1223 | # 1224 | ################################################################################################# 1225 | # type,id0|id1,name,fuses,pins,rows,bits,uesrow,uesfuse,uesbytes,eraserow,eraseallrow,pesrow,pesbytes,cfgrow,config,cfgbits 1226 | sub FormatJEDEC 1227 | { 1228 | my $buffer; 1229 | my $fuseindex; 1230 | my $l; 1231 | my $bit; 1232 | my $bytes; 1233 | my $ch; 1234 | 1235 | &ClrListBox; 1236 | &ToListBox(sprintf "JEDEC file created on %s", strftime("%a %Y-%m-%d %k:%m:%S", localtime(time))); 1237 | &ToListBox(sprintf "%c", 0x02); 1238 | &ToListBox(sprintf "%s", $galname); 1239 | &ToListBox(sprintf "*QP%d*", $galpins); 1240 | &ToListBox(sprintf "QF%d*", $galfuses); 1241 | &ToListBox(sprintf "QV0*F0*G0*X0*", $galpins, $galfuses); 1242 | 1243 | if (($galtype == GAL6001) || ($galtype == GAL6002)) 1244 | { 1245 | for ($bit = $fuseindex = 0; $bit < $galbits; $bit++) 1246 | { 1247 | $buffer = sprintf "L%04d ", $fuseindex; 1248 | for ($bytes = 0; $bytes < 114; $bytes++) 1249 | { 1250 | $buffer .= sprintf "%s", ($fuses[$fuseindex++] == 1) ? '1' : '0'; 1251 | } 1252 | $buffer .= "*"; 1253 | &ToListBox($buffer); 1254 | } 1255 | for ($bit = 0; $bit < 11; $bit++) 1256 | { 1257 | $buffer = sprintf "L%04d ", $fuseindex; 1258 | for ($bytes = 0; $bytes < 78; $bytes++) 1259 | { 1260 | $buffer .= sprintf "%s", ($fuses[$fuseindex++] == 1) ? '1' : '0'; 1261 | } 1262 | $buffer .= "*"; 1263 | &ToListBox($buffer); 1264 | } 1265 | } 1266 | else 1267 | { 1268 | # do FUSES 1269 | for ($bit = $fuseindex = 0; $bit < $galbits; $bit++) 1270 | { 1271 | $buffer = sprintf "L%04d ", $fuseindex; 1272 | for ($bytes = 0; $bytes < $galrows; $bytes++) 1273 | { 1274 | $buffer .= sprintf "%s", ($fuses[$fuseindex++] == 1) ? '1' : '0'; 1275 | } 1276 | $buffer .= "*"; 1277 | &ToListBox($buffer); 1278 | } 1279 | if ($fuseindex < $galuesfuse) 1280 | { 1281 | $buffer = sprintf "L%04d ", $fuseindex; 1282 | while ($fuseindex < $galuesfuse) 1283 | { 1284 | $buffer .= sprintf "%s", ($fuses[$fuseindex++] == 1) ? '1' : '0'; 1285 | } 1286 | $buffer .= "*"; 1287 | &ToListBox($buffer); 1288 | } 1289 | # do UES 1290 | $buffer = sprintf "N UES"; 1291 | for ($bytes = 0; $bytes < $galuesbytes; $bytes++) 1292 | { 1293 | $ch = 0; 1294 | for ($bit = 0; $bit < 8; $bit++) 1295 | { 1296 | if ($fuses[$fuseindex + (8 * $bytes) + $bit]) 1297 | { 1298 | if ($galtype == ATF22V10C) 1299 | { 1300 | $ch |= (1 << (7 - $bit)); # BIG ENDIAN 1301 | } 1302 | else 1303 | { 1304 | $ch |= (1 << $bit); # LITTLE ENDIAN 1305 | } 1306 | } 1307 | } 1308 | $buffer .= sprintf " %02X", $ch; 1309 | } 1310 | $buffer .= "*"; 1311 | &ToListBox($buffer); 1312 | 1313 | $buffer = sprintf "L%04d ", $fuseindex; 1314 | for ($bytes = 0; $bytes < ($galuesbytes * 8); $bytes++) ##??? 1315 | { 1316 | $buffer .= sprintf "%s", ($fuses[$fuseindex++] == 1) ? '1' : '0'; 1317 | } 1318 | $buffer .= "*"; 1319 | &ToListBox($buffer); 1320 | # remainder 1321 | if ($fuseindex < $galfuses) 1322 | { 1323 | $buffer = sprintf "L%04d ", $fuseindex; 1324 | while ($fuseindex < $galfuses) 1325 | { 1326 | $buffer .= sprintf "%s", ($fuses[$fuseindex++] == 1) ? '1' : '0'; 1327 | } 1328 | $buffer .= "*"; 1329 | &ToListBox($buffer); 1330 | } 1331 | # do PES 1332 | $buffer = sprintf "N PES"; 1333 | for ($bit = 0; $bit < $galpesbytes; $bit++) 1334 | { 1335 | $buffer .= sprintf " %02X", $pes[$bit]; 1336 | } 1337 | $buffer .= "*"; 1338 | &ToListBox ($buffer); 1339 | &ToListBox ( sprintf "C%04X*", &CheckSum(\@fuses, $galfuses)); 1340 | &ToListBox ( sprintf "%c", 0x03); 1341 | } 1342 | } 1343 | 1344 | ################################################################################################# 1345 | # 1346 | # 1347 | # 1348 | ################################################################################################# 1349 | sub CheckJEDEC 1350 | { 1351 | my $pos = &ParseFuseMap($_[0]); 1352 | 1353 | if ($pos == length $_[0]) 1354 | { 1355 | return TRUE; 1356 | } 1357 | &DialogHandler(MSG_ALERT, (sprintf "Error in JEDEC at position %d", $pos), 0); 1358 | } 1359 | 1360 | ################################################################################################# 1361 | # 1362 | # 1363 | # 1364 | ################################################################################################# 1365 | sub ParseFuseMap 1366 | { 1367 | my @fusebuf = split(/|/, $_[0]); 1368 | my $len = length $_[0]; 1369 | my $i; 1370 | my $n; 1371 | my $type; 1372 | my $oldtype; 1373 | my $checksumpos = 0; 1374 | my $address; 1375 | my $pins = 0; 1376 | my $lastfuse = 0; 1377 | my $state = 0; 1378 | my $security = 0; 1379 | my $checksum = 0; 1380 | my $char; 1381 | 1382 | for ($n = 0; $n < $len; $n++) 1383 | { 1384 | $char = $fusebuf[$n]; 1385 | if ($char eq '*') 1386 | { 1387 | $state = 2; 1388 | } 1389 | else 1390 | { 1391 | # pseudo switch 1392 | if ($state == 2) 1393 | { 1394 | if ($char ne ' ') 1395 | { 1396 | if ($char eq 'L') 1397 | { 1398 | $address = 0; 1399 | $state = 3; 1400 | } 1401 | elsif ($char eq 'F') 1402 | { 1403 | $state = 5; 1404 | } 1405 | elsif ($char eq 'Q') 1406 | { 1407 | $state = 7; 1408 | } 1409 | elsif ($char eq 'C') 1410 | { 1411 | $state = 14; 1412 | $checksumpos = $n; 1413 | goto BREAK; 1414 | } 1415 | else 1416 | { 1417 | $state = 1; 1418 | } 1419 | } 1420 | goto BREAK; 1421 | } 1422 | elsif ($state == 3) 1423 | { 1424 | if ($char =~ m/[^0-9]/) 1425 | { 1426 | return $n; 1427 | } 1428 | $address = $char - '0'; 1429 | $state = 4; 1430 | goto BREAK; 1431 | } 1432 | elsif ($state == 4) 1433 | { 1434 | if ($char eq ' ') 1435 | { 1436 | $state = 6; 1437 | } 1438 | elsif ($char =~ m/[0-9]/) 1439 | { 1440 | $address = 10 * $address + ($char - '0'); 1441 | } 1442 | else 1443 | { 1444 | return $n; 1445 | } 1446 | goto BREAK; 1447 | } 1448 | elsif ($state == 5) 1449 | { 1450 | if ($char eq ' ') 1451 | { 1452 | goto BREAK; 1453 | } 1454 | if (($char eq '0') || ($char eq '1')) 1455 | { 1456 | @fuses = (1) x $galfuses; # empty fusemap 1457 | } 1458 | else 1459 | { 1460 | return $n; 1461 | } 1462 | $state = 1; 1463 | goto BREAK; 1464 | } 1465 | elsif ($state == 6) 1466 | { 1467 | if ($char eq ' ') 1468 | { 1469 | goto BREAK; 1470 | } 1471 | if (($char eq '0') || ($char eq '1')) 1472 | { 1473 | $fuses[$address++] = ($char - '0'); 1474 | } 1475 | else 1476 | { 1477 | return $n; 1478 | } 1479 | goto BREAK; 1480 | } 1481 | elsif ($state == 7) 1482 | { 1483 | if ($char eq ' ') 1484 | { 1485 | goto BREAK; 1486 | } 1487 | if ($char eq 'P') 1488 | { 1489 | $pins = 0; 1490 | $state = 8; 1491 | } 1492 | elsif ($char eq 'F') 1493 | { 1494 | $lastfuse = 0; 1495 | $state = 9; 1496 | } 1497 | else 1498 | { 1499 | $state = 2; 1500 | } 1501 | goto BREAK; 1502 | } 1503 | elsif ($state == 8) 1504 | { 1505 | if ($char eq ' ') 1506 | { 1507 | goto BREAK; 1508 | } 1509 | if ($char =~ m/[^0-9]/) 1510 | { 1511 | return $n; 1512 | } 1513 | $pins = $char - '0'; 1514 | $state = 10; 1515 | goto BREAK; 1516 | } 1517 | elsif ($state == 9) 1518 | { 1519 | if ($char eq ' ') 1520 | { 1521 | goto BREAK; 1522 | } 1523 | if ($char =~ m/[^0-9]/) 1524 | { 1525 | return $n; 1526 | } 1527 | $lastfuse = $char - '0'; 1528 | $state = 11; 1529 | goto BREAK; 1530 | } 1531 | elsif ($state == 10) 1532 | { 1533 | if ($char =~ m/[0-9]/) 1534 | { 1535 | $pins = 10 * $pins + ($char - '0'); 1536 | } 1537 | elsif ($char eq ' ') 1538 | { 1539 | $state = 12; 1540 | } 1541 | else 1542 | { 1543 | return $n; 1544 | } 1545 | goto BREAK; 1546 | } 1547 | elsif ($state == 11) 1548 | { 1549 | if ($char =~ m/[0-9]/) 1550 | { 1551 | $lastfuse = 10 * $lastfuse + ($char - '0'); 1552 | } 1553 | elsif ($char eq ' ') 1554 | { 1555 | $state = 12; 1556 | } 1557 | else 1558 | { 1559 | return $n; 1560 | } 1561 | goto BREAK; 1562 | } 1563 | elsif ($state == 12) 1564 | { 1565 | if ($char ne ' ') 1566 | { 1567 | return $n; 1568 | } 1569 | goto BREAK; 1570 | } 1571 | elsif ($state == 13) 1572 | { 1573 | if ($char eq ' ') 1574 | { 1575 | goto BREAK; 1576 | } 1577 | if (($char eq '0') || ($char eq '1')) 1578 | { 1579 | $security = ($char - '0'); 1580 | } 1581 | else 1582 | { 1583 | return $n; 1584 | } 1585 | $state = 1; 1586 | goto BREAK; 1587 | } 1588 | elsif ($state == 14) 1589 | { 1590 | if ($char eq ' ') 1591 | { 1592 | goto BREAK; 1593 | } 1594 | if ($char =~ m/[0-9]/) 1595 | { 1596 | $checksum = $char - '0'; 1597 | } 1598 | elsif(((uc $char) gt 'A') && ((uc $char) le 'F')) 1599 | { 1600 | $checksum = ((uc $char) - 'A' + 10); 1601 | } 1602 | else 1603 | { 1604 | return $n; 1605 | } 1606 | $state = 15; 1607 | goto BREAK; 1608 | 1609 | } 1610 | elsif ($state == 15) 1611 | { 1612 | if ($char =~ m/[0-9]/) 1613 | { 1614 | $checksum = 16 * $checksum + ($char - '0'); 1615 | } 1616 | elsif(((uc $char) gt 'A') && ((uc $char) le 'F')) 1617 | { 1618 | $checksum = (16 * $checksum) + ((ord (uc $char) - 0x41) + 10); 1619 | } 1620 | elsif ($char eq ' ') 1621 | { 1622 | $state = 2; 1623 | } 1624 | else 1625 | { 1626 | return $n; 1627 | } 1628 | goto BREAK; 1629 | } 1630 | BREAK: 1631 | } 1632 | } 1633 | if (($lastfuse) || ($pins)) 1634 | { 1635 | if(($checksum) && ($checksum != &CheckSum(\@fuses, $lastfuse))) 1636 | { 1637 | if (&DialogHandler(MSG_WARNING, ("Checksum given %04X calculated %04X", $checksum, &CheckSum(\@fuses, $lastfuse)), 0) == FALSE) 1638 | { 1639 | return $checksumpos; 1640 | } 1641 | } 1642 | $type = 0; 1643 | $oldtype = $galtype; 1644 | for ($i = 1; $i < keys %galinfo; $i++) 1645 | { 1646 | &SetGalParms($i); 1647 | if ((($lastfuse == 0) || ($galfuses == $lastfuse) || (($galuesfuse == $lastfuse) && ($galuesfuse + 8 * $galuesbytes) == $galfuses)) 1648 | && (($pins == 0) || ($galpins == $pins) || ($galpins == 24) && ($pins == 28)) ) 1649 | { 1650 | if ($galtype == UNKNOWN) 1651 | { 1652 | $type = $i; 1653 | goto BREAK2; 1654 | } 1655 | elsif (!$type) 1656 | { 1657 | $type = $i; 1658 | goto BREAK2; 1659 | } 1660 | } 1661 | } 1662 | BREAK2: 1663 | if ($oldtype != $type) 1664 | { 1665 | $galtype = $type; 1666 | &SetGalParms($type); 1667 | &DialogHandler(MSG_ALERT, "galtype has changed!! ", 0); 1668 | } 1669 | } 1670 | return $n; 1671 | } 1672 | 1673 | ################################################################################################# 1674 | # 1675 | # 1676 | # 1677 | ################################################################################################# 1678 | # Checksum(array, count) fuses 1679 | sub CheckSum 1680 | { 1681 | my @array = @{$_[0]}; 1682 | my $count = $_[1]; 1683 | my $sum = 0; 1684 | my $byte = 0; 1685 | my $mask = 1; 1686 | 1687 | for ($i = 0; $i < $count; $i++) 1688 | { 1689 | if ($array[$i] == 1) 1690 | { 1691 | $byte |= $mask; 1692 | } 1693 | $mask = $mask << 1; 1694 | if ($mask > 255) 1695 | { 1696 | $sum += $byte; 1697 | $byte = 0; 1698 | $mask = 1; 1699 | } 1700 | } 1701 | return ($byte + $sum) & 0xFFFF; 1702 | } 1703 | ################################################################################################# 1704 | # 1705 | # 1706 | # 1707 | ################################################################################################# 1708 | sub WriteGAL 1709 | { 1710 | my @array = @{$_[0]}; 1711 | my $row; 1712 | my $bit; 1713 | 1714 | if (&TurnOn(WRITEGAL)) 1715 | { 1716 | if(($galtype == GAL16V8) || ($galtype == GAL20V8)) 1717 | { 1718 | # write fuse rows 1719 | for ($row = 0; $row < $galrows; $row++) 1720 | { 1721 | &SetRow($row); 1722 | for ($bit = 0; $bit < $galbits; $bit++) 1723 | { 1724 | &SendBit (($array[$galrows * $bit + $row]) ? 1 : 0); 1725 | } 1726 | &Strobe($progtime); 1727 | } 1728 | # write UES 1729 | &SetRow($galuesrow); 1730 | for ($bit = 0; $bit < $galuesbytes * 8; $bit++) 1731 | { 1732 | &SendBit(($array[$galuesfuse + $bit]) ? 1 : 0); 1733 | } 1734 | &Strobe($progtime); 1735 | # write CFG 1736 | &SetRow($galcfgrow); 1737 | for ($bit = 0; $bit < $#{$galconfig}+1 ; $bit++) 1738 | { 1739 | if ($pes[2] == 0x1A) 1740 | { 1741 | &SendBit(($array[$cfg16V8AB[$bit]]) ? 1 : 0); 1742 | } 1743 | elsif ($pes[2] == 0x20) 1744 | { 1745 | &SendBit(($array[$cfg20V8[$bit]]) ? 1 : 0); 1746 | } 1747 | elsif ($pes[2] == 0x3A) 1748 | { 1749 | &SendBit(($array[$cfg20V8AB[$bit]]) ? 1 : 0); 1750 | } 1751 | else 1752 | { 1753 | # pes[2] = 0 or pes[2] is invalid 1754 | &SendBit(($array[$cfg16V8[$bit]]) ? 1 : 0); 1755 | } 1756 | } 1757 | &Strobe($progtime); 1758 | } 1759 | elsif (($galtype == GAL6001) || ($galtype == GAL6002)) 1760 | { 1761 | &SetRow(0); 1762 | for ($row = 0; $row < 78; $row++) 1763 | { 1764 | &SendBits(20, 0); 1765 | for ($bit = 0; $bit < 11 ; $bit++) 1766 | { 1767 | &SendBit( $array[7296 + 78 * $bit + $row] ); 1768 | } 1769 | for ($bit = 0; $bit < 64 ; $bit++) 1770 | { 1771 | &SendBit(($array[114 * $bit + $row]) ? 1 : 0); 1772 | } 1773 | &SendBit(1); 1774 | &SendAddress(7, $row); 1775 | &SendBits(16, 0); 1776 | &SetSDIN(OFF); 1777 | &Strobe($progtime); 1778 | } 1779 | for ($row = 0; $row < 64; $row++) 1780 | { 1781 | for ($bit = 0; $bit < 20; $bit++) 1782 | { 1783 | &SendBit (($array[78 + 114 * $row + $bit]) ? 1 : 0); 1784 | } 1785 | &DiscardBits(83); 1786 | for ($bit = 0; $bit < 16; $bit++) 1787 | { 1788 | &SendBit (($array[98 + 114 * $row + $bit]) ? 1 : 0); 1789 | } 1790 | } 1791 | # write UES 1792 | &SetRow($galuesrow); 1793 | &DiscardBits(20); 1794 | for ($bit = 0; $bit < 72; $bit++) 1795 | { 1796 | &SendBit (($array[$galuesbits + $bit]) ? 1 : 0); 1797 | } 1798 | # write CFG 1799 | &SetRow($galcfgrow); 1800 | &Strobe(2); 1801 | for ($bit = 0; $bit < $#{$galconfig}+1; $bit++) 1802 | { 1803 | &SendBit (($array[@{$galconfig}[$bit]]) ? 1 : 0); 1804 | } 1805 | } 1806 | elsif ($galtype == ATF16V8B) 1807 | { 1808 | for ($row = 0; $row < $galrows; $row++) 1809 | { 1810 | &SetRow($row); 1811 | for ($bit = 0; $ bit < $galbits; $bit++) 1812 | { 1813 | &SendBit(($array[$galrows * $bit + $row]) ? 1 : 0); 1814 | } 1815 | &Strobe($progtime); 1816 | } 1817 | # write UES STF16V8 1818 | &SetRow($galuesrow); 1819 | for ($bit = 0; $bit < $galuesbytes * 8; $bit++) 1820 | { 1821 | &SendBit(($array[$galuesfuse + $bit]) ? 1 : 0); 1822 | } 1823 | &Strobe($progtime); 1824 | # write CFG ATF16V8 1825 | &SetRow($galcfgrow); 1826 | for ($bit = 0; $bit < $#{$galconfig} + 1; $bit++) 1827 | { 1828 | &SendBit(($array[@{$galconfig}[$bit]]) ? 1 : 0); 1829 | } 1830 | &Strobe($progtime); 1831 | } 1832 | elsif (($galtype == GAL22V10) || ($galtype == ATF22V10B)) 1833 | { 1834 | &SetRow(0); # RA0...RA5 low 1835 | for ($row = 0; $row < $galrows; $row++) 1836 | { 1837 | for ($bit = 0; $bit < $galbits; $bit++) 1838 | { 1839 | &SendBit (($array[$galrows * $bit + $row]) ? 1 : 0); 1840 | } 1841 | &SendAddress(6, $row); 1842 | &SetSDIN(OFF); 1843 | &Strobe($progtime); 1844 | } 1845 | # write UES 1846 | if ($galtype == ATF22V10B) 1847 | { 1848 | &SendBits(68, 1); 1849 | for ($bit = 0; $bit < ($galuesbytes * 8) ; $bit++) 1850 | { 1851 | &SendBit(($array[$galuesfuse + $bit]) ? 1 : 0); 1852 | } 1853 | } 1854 | else 1855 | { 1856 | for ($bit = 0; $bit < ($galuesbytes * 8) ; $bit++) 1857 | { 1858 | &SendBit(($array[$galuesfuse + $bit]) ? 1 : 0); 1859 | } 1860 | if (($galuesbytes * 8) < $galbits) 1861 | { 1862 | &SendBits($galbits - ($galuesbytes * 8), 0); 1863 | } 1864 | } 1865 | &SendAddress(6, $galuesrow); 1866 | &SetSDIN(OFF); 1867 | &Strobe($progtime); 1868 | # write CFG 1869 | &SetRow($galcfgrow); 1870 | for ($bit = 0; $bit < $#{$galconfig} + 1; $bit++) 1871 | { 1872 | &SendBit(($array[@{$galconfig}[$bit]]) ? 1 : 0); 1873 | } 1874 | &SetSDIN(OFF); 1875 | &Strobe($progtime); 1876 | } 1877 | elsif ($galtype == ATF22V10C) 1878 | { 1879 | &SetRow(0); 1880 | for ($row = 0; $row < $galrows; $row++) 1881 | { 1882 | for ($bit = 0; $bit < $galbits; $bit++) 1883 | { 1884 | &SendBit(($array[$galrows * $bit + $row]) ? 1 : 0); 1885 | } 1886 | &SendAddress( 6, $row); 1887 | &SetPV(ON); 1888 | &Strobe($progtime); 1889 | &SetPV(OFF); 1890 | } 1891 | # write UES 1892 | &SendBits(68, 1); 1893 | for ($bit = 0; $bit < ($galuesbytes * 8); $bit++) 1894 | { 1895 | &SendBit(($array[$galuesfuse + $bit]) ? 1 : 0); 1896 | } 1897 | &SendAddress( 6, $row); 1898 | &SetPV(ON); 1899 | &Strobe($progtime); 1900 | &SetPV(OFF); 1901 | # write CFG 1902 | &SetRow($galcfgrow); 1903 | for ($bit = 0; $bit < 19; $bit++) 1904 | { 1905 | &SendBit(($array[@{$galconfig}[$bit]]) ? 1 : 0); 1906 | } 1907 | &SetSDIN($array[@{$galconfig}[19]]); 1908 | &SetPV(ON); 1909 | &Strobe($progtime); 1910 | &SetPV(OFF); 1911 | # disable power-down feature 1912 | &SetRow(0); 1913 | &SendAddress(6, 59); 1914 | &SetPV(ON); 1915 | &Strobe($progtime); 1916 | &SetPV(OFF) 1917 | } 1918 | else # default 1919 | { 1920 | &SetRow(0); 1921 | for ($row = 0; $row < $galrows; $row++) 1922 | { 1923 | for ($bit = 0; $bit < $galbits; $bit++) 1924 | { 1925 | &SendBit (($array[$galrows * $bit + $row]) ? 1 : 0); 1926 | } 1927 | &SendAddress(6, $row); 1928 | &SetSDIN(OFF); 1929 | &Strobe($progtime); 1930 | } 1931 | # UES 1932 | for ($bit = 0; $bit < ($galuesbytes * 8); $bit++) 1933 | { 1934 | &SendBit(($array[$galuesfuse + $bit]) ? 1 : 0); 1935 | } 1936 | if (($galuesbytes * 8) < $galbits) 1937 | { 1938 | &SendBits($galbits - ($galuesbytes * 8), 0); 1939 | } 1940 | &SendAddress (6, $galuesrow); 1941 | &SetSDIN(OFF); 1942 | &Strobe($progtime); 1943 | # CFG 1944 | &SetRow($galcfgrow); 1945 | for ($bit = 0; $bit < $#{$galconfig} + 1; $bit++) 1946 | { 1947 | &SendBit (($array[@{$galconfig}[$bit]]) ? 1 : 0); 1948 | } 1949 | &SetSDIN(OFF); 1950 | &Strobe($progtime); 1951 | } 1952 | &TurnOff; 1953 | } 1954 | return ; 1955 | } 1956 | 1957 | ################################################################################################# 1958 | # 1959 | # 1960 | # 1961 | ################################################################################################# 1962 | sub EraseGAL 1963 | { 1964 | if (&TurnOn(ERASEGAL)) 1965 | { 1966 | &SetRow($galeraserow); 1967 | if (($galtype == GAL16V8) || ($galtype == ATF16V8B) || ($galtype == GAL20V8)) 1968 | { 1969 | &SendBit(1); 1970 | } 1971 | &Strobe($erasetime); 1972 | &TurnOff; 1973 | } 1974 | } 1975 | 1976 | ################################################################################################# 1977 | # 1978 | # 1979 | # 1980 | ################################################################################################# 1981 | sub EraseALL 1982 | { 1983 | if (&TurnOn(ERASEALL)) 1984 | { 1985 | &SetRow($galeraseallrow); 1986 | if(($galtype == GAL16V8) || ($galtype == ATF16V8B) || ($galtype == GAL20V8)) 1987 | { 1988 | &SendBit(1); 1989 | } 1990 | &Strobe($erasetime); 1991 | &TurnOff; 1992 | } 1993 | } 1994 | 1995 | ############################################################################################## 1996 | # 1997 | # 1998 | # 1999 | ############################################################################################## 2000 | sub BurnSECURITY 2001 | { 2002 | if (&TurnOn(BURNSECURITY)) 2003 | { 2004 | if (($galtype == GAL16V8) || ($galtype == GAL20V8) || ($galtype == ATF16V8B)) 2005 | { 2006 | &SetRow(61); 2007 | &SendBit(1); 2008 | } 2009 | elsif (($galtype == GAL6001) || ($galtype == GAL6002)) 2010 | { 2011 | &SetRow(0); 2012 | &SendBits(20 + 11 + 64, 0); 2013 | &SendBit(1); 2014 | &SendAddress(7, 98); 2015 | &SendBits(16, 0); 2016 | &SetSDIN(OFF); 2017 | } 2018 | else 2019 | { 2020 | &SetRow(0); 2021 | if ($galtype == GAL18V10) 2022 | { 2023 | &SendBits(96, 0); 2024 | } 2025 | elsif ($galtype == GAL20RA10) 2026 | { 2027 | &SendBits(80, 0); 2028 | } 2029 | elsif ($galtype == GAL20XV10) 2030 | { 2031 | &SendBits(40, 0); 2032 | } 2033 | elsif (($galtype == GAL22V10) || ($galtype == ATF22V10B) || ($galtype == ATF22V10C)) 2034 | { 2035 | &SendBits(132, 0); 2036 | } 2037 | elsif ($galtype == GAL26CV12) 2038 | { 2039 | &SendBits(122, 0); 2040 | } 2041 | &SendAddress(6, 61); 2042 | &SetSDIN(OFF); 2043 | } 2044 | &Strobe($progtime); 2045 | &TurnOff; 2046 | } 2047 | } 2048 | 2049 | ############################################################################################## 2050 | # 2051 | # 2052 | # 2053 | ############################################################################################## 2054 | sub StrobeRow 2055 | { 2056 | my $row = $_[0]; 2057 | 2058 | if(($galtype == GAL16V8) || ($galtype == GAL20V8) || ($galtype == ATF16V8B)) 2059 | { 2060 | &SetRow($row); 2061 | } 2062 | elsif (($galtype == GAL6001) || ($galtype == GAL6002)) 2063 | { 2064 | &SetRow(0); 2065 | &SendBits(95,0); 2066 | &SendBit(1); 2067 | &SendAddress(7, $row); 2068 | &SendBits(16); 2069 | } 2070 | elsif (($galtype == GAL22V10) || ($galtype == ATF22V10B) || ($galtype == ATF22V10C)) 2071 | { 2072 | &SetRow(0); 2073 | &SendAddress(6, $_[0]); 2074 | &SetSTB(ON); 2075 | &SetSTB(OFF); 2076 | &SetSDIN(OFF); 2077 | return; 2078 | } 2079 | else 2080 | { 2081 | &SetRow(0); 2082 | &SendBits($galbits, 0); 2083 | &SendAddress(6, $row); 2084 | } 2085 | &Strobe(2); 2086 | } 2087 | 2088 | ################################################################################################# 2089 | # 2090 | # 2091 | # 2092 | ################################################################################################# 2093 | sub ReceiveBit 2094 | { 2095 | # clock bit in from SDOUT 2096 | &SetSDIN(OFF); 2097 | usleep(10); 2098 | my $bit = &GetSDOUT(); 2099 | &SetSCLK(ON); 2100 | usleep(10); 2101 | &SetSCLK(OFF); 2102 | usleep(10); 2103 | #print "bit: $bit\n"; 2104 | return ($bit == TRUE) ? 1 : 0; 2105 | } 2106 | 2107 | ################################################################################################# 2108 | # 2109 | # 2110 | # 2111 | ################################################################################################# 2112 | sub GetSDOUT 2113 | { 2114 | return &GetACK; # ack is output from DUT 2115 | } 2116 | 2117 | ################################################################################################# 2118 | # 2119 | # 2120 | # 2121 | ################################################################################################# 2122 | sub SendBit 2123 | { 2124 | &SetSDIN(($_[0]) ? ON : OFF); # (bit) 2125 | usleep(10); 2126 | &SetSCLK(ON); 2127 | usleep(10); 2128 | &SetSCLK(OFF); 2129 | usleep(10); 2130 | } 2131 | 2132 | ################################################################################################# 2133 | # 2134 | # 2135 | # 2136 | ################################################################################################# 2137 | sub SendBits 2138 | { 2139 | my $count = $_[0]; # (n, bit) 2140 | my $bit = $_[1]; 2141 | 2142 | while($count--) 2143 | { 2144 | &SendBit($bit); 2145 | } 2146 | } 2147 | 2148 | ################################################################################################# 2149 | # 2150 | # 2151 | # 2152 | ################################################################################################# 2153 | sub DiscardBits 2154 | { 2155 | my $count = $_[0]; # (n) 2156 | 2157 | while($count--) 2158 | { 2159 | &ReceiveBit; # throw away data 2160 | } 2161 | } 2162 | 2163 | ################################################################################################# 2164 | # 2165 | # 2166 | # 2167 | ################################################################################################# 2168 | sub SendAddress 2169 | { 2170 | my $count = $_[0]; # (n, row) 2171 | my $row = $_[1]; 2172 | 2173 | if ($galtype == ATF22V10C) # /* ATF22V10C MSb first, other 22V10 LSb first */ 2174 | { 2175 | while ($count-- > 1) 2176 | { 2177 | &SendBit(($row & 32) ? 1 : 0); 2178 | $row <<= 1; 2179 | } 2180 | &SetSDIN(($row & 32) ? ON : OFF); 2181 | } 2182 | else 2183 | { 2184 | while ($count-- > 0) 2185 | { 2186 | &SendBit(($row & 1) ? 1 : 0); 2187 | $row >>= 1; 2188 | } 2189 | &SetSDIN(OFF); 2190 | } 2191 | } 2192 | 2193 | ################################################################################################# 2194 | # 2195 | # 2196 | # 2197 | ################################################################################################# 2198 | sub Delay 2199 | { 2200 | my $msec = $_[0]; 2201 | 2202 | usleep($msec * 1000); 2203 | } 2204 | 2205 | ################################################################################################# 2206 | # 2207 | # 2208 | # 2209 | ################################################################################################# 2210 | sub Strobe() 2211 | { 2212 | &Delay(1); 2213 | &SetSTB(ON); 2214 | &Delay($_[0]); 2215 | &SetSTB(OFF); 2216 | &Delay(1); 2217 | } 2218 | 2219 | ################################################################################################# 2220 | # 2221 | # 2222 | # 2223 | ################################################################################################# 2224 | sub SetSTB 2225 | { 2226 | SetSTROBE($_[0]); # ON / OFF 2227 | } 2228 | 2229 | ################################################################################################# 2230 | # 2231 | # 2232 | # 2233 | ################################################################################################# 2234 | sub CheckHexEntry 2235 | { 2236 | my ($val) = @_; 2237 | my $b_valid = ($val =~ /^[0-9A-F]{1,2}$/i)? 1: 0; 2238 | 2239 | return $b_valid; 2240 | } 2241 | 2242 | ######################################################################################################## 2243 | # 2244 | # load JEDEC file 2245 | # 2246 | ######################################################################################################## 2247 | sub LoadFile 2248 | { 2249 | my $types = [ 2250 | ['JEDEC Files', ['.jed', '.JED']], 2251 | ['All Files', '*', ], 2252 | ]; 2253 | 2254 | my $file = $mw->getOpenFile(-filetypes => $types, -defaultextension => ".JED" ); 2255 | if (defined $file) 2256 | { 2257 | return &ProcessLoadFile($file); 2258 | } 2259 | else 2260 | { 2261 | return -1; 2262 | } 2263 | } 2264 | 2265 | ######################################################################################################## 2266 | # 2267 | # save JEDEC file 2268 | # 2269 | ######################################################################################################## 2270 | sub SaveFile 2271 | { 2272 | my $types = [ 2273 | ['JEDEC Files', ['.jed', '.JED']], 2274 | ['All Files', '*', ], 2275 | ]; 2276 | 2277 | my $file = $mw->getSaveFile(-filetypes => $types, -defaultextension => ".JED" ); 2278 | &ProcessSaveFile($file) if defined $file; 2279 | } 2280 | 2281 | ######################################################################################################## 2282 | # 2283 | # load PES from file 2284 | # 2285 | ######################################################################################################## 2286 | sub LoadPESFile 2287 | { 2288 | my $types = [ 2289 | ['PES Files', ['.pes', '.PES']], 2290 | ['All Files', '*', ], 2291 | ]; 2292 | 2293 | my $file = $mw->getOpenFile(-filetypes => $types, -defaultextension => ".PES" ); 2294 | &ProcessLoadPESFile($file) if defined $file; 2295 | } 2296 | 2297 | ######################################################################################################## 2298 | # 2299 | # load PES from file 2300 | # 2301 | ######################################################################################################## 2302 | sub SavePESFile 2303 | { 2304 | my $types = [ 2305 | ['PES Files', ['.pes', '.PES']], 2306 | ['All Files', '*', ], 2307 | ]; 2308 | 2309 | my $file = $mw->getSaveFile(-filetypes => $types, -defaultextension => ".PES" ); 2310 | return &ProcessSavePESFile($file) if defined $file; 2311 | } 2312 | 2313 | ################################################################################################# 2314 | # 2315 | # Load a JEDEC file 2316 | # 2317 | ################################################################################################# 2318 | sub ProcessLoadFile 2319 | { 2320 | my $filename = $_[0]; 2321 | my @filebuf; 2322 | my $fusedata; 2323 | my $i; 2324 | my $ptr; 2325 | my $fcflag = 0; 2326 | my $loadchecksum = 0; 2327 | my $filechecksum = 0; 2328 | my $listboxline; 2329 | 2330 | my $oldslurp = $/; 2331 | local ($/); # slurp mode 2332 | 2333 | &ClrListBox; 2334 | open (JEDECIN, "<", $filename) || &DialogHandler(MSG_ALERT," File not found!" , 0); 2335 | # first RAW read for FILE checksum 2336 | while() 2337 | { 2338 | @filebuf = split ('|', $_); ##unpack "a1" x (length( $_ ) /1 ), $_; 2339 | for ($i = 0; $i < $#filebuf; $i++) 2340 | { 2341 | if (ord $filebuf[$i] == 0x02) 2342 | { 2343 | $fcflag = 1; 2344 | } 2345 | if ($fcflag == 1) 2346 | { 2347 | $loadchecksum += ord $filebuf[$i]; 2348 | $loadchecksum &= 0xFFFF; # max 65535 2349 | } 2350 | if (ord $filebuf[$i] == 0x03) 2351 | { 2352 | $fcflag = 0; 2353 | } 2354 | } 2355 | } 2356 | # now normal read to process data 2357 | $/ = $oldslurp; 2358 | seek JEDECIN, 0,0 ; # REWIND FILE 2359 | # now in normal mode 2360 | while() 2361 | { 2362 | chomp; 2363 | $_ =~ s/[\r\n]//g; # remove EOL 2364 | $fusedata .= $_; 2365 | # display 2366 | &ToListBox($_); 2367 | } 2368 | close JEDECIN; 2369 | # 2370 | # $fusedata now holds the clean file info, now remove everything outside STX and ETX 2371 | # 2372 | $ptr = index($fusedata, chr(0x02)); 2373 | if ($ptr < 0) 2374 | { 2375 | &DialogHandler(MSG_ALERT,"Error in File, can't locate STX",0); 2376 | return; 2377 | } 2378 | else 2379 | { 2380 | $fusedata = substr($fusedata, $ptr+1); # cut everything before and including STX 2381 | } 2382 | 2383 | $ptr = index($fusedata, chr(0x03)); 2384 | if ($ptr < 0) 2385 | { 2386 | &DialogHandler(MSG_ALERT,"Error in File, can't locate ETX",0); 2387 | return; 2388 | } 2389 | else 2390 | { 2391 | $filechecksum = substr($fusedata, $ptr + 1, 4); # grab file checksum here 2392 | $fusedata = substr($fusedata, 0, $ptr); # drop everything after and including ETX 2393 | } 2394 | @ffuses = split(/|/, $fusedata); 2395 | &CheckJEDEC ($fusedata); 2396 | # accept files where filechecksum has been declared 0000 2397 | return (hex($filechecksum) == 0) ? 0 : hex($filechecksum)-$loadchecksum; 2398 | } 2399 | 2400 | ################################################################################################# 2401 | # 2402 | # Save a JEDEC file 2403 | # 2404 | ################################################################################################# 2405 | sub ProcessSaveFile 2406 | { 2407 | my $filename = $_[0]; 2408 | my @elements = $blg->get(0, 'end'); 2409 | my $filechecksum = 0; 2410 | my $checksumon = 0; 2411 | my $characters; 2412 | my $i; 2413 | 2414 | if ($#elements != -1) 2415 | { 2416 | open (JEDECOUT, ">", $filename) || &DialogHandler(MSG_ALERT, "Could not open outputfile!", 0); 2417 | 2418 | foreach $line (@elements) 2419 | { 2420 | @characters = split (/|/, $line); 2421 | for ($i = 0; $i < $#characters + 1; $i++) 2422 | { 2423 | if (($checksumon == 0) && (ord $characters[$i] == 2 )) # STX 2424 | { 2425 | $checksumon = 1; 2426 | } 2427 | elsif (($checksumon == 1) && (ord $characters[$i] == 3)) #ETX 2428 | { 2429 | $checksumon = 2; 2430 | } 2431 | printf JEDECOUT "%s", $characters[$i]; 2432 | if ($checksumon != 0) 2433 | { 2434 | $filechecksum += ord $characters[$i]; 2435 | } 2436 | elsif ($checksumon == 2) 2437 | { 2438 | $checksumon = 0; 2439 | printf JEDECOUT "%04X", $filechecksum; 2440 | $i += 4; # skip over possible existing checksum from prev load 2441 | } 2442 | $filechecksum &= 0xffff; 2443 | } 2444 | printf JEDECOUT "\r\n"; 2445 | if ($checksumon == 1) 2446 | { 2447 | $filechecksum += ord "\r"; 2448 | $filechecksum += ord "\n"; 2449 | } 2450 | } 2451 | close JEDECOUT; 2452 | } 2453 | else 2454 | { 2455 | &DialogHandler(MSG_ALERT, "No data to write!, nothing done", 0); 2456 | } 2457 | } 2458 | 2459 | ################################################################################################# 2460 | # 2461 | # 2462 | # 2463 | ################################################################################################# 2464 | sub ProcessLoadPESFile 2465 | { 2466 | my $filename = $_[0]; 2467 | my $line; 2468 | my $fh; 2469 | my $i; 2470 | 2471 | if (!open($fh, "<", $filename)) 2472 | { 2473 | &DialogHandler(MSG_ALERT, "Can't open file: $filename", 0); 2474 | return; 2475 | } 2476 | $line = <$fh>; 2477 | close $fh; 2478 | 2479 | $line =~ s/[\r\n]//g; # remove EOL chars 2480 | if (length $line != 16) # 8 HEX character sets 2481 | { 2482 | &DialogHandler(MSG_ALERT,"PES File has not correct size!", 0); 2483 | return; 2484 | } 2485 | if (&CheckHexEntry(split(/|/,$line))) 2486 | { 2487 | for ($i =0; $i <8; $i++) 2488 | { 2489 | @pes[$i] = hex( substr($line,$i*2, 2)); 2490 | } 2491 | } 2492 | else 2493 | { 2494 | &DialogHandler(MSG_ALERT,"PES File has non HEX characters!", 0); 2495 | return; 2496 | } 2497 | } 2498 | 2499 | ################################################################################################# 2500 | # 2501 | # 2502 | # 2503 | ################################################################################################# 2504 | sub ProcessSavePESFile 2505 | { 2506 | my $filename = $_[0]; 2507 | my $fh; 2508 | my $i; 2509 | 2510 | if (!open($fh, ">", $filename)) 2511 | { 2512 | &DialogHandler(MSG_ALERT, "Can't open file: $filename", 0); 2513 | return; 2514 | } 2515 | 2516 | for ($i = 0; $i < 8 ; $i++) 2517 | { 2518 | printf $fh "%02X", $pes[$i]; 2519 | } 2520 | printf $fh "\n"; 2521 | 2522 | close $fh; 2523 | } 2524 | 2525 | ################################################################################################# 2526 | # 2527 | # 2528 | # 2529 | ################################################################################################# 2530 | # turn on DUT 2531 | sub TurnOn 2532 | { 2533 | my $mode = $_[0]; # function 2534 | my $writeorerase = FALSE; 2535 | 2536 | #print "TO: vpp= $vpp\n"; 2537 | 2538 | if (($mode == WRITEGAL) || ($mode == ERASEGAL) || ($mode == ERASEALL) 2539 | || ($mode == BURNSECURITY) || ($mode == WRITEPES) || ($mode == VPPTEST)) 2540 | { 2541 | if (&DialogHandler(MSG_ASSURE, "Write DUT", $mode) == FALSE) 2542 | { 2543 | return FALSE; 2544 | } 2545 | else 2546 | { 2547 | $writeorerase = TRUE; 2548 | } 2549 | } 2550 | 2551 | #print "TO2: vpp= $vpp\n"; 2552 | 2553 | &SetVPP(0); # VPP off 2554 | &SetPV(OFF); # P/V- low resistor will correct for levels 2555 | &SetRow(0x3f); # RA0-5 High 2556 | &SetVCC($galvcc);# turn on VCC 2557 | &SetSDIN(OFF); # SDIN high 2558 | &SetSCLK(OFF); # SCLK low 2559 | &SetSTB(OFF); # STB high, outputs to H 2560 | &Delay(100); 2561 | &SetVPP(($writeorerase == TRUE) ? $vpp : $read12v); 2562 | 2563 | if ($writeorerase == TRUE) 2564 | { 2565 | &SetPV(ON); # P/V- is to O1, 2566 | &Delay(10); 2567 | } 2568 | return TRUE; # true 2569 | } 2570 | 2571 | ################################################################################################# 2572 | # 2573 | # unpower the DUT 2574 | # 2575 | ################################################################################################# 2576 | # turn off DUT 2577 | sub TurnOff 2578 | { 2579 | &Delay(10); 2580 | &SetPV(OFF); # P/V- LOW = verify 2581 | &SetRow(0x3F); # RA0-5 HIGH 2582 | &SetSDIN(OFF); # SDIN High 2583 | &SetVPP(0); # VPP off 2584 | &Delay(2); 2585 | &SetVCC(0); # turn off VCC 2586 | } 2587 | 2588 | ################################################################################################# 2589 | # 2590 | # 2591 | # 2592 | ################################################################################################# 2593 | # set P/V- signal level 2594 | sub SetPV 2595 | { 2596 | &SetSEL($_[0]); # ON / OFF 2597 | } 2598 | 2599 | #================================================================================================ 2600 | # 2601 | # Dialogs and other User interaction 2602 | # 2603 | # message types MSG_OK MSG_ALERT MSG_WARNING MSG_ASSURE 2604 | # mode types READGAL READPES VERIFYGAL SCLKTEST WRITEGAL ERASEGAL ERASEALL CHECKBURNSEC BURNSECURITY WRITEPES VPPTEST TESTGAL 2605 | #================================================================================================ 2606 | sub DialogHandler 2607 | { 2608 | my $msgfunc = $_[0]; 2609 | my $title = $_[1]; 2610 | my $mode = $_[2]; 2611 | my $testval = -1; 2612 | my $textrow1; 2613 | my $textrow2; 2614 | my $textrow3; 2615 | my $auxtext = ""; 2616 | my $temptext; 2617 | my $lbuttontext = "OK"; 2618 | my $rbuttontext = "Cancel"; 2619 | my $i; 2620 | my @lpes = (0,0,0,0,0,0,0,0); 2621 | 2622 | #print "msgfunc: $msgfunc mode: $mode\n"; 2623 | # fixed size and default buttons 2624 | 2625 | my $dw = $mw->Toplevel( 2626 | -title => $title, 2627 | ); 2628 | 2629 | my $can = $dw->Button ( 2630 | -text => $rbuttontext, 2631 | -width => 10, 2632 | -command => sub { $testval = 0; $dw->withdraw() }, 2633 | )->pack(-side => 'right', -anchor => 's'); 2634 | 2635 | $dwb1 = $dw->Button ( 2636 | -text => $lbuttontext, 2637 | -width => 10, 2638 | -command => sub { $testval = 1; $dw->withdraw() }, 2639 | )->pack(-side => 'right', -anchor => 's'); 2640 | 2641 | $dwl1 = $dw->Label( 2642 | -text => $textrow1, 2643 | -just => 'left', 2644 | )->place(-x => 0, -y => 5); 2645 | #----------------------------------------------------------------------------------------------------- 2646 | # 2647 | # Declare UI layout for Dialogs, show settings and allow for to edit (some) 2648 | # 2649 | #----------------------------------------------------------------------------------------------------- 2650 | if ($msgfunc == MSG_ASSURE) 2651 | { 2652 | $dwl2 = $dw->Label( 2653 | -text => $textrow2, 2654 | )->place(-x => 0, -y => 25); 2655 | # 2656 | $dwl3 = $dw->Label( 2657 | -text => $textrow3, 2658 | )->place(-x => 0, -y => 45); 2659 | # 2660 | # variable items 2661 | # 2662 | $dw->geometry('400x150'); # textrow1 / textrow3 / vpp:prog setting /buttons 2663 | 2664 | $dwb1->configure(-text => $lbuttontext); 2665 | 2666 | if (($mode == CHECKPES) || ($mode == WRITEPES) || ($mode == WRITEGAL) ||($mode == ERASEGAL) || ($mode == ERASEALL)) 2667 | { 2668 | &ParsePES; 2669 | for ($i = 0; $i <= $#pes; $i++) 2670 | { 2671 | $lpes[$i] = sprintf "%02X", $pes[$i]; 2672 | } 2673 | } 2674 | 2675 | if (($mode == WRITEPES) || ($mode == WRITEGAL) || ($mode == ERASEGAL) || ($mode == ERASEALL) || ($mode == BURNSECURITY)) 2676 | { 2677 | $dle1 = $dw->LabEntry( 2678 | -textvariable => \$vppf, 2679 | -label => 'VPP: ', 2680 | -labelPack => [-side => 'left', -anchor => 'w'], 2681 | -width => 5, 2682 | -bg => 'white', 2683 | -font => ['courier', '12', 'bold'], 2684 | )->place(-x => 0, -y => 70); 2685 | 2686 | $dle2 = $dw->LabEntry( 2687 | -textvariable => \$progf, 2688 | -label => 'Prog-Pulse ', 2689 | -labelPack => [-side => 'left', -anchor => 'w'], 2690 | -width => 3, 2691 | -bg => 'white', 2692 | -font => ['courier', '12', 'bold'], 2693 | )->place(-x => 160, -y => 70); 2694 | } 2695 | $dwl4 = $dw->Label( 2696 | -font => ['courier', '12', 'bold'], 2697 | -text => $auxtext, 2698 | )->place (-x => 0, -y => 90); 2699 | 2700 | if ($mode == CHECKPES) 2701 | { 2702 | $dw->geometry('400x100'); 2703 | 2704 | $lbuttontext = "Write PES"; 2705 | $dwb1->configure(-text => $lbuttontext); 2706 | 2707 | for ($i = 0 ; $i <8; $i++) 2708 | { 2709 | my $wname = sprintf "\$de%1d", $i; 2710 | $wname = $dw->LabEntry( 2711 | -width => 2, 2712 | # -textvariable => $lpes[$i], 2713 | -font => ['courier', '12', 'bold'], 2714 | -bg => 'white', 2715 | -validatecommand => \&CheckHexEntry, 2716 | -validate => 'key', 2717 | )->place(-x => $i * 24, -y => 20); 2718 | $wname->configure(-textvariable => \$lpes[$i]); 2719 | } 2720 | } 2721 | } 2722 | #----------------------------------------------------------------------------------------------------- 2723 | # 2724 | # show a simple message to the user, return on buttonpress 2725 | # 2726 | #----------------------------------------------------------------------------------------------------- 2727 | elsif ($msgfunc == MSG_ALERT) 2728 | { 2729 | $dw->geometry('400x50'); 2730 | 2731 | $textrow1 = $title; 2732 | $can->destroy(); 2733 | $dwl1->configure(-text => $textrow1); 2734 | } 2735 | #----------------------------------------------------------------------------------------------------- 2736 | # 2737 | # show warning, user can preceed or abort 2738 | # 2739 | #----------------------------------------------------------------------------------------------------- 2740 | elsif ($msgfunc == MSG_WARNING) 2741 | { 2742 | $dw->geometry('700x50'); 2743 | $textrow1 = $title; 2744 | $dwl1->configure(-text => $textrow1); 2745 | 2746 | if (($mode == TESTGAL) || ($mode == CHECKBURNSEC)) 2747 | { 2748 | $lbuttontext = "Yes"; 2749 | $rbuttontext = "No"; 2750 | $can->configure(-text => $rbuttontext); 2751 | $dwb1->configure(-text => $lbuttontext); 2752 | } 2753 | } 2754 | # 2755 | # initial contents 2756 | # 2757 | if (($mode == CHECKPES) || ($mode == WRITEPES) || ($mode == WRITEGAL) ||($mode == ERASEGAL) || ($mode == ERASEALL) || ($mode == BURNSECURITY)) 2758 | { 2759 | if (hex($lpes[3]) == $LATTICE) 2760 | { 2761 | $temptext = "Lattice"; 2762 | } 2763 | elsif (hex($lpes[3]) == $NATIONAL) 2764 | { 2765 | $temptext = "National"; 2766 | } 2767 | elsif (hex($lpes[3]) == $SGSTHOMSON) 2768 | { 2769 | $temptext = "ST"; 2770 | } 2771 | else 2772 | { 2773 | $temptext = "Unknown"; 2774 | } 2775 | } 2776 | 2777 | if ($mode == CHECKPES) 2778 | { 2779 | $textrow1 = sprintf "B1 B2 B3 B4 D1 D2 D3 D4"; 2780 | $dwl1->configure(-text => $textrow1, -just => 'left'); 2781 | $textrow3 = sprintf "VPP=%2.2f Prog-Pulse=%dmS Erase-Pulse=%dmS", $vpp/4.0, $progtime, $erasetime; 2782 | $dwl3->configure(-text => $textrow3); 2783 | } 2784 | elsif (($mode == WRITEPES) || ($mode == WRITEGAL) || ($mode == ERASEGAL) || ($mode == ERASEALL) || ($mode == BURNSECURITY)) 2785 | { 2786 | $textrow1 = sprintf "%s %s %s", ($pes[1] & 0x10)?"3.3V":"5.0V", $temptext, @{$galinfo{$galtype}}[3]; 2787 | $dwl1->configure(-text => $textrow1); 2788 | $textrow2 = sprintf "PES: %02s %02s %02s %02s %02s %02s %02s %02s", $lpes[0],$lpes[1],$lpes[2],$lpes[3],$lpes[4],$lpes[5],$lpes[6],$lpes[7]; 2789 | $dwl2->configure(-text => $textrow2); 2790 | $textrow3 = sprintf "VPP=%2.2f Prog-Pulse=%dmS Erase-Pulse=%dmS", $vpp/4.0, $progtime, $erasetime; 2791 | $dwl3->configure(-text => $textrow3); 2792 | $vppf = sprintf "%2.2f", $vpp / 4.0; 2793 | $dle1->configure(-text => $vppf); 2794 | if (($mode == WRITEPES) || ($mode == WRITEGAL) || ($mode == BURNSECURITY)) 2795 | { 2796 | $progf = sprintf "%3d", $progtime; 2797 | } 2798 | elsif (($mode == ERASEGAL) || ($mode == ERASEALL)) 2799 | { 2800 | $dle2->configure(-label => 'Erase-Pulse'); 2801 | $progf = sprintf "%3d", $erasetime; 2802 | } 2803 | else 2804 | { 2805 | $progf = "XXX"; 2806 | } 2807 | $dle2->configure(-text => $progf); 2808 | } 2809 | 2810 | if ($mode == WRITEGAL) 2811 | { 2812 | $lbuttontext = "Write GAL"; 2813 | $dwb1->configure(-text => $lbuttontext); 2814 | } 2815 | 2816 | if ($mode == ERASEGAL) 2817 | { 2818 | $auxtext = "*** Erase GAL ***"; 2819 | $dwl4->configure(-text => $auxtext); 2820 | $lbuttontext = "Erase GAL"; 2821 | $dwb1->configure(-text => $lbuttontext); 2822 | } 2823 | elsif ($mode == ERASEALL) 2824 | { 2825 | $auxtext = "*** Erase WHOLE GAL, including PES! ***"; 2826 | $dwl4->configure(-text => $auxtext); 2827 | $lbuttontext = "Erase ALL"; 2828 | $dwb1->configure(-text => $lbuttontext); 2829 | } 2830 | 2831 | # 2832 | # wait user response here and update everything in the while 2833 | # 2834 | &KeysOff; 2835 | 2836 | # 2837 | # wait until use presses button 2838 | # 2839 | while($testval < 0){ 2840 | $mw->update; 2841 | 2842 | if (hex($lpes[3]) == $LATTICE) 2843 | { 2844 | $temptext = "Lattice"; 2845 | } 2846 | elsif (hex($lpes[3]) == $NATIONAL) 2847 | { 2848 | $temptext = "National"; 2849 | } 2850 | elsif (hex($lpes[3]) == $SGSTHOMSON) 2851 | { 2852 | $temptext = "ST"; 2853 | } 2854 | else 2855 | { 2856 | $temptext = "Unknown"; 2857 | } 2858 | usleep(10000); 2859 | } 2860 | 2861 | if ($testval == 1) 2862 | { 2863 | if ($mode == CHECKPES) 2864 | { 2865 | for ($i = 0; $i < 8 ; $i++) 2866 | { 2867 | $pes[$i] = hex($lpes[$i]); 2868 | } 2869 | } 2870 | } 2871 | &KeysOn; 2872 | # on success copy the data 2873 | return ($testval == 1) ? TRUE : FALSE; 2874 | } 2875 | 2876 | #================================================================================================ 2877 | # 2878 | # all functions that interact directly with the port hardware 2879 | # 2880 | #================================================================================================ 2881 | 2882 | ################################################################################################# 2883 | # 2884 | # set VCC voltage 0.0, 3.3 or 5.0 V 2885 | # 2886 | ################################################################################################# 2887 | sub SetVCC 2888 | { 2889 | my $setting = $_[0]; # parameter that represents the desired voltage 2890 | my $portdata; 2891 | 2892 | # for the CSGBLAST hardware uncomment the following lines 2893 | # $portdata = ord $parport->get_data(); # save present state 2894 | # &SetFEED(OFF); # freezes the data settings in the hardware 2895 | # if ($setting == 0.0) 2896 | # { 2897 | # $ls273shadow &= ~0xC0; # VCC (3.3 and 5) off 2898 | # } 2899 | # elsif ($setting == 3.3) 2900 | # { 2901 | # $ls273shadow &= ~0x40; # 3V3 select 2902 | # $ls273shadow |= 0x80; # 2903 | # } 2904 | # elsif ($setting == 5.0) 2905 | # { 2906 | # $ls273shadow |= 0xC0; # 5V0 select 2907 | # } 2908 | # $parport->set_data(chr($ls273shadow)); 2909 | # &SetINIT(ON); # strobe 74LS273 2910 | # &SetINIT(OFF); # 2911 | # $parport->set_data(chr($portdata)); # restore old 2912 | # &SetFEED(ON); # re-enable 2913 | # for a simple ON/OFF control this is sufficient 2914 | &SetINIT($setting); # ON / OFF 2915 | } 2916 | 2917 | ################################################################################################# 2918 | # 2919 | # This is the modules that should be adapted to the REAL programming hardware where 2920 | # it comes to voltage settings 2921 | # 2922 | ################################################################################################# 2923 | # set programming voltage 2924 | sub SetVPP 2925 | { 2926 | my $setting = $_[0]; # parameter that represents the desired voltage 2927 | my $portdata; 2928 | 2929 | if ($parport != -1) 2930 | { 2931 | # for the CSGBLAST hardware uncomment the following lines 2932 | # $portdata = ord $parport->get_data(); # save present state 2933 | # &SetFEED(OFF); # freezes the data settings in the hardware 2934 | # if ($setting == 0) # off 2935 | # { 2936 | # $ls273shadow &= ~0x20; # VPP off 2937 | # $parport->set_data(chr($ls273shadow)); 2938 | # &SetINIT(ON); 2939 | # &SetINIT(OFF); # clear 74LS273, VPP off 2940 | # } 2941 | # else 2942 | # { 2943 | # if( ($setting < $read12v) || ($setting > 68)) 2944 | # { 2945 | ## should not happen!! 2946 | # } 2947 | # else 2948 | # { 2949 | # $dacvalue = (($setting - $read12v) / 4.0) / 5.0 * 255; 2950 | # $parport->set_data(chr($dacvalue)); 2951 | # &SetSTROBE(ON); 2952 | # &SetSTROBE(OFF); 2953 | # $dacvalueshadow = $dacvalue; 2954 | # $ls273shadow |= 0x20; # VPP ON 2955 | # $parport->set_data(chr($ls273shadow)); 2956 | # &SetINIT(ON); 2957 | # &SetINIT(OFF); # clear 74LS273, VPP off 2958 | # } 2959 | # } 2960 | # $parport->set_data(chr($portdata)); # restore old 2961 | # &SetFEED(ON); # re-enable 2962 | # for a simple ON/OFF control where the real voltage is controlled by user 2963 | if ($setting != 0) 2964 | { 2965 | &SetFEED(ON); # direct VPP on 2966 | } 2967 | else 2968 | { 2969 | &SetFEED(OFF); # direct VPP off 2970 | } 2971 | } 2972 | return FALSE; 2973 | } 2974 | 2975 | ################################################################################################# 2976 | # 2977 | # 2978 | # 2979 | ################################################################################################# 2980 | sub InitAll 2981 | { 2982 | &SetPort; 2983 | &SetGalParms(UNKNOWN); 2984 | } 2985 | 2986 | ################################################################################################# 2987 | # 2988 | # 2989 | # 2990 | ################################################################################################# 2991 | sub MyExit 2992 | { 2993 | &TurnOff; 2994 | exit; 2995 | } 2996 | 2997 | ################################################################################################# 2998 | # 2999 | # 3000 | # 3001 | ################################################################################################# 3002 | # now device port is open, sync the hardware with the software 3003 | sub HardwareInit 3004 | { 3005 | &TurnOff; 3006 | # for the CSGBLAST hardware uncomment the following lines 3007 | # &SetFEED(ON); # 3008 | # $parport->set_data(chr(0x7E)); # all row bits high, clock and data low 3009 | # &SetFEED(OFF); # 3010 | # $parport->set_data(chr(0x00)); # reset everything 3011 | # &SetSTROBE(ON); 3012 | # &SetStROBE(OFF): # this clears the DAC 3013 | # &SetINIT(ON); # strobe2 3014 | # $SetINIT(OFF): # clear the 74LS273 latch (VCC/VPP = off) 3015 | # &SetFEED(ON); # 3016 | # $parport->set_data(chr(0x7E)); # all row bits high, clock and data low 3017 | } 3018 | 3019 | ############################################################################################## 3020 | # 3021 | # all functions that interact with HARDWARE 3022 | # 3023 | ########################################### data ############################################# 3024 | 3025 | ################################################################################################# 3026 | # 3027 | # 3028 | # 3029 | ################################################################################################# 3030 | sub SetSDIN 3031 | { 3032 | if ($parport != -1) 3033 | { 3034 | if ($_[0] == ON) 3035 | { 3036 | $parport->set_bit(0,1); # data high TO DUT 3037 | } 3038 | else 3039 | { 3040 | $parport->set_bit(0,0); # data low TO DUT 3041 | } 3042 | } 3043 | return FALSE; 3044 | } 3045 | 3046 | ################################################################################################# 3047 | # 3048 | # 3049 | # 3050 | ################################################################################################# 3051 | sub SetSCLK 3052 | { 3053 | if ($parport != -1) 3054 | { 3055 | if ($_[0] == ON) 3056 | { 3057 | $parport->set_bit(7,1); # clock high TO DUT 3058 | } 3059 | else 3060 | { 3061 | $parport->set_bit(7,0); # clock low TO DUT 3062 | } 3063 | } 3064 | return FALSE; 3065 | } 3066 | 3067 | ################################################################################################# 3068 | # 3069 | # 3070 | # 3071 | ################################################################################################# 3072 | sub SetRow 3073 | { 3074 | if ($parport != -1) 3075 | { 3076 | my $control = ord $parport->get_data(); 3077 | 3078 | if ($_[0] > 63) 3079 | { 3080 | printf STDERR "Fatal: illegal row number $_[0]!\n"; 3081 | } 3082 | $inverse = $_[0] & 0x3F; 3083 | $control = ($control & 0x81) | ($inverse <<= 1); # keep clk and data bit 3084 | $parport->set_data(chr($control)); # set bit 3085 | } 3086 | return FALSE; 3087 | } 3088 | 3089 | ######################################## outputs ############################################## 3090 | 3091 | ################################################################################################# 3092 | # 3093 | # ON = low level @ interface pin, OFF = high level @ interface pin 3094 | # 3095 | ################################################################################################# 3096 | sub SetSTROBE 3097 | { 3098 | if ($parport != -1) 3099 | { 3100 | my $control = ord $parport->get_control() & ~$STROBE; 3101 | 3102 | if ($_[0] == ON) 3103 | { 3104 | $control |= $STROBE; # out = low 3105 | } 3106 | $parport->set_control(chr($control)); 3107 | } 3108 | return FALSE; 3109 | } 3110 | 3111 | ################################################################################################# 3112 | # 3113 | # ON = high level @ interface pin, OFF = low level @ interface pin 3114 | # 3115 | ################################################################################################# 3116 | sub SetFEED 3117 | { 3118 | if ($parport != -1) 3119 | { 3120 | my $control = ord $parport->get_control() & ~$LNFEED; 3121 | 3122 | if ($_[0] == !ON) 3123 | { 3124 | $control |= $LNFEED; 3125 | } 3126 | $parport->set_control(chr($control)); 3127 | } 3128 | return FALSE; 3129 | } 3130 | 3131 | ################################################################################################# 3132 | # 3133 | # ON = high level @ interface pin, OFF is low level @ interface pin 3134 | # 3135 | ################################################################################################# 3136 | sub SetINIT 3137 | { 3138 | if ($parport != -1) 3139 | { 3140 | my $control = ord $parport->get_control() & ~$INIT; 3141 | 3142 | if ($_[0] == ON) 3143 | { 3144 | $control |= $INIT; 3145 | } 3146 | $parport->set_control(chr($control)); 3147 | } 3148 | return FALSE; 3149 | } 3150 | 3151 | ################################################################################################# 3152 | # 3153 | # ON = high level @ interface pin, OFF is low level @ interface pin 3154 | # 3155 | ################################################################################################# 3156 | sub SetSEL 3157 | { 3158 | if ($parport != -1) 3159 | { 3160 | my $control = ord $parport->get_control() & ~$SELCTP; 3161 | 3162 | if ($_[0] == !ON) 3163 | { 3164 | $control |= $SELCTP; # P/V- high 3165 | } 3166 | $parport->set_control(chr($control)); # set bit 3167 | } 3168 | return FALSE; 3169 | } 3170 | 3171 | ########################################## inputs ############################################## 3172 | 3173 | ################################################################################################# 3174 | # 3175 | # 3176 | # 3177 | ################################################################################################# 3178 | sub GetACK 3179 | { 3180 | if ($parport != -1) 3181 | { 3182 | my $val = ord $parport->get_status & $ACK; # get bit 3183 | 3184 | return ($val != 0) ? TRUE : FALSE; 3185 | } 3186 | return FALSE; 3187 | } 3188 | 3189 | ################################################################################################# 3190 | # 3191 | # 3192 | # 3193 | ################################################################################################# 3194 | sub GetBUSY 3195 | { 3196 | if ($parport != -1) 3197 | { 3198 | my $val = ord $parport->get_status & $BUSY; 3199 | 3200 | return ($val != 0) ? TRUE : FALSE; 3201 | } 3202 | return FALSE; 3203 | } 3204 | 3205 | ################################################################################################# 3206 | # 3207 | # 3208 | # 3209 | ################################################################################################# 3210 | sub GetERROR 3211 | { 3212 | if ($parport != -1) 3213 | { 3214 | my $val = ord $parport->get_status & $ERROR; 3215 | 3216 | return ($val != 0) ? TRUE : FALSE; 3217 | } 3218 | return FALSE; 3219 | } 3220 | 3221 | ################################################################################################# 3222 | # 3223 | # 3224 | # 3225 | ################################################################################################# 3226 | sub GetPAPOUT 3227 | { 3228 | if ($parport != -1) 3229 | { 3230 | my $val = ord $parport->get_status & $PAPOUT; 3231 | 3232 | return ($val != 0) ? TRUE : FALSE; 3233 | } 3234 | return FALSE; 3235 | } 3236 | 3237 | ################################################################################################# 3238 | # 3239 | # 3240 | # 3241 | ################################################################################################# 3242 | sub GetSELECT 3243 | { 3244 | if ($parport != -1) 3245 | { 3246 | my $val = ord $parport->get_status & $SELECT; 3247 | 3248 | return ($val != 0) ? TRUE : FALSE; 3249 | } 3250 | return FALSE; 3251 | } 3252 | -------------------------------------------------------------------------------- /software/README.md: -------------------------------------------------------------------------------- 1 | * 'perlblast_nh' is a Perl implementation of 'Galblast' and is ment to be used with my CSGBLAST/CSGSOCK2 hardware. 2 | * It switches all voltages on the programming socket to a low value when idle. (remain some 1 to 1.5V) 3 | * Is designed to protect the parallel port hardware from dangerous voltages from the DUT in case of faults. 4 | * Has shown, under Linux, that it also can be used with certain USB<->IEE1284 dongles. (Lucent USS720 chip compatible) 5 | * Programming voltage VPP can be set from 12.0 to 17.0 Volt, which is adequate for almost all GAL types 6 | * Supply voltage VCC can be set for 3V3 and 5V0 volt. perlblast_nh does this automatically. 7 | 8 | * Needs an external 24VDC adapter for supply. 9 | * On board voltage regulators. 10 | 11 | --------------------------------------------------------------------------------