📄 serialconsoledriver_comp.c
字号:
/*
* Copyright (c) 1999 by TriMedia Technologies.
*
* +------------------------------------------------------------------+
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such |
* | a license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided|
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | TriMedia Technologies. |
* | |
* | this code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +------------------------------------------------------------------+
*
* Module name : %M% %I%
*
* Last update : %U% - %E%
*
* Description : Component for installing
* simple serial IO driver via
* serial device, e.g. UART
*
*/
#include <tm1/tsaComponent.h>
#include <tm1/tmLibdevErr.h>
#include <tmlib/HostCall.h>
#include <tmlib/dprintf.h>
#include <tm1/tsaUart.h>
#include <tm1/tsaReg.h>
#include <tmlib/IODrivers.h>
#include <tmlib/AppSem.h>
#include "IOComponents.h"
#define CR 0xd
#define LF 0xa
#define BS '\b'
static Int consoleInstance;
static struct _AppSem_Semaphore readLock = _AppSem_INITIALISED_SEM;
static struct _AppSem_Semaphore writeLock = _AppSem_INITIALISED_SEM;
static struct _AppSem_Semaphore readDone = _AppSem_INITIALISED_SEM;
static struct _AppSem_Semaphore writeDone = _AppSem_INITIALISED_SEM;
static void writeCompletionFunc(Int instance, Int count, Pointer handle);
static void readCompletionFunc(Int instance, Int count, Pointer handle);
static void errorFunc(Int instance, tmLibdevErr_t err, Pointer handle);
static Char readChar(Int instance);
static void writeChar(Int instance, Char a);
static Bool myRecogUart(String path);
static Int32 myWriteUart(Int32 fd, Address buffer, Int32 size);
static Int32 myReadUart(Int32 fd, Address buffer, Int32 size);
static Int32 myIsattyUart(Int32 fd, struct stat *buf);
static Int32 myStatUart(Int32 fd, struct stat *buf);
static Int32 myOpenUart(void);
static void errorFunc(Int instance, tmLibdevErr_t err, Pointer handle)
{
DP(("SerialConsoleDriver: errorFunc: err %#x\n", err));
}
static Bool myRecogUart(String path)
{
return strcmp(path, CONSOLE) == 0;
}
static Int32 myWriteUart(Int32 fd, Address buffer, Int32 size)
{
Int c = 0;
Bool done;
AppSem_P(&writeLock);
done = False;
while (!done)
{
writeChar(consoleInstance, buffer[c]);
if (buffer[c++] == LF)
writeChar(consoleInstance, CR);
if (c == size)
done = True;
}
AppSem_V(&writeLock);
return size;
}
static Int32 myReadUart(Int32 fd, Address buffer, Int32 size)
{
Char d;
Int c = 0;
Bool done;
AppSem_P(&readLock);
done = False;
while(!done)
{
d = readChar(consoleInstance);
if(d == BS)
{
if(c > 0)
{
writeChar(consoleInstance, d);
writeChar(consoleInstance, ' ');
writeChar(consoleInstance, d);
c--;
}
}
else
writeChar(consoleInstance, d);
if (d == CR)
{
writeChar(consoleInstance, LF);
done = True;
d = LF;
}
if(d != BS)
buffer[c++] = d;
if (c == size)
done = True;
}
AppSem_V(&readLock);
return c;
}
static Int32 myIsattyUart(Int32 fd, struct stat *buf)
{
return 1;
}
static Int32 myOpenUart(void)
{
return 0;
}
static Int32 myStatUart(Int32 fd, struct stat *buf)
{
memset(buf, 0, sizeof(*buf));
buf->st_mode = S_IFCHR;
return 0;
}
static Char readChar(Int instance)
{
tmLibdevErr_t err;
Char d;
AppSem_P(&readDone);
err = tsaUartRead(instance, &d, 1);
if (err)
DP(("readChar: err %#x\n", err));
AppSem_P(&readDone);
AppSem_V(&readDone);
return d;
}
static void writeChar(Int instance, Char a)
{
tmLibdevErr_t err;
Char d = a;
AppSem_P(&writeDone);
err = tsaUartWrite(instance, &d, 1);
if (err)
DP(("writeChar: err %#x\n", err));
AppSem_P(&writeDone);
AppSem_V(&writeDone);
}
static void writeCompletionFunc(Int instance, Int count, Pointer handle)
{
AppSem_V(&writeDone);
}
static void readCompletionFunc(Int instance, Int count, Pointer handle)
{
AppSem_V(&readDone);
}
static tmLibdevErr_t comp_init()
{
tsaUartInstanceSetup_t uartSetup;
tmLibdevErr_t err;
unitSelect_t portID;
Char tmpBuf[] = ID(SerialConsolePort);
tsaRegEntryClass_t entryType;
ptsaRegDataEntry_t entry;
portID = unit0; /* default port */
err = tsaRegQuery(tmpBuf, &entryType, (Pointer *) &entry);
if (err == TMLIBDEV_OK)
{
portID = *(UInt32*)(entry->data);
}
err = tsaUartOpen(&consoleInstance, portID);
if (err)
{
_dp("serial StdIO driver: Error while opening unit %d : %#x\n", UART_COM1, err);
return err;
}
uartSetup.baudRate = UART_BAUD_38400;
uartSetup.numDataBits = 8;
uartSetup.numStopBits = 1;
uartSetup.parity = UART_PARITY_NONE;
uartSetup.handle = Null;
uartSetup.writeCompletionFunc = writeCompletionFunc;
uartSetup.readCompletionFunc = readCompletionFunc;
uartSetup.controlMode = UART_CONTROL_OFF;
uartSetup.controlHandler = Null;
uartSetup.errorHandlerFunc = errorFunc;
err = tsaUartInstanceSetup(consoleInstance, &uartSetup);
if (err)
{
_dp("serial StdIO driver: Error while doing instance setup: %#x\n", err);
return err;
}
IOD_install_driver(
(IOD_RecogFunc) myRecogUart,
(IOD_InitFunc) Null,
(IOD_TermFunc) Null,
(IOD_OpenFunc) myOpenUart,
(IOD_OpenDllFunc)Null,
(IOD_CloseFunc) Null,
(IOD_ReadFunc) myReadUart,
(IOD_WriteFunc) myWriteUart,
(IOD_SeekFunc) Null,
(IOD_IsattyFunc) myIsattyUart,
(IOD_FstatFunc) myStatUart,
(IOD_FcntlFunc) Null,
(IOD_StatFunc) Null
);
return TMLIBDEV_OK;
}
static tmLibdevErr_t activate(pcomponent_t comp)
{
TRY(comp_init());
IDENTIFY(SerialConsoleDriver);
return TMLIBDEV_OK;
}
TSA_COMP_DEF_IO_COMPONENT(SerialConsoleDriver,
TSA_COMP_BUILD_ARG_LIST_2_M("bsp/uart", compInputRequired, ID(SerialConsolePort), compInputNotRequired),
TSA_COMP_BUILD_ARG_LIST_1(ID(SerialConsoleDriver)),
activate);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -