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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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