📄 fifo_if.c
字号:
/*
* description: FIFO I/F Module (S1R72V05)
* Maker : Tsuyoshi Yamashita
* Copyright : (C)2004,SEIKO EPSON Corp. All Rights Reserved.
*
* --------------------------------------------------------------------------
*/
/*=== Include =============================================================*/
#include <string.h>
#include "SPRSTS.h"
#include "fifo_if.h"
#include "Reg72V05.h"
#include "OSCall.h"
/*=== Define ==============================================================*/
#define MAX_FIFO (5) /* EP0,EPa,EPb,EPc,Media */
#define MAX_REGISTER_NUM (2) /* Maximum number of registration */
/* Callbacks */
#define CBINF_FIFO_IDE_CMP (0x00) /* FIFO_IDE_CMP */
#define CBINF_FIFO0_CMP (0x01) /* FIFO0_CMP */
#define CBINF_FIFO1_CMP (0x02) /* FIFO1_CMP */
#define CBINF_FIFO_FULL (0x03) /* FIFO_FULL */
#define CBINF_FIFO_EMPTY (0x04) /* FIFO_EMPTY */
#define MAX_CALLBACK (8) /* Number of callback */
/* Int Stat Mask */
#define MASK_MAIN_INT_STAT (0x88) /* MainIntStat.DeviceIntStat,MainIntStat.MediaFIFO_IntStat */
#define MASK_DEVICE_INT_STAT (0x04) /* DeviceIntStat.D_FIFO_IntStat */
#define MASK_FIFO_INT_STAT (0x73) /* FIFO_IDE_CMP,FIFO1_CMP,FIFO0_CMP,FIFO_FULL,FIFO_EMPTY */
#define R8_INT_ALLZERO (0xFF)
#define R8_ALLZERO (0x00)
/* Mask for RdRemain */
#define RD_REMAIN_VALID_MASK (0x8000)
#define FRACTION_MASK (0x0001)
/* INT Check */
#define INT_FIFO_IDE_CMP (0x40) /* FIFO_IDE_CMP */
#define INT_FIFO1_CMP (0x20) /* FIFO1_CMP */
#define INT_FIFO0_CMP (0x10) /* FIFO0_CMP */
#define INT_FIFO_FULL (0x02) /* FIFO_FULL */
#define INT_FIFO_EMPTY (0x01) /* FIFO_EMPTY */
#define INT_FIFO_NOT_EMPTY (0x04) /* FIFO_NOT_EMPTY */
/*=== Structure ===========================================================*/
/* Transfer information for EP */
typedef struct fifoinfo {
UCHAR ByteAccess:1; /* ByteAccess */
UCHAR Reserved:7; /* Reserved */
} FIFO_INFO;
/*=== Macro ===============================================================*/
#define IS_BIT(bits,mask) (((bits) & (mask)) != 0x00 ? TRUE : FALSE)
#define CLR_BIT(bits,mask) ((bits) = ((bits) & ~(mask)))
#define SET_BIT(bits,mask) ((bits) = ((bits) | (mask)))
#define DIRECT_B(a) *(unsigned char *)&(a) /* Structure's direct access */
/*=== Variable ============================================================*/
/* Save area of Interrupt status */
static volatile UCHAR FIFO_IntStat;
/* Save area of Interrupt factor */
static volatile UCHAR FIFO_IntEnb;
/* FIFO information */
static FIFO_INFO sFifoInfo[MAX_FIFO];
/* Table of callback function */
static CALLBACK_PROC CallbackTable[MAX_REGISTER_NUM][MAX_CALLBACK];
/*=== Function Prototype ==================================================*/
static LONG InitVariables(void);
static void IntStatusCheck(UCHAR bFIFO_IntStat);
static LONG SendCallback( UCHAR event, ULONG lParam0, ULONG lParam1, VOID *pParam );
/* =============================================================================
// Function_Name: SendCallback
// description : Call the callback function
// argument : None
// return : STATUS_SUCCESS Terminated normally
// flag :
// global :
// =============================================================================
*/
Inline LONG SendCallback( UCHAR event, ULONG lParam0, ULONG lParam1, VOID *pParam )
{
LONG retValue;
UCHAR i;
retValue = STATUS_UNSUCCESSFUL;
for( i = 0; i < MAX_REGISTER_NUM; i++ )
{
if( CallbackTable[i][event] != NULL )
{
retValue = CallbackTable[i][event]( lParam0, lParam0, pParam );
}
}
return retValue;
}
/* =============================================================================
// Function_Name: FIFO_IFReset
// description : Reset the FIFO I/F
// argument : None
// return : STATUS_SUCCESS Terminated normally
// flag :
// global :
// =============================================================================
*/
LONG FIFO_IFReset(void)
{
LONG retValue;
retValue = STATUS_SUCCESS;
while (1) {
/* Variable Initialization*/
retValue = InitVariables();
if (retValue != STATUS_SUCCESS) {
break;
}
// Enable the main interrupt
RegSet(REG08_MainIntEnb,BIT_EnDeviceIntStat);
RegSet(REG08_DeviceIntEnb,BIT_EnD_FIFO_IntStat);
RegSet(REG08_MainIntEnb,BIT_EnMediaFIFO_IntStat);
break;};
return retValue;
}
/* =============================================================================
// Function_Name: FIFO_IFGetFIFODirection
// description : Get the FIFO's transfer direction
// argument : number fifo number (0,1,2,3)
// direction Pointer to return direction
// FIFO_IF_DIRIN IN
// FIFO_IF_DIROUT OUT
// return : STATUS_SUCCESS Terminated normally
// STATUS_NOT_OPENED Not opened
// flag :
// global :
// =============================================================================
*/
LONG FIFO_IFGetFIFODirection(UCHAR number,UCHAR *direction)
{
LONG retValue;
retValue = STATUS_SUCCESS;
while (1) {
if (number >= MAX_FIFO) {
retValue = STATUS_INVALID_PARAMETER;
break;
}
if( number == FIFO_IF_NUM_FIFO_MEDIA ) {
if ((RegRead(REG08_IDE_Control) & MASK_IDE_Dir) == BIT_IDEtoFIFO) {
*direction = FIFO_IF_DIRIN;
} else {
*direction = FIFO_IF_DIROUT;
}
break;
}
if (number == 0) {
if ((RegRead(REG08_D_EP0Control) & MASK_INxOUT) == BIT_INxOUT_IN) {
*direction = FIFO_IF_DIRIN;
} else {
*direction = FIFO_IF_DIROUT;
}
} else {
if ((RegRead(REG08_D_EPxConfig_0(number - 1)) & MASK_INxOUT) == BIT_INxOUT_IN) {
*direction = FIFO_IF_DIRIN;
} else {
*direction = FIFO_IF_DIROUT;
}
}
break;};
return retValue;
}
/* =============================================================================
// Function_Name: FIFO_IFSetFIFODirection
// description : Set the FIFO's transfer direction
// argument : fifoNum fifo number(0,1,2,3)
// direction Set the direction
// FIFO_IF_DIRIN IN
// FIFO_IF_DIROUT OUT
// return : STATUS_SUCCESS Terminated normally
// STATUS_NOT_OPENED Not opened
// flag :
// global :
// =============================================================================
*/
LONG FIFO_IFSetFIFODirection(UCHAR number,UCHAR direction)
{
LONG retValue;
retValue = STATUS_SUCCESS;
while (1) {
if (number >= MAX_FIFO) {
retValue = STATUS_INVALID_PARAMETER;
break;
}
if (!(direction == FIFO_IF_DIRIN || direction == FIFO_IF_DIROUT)) {
retValue = STATUS_INVALID_PARAMETER;
break;
}
if( number != FIFO_IF_NUM_FIFO_MEDIA ) {
if (number == 0) {
if (direction == FIFO_IF_DIRIN) {
RegModify(REG08_D_EP0Control,MASK_INxOUT,BIT_INxOUT_IN);
} else {
RegModify(REG08_D_EP0Control,MASK_INxOUT,BIT_INxOUT_OUT);
}
} else {
if (direction == FIFO_IF_DIRIN) {
RegModify(REG08_D_EPxConfig_0(number - 1),MASK_INxOUT,BIT_INxOUT_IN);
} else {
RegModify(REG08_D_EPxConfig_0(number - 1),MASK_INxOUT,BIT_INxOUT_OUT);
}
}
}
if (direction == FIFO_IF_DIRIN ) {
RegModify(REG08_DMA0_Control,MASK_DMA_Dir,BIT_DMA_DirFromFIFO);
} else {
RegModify(REG08_DMA0_Control,MASK_DMA_Dir,BIT_DMA_DirToFIFO);
}
break;};
return retValue;
}
/* =============================================================================
// Function_Name: FIFO_IF_FIFORead
// description : Read data from FIFO
// argument : number FIFO number
// pBuffer Pointer to store data
// numOfByteToRead Number of bytes to read
// pCount Pointer to return the actually read number of bytes
// return : STATUS_SUCCESS Terminated normally
// STATUS_NOT_OPENED Not opened
// STATUS_INVALID_PARAMETER Parameter error
// flag :
// global :
// =============================================================================
*/
LONG FIFO_IF_FIFORead(UCHAR number,UCHAR* pBuffer,ULONG numOfByteToRead,ULONG *pCount)
{
LONG retValue;
ULONG count,readByte,i;
USHORT wFIFODataCount;
UCHAR *ptr;
UCHAR bFraction;
UCHAR bTemp[2];
retValue = STATUS_SUCCESS;
while (1) {
if (number >= MAX_FIFO) {
/* Specified the FIFO number when it cannot be specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if( number == FIFO_IF_NUM_FIFO_MEDIA ) {
if ((RegRead(REG08_MediaFIFO_Join) & (MASK_JoinDMA0 | MASK_JoinDMA1))) {
/* This FIFO became error when Joined with DMA */
retValue = STATUS_UNSUCCESSFUL;
break;
}
RegSet(REG08_MediaFIFO_Join,BIT_JoinCPU_Rd); /* Select Join CPU_Rd */
} else {
if (number == 0) {
if ((RegRead(REG08_D_EP0Join) & (MASK_JoinDMA0 | MASK_JoinDMA1))) {
/* This FIFO became error when Joined with DMA */
retValue = STATUS_UNSUCCESSFUL;
break;
}
RegSet(REG08_D_EP0Join,BIT_JoinCPU_Rd); /* Select Join CPU_Rd */
} else {
if ((RegRead(REG08_D_EPxJoin(number - 1)) & (MASK_JoinDMA0 | MASK_JoinDMA1))) {
/* This FIFO became error when Joined with DMA */
retValue = STATUS_UNSUCCESSFUL;
break;
}
RegSet(REG08_D_EPxJoin(number - 1),BIT_JoinCPU_Rd);
}
}
bTemp[1] = RegRead(REG08_FIFO_RdRemain_H);
bTemp[0] = RegRead(REG08_FIFO_RdRemain_L);
wFIFODataCount = MAKEWORD(bTemp[0],bTemp[1]); /* Dummy Cycle for waiting cash operation's start */
do {
bTemp[1] = RegRead(REG08_FIFO_RdRemain_H);
bTemp[0] = RegRead(REG08_FIFO_RdRemain_L);
wFIFODataCount = MAKEWORD(bTemp[0],bTemp[1]);
} while (!(wFIFODataCount & RD_REMAIN_VALID_MASK));
wFIFODataCount &= ~RD_REMAIN_VALID_MASK;
readByte = count = MIN(wFIFODataCount,numOfByteToRead);
ptr = pBuffer;
if (count > 0 && sFifoInfo[number].ByteAccess == 1) {
/* After Byte Access */
*ptr++ = RegRead(REG08_FIFO_ByteRd);
count--;
sFifoInfo[number].ByteAccess = 0;
}
bFraction = (count & FRACTION_MASK);
for (i = count / 2;i > 0;i--) {
*ptr++ = RegRead(REG08_FIFO_ByteRd);
*ptr++ = RegRead(REG08_FIFO_ByteRd);
}
if (bFraction != 0) {
*ptr++ = RegRead(REG08_FIFO_ByteRd);
sFifoInfo[number].ByteAccess = 1;
}
if( number == FIFO_IF_NUM_FIFO_MEDIA ) {
RegClear(REG08_MediaFIFO_Join,BIT_JoinCPU_Rd); /* Clear EP0 Join_Rd */
} else {
if (number == 0) {
RegClear(REG08_D_EP0Join,BIT_JoinCPU_Rd); /* Clear EP0 Join_Rd */
} else {
RegClear(REG08_D_EPxJoin(number - 1),BIT_JoinCPU_Rd); /* Clear EPa,EPb,EPc Join_Rd */
}
}
/* Return the read number */
*pCount = readByte;
break;};
return retValue;
}
/* =============================================================================
// Function_Name: FIFO_IFEPxFIFOWrite
// description : Write data in FIFO
// argument: number FIFO number
// pBuffer Pointer of writing data
// numOfByteToRead Number of bytes to write
// pCount Pointer to return actually written number of bytes
// return : STATUS_SUCCESS Terminated normally
// STATUS_NOT_OPENED Not opened
// STATUS_INVALID_PARAMETER Parameter error
// flag :
// global :
// =============================================================================
*/
LONG FIFO_IF_FIFOWrite(UCHAR number,const UCHAR *pBuffer,ULONG numOfByteToWrite,ULONG *pCount)
{
LONG retValue;
ULONG count,writeByte,i;
USHORT wFIFODataRemain;
UCHAR *ptr;
UCHAR bFraction;
UCHAR bTemp[2];
retValue = STATUS_SUCCESS;
while (1) {
if (number >= MAX_FIFO) {
/* Specified the FIFO when it cannot be specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if( number == FIFO_IF_NUM_FIFO_MEDIA ) {
if ((RegRead(REG08_MediaFIFO_Join) & (MASK_JoinDMA0 | MASK_JoinDMA1))) {
/* This FIFO became error when Joined with DMA */
retValue = STATUS_UNSUCCESSFUL;
break;
}
RegSet(REG08_MediaFIFO_Join,BIT_JoinCPU_Wr); /* Select Join CPU_Rd */
} else {
if (number == 0) {
if ((RegRead(REG08_D_EP0Join) & (MASK_JoinDMA0 | MASK_JoinDMA1))) {
/* This FIFO became error when Joined with DMA */
retValue = STATUS_UNSUCCESSFUL;
break;
}
RegSet(REG08_D_EP0Join,BIT_JoinCPU_Wr); /* Select Join CPU_Rd */
} else {
if ((RegRead(REG08_D_EPxJoin(number - 1)) & (MASK_JoinDMA0 | MASK_JoinDMA1))) {
/* This FIFO became error when Joined with DMA */
retValue = STATUS_UNSUCCESSFUL;
break;
}
RegSet(REG08_D_EPxJoin(number - 1),BIT_JoinCPU_Wr);
}
}
ptr = (UCHAR *)pBuffer;
bTemp[1] = RegRead(REG08_FIFO_WrRemain_H);
bTemp[0] = RegRead(REG08_FIFO_WrRemain_L);
wFIFODataRemain = MAKEWORD(bTemp[0],bTemp[1]);
writeByte = count = MIN(wFIFODataRemain,numOfByteToWrite);
if (count > 0 && sFifoInfo[number].ByteAccess == 1) {
RegWrite(REG08_FIFO_Wr_1,*ptr);ptr++;
count--;
sFifoInfo[number].ByteAccess = 0;
}
bFraction = (count & FRACTION_MASK);
/* When ptr is odd address */
for (i = count / 2;i > 0;i--) {
RegWrite(REG08_FIFO_Wr_0,*ptr);ptr++;
RegWrite(REG08_FIFO_Wr_1,*ptr);ptr++;
}
if (bFraction != 0) {
RegWrite(REG08_FIFO_Wr_0,*ptr);ptr++;
sFifoInfo[number].ByteAccess = 1;
}
if( number == FIFO_IF_NUM_FIFO_MEDIA ) {
RegClear(REG08_MediaFIFO_Join,BIT_JoinCPU_Wr); /* Clear EP0 JoinCPU_Wr */
} else {
if (number == 0) {
RegClear(REG08_D_EP0Join,BIT_JoinCPU_Wr); /* Clear EP0 JoinCPU_Wr */
} else {
RegClear(REG08_D_EPxJoin(number - 1),BIT_JoinCPU_Wr); /* Clear EPa,EPb,EPc JoinCPU_Wr */
}
}
/* Return the number of bytes which has been written */
*pCount = (ULONG)writeByte;
break;};
return retValue;
}
/* =============================================================================
// Function_Name: FIFO_IF_FIFORdRemain
// description : Return the number that can be read from FIFO
// argument : number FIFO number
// pRemain Pointer to return number that can be read
// return : STATUS_SUCCESS Terminated normally
// STATUS_NOT_OPENED Not opened
// STATUS_INVALID_PARAMETER Parameter error
// flag :
// global :
// =============================================================================
*/
LONG FIFO_IF_FIFORdRemain(UCHAR number,ULONG *pRemain)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -