CompileDES 3.14
Executable-Code Generation from Synchronised libFAUDES Automata
cgp_kinetis.cpp
Go to the documentation of this file.
1
3/*
4 FAU Discrete Event Systems Library (libFAUDES)
5
6 Copyright (C) 2016 Thomas Moor
7
8*/
9
10// my includes
11#include "cgp_kinetis.h"
12
13
14/*
15******************************************************************
16******************************************************************
17******************************************************************
18
19KinetisCodeGenerator implementation --- class mainenance
20
21******************************************************************
22******************************************************************
23******************************************************************
24*/
25
26
27// Register derived class
29
30
31// KinetisCodeGenerator(void)
33 FD_DCG("KinetisCodeGenerator(" << this << ")::KinetisCodeGenerator()");
34}
35
36// KinetisCodeGenerator(void)
38 FD_DCG("KinetisCodeGenerator(" << this << ")::~KinetisCodeGenerator()");
39}
40
41
42// clear
44 FD_DCG("KinetisCodeGenerator::Clear()");
45 // call base
47 // my flavor of defaults
48 mPrefix="fcg_";
49 mWordType="uint32_t";
50 mWordSize=32;
51 mIntegerType="int16_t";
52 mIntegerSize=16;
53 // my config parameter
56}
57
58//DoReadTargetConfiguration(rTr)
60 FD_DCG("KinetisCodeGenerator::DoReadTargetConfiguration()");
61 // base
63 // k20 options
64 Token token;
65 if(rTr.ExistsBegin("KinetisOutputControl")) {
66 rTr.ReadBegin("KinetisOutputControl",token);
67 mKinetisOutputControl= token.AttributeStringValue("val");
68 rTr.ReadEnd("KinetisOutputControl");
69 }
70 if(rTr.ExistsBegin("KinetisInputControl")) {
71 rTr.ReadBegin("KinetisInputControl",token);
72 mKinetisInputControl= token.AttributeStringValue("val");
73 rTr.ReadEnd("KinetisInputControl");
74 }
75}
76
77//DoWriteTargetConfiguration(rTw)
79 FD_DCG("KinetisCodeGenerator::DoWriteTargetConfiguration()");
80 // base
82 // k20 opts
83 Token token;
84 token.SetEmpty("KinetisOutputControl");
85 token.InsAttributeString("val",mKinetisOutputControl);
86 rTw.Write(token);
87 token.SetEmpty("KinetisInputControl");
88 token.InsAttributeString("val",mKinetisInputControl);
89 rTw.Write(token);
90}
91
92
93/*
94******************************************************************
95******************************************************************
96******************************************************************
97
98KinetisCodeGenerator implementation --- code organisation
99
100******************************************************************
101******************************************************************
102******************************************************************
103*/
104
105
106// DoCompile()
108 FD_DCG("KinetisCodeGenerator(" << this << ")::DoCompile()");
109 // call base
111}
112
113// DoGenerate()
115 FD_DCG("KinetisCodeGenerator(" << this << ")::DoGenerate()");
116 // cut and paste from base
117 mBitarrays.clear();
118 // say hello
119 Comment("************************************************");
120 Comment("CodeGenerator: Target Kinetis K20 uController ");
121 Comment("************************************************");
122 LineFeed(1);
123 Comment(std::string("CompileDES ") + VersionString());
124 Comment(std::string("Configuration: ") + Name());
125 LineFeed(2+1);
126 // base class for std snippets
129 // cyclic function
130 LineFeed(2);
131 Output() << "void " << mPrefix <<"cyclic(void) { ";
132 LineFeed();
135 Output() << "}; /* end function " << mPrefix <<"cyclic() */";
136 LineFeed();
137 LineFeed(2+1);
138 // extra from ecCodeGenerator: provide timer decrement interface to host application
140 // extra from KinetisCodeGenerator: initialise ports
142 // snippets
144 // done
145 Comment("************************************************");
146 Comment("CodeGenerator: Generated Code Ends Here ");
147 Comment("************************************************");
148}
149
150
151// support: parse "PORTxn" to "xn"
152std::string KinetisCodeGenerator::ParseLiteralPort(const std::string& lport) {
153 std::string res;
154 if((lport.size()<6) || (lport.size()>7)) return res;
155 if(lport.substr(0,4)!="PORT") return res;
156 char port = lport[4];
157 if((port < 'A') || (port > 'E')) return res;
158 int pin = lport[5] - '0';
159 if((pin <0) || (pin > 9)) return res;
160 if(lport.size()>6) {
161 int pin2 = lport[6] - '0';
162 if((pin2 <0) || (pin2 > 9)) return res;
163 pin=10*pin+pin2;
164 }
165 if(pin >=32) return res;
166 res.append(1,port);
167 res.append(1,pin);
168 return res;
169}
170
171
172// code blocks: initialise ports
174 // figure output pins on ports A,B,C,D,E
175 bool outexists= false;
176 std::map<char, std::set< int > > outbits;
178 for(;ait!=ActionAddressesEnd();++ait) {
179 // strict syntax check for set/clr actions, otherwise we cannot handle bit operations
180 if(!ait->second.mSetClr) continue;
181 std::string portpin=ParseLiteralPort(ait->second.mAddress);
182 if(portpin=="")
183 FCG_ERR("KinetisCodeGenerator::InitialisePorts(): unkown output port [" << ait->second.mAddress << "]");
184 outbits[portpin[0]].insert(portpin[1]);
185 outexists= true;
186 }
187 // figure input pins on ports A,B,C,D,E
188 bool inpexists= false;
189 std::map<char, std::set< int > > inpbits;
191 for(;lit!=LinesEnd();++lit) {
192 // weak syntax check for inputs, interpret as boolean expression if its not a port bit
193 std::string portpin=ParseLiteralPort(lit->second.mAddress);
194 if(portpin=="") continue;
195 inpbits[portpin[0]].insert(portpin[1]);
196 inpexists= true;
197 }
198 // skip this section
199 if(mKinetisOutputControl=="") outexists=false;
200 if(mKinetisInputControl=="") inpexists=false;
201 if( !(outexists || inpexists) ) return;
202 // configure ports
203 Comment("************************************************");
204 Comment("* initialise input/output pins *");
205 Comment("************************************************");
206 Output() << "void " << mPrefix <<"initpio(void) { ";
207 LineFeed();
208 IndentInc();
209 if(outexists) {
210 std::map<char, std::set< int > >::iterator oit = outbits.begin();
211 for(;oit!= outbits.end(); ++oit) {
212 std::set< int >::iterator bit= oit->second.begin();
213 for(;bit!=oit->second.end();++bit) {
214 Output() << "PORT" << oit->first << "_PCR" << *bit << " = " << mKinetisOutputControl << " | PORT_PCR_MUX(1);";
215 LineFeed();
216 }
217 word_t msk=0;
218 bit= oit->second.begin();
219 for(;bit!=oit->second.end();++bit)
220 msk |= (1L << *bit);
221 if(msk!=0) {
222 Output() << "GPIO" << oit->first << "_PDDR |= " << WordConstant(msk) << ";";
223 LineFeed();
224 }
225 }
226 }
227 if(inpexists) {
228 std::map<char, std::set< int > >::iterator iit = inpbits.begin();
229 for(;iit!= inpbits.end(); ++iit) {
230 std::set< int >::iterator bit= iit->second.begin();
231 for(;bit!=iit->second.end();++bit) {
232 Output() << "PORT" << iit->first << "_PCR" << *bit << " = " << mKinetisInputControl << " | PORT_PCR_MUX(1);";
233 LineFeed();
234 }
235 }
236 }
237 IndentDec();
238 Output() << "};";
239 LineFeed(1+2);
240}
241
242// output actions
243void KinetisCodeGenerator::RunActionSet(const std::string& address) {
244 std::string portpin=ParseLiteralPort(address);
245 if(portpin=="")
246 FCG_ERR("KinetisCodeGenerator::RunAction(): unkown output port [" << address << "]");
247 Output() << "GPIO" << portpin[0] << "_PSOR = ( 1L << " << int(portpin[1]) << " );";
248 LineFeed();
249}
250void KinetisCodeGenerator::RunActionClr(const std::string& address) {
251 std::string portpin=ParseLiteralPort(address);
252 if(portpin=="")
253 FCG_ERR("KinetisCodeGenerator::RunAction(): unkown output port [" << address << "]");
254 Output() << "GPIO" << portpin[0] << "_PCOR = ( 1L << " << int(portpin[1]) << " );";
255 LineFeed();
256}
257
258// read inputs
259KinetisCodeGenerator::AX KinetisCodeGenerator::ReadInputLine(const std::string& address) {
260 // if it is a port bit, convert to boolean expression
261 std::string portpin=ParseLiteralPort(address);
262 if(portpin!="") {
263 std::string res = "( GPIO" + std::string(1,portpin[0]) + "_PDIR & ( 1L << " + ToStringInteger(portpin[1]) + " ) )";
264 return AX(res);
265 }
266 // fallback to boolean expression
267 std::string res = address;
268 return AX(res);
269}
270
271
272
273
274
275
#define FAUDES_REGISTERCODEGENERATOR(ftype, ctype)
Class registration macro.
Code-generator for Freescale Kinetis microcontrollers.
virtual void LineFeed(int lines=1)
LineFeed (convenience support for derived classes)
virtual const std::string & Name(void) const
Get objects's name (reimplementing base faudes::Type)
LineIterator LinesEnd()
Access to line records by iterator.
std::map< std::string, ActionAddress >::iterator ActionAddressIterator
Access to action record by iterator.
virtual void IndentInc()
Indentation (convenience support for derived classes)
int mWordSize
compressed boolean capacity of target type word
LineIterator LinesBegin()
Access to line records by iterator.
int mIntegerSize
compressed boolean capacity of target type integer
virtual std::ostream & Output(void)
Output stream.
std::map< std::string, LineAddress >::iterator LineIterator
Access to line records by iterator.
static std::string VersionString(void)
Version (refers to macro COMPILEDES_VERSION, defined in cgp_codegenerator.h)
virtual void IndentDec()
Indentation (convenience support for derived classes)
ActionAddressIterator ActionAddressesEnd()
Access to action addresses by iterator.
ActionAddressIterator ActionAddressesBegin()
Access to action addresses by iterator.
unsigned long word_t
Code-generator internal data type of target words.
Abstract expression; see also Absstract_Addresses.
virtual void DoGenerateDeclarations(void)
cut-and-paste template for code snippet assembly
virtual void DoGenerateResetCode(void)
cut-and-paste template for code snippet assembly
virtual void LiteralAppend(void)
Cosmetic: append literally from configuration.
std::map< std::string, bitarray_rec > mBitarrays
Record of all declared bit-arrays.
std::string mIntegerType
target data type for integer
virtual void DoGenerateCyclicCode(void)
cut-and-paste template for code snippet assembly
std::string mWordType
target data type for word
virtual void LiteralPrepend(void)
Cosmetic: prepend literally from configuration data.
std::string mPrefix
universal prefix (pseudo name space)
Implementation of code primitives by generic C-code.
void DoCompile(void)
add my preferences to DoCompile
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
virtual void Comment(const std::string &text)
Target comments (see EmbeddedcCodeGenerator for consistent reimplementation pattern)
virtual void DoReadTargetConfiguration(TokenReader &rTr)
File i/o.
virtual void Clear(void)
Clear all data.
virtual void DecrementTimers(void)
re-implemented/additional code blocks
Target Freescale Kinetis micro-controllers (K20)
std::string mKinetisInputControl
Kinetis code options.
virtual void Clear(void)
std::string mKinetisOutputControl
Kinetis code options.
virtual ~KinetisCodeGenerator(void)
virtual void DoReadTargetConfiguration(TokenReader &rTr)
reimplemented/additional code blocks
virtual void InitialisePorts(void)
reimplemented/additional code blocks
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
void DoCompile(void)
add my preferences to DoCompile
void DoGenerate(void)
protected version of generate