libpropeller
Making PropellerGCC Easier
 All Classes Files Functions Variables Enumerations Enumerator Macros Pages
full_duplex_serial.h
Go to the documentation of this file.
1 #ifndef libpropeller_full_duplex_serial_h_
2 #define libpropeller_full_duplex_serial_h_
3 
4 
5 #include <propeller.h>
6 #include <string.h>
7 
8 static inline int Rotl__(unsigned int a, unsigned int b) {
9  return (a << b) | (a >> (32 - b));
10 }
11 
12 static inline int Lookup__(int x, int b, int a[], int n) {
13  int i = (x)-(b);
14  return ((unsigned) i >= n) ? 0 : (a)[i];
15 }
16 
18 
19 
20 //Warning: To change the buffer size you must change it here and in the .S file
21 #define buffersize 256
22 #define buffermask (buffersize - 1)
23 
43 public:
44 
56  void Start(int Rxpin, int Txpin, int Mode, int Baudrate) {
57  volatile void * asm_reference = NULL;
58  __asm__ volatile ( "mov %[asm_reference], #FullDuplexSerial_Entry \n\t"
59  : [asm_reference] "+r" (asm_reference));
60 
61 
62  Stop();
63 
64  Rx_head = 0;
65  Rx_tail = 0;
66  Tx_head = 0;
67  Tx_tail = 0;
68 
69  Rx_pin = Rxpin;
70  Tx_pin = Txpin;
71  Rxtx_mode = Mode;
72 
73  Bit_ticks = (CLKFREQ / Baudrate);
74  Buffer_ptr = Rx_buffer;
75 
76  Cog = cognew(_load_start_full_duplex_serial_cog, &Rx_head) + 1;
77 
78  }
79 
82  void Stop(void) {
83  if (Cog > 0) {
84  cogstop(Cog - 1);
85  Cog = 0;
86  }
87 
88  Rx_head = 0;
89  Rx_tail = 0;
90  Tx_head = 0;
91  Tx_tail = 0;
92  Rx_pin = 0;
93  Tx_pin = 0;
94  Rxtx_mode = 0;
95  Bit_ticks = 0;
96  Buffer_ptr = 0;
97  }
98 
105  void GetFlush(void) {
106  while (CheckBuffer() >= 0) {
107  }
108  }
109 
119  int Get(const int timeout = -1) {
120  int Rxbyte = 0;
121  if (timeout < 0) {
122  while ((Rxbyte = CheckBuffer()) < 0) {
123  }
124  } else {
125  int T = CNT;
126  while (!(((Rxbyte = CheckBuffer()) >= 0)
127  || (((CNT - T) / (CLKFREQ / 1000)) > timeout))) {
128  }
129  }
130  return Rxbyte;
131  }
132 
137  void Put(const char Txbyte) {
138  while (!(Tx_tail != ((Tx_head + 1) & buffermask))) {
139  }
140  Tx_buffer[Tx_head] = Txbyte;
141  Tx_head = ((Tx_head + 1) & buffermask);
142  if (Rxtx_mode & 0x8) {
143  Get();
144  }
145  }
146 
153  void Put(const char * string) {
154  const int length = strlen(string);
155  for (int i = 0; i < length; i++) {
156  Put(string[i]);
157  }
158 
159  }
160 
161 
162 
163  //The Dec, Hex, and Bin functions are left out in the hopes of getting a separate object to do the conversion.
164 
174  int PutDec(int Value) {
175  int I;
176  int result = 0;
177  if (Value == (int) 0x80000000U) {
178  //TODO(SRLM): take care of the MAX negative value (it can't be made positive...)
179  }
180  if (Value < 0) {
181  Value = -Value;
182  Put('-');
183  }
184  I = 1000000000;
185  {
186  int _idx__0043;
187  for (_idx__0043 = 1; _idx__0043 <= 10; (_idx__0043 = (_idx__0043 + 1))) {
188  if (Value >= I) {
189  Put((((Value / I) + '0')));
190  Value = (Value % I);
191  result = -1;
192  } else {
193  if ((result) || (I == 1)) {
194  Put('0');
195  }
196  }
197  I = (I / 10);
198  }
199  }
200  return result;
201  }
202 private:
203 
204  void PutHex(int Value, int Digits) {
205  static int look__0044[] = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,};
206 
207  Value = (Value << ((8 - Digits) << 2));
208  {
209  int _idx__0045;
210  int _limit__0046 = Digits;
211  for (_idx__0045 = 1; _idx__0045 <= _limit__0046; (_idx__0045 = (_idx__0045 + 1))) {
212  Put(Lookup__(((Value = (Rotl__(Value, 4))) & 0xf), 0, look__0044, 16));
213  }
214  }
215  }
216 
217  void PutBin(int Value, int Digits) {
218  Value = (Value << (32 - Digits));
219  {
220  int _idx__0047;
221  int _limit__0048 = Digits;
222  for (_idx__0047 = 1; _idx__0047 <= _limit__0048; (_idx__0047 = (_idx__0047 + 1))) {
223  Put((((Value = (Rotl__(Value, 1))) & 0x1) + '0'));
224  }
225  }
226 
227  }
228 
229  int Cog;
230 
231  //Warning: the order of these variables is important! Do not change.
232  volatile int Rx_head;
233  volatile int Rx_tail;
234  volatile int Tx_head;
235  volatile int Tx_tail;
236  volatile int Rx_pin;
237  volatile int Tx_pin;
238  volatile int Rxtx_mode;
239  volatile int Bit_ticks;
240  volatile char * Buffer_ptr;
241  volatile char Rx_buffer[buffersize];
242  volatile char Tx_buffer[buffersize];
243 
244  int CheckBuffer(void) {
245  int Rxbyte = -1;
246  if (Rx_tail != Rx_head) {
247  Rxbyte = Rx_buffer[Rx_tail];
248  Rx_tail = (Rx_tail + 1) & buffermask;
249  }
250  return Rxbyte;
251  }
252 };
253 
254 #endif // libpropeller_full_duplex_serial_h_