⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 Plasma IP Core 你可以利用这个组件在FPGA中设计MIPS结构的CPU
💻 C
字号:
/*-------------------------------------------------------------------- * TITLE: Plasma Uart Driver * AUTHOR: Steve Rhoads (rhoadss@yahoo.com) * DATE CREATED: 12/31/05 * FILENAME: uart.c * PROJECT: Plasma CPU core * COPYRIGHT: Software placed into the public domain by the author. *    Software 'as is' without warranty.  Author liable for nothing. * DESCRIPTION: *    Plasma Uart Driver *--------------------------------------------------------------------*/#define NO_ELLIPSIS2#include "plasma.h"#include "rtos.h"#define SUPPORT_DATA_PACKETS#define BUFFER_WRITE_SIZE 128#define BUFFER_READ_SIZE 128#define BUFFER_PRINTF_SIZE 1024#undef UartPrintfvoid UartPrintfCritical(const char *format,                        int arg0, int arg1, int arg2, int arg3,                        int arg4, int arg5, int arg6, int arg7);typedef struct Buffer_s {   uint8 *data;   int size;   volatile int read, write;   volatile int pendingRead, pendingWrite;   OS_Semaphore_t *semaphoreRead, *semaphoreWrite;} Buffer_t;static Buffer_t *WriteBuffer, *ReadBuffer;static OS_Semaphore_t *SemaphoreUart;static char PrintfString[BUFFER_PRINTF_SIZE];  //Used in UartPrintf#ifdef SUPPORT_DATA_PACKETS//For packet processing [0xff lengthMSB lengthLSB checksum data]static PacketGetFunc_t UartPacketGet;static uint8 *PacketCurrent;static uint32 UartPacketSize;static uint32 UartPacketChecksum, Checksum;static OS_MQueue_t *UartPacketMQueue;static uint32 PacketBytes, PacketLength;static uint32 UartPacketOutLength, UartPacketOutByte;int CountOk, CountError;#endifstatic uint8 *UartPacketOut;/******************************************/Buffer_t *BufferCreate(int size){   Buffer_t *buffer;   buffer = (Buffer_t*)OS_HeapMalloc(NULL, sizeof(Buffer_t) + size);   if(buffer == NULL)      return NULL;   buffer->data = (uint8*)(buffer + 1);   buffer->read = 0;   buffer->write = 0;   buffer->size = size;   buffer->pendingRead = 0;   buffer->pendingWrite = 0;   buffer->semaphoreRead = OS_SemaphoreCreate("BufferRead", 0);   buffer->semaphoreWrite = OS_SemaphoreCreate("BufferWrite", 0);   return buffer;}void BufferWrite(Buffer_t *buffer, int value, int pend){   int writeNext;   writeNext = buffer->write + 1;   if(writeNext >= buffer->size)      writeNext = 0;   //Check if room for value   if(writeNext == buffer->read)   {      if(pend == 0)         return;      ++buffer->pendingWrite;      OS_SemaphorePend(buffer->semaphoreWrite, OS_WAIT_FOREVER);   }   buffer->data[buffer->write] = (uint8)value;   buffer->write = writeNext;   if(buffer->pendingRead)   {      --buffer->pendingRead;      OS_SemaphorePost(buffer->semaphoreRead);   }}int BufferRead(Buffer_t *buffer, int pend){   int value;   //Check if empty buffer   if(buffer->read == buffer->write)   {      if(pend == 0)         return 0;      ++buffer->pendingRead;      OS_SemaphorePend(buffer->semaphoreRead, OS_WAIT_FOREVER);   }   value = buffer->data[buffer->read];   if(++buffer->read >= buffer->size)      buffer->read = 0;   if(buffer->pendingWrite)   {      --buffer->pendingWrite;      OS_SemaphorePost(buffer->semaphoreWrite);   }   return value;}/******************************************/#ifdef SUPPORT_DATA_PACKETSstatic void UartPacketRead(uint32 value){   uint32 message[4];   if(PacketBytes == 0 && value == 0xff)   {      ++PacketBytes;   }   else if(PacketBytes == 1)   {      ++PacketBytes;      PacketLength = value << 8;   }   else if(PacketBytes == 2)   {      ++PacketBytes;      PacketLength |= value;      if(PacketLength <= UartPacketSize)         PacketCurrent = UartPacketGet();      else      {         PacketCurrent = NULL;         PacketBytes = 0;      }   }   else if(PacketBytes == 3)   {      ++PacketBytes;      UartPacketChecksum = value;      Checksum = 0;   }   else if(PacketBytes >= 4)   {      if(PacketCurrent)         PacketCurrent[PacketBytes - 4] = (uint8)value;      Checksum += value;      ++PacketBytes;      if(PacketBytes - 4 >= PacketLength)      {         if((uint8)Checksum == UartPacketChecksum)         {            //Notify thread that a packet have been received            ++CountOk;            message[0] = 0;            message[1] = (uint32)PacketCurrent;            message[2] = PacketLength;            if(PacketCurrent)               OS_MQueueSend(UartPacketMQueue, message);         }         else         {            ++CountError;            //printf("E");         }         PacketBytes = 0;      }   }}static int UartPacketWrite(void){   int value=0, i;   uint32 message[4];   if(UartPacketOut)   {      if(UartPacketOutByte == 0)      {         value = 0xff;         ++UartPacketOutByte;      }      else if(UartPacketOutByte == 1)      {         value = UartPacketOutLength >> 8;         ++UartPacketOutByte;      }      else if(UartPacketOutByte == 2)      {         value = (uint8)UartPacketOutLength;         ++UartPacketOutByte;      }      else if(UartPacketOutByte == 3)      {         value = 0;         for(i = 0; i < (int)UartPacketOutLength; ++i)            value += UartPacketOut[i];         value = (uint8)value;         ++UartPacketOutByte;      }      else       {         value = UartPacketOut[UartPacketOutByte - 4];         ++UartPacketOutByte;         if(UartPacketOutByte - 4 >= UartPacketOutLength)         {            //Notify thread that a packet has been sent            message[0] = 1;            message[1] = (uint32)UartPacketOut;            UartPacketOut = 0;            OS_MQueueSend(UartPacketMQueue, message);         }      }   }   return value;}#endifstatic void UartInterrupt(void *arg){   uint32 status, value, count=0;   (void)arg;   status = OS_InterruptStatus();   while(status & IRQ_UART_READ_AVAILABLE)   {      value = MemoryRead(UART_READ);#ifdef SUPPORT_DATA_PACKETS      if(UartPacketGet && (value == 0xff || PacketBytes))         UartPacketRead(value);      else#endif      BufferWrite(ReadBuffer, value, 0);      status = OS_InterruptStatus();      if(++count >= 16)         break;   }   while(status & IRQ_UART_WRITE_AVAILABLE)   {#ifdef SUPPORT_DATA_PACKETS      if(UartPacketOut)      {         value = UartPacketWrite();         MemoryWrite(UART_WRITE, value);      } else #endif      if(WriteBuffer->read != WriteBuffer->write)      {         value = BufferRead(WriteBuffer, 0);         MemoryWrite(UART_WRITE, value);      }      else      {         OS_InterruptMaskClear(IRQ_UART_WRITE_AVAILABLE);         break;      }      status = OS_InterruptStatus();   }}void UartInit(void){   uint32 mask;   SemaphoreUart = OS_SemaphoreCreate("Uart", 1);   WriteBuffer = BufferCreate(BUFFER_WRITE_SIZE);   ReadBuffer = BufferCreate(BUFFER_READ_SIZE);   mask = IRQ_UART_READ_AVAILABLE | IRQ_UART_WRITE_AVAILABLE;   OS_InterruptRegister(mask, UartInterrupt);   OS_InterruptMaskSet(IRQ_UART_READ_AVAILABLE);}void UartWrite(int ch){   BufferWrite(WriteBuffer, ch, 1);   OS_InterruptMaskSet(IRQ_UART_WRITE_AVAILABLE);}uint8 UartRead(void){   return (uint8)BufferRead(ReadBuffer, 1);}void UartWriteData(uint8 *data, int length){   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);   while(length--)      UartWrite(*data++);   OS_SemaphorePost(SemaphoreUart);}void UartReadData(uint8 *data, int length){   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);   while(length--)      *data++ = UartRead();   OS_SemaphorePost(SemaphoreUart);}void UartPrintf(const char *format,                int arg0, int arg1, int arg2, int arg3,                int arg4, int arg5, int arg6, int arg7){   uint8 *ptr;   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,           arg4, arg5, arg6, arg7);   ptr = (uint8*)PrintfString;   while(*ptr)   {      if(*ptr == '\n')         UartWrite('\r');#ifdef SUPPORT_DATA_PACKETS      if(*ptr == 0xff)         *ptr = '@';#endif      UartWrite(*ptr++);   }   OS_SemaphorePost(SemaphoreUart);}void UartPrintfPoll(const char *format,                    int arg0, int arg1, int arg2, int arg3,                    int arg4, int arg5, int arg6, int arg7){   uint8 *ptr;   uint32 state;   if(SemaphoreUart)      OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,           arg4, arg5, arg6, arg7);   ptr = (uint8*)PrintfString;   while(*ptr)   {      while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0)         ;      state = OS_CriticalBegin();      if((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) &&         UartPacketOut == NULL)      {         MemoryWrite(UART_WRITE, *ptr++);      }      OS_CriticalEnd(state);   }   if(SemaphoreUart)      OS_SemaphorePost(SemaphoreUart);}void UartPrintfCritical(const char *format,                        int arg0, int arg1, int arg2, int arg3,                        int arg4, int arg5, int arg6, int arg7){   uint8 *ptr;   uint32 state;   state = OS_CriticalBegin();   sprintf(PrintfString, format, arg0, arg1, arg2, arg3,           arg4, arg5, arg6, arg7);   ptr = (uint8*)PrintfString;   while(*ptr)   {      while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0)         ;      MemoryWrite(UART_WRITE, *ptr++);#ifdef SUPPORT_DATA_PACKETS      if(UartPacketOut && UartPacketOutByte - 4 < UartPacketOutLength)      {         ++UartPacketOutByte;         --ptr;      }#endif   }   memset(PrintfString, 0, sizeof(PrintfString));   OS_CriticalEnd(state);}void UartPrintfNull(void){}void UartScanf(const char *format,               int arg0, int arg1, int arg2, int arg3,               int arg4, int arg5, int arg6, int arg7){   int index = 0, ch;   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);   for(;;)   {      ch = UartRead();      if(ch != '\b' || index)         UartWrite(ch);      if(ch == '\n' || ch == '\r')         break;      else if(ch == '\b')      {         if(index)         {            UartWrite(' ');            UartWrite(ch);            --index;         }      }      else if(index < sizeof(PrintfString))         PrintfString[index++] = (uint8)ch;   }   UartWrite('\n');   PrintfString[index] = 0;   sscanf(PrintfString, format, arg0, arg1, arg2, arg3,          arg4, arg5, arg6, arg7);   OS_SemaphorePost(SemaphoreUart);}#ifdef SUPPORT_DATA_PACKETSvoid UartPacketConfig(PacketGetFunc_t PacketGetFunc,                       int PacketSize,                       OS_MQueue_t *mQueue){   UartPacketGet = PacketGetFunc;   UartPacketSize = PacketSize;   UartPacketMQueue = mQueue;}void UartPacketSend(uint8 *data, int bytes){   UartPacketOutByte = 0;   UartPacketOutLength = bytes;   UartPacketOut = data;   OS_InterruptMaskSet(IRQ_UART_WRITE_AVAILABLE);}#endifvoid Led(int value){   value |= 0xffffff00;   MemoryWrite(GPIO0_OUT, value);  //Change LEDs}/******************************************/#ifndef WIN32int puts(const char *string){   uint8 *ptr;   OS_SemaphorePend(SemaphoreUart, OS_WAIT_FOREVER);   ptr = (uint8*)string;   while(*ptr)   {      if(*ptr == '\n')         UartWrite('\r');      UartWrite(*ptr++);   }   OS_SemaphorePost(SemaphoreUart);   return 0;}int getch(void){   return BufferRead(ReadBuffer, 1);}int kbhit(void){   return ReadBuffer->read != ReadBuffer->write;}#endif/******************************************/#if 0int LogArray[100], LogIndex;void LogWrite(int a){   if(LogIndex < sizeof(LogArray)/4)      LogArray[LogIndex++] = a;}void LogDump(void){   int i;   for(i = 0; i < LogIndex; ++i)   {      if(LogArray[i] > 0xfff)         UartPrintfCritical("\n", 0,0,0,0,0,0,0,0);      UartPrintfCritical("0x%x ", LogArray[i], 0,0,0,0,0,0,0);   }   LogIndex = 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -