comparison nuc-fw/nucleus/sdc.c @ 79:947b1f473960

beginning of nuc-fw
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 11 Aug 2013 07:17:25 +0000
parents
children
comparison
equal deleted inserted replaced
78:2c266d4339ff 79:947b1f473960
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 */