FreeCalypso > hg > freecalypso-citrine
comparison nucleus/demo/sdc.c @ 0:75a11d740a02
initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 09 Jun 2016 00:02:41 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:75a11d740a02 |
---|---|
1 /************************************************************************** | |
2 * | |
3 * Copyright Mentor Graphics Corporation 2002 | |
4 * All Rights Reserved. | |
5 * | |
6 * THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS | |
7 * THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS | |
8 * SUBJECT TO LICENSE TERMS. | |
9 * | |
10 *************************************************************************** | |
11 *************************************************************************** | |
12 * | |
13 * FILE NAME VERSION | |
14 * | |
15 * sdc.c Nucleus PLUS\ARM925\Code Composer 1.14.1 | |
16 * | |
17 * DESCRIPTION | |
18 * | |
19 * This file contains the Serial Driver specific functions. | |
20 * | |
21 * DATA STRUCTURES | |
22 * | |
23 * SD_PORT * : An array of pointers to serial port structures. | |
24 * | |
25 * FUNCTIONS | |
26 * | |
27 * SDC_Init_Port | |
28 * SDC_Date_Ready | |
29 * SDC_Put_String | |
30 * SDC_LISR | |
31 * SDC_Get_Char | |
32 * SDC_Put_Char | |
33 * SDC_Set_Baud_Rate | |
34 * | |
35 * DEPENDENCIES | |
36 * | |
37 * nucleus.h | |
38 * sd_defs.h | |
39 * sd_extr.h | |
40 * target.h | |
41 * protocol.h | |
42 * externs.h | |
43 * ppp.h | |
44 * | |
45 * HISTORY | |
46 * | |
47 * NAME DATE REMARKS | |
48 * | |
49 * B. Ronquillo 08-28-2002 Released version 1.14.1 | |
50 ****************************************************************************/ | |
51 | |
52 #include "nucleus.h" | |
53 #include "sd_defs.h" | |
54 #include "sd_extr.h" | |
55 #include "calirq.h" | |
56 | |
57 #ifdef NU_ENABLE_PPP | |
58 | |
59 #include "net\target.h" | |
60 #include "net\inc\externs.h" | |
61 #include "net\inc\tcp_errs.h" | |
62 #include "ppp\inc\ppp.h" | |
63 | |
64 #endif /* NU_ENABLE_PPP */ | |
65 | |
66 extern NU_MEMORY_POOL System_Memory; | |
67 | |
68 /* Define a small array to hold pointers to the two UART data | |
69 structures. This is used by the LISR to find the correct | |
70 data structure for the interrupt being handled. */ | |
71 SD_PORT *SDC_Port_List[SD_MAX_UARTS]; | |
72 | |
73 | |
74 /* Define prototypes for functions local to this module. */ | |
75 | |
76 /**************** Begin Port Specific Section **************/ | |
77 #ifdef GRAFIX_MOUSE | |
78 extern NU_HISR Mouse_HISR; | |
79 #endif | |
80 /**************** End Port Specific Section **************/ | |
81 | |
82 static VOID SDC_Set_Baud_Rate(UINT32, SD_PORT *); | |
83 /*************************************************************************** | |
84 * FUNCTION | |
85 * | |
86 * SDC_Init_Port | |
87 * | |
88 * DESCRIPTION | |
89 * | |
90 * This function intializes the COM port that will be used for PPP | |
91 * communications. | |
92 * | |
93 * | |
94 * INPUTS | |
95 * | |
96 * SD_PORT * : device initialization structure. | |
97 * | |
98 * OUTPUTS | |
99 * | |
100 * STATUS : Returns NU_SUCCESS if successful initialization, | |
101 * else a negative value is returned. | |
102 * | |
103 ****************************************************************************/ | |
104 STATUS SDC_Init_Port(SD_PORT *uart) | |
105 { | |
106 STATUS status = NU_SUCCESS; | |
107 INT32 int_level, /* old interrupt level */ | |
108 tInt; | |
109 UINT8 temp_byte; | |
110 UINT32 temp_word, int_val; | |
111 CHAR sem_name[8]; | |
112 static INT num_ports = 0; | |
113 VOID (*old_lisr)(INT); /* old LISR */ | |
114 | |
115 #ifdef GRAFIX_MOUSE | |
116 if ((uart->communication_mode == SERIAL_MODE) || | |
117 (uart->communication_mode == SERIAL_MOUSE)) | |
118 #else | |
119 if (uart->communication_mode == SERIAL_MOUSE) | |
120 { | |
121 status = NU_INVALID_MOUSE_MODE; | |
122 } | |
123 else if (uart->communication_mode == SERIAL_MODE) | |
124 #endif | |
125 | |
126 { | |
127 | |
128 /* Check for max allowed UARTS. */ | |
129 if (num_ports >= SD_MAX_UARTS) | |
130 | |
131 /* We have already initialized the max allowed UARTS. */ | |
132 status = NU_UART_LIST_FULL; | |
133 } | |
134 | |
135 if (status != NU_SUCCESS) | |
136 return (status); | |
137 | |
138 /* Check the supplied parity */ | |
139 else if ((uart->parity != SD_PARITY_NONE) && | |
140 (uart->parity != SD_PARITY_EVEN) && | |
141 (uart->parity != SD_PARITY_ODD)) | |
142 | |
143 /* The supplied parity is not valid */ | |
144 status = NU_INVALID_PARITY; | |
145 | |
146 /* Check the supplied number of data bits */ | |
147 else if ((uart->data_bits != SD_DATA_BITS_7) && | |
148 (uart->data_bits != SD_DATA_BITS_8)) | |
149 | |
150 /* The supplied data bits value is not valid */ | |
151 status = NU_INVALID_DATA_BITS; | |
152 | |
153 /* Check the supplied number of stop bits */ | |
154 else if ((uart->stop_bits != SD_STOP_BITS_1) && | |
155 (uart->stop_bits != SD_STOP_BITS_2)) | |
156 | |
157 /* The supplied stop bits value is not valid */ | |
158 status = NU_INVALID_STOP_BITS; | |
159 | |
160 /* Verify the baud rate is within acceptable range */ | |
161 else if ((uart->baud_rate < 300) || (uart->baud_rate > 115200)) | |
162 | |
163 /* The baud rate is out of range */ | |
164 status = NU_INVALID_BAUD; | |
165 | |
166 /************** Begin Port Specific Section ****************/ | |
167 | |
168 /* Validate the com port. */ | |
169 else if ((uart->com_port == SD_UART1) || | |
170 (uart->com_port == SD_UART2)) | |
171 { | |
172 /* Handle UARTA */ | |
173 if (uart->com_port == SD_UART_MODEM) | |
174 { | |
175 /* Set the vector inside this structure */ | |
176 uart->vector = IRQ_UART_MODEM; | |
177 | |
178 /* Set the base address for this UART. */ | |
179 uart->base_address = SD_UART_MODEM_BASE; | |
180 } | |
181 else /* Otherwise handle UARTB. */ | |
182 { | |
183 /* Set the vector inside this structure */ | |
184 uart->vector = IRQ_UART_IRDA; | |
185 | |
186 /* Set the base address for this UART. */ | |
187 uart->base_address = SD_UART_IRDA_BASE; | |
188 } | |
189 } | |
190 else | |
191 | |
192 /************** End Port Specific Section **************/ | |
193 | |
194 /* Not a supported port. */ | |
195 status = NU_INVALID_COM_PORT; | |
196 | |
197 #ifdef GRAFIX_MOUSE | |
198 if ((uart->communication_mode == SERIAL_MODE) || | |
199 (uart->communication_mode == SERIAL_MOUSE)) | |
200 #else | |
201 if (uart->communication_mode == SERIAL_MODE) | |
202 #endif | |
203 | |
204 { | |
205 /* Make sure the port was valid and the LISR was | |
206 registered. Then create the semaphore used to make | |
207 the SD_Put_String service thread safe. */ | |
208 if (status == NU_SUCCESS) | |
209 { | |
210 /* Allocate memory for the semaphore control block. */ | |
211 status = NU_Allocate_Memory(&System_Memory,(VOID**) &uart->sd_semaphore, | |
212 sizeof(NU_SEMAPHORE), NU_NO_SUSPEND); | |
213 | |
214 #if 0 | |
215 /* original code */ | |
216 for(tInt=0; tInt < sizeof(NU_SEMAPHORE); tInt++) | |
217 /* Fixed SPR 211. Changed type from (UINT32) to (CHAR *) */ | |
218 SD_OUTBYTE((CHAR *) uart->sd_semaphore + tInt, 0x00); | |
219 #else | |
220 bzero(uart->sd_semaphore, sizeof(NU_SEMAPHORE)); | |
221 #endif | |
222 | |
223 if (status == NU_SUCCESS) | |
224 { | |
225 /* Build the name. */ | |
226 sem_name[0] = 's'; | |
227 sem_name[1] = 'e'; | |
228 sem_name[2] = 'r'; | |
229 sem_name[3] = 'i'; | |
230 sem_name[4] = 'a'; | |
231 sem_name[5] = 'l'; | |
232 sem_name[6] = '_'; | |
233 sem_name[7] = (CHAR)(0x30 + num_ports); | |
234 | |
235 status = NU_Create_Semaphore (uart->sd_semaphore, sem_name, | |
236 1, NU_FIFO); | |
237 } | |
238 } | |
239 | |
240 /* Make sure all the above was completed. Then store off this | |
241 UART stucture and initialize the chip. */ | |
242 if (status == NU_SUCCESS) | |
243 { | |
244 SDC_Port_List[num_ports++] = uart; | |
245 } | |
246 } | |
247 | |
248 if (status == NU_SUCCESS) | |
249 { | |
250 /* Allocate memory for the data buffers. PPP only requires a TX | |
251 buffer so the allocation will be a little different for PPP mode. */ | |
252 #ifdef GRAFIX_MOUSE | |
253 if ((uart->communication_mode == SERIAL_MODE) || | |
254 (uart->communication_mode == SERIAL_MOUSE)) | |
255 #else | |
256 if (uart->communication_mode == SERIAL_MODE) | |
257 #endif | |
258 | |
259 { | |
260 status = NU_Allocate_Memory (&System_Memory,(VOID**) &uart->tx_buffer, | |
261 (2 * uart->sd_buffer_size), NU_NO_SUSPEND); | |
262 | |
263 /* Set the RX buffer to just past the TX buffer. */ | |
264 uart->rx_buffer = (CHAR *)(uart->tx_buffer + uart->sd_buffer_size); | |
265 } | |
266 else | |
267 { | |
268 status = NU_Allocate_Memory (&System_Memory,(VOID**) &uart->tx_buffer, | |
269 uart->sd_buffer_size, NU_NO_SUSPEND); | |
270 } | |
271 | |
272 if (status == NU_SUCCESS) | |
273 { | |
274 /* Setup the RX SD buffer */ | |
275 uart->rx_buffer_read = uart->rx_buffer_write = 0; | |
276 | |
277 uart->rx_buffer_status = NU_BUFFER_EMPTY; | |
278 | |
279 /* Setup the TX SD buffer */ | |
280 uart->tx_buffer_read = uart->tx_buffer_write = 0; | |
281 uart->tx_buffer_status = NU_BUFFER_EMPTY; | |
282 } | |
283 } | |
284 | |
285 if (status == NU_SUCCESS) | |
286 { | |
287 /* Disable interrupts */ | |
288 int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS); | |
289 | |
290 /* Initialize the UART */ | |
291 | |
292 /************** Begin Port Specific Section *************/ | |
293 | |
294 /* Configure the Mode Definition Register */ | |
295 /* Set the serial port to UART mode */ | |
296 SD_OUTBYTE(uart->base_address + MDR_OFFSET, MDR_UART_MODE); | |
297 | |
298 /* Reset the TX/RX FIFOs */ | |
299 SD_OUTBYTE(uart->base_address + FCR_OFFSET, FCR_FIFO_RESET); | |
300 | |
301 /* Setup baud rate */ | |
302 SDC_Set_Baud_Rate(uart->baud_rate, uart); | |
303 | |
304 /* Set the modem control register. Set DTR, RTS to output to LOW, | |
305 and set INT output pin to normal operating mode */ | |
306 SD_OUTBYTE (uart->base_address + MCR_OFFSET, (MCR_DTR_LOW | MCR_RTS_LOW)); | |
307 | |
308 /* Setup parity, data bits, and stop bits */ | |
309 SD_OUTBYTE (uart->base_address + LCR_OFFSET, | |
310 (LCR_NO_BREAK|uart->parity|uart->data_bits|uart->stop_bits )); | |
311 | |
312 /* Setup Fifo trigger level and enable FIFO */ | |
313 SD_OUTBYTE (uart->base_address + FCR_OFFSET, 0); | |
314 | |
315 /* Register the interrupt handler for the UART receiver */ | |
316 status = NU_Register_LISR(uart->vector, SDC_LISR, &old_lisr); | |
317 | |
318 if (status == NU_SUCCESS) | |
319 { | |
320 /* Enable the RX interrupts */ | |
321 SD_OUTBYTE (uart->base_address + IER_OFFSET, IER_RX_HOLDING_REG); | |
322 | |
323 if(uart->com_port == SD_UART_MODEM) | |
324 { | |
325 /* Enable the UART interrupt globally */ | |
326 INTH_REGS.ilr_irq[IRQ_UART_MODEM] = 0x7C; | |
327 INTH_REGS.mask_it_reg1 &= ~(1 << IRQ_UART_MODEM); | |
328 } | |
329 else /* Handle UART B */ | |
330 { | |
331 /* Enable the UART interrupt globally */ | |
332 INTH_REGS.ilr_irq[IRQ_UART_IRDA] = 0x7C; | |
333 INTH_REGS.mask_it_reg2 &= ~(1 << (IRQ_UART_IRDA - 16)); | |
334 } | |
335 | |
336 } | |
337 | |
338 /************** End Port Specific Section *************/ | |
339 | |
340 | |
341 /* Initialize the error counters. */ | |
342 uart->parity_errors = | |
343 uart->frame_errors = | |
344 uart->overrun_errors = | |
345 uart->busy_errors = | |
346 uart->general_errors = 0; | |
347 | |
348 /* Restore interrupts to previous level */ | |
349 NU_Local_Control_Interrupts(int_level); | |
350 } | |
351 | |
352 return (status); | |
353 } | |
354 /*************************************************************************** | |
355 * FUNCTION | |
356 * | |
357 * SDC_Put_Char | |
358 * | |
359 * DESCRIPTION | |
360 * | |
361 * This writes a character out to the serial port. | |
362 * | |
363 * INPUTS | |
364 * | |
365 * UINT8 : Character to to be written to the serial port. | |
366 * SD_PORT * : Serial port to send the char to. | |
367 * | |
368 * OUTPUTS | |
369 * | |
370 * none | |
371 * | |
372 ****************************************************************************/ | |
373 VOID SDC_Put_Char(UINT8 ch, SD_PORT *uart) | |
374 { | |
375 INT int_level; /* old interrupt level */ | |
376 UINT32 temp_long; | |
377 | |
378 #ifdef GRAFIX_MOUSE | |
379 if ((uart->communication_mode == SERIAL_MODE) || | |
380 (uart->communication_mode == SERIAL_MOUSE)) | |
381 #else | |
382 if (uart->communication_mode == SERIAL_MODE) | |
383 #endif | |
384 | |
385 { | |
386 /* If the buffer is full wait for it to empty a little. */ | |
387 while (uart->tx_buffer_status == NU_BUFFER_FULL); | |
388 | |
389 /* Disable interrupts */ | |
390 int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS); | |
391 | |
392 /* Check the transmit buffer status. If it has data already | |
393 just add this byte to the buffer. */ | |
394 if ( uart->tx_buffer_status != NU_BUFFER_EMPTY) | |
395 { | |
396 /* Add byte to buffer. */ | |
397 uart->tx_buffer[uart->tx_buffer_write++] = ch; | |
398 | |
399 /* Check for wrap of buffer. */ | |
400 if(uart->tx_buffer_write == uart->sd_buffer_size) | |
401 uart->tx_buffer_write = 0; | |
402 | |
403 /* Check for full buffer. */ | |
404 if (uart->tx_buffer_write == uart->tx_buffer_read) | |
405 uart->tx_buffer_status = NU_BUFFER_FULL; | |
406 | |
407 /* Restore interrupts to previous level */ | |
408 NU_Local_Control_Interrupts(int_level); | |
409 } | |
410 else | |
411 { | |
412 /* Otherwise send the data. */ | |
413 | |
414 /* Restore interrupts to previous level */ | |
415 NU_Local_Control_Interrupts(int_level); | |
416 | |
417 /* Add byte to buffer. */ | |
418 uart->tx_buffer[uart->tx_buffer_write++] = ch; | |
419 | |
420 /* Check for wrap of buffer. */ | |
421 if(uart->tx_buffer_write == uart->sd_buffer_size) | |
422 uart->tx_buffer_write = 0; | |
423 | |
424 /* Set status */ | |
425 uart->tx_buffer_status = NU_BUFFER_DATA; | |
426 | |
427 /**************** Begin Port Specific Section **************/ | |
428 | |
429 /* Wait until the transmitter buffer is empty */ | |
430 while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY)); | |
431 | |
432 /* Transmit the character */ | |
433 SD_OUTBYTE (uart->base_address + THR_OFFSET, ch); | |
434 | |
435 /* Enable the TX interrupts */ | |
436 temp_long = SD_INBYTE (uart->base_address + IER_OFFSET); | |
437 temp_long |= IER_TX_HOLDING_REG; | |
438 SD_OUTBYTE (uart->base_address + IER_OFFSET, temp_long); | |
439 | |
440 } | |
441 | |
442 } /* endif mode */ | |
443 else | |
444 { | |
445 /* Wait until the transmitter buffer is empty */ | |
446 while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY)); | |
447 | |
448 /* Transmit the character */ | |
449 SD_OUTBYTE (uart->base_address + THR_OFFSET, ch); | |
450 | |
451 #ifndef PPP_POLLED_TX | |
452 | |
453 /* Enable the TX interrupts */ | |
454 temp_long = SD_INBYTE (uart->base_address + IER_OFFSET); | |
455 temp_long |= IER_TX_HOLDING_REG; | |
456 SD_OUTBYTE (uart->base_address + IER_OFFSET, temp_long); | |
457 | |
458 #endif /* PPP_POLLED_TX */ | |
459 | |
460 | |
461 } | |
462 | |
463 /***************** End Port Specific Section ***************/ | |
464 | |
465 } | |
466 | |
467 /*************************************************************************** | |
468 * FUNCTION | |
469 * | |
470 * SDC_LISR | |
471 * | |
472 * DESCRIPTION | |
473 * | |
474 * This is the entry function for the receive ISR that services the UART | |
475 * in the ARM925. | |
476 * | |
477 * INPUTS | |
478 * | |
479 * INT : Interrupt vector | |
480 * | |
481 * OUTPUTS | |
482 * | |
483 * none | |
484 * | |
485 ****************************************************************************/ | |
486 VOID SDC_LISR(INT vector) | |
487 { | |
488 | |
489 SD_PORT *uart; | |
490 CHAR receive; | |
491 UINT8 status; | |
492 UINT8 int_status; | |
493 UINT8 vector_found = NU_FALSE; | |
494 UINT8 ier_val; | |
495 | |
496 | |
497 #ifdef NU_ENABLE_PPP | |
498 DV_DEVICE_ENTRY *device; | |
499 #endif /* NU_ENABLE_PPP */ | |
500 | |
501 for(receive = 0 ; (SDC_Port_List[receive] != NU_NULL) && | |
502 (receive < SD_MAX_UARTS) && !vector_found ; receive++) | |
503 { | |
504 /* See if we found one. Better have since we got an interrupt | |
505 from one. */ | |
506 if (SDC_Port_List[receive] -> vector == vector) | |
507 { | |
508 /* Point our local structure to it. */ | |
509 uart = SDC_Port_List[receive]; | |
510 vector_found = NU_TRUE; | |
511 } | |
512 } | |
513 | |
514 #ifdef NU_ENABLE_PPP | |
515 | |
516 /* Find the device for this interrupt */ | |
517 if ( (device = DEV_Get_Dev_For_Vector(vector)) != NU_NULL) | |
518 { | |
519 /* Get the address of the uart structure for this device. */ | |
520 uart = &((PPP_LAYER *) device->ppp_layer)->uart; | |
521 vector_found = NU_TRUE; | |
522 } | |
523 | |
524 #endif /* NU_ENABLE_PPP */ | |
525 | |
526 if (vector_found == NU_TRUE) | |
527 { | |
528 /**************** Begin Port Specific Section **************/ | |
529 | |
530 /* Get the interrupt status register value */ | |
531 int_status = SD_INBYTE(uart->base_address + IIR_OFFSET); | |
532 | |
533 /* Loop until all interrupts are processed */ | |
534 while (!(int_status & IIR_PENDING)) | |
535 { | |
536 /* Check for a receive interrupt */ | |
537 if (((int_status & IIR_RX_LINE_STAT) ==IIR_RX_LINE_STAT) || | |
538 ((int_status & IIR_RX_RDY) ==IIR_RX_RDY) || | |
539 ((int_status & IIR_RX_TIMEOUT) ==IIR_RX_TIMEOUT) ) | |
540 { | |
541 /* Process every character in the receive FIFO */ | |
542 status = SD_INBYTE(uart->base_address + LSR_OFFSET); | |
543 | |
544 while (status & LSR_RX_DATA_READY) | |
545 { | |
546 /* Get character from receive FIFO */ | |
547 receive = SD_INBYTE (uart->base_address + RHR_OFFSET); | |
548 | |
549 /* Check if receive character has errors */ | |
550 if (status & (LSR_FRAMING_ERROR | LSR_PARITY_ERROR)) | |
551 { | |
552 /* Increment parity errors if necessary */ | |
553 uart->parity_errors += ((status & LSR_PARITY_ERROR) == LSR_PARITY_ERROR); | |
554 | |
555 /* Increment framing errors if necessary */ | |
556 uart->frame_errors += ((status & LSR_FRAMING_ERROR) == LSR_FRAMING_ERROR); | |
557 } | |
558 else // no framing or parity errors | |
559 { | |
560 /* Increment overrun errors if necessary */ | |
561 uart->overrun_errors += ((status & LSR_RX_DATA_READY) == LSR_RX_DATA_READY); | |
562 | |
563 /* Switch based on UART mode */ | |
564 switch(uart->communication_mode) | |
565 { | |
566 case SERIAL_MODE: | |
567 | |
568 if (uart->rx_buffer_status != NU_BUFFER_FULL) | |
569 { | |
570 | |
571 /* Put the character into the buffer */ | |
572 uart->rx_buffer[uart->rx_buffer_write++] = receive; | |
573 | |
574 /* Check for wrap of buffer. */ | |
575 if(uart->rx_buffer_write == uart->sd_buffer_size) | |
576 uart->rx_buffer_write = 0; | |
577 | |
578 /* Set status field based on latest character */ | |
579 if (uart->rx_buffer_write == uart->rx_buffer_read) | |
580 uart->rx_buffer_status = NU_BUFFER_FULL; | |
581 else | |
582 uart->rx_buffer_status = NU_BUFFER_DATA; | |
583 } | |
584 else | |
585 uart->busy_errors++; | |
586 | |
587 break; | |
588 | |
589 #ifdef NU_ENABLE_PPP | |
590 /* call PPP processing functions */ | |
591 | |
592 case MDM_NETWORK_COMMUNICATION: | |
593 /* Call this devices receive routine */ | |
594 device->dev_receive(device); | |
595 break; | |
596 | |
597 case MDM_TERMINAL_COMMUNICATION: | |
598 default: | |
599 MDM_Receive(device); | |
600 break; | |
601 #endif /* NU_ENABLE_PPP */ | |
602 } | |
603 } | |
604 | |
605 /* Check the rx buffer status again... */ | |
606 status = SD_INBYTE(uart->base_address + LSR_OFFSET); | |
607 | |
608 } | |
609 | |
610 } // if ((status & IIR_TYPE_MASK) == IIR_Rx_Rdy) | |
611 | |
612 | |
613 int_status = SD_INBYTE(uart->base_address + IER_OFFSET); | |
614 | |
615 if (int_status & IER_TX_HOLDING_REG) | |
616 { | |
617 if (uart->communication_mode == SERIAL_MODE) | |
618 { | |
619 /* Bump the read pointer past the byte that was just | |
620 transmitted. */ | |
621 ++(uart->tx_buffer_read); | |
622 | |
623 /* Check for wrap of buffer. */ | |
624 if(uart->tx_buffer_read == uart->sd_buffer_size) | |
625 uart->tx_buffer_read = 0; | |
626 | |
627 /* Update the status. */ | |
628 if (uart->tx_buffer_write == uart->tx_buffer_read) | |
629 { | |
630 uart->tx_buffer_status = NU_BUFFER_EMPTY; | |
631 | |
632 /* Since it is now empty disable the TX interrupt! */ | |
633 ier_val = SD_INBYTE(uart->base_address + IER_OFFSET); | |
634 ier_val &= ~IER_TX_HOLDING_REG; | |
635 SD_OUTBYTE(uart->base_address + IER_OFFSET, ier_val); | |
636 } | |
637 else | |
638 { | |
639 | |
640 /* Wait until the transmitter buffer is empty */ | |
641 while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY)); | |
642 | |
643 /* Send the next byte in the queue. */ | |
644 SD_OUTBYTE(uart->base_address + THR_OFFSET, uart->tx_buffer[uart->tx_buffer_read]); | |
645 | |
646 /* Update the status. */ | |
647 uart->tx_buffer_status = NU_BUFFER_DATA; | |
648 } | |
649 } | |
650 #ifdef NU_ENABLE_PPP | |
651 else | |
652 { | |
653 #ifndef PPP_POLLED_TX | |
654 /* Check for a transmit interrupt. */ | |
655 /* Is there another byte in the TX buffer to send? */ | |
656 if (uart->tx_buffer_read != uart->tx_buffer_write) | |
657 { | |
658 /* Wait until the transmitter buffer is empty */ | |
659 while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY)); | |
660 | |
661 /* Send the next byte in the queue. */ | |
662 SD_OUTBYTE (uart->base_address + THR_OFFSET, uart->tx_buffer[uart->tx_buffer_read++]); | |
663 | |
664 /* Check for wrap of buffer. */ | |
665 uart->tx_buffer_read %= uart->sd_buffer_size; | |
666 } | |
667 else | |
668 { | |
669 | |
670 /* Since it is now empty disable the TX interrupt! */ | |
671 ier_val = SD_INBYTE (uart->base_address + IER_OFFSET); | |
672 ier_val &= ~IER_TX_HOLDING_REG; | |
673 SD_OUTBYTE (uart->base_address + IER_OFFSET, ier_val); | |
674 | |
675 /* Only activate the HISR if we are tranmitting | |
676 network data. */ | |
677 if (uart->communication_mode == MDM_NETWORK_COMMUNICATION) | |
678 { | |
679 /* Add this device to the list of PPP devices that have finished | |
680 sending a packet. */ | |
681 _ppp_tx_dev_ptr_queue [_ppp_tx_dev_ptr_queue_write++] = device; | |
682 | |
683 /* Activate the HISR that will take care of processing the | |
684 next packet in queue, if one is ready. */ | |
685 NU_Activate_HISR (&PPP_TX_HISR); | |
686 | |
687 /* Check for wrap of ring buffer. */ | |
688 | |
689 _ppp_tx_dev_ptr_queue_write %= PPP_MAX_TX_QUEUE_PTRS; | |
690 | |
691 } | |
692 } | |
693 #endif /* PPP_POLLED_TX */ | |
694 } | |
695 #endif /* NU_ENABLE_PPP */ | |
696 } | |
697 | |
698 /* Get the interrupt status register value */ | |
699 int_status = SD_INBYTE(uart->base_address + IIR_OFFSET); | |
700 } | |
701 | |
702 /**************** End Port Specific Section **************/ | |
703 | |
704 /* No port is associated with the vector */ | |
705 } | |
706 else | |
707 { | |
708 ERC_System_Error(NU_UNHANDLED_INTERRUPT); | |
709 } | |
710 } | |
711 | |
712 /**************************************************************************** | |
713 * FUNCTION | |
714 * | |
715 * SDC_Set_Baud_Rate | |
716 * | |
717 * DESCRIPTION | |
718 * | |
719 * This function sets the UART buad rate. | |
720 * | |
721 * INPUTS | |
722 * | |
723 * UINT32 : The new baud rate. | |
724 * SD_PORT * : Serial port to set the baud rate. | |
725 * | |
726 * OUTPUTS | |
727 * | |
728 * none | |
729 * | |
730 ****************************************************************************/ | |
731 VOID SDC_Set_Baud_Rate(UINT32 baud_rate, SD_PORT *uart) | |
732 { | |
733 UNSIGNED baud_div; | |
734 UINT32 temp_long; | |
735 | |
736 /**************** Begin Port Specific Section **************/ | |
737 | |
738 /* Write to the divisor latch bit to enable the DLH and DLL registers */ | |
739 temp_long = SD_INBYTE(uart->base_address + LCR_OFFSET); | |
740 SD_OUTBYTE (uart->base_address + LCR_OFFSET, LCR_DIV_EN); | |
741 | |
742 /* Set the baud rate */ | |
743 baud_div = 115200 * 7 / uart->baud_rate; | |
744 | |
745 /* Put LSB in DLL Reg */ | |
746 SD_OUTBYTE (uart->base_address + DLL_OFFSET, baud_div); | |
747 | |
748 /* Put MSB in DLH Reg */ | |
749 SD_OUTBYTE (uart->base_address + DLH_OFFSET, (baud_div >> 8)); | |
750 | |
751 /* Disable the Divisor Latch bit */ | |
752 SD_OUTBYTE (uart->base_address + LCR_OFFSET, temp_long & ~LCR_DIV_EN); | |
753 /**************** End Port Specific Section ****************/ | |
754 | |
755 } | |
756 /**************************************************************************** | |
757 * FUNCTION | |
758 * | |
759 * SDC_Get_Char | |
760 * | |
761 * DESCRIPTION | |
762 * | |
763 * This function reads the last received character from the UART. | |
764 * | |
765 * INPUTS | |
766 * | |
767 * SD_PORT * : Serial port to get the char from. | |
768 * | |
769 * OUTPUTS | |
770 * | |
771 * CHAR : Character read | |
772 * | |
773 ****************************************************************************/ | |
774 CHAR SDC_Get_Char(SD_PORT *uart) | |
775 { | |
776 CHAR ch = NU_NULL; | |
777 | |
778 #ifdef GRAFIX_MOUSE | |
779 if ((uart->communication_mode == SERIAL_MODE) || | |
780 (uart->communication_mode == SERIAL_MOUSE)) | |
781 #else | |
782 if (uart->communication_mode == SERIAL_MODE) | |
783 #endif | |
784 | |
785 { | |
786 if ((uart->rx_buffer_status == NU_BUFFER_FULL) || | |
787 (uart->rx_buffer_status == NU_BUFFER_DATA)) | |
788 { | |
789 /* Store the character to be returned */ | |
790 ch = uart->rx_buffer[uart->rx_buffer_read++]; | |
791 | |
792 /* If read pointer is at end, wrap it around */ | |
793 if (uart->rx_buffer_read == uart->sd_buffer_size) | |
794 uart->rx_buffer_read = 0; | |
795 | |
796 /* Set the status to reflect removal of the character */ | |
797 if (uart->rx_buffer_write == uart->rx_buffer_read) | |
798 uart->rx_buffer_status = NU_BUFFER_EMPTY; | |
799 else | |
800 uart->rx_buffer_status = NU_BUFFER_DATA; | |
801 } | |
802 | |
803 return (ch); | |
804 } /* endif mode */ | |
805 | |
806 #ifdef NU_ENABLE_PPP | |
807 else if (uart->communication_mode == MDM_TERMINAL_COMMUNICATION || | |
808 uart->communication_mode == MDM_NETWORK_COMMUNICATION) | |
809 | |
810 /**************** Begin Port Specific Section **************/ | |
811 | |
812 return ((UINT8)SD_INBYTE (uart->base_address + RHR_OFFSET)); | |
813 | |
814 /**************** End Port Specific Section ****************/ | |
815 | |
816 #endif /* NU_ENABLE_PPP */ | |
817 | |
818 /* Execution should never reach this point, this return was added | |
819 in response to the 'implicit return' compiler warning */ | |
820 | |
821 return (ch); | |
822 } | |
823 | |
824 /**************************************************************************** | |
825 * FUNCTION | |
826 * | |
827 * SDC_Carrier | |
828 * | |
829 * DESCRIPTION | |
830 * | |
831 * This function checks for a carrier. | |
832 * | |
833 * INPUTS | |
834 * | |
835 * none | |
836 * | |
837 * OUTPUTS | |
838 * | |
839 * STATUS : The status of the detection. | |
840 * | |
841 ****************************************************************************/ | |
842 STATUS SDC_Carrier(SD_PORT *uart) | |
843 { | |
844 return (NU_TRUE); | |
845 } | |
846 | |
847 /**************************************************************************** | |
848 Note: All functions below this point are generic and should not require | |
849 any changes to support other UARTS. | |
850 ****************************************************************************/ | |
851 | |
852 /**************************************************************************** | |
853 * FUNCTION | |
854 * | |
855 * SDC_Put_String | |
856 * | |
857 * DESCRIPTION | |
858 * | |
859 * This writes a null-terminated string out to the serial port. | |
860 * | |
861 * INPUTS | |
862 * | |
863 * CHAR * : String to be written to the serial port. | |
864 * SD_PORT * : Serial port to send the string to. | |
865 * | |
866 * OUTPUTS | |
867 * | |
868 * none | |
869 * | |
870 ****************************************************************************/ | |
871 VOID SDC_Put_String(CHAR *str, SD_PORT *uart) | |
872 { | |
873 | |
874 /* Grab the semaphore so that strings between threads | |
875 do not get mixed. */ | |
876 if (NU_Obtain_Semaphore(uart->sd_semaphore, NU_SUSPEND) == NU_SUCCESS) | |
877 { | |
878 | |
879 /* Send out the string. */ | |
880 for (; *str != 0; str++) | |
881 SDC_Put_Char(*str, uart); | |
882 | |
883 /* Allow other threads to use this service. */ | |
884 NU_Release_Semaphore (uart->sd_semaphore); | |
885 } | |
886 | |
887 } | |
888 | |
889 | |
890 /**************************************************************************** | |
891 * FUNCTION | |
892 * | |
893 * SDC_Data_Ready | |
894 * | |
895 * DESCRIPTION | |
896 * | |
897 * This function checks to see if there are any characters in the | |
898 * receive buffer. A status value is returned indicating whether | |
899 * characters are present in the receive buffer. | |
900 * | |
901 * INPUTS | |
902 * | |
903 * SD_PORT * : Serial port to check for data. | |
904 * | |
905 * OUTPUTS | |
906 * | |
907 * STATUS The status indicates the | |
908 * presence of characters. | |
909 * | |
910 ****************************************************************************/ | |
911 STATUS SDC_Data_Ready(SD_PORT *port) | |
912 { | |
913 /* Check the status. */ | |
914 if((port->rx_buffer_status == NU_BUFFER_FULL) || | |
915 (port->rx_buffer_status == NU_BUFFER_DATA)) | |
916 | |
917 return (NU_TRUE); | |
918 | |
919 else | |
920 | |
921 return (NU_FALSE); | |
922 } | |
923 | |
924 /**************************************************************************** | |
925 * FUNCTION | |
926 * | |
927 * SDC_Change_Communication_Mode | |
928 * | |
929 * DESCRIPTION | |
930 * | |
931 * This function switches the serial port between terminal mode and | |
932 * network mode. The mode affects how incoming characters are directed. | |
933 * | |
934 * INPUTS | |
935 * | |
936 * INT : The mode of operation desired. | |
937 * | |
938 * OUTPUTS | |
939 * | |
940 * none | |
941 * | |
942 ****************************************************************************/ | |
943 VOID SDC_Change_Communication_Mode(INT mode, SD_PORT *uart) | |
944 { | |
945 uart->communication_mode = mode; | |
946 | |
947 } /* SDC_Change_Communication_Mode */ | |
948 | |
949 /**************************************************************************** | |
950 * FUNCTION | |
951 * | |
952 * SDC_Reset | |
953 * | |
954 * DESCRIPTION | |
955 * | |
956 * This function intializes the data variables associated with a UART | |
957 * | |
958 * INPUTS | |
959 * | |
960 * SD_PORT * : Serial port to reset | |
961 * | |
962 * OUTPUTS | |
963 * | |
964 * STATUS : Returns URT_SUCCESS if successful initialization, | |
965 * else a negative value is returned. | |
966 * | |
967 ****************************************************************************/ | |
968 VOID SDC_Reset (SD_PORT *uart) | |
969 { | |
970 /* Ini the error counters */ | |
971 uart->frame_errors = 0; | |
972 uart->overrun_errors = 0; | |
973 uart->parity_errors = 0; | |
974 uart->busy_errors = 0; | |
975 uart->general_errors = 0; | |
976 } | |
977 | |
978 /*************************************************************************** | |
979 * FUNCTION | |
980 * | |
981 * URT_Init_Port | |
982 * | |
983 * DESCRIPTION | |
984 * | |
985 * This function intializes the data variables associated with a UART | |
986 * | |
987 * INPUTS | |
988 * | |
989 * SD_PORT * : Serial port to reset | |
990 * | |
991 * OUTPUTS | |
992 * | |
993 * STATUS : Returns URT_SUCCESS if successful initialization, | |
994 * else a negative value is returned. | |
995 * | |
996 ****************************************************************************/ | |
997 #ifdef NU_ENABLE_PPP | |
998 STATUS URT_Init_Port(DV_DEVICE_ENTRY *device) | |
999 { | |
1000 SD_PORT *uart; | |
1001 STATUS ret_status; | |
1002 | |
1003 /* Get a pointer to the UART layer of this device. */ | |
1004 uart = &((PPP_LAYER *) device->ppp_layer)->uart; | |
1005 | |
1006 /* Init the serial port, copy init parameters from the device | |
1007 structure. */ | |
1008 uart->com_port = device->dev_com_port; | |
1009 uart->baud_rate = device->dev_baud_rate; | |
1010 uart->data_bits = device->dev_data_bits; | |
1011 uart->stop_bits = device->dev_stop_bits; | |
1012 uart->parity = device->dev_parity; | |
1013 uart->data_mode = device->dev_data_mode; | |
1014 uart->vector = device->dev_vect; | |
1015 uart->driver_options = device->dev_driver_options; | |
1016 uart->communication_mode = MDM_TERMINAL_COMMUNICATION; | |
1017 uart->sd_buffer_size = (2 * (PPP_MTU + PPP_FCS_SIZE + | |
1018 PPP_MAX_PROTOCOL_SIZE + PPP_MAX_ADDR_CONTROL_SIZE)); | |
1019 | |
1020 /* Init the port */ | |
1021 ret_status = NU_SD_Init_Port (uart); | |
1022 | |
1023 if (ret_status == NU_SUCCESS) | |
1024 { | |
1025 /* Copy the vector back into the device entry just in case | |
1026 the UART driver changed it. */ | |
1027 device->dev_vect = uart->vector; | |
1028 } | |
1029 | |
1030 return (ret_status); | |
1031 | |
1032 } | |
1033 #endif /* NU_ENABLE_PPP */ |