📄 ssi2.c
字号:
//****************************************************************************
//
// SSI2.C - Routines to enable the SSI2 interface and use it to send and
// receive data
//
// Copyright (c) 2001 Cirrus Logic, Inc.
//
//****************************************************************************
#include "ep7312.h"
#include "lib7312.h"
//****************************************************************************
//
// The following variables describe the buffer of data that is to be sent out
// via the SSI2 interface.
//
//****************************************************************************
static char cOutputData[64];
static long lOutputRead, lOutputWrite;
//****************************************************************************
//
// The following variables describe the buffer of data that has been read via
// the SSI2 interface.
//
//****************************************************************************
static char cInputData[64];
static long lInputRead, lInputWrite;
//****************************************************************************
//
// SSI2ISR is the interrupt handler for the SSI2 interrupt. It will write
// data into the output FIFO and read any available samples from the input
// FIFO.
//
//****************************************************************************
static void
SSI2ISR(void)
{
unsigned long * volatile pulPtr = (unsigned long *)HwBaseAddress;
unsigned long ulTemp;
//
// If the transmit FIFO has space available, then fill it with all the
// data we have available.
//
while(!(pulPtr[HwStatus2 >> 2] & HwStatus2SSI2TxFIFOFull))
{
//
// If we have no more data in the output queue (or there is only a
// single byte), then disable the transmit interrupt.
//
if(((lOutputRead == lOutputWrite) ||
(((lOutputRead + 1) & 63) == lOutputWrite)))
{
//
// Disable the SSI2 transmit interrupt.
//
pulPtr[HwIntMask2 >> 2] &= ~HwIrqSSI2Tx;
//
// Stop trying to fill the transmit FIFO.
//
break;
}
//
// Write a pair of bytes to the transmit FIFO.
//
pulPtr[HwSSI2Data >> 2] = (cOutputData[lOutputRead] << 8) |
cOutputData[lOutputRead + 1];
//
// Skip to the next pair of bytes in the buffer.
//
lOutputRead = (lOutputRead + 2) & 63;
}
//
// If the receive FIFO has data in it, then read it.
//
while(!(pulPtr[HwStatus2 >> 2] & HwStatus2SSI2RxFIFOEmpty))
{
//
// Read the next pair of bytes from the receive FIFO.
//
ulTemp = pulPtr[HwSSI2Data >> 2];
//
// Place the individual bytes into the receive buffer.
//
cInputData[lInputWrite] = (ulTemp >> 8) & 255;
cInputData[lInputWrite + 1] = ulTemp & 255;
//
// Skip to the next pair of bytes in the buffer.
//
lInputWrite = (lInputWrite + 2) & 63;
}
}
//****************************************************************************
//
// SSI2Enable configures the SSI2 interface for sending and receiving data.
//
//****************************************************************************
void
SSI2Enable(int bMaster)
{
unsigned long * volatile pulPtr = (unsigned long *)HwBaseAddress;
//
// Select the SSI2 interface instead of CODEC/DAI.
//
pulPtr[HwControl2 >> 2] &= ~HwControl2CodecEnable;
pulPtr[HwControl3 >> 2] &= ~HwControl3DAISelect;
//
// Set the clock rate to 128KHz.
//
pulPtr[HwControl >> 2] &= ~HwControlSpiClockSelect;
pulPtr[HwControl >> 2] |= HwControlSpiClock128KHz;
//
// Set the interface to master or slave as requested.
//
if(bMaster)
{
pulPtr[HwControl2 >> 2] |= HwControl2SSI2MasterEnable;
}
else
{
pulPtr[HwControl2 >> 2] &= ~HwControl2SSI2MasterEnable;
}
//
// Enable the SSI2 transmit and receive paths.
//
pulPtr[HwControl2 >> 2] |= HwControl2SSI2TxEnable | HwControl2SSI2RxEnable;
//
// Install the interrupt handler for the SSI2 interrupt.
//
InterruptInstallIRQ();
InterruptSetSSI2Handler(SSI2ISR);
//
// Enable the SSI2 receive interrupt.
//
pulPtr[HwIntMask2 >> 2] |= HwIrqSSI2Rx;
}
//****************************************************************************
//
// SSI2Disable shuts down the SSI2 interface.
//
//****************************************************************************
void
SSI2Disable(void)
{
unsigned long * volatile pulPtr = (unsigned long *)HwBaseAddress;
//
// Disable the SSI2 interrupts.
//
pulPtr[HwIntMask2 >> 2] &= ~(HwIrqSSI2Rx | HwIrqSSI2Tx);
//
// Remove the SSI2 interrupt handler.
//
InterruptSetSSI2Handler(0);
InterruptRemoveIRQ();
//
// Disable the SSI2 transmit and receive paths.
//
pulPtr[HwControl2 >> 2] &= ~(HwControl2SSI2TxEnable |
HwControl2SSI2RxEnable);
}
//****************************************************************************
//
// SSI2SendChar sends a character via the SSI2 interface. The data will only
// be sent out the SSI2 interface in pairs...a single character will remain
// in the buffer waiting to be sent forever if a pair is not sent as well.
//
//****************************************************************************
void
SSI2SendChar(char cChar)
{
unsigned long * volatile pulPtr = (unsigned long *)HwBaseAddress;
//
// Write the character into the output buffer.
//
cOutputData[lOutputWrite] = cChar;
//
// Increment the write pointer.
//
lOutputWrite = (lOutputWrite + 1) & 63;
//
// Enable the SSI2 transmit interrupt.
//
pulPtr[HwIntMask2 >> 2] |= HwIrqSSI2Tx;
}
//****************************************************************************
//
// SSI2ReceiveChar returns a character read via the SSI2 interface. Data will
// only be available when a pair of values have been read from the interface.
//
//****************************************************************************
char
SSI2ReceiveChar(void)
{
char cRet;
//
// Wait until there is data available to be read.
//
while(lInputRead == lInputWrite)
{
}
//
// Read a character from the input buffer.
//
cRet = cInputData[lInputRead];
//
// Increment the read pointer.
//
lInputRead = (lInputRead + 1) & 63;
//
// Return the character we read.
//
return(cRet);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -