📄 xsssp.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: xsssp.c
**
** PURPOSE: API functions for the SSP1, SSP2, and SSP3 Serial Ports
**
** $Modtime: 7/17/03 1:01p $
******************************************************************************/
/*
*******************************************************************************
* HEADER FILES
*******************************************************************************
*/
#include "systypes.h"
#include "timedelays.h"
#include "XsClkMgr.h"
#include "XsGpioApi.h"
#include "XsOst.h"
#include "DM_Debug.h"
#include "XsDmaApi.h"
#include "XsIntCtrlApi.h"
#include "DM_Errors.h"
#define SSP_GLOBALS 1
#include "xsssp.h"
/*
*******************************************************************************
* GLOBAL DEFINITIONS
*******************************************************************************
*/
/*
*******************************************************************************
* LOCAL DEFINITIONS
*******************************************************************************
*/
static SspCfgT defaultSspCfg = {
16, // data size 16 bit
SspFormat_Ssp, // SSP
SspOnChipClock, // On-chip clock
NOT_USED, // No ext clock
22500, // 22500 bps
SspFIFOIntDisabled, // Rx FIFO level interrupt is disabled
SspFIFOIntDisabled, // Tx FIFO level interrupt is disabled
SspLoopbackOff, // The loopback mode is disabled
NOT_USED, // If SPI interface was selected, this is used to choose a polarity
NOT_USED, // If SPI interface was selected, this is used to choose a phase
NOT_USED, // If Microwire interface was selected, this is used to choose the data
7, // Transmit FIFO treshold value
7, // Receive FIFO treshold value
FALSE, // DMA disabled
NOT_USED, // FIFO special function is disabled
NOT_USED, // FIFO special function is disabled
NOT_USED, // Serial bit-rate Clock Mode for PSP mode
NOT_USED, // Serial Frame Polarity for PSP mode
NOT_USED, // End of Transfer Data State for PSP mode
NOT_USED, // Start Delay for PSP mode
NOT_USED, // Dummy Start for PSP mode
NOT_USED, // Serial Frame Delay for PSP mode
NOT_USED, // Serial Frame Width for PSP mode
NOT_USED // Dummy Stop for PSP mode
};
// DMA configuration structure to setup the transmit channel
static SspDmaCfgT defaultDmaTxCfg =
{
NUM_BUF_DEFAULT_SSP,
BUFF_SIZE_DEFAULT_SSP,
XFER_LEN_DEFAULT_SSP,
XSDMA_DN_MEMORY,
XSDMA_DN_SSP1,
XSDMA_CH_PR_LOW
};
// DMA configuration structure to setup the receive channel
static SspDmaCfgT defaultDmaRxCfg =
{
NUM_BUF_DEFAULT_SSP,
BUFF_SIZE_DEFAULT_SSP,
XFER_LEN_DEFAULT_SSP,
XSDMA_DN_SSP1,
XSDMA_DN_MEMORY,
XSDMA_CH_PR_LOW
};
static SspDmaStatusT defaultDmaTxStatus = {0,0,0,0};
static SspDmaStatusT defaultDmaRxStatus = {0,0,0,0};
static OSTContextT *ostCtxP = &Ost;
/*
*******************************************************************************
*
* FUNCTION: XsSspInterruptHandler
*
* DESCRIPTION: This routine is the interrupt handler for the SSP.
*
*
* INPUT PARAMETERS:
*
* RETURNS: None
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS: None
*
* CALLS: None
*
* CALLED BY: Anyone
*
* VOID XsSspInterruptHandler(SspContextT * ctxP);
*
*******************************************************************************
*/
VOID XsSspInterruptHandler(SspContextT * ctxP)
{
volatile SspRegT * regsP = (SspRegT *)ctxP->regsP;
DM_CwDbgPrintf(DM_CW_SSP, "XsSspInterrupt Handler\r\n");
// Check if the RX FIFO is empty.
if ((regsP->SSSR & SSP_SSSR_RNE) &&
((regsP->SSSR & SSP_SSSR_RFL_MASK) != SSP_SSSR_RFL_MASK))
{
ctxP->xferRxComplete = TRUE;
}
else
{
ctxP->xferRxComplete = FALSE;
}
// Check if the TX FIFO is empty.
if ((regsP->SSSR & SSP_SSSR_TNF) && (!(regsP->SSSR & SSP_SSSR_TFL_MASK)))
{
ctxP->xferTxComplete = TRUE;
}
else
{
ctxP->xferTxComplete = FALSE;
}
}
/*
******************************************************************************************
*
* FUNCTION: XsSspHWSetup
*
* DESCRIPTION: This function is used for hardware initialization of SSP.
* It uses the SSP configuration structure to configure SSP's
* modes of operation.
*
* INPUT PARAMETERS: ctxP is a pointer to SSP's context structure
*
* RETURNS: 0 if successful
* UINT32 in case of error.
*
* GLOBAL EFFECTS: none
*
* ASSUMPTIONS: none
*
*******************************************************************************************
*/
static
UINT32 XsSspHWSetup(SspContextT * ctxP)
{
volatile SspRegT * regsP = (SspRegT *)ctxP->regsP;
SspCfgT * cfgP = (SspCfgT *)ctxP->cfgP;
UINT scr;
UINT32 error = FALSE;
// Clear any previous setup
regsP->SSCR0 = 0;
regsP->SSCR1 = 0;
// Select the peripheral clock bit for the SSP
switch (ctxP->type & 0x03)
{
case SSP1:
xsCMEnableClock (CK_SSP);
break;
case SSP2:
xsCMEnableClock (CK_SSP2);
break;
case SSP3:
xsCMEnableClock (CK_SSP3);
}
// Clear SSSR.ROR if it was set
if (regsP->SSSR & SSP_SSSR_ROR)
regsP->SSSR = SSP_SSSR_ROR;
// Select to use on-chip or external clock
if (cfgP->extClock == SspExtClock)
{
// Configure GPIOs to input external clock
XsGpioSetSspExtClock (ctxP->type);
// Use external clock
regsP->SSCR0 |= SSP_SSCR0_ECS;
// Calculate the serial clock rate
scr = cfgP->SspExtClockFreq / cfgP->bitRate - 1;
regsP->SSCR0 |= (scr << SSP_SSCR0_SCR_SHIFT) & SSP_SSCR0_SCR_MASK;
}
else
{
// Configure GPIO[27]
XsGpioClearSspExtClock (ctxP->type);
// Use on-chip clock
regsP->SSCR0 &= ~SSP_SSCR0_ECS;
// Calculate the serial clock rate
// scr = (3686400 / cfgP->bitRate) - 1;
// regsP->SSCR0 |= (scr << SSP_SSCR0_SCR_SHIFT) & SSP_SSCR0_SCR_MASK;
scr = (13000000 / cfgP->bitRate) - 1;
regsP->SSCR0 |= (scr << SSP_SSCR0_SCR_SHIFT) & SSP_SSCR0_SCR_MASK;
}
// Choose SSP frame format
switch (cfgP->frameFormat)
{
case SspFormat_Spi:
regsP->SSCR0 |= SSP_SSCR0_FRF_SPI;
// Select SSPSCLK polarity
if (cfgP->polaritySPI == SpiPolarityLow)
regsP->SSCR1 &= ~SSP_SSCR1_SPO;
else
regsP->SSCR1 |= SSP_SSCR1_SPO;
// Select SSPSCLK phase
if (cfgP->phaseSPI == SpiPhaseOne)
regsP->SSCR1 &= ~SSP_SSCR1_SPH;
else
regsP->SSCR1 |= SSP_SSCR1_SPH;
break;
case SspFormat_Ssp:
regsP->SSCR0 |= SSP_SSCR0_FRF_SSP;
break;
case SspFormat_Mwire:
regsP->SSCR0 |= SSP_SSCR0_FRF_MICWIRE;
// Select Microware transmit data size
if (cfgP->dataMicroWire == MwireData8)
regsP->SSCR1 &= ~SSP_SSCR1_MWDS;
else
regsP->SSCR1 |= SSP_SSCR1_MWDS;
break;
case SspFormat_Psp:
// Set Programmable Serial Protocol.
regsP->SSCR0 |= SSP_SSCR0_FRF_PSP;
// Set serial bit-rate clock mode.
regsP->SSPSP &= ~SSP_SSPSP_SCMODE_MASK;
regsP->SSPSP |= (cfgP->scmodePsp << SSP_SSPSP_SCMODE_SHFT);
// Check serial frame polarity.
if (cfgP->sfrmpPsp)
regsP->SSPSP |= SSP_SSPSP_SFRMP;
else
regsP->SSPSP &= ~SSP_SSPSP_SFRMP;
// Check end of transfer data state
if (cfgP->etdsPsp)
regsP->SSPSP |= SSP_SSPSP_ETDS;
else
regsP->SSPSP &= ~SSP_SSPSP_ETDS;
// Set start delay.
regsP->SSPSP &= ~SSP_SSPSP_STRTDLY_MASK;
regsP->SSPSP |= (cfgP->strDlyPsp << SSP_SSPSP_STRTDLY_SHFT);
// Set dummy start.
regsP->SSPSP &= ~SSP_SSPSP_DMYSTRT_MASK;
regsP->SSPSP |= (cfgP->dmyStrtPsp << SSP_SSPSP_DMYSTRT_SHFT);
// Set serial frame delay
regsP->SSPSP &= ~SSP_SSPSP_SFRMDLY_MASK;
regsP->SSPSP |= (cfgP->sfrmDlyPsp << SSP_SSPSP_SFRMDLY_SHFT);
// Set serial frame width
regsP->SSPSP &= ~SSP_SSPSP_SFRMWDTH_MASK;
regsP->SSPSP |= (cfgP->sfrmWidthPsp << SSP_SSPSP_SFRMWDTH_SHFT);
// Set dummy stop
regsP->SSPSP &= ~SSP_SSPSP_DMYSTOP_MASK;
regsP->SSPSP |= (cfgP->dmyStopPsp << SSP_SSPSP_DMYSTOP_SHFT);
break;
default:
regsP->SSCR0 |= SSP_SSCR0_FRF_SSP;
}
// Select SSP data size
if (cfgP->dataSize > 16)
{
// Set SSCR0.DSS bits
regsP->SSCR0 |= (cfgP->dataSize - 1) & SSP_SSCR0_DSS_MASK;
// Set SSCR0.EDSS bit to select data size 17-32
regsP->SSCR0 |= SSP_SSCR0_EDSS;
}
else
{
// Set SSCR0.DSS bits
regsP->SSCR0 |= (cfgP->dataSize - 1) & SSP_SSCR0_DSS_MASK;
// Clear SSCR0.EDSS bit to select data size 4-16
regsP->SSCR0 &= ~SSP_SSCR0_EDSS;
}
// Set loopback mode
if (cfgP->loopback == SspLoopbackOn && cfgP->frameFormat != SspFormat_Mwire)
regsP->SSCR1 |= SSP_SSCR1_LBM;
else
regsP->SSCR1 &= ~SSP_SSCR1_LBM;
// Register interrupt handler if TX/RX interrupt enabled.
if ((cfgP->RxIntEnable == SspFIFOIntDisabled) &&
(cfgP->TxIntEnable == SspFIFOIntDisabled))
{
// Unregister interrupt handler.
XsIcUnRegisterHandler(XSIC_SSP_SGNL);
XsIcDisableIrqDeviceInt (XSIC_SSP_SGNL);
}
else
{
// Register interrupt handler.
XsIcRegisterHandler(XSIC_SSP_SGNL,
(XsIcL1IntHandlerFnPT)&XsSspInterruptHandler,
ctxP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -