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

Subversion Repositories mlite

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

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
   //Check for string "!M#~" to mask print statement
328
   static char moduleLevel[26];
329
   if(format[0] == '!' && format[3] == '~' &&
330
      'A' <= format[1] && format[1] <= 'Z')
331
   {
332
      int module = format[1] - 'A';
333
      int level = format[2] - '5';
334
      if(format[2] == '#')
335
      {
336
         //Set level with "!M#~#"
337
         moduleLevel[module] = (char)(format[4] - '5');
338
         return;
339
      }
340
      if(level < moduleLevel[module])
341
         return;
342
      format += 4;
343
   }
344
#endif
345 138 rhoads
   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
346
   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
347
           arg4, arg5, arg6, arg7);
348
   ptr = (uint8*)PrintfString;
349
   while(*ptr)
350
   {
351
      if(*ptr == '\n')
352
         UartWrite('\r');
353 158 rhoads
#ifdef SUPPORT_DATA_PACKETS
354 152 rhoads
      if(*ptr == 0xff)
355
         *ptr = '@';
356
#endif
357 138 rhoads
      UartWrite(*ptr++);
358
   }
359
   OS_SemaphorePost(SemaphoreUart);
360
}
361
 
362
 
363
void UartPrintfPoll(const char *format,
364
                    int arg0, int arg1, int arg2, int arg3,
365
                    int arg4, int arg5, int arg6, int arg7)
366
{
367
   uint8 *ptr;
368 152 rhoads
   uint32 state;
369 138 rhoads
 
370
   if(SemaphoreUart)
371
      OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
372
   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
373
           arg4, arg5, arg6, arg7);
374
   ptr = (uint8*)PrintfString;
375
   while(*ptr)
376
   {
377
      while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0)
378
         ;
379 152 rhoads
      state = OS_CriticalBegin();
380
      if((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) &&
381
         UartPacketOut == NULL)
382
      {
383
         MemoryWrite(UART_WRITE, *ptr++);
384
      }
385
      OS_CriticalEnd(state);
386 138 rhoads
   }
387
   if(SemaphoreUart)
388
      OS_SemaphorePost(SemaphoreUart);
389
}
390
 
391
 
392
void UartPrintfCritical(const char *format,
393
                        int arg0, int arg1, int arg2, int arg3,
394
                        int arg4, int arg5, int arg6, int arg7)
395
{
396
   uint8 *ptr;
397
   uint32 state;
398
 
399
   state = OS_CriticalBegin();
400
   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,
401
           arg4, arg5, arg6, arg7);
402
   ptr = (uint8*)PrintfString;
403
   while(*ptr)
404
   {
405
      while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0)
406
         ;
407
      MemoryWrite(UART_WRITE, *ptr++);
408 152 rhoads
#ifdef SUPPORT_DATA_PACKETS
409
      if(UartPacketOut && UartPacketOutByte - 4 < UartPacketOutLength)
410
      {
411
         ++UartPacketOutByte;
412
         --ptr;
413
      }
414
#endif
415 138 rhoads
   }
416
   memset(PrintfString, 0, sizeof(PrintfString));
417
   OS_CriticalEnd(state);
418
}
419
 
420
 
421 163 rhoads
void UartPrintfNull(void)
422
{
423
}
424
 
425
 
426 138 rhoads
void UartScanf(const char *format,
427
               int arg0, int arg1, int arg2, int arg3,
428
               int arg4, int arg5, int arg6, int arg7)
429
{
430
   int index = 0, ch;
431
   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
432
   for(;;)
433
   {
434
      ch = UartRead();
435
      if(ch != '\b' || index)
436
         UartWrite(ch);
437
      if(ch == '\n' || ch == '\r')
438
         break;
439
      else if(ch == '\b')
440
      {
441
         if(index)
442
         {
443
            UartWrite(' ');
444
            UartWrite(ch);
445
            --index;
446
         }
447
      }
448
      else if(index < sizeof(PrintfString))
449
         PrintfString[index++] = (uint8)ch;
450
   }
451
   UartWrite('\n');
452
   PrintfString[index] = 0;
453
   sscanf(PrintfString, format, arg0, arg1, arg2, arg3,
454
          arg4, arg5, arg6, arg7);
455
   OS_SemaphorePost(SemaphoreUart);
456
}
457
 
458
 
459 152 rhoads
#ifdef SUPPORT_DATA_PACKETS
460
void UartPacketConfig(PacketGetFunc_t PacketGetFunc,
461
                      int PacketSize,
462
                      OS_MQueue_t *mQueue)
463
{
464
   UartPacketGet = PacketGetFunc;
465
   UartPacketSize = PacketSize;
466
   UartPacketMQueue = mQueue;
467
}
468
 
469
 
470 188 rhoads
void UartPacketSend(uint8 *data, int bytes)
471 152 rhoads
{
472
   UartPacketOutByte = 0;
473 188 rhoads
   UartPacketOutLength = bytes;
474
   UartPacketOut = data;
475 152 rhoads
   OS_InterruptMaskSet(IRQ_UART_WRITE_AVAILABLE);
476
}
477
#endif
478
 
479
 
480
void Led(int value)
481
{
482
   value |= 0xffffff00;
483
   MemoryWrite(GPIO0_OUT, value);  //Change LEDs
484
}
485
 
486
 
487 138 rhoads
/******************************************/
488
int puts(const char *string)
489
{
490
   uint8 *ptr;
491
   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);
492
   ptr = (uint8*)string;
493
   while(*ptr)
494
   {
495
      if(*ptr == '\n')
496
         UartWrite('\r');
497
      UartWrite(*ptr++);
498
   }
499
   OS_SemaphorePost(SemaphoreUart);
500
   return 0;
501
}
502
 
503
 
504
int getch(void)
505
{
506
   return BufferRead(ReadBuffer, 1);
507
}
508
 
509
 
510
int kbhit(void)
511
{
512
   return ReadBuffer->read != ReadBuffer->write;
513
}
514
 
515
 
516
/******************************************/
517
#if 0
518
int LogArray[100], LogIndex;
519
void LogWrite(int a)
520
{
521
   if(LogIndex < sizeof(LogArray)/4)
522
      LogArray[LogIndex++] = a;
523
}
524
 
525
void LogDump(void)
526
{
527
   int i;
528
   for(i = 0; i < LogIndex; ++i)
529
   {
530
      if(LogArray[i] > 0xfff)
531
         UartPrintfCritical("\n", 0,0,0,0,0,0,0,0);
532
      UartPrintfCritical("0x%x ", LogArray[i], 0,0,0,0,0,0,0);
533
   }
534
   LogIndex = 0;
535
}
536
#endif
537
 

powered by: WebSVN 2.1.0

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