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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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