Files
ISTTOK/epics/css/sys-mng-opi/CSS/MARTe/GAMs/isttokbiblio/UFSerialUART.cpp
2019-10-21 16:02:55 +01:00

363 lines
8.0 KiB
C++

#include "UFSerialUART.h"
#include <stdio.h>
// ******************************************************************
// Default constructor/destructor
// ******************************************************************
UFSerialUART::UFSerialUART(unsigned int address)
{
this->UARTPortAddress = address;
this->NineBitMode = false;
//
// Get permission from the kernel to access the UART ports
//
#if !defined(_RTAI)
if(ioperm(this->UARTPortAddress, 8, 1))
this->KernelPermission = false;
else
this->KernelPermission = true;
#else
this->KernelPermission = true;
#endif
}
UFSerialUART::~UFSerialUART()
{
//
// Release permission from the kernel to access the UART ports
//
#if !defined(_RTAI)
ioperm(this->UARTPortAddress, 8, 0);
#endif
}
// ******************************************************************
// ******************************************************************
// Get UART initialisation status
// ******************************************************************
bool UFSerialUART::IsUARTInitialised()
{
return this->KernelPermission;
}
// ******************************************************************
// ******************************************************************
// Set/Get UART port address
// ******************************************************************
void UFSerialUART::SetUARTPortAddress(unsigned int address)
{
this->UARTPortAddress = address;
}
unsigned int UFSerialUART::GetUARTPortAddress()
{
return this->UARTPortAddress;
}
// ******************************************************************
// ******************************************************************
// DLAB Set/Clear
// ******************************************************************
void UFSerialUART::SetDLAB()
{
unsigned char LcrValue = inb(LCR);
outb(LcrValue | 0x80, LCR);
}
void UFSerialUART::ClearDLAB()
{
unsigned char LcrValue = inb(LCR);
outb(LcrValue & 0x7F, LCR);
}
// ******************************************************************
// ******************************************************************
// Set Frequency Divider
// IMPORTANT: only call when DLAB = 0
// ******************************************************************
void UFSerialUART::SetFrequencyDivider(unsigned short newDivider)
{
unsigned char Low = (unsigned char)(newDivider & 0x00FF);
unsigned char High = (unsigned char)((newDivider & 0xFF00) >> 8);
SetDLAB();
outb(Low, DLL);
outb(High, DLM);
ClearDLAB();
}
// ******************************************************************
// ******************************************************************
// Configure LCR: 8-bits, 1 stop bit, keep the rest of the byte
// TODO: erase this method
// ******************************************************************
void UFSerialUART::ConfigureLCR()
{
unsigned char LcrValue = inb(LCR);
LcrValue |= 0x03;
LcrValue &= 0xFB;
outb(LcrValue, LCR);
}
// ******************************************************************
// ******************************************************************
// Select operation mode
// ******************************************************************
void UFSerialUART::Select950Mode()
{
unsigned char FcrValue = inb(FCR);
FcrValue |= 0x01;
outb(FcrValue, FCR);
unsigned char LcrValue = inb(LCR);
outb(0xBF, LCR);
unsigned char EfrValue = inb(EFR);
EfrValue |= 0x10;
outb(LcrValue, LCR);
}
// ******************************************************************
// ******************************************************************
// Enable/Disable 9-bit mode
// ******************************************************************
void UFSerialUART::Enable9BitMode()
{
outb(0x0D, SPR);
outb(0x01, ICR);
this->NineBitMode = true;
}
void UFSerialUART::Disable9BitMode()
{
outb(0x0D, SPR);
outb(0x00, ICR);
this->NineBitMode = false;
}
// ******************************************************************
// ******************************************************************
// Set Low/High Parity
// ******************************************************************
void UFSerialUART::DisableParity()
{
unsigned char LcrValue = inb(LCR);
outb(LcrValue & 0xF7, LCR);
}
void UFSerialUART::SetLowParity()
{
unsigned char LcrValue = inb(LCR);
outb(LcrValue | 0x38, LCR);
}
void UFSerialUART::SetHighParity()
{
unsigned char LcrValue = inb(LCR);
LcrValue |= 0x28;
LcrValue &= 0xEF;
outb(LcrValue, LCR);
}
void UFSerialUART::SetEvenParity()
{
unsigned char LcrValue = inb(LCR);
LcrValue |= 0x18;
LcrValue &= 0xDF;
outb(LcrValue, LCR);
}
void UFSerialUART::SetOddParity()
{
unsigned char LcrValue = inb(LCR);
LcrValue |= 0x08;
LcrValue &= 0xCF;
outb(LcrValue, LCR);
}
// ******************************************************************
// ******************************************************************
// Set Data Length
// ******************************************************************
void UFSerialUART::SetFiveBitsLength()
{
unsigned char LcrValue = inb(LCR);
LcrValue &= 0xFC;
outb(LcrValue, LCR);
}
void UFSerialUART::SetSixBitsLength()
{
unsigned char LcrValue = inb(LCR);
LcrValue &= 0xFD;
LcrValue |= 0x01;
outb(LcrValue, LCR);
}
void UFSerialUART::SetSevenBitsLength()
{
unsigned char LcrValue = inb(LCR);
LcrValue &= 0xFE;
LcrValue |= 0x02;
outb(LcrValue, LCR);
}
void UFSerialUART::SetEightBitsLength()
{
unsigned char LcrValue = inb(LCR);
LcrValue |= 0x03;
outb(LcrValue, LCR);
}
// ******************************************************************
// ******************************************************************
// Enable/disable usage of FIFOs
// ******************************************************************
void UFSerialUART::EnableFifos()
{
outb(0xF7, FCR);
}
void UFSerialUART::DisableFifos()
{
outb(0xF6, FCR);
}
// ******************************************************************
// ******************************************************************
// Select number of stop bits
// ******************************************************************
void UFSerialUART::SelectOneStopBit()
{
unsigned char LcrValue = inb(LCR);
LcrValue &= 0xFB;
outb(LcrValue, LCR);
}
void UFSerialUART::SelectTwoStopBits()
{
unsigned char LcrValue = inb(LCR);
LcrValue |= 0x04;
outb(LcrValue, LCR);
}
// ******************************************************************
// ******************************************************************
// Clear FIFOs
// Note: I don't know if these methods work with the 950 UARTs
// ******************************************************************
void UFSerialUART::ClearTxFifo()
{
unsigned char FcrValue = inb(FCR);
outb(FcrValue | 0x04, FCR);
}
void UFSerialUART::ClearRxFifo()
{
unsigned char FcrValue = inb(FCR);
outb(FcrValue | 0x02, FCR);
}
// ******************************************************************
// ******************************************************************
// Check if there is data waiting to be read
// ******************************************************************
bool UFSerialUART::IsDataAvailable()
{
if((inb(LSR) & 0x01) == 0)
return false;
return true;
}
// ******************************************************************
// ******************************************************************
// Send/receive value
// ******************************************************************
bool UFSerialUART::SendValue(unsigned short value)
{
// TODO: delete these comments
//unsigned char result = inb(LSR);
//if((result & 0x20))
// outb(value, THR);
//else
// return -1;
// Place the 9th bit
if(this->NineBitMode)
{
if(value & 0x0100)
outb(0x01, SPR);
else
outb(0x00, SPR);
}
outb((unsigned char)(value & 0x00FF), THR);
return true;
}
// TODO:
bool UFSerialUART::ReadValue(unsigned short &value)
{
bool Is9BitAsserted = false;
//
// Get the 9th bit
//
if(this->NineBitMode)
{
if(inb(LSR) & 0x04)
Is9BitAsserted = true;
else
Is9BitAsserted = false;
}
//
// Read the remainder of the value
//
value = (unsigned short) inb(RHR);
value &= 0x00FF;
//
// Mix the 9 bits
//
if(Is9BitAsserted)
value |= 0x0100;
return true;
}
// ******************************************************************