1 /*--------------------------------------------------------------------
2 * TITLE: Plasma Uart Driver
3 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4 * DATE CREATED: 12/31/05
6 * PROJECT: Plasma CPU core
7 * COPYRIGHT: Software placed into the public domain by the author.
8 * Software 'as is' without warranty. Author liable for nothing.
11 *--------------------------------------------------------------------*/
17 #define SUPPORT_DATA_PACKETS
20 #define BUFFER_WRITE_SIZE 128
21 #define BUFFER_READ_SIZE 128
22 #define BUFFER_PRINTF_SIZE 1024
25 void UartPrintfCritical(const char *format,
26 int arg0, int arg1, int arg2, int arg3,
27 int arg4, int arg5, int arg6, int arg7);
29 typedef struct Buffer_s {
32 volatile int read, write;
33 volatile int pendingRead, pendingWrite;
34 OS_Semaphore_t *semaphoreRead, *semaphoreWrite;
37 static Buffer_t *WriteBuffer, *ReadBuffer;
38 static OS_Semaphore_t *SemaphoreUart;
39 static char PrintfString[BUFFER_PRINTF_SIZE]; //Used in UartPrintf
41 #ifdef SUPPORT_DATA_PACKETS
42 //For packet processing [0xff lengthMSB lengthLSB checksum data]
43 static PacketGetFunc_t UartPacketGet;
44 static uint8 *PacketCurrent;
45 static uint32 UartPacketSize;
46 static uint32 UartPacketChecksum, Checksum;
47 static OS_MQueue_t *UartPacketMQueue;
48 static uint32 PacketBytes, PacketLength;
49 static uint32 UartPacketOutLength, UartPacketOutByte;
50 int CountOk, CountError;
52 static uint8 *UartPacketOut;
55 /******************************************/
56 Buffer_t *BufferCreate(int size)
59 buffer = (Buffer_t*)OS_HeapMalloc(NULL, sizeof(Buffer_t) + size);
62 buffer->data = (uint8*)(buffer + 1);
66 buffer->pendingRead = 0;
67 buffer->pendingWrite = 0;
68 buffer->semaphoreRead = OS_SemaphoreCreate("BufferRead", 0);
69 buffer->semaphoreWrite = OS_SemaphoreCreate("BufferWrite", 0);
74 void BufferWrite(Buffer_t *buffer, int value, int pend)
78 writeNext = buffer->write + 1;
79 if(writeNext >= buffer->size)
82 //Check if room for value
83 if(writeNext == buffer->read)
87 ++buffer->pendingWrite;
88 OS_SemaphorePend(buffer->semaphoreWrite, OS_WAIT_FOREVER);
91 buffer->data[buffer->write] = (uint8)value;
92 buffer->write = writeNext;
93 if(buffer->pendingRead)
95 --buffer->pendingRead;
96 OS_SemaphorePost(buffer->semaphoreRead);
101 int BufferRead(Buffer_t *buffer, int pend)
105 //Check if empty buffer
106 if(buffer->read == buffer->write)
110 ++buffer->pendingRead;
111 OS_SemaphorePend(buffer->semaphoreRead, OS_WAIT_FOREVER);
114 value = buffer->data[buffer->read];
115 if(++buffer->read >= buffer->size)
117 if(buffer->pendingWrite)
119 --buffer->pendingWrite;
120 OS_SemaphorePost(buffer->semaphoreWrite);
126 /******************************************/
127 #ifdef SUPPORT_DATA_PACKETS
128 static void UartPacketRead(uint32 value)
131 if(PacketBytes == 0 && value == 0xff)
135 else if(PacketBytes == 1)
138 PacketLength = value << 8;
140 else if(PacketBytes == 2)
143 PacketLength |= value;
144 if(PacketLength <= UartPacketSize)
146 if(PacketCurrent == NULL)
147 PacketCurrent = UartPacketGet();
154 else if(PacketBytes == 3)
157 UartPacketChecksum = value;
160 else if(PacketBytes >= 4)
163 PacketCurrent[PacketBytes - 4] = (uint8)value;
166 if(PacketBytes - 4 >= PacketLength)
168 if((uint8)Checksum == UartPacketChecksum)
170 //Notify thread that a packet has been received
173 message[1] = (uint32)PacketCurrent;
174 message[2] = PacketLength;
176 OS_MQueueSend(UartPacketMQueue, message);
177 PacketCurrent = NULL;
190 static int UartPacketWrite(void)
196 if(UartPacketOutByte == 0)
201 else if(UartPacketOutByte == 1)
203 value = UartPacketOutLength >> 8;
206 else if(UartPacketOutByte == 2)
208 value = (uint8)UartPacketOutLength;
211 else if(UartPacketOutByte == 3)
214 for(i = 0; i < (int)UartPacketOutLength; ++i)
215 value += UartPacketOut[i];
216 value = (uint8)value;
221 value = UartPacketOut[UartPacketOutByte - 4];
223 if(UartPacketOutByte - 4 >= UartPacketOutLength)
225 //Notify thread that a packet has been sent
227 message[1] = (uint32)UartPacketOut;
229 OS_MQueueSend(UartPacketMQueue, message);
238 static void UartInterrupt(void *arg)
240 uint32 status, value, count=0;
243 status = OS_InterruptStatus();
244 while(status & IRQ_UART_READ_AVAILABLE)
246 value = MemoryRead(UART_READ);
247 #ifdef SUPPORT_DATA_PACKETS
248 if(UartPacketGet && (value == 0xff || PacketBytes))
249 UartPacketRead(value);
252 BufferWrite(ReadBuffer, value, 0);
253 status = OS_InterruptStatus();
257 while(status & IRQ_UART_WRITE_AVAILABLE)
259 #ifdef SUPPORT_DATA_PACKETS
262 value = UartPacketWrite();
263 MemoryWrite(UART_WRITE, value);
266 if(WriteBuffer->read != WriteBuffer->write)
268 value = BufferRead(WriteBuffer, 0);
269 MemoryWrite(UART_WRITE, value);
273 OS_InterruptMaskClear(IRQ_UART_WRITE_AVAILABLE);
276 status = OS_InterruptStatus();
285 SemaphoreUart = OS_SemaphoreCreate("Uart", 1);
286 WriteBuffer = BufferCreate(BUFFER_WRITE_SIZE);
287 ReadBuffer = BufferCreate(BUFFER_READ_SIZE);
289 mask = IRQ_UART_READ_AVAILABLE | IRQ_UART_WRITE_AVAILABLE;
290 OS_InterruptRegister(mask, UartInterrupt);
291 OS_InterruptMaskSet(IRQ_UART_READ_AVAILABLE);
295 void UartWrite(int ch)
297 BufferWrite(WriteBuffer, ch, 1);
298 OS_InterruptMaskSet(IRQ_UART_WRITE_AVAILABLE);
304 return (uint8)BufferRead(ReadBuffer, 1);
308 void UartWriteData(uint8 *data, int length)
310 OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
313 OS_SemaphorePost(SemaphoreUart);
317 void UartReadData(uint8 *data, int length)
319 OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
321 *data++ = UartRead();
322 OS_SemaphorePost(SemaphoreUart);
326 void UartPrintf(const char *format,
327 int arg0, int arg1, int arg2, int arg3,
328 int arg4, int arg5, int arg6, int arg7)
332 //Check for string "!m#~" to mask print statement
333 static char moduleLevel[26];
334 if(format[0] == '!' && format[3] == '~')
336 int level = format[2] - '5';
337 if('a' <= format[1] && format[1] <= 'z')
339 if(level < moduleLevel[format[1] - 'a'])
342 else if('A' <= format[1] && format[1] <= 'Z')
343 moduleLevel[format[1] - 'A'] = (char)level;
347 OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
348 sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
349 arg4, arg5, arg6, arg7);
350 ptr = (uint8*)PrintfString;
355 #ifdef SUPPORT_DATA_PACKETS
361 OS_SemaphorePost(SemaphoreUart);
365 void UartPrintfPoll(const char *format,
366 int arg0, int arg1, int arg2, int arg3,
367 int arg4, int arg5, int arg6, int arg7)
373 OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
374 sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
375 arg4, arg5, arg6, arg7);
376 ptr = (uint8*)PrintfString;
379 while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0)
381 state = OS_CriticalBegin();
382 if((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) &&
383 UartPacketOut == NULL)
385 MemoryWrite(UART_WRITE, *ptr++);
387 OS_CriticalEnd(state);
390 OS_SemaphorePost(SemaphoreUart);
394 void UartPrintfCritical(const char *format,
395 int arg0, int arg1, int arg2, int arg3,
396 int arg4, int arg5, int arg6, int arg7)
401 state = OS_CriticalBegin();
402 sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
403 arg4, arg5, arg6, arg7);
404 ptr = (uint8*)PrintfString;
407 while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0)
409 MemoryWrite(UART_WRITE, *ptr++);
410 #ifdef SUPPORT_DATA_PACKETS
411 if(UartPacketOut && UartPacketOutByte - 4 < UartPacketOutLength)
418 memset(PrintfString, 0, sizeof(PrintfString));
419 OS_CriticalEnd(state);
423 void UartPrintfNull(void)
428 void UartScanf(const char *format,
429 int arg0, int arg1, int arg2, int arg3,
430 int arg4, int arg5, int arg6, int arg7)
433 OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
437 if(ch != '\b' || index)
439 if(ch == '\n' || ch == '\r')
450 else if(index < sizeof(PrintfString))
451 PrintfString[index++] = (uint8)ch;
454 PrintfString[index] = 0;
455 sscanf(PrintfString, format, arg0, arg1, arg2, arg3,
456 arg4, arg5, arg6, arg7);
457 OS_SemaphorePost(SemaphoreUart);
461 #ifdef SUPPORT_DATA_PACKETS
462 void UartPacketConfig(PacketGetFunc_t PacketGetFunc,
466 UartPacketGet = PacketGetFunc;
467 UartPacketSize = PacketSize;
468 UartPacketMQueue = mQueue;
472 void UartPacketSend(uint8 *data, int bytes)
474 UartPacketOutByte = 0;
475 UartPacketOutLength = bytes;
476 UartPacketOut = data;
477 OS_InterruptMaskSet(IRQ_UART_WRITE_AVAILABLE);
480 void UartPacketConfig(PacketGetFunc_t PacketGetFunc,
483 { (void)PacketGetFunc; (void)PacketSize; (void)mQueue; }
486 void UartPacketSend(uint8 *data, int bytes)
487 { (void)data; (void)bytes; }
491 void Led(int mask, int value)
494 MemoryWrite(GPIO0_CLEAR, mask); //clear
495 MemoryWrite(GPIO0_OUT, value & mask); //set LEDs
499 /******************************************/
500 int puts(const char *string)
503 OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
504 ptr = (uint8*)string;
511 OS_SemaphorePost(SemaphoreUart);
518 return BufferRead(ReadBuffer, 1);
524 return ReadBuffer->read != ReadBuffer->write;
528 /******************************************/
530 int LogArray[100], LogIndex;
533 if(LogIndex < sizeof(LogArray)/4)
534 LogArray[LogIndex++] = a;
540 for(i = 0; i < LogIndex; ++i)
542 if(LogArray[i] > 0xfff)
543 UartPrintfCritical("\n", 0,0,0,0,0,0,0,0);
544 UartPrintfCritical("0x%x ", LogArray[i], 0,0,0,0,0,0,0);