00001 00007 /* Embedded XINU, Copyright (C) 2007. All rights reserved. */ 00008 00009 #include <kernel.h> 00010 #include <uart.h> 00011 #include <device.h> 00012 00020 devcall uartWrite(device *pdev, unsigned char *buf, int len) 00021 { 00022 irqmask ps; 00023 int count = 0; 00024 struct uart *puart; 00025 volatile struct uart_csreg *pucsr; 00026 00027 /* Setup and error check pointers to structures */ 00028 if (NULL == pdev) { return SYSERR; } 00029 00030 puart = (struct uart *)pdev->controlblk; 00031 if (NULL == puart) { return SYSERR; } 00032 00033 pucsr = puart->csr; 00034 if (NULL == pucsr) { return SYSERR; } 00035 00036 ps = disable(); 00037 00038 /* If in non-blocking mode, ensure there is enough space for the entire 00039 * write request */ 00040 if (puart->oflags & UART_OFLAG_NOBLOCK) 00041 { 00042 if (scount(puart->osema) < len) { restore(ps); return SYSERR; } 00043 } 00044 00045 /* Put each character from the buffer into the output buffer for the 00046 * lower half */ 00047 while (count < len) 00048 { 00049 /* If in non-blocking mode, ensure there is another byte of space 00050 * for output */ 00051 if (puart->oflags & UART_OFLAG_NOBLOCK) 00052 { 00053 if (scount(puart->osema) < 1) { break; } 00054 } 00055 00056 /* If the UART transmitter hardware is idle, write directly to the 00057 * hardware */ 00058 if (puart->oidle) 00059 { 00060 puart->oidle = 0; 00061 pucsr->thr = *buf++; 00062 count++; 00063 puart->cout++; 00064 } 00065 /* Wait for space and place character in the output buffer for the 00066 * lower half; Preserve the circular buffer */ 00067 else 00068 { 00069 wait(puart->osema); 00070 puart->out[(puart->ostart + puart->ocount) % UART_OBLEN] = *buf++; 00071 count++; 00072 puart->ocount++; 00073 } 00074 } 00075 00076 restore(ps); 00077 return count; 00078 }