PIC24 Support Libraries
esos_comm.c
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 #include "esos.h"
31 #include "esos_comm.h"
32 
33 // ******** G L O B A L S ***************
34 volatile uint8_t __esos_comm_tx_buff[ESOS_SERIAL_IN_EP_SIZE];
35 volatile uint8_t __esos_comm_rx_buff[ESOS_SERIAL_OUT_EP_SIZE];
36 volatile ESOS_COMM_BUFF_DSC __st_TxBuffer, __st_RxBuffer;
37 volatile struct stTask __stChildTaskTx, __stChildTaskRx;
38 
39 /****************************************************************
40 ** F U N C T I O N S
41 ****************************************************************/
42 void __esos_InitCommSystem(void) {
43  // setup the buffer descriptors
44  __st_TxBuffer.pau8_Data = &__esos_comm_tx_buff[0];
45  __st_TxBuffer.u16_Head = 0;
46  __st_TxBuffer.u16_Tail = 0;
47  __st_TxBuffer.u16_Length = ESOS_SERIAL_IN_EP_SIZE;
48  __st_RxBuffer.pau8_Data = __esos_comm_rx_buff;
49  __st_RxBuffer.u16_Head = 0;
50  __st_RxBuffer.u16_Tail = 0;
51  __st_RxBuffer.u16_Length = ESOS_SERIAL_OUT_EP_SIZE;
52 
53  __esos_hw_InitCommSystem();
54 
55 } // endof esos_Init_CommSystem()
56 
57 uint8_t __esos_u8_GetMSBHexCharFromUint8(uint8_t u8_x) {
58  uint8_t u8_c;
59 
60  u8_c = (u8_x>>4)& 0xf;
61  if (u8_c > 9) return('A'+u8_c-10);
62  else return('0'+u8_c);
63 }
64 
65 uint8_t __esos_u8_GetLSBHexCharFromUint8(uint8_t u8_x) {
66  uint8_t u8_c;
67 
68  u8_c = u8_x & 0xf;
69  if (u8_c > 9) return('A'+u8_c-10);
70  else return('0'+u8_c);
71 }
72 
73 
74 ESOS_CHILD_TASK( __esos_OutChar, uint8_t u8_c) {
75  static uint16_t u16_tmp;
76  static uint8_t u8_TempChar;
77 
79  u8_TempChar = u8_c;
80 
81  __ESOS_COMM_TXFIFO_PREP();
82  // wait for room in the TX FIFO
83  ESOS_TASK_WAIT_WHILE( u16_tmp == __st_TxBuffer.u16_Tail );
84  __ESOS_COMM_WRITE_TXFIFO( u8_TempChar );
85  __esos_hw_signal_start_tx();
86 
87  ESOS_TASK_END();
88 } // end __esos_OutChar
89 
90 
91 ESOS_CHILD_TASK( __esos_OutUint8AsHexString, uint8_t u8_x) {
92  static uint8_t au8_String[5];
93  static uint8_t u8_c;
94  static uint16_t u16_tmp;
95 
97  au8_String[0] = '0';
98  au8_String[1] = 'x';
99  au8_String[2] = __esos_u8_GetMSBHexCharFromUint8(u8_x);
100  au8_String[3] = __esos_u8_GetLSBHexCharFromUint8(u8_x);
101  au8_String[4] = 0;
102  u8_c = 0;
103 
104  while (u8_c < 4) {
105  __ESOS_COMM_TXFIFO_PREP();
106  ESOS_TASK_WAIT_WHILE( u16_tmp == __st_TxBuffer.u16_Tail );
107  __ESOS_COMM_WRITE_TXFIFO( au8_String[u8_c++] ); //write to buffer
108  __esos_hw_signal_start_tx();
109  } //end while()
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  static uint16_t u16_tmp;
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  __ESOS_COMM_TXFIFO_PREP();
132  ESOS_TASK_WAIT_WHILE( u16_tmp == __st_TxBuffer.u16_Tail );
133  __ESOS_COMM_WRITE_TXFIFO( au8_String[u8_c++] ); //write to buffer
134  __esos_hw_signal_start_tx();
135  } //end while()
136  ESOS_TASK_END();
137 } // end __esos_OutUint8AsDecString
138 
139 ESOS_CHILD_TASK( __esos_OutUint32AsHexString, uint32_t u32_x) {
140  static uint8_t au8_String[11];
141  static uint8_t u8_c;
142  static uint16_t u16_tmp;
143 
144  ESOS_TASK_BEGIN();
145  au8_String[0] = '0';
146  au8_String[1] = 'x';
147  u8_c = (u32_x >> 24);
148  au8_String[2] = __esos_u8_GetMSBHexCharFromUint8(u8_c);
149  au8_String[3] = __esos_u8_GetLSBHexCharFromUint8(u8_c);
150  u8_c = (u32_x >> 16);
151  au8_String[4] = __esos_u8_GetMSBHexCharFromUint8(u8_c);
152  au8_String[5] = __esos_u8_GetLSBHexCharFromUint8(u8_c);
153  u8_c = (u32_x >> 8);
154  au8_String[6] = __esos_u8_GetMSBHexCharFromUint8(u8_c);
155  au8_String[7] = __esos_u8_GetLSBHexCharFromUint8(u8_c);
156  u8_c = u32_x;
157  au8_String[8] = __esos_u8_GetMSBHexCharFromUint8(u8_c);
158  au8_String[9] = __esos_u8_GetLSBHexCharFromUint8(u8_c);
159  au8_String[10] = 0;
160  u8_c = 0;
161 
162  while (u8_c < 10) {
163  __ESOS_COMM_TXFIFO_PREP();
164  ESOS_TASK_WAIT_WHILE( u16_tmp == __st_TxBuffer.u16_Tail );
165  __ESOS_COMM_WRITE_TXFIFO( au8_String[u8_c++] ); //write to buffer
166  __esos_hw_signal_start_tx();
167  } //end while()
168  ESOS_TASK_END();
169 
170 } // end __esos_OutUint32AsHexString()
171 
172 
173 ESOS_CHILD_TASK( __esos_OutCharBuffer, uint8_t* pu8_out, uint8_t u8_len) {
174  static uint16_t u16_tmp;
175  static uint8_t u8_i;
176  static uint8_t u8_StoreLen;
177  static uint8_t* pu8_StorePtr;
178 
179  ESOS_TASK_BEGIN();
180  u8_StoreLen = u8_len;
181  pu8_StorePtr = pu8_out;
182  u8_i = 0;
183  while (u8_StoreLen) {
184  __ESOS_COMM_TXFIFO_PREP();
185  ESOS_TASK_WAIT_WHILE( u16_tmp == __st_TxBuffer.u16_Tail );
186  __ESOS_COMM_WRITE_TXFIFO( pu8_StorePtr[u8_i++] ); //write to buffer
187  __esos_hw_signal_start_tx();
188  u8_StoreLen--; //update number of chars remaining to TX
189  } //end while()
190  ESOS_TASK_END();
191 
192 } // end __esos_OutCharBuffer
193 
194 ESOS_CHILD_TASK( __esos_getBuffer, uint8_t* pau8_buff, uint8_t u8_size) {
195  static uint8_t u8_i;
196  static uint8_t* pau8_LocalPtr;
197  static uint8_t u8_LocalSize;
198 
199  ESOS_TASK_BEGIN();
200  u8_LocalSize = u8_size;
201  pau8_LocalPtr = pau8_buff;
202 
203  for (u8_i=0; u8_i<u8_size; u8_i++) {
204  //wait for the RX character to arrive
205  ESOS_TASK_WAIT_WHILE ( __st_RxBuffer.u16_Head == __st_RxBuffer.u16_Tail);
206 
207  __st_RxBuffer.u16_Tail++;
208  if (__st_RxBuffer.u16_Tail == ESOS_SERIAL_OUT_EP_SIZE) __st_RxBuffer.u16_Tail=0; //wrap
209 
210  pau8_buff[u8_i] = __st_RxBuffer.pau8_Data[__st_RxBuffer.u16_Tail];
211  } // end for(...)
212  ESOS_TASK_END();
213 } // end __esos_getBuffer
214 
215 
216 ESOS_CHILD_TASK( __esos_getString, char* pau8_buff) {
217  static uint8_t u8_i;
218 
219  ESOS_TASK_BEGIN();
220  for (u8_i=0; u8_i<(ESOS_SERIAL_OUT_EP_SIZE-1); u8_i++) {
221 
222  ESOS_TASK_WAIT_WHILE ( __st_RxBuffer.u16_Head == __st_RxBuffer.u16_Tail);
223 
224  __st_RxBuffer.u16_Tail++;
225  if (__st_RxBuffer.u16_Tail == ESOS_SERIAL_OUT_EP_SIZE) __st_RxBuffer.u16_Tail=0; //wrap
226 
227  pau8_buff[u8_i] = __st_RxBuffer.pau8_Data[__st_RxBuffer.u16_Tail];
228  if ((pau8_buff[u8_i] == '\n') || (pau8_buff[u8_i] == '\r') || (pau8_buff[u8_i] == 0)) break;
229  } // end for(...)
230  pau8_buff[u8_i] = 0;
231  ESOS_TASK_END();
232 } // end __esos_getBuffer
233 
234 ESOS_CHILD_TASK( __esos_OutString, char* psz_out ) {
235  static uint16_t u16_tmp;
236  static char* psz_local;
237 
238  ESOS_TASK_BEGIN();
239  psz_local = psz_out;
240  while ( *psz_local ) {
241  __ESOS_COMM_TXFIFO_PREP();
242  ESOS_TASK_WAIT_WHILE( u16_tmp == __st_TxBuffer.u16_Tail );
243  __ESOS_COMM_WRITE_TXFIFO( *psz_local++ ); //write to buffer
244  __esos_hw_signal_start_tx();
245  } //end while()
246  ESOS_TASK_END();
247 
248 } // end __esos_OutCharBuffer
249 
250 
251 // ================================================================
252 // UNSAFE I/O functions. Only use when you can be absolutely sure
253 // that they will not hang the communications or ESOS scheduler.
254 // Usually used during init of ESOS before the comm system or scheduler
255 // are even running.
256 // ================================================================
257 
258 // This routine is UNSAFE. It can HANG the system!!!!
259 void __esos_unsafe_PutUint8(uint8_t u8_c) {
260  uint16_t u16_tmp;
261 
262  __ESOS_COMM_TXFIFO_PREP();
263  // wait for room in the TX FIFO -- CAN HANG HERE!
264  while (u16_tmp == __st_TxBuffer.u16_Tail);
265  __ESOS_COMM_WRITE_TXFIFO( u8_c );
266  __esos_hw_signal_start_tx();
267 } //end of __esos_unsafe_PutUint8()
268 
269 // This routine is UNSAFE. It can HANG the system!!!!
270 void __esos_unsafe_PutString(char* psz_in) {
271  uint16_t u16_tmp;
272 
273  while ( *psz_in ) {
274  __ESOS_COMM_TXFIFO_PREP();
275  // wait for room in the TX FIFO -- CAN HANG HERE!
276  while (u16_tmp == __st_TxBuffer.u16_Tail);
277  __ESOS_COMM_WRITE_TXFIFO( *psz_in++ );
278  __esos_hw_signal_start_tx();
279  } //end while
280 } // end __esos_unsafe_PutString()
281 
282 // This routine is UNSAFE. It can HANG the system!!!!
283 uint8_t __esos_unsafe_GetUint8(void) {
284  //wait for the RX character to arrive -- CAN HANG HERE!
285  while (__st_RxBuffer.u16_Head == __st_RxBuffer.u16_Tail);
286  __st_RxBuffer.u16_Tail++;
287  if (__st_RxBuffer.u16_Tail == ESOS_SERIAL_OUT_EP_SIZE) __st_RxBuffer.u16_Tail=0; //wrap
288  return __st_RxBuffer.pau8_Data[__st_RxBuffer.u16_Tail]; //return the character
289 }
#define ESOS_CHILD_TASK(taskname,...)
Definition: esos_task.h:247
#define ESOS_TASK_END()
Definition: esos_task.h:272
#define ESOS_TASK_WAIT_WHILE(cond)
Definition: esos_task.h:364
#define ESOS_TASK_BEGIN()
Definition: esos_task.h:260
unsigned char uint8_t
An abbreviation for an 8-bit unsigned integer.
Definition: dataXferImpl.h:194