CompileDES  3.12
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.
virtual void DoGenerateCyclicCode(void)
cut-and-paste template for code snippet assembly
Abstract expression; see also Absstract_Addresses.
LineIterator LinesEnd()
Access to line records by iterator.
virtual std::ostream & Output(void)
Output stream.
void DoGenerate(void)
protected version of generate
virtual void DoGenerateResetCode(void)
cut-and-paste template for code snippet assembly
std::string mKinetisInputControl
Kinetis code options.
Definition: cgp_kinetis.h:144
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
Definition: cgp_kinetis.cpp:78
int mWordSize
compressed boolean capacity of target type word
virtual ~KinetisCodeGenerator(void)
Definition: cgp_kinetis.cpp:37
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
virtual void LineFeed(int lines=1)
LineFeed (convenience support for derived classes)
Implementation of code primitives by generic C-code.
Definition: cgp_embeddedc.h:71
std::string mKinetisOutputControl
Kinetis code options.
Definition: cgp_kinetis.h:141
virtual void DecrementTimers(void)
re-implemented/additional code blocks
virtual void Clear(void)
Clear all data.
virtual void IndentInc()
Indentation (convenience support for derived classes)
virtual void DoGenerateDeclarations(void)
cut-and-paste template for code snippet assembly
void DoCompile(void)
add my preferences to DoCompile
static std::string VersionString(void)
Version (refers to macro COMPILEDES_VERSION, defined in cgp_codegenerator.h)
std::string mIntegerType
target data type for integer
virtual void LiteralAppend(void)
Cosmetic: append literally from configuration.
virtual void DoReadTargetConfiguration(TokenReader &rTr)
File i/o.
virtual const std::string & Name(void) const
Get objects&#39;s name (reimplementing base faudes::Type)
int mIntegerSize
compressed boolean capacity of target type integer
std::map< std::string, ActionAddress >::iterator ActionAddressIterator
Access to action record by iterator.
std::string mWordType
target data type for word
virtual void Clear(void)
Definition: cgp_kinetis.cpp:43
unsigned long word_t
Code-generator internal data type of target words.
ActionAddressIterator ActionAddressesBegin()
Access to action addresses by iterator.
Code-generator for Freescale Kinetis microcontrollers.
ActionAddressIterator ActionAddressesEnd()
Access to action addresses by iterator.
std::string mPrefix
universal prefix (pseudo name space)
virtual void DoReadTargetConfiguration(TokenReader &rTr)
reimplemented/additional code blocks
Definition: cgp_kinetis.cpp:59
virtual void IndentDec()
Indentation (convenience support for derived classes)
std::map< std::string, LineAddress >::iterator LineIterator
Access to line records by iterator.
void DoCompile(void)
add my preferences to DoCompile
std::map< std::string, bitarray_rec > mBitarrays
Record of all declared bit-arrays.
Target Freescale Kinetis micro-controllers (K20)
Definition: cgp_kinetis.h:107
virtual void InitialisePorts(void)
reimplemented/additional code blocks
LineIterator LinesBegin()
Access to line records by iterator.
virtual void LiteralPrepend(void)
Cosmetic: prepend literally from configuration data.
virtual void Comment(const std::string &text)
Target comments (see EmbeddedcCodeGenerator for consistent reimplementation pattern) ...