HWA
Bare metal programming with style
hd44780.h
Go to the documentation of this file.
1 
2 /* This file is part of the HWA project.
3  * Copyright (c) 2018 Christophe Duparquet.
4  * All rights reserved. Read LICENSE.TXT for details.
5  */
6 
66 #define hw_class__hd44780
67 
68 
74 #define HW_HD44780(...) _HW_HD44780_(__VA_ARGS__,,,,,,,,,,)
75 #define _HW_HD44780_(k,...) HW_BW(_HW_HD44780_1,lines,k)(k,__VA_ARGS__)
76 #define _HW_HD44780_10(k,...) _HW_HD44780_E(k,__VA_ARGS__)
77 #define _HW_HD44780_11(k0,l,k,...) HW_BW(_HW_HD44780_2,cols,k)(l,k,__VA_ARGS__)
78 #define _HW_HD44780_20(l,k,...) _HW_HD44780_E(k,__VA_ARGS__)
79 #define _HW_HD44780_21(l,k0,c,k,...) HW_BW(_HW_HD44780_3,e,k)(l,c,k,__VA_ARGS__)
80 #define _HW_HD44780_30(l,c,k,...) _HW_HD44780_E(k,__VA_ARGS__)
81 #define _HW_HD44780_31(l,c,k,...) _HW_HD44780_32(l,c,HW_AD(__VA_ARGS__))
82 #define _HW_HD44780_32(...) _HW_HD44780_33(__VA_ARGS__)
83 #define _HW_HD44780_33(l,c,e,...) _HW_B(_HW_HD44780_33,HW_A0 e)(l,c,e,__VA_ARGS__)
84 #define _HW_HD44780_331(l,c,e,...) ,HW_HD44780(...),(HW_HD44780(...): HW_A2 e)
85 #define _HW_HD44780_330(l,c,e,k,...) HW_BW(_HW_HD44780_4,rs,k)(l,c,e,k,__VA_ARGS__)
86 #define _HW_HD44780_40(l,c,e,k,...) _HW_HD44780_E(k,__VA_ARGS__)
87 #define _HW_HD44780_41(l,c,e,k,...) _HW_HD44780_42(l,c,e,HW_AD(__VA_ARGS__))
88 #define _HW_HD44780_42(...) _HW_HD44780_43(__VA_ARGS__)
89 #define _HW_HD44780_43(l,c,e,s,...) _HW_B(_HW_HD44780_43,HW_A0 s)(l,c,e,s,__VA_ARGS__)
90 #define _HW_HD44780_431(l,c,e,s,...) ,HW_HD44780(...),(HW_HD44780(...): HW_A2 s)
91 #define _HW_HD44780_430(l,c,e,s,k,...) HW_BW(_HW_HD44780_5,rw,k)(l,c,e,s,k,__VA_ARGS__)
92 #define _HW_HD44780_50(l,c,e,s,k,...) _HW_HD44780_E(k,__VA_ARGS__)
93 #define _HW_HD44780_51(l,c,e,s,k,...) _HW_HD44780_52(l,c,e,s,HW_AD(__VA_ARGS__))
94 #define _HW_HD44780_52(...) _HW_HD44780_53(__VA_ARGS__)
95 #define _HW_HD44780_53(l,c,e,s,w,...) _HW_B(_HW_HD44780_53,HW_A0 w)(l,c,e,s,w,__VA_ARGS__)
96 #define _HW_HD44780_531(l,c,e,s,w,...) ,HW_HD44780(...),(HW_HD44780(...): HW_A2 w)
97 #define _HW_HD44780_530(l,c,e,s,w,k,...) HW_BW(_HW_HD44780_6,data,k)(l,c,e,s,w,k,__VA_ARGS__)
98 #define _HW_HD44780_60(l,c,e,s,w,k,...) _HW_HD44780_E(k,__VA_ARGS__)
99 #define _HW_HD44780_61(l,c,e,s,w,k,...) _HW_HD44780_62(l,c,e,s,w,HW_AD(__VA_ARGS__))
100 #define _HW_HD44780_62(...) _HW_HD44780_63(__VA_ARGS__)
101 #define _HW_HD44780_63(l,c,e,s,w,d,...) _HW_B(_HW_HD44780_63,HW_A0 d)(l,c,e,s,w,d,__VA_ARGS__)
102 #define _HW_HD44780_631(l,c,e,s,w,d,...) ,HW_HD44780(...),(HW_HD44780(...): HW_A2 d)
103 #define _HW_HD44780_630(l,c,e,s,w,d,g,...) HW_B(_HW_HD44780_7,g)(l,c,e,s,w,d,g,__VA_ARGS__)
104 #define _HW_HD44780_70(x,...) HW_E(HW_EM_G(x))
105 
106 /* Verify that e is of class _io8574
107  */
108 #define _HW_HD44780_71(l,c,e,s,w,d,...) _HW_HD44780_72(HW_A0_A1 e, HW_A2 d, l,c,e,s,w,d)
109 #define _HW_HD44780_72(...) _HW_HD44780_73(__VA_ARGS__)
110 #define _HW_HD44780_73(ec,eo,df,...) HW_BW(_HW_HD44780_73,_io8574,ec)(ec,eo,HW_A0 df,__VA_ARGS__)
111 #define _HW_HD44780_730(ec,...) ,HW_HD44780(...),HW_HD44780(...): class ec for "e" is not supported
112 #define _HW_HD44780_731(ec,eo,...) _hd44780,hd44780_##eo,(ec,__VA_ARGS__)
113 
114 #define _HW_HD44780_E(k,...) \
115  ,HW_HD44780(...),(HW_EM_SY("HW_HD44780(lines,..., cols,..., e,..., rs,..., rw,..., data,...)"))
116 
117 #define _hw_is__io8574__io8574 , 1
118 
119 
125 #define HW_DECLARE__hd44780 , _hw_dchd44780
126 
127 #define _hw_dchd44780(o,ec,dw,l,c,e,rs,rw,d,...) HW_BV(_hw_dchd44780,declare_,HW_A0(__VA_ARGS__),o,ec,dw)
128 #define _hw_dchd447800(v,...) HW_E(HW_EM_OVL(v,(weak)))
129 #define _hw_dchd447801(weak,o,ec,dw) \
130  void weak _hw_##o##ec##_##dw##__pulse ( ); \
131  void weak _hw_##o##ec##_##dw##__write ( uint8_t, uint8_t ); \
132  uint8_t weak _hw_##o##ec##_##dw##__read ( uint8_t ); \
133  uint8_t weak _hw_##o##__wait ( ); \
134  void weak _hw_##o##__command ( uint8_t ); \
135  void weak _hw_##o##__data ( uint8_t ); \
136  void weak _hw_##o##_clear_cgram ( ); \
137  void weak _hw_##o##_cls ( ); \
138  void weak _hw_##o##ec##_##dw##_init ( ); \
139  void weak _hw_##o##_gotoxy ( uint8_t, uint8_t ); \
140  void weak _hw_##o##_newline( uint8_t ); \
141  void weak _hw_##o##_home ( ); \
142  void weak _hw_##o##_putchar( unsigned char ) /* require a ; */
143 
144 
150 #define HW_IMPLEMENT__hd44780 , _hw_dfhd44780
151 
152 #define _hw_dfhd44780(o,ec,dw,...) \
153  _hw_dfhd44780_io8574_4__pulse(o,__VA_ARGS__) \
154  _hw_dfhd44780_io8574_4__write(o,__VA_ARGS__) \
155  _hw_dfhd44780_io8574_4__read(o,__VA_ARGS__) \
156  _hw_dfhd44780__wait(o,__VA_ARGS__) \
157  _hw_dfhd44780__command(o,__VA_ARGS__) \
158  _hw_dfhd44780__data(o,__VA_ARGS__) \
159  _hw_dfhd44780_cls(o,__VA_ARGS__) \
160  _hw_dfhd44780_io8574_4_init(o,__VA_ARGS__) \
161  _hw_dfhd44780_gotoxy(o,__VA_ARGS__) \
162  _hw_dfhd44780_newline(o,__VA_ARGS__) \
163  _hw_dfhd44780_home(o,__VA_ARGS__) \
164  _hw_dfhd44780_putchar(o,__VA_ARGS__) \
165  extern uint8_t hw_foo()
166 
167 /* FIXME: 'hw(pulse,e)' could spare a few bytes by not updating the data cache
168  * of PCF.
169  */
170 #define _hw_dfhd44780_io8574_4__pulse(o,lines,cols,e,...) \
171  void _hw_##o##__pulse ( ) { \
172  hw(write, e, 1); \
173  hw(write, e, 0); \
174  }
175 
176 /* #define _hwa_dfhd44780_io8574_4__pulse(o,lines,cols,e,...) \ */
177 /* void _hwa_##o##__pulse ( ) { \ */
178 /* hwa(write, e, 1); \ */
179 /* _hwa( commit, (e,port) ); \ */
180 /* hwa(write, e, 0); \ */
181 /* _hwa( commit, (e,port) ); \ */
182 /* } */
183 
184 /* Access for writing:
185  * * RS and RW must be stable >40 ns before rising of E
186  * * E must be stable high for >230 ns
187  * * D must be stable >80 ns before falling of E and >10 ns after falling of E
188  * * period of E must be >500 ns
189  */
190 #define _hw_dfhd44780_io8574_4__write(o,lines,cols,e,rs,rw,d,...) \
191  void _hw_##o##__write ( uint8_t data, uint8_t r ) { \
192  _hw_##o##__wait(); \
193  hw( writea, rs, r ); \
194  hw( writea, rw, 0 ); \
195  hw( writea, d, data>>4 ); \
196  hw( commit, (e,port) ); \
197  _hw_##o##__pulse(); \
198  hw( write, d, data&15 ); \
199  _hw_##o##__pulse(); \
200  }
201 
202 /* #define _hw_dfhd44780_io8574_4__write(o,lines,cols,e,rs,rw,d,...) \ */
203 /* void _hw_##o##__write ( uint8_t data, uint8_t r ) { \ */
204 /* _hw_##o##__wait(); \ */
205 /* _hwa( begin, (rs,port) ); \ */
206 /* _hwa( begin, (rw,port) ); \ */
207 /* _hwa( begin, (d,port) ); \ */
208 /* _hwa( begin, (e,port) ); \ */
209 /* _hwa( write, rs, r ); \ */
210 /* _hwa( write, rw, 0 ); \ */
211 /* _hwa( commit, (rs,port) ); \ */
212 /* _hwa( commit, (rw,port) ); \ */
213 /* _hwa( write, e, 1 ); \ */
214 /* _hwa( commit, (e,port) ); \ */
215 /* _hwa( write, d, data>>4 ); \ */
216 /* _hwa( commit, (d,port) ); \ */
217 /* _hwa( write, e, 0 ); \ */
218 /* _hwa( commit, (e,port) ); \ */
219 /* _hwa( write, e, 1 ); \ */
220 /* _hwa( commit, (e,port) ); \ */
221 /* _hwa( write, d, data&0x0F ); \ */
222 /* _hwa( commit, (d,port) ); \ */
223 /* _hwa( write, e, 0 ); \ */
224 /* _hwa( commit, (e,port) ); \ */
225 /* _hwa( write, d, 15 ); \ */
226 /* _hwa( commit, (d,port) ); \ */
227 /* } */
228 
229 #define _hw_dfhd44780_io8574_4__read(o,lines,cols,e,rs,rw,d,...) \
230  uint8_t _hw_##o##__read ( uint8_t r ) { \
231  hw( writea, rs, r ); \
232  hw( writea, rw, 1 ); \
233  hw( writea, d, 0x0F ); \
234  hw( commit, (e,port) ); \
235  _hw( write, e, 1 ); \
236  uint8_t hi = _hw( read, d ); \
237  _hw( write, e, 0 ); \
238  _hw( write, e, 1 ); \
239  hw_waste_cycles( 100e-6 * HW_SYSHZ );/*FIXME: can't have it working without this delay?*/ \
240  uint8_t lo = _hw( read, d ); \
241  _hw( write, e, 0 ); \
242  return (hi<<4)|lo ; \
243  }
244 
245 /* #define _hw_dfhd44780_io8574_4__read(o,lines,cols,e,rs,rw,d,...) \ */
246 /* uint8_t _hw_##o##__read ( uint8_t r ) { \ */
247 /* _hwa( begin, (rs,port) ); \ */
248 /* _hwa( begin, (rw,port) ); \ */
249 /* _hwa( begin, (d,port) ); \ */
250 /* _hwa( begin, (e,port) ); \ */
251 /* _hwa( write, rs, 1 ); \ */
252 /* _hwa( write, rw, 1 ); \ */
253 /* _hwa( commit, (rs,port) ); \ */
254 /* _hwa( commit, (rw,port) ); \ */
255 /* _hwa( write, e, 1 ); \ */
256 /* _hwa( commit, (e,port) ); \ */
257 /* uint8_t hi = _hw( read, d ); \ */
258 /* _hwa( write, e, 0 ); \ */
259 /* _hwa( commit, (e,port) ); \ */
260 /* _hwa( write, e, 1 ); \ */
261 /* _hwa( commit, (e,port) ); \ */
262 /* hw_waste_cycles( 100e-6 * HW_SYSHZ );/\*FIXME: can't have it working without this delay?*\/ \ */
263 /* uint8_t lo = _hw( read, d ); \ */
264 /* _hwa( write, e, 0 ); \ */
265 /* _hwa( commit, (e,port) ); \ */
266 /* return (hi<<4)|lo ; \ */
267 /* } */
268 
269 
270 #define _hw_dfhd44780__wait(o,lines,cols,e,rs,rw,d,...) \
271  uint8_t _hw_##o##__wait ( ) { \
272  uint8_t r0 ; \
273  while( (r0 = _hw_##o##__read(0)) & 0x80 ) /* Bit 7 of register #0: busy */ \
274  hw_waste_cycles( 10e-6 * HW_SYSHZ ); \
275  return r0; /* Return counter */ \
276  }
277 
278 #define _hw_dfhd44780__command(o,lines,cols,e,rs,rw,d,...) \
279  void _hw_##o##__command ( uint8_t c ) { \
280  _hw_##o##__write(c,0); \
281  }
282 
283 #define _hw_dfhd44780__data(o,lines,cols,e,rs,rw,d,...) \
284  void _hw_##o##__data ( uint8_t data ) { \
285  _hw_##o##__write(data,1); \
286  }
287 
288 #define _hw_dfhd44780_cls(o,lines,cols,e,rs,rw,d,...) \
289  void _hw_##o##_cls ( ) { \
290  _hw_##o##__command(1); \
291  }
292 
293 #define _hw_dfhd44780_io8574_4_init(o,lines,cols,e,rs,rw,d,...) HW_EOL(__VA_ARGS__) \
294  void _hw_##o##_init ( ) { \
295  if ( lines < 1 || lines > 2 ) { \
296  HWA_E(HW_EM(parameter "lines" must be 1 or 2)); \
297  return ; \
298  } \
299  uint8_t bits = 4 ; \
300  uint16_t font = 58 ; \
301  hw( writea, e, 0 ); \
302  hw( writea, rs, 0 ); \
303  hw( writea, rw, 0 ); \
304  hw( writea, d, 0 ); \
305  hw_waste_cycles( 0.015 * HW_SYSHZ ); \
306  hw( write, d, 3 ); /* initial write 8bit */ \
307  _hw_##o##__pulse(); \
308  hw_waste_cycles( 0.0041 * HW_SYSHZ ); \
309  _hw_##o##__pulse(); /* repeat last command */ \
310  hw_waste_cycles( 100e-6 * HW_SYSHZ ); \
311  _hw_##o##__pulse(); /* repeat last command */ \
312  if ( bits == 4 ) \
313  hw( write, d, 2 ); \
314  _hw_##o##__pulse(); \
315  uint8_t val = (bits==4)*0x20 + (lines==2)*0x08 + (font==58)*0x04; \
316  _hw_##o##__command( val ); \
317  _hw_##o##__command( 0x0C ); /* Display on, no cursor, no blink */ \
318  _hw_##o##_cls( ); \
319  }
320 
321  /* _hw_##o##__command( 0x08 ); /\* Display off, no cursor, no blink *\/ \ */
322  /* _hw_##o##__command( 0x06 ); /\* Entry mode: inc, no shift *\/ \ */
323  /* _hw_##o##__command( 0x0C ); /\* Display on, no cursor, no blink *\/ \ */
324 
325 /* #define _hw_dfhd44780_io8574_4_init(o,lines,cols,e,rs,rw,d,...) \ */
326 /* void _hw_##o##_init ( ) { \ */
327 /* _hwa( begin, (rs,port) ); \ */
328 /* _hwa( begin, (rw,port) ); \ */
329 /* _hwa( begin, (d,port) ); \ */
330 /* _hwa( begin, (e,port) ); \ */
331 /* _hwa( write, rs, r ); \ */
332 /* _hwa( write, rw, 0 ); \ */
333 /* _hwa( write, d, 0 ); \ */
334 /* _hwa( write, e, 0 ); \ */
335 /* _hwa( commit, (rs,port) ); \ */
336 /* _hwa( commit, (rw,port) ); \ */
337 /* _hwa( commit, (d,port) ); \ */
338 /* _hwa( commit, (e,port) ); \ */
339 /* hw_waste_cycles( 0.015 * HW_SYSHZ ); \ */
340 /* _hwa( write, d, 3 ); /\* initial write 8bit *\/ \ */
341 /* _hwa( commit, (d,port) ); \ */
342 /* _hwa_##o##__pulse(); \ */
343 /* hw_waste_cycles( 0.0041 * HW_SYSHZ ); \ */
344 /* _hw_##o##__pulse(); /\* repeat last command *\/ \ */
345 /* hw_waste_cycles( 64e-6 * HW_SYSHZ ); \ */
346 /* _hw_##o##__pulse(); /\* repeat last command *\/ \ */
347 /* hw_waste_cycles( 64e-6 * HW_SYSHZ ); \ */
348 /* hw( write, d, 2 ); /\* configure for 4bit *\/ \ */
349 /* _hw_##o##__pulse(); \ */
350 /* hw_waste_cycles( 64e-6 * HW_SYSHZ ); \ */
351 /* uint8_t rv = 0x20 ; /\* 4-bit, 1 line, 5x8 font *\/ \ */
352 /* if ( lines == 2 ) \ */
353 /* rv |= 0x08 ; \ */
354 /* _hw_##o##__command( rv ); /\* 4-bit, 2 lines, 5x8 font *\/ \ */
355 /* _hw_##o##__command( 0x08 ); /\* Display off, no cursor, no blink *\/ \ */
356 /* _hw_##o##_cls( ); \ */
357 /* _hw_##o##__command( 0x06 ); /\* Entry mode: inc, no shift *\/ \ */
358 /* _hw_##o##__command( 0x0C ); /\* Display on, no cursor, no blink *\/ \ */
359 /* } */
360 
361 
362 #define _hw_dfhd44780_gotoxy(o,lines,cols,e,rs,rw,d,...) \
363  void _hw_##o##_gotoxy ( uint8_t x, uint8_t y ) { \
364  if ( lines==2 && y>0 ) \
365  _hw_##o##__command(0x80+64+x); \
366  else \
367  _hw_##o##__command(0x80+0+x); \
368  }
369 
370 #define _hw_dfhd44780_newline(o,lines,cols,e,rs,rw,d,...) \
371  void _hw_##o##_newline ( uint8_t pos ) { \
372  if ( lines==1 ) \
373  _hw_##o##_gotoxy(0,0); \
374  else if ( lines==2 ) { \
375  if ( pos < 64 ) \
376  _hw_##o##_gotoxy(0,1); \
377  else \
378  _hw_##o##_gotoxy(0,0); \
379  } \
380  } \
381 
382 #define _hw_dfhd44780_home(o,lines,cols,e,rs,rw,d,...) \
383  void _hw_##o##_home ( ) { \
384  _hw_##o##__command(2); \
385  }
386 
387 /* FIXME: should cache current line and column so that reading the LCD would not be necessary
388  */
389 #define _hw_dfhd44780_putchar(o,lines,cols,e,rs,rw,d,...) \
390  void _hw_##o##_putchar ( unsigned char c ) { \
391  uint8_t pos; \
392  \
393  pos = _hw_##o##__wait(); /* wait busy-flag and get address counter */ \
394  if (c=='\n') \
395  _hw_##o##_newline(pos); \
396  else { \
397  if ( lines==1 ) { \
398  if ( pos == cols ) \
399  _hw_##o##_gotoxy(0,0); \
400  } \
401  else if ( lines==2 ) { \
402  if ( pos == 0+cols ) \
403  _hw_##o##_gotoxy(0,1); \
404  else if ( pos == 64+cols ) \
405  _hw_##o##_gotoxy(0,0); \
406  } \
407  _hw_##o##__data(c); \
408  } \
409  }
410 
411 
429 #define hw__hd44780_putchar , _hw_hd44780putchar
430 #define _hw_hd44780putchar(o,...) _hw_##o##_##putchar
431 
432 
453 #define hw_configure__hd44780 , _hw_cfhd44780
454 
455 #define _hw_cfhd44780(o,ec,dw,lines,cols,e,rs,rw,d,...) \
456  do{ \
457  uint8_t init=0 ; \
458  uint8_t display=0xFF ; \
459  uint8_t cursor=0xFF ; \
460  uint8_t blink=0xFF ; \
461  uint8_t shift=0xFF ; \
462  uint8_t direction=0xFF ; \
463  _hw_cfhd44780_(__VA_ARGS__,); \
464  uint8_t val ; \
465  \
466  if ( init == 1 ) \
467  _hw_##o##_init(); \
468  \
469  if ( display != 0xFF ) { \
470  val = 8 + (display==1)*4 + (cursor==1)*2 + (blink==1)*1; \
471  _hw_##o##__command( val ); \
472  } \
473  \
474  if ( shift != 0xFF ) { \
475  val = 16 + (shift==1)*8 + (direction==1)*4; \
476  _hw_##o##__command( val ); \
477  } \
478  }while(0)
479 
480 #define _hw_is_init_init , 1
481 #define _hw_is_display_display , 1
482 #define _hw_is_cursor_cursor , 1
483 #define _hw_is_blink_blink , 1
484 #define _hw_is_shift_shift , 1
485 #define _hw_hd44780_shift_cursor , 0
486 #define _hw_hd44780_shift_display , 1
487 #define _hw_hd44780_direction_left , 0
488 #define _hw_hd44780_direction_right , 1
489 
490 #define _hw_cfhd44780_(k,...) HW_BW(_hw_cfhd44780_ini,init,k)(k,__VA_ARGS__)
491 #define _hw_cfhd44780_ini0(k,...) HW_BW(_hw_cfhd44780_dis1,display,k)(k,__VA_ARGS__)
492 #define _hw_cfhd44780_ini1(k,v,...) HW_BV(_hw_cfhd44780_ini2,state_,v,)(__VA_ARGS__) // PUSH
493 #define _hw_cfhd44780_ini20(v,...) HW_E(HW_EM_ST(v)) HW_EAT // POP
494 #define _hw_cfhd44780_ini21(v,...) init=v; _hw_cfhd44780_dis // POP
495 
496 #define _hw_cfhd44780_dis(k,...) HW_BW(_hw_cfhd44780_dis1,display,k)(k,__VA_ARGS__)
497 #define _hw_cfhd44780_dis10(k,...) HW_BW(_hw_cfhd44780_shf1,shift,k)(k,__VA_ARGS__)
498 #define _hw_cfhd44780_dis11(k,v,...) HW_BV(_hw_cfhd44780_dis2,state_,v,)(__VA_ARGS__)
499 #define _hw_cfhd44780_dis20(v,...) HW_E(HW_EM_ST(v)) HW_EAT
500 #define _hw_cfhd44780_dis21(v,...) display=v; _hw_cfhd44780_cur
501 
502 #define _hw_cfhd44780_cur(k,...) HW_BW(_hw_cfhd44780_cur1,cursor,k)(k,__VA_ARGS__)
503 #define _hw_cfhd44780_cur10(k,...) HW_E(HW_EM_AN(k,cursor))
504 #define _hw_cfhd44780_cur11(k,v,...) HW_BV(_hw_cfhd44780_cur2,state_,v,)(__VA_ARGS__)
505 #define _hw_cfhd44780_cur20(v,...) HW_E(HW_EM_ST(v)) HW_EAT
506 #define _hw_cfhd44780_cur21(v,...) cursor=v; _hw_cfhd44780_blk
507 
508 #define _hw_cfhd44780_blk(k,...) HW_BW(_hw_cfhd44780_blk1,blink,k)(k,__VA_ARGS__)
509 #define _hw_cfhd44780_blk10(k,...) HW_E(HW_EM_AN(k,blink))
510 #define _hw_cfhd44780_blk11(k,v,...) HW_BV(_hw_cfhd44780_blk2,state_,v,)(__VA_ARGS__)
511 #define _hw_cfhd44780_blk20(v,...) HW_E(HW_EM_ST(v)) HW_EAT
512 #define _hw_cfhd44780_blk21(v,...) blink=v; _hw_cfhd44780_shf
513 
514 #define _hw_cfhd44780_shf(k,...) HW_BW(_hw_cfhd44780_shf1,shift,k)(k,__VA_ARGS__)
515 #define _hw_cfhd44780_shf10(k,...) HW_B(_hw_cfhd44780_shf2,k)(k,__VA_ARGS__)
516 #define _hw_cfhd44780_shf21(...) HW_EOL(__VA_ARGS__)
517 #define _hw_cfhd44780_shf20(k,...) HW_E(HW_EM_XNIL(k,(init,display,shift)))
518 #define _hw_cfhd44780_shf11(k,v,...) HW_BV(_hw_cfhd44780_shf3,hd44780_shift_,v,)(__VA_ARGS__)
519 #define _hw_cfhd44780_shf30(v,...) HW_E(HW_EM_XNIL(v,(cursor,display))) HW_EAT
520 #define _hw_cfhd44780_shf31(v,...) shift=v; _hw_cfhd44780_drn
521 
522 #define _hw_cfhd44780_drn(k,...) HW_BW(_hw_cfhd44780_drn1,direction,k)(k,__VA_ARGS__)
523 #define _hw_cfhd44780_drn10(k,...) HW_E(HW_EM_AN(k,direction))
524 #define _hw_cfhd44780_drn11(k,v,...) HW_BV(_hw_cfhd44780_drn2,hd44780_direction_,v,)(__VA_ARGS__)
525 #define _hw_cfhd44780_drn20(v,...) HW_E(HW_EM_XNIL(v,(left,right))) HW_EAT
526 #define _hw_cfhd44780_drn21(v,...) direction=v; HW_EOL /*__VA_ARGS__*/
527 
528 
538 #define hw_cls__hd44780 , _hw_hd44780_cls
539 #define _hw_hd44780_cls(o,ec,dw,...) _hw_##o##_cls()
540 
541 
551 #define hw_gotoxy__hd44780 , _hw_hd44780_gotoxy
552 #define _hw_hd44780_gotoxy(o,ec,dw,lines,cols,e,rs,rw,d,x,y,...) _hw_##o##_gotoxy(x,y)
553 
554 
564 #define hw_newline__hd44780 , _hw_hd44780_newline
565 #define _hw_hd44780_newline(o,ec,dw,lines,cols,e,rs,rw,d,pos,...) _hw_##o##_newline(pos)
566 
567 
577 #define hw_home__hd44780 , _hw_hd44780_home
578 #define _hw_hd44780_home(o,...) _hw_##o##_home()
579 
580 
590 #define hw_putchar__hd44780 , _hw_hd44780_putchar
591 #define _hw_hd44780_putchar(o,ec,dw,lines,cols,e,rs,rw,d,ch,...) _hw_##o##_putchar(ch)