CompileDES  3.09
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 
19 KinetisCodeGenerator 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 
98 KinetisCodeGenerator 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
127  LiteralPrepend();
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
139  DecrementTimers();
140  // extra from KinetisCodeGenerator: initialise ports
141  InitialisePorts();
142  // snippets
143  LiteralAppend();
144  // done
145  Comment("************************************************");
146  Comment("CodeGenerator: Generated Code Ends Here ");
147  Comment("************************************************");
148 }
149 
150 
151 // support: parse "PORTxn" to "xn"
152 std::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;
190  LineIterator lit=LinesBegin();
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
243 void 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 }
250 void 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
259 KinetisCodeGenerator::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