📄 xsicp.c
字号:
/******************************************************************************
**
** COPYRIGHT (C) 2000, 2001 Intel Corporation.
**
** This software as well as the software described in it is furnished under
** license and may only be used or copied in accordance with the terms of the
** license. The information in this file is furnished for informational use
** only, is subject to change without notice, and should not be construed as
** a commitment by Intel Corporation. Intel Corporation assumes no
** responsibility or liability for any errors or inaccuracies that may appear
** in this document or any software that may be provided in association with
** this document.
** Except as permitted by such license, no part of this document may be
** reproduced, stored in a retrieval system, or transmitted in any form or by
** any means without the express written consent of Intel Corporation.
**
** FILENAME: xsicp.c
**
** PURPOSE: API functions for the Infrared Communication Port.
**
** LAST MODIFIED: $Modtime: 7/17/03 1:01p $
******************************************************************************/
/*
*******************************************************************************
* HEADER FILES
*******************************************************************************
*/
#include <string.h>
#include "systypes.h"
#include "XsGpioApi.h"
#include "timedelays.h"
#include "DM_Debug.h"
#include "dm_errors.h"
#include "XsDmaApi.h"
#include "XsClkMgr.h"
#include "XsIntCtrlApi.h"
#define ICP_GLOBALS 1
#include "xsicp.h"
/*
*******************************************************************************
* GLOBAL DEFINITIONS
*******************************************************************************
*/
/*
*******************************************************************************
* LOCAL DEFINITIONS
*******************************************************************************
*/
static IcpCfgT defaultIcpCfg = {
IcpLoopbackOn, // Enable loopback mode
IcpRxOperation, // Enable receive or transmit operation
IcpTxFIFOUnderunNoInt, // Ignore interrupt on Tx FIFO underrun
IcpFIFOIntDisabled, // Receive FIFO interrupt disabled
IcpFIFOIntDisabled, // Transmit FIFO interrupt disabled
IcpAddressMatchDisabled, // Address match disabled
ICP_MATCH_ALL, // Address match is not used, why bother
IcpRxFIFOTrgLevel8, // Rx FIFO trigger level 8 bytes
IcpPinPolarityInvert, // Tx pin polarity is not inverted
IcpPinPolarityInvert, // Rx pin polarity is not inverted
};
// DMA configuration structure to setup the transmit channel
static IcpDmaCfgT defaultDmaTxCfg =
{
NUM_BUF_DEFAULT_ICP,
BUFF_SIZE_DEFAULT_ICP,
XFER_LEN_DEFAULT_ICP,
XSDMA_DN_MEMORY,
XSDMA_DN_ICP,
XSDMA_CH_PR_LOW
};
// DMA configuration structure to setup the receive channel
static IcpDmaCfgT defaultDmaRxCfg =
{
NUM_BUF_DEFAULT_ICP,
BUFF_SIZE_DEFAULT_ICP,
XFER_LEN_DEFAULT_ICP,
XSDMA_DN_ICP,
XSDMA_DN_MEMORY,
XSDMA_CH_PR_LOW
};
static IcpDmaStatusT defaultDmaTxStatus;
static IcpDmaStatusT defaultDmaRxStatus;
static IcpIntStatusT defaultIntStatus;
/*
******************************************************************************************
*
* FUNCTION: XsIcpHWSetup
*
* DESCRIPTION: This function is used for hardware initialization of ICP.
* It uses the ICP configuration structure to configure ICP's
* modes of operation.
*
* INPUT PARAMETERS: ctxP is a pointer to ICP's context structure
*
* RETURNS: 0 if successful
* UINT32 in case of error.
*
* GLOBAL EFFECTS: none
*
* ASSUMPTIONS: none
*
*******************************************************************************************
*/
static
UINT32 XsIcpHWSetup(IcpContextT * ctxP)
{
volatile IcpRegsT * regsP = (IcpRegsT *)ctxP->regsP;
IcpCfgT * cfgP = (IcpCfgT *)ctxP->cfgP;
UINT32 error = FALSE;
UINT data;
/*
PVUINT GPSRy = (PVUINT)0x40e0001c;
PVUINT GPDRy = (PVUINT)0x40e00010;
PVUINT GAFR0y = (PVUINT)0x40e0005c;
*/
// Disable the peripheral clock bit for the STUART
xsCMDisableClock(CK_STUART);
// Clear any previous setup
regsP->ICCR0 = 0;
regsP->ICCR1 = 0;
regsP->ICCR2 = 0;
// Clear any sticky bits
regsP->ICSR0 = ICP_ICSR0_STICKY;
// Configure GPIOs
/*
*GPSRy = 0x00008000;
*GPDRy &= ~0x0000C000;
*GPDRy |= 0x00008000;
*GAFR0y &= ~0xf0000000;
*GAFR0y |= 0x90000000;
*/
XsGpioSetIcp ();
// Select the peripheral clock bit for the ICP
xsCMEnableClock (CK_ICP);
// Enable ICP unit
regsP->ICCR0 |= ICP_ICCR0_ITR;
// Select what action to take on transmit FIFO underrun
if (cfgP->actionTxFIFOUnderrun == IcpTxFIFOUnderunNoInt)
{
// Transmit FIFO underrun causes CRC, stop flag, and
// SIR to be transmitted (TUR ignored)
regsP->ICCR0 &= ~ICP_ICCR0_TUS;
}
else
{
// Transmit FIFO underrun causes an abort to be transmitted
// state of TUR sent to interrupt controller
regsP->ICCR0 |= ICP_ICCR0_TUS;
}
// Enable/disable address match function
if (cfgP->enableAddressMatch == IcpAddressMatchDisabled)
{
// Disable receiver address match function
regsP->ICCR0 &= ~ICP_ICCR0_AME;
}
else
{
// Enable receiver address match function
regsP->ICCR0 |= ICP_ICCR0_AME;
// Write the address match value to the ICCR1
regsP->ICCR1 = cfgP->addressMatchValue & ICP_ICCR1_MASK;
}
// Select the receiver FIFO trigger level
switch (cfgP->RxFIFOTrgLevel)
{
case IcpRxFIFOTrgLevel8:
regsP->ICCR2 |= ICP_ICCR2_TRIG_8BYTES;
break;
case IcpRxFIFOTrgLevel16:
regsP->ICCR2 |= ICP_ICCR2_TRIG_16BYTES;
break;
case IcpRxFIFOTrgLevel32:
regsP->ICCR2 |= ICP_ICCR2_TRIG_32BYTES;
break;
default:
regsP->ICCR2 |= ICP_ICCR2_TRIG_8BYTES;
}
// Select Tx pin polarity
if (cfgP->TxPinPolarity == IcpPinPolarityInvert)
{
// Data output from ICP is inverted
regsP->ICCR2 &= ~ICP_ICCR2_TXP;
}
else
{
// Data output from ICP is non-inverted
regsP->ICCR2 |= ICP_ICCR2_TXP;
}
// Select Rx pin polarity
if (cfgP->RxPinPolarity == IcpPinPolarityInvert)
{
// Data input from receive data pin is inverted
regsP->ICCR2 &= ~ICP_ICCR2_RXP;
}
else
{
// Data input from receive data pin is non-inverted
regsP->ICCR2 |= ICP_ICCR2_RXP;
}
// Enable/disable receiver FIFO interrupt
if (cfgP->RxIntEnable == IcpFIFOIntDisabled)
{
// Receive FIFO does not generate an interrupt
regsP->ICCR0 &= ~ICP_ICCR0_RIE;
}
else
{
// Receive FIFO generates an interrupt
regsP->ICCR0 |= ICP_ICCR0_RIE;
}
// Enable/disable transmitter FIFO interrupt
if (cfgP->TxIntEnable == IcpFIFOIntDisabled)
{
// Transmit FIFO does not generate an interrupt
regsP->ICCR0 &= ~ICP_ICCR0_TIE;
}
else
{
// Transmit FIFO generates an interrupt
regsP->ICCR0 |= ICP_ICCR0_TIE;
}
// Make sure the Rx FIFO is empty
while (ctxP->readBitStatusReg1IcpFnP(ctxP, IcpRxNotEmpty))
data = regsP->ICDR;
// Register an interrupt handler
error = XsIcRegisterHandler (XSIC_ICP_SGNL,
ctxP->intHandlerIcpFnP,
(void *) ctxP);
if (error)
{
LOGERROR(ctxP->loggedError, ERR_L_XSICP,
ERR_S_XSICP_HWSETUP, ERR_T_ILLPARAM, error, 0, 0);
return (ctxP->loggedError);
}
// Enable first level ICP interrupt
/*
error = XsIcEnableIrqDeviceInt (XSIC_ICP_SGNL);
if (error)
{
LOGERROR(ctxP->loggedError, ERR_L_XSICP,
ERR_S_XSICP_HWSETUP, ERR_T_NO_HANDLER, error, 0, 0);
return (ctxP->loggedError);
}
*/
// Enable/disable HSSP transmit and receive operations
if (cfgP->loopback == IcpLoopbackOn)
{
// Loopback mode of operation enabled
regsP->ICCR0 |= ICP_ICCR0_LBM;
// if loopback mode is enabled than enable both Tx and Rx operations
regsP->ICCR0 |= (ICP_ICCR0_TXE | ICP_ICCR0_RXE);
}
else if ((cfgP->loopback == IcpLoopbackOff) && (cfgP->function == IcpRxOperation))
{
// Normal serial port operation enabled
regsP->ICCR0 &= ~ICP_ICCR0_LBM;
// Enable ICP receive operation
regsP->ICCR0 |= ICP_ICCR0_RXE;
}
else if ((cfgP->loopback == IcpLoopbackOff) && (cfgP->function == IcpTxOperation))
{
// Normal serial port operation enabled
regsP->ICCR0 &= ~ICP_ICCR0_LBM;
// Enable ICP transmit operation
regsP->ICCR0 |= ICP_ICCR0_TXE;
}
return error;
}
/*
*******************************************************************************
*
* FUNCTION: loopbackIcp
*
* DESCRIPTION: This function is used to test ICP in loopback mode of operation.
*
* INPUT PARAMETERS: ctxP is a pointer to ICP context structure.
* data is the data sent via loopback path.
*
* RETURNS: INT data only max. 8 bit of data are significant).
* or -1 if timeout expired and no character has been received.
*
* GLOBAL EFFECTS: none
*
* ASSUMPTIONS: ICP's FIFO' Tx and Rx level interrupts are disabled, Tx and Rx units
* are enabled, and loopback test mode is enabled
*
*******************************************************************************
*/
static
INT loopbackIcp(IcpContextT * ctxP, INT data)
{
volatile IcpRegsT * regsP = (IcpRegsT *)ctxP->regsP;
INT retry = ICP_RETRY_LOOP;
// Check if Tx FIFO is not full
while ((regsP->ICSR1 & ICP_ICSR1_TNF) == 0);
// Write data to the transmit FIFO
regsP->ICDR = data;
DM_WaitUs(10);
// Wait for the loopback data to arrive
while (((regsP->ICSR1 & ICP_ICSR1_RNE) == 0) && (--retry > 0))
DM_WaitUs(1);
if (retry > 0)
return regsP->ICDR;
return (-1);
}
/*
*******************************************************************************
*
* FUNCTION: writeIcp
*
* DESCRIPTION: This function is used to transmit data via ICP in polled mode
* operation
*
* INPUT PARAMETERS: ctxP is a pointer to ICP context structure
* txbufP is a pointer to the buffer where the data is going
* to be taken from
* len is number of bytes to be sent
*
* RETURNS: none.
*
* GLOBAL EFFECTS: none.
*
* ASSUMPTIONS: none.
*
*******************************************************************************
*/
static
void writeIcp (IcpContextT * ctxP, PCHAR txbufP, INT len)
{
volatile IcpRegsT * regsP = (IcpRegsT *)ctxP->regsP;
INT i;
for (i = 0; i < len; i++)
{
// Check if Tx FIFO is not full
while ((regsP->ICSR1 & ICP_ICSR1_TNF) == 0);
// Write data
regsP->ICDR = *txbufP++;
}
}
/*
*******************************************************************************
*
* FUNCTION: readIcp
*
* DESCRIPTION: This function is used to receive data via Icp in polled mode
* operation
*
* INPUT PARAMETERS: ctxP is a pointer to ICP's context structure
* rxbufP is a pointer to the buffer where received data is
* going to be placed
* len is a specified number of bytes to read.
*
* RETURNS: INT an actual number of bytes have been read
*
* GLOBAL EFFECTS: none.
*
* ASSUMPTIONS: none.
*
*******************************************************************************
*/
static
INT readIcp (IcpContextT * ctxP, PCHAR rxbufP, INT len)
{
volatile IcpRegsT * regsP = (IcpRegsT *)ctxP->regsP;
INT retry = ICP_RETRY_LOOP;
INT i;
for (i = 0; i < len; i++)
{
// Wait for data to be available
while (((regsP->ICSR1 & ICP_ICSR1_RNE) == 0) && (--retry > 0))
DM_WaitUs(1);
if (retry > 0)
{
*rxbufP++ = regsP->ICDR;
retry = ICP_RETRY_LOOP;
}
else
{
break;
}
}
if (retry > 0)
return i;
return (-1);
}
/*
*******************************************************************************
*
* FUNCTION: clearRxIcp
*
* DESCRIPTION: This function is used to clear receive FIFO of the Icp
*
* INPUT PARAMETERS: ctxP is a pointer to the ICP's context structure
*
* RETURNS: INT a contence of the ICCR0
*
* GLOBAL EFFECTS: none.
*
* ASSUMPTIONS: none.
*
*******************************************************************************
*/
static
INT clearRxIcp (IcpContextT * ctxP)
{
volatile IcpRegsT * regsP = (IcpRegsT *)ctxP->regsP;
regsP->ICCR0 &= ~ICP_ICCR0_RXE;
return regsP->ICCR0;
}
/*
*******************************************************************************
*
* FUNCTION: clearTxIcp
*
* DESCRIPTION: This function is used to clear transmit FIFO of the Icp
*
* INPUT PARAMETERS: ctxP is a pointer to the ICP's context structure
*
* RETURNS: INT a contence of the ICCR0
*
* GLOBAL EFFECTS: none.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -