1;;; gEDA - GPL Electronic Design Automation
2;;; gnetlist - gEDA Netlist
3;;; Backend for cascade (http://rfcascade.sourceforge.net)
4;;; Copyright (C) 2003-2010 Dan McMahill
5;;;
6;;; This program is free software; you can redistribute it and/or modify
7;;; it under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 2 of the License, or
9;;; (at your option) any later version.
10;;;
11;;; This program is distributed in the hope that it will be useful,
12;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with this program; if not, write to the Free Software
18;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19;;; MA 02111-1301 USA.
20
21
22;; Locate and print out the global defaults if the element exists
23(define cascade:write-defaults-top
24  (lambda (port pkgs)
25    (if (not (null? pkgs))
26	(let ( (pkg (car pkgs)) )
27	  (if (string=? (get-device pkg) "cascade-defaults-top")
28	      (begin
29		(display "# Initial global defaults\n" port)
30		(display "defaults " port)
31		(map (lambda (attrib)
32		       (let ((val (gnetlist:get-package-attribute pkg attrib)))
33			 (if (not (string=? val "unknown"))
34			     (display (string-append attrib "=" val " ") port)
35			     )
36			 )
37		       )
38		     (list "rin" "RIN" "rout" "ROUT" "rho" "RHO")
39		     )
40		(newline port)
41		(newline port)
42		)
43	      (cascade:write-defaults-top port (cdr pkgs))
44	      )
45	  )
46	)
47    )
48  )
49
50;; Locate and print out the "source" line and return the refdes of
51;; the first element in the cascade
52(define cascade:write-source
53  (lambda (port pkgs)
54    (if (not (null? pkgs))
55	(let ( (package (car pkgs) )
56	       (sourcenet #f)
57	       )
58	  (if (string=? (get-device package) "cascade-source")
59	      (begin
60		(set! sourcenet (gnetlist:get-nets package "1"))
61		(display "source " port)
62		(map (lambda (attrib)
63		       (let ((val (gnetlist:get-package-attribute package attrib)))
64			 (if (not (string=? val "unknown"))
65			     (display (string-append attrib "=" val " ") port)
66			     )
67			 )
68		       )
69		     (list "c" "C" "cn0" "CN0" "cn" "CN" "bw" "BW")
70		     )
71		(newline port)
72
73		(if (string=? (caadr sourcenet) package)
74		    (caaddr sourcenet)
75		    (caadr sourcenet)
76		    )
77		)
78	      (cascade:write-source port (cdr pkgs) )
79	      )
80	  )
81	;; the list of packages is now empty
82	'()
83	)
84    )
85  )
86
87;; recursively follow the cascade and print out each element as its
88;; found
89(define cascade:follow-cascade
90  (lambda (port pkg)
91    (if (not (null? pkg))
92	(begin
93	  (let ( (outnet (gnetlist:get-nets pkg "2"))
94		 )
95
96	    ;; Is this a "defaults" element or a normal element?
97	    ;; If its a defaults element, then print "defaults"
98	    ;; instead of the reference designator because thats
99	    ;; a keyword for cascade.
100	    (if (string=? (get-device pkg) "cascade-defaults")
101		(display "defaults " port)
102		(display (string-append pkg " ") port)
103		)
104
105	    ;; spit out all the relevant attributes for element or
106	    ;; defaults lines
107	    (map (lambda (attrib)
108		   (let ((val (gnetlist:get-package-attribute pkg attrib)))
109		     (if (not (string=? val "unknown"))
110			 (display (string-append attrib "=" val " ") port)
111			 )
112		     )
113		   )
114		 (list "g" "G" "gp" "GP" "gv" "GV" "nf" "NF" "iip3"
115		       "IIP3" "r" "R" "rin" "RIN" "rout" "ROUT"
116		       "rho" "RHO")
117		 )
118	    (newline port)
119
120	    ;;(display "cascade:follow-cascade  -- outnet = ")
121	    ;;(display outnet)
122	    ;;(newline)
123	    (if (>= (length outnet) 3)
124		(if (string=? (caadr outnet) pkg)
125		    (cascade:follow-cascade port(caaddr outnet))
126		    (cascade:follow-cascade port (caadr outnet))
127		    )
128		)
129	    )
130	  )
131	)
132    )
133  )
134
135;; The top level netlister for cascade
136(define cascade
137   (lambda (filename)
138     (newline)
139     (display "---------------------------------\n")
140     (display "gEDA/gnetlist Cascade Backend\n")
141
142     (display "---------------------------------\n\n")
143
144     (display (string-append "Writing to output file \"" filename
145			     "\"... ") )
146      (let ((port (open-output-file filename))
147	    (first_block #f)
148	    )
149
150	;; write the header
151	(display "# Cascade (http://rfcascade.sourceforge.net)\n"
152		 port)
153	(display "# Created with gEDA/gnetlist\n\n" port)
154
155	;; Write out an initial "defaults" line if it exists
156	(cascade:write-defaults-top port packages)
157
158	;; Write out the "source" line and keep track of what its
159	;; connected to.  If we couldn't find the source, then
160	;; exit out.
161	(display "# Source definition\n" port)
162	(set! first_block (cascade:write-source port packages))
163	(if (null? first_block)
164	    (error "You must include a source element in your schematic!")
165	    )
166
167	;; write the components
168	(display "\n# Cascaded system\n" port)
169	(cascade:follow-cascade port first_block)
170
171	;; write the footer
172	(newline port)
173	(display "# End of netlist created by gEDA/gnetlist\n\n" port)
174
175	;; close netlist
176	(close-output-port port)
177
178	)
179
180      (display "done\n")
181      )
182   )
183
184