1 #Copyright (C) 2012 jaseg <s@jaseg.de>
3 #This program is free software; you can redistribute it and/or
4 #modify it under the terms of the GNU General Public License
5 #version 3 as published by the Free Software Foundation.
10 from mako
.template
import Template
17 /* AUTOGENERATED CODE FOLLOWS!
18 * This file contains the code generated from the module templates as well as
19 * some glue logic. It is generated following the device config by "generate.py"
20 * in this very folder. Please refrain from modifying it, modify the templates
21 * and generation logic instead.
24 * Device name: ${devname},
26 * Build version: ${version}, build date: ${builddate}
36 #include <avr/pgmspace.h>
38 comm_callback comm_callbacks[] = {
39 % for (callback, id) in callbacks:
44 const uint16_t num_callbacks = ${len(callbacks)};
47 % for initfunc in init_functions:
53 % for loopfunc in loop_functions:
58 void callback_get_descriptor_auto(uint16_t alen, uint8_t* argbuf){
60 uart_putc(auto_config_descriptor_length >> 8);
61 uart_putc(auto_config_descriptor_length & 0xFF);
62 for(const char* i=auto_config_descriptor; i < auto_config_descriptor+auto_config_descriptor_length; i++){
63 uart_putc(pgm_read_byte(i));
65 //FIXME add crc generation
72 accessor_callbacks
= """
73 void callback_set_${name}(uint16_t alen, uint8_t* argbuf){
74 if(! ${bsize} == alen){
75 //FIXME error handling
78 memcpy(&${name}, argbuf, ${bsize});
81 void callback_get_${name}(uint16_t alen, uint8_t* argbuf){
83 //FIXME error handling
86 uart_putc(${bsize}>>8);
87 uart_putc(${bsize}&0xFF);
88 for(char* i=((char*)&${name}); i<((char*)&${name})+${bsize}; i++){
91 //FIXME add crc generation
98 config_c_template
= """\
99 /* AUTOGENERATED CODE AHEAD!
100 * This file contains the device configuration in lzma-ed json-format. It is
101 * autogenerated by "generate.py" (which should be found in this folder).
104 unsigned int auto_config_descriptor_length = ${desc_len};
105 const char auto_config_descriptor[] PROGMEM = {${desc}};
108 def generate(dev
, devicename
, builddate
):
109 members
= dev
["members"]
112 dev
["builddate"] = str(builddate
)
113 autocode
= Template(autocode_stub
).render_unicode(devname
=devicename
, version
=dev
["version"], builddate
=builddate
)
118 def register_callback(name
):
120 callbacks
.append((name
, current_id
))
125 register_callback("callback_get_descriptor_auto")
127 def generate_accessors(name
, ctype
, aval
=1):
128 return Template(accessor_callbacks
).render_unicode(name
=name
, bsize
="({}*sizeof({}))".format(aval
, ctype
));
130 for mname
, member
in members
.items():
131 mfile
= member
["type"]
132 mtype
= mfile
.replace('-', '_')
133 typepath
= os
.path
.join(os
.path
.dirname(__file__
), mfile
+ ".c.tp")
136 fun
= "init_{}_{}".format(mtype
, seqnum
)
137 init_functions
.append(fun
)
140 fun
= "loop_{}_{}".format(mtype
, seqnum
)
141 loop_functions
.append(fun
)
148 def modulevar(name
, ctype
=None, fmt
=None, array
=False):
149 varname
= "modvar_{}_{}_{}".format(mtype
, seqnum
, name
)
150 if fmt
is not None and ctype
is not None:
155 accessors
+= generate_accessors(varname
, ctype
, aval
)
157 accid
= register_callback("callback_get_" + varname
)
158 register_callback("callback_set_" + varname
)
160 "size": struct
.calcsize(fmt
),
165 array_component
= "[]"
167 array_component
= "[{}]".format(array
)
168 return "{} {}{}".format(ctype
, varname
, array_component
)
172 def module_callback(name
, argformat
="", retformat
=""):
173 cbname
= 'callback_{}_{}_{}'.format(mtype
, seqnum
, name
)
174 cbid
= register_callback(cbname
)
175 func
= { 'id': cbid
}
176 if argformat
is not '':
177 func
['args'] = argformat
178 if retformat
is not '':
179 func
['returns'] = retformat
180 functions
[name
] = func
184 tp
= Template(filename
=typepath
)
185 autocode
+= tp
.render_unicode(
186 init_function
=init_function
,
187 loop_function
=loop_function
,
189 module_callback
=module_callback
,
191 autocode
+= accessors
194 member
['functions'] = functions
196 member
['properties'] = properties
198 autocode
+= Template(autoglue
).render_unicode(init_functions
=init_functions
, loop_functions
=loop_functions
, callbacks
=callbacks
)
199 with
open(os
.path
.join(os
.path
.dirname(__file__
), 'autocode.c'), 'w') as f
:
201 config
= pylzma
.compress(json
.JSONEncoder(separators
=(',',':')).encode(dev
))
202 with
open(os
.path
.join(os
.path
.dirname(__file__
), 'config.c'), 'w') as f
:
203 f
.write(Template(config_c_template
).render_unicode(desc_len
=len(config
), desc
=','.join(map(str, config
))))
204 subprocess
.call(['/usr/bin/env', 'make', '-C', os
.path
.dirname(__file__
), 'clean', 'all'])
205 return dev
, os
.path
.join(os
.path
.dirname(__file__
), 'main.hex')
208 make_env
= os
.environ
.copy()
209 make_env
["PORT"] = args
.port
210 subprocess
.call(["/usr/bin/env", "make", "-C", os
.path
.dirname(__file__
), "program"], env
=make_env
)