view formatting.h @ 5:1a405bda2ffe

rewrite gpib using state machine instead of procedural code, add proper timeout, command queueing, several new commands, improve hardcopy utility
author Frank Kingswood <frank@kingswood-consulting.co.uk>
date Sat, 29 Mar 2014 23:23:58 +0000
parents a70e0a8ac73e
children
line wrap: on
line source
1 /* #------------------------------------------------------------------------#
2 | |
3 | formatting.h |
4 | |
5 | String formatting helper class, used as CRTP. |
6 | |
7 | Copyright 2014, Frank A. Kingswood, www.kingswood-consulting.co.uk |
8 | |
9 #------------------------------------------------------------------------# */
11 #ifndef FORMATTING_H_
12 #define FORMATTING_H_
13 #include <avr/pgmspace.h>
15 enum _ROMS { A=0, B=0xffff };
16 #define ROM(s) ((_ROMS)(intptr_t)(s))
17 #define ROMS(s) ROM(PSTR(s))
19 PROGMEM extern const char CRLF[];
20 template<class Output> class Formatting
21 {
22 public:
24 static void Send(char c)
25 {
26 Output::Send_(c);
27 }
29 static void __attribute__((noinline)) SendSafeChar(char c)
30 {
31 // a bit of safety - output only visible chars and make the rest octal
32 if((c>=32 && c<127) || c==13 || c==10 || c==9)
33 Send(c);
34 else
35 { Send('\\');
36 Send(char('0'+(((c>>6))&3)));
37 Send(char('0'+(((c>>3))&7)));
38 Send(char('0'+(((c>>0))&7)));
39 }
40 }
42 static void __attribute__((noinline)) Send(const char *message)
43 {
44 while(char c=*message)
45 {
46 SendSafeChar(c);
47 message++;
48 }
49 }
51 static void __attribute__((noinline)) Send(_ROMS message)
52 {
53 intptr_t m=message;
54 while(char c=pgm_read_byte_near(m))
55 {
56 SendSafeChar(c);
57 m++;
58 }
59 }
61 static void __attribute__((noinline)) Send(uint16_t value)
62 {
63 static const unsigned powers[]={10000,1000,100,10,0};
64 bool f=false;
65 for(uint8_t i=0;;i++)
66 { unsigned n=powers[i];
67 if(n==0)
68 break;
69 char d='0';
70 while(value>=n)
71 { value-=n;
72 d=d+1;
73 }
74 if(d!='0')
75 f=true;
76 if(f)
77 Send(d);
78 }
79 Send(char('0'+value));
80 }
82 static void __attribute__((noinline)) Hex(uint16_t value)
83 {
84 Send(ROMS("0x"));
85 SendHex8(value>>8);
86 SendHex8(value);
87 }
89 static void __attribute__((noinline)) Hex(int16_t value)
90 { Hex(uint16_t(value));
91 }
93 static void __attribute__((noinline)) Hex(uint8_t value)
94 {
95 Send(ROMS("0x"));
96 SendHex8(value);
97 }
99 static void __attribute__((noinline)) Hex(int8_t value)
100 { Hex(uint8_t(value));
101 }
103 static void __attribute__((noinline)) Send(int16_t value)
104 {
105 uint16_t v;
106 if(value<0)
107 { Send('-');
108 v=-value;
109 }
110 else
111 v=value;
112 Send(v);
113 }
115 static void __attribute__((noinline)) Send()
116 { Send(ROM(CRLF));
117 }
119 private:
120 static void __attribute__((noinline)) SendHex8(uint8_t value)
121 { SendHex4(value>>4);
122 SendHex4(value);
123 }
124 static void __attribute__((noinline)) SendHex4(uint8_t value)
125 { value&=15;
126 if(value>9)
127 Send(char('a'-10+value));
128 else
129 Send(char('0'+value));
130 }
131 };
133 class FormattingNL { };
134 extern const FormattingNL endl;
136 template<class Output> const Formatting<Output> &operator <<(const Formatting<Output> &o, int16_t value)
137 { o.Send(value);
138 return o;
139 }
141 template<class Output> const Formatting<Output> &operator <<(const Formatting<Output> &o, uint16_t value)
142 { o.Send(value);
143 return o;
144 }
146 template<class Output> const Formatting<Output> &operator <<(const Formatting<Output> &o, char value)
147 { o.Send(value);
148 return o;
149 }
151 template<class Output> const Formatting<Output> &operator <<(const Formatting<Output> &o, const char *value)
152 { o.Send(value);
153 return o;
154 }
156 template<class Output> const Formatting<Output> &operator <<(const Formatting<Output> &o, _ROMS value)
157 { o.Send(value);
158 return o;
159 }
161 template<class Output> const Formatting<Output> &operator <<(const Formatting<Output> &o, const FormattingNL &)
162 { o.Send();
163 return o;
164 }
167 #endif /* FORMATTING_H_ */
169 /* ----- EOF formatting.h ----- */