CompileDES  3.13
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 
#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)
LineIterator LinesEnd()
Access to line records by iterator.
std::map< std::string, LineAddress >::iterator LineIterator
Access to line records 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.
static std::string VersionString(void)
Version (refers to macro COMPILEDES_VERSION, defined in cgp_codegenerator.h)
virtual const std::string & Name(void) const
Get objects's name (reimplementing base faudes::Type)
virtual void IndentDec()
Indentation (convenience support for derived classes)
ActionAddressIterator ActionAddressesEnd()
Access to action addresses by iterator.
std::map< std::string, ActionAddress >::iterator ActionAddressIterator
Access to action record 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.
Definition: cgp_embeddedc.h:71
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)
Definition: cgp_kinetis.h:107
std::string mKinetisInputControl
Kinetis code options.
Definition: cgp_kinetis.h:144
virtual void Clear(void)
Definition: cgp_kinetis.cpp:43
std::string mKinetisOutputControl
Kinetis code options.
Definition: cgp_kinetis.h:141
virtual ~KinetisCodeGenerator(void)
Definition: cgp_kinetis.cpp:37
virtual void DoReadTargetConfiguration(TokenReader &rTr)
reimplemented/additional code blocks
Definition: cgp_kinetis.cpp:59
virtual void InitialisePorts(void)
reimplemented/additional code blocks
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
Definition: cgp_kinetis.cpp:78
void DoCompile(void)
add my preferences to DoCompile
void DoGenerate(void)
protected version of generate