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

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [uart.c] - Blame information for rev 422

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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