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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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