ESOS32
ESOSOn32-bitProcessors
esos_comm.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2019 J. W. Bruce ("AUTHOR(S)")"
3  * All rights reserved.
4  * (J. W. Bruce, jwbruce_AT_tntech.edu, Tennessee Tech University)
5  *
6  * Permission to use, copy, modify, and distribute this software and its
7  * documentation for any purpose, without fee, and without written agreement is
8  * hereby granted, provided that the above copyright notice, the following
9  * two paragraphs and the authors appear in all copies of this software.
10  *
11  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
12  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
13  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
14  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15  *
16  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
19  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
20  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
21  *
22  * Please maintain this header in its entirety when copying/modifying
23  * these files.
24  *
25  *
26  */
27 
34 #include "esos.h"
35 #include "esos_cb.h"
36 #include "esos_comm.h"
37 
38 // ******** G L O B A L S ***************
39 volatile uint8_t __esos_comm_tx_buff[ESOS_SERIAL_IN_EP_SIZE];
40 volatile uint8_t __esos_comm_rx_buff[ESOS_SERIAL_OUT_EP_SIZE];
41 CBUFFER __st_CB_Tx, __st_CB_Rx;
42 CBUFFER* __pst_CB_Tx;
43 CBUFFER* __pst_CB_Rx;
44 volatile struct stTask __stChildTaskTx, __stChildTaskRx;
45 
46 /****************************************************************
47 ** F U N C T I O N S
48 ****************************************************************/
49 void __esos_InitCommSystem(void) {
50  // setup the circular buffers & their descriptors
51  __pst_CB_Rx = &__st_CB_Rx;
52  __pst_CB_Tx = &__st_CB_Tx;
53  __esos_CB_Init( __pst_CB_Tx, __esos_comm_tx_buff, ESOS_SERIAL_IN_EP_SIZE);
54  __esos_CB_Init( __pst_CB_Rx, __esos_comm_rx_buff, ESOS_SERIAL_OUT_EP_SIZE);
55 
56  __esos_hw_InitCommSystem();
57 
58 } // endof esos_Init_CommSystem()
59 
60 uint8_t __esos_u8_GetMSBHexCharFromUint8(uint8_t u8_x) {
61  uint8_t u8_c;
62 
63  u8_c = (u8_x>>4)& 0xf;
64  if (u8_c > 9) return('A'+u8_c-10);
65  else return('0'+u8_c);
66 }
67 
68 uint8_t __esos_u8_GetLSBHexCharFromUint8(uint8_t u8_x) {
69  uint8_t u8_c;
70 
71  u8_c = u8_x & 0xf;
72  if (u8_c > 9) return('A'+u8_c-10);
73  else return('0'+u8_c);
74 }
75 
76 
77 ESOS_CHILD_TASK( __esos_OutChar, uint8_t u8_c) {
78  static uint8_t u8_localChar;
79 
81  u8_localChar = u8_c;
82 
83  // wait for room in the TX CB to appear
84  ESOS_TASK_WAIT_WHILE_CB_IS_FULL( __pst_CB_Tx );
85  // write the data in the TX CB
86  __esos_CB_WriteUINT8( __pst_CB_Tx, u8_localChar);
87  // signal the hardware that a xfer should be started if
88  // not already ongoing
89  __esos_hw_signal_start_tx();
90 
91  ESOS_TASK_END();
92 } // end __esos_OutChar
93 
94 
95 ESOS_CHILD_TASK( __esos_OutUint8AsHexString, uint8_t u8_x) {
96  static uint8_t au8_String[5];
97 
99  au8_String[0] = '0';
100  au8_String[1] = 'x';
101  au8_String[2] = __esos_u8_GetMSBHexCharFromUint8(u8_x);
102  au8_String[3] = __esos_u8_GetLSBHexCharFromUint8(u8_x);
103  au8_String[4] = 0;
104 
105  ESOS_TASK_WAIT_UNTIL_CB_HAS_AVAILABLE_AT_LEAST( __pst_CB_Tx, 4);
106  __esos_CB_WriteUINT8Buffer( __pst_CB_Tx, &au8_String[0], 4 );
107  // signal the hardware that a xfer should be started if
108  // not already ongoing
109  __esos_hw_signal_start_tx();
110  ESOS_TASK_END();
111 
112 } // end __esos_OutUint8AsHexString()
113 
114 ESOS_CHILD_TASK( __esos_OutUint8AsDecString, uint8_t u8_x) {
115  // code provided by Gary Weasel
116  static uint8_t au8_String[5];
117  static uint8_t u8_c;
118  static uint8_t u8_digit;
119 
120 
121  ESOS_TASK_BEGIN();
122  u8_digit = 0;
123  if (u8_x > 99)
124  au8_String[u8_digit++] = '0' + u8_x / 100;
125  if (u8_x > 9)
126  au8_String[u8_digit++] = '0' + (u8_x % 100) / 10;
127  au8_String[u8_digit++] = '0' + (u8_x % 10);
128  au8_String[u8_digit] = 0;
129  u8_c = 0;
130  while (u8_c < u8_digit) {
131  // wait for room in the TX CB to appear
132  ESOS_TASK_WAIT_WHILE_CB_IS_FULL( __pst_CB_Tx );
133  // write the data in the TX CB
134  __esos_CB_WriteUINT8( __pst_CB_Tx, au8_String[u8_c++] );
135  } //end while()
136  // signal the hardware that a xfer should be started if
137  // not already ongoing
138  __esos_hw_signal_start_tx();
139  ESOS_TASK_END();
140 } // end __esos_OutUint8AsDecString
141 
142 ESOS_CHILD_TASK( __esos_OutUint32AsHexString, uint32_t u32_x) {
143  static uint8_t au8_String[11];
144  static uint8_t u8_c;
145 
146  ESOS_TASK_BEGIN();
147  au8_String[0] = '0';
148  au8_String[1] = 'x';
149  u8_c = (u32_x >> 24);
150  au8_String[2] = __esos_u8_GetMSBHexCharFromUint8(u8_c);
151  au8_String[3] = __esos_u8_GetLSBHexCharFromUint8(u8_c);
152  u8_c = (u32_x >> 16);
153  au8_String[4] = __esos_u8_GetMSBHexCharFromUint8(u8_c);
154  au8_String[5] = __esos_u8_GetLSBHexCharFromUint8(u8_c);
155  u8_c = (u32_x >> 8);
156  au8_String[6] = __esos_u8_GetMSBHexCharFromUint8(u8_c);
157  au8_String[7] = __esos_u8_GetLSBHexCharFromUint8(u8_c);
158  u8_c = u32_x;
159  au8_String[8] = __esos_u8_GetMSBHexCharFromUint8(u8_c);
160  au8_String[9] = __esos_u8_GetLSBHexCharFromUint8(u8_c);
161  au8_String[10] = 0;
162  u8_c = 0;
163 
164  ESOS_TASK_WAIT_UNTIL_CB_HAS_AVAILABLE_AT_LEAST( __pst_CB_Tx, 10);
165  __esos_CB_WriteUINT8Buffer( __pst_CB_Tx, &au8_String[0], 10 );
166  // signal the hardware that a xfer should be started if
167  // not already ongoing
168  __esos_hw_signal_start_tx();
169  ESOS_TASK_END();
170 
171 } // end __esos_OutUint32AsHexString()
172 
173 ESOS_CHILD_TASK( __esos_OutCharBuffer, uint8_t* pu8_out, uint8_t u8_len) {
174  ESOS_TASK_BEGIN();
175  ESOS_TASK_WAIT_UNTIL_CB_HAS_AVAILABLE_AT_LEAST( __pst_CB_Tx, u8_len);
176  __esos_CB_WriteUINT8Buffer( __pst_CB_Tx, pu8_out, u8_len );
177  // signal the hardware that a xfer should be started if
178  // not already ongoing
179  __esos_hw_signal_start_tx();
180  ESOS_TASK_END();
181 } // end __esos_OutCharBuffer
182 
183 
184 ESOS_CHILD_TASK( __esos_OutString, char* psz_out ) {
185  static char* psz_local;
186 
187  ESOS_TASK_BEGIN();
188  psz_local = psz_out;
189  while ( *psz_local ) {
190  // wait for room in the TX CB to appear
191  ESOS_TASK_WAIT_WHILE_CB_IS_FULL( __pst_CB_Tx );
192  // write the data in the TX CB
193  __esos_CB_WriteUINT8( __pst_CB_Tx, *psz_local++ );
194  __esos_hw_signal_start_tx();
195  } //end while()
196  ESOS_TASK_END();
197 } // end __esos_OutString
198 
199 
200 /* ***********************************
201  * INCOMING COMM CHILD TASKS
202  *************************************
203 */
204 ESOS_CHILD_TASK( __esos_getBuffer, uint8_t* pau8_buff, uint8_t u8_size) {
205  static uint8_t u8_i;
206  static uint8_t* pau8_LocalPtr;
207  static uint8_t u8_LocalSize;
208 
209  ESOS_TASK_BEGIN();
210  u8_LocalSize = u8_size;
211  pau8_LocalPtr = pau8_buff;
212 
213  for (u8_i=0; u8_i<u8_LocalSize; u8_i++) {
214  //wait for the RX character to arrive
215  ESOS_TASK_WAIT_WHILE ( __ESOS_CB_IS_EMPTY( __pst_CB_Rx ) );
216  pau8_LocalPtr[u8_i] = __esos_CB_ReadUINT8( __pst_CB_Rx );
217  } // end for(...)
218  ESOS_TASK_END();
219 } // end __esos_getBuffer
220 
221 // ************************************************************
222 // THIS FUNCTION IS POTENTIALLY VERY DANGEROUS!!!!!!
223 // ************************************************************
224 // The return data buffer pau8_buff must be at least as big as
225 // the ESOS coming incoming buffer -- ESOS_SERIAL_OUT_EP_SIZE
226 //
227 // Will suck down data until we get a zero-terminator, or
228 // carriage return/newline type character. Will also return when
229 // the number of characters received is the size of the ESOS
230 // incoming data buffer -- ESOS_SERIAL_OUT_EP_SIZE
231 //
232 ESOS_CHILD_TASK( __esos_getString, char* pau8_buff) {
233  static uint8_t u8_i;
234 
235  ESOS_TASK_BEGIN();
236  for (u8_i=0; u8_i<(ESOS_SERIAL_OUT_EP_SIZE-1); u8_i++) {
237  //wait for the RX character to arrive
238  ESOS_TASK_WAIT_WHILE ( __ESOS_CB_IS_EMPTY( __pst_CB_Rx ) );
239  pau8_buff[u8_i] = __esos_CB_ReadUINT8( __pst_CB_Rx );
240  if ((pau8_buff[u8_i] == '\n') || (pau8_buff[u8_i] == '\r') || (pau8_buff[u8_i] == 0)) break;
241  } // end for(...)
242  pau8_buff[u8_i] = 0;
243  ESOS_TASK_END();
244 } // end __esos_getString
245 
246 
247 // ================================================================
248 // UNSAFE I/O functions. Only use when you can be absolutely sure
249 // that they will not hang the communications or ESOS scheduler.
250 // Usually used during init of ESOS before the comm system or scheduler
251 // are even running.
252 // ================================================================
253 
254 // This routine is UNSAFE. It can HANG the system!!!!
255 void __esos_unsafe_PutUint8(uint8_t u8_c) {
256  // hang while CB is full
257  while (__ESOS_CB_IS_FULL( __pst_CB_Tx ));
258  // write the data in the TX CB
259  __esos_CB_WriteUINT8( __pst_CB_Tx, u8_c);
260  // signal the hardware that a xfer should be started if
261  // not already ongoing
262  __esos_hw_signal_start_tx();
263 } //end of __esos_unsafe_PutUint8()
264 
265 // This routine is UNSAFE. It can HANG the system!!!!
266 void __esos_unsafe_PutString(char* psz_in) {
267  while ( *psz_in ) {
268  // hang while CB is full
269  while (__ESOS_CB_IS_FULL( __pst_CB_Tx ));
270  // write the data in the TX CB
271  __esos_CB_WriteUINT8( __pst_CB_Tx, *psz_in++);
272  // signal the hardware that a xfer should be started if
273  // not already ongoing
274  __esos_hw_signal_start_tx();
275  } //end while
276 } // end __esos_unsafe_PutString()
277 
278 // This routine is UNSAFE. It can HANG the system!!!!
279 uint8_t __esos_unsafe_GetUint8(void) {
280  //wait for the RX character to arrive -- CAN HANG HERE!
281  while (__ESOS_CB_IS_EMPTY( __pst_CB_Rx ));
282  return __esos_CB_ReadUINT8( __pst_CB_Rx ); //return the character
283 }
284 
__stCIRCBUFF
Definition: esos_cb.h:56
esos.h
ESOS_TASK_END
#define ESOS_TASK_END()
Definition: esos_task.h:271
ESOS_CHILD_TASK
#define ESOS_CHILD_TASK(taskname,...)
Definition: esos_task.h:246
esos_cb.h
ESOS_TASK_WAIT_WHILE
#define ESOS_TASK_WAIT_WHILE(cond)
Definition: esos_task.h:363
stTask
Definition: esos_task.h:54
ESOS_TASK_BEGIN
#define ESOS_TASK_BEGIN()
Definition: esos_task.h:259
esos_comm.h
__esos_CB_WriteUINT8
void __esos_CB_WriteUINT8(CBUFFER *pst_CBuffer, uint8_t u8_x)
Definition: esos_cb.c:95