OpenCores
URL https://opencores.org/ocsvn/mlite/mlite/trunk

Subversion Repositories mlite

[/] [mlite/] [trunk/] [kernel/] [uart.c] - Blame information for rev 253

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 138 rhoads
/*--------------------------------------------------------------------
2
 * TITLE: Plasma Uart Driver
3
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
 * DATE CREATED: 12/31/05
5
 * FILENAME: uart.c
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.
9
 * DESCRIPTION:
10
 *    Plasma Uart Driver
11
 *--------------------------------------------------------------------*/
12
#define NO_ELLIPSIS2
13
#include "plasma.h"
14
#include "rtos.h"
15
 
16 152 rhoads
#define SUPPORT_DATA_PACKETS
17
 
18 138 rhoads
#define BUFFER_WRITE_SIZE 128
19
#define BUFFER_READ_SIZE 128
20 152 rhoads
#define BUFFER_PRINTF_SIZE 1024
21 138 rhoads
#undef UartPrintf
22
 
23 188 rhoads
void UartPrintfCritical(const char *format,
24
                        int arg0, int arg1, int arg2, int arg3,
25
                        int arg4, int arg5, int arg6, int arg7);
26
 
27 138 rhoads
typedef struct Buffer_s {
28
   uint8 *data;
29
   int size;
30
   volatile int read, write;
31
   volatile int pendingRead, pendingWrite;
32
   OS_Semaphore_t *semaphoreRead, *semaphoreWrite;
33
} Buffer_t;
34
 
35
static Buffer_t *WriteBuffer, *ReadBuffer;
36
static OS_Semaphore_t *SemaphoreUart;
37
static char PrintfString[BUFFER_PRINTF_SIZE];  //Used in UartPrintf
38
 
39 152 rhoads
#ifdef SUPPORT_DATA_PACKETS
40
//For packet processing [0xff lengthMSB lengthLSB checksum data]
41
static PacketGetFunc_t UartPacketGet;
42
static uint8 *PacketCurrent;
43
static uint32 UartPacketSize;
44
static uint32 UartPacketChecksum, Checksum;
45
static OS_MQueue_t *UartPacketMQueue;
46
static uint32 PacketBytes, PacketLength;
47
static uint32 UartPacketOutLength, UartPacketOutByte;
48
int CountOk, CountError;
49
#endif
50
static uint8 *UartPacketOut;
51 138 rhoads
 
52 152 rhoads
 
53 138 rhoads
/******************************************/
54
Buffer_t *BufferCreate(int size)
55
{
56
   Buffer_t *buffer;
57
   buffer = (Buffer_t*)OS_HeapMalloc(NULL, sizeof(Buffer_t) + size);
58
   if(buffer == NULL)
59
      return NULL;
60
   buffer->data = (uint8*)(buffer + 1);
61
   buffer->read = 0;
62
   buffer->write = 0;
63
   buffer->size = size;
64
   buffer->pendingRead = 0;
65
   buffer->pendingWrite = 0;
66
   buffer->semaphoreRead = OS_SemaphoreCreate("BufferRead", 0);
67
   buffer->semaphoreWrite = OS_SemaphoreCreate("BufferWrite", 0);
68
   return buffer;
69
}
70
 
71
 
72 188 rhoads
void BufferWrite(Buffer_t *buffer, int value, int pend)
73 138 rhoads
{
74
   int writeNext;
75
 
76 188 rhoads
   writeNext = buffer->write + 1;
77
   if(writeNext >= buffer->size)
78 138 rhoads
      writeNext = 0;
79
 
80
   //Check if room for value
81 188 rhoads
   if(writeNext == buffer->read)
82 138 rhoads
   {
83 188 rhoads
      if(pend == 0)
84 138 rhoads
         return;
85 188 rhoads
      ++buffer->pendingWrite;
86
      OS_SemaphorePend(buffer->semaphoreWrite, OS_WAIT_FOREVER);
87 138 rhoads
   }
88
 
89 188 rhoads
   buffer->data[buffer->write] = (uint8)value;
90
   buffer->write = writeNext;
91
   if(buffer->pendingRead)
92 138 rhoads
   {
93 188 rhoads
      --buffer->pendingRead;
94
      OS_SemaphorePost(buffer->semaphoreRead);
95 138 rhoads
   }
96
}
97
 
98
 
99 188 rhoads
int BufferRead(Buffer_t *buffer, int pend)
100 138 rhoads
{
101
   int value;
102
 
103
   //Check if empty buffer
104 188 rhoads
   if(buffer->read == buffer->write)
105 138 rhoads
   {
106 188 rhoads
      if(pend == 0)
107 138 rhoads
         return 0;
108 188 rhoads
      ++buffer->pendingRead;
109
      OS_SemaphorePend(buffer->semaphoreRead, OS_WAIT_FOREVER);
110 138 rhoads
   }
111
 
112 188 rhoads
   value = buffer->data[buffer->read];
113
   if(++buffer->read >= buffer->size)
114
      buffer->read = 0;
115
   if(buffer->pendingWrite)
116 138 rhoads
   {
117 188 rhoads
      --buffer->pendingWrite;
118
      OS_SemaphorePost(buffer->semaphoreWrite);
119 138 rhoads
   }
120
   return value;
121
}
122
 
123
 
124
/******************************************/
125 152 rhoads
#ifdef SUPPORT_DATA_PACKETS
126
static void UartPacketRead(uint32 value)
127
{
128
   uint32 message[4];
129
   if(PacketBytes == 0 && value == 0xff)
130
   {
131
      ++PacketBytes;
132
   }
133
   else if(PacketBytes == 1)
134
   {
135
      ++PacketBytes;
136
      PacketLength = value << 8;
137
   }
138
   else if(PacketBytes == 2)
139
   {
140
      ++PacketBytes;
141
      PacketLength |= value;
142
      if(PacketLength <= UartPacketSize)
143
         PacketCurrent = UartPacketGet();
144
      else
145
      {
146
         PacketCurrent = NULL;
147
         PacketBytes = 0;
148
      }
149
   }
150
   else if(PacketBytes == 3)
151
   {
152
      ++PacketBytes;
153
      UartPacketChecksum = value;
154
      Checksum = 0;
155
   }
156
   else if(PacketBytes >= 4)
157
   {
158
      if(PacketCurrent)
159
         PacketCurrent[PacketBytes - 4] = (uint8)value;
160
      Checksum += value;
161
      ++PacketBytes;
162
      if(PacketBytes - 4 >= PacketLength)
163
      {
164
         if((uint8)Checksum == UartPacketChecksum)
165
         {
166
            //Notify thread that a packet have been received
167
            ++CountOk;
168
            message[0] = 0;
169
            message[1] = (uint32)PacketCurrent;
170
            message[2] = PacketLength;
171
            if(PacketCurrent)
172
               OS_MQueueSend(UartPacketMQueue, message);
173
         }
174
         else
175
         {
176
            ++CountError;
177
            //printf("E");
178
         }
179
         PacketBytes = 0;
180
      }
181
   }
182
}
183
 
184
 
185
static int UartPacketWrite(void)
186
{
187
   int value=0, i;
188
   uint32 message[4];
189
   if(UartPacketOut)
190
   {
191
      if(UartPacketOutByte == 0)
192
      {
193
         value = 0xff;
194
         ++UartPacketOutByte;
195
      }
196
      else if(UartPacketOutByte == 1)
197
      {
198
         value = UartPacketOutLength >> 8;
199
         ++UartPacketOutByte;
200
      }
201
      else if(UartPacketOutByte == 2)
202
      {
203
         value = (uint8)UartPacketOutLength;
204
         ++UartPacketOutByte;
205
      }
206
      else if(UartPacketOutByte == 3)
207
      {
208
         value = 0;
209
         for(i = 0; i < (int)UartPacketOutLength; ++i)
210
            value += UartPacketOut[i];
211
         value = (uint8)value;
212
         ++UartPacketOutByte;
213
      }
214
      else
215
      {
216
         value = UartPacketOut[UartPacketOutByte - 4];
217
         ++UartPacketOutByte;
218
         if(UartPacketOutByte - 4 >= UartPacketOutLength)
219
         {
220
            //Notify thread that a packet has been sent
221
            message[0] = 1;
222
            message[1] = (uint32)UartPacketOut;
223
            UartPacketOut = 0;
224
            OS_MQueueSend(UartPacketMQueue, message);
225
         }
226
      }
227
   }
228
   return value;
229
}
230
#endif
231
 
232
 
233 188 rhoads
static void UartInterrupt(void *arg)
234 138 rhoads
{
235 152 rhoads
   uint32 status, value, count=0;
236 188 rhoads
   (void)arg;
237 138 rhoads
 
238
   status = OS_InterruptStatus();
239 152 rhoads
   while(status & IRQ_UART_READ_AVAILABLE)
240 138 rhoads
   {
241
      value = MemoryRead(UART_READ);
242 152 rhoads
#ifdef SUPPORT_DATA_PACKETS
243
      if(UartPacketGet && (value == 0xff || PacketBytes))
244
         UartPacketRead(value);
245
      else
246
#endif
247 138 rhoads
      BufferWrite(ReadBuffer, value, 0);
248 152 rhoads
      status = OS_InterruptStatus();
249
      if(++count >= 16)
250
         break;
251 138 rhoads
   }
252 152 rhoads
   while(status & IRQ_UART_WRITE_AVAILABLE)
253 138 rhoads
   {
254 152 rhoads
#ifdef SUPPORT_DATA_PACKETS
255
      if(UartPacketOut)
256
      {
257
         value = UartPacketWrite();
258
         MemoryWrite(UART_WRITE, value);
259
      } else
260
#endif
261 138 rhoads
      if(WriteBuffer->read != WriteBuffer->write)
262
      {
263
         value = BufferRead(WriteBuffer, 0);
264
         MemoryWrite(UART_WRITE, value);
265
      }
266
      else
267
      {
268
         OS_InterruptMaskClear(IRQ_UART_WRITE_AVAILABLE);
269 152 rhoads
         break;
270 138 rhoads
      }
271 152 rhoads
      status = OS_InterruptStatus();
272 138 rhoads
   }
273
}
274
 
275
 
276
void UartInit(void)
277
{
278
   uint32 mask;
279
 
280
   SemaphoreUart = OS_SemaphoreCreate("Uart", 1);
281
   WriteBuffer = BufferCreate(BUFFER_WRITE_SIZE);
282
   ReadBuffer = BufferCreate(BUFFER_READ_SIZE);
283
 
284
   mask = IRQ_UART_READ_AVAILABLE | IRQ_UART_WRITE_AVAILABLE;
285
   OS_InterruptRegister(mask, UartInterrupt);
286
   OS_InterruptMaskSet(IRQ_UART_READ_AVAILABLE);
287
}
288
 
289
 
290 188 rhoads
void UartWrite(int ch)
291 138 rhoads
{
292 188 rhoads
   BufferWrite(WriteBuffer, ch, 1);
293 138 rhoads
   OS_InterruptMaskSet(IRQ_UART_WRITE_AVAILABLE);
294
}
295
 
296
 
297
uint8 UartRead(void)
298
{
299
   return (uint8)BufferRead(ReadBuffer, 1);
300
}
301
 
302
 
303 188 rhoads
void UartWriteData(uint8 *data, int length)
304 138 rhoads
{
305
   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
306 188 rhoads
   while(length--)
307
      UartWrite(*data++);
308 138 rhoads
   OS_SemaphorePost(SemaphoreUart);
309
}
310
 
311
 
312 188 rhoads
void UartReadData(uint8 *data, int length)
313 138 rhoads
{
314
   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
315 188 rhoads
   while(length--)
316
      *data++ = UartRead();
317 138 rhoads
   OS_SemaphorePost(SemaphoreUart);
318
}
319
 
320
 
321
void UartPrintf(const char *format,
322
                int arg0, int arg1, int arg2, int arg3,
323
                int arg4, int arg5, int arg6, int arg7)
324
{
325
   uint8 *ptr;
326 234 rhoads
#if 0
327 253 rhoads
   //Check for string "!m#~" to mask print statement
328 234 rhoads
   static char moduleLevel[26];
329 253 rhoads
   if(format[0] == '!' && format[3] == '~')
330 234 rhoads
   {
331
      int level = format[2] - '5';
332 253 rhoads
      if('a' <= format[1] && format[1] <= 'z')
333 234 rhoads
      {
334 253 rhoads
         if(level < moduleLevel[format[1] - 'a'])
335
            return;
336 234 rhoads
      }
337 253 rhoads
      else if('A' <= format[1] && format[1] <= 'Z')
338
         moduleLevel[format[1] - 'A'] = (char)level;
339 234 rhoads
      format += 4;
340
   }
341
#endif
342 138 rhoads
   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
343
   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
344
           arg4, arg5, arg6, arg7);
345
   ptr = (uint8*)PrintfString;
346
   while(*ptr)
347
   {
348
      if(*ptr == '\n')
349
         UartWrite('\r');
350 158 rhoads
#ifdef SUPPORT_DATA_PACKETS
351 152 rhoads
      if(*ptr == 0xff)
352
         *ptr = '@';
353
#endif
354 138 rhoads
      UartWrite(*ptr++);
355
   }
356
   OS_SemaphorePost(SemaphoreUart);
357
}
358
 
359
 
360
void UartPrintfPoll(const char *format,
361
                    int arg0, int arg1, int arg2, int arg3,
362
                    int arg4, int arg5, int arg6, int arg7)
363
{
364
   uint8 *ptr;
365 152 rhoads
   uint32 state;
366 138 rhoads
 
367
   if(SemaphoreUart)
368
      OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
369
   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
370
           arg4, arg5, arg6, arg7);
371
   ptr = (uint8*)PrintfString;
372
   while(*ptr)
373
   {
374
      while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0)
375
         ;
376 152 rhoads
      state = OS_CriticalBegin();
377
      if((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) &&
378
         UartPacketOut == NULL)
379
      {
380
         MemoryWrite(UART_WRITE, *ptr++);
381
      }
382
      OS_CriticalEnd(state);
383 138 rhoads
   }
384
   if(SemaphoreUart)
385
      OS_SemaphorePost(SemaphoreUart);
386
}
387
 
388
 
389
void UartPrintfCritical(const char *format,
390
                        int arg0, int arg1, int arg2, int arg3,
391
                        int arg4, int arg5, int arg6, int arg7)
392
{
393
   uint8 *ptr;
394
   uint32 state;
395
 
396
   state = OS_CriticalBegin();
397
   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
398
           arg4, arg5, arg6, arg7);
399
   ptr = (uint8*)PrintfString;
400
   while(*ptr)
401
   {
402
      while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0)
403
         ;
404
      MemoryWrite(UART_WRITE, *ptr++);
405 152 rhoads
#ifdef SUPPORT_DATA_PACKETS
406
      if(UartPacketOut && UartPacketOutByte - 4 < UartPacketOutLength)
407
      {
408
         ++UartPacketOutByte;
409
         --ptr;
410
      }
411
#endif
412 138 rhoads
   }
413
   memset(PrintfString, 0, sizeof(PrintfString));
414
   OS_CriticalEnd(state);
415
}
416
 
417
 
418 163 rhoads
void UartPrintfNull(void)
419
{
420
}
421
 
422
 
423 138 rhoads
void UartScanf(const char *format,
424
               int arg0, int arg1, int arg2, int arg3,
425
               int arg4, int arg5, int arg6, int arg7)
426
{
427
   int index = 0, ch;
428
   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
429
   for(;;)
430
   {
431
      ch = UartRead();
432
      if(ch != '\b' || index)
433
         UartWrite(ch);
434
      if(ch == '\n' || ch == '\r')
435
         break;
436
      else if(ch == '\b')
437
      {
438
         if(index)
439
         {
440
            UartWrite(' ');
441
            UartWrite(ch);
442
            --index;
443
         }
444
      }
445
      else if(index < sizeof(PrintfString))
446
         PrintfString[index++] = (uint8)ch;
447
   }
448
   UartWrite('\n');
449
   PrintfString[index] = 0;
450
   sscanf(PrintfString, format, arg0, arg1, arg2, arg3,
451
          arg4, arg5, arg6, arg7);
452
   OS_SemaphorePost(SemaphoreUart);
453
}
454
 
455
 
456 152 rhoads
#ifdef SUPPORT_DATA_PACKETS
457
void UartPacketConfig(PacketGetFunc_t PacketGetFunc,
458
                      int PacketSize,
459
                      OS_MQueue_t *mQueue)
460
{
461
   UartPacketGet = PacketGetFunc;
462
   UartPacketSize = PacketSize;
463
   UartPacketMQueue = mQueue;
464
}
465
 
466
 
467 188 rhoads
void UartPacketSend(uint8 *data, int bytes)
468 152 rhoads
{
469
   UartPacketOutByte = 0;
470 188 rhoads
   UartPacketOutLength = bytes;
471
   UartPacketOut = data;
472 152 rhoads
   OS_InterruptMaskSet(IRQ_UART_WRITE_AVAILABLE);
473
}
474
#endif
475
 
476
 
477
void Led(int value)
478
{
479
   value |= 0xffffff00;
480
   MemoryWrite(GPIO0_OUT, value);  //Change LEDs
481
}
482
 
483
 
484 138 rhoads
/******************************************/
485
int puts(const char *string)
486
{
487
   uint8 *ptr;
488
   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
489
   ptr = (uint8*)string;
490
   while(*ptr)
491
   {
492
      if(*ptr == '\n')
493
         UartWrite('\r');
494
      UartWrite(*ptr++);
495
   }
496
   OS_SemaphorePost(SemaphoreUart);
497
   return 0;
498
}
499
 
500
 
501
int getch(void)
502
{
503
   return BufferRead(ReadBuffer, 1);
504
}
505
 
506
 
507
int kbhit(void)
508
{
509
   return ReadBuffer->read != ReadBuffer->write;
510
}
511
 
512
 
513
/******************************************/
514
#if 0
515
int LogArray[100], LogIndex;
516
void LogWrite(int a)
517
{
518
   if(LogIndex < sizeof(LogArray)/4)
519
      LogArray[LogIndex++] = a;
520
}
521
 
522
void LogDump(void)
523
{
524
   int i;
525
   for(i = 0; i < LogIndex; ++i)
526
   {
527
      if(LogArray[i] > 0xfff)
528
         UartPrintfCritical("\n", 0,0,0,0,0,0,0,0);
529
      UartPrintfCritical("0x%x ", LogArray[i], 0,0,0,0,0,0,0);
530
   }
531
   LogIndex = 0;
532
}
533
#endif
534
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.