📄 cpudma_if.c
字号:
/*
* description: CPUDMA I/F Module (S1R72DEVICE)
* Maker : Tsuyoshi Yamashita
* Copyright : (C)2004,SEIKO EPSON Corp. All Rights Reserved.
*
* --------------------------------------------------------------------------
*/
/*=== Include =============================================================*/
#include "string.h"
#include "SPRSTS.h"
#include "SPRDEF.h"
#include "OSCall.h"
#include "Reg72V05.h"
#include "CPUDMA_IF.h"
/*=== define =============================================================*/
/* CallBack */
#define CBINF_DMA0_CMP (0x00) /* DMA0 interrupt complete */
#define CBINF_DMA0_COUNTUP (0x01) /* DMA0 count overflow interrupt */
#define CBINF_DMA1_CMP (0x02) /* DMA0 interrupt complete */
#define CBINF_DMA1_COUNTUP (0x03) /* DMA0 count overflow interrupt */
#define MAX_CALLBACK (4)
/* Interrupt Status */
#define IS_MAIN_INT_STAT (0x00) /* Saving place of interrupt status */
#define IS_CPU_INT_STAT (0x01) /* Saving place of interrupt status */
#define MAX_IS (2) /* Number of interrupt status */
/* Main Int Stat Mask */
#define MASK_MAIN_INT_STAT (0x20) /* CPU_IntStat */
#define MASK_CPU_INT_STAT (0x0F) /* DMAx_Countup, DMAx_Cmp */
#define R8_INT_ALLZERO (0xFF)
#define R8_ALLZERO (0x00)
/* FLG */
#define STOP (0x00) /* Stop */
#define EXEC (0x01) /* Exec */
/* CPU DMA Port status */
typedef struct strmifport {
UCHAR portStatus; /* Port Status */
UCHAR execState; /* Exec State */
} CPUDMA_IFPORT;
/*=== Macro ===============================================================*/
#define IS_EPX_DIRIN(epn) (((epn) & 0x80) == 0x80 ? TRUE : FALSE)
#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 direct access */
/*=== Variable ================================================*/
/* Saving place of interrupt status */
static volatile UCHAR IntStat[MAX_IS];
static CPUDMA_IFPORT DmaPort[CPUDMA_IF_MAX_PORT]; /* Stream Port Number */
static CALLBACK_PROC CallbackTable[MAX_CALLBACK]; /* Callback Transfer Complete */
static volatile UCHAR tempCPU_IntStat;
static volatile UCHAR CPU_IntEnb;
/*=== Function Prototype ==================================================*/
static void ModuleInit ( void );
static void CPUDMA_IFISRProcess ( void );
/*=============================================================================
// description : Reset
// argument : None
// return : STATUS_SUCCESS Normal finish
// STATUS_UNSUCCESSFUL Not opened
// flag :
// global :
// =============================================================================
*/
LONG CPUDMA_IFReset ( void )
{
LONG retVal;
int i;
retVal = STATUS_SUCCESS;
ModuleInit();
/* Table of call back function */
for (i = 0;i < MAX_CALLBACK;i++) {
CallbackTable[i] = 0x00;
}
return retVal;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: CPUDMA_IFInitPort
// description : Initialize for each port.
//: Carry out initialization for specified port number. Release lock state too after initialization.
// argument : USHORT portNumber Port number
// return : LONG Process result
// STATUS_SUCCESS Success
////////////////////////////////////////////////////////////////////////
*/
LONG CPUDMA_IFInitPort( USHORT portNumber )
{
/* Init Port */
memset( &DmaPort[portNumber], 0x00, sizeof( DmaPort[portNumber] ) );
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: CPUDMA_IFLockPort
// description : Lock specified port.
// : In case of port specified by upper module is usable, lock the port,
// notify current state if the port is locked already.
// argument : USHORT portNumber Port number
// return : LONG Process result
// STATUS_SUCCESS Success
// STATU_LOCKED_PORT Specified port number is locked already
////////////////////////////////////////////////////////////////////////
*/
LONG CPUDMA_IFLockPort( USHORT portNumber )
{
/* Check Lock Port */
if( DmaPort[portNumber].portStatus != CPUDMA_IF_PORT_UNLOCK ) {
return STATUS_LOCKED_PORT;
}
/* Set Stream Mode */
if( portNumber == 0 )
{
RegSet(REG08_DMA0_Config,BIT_ActiveDMA); /* ActivePort */
}
else
{
RegSet(REG08_DMA1_Config,BIT_ActiveDMA); /* ActivePort */
}
/* Lock Port */
DmaPort[portNumber].portStatus = CPUDMA_IF_PORT_LOCK;
/* Complete */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: CPUDMA_IFUnlockPort
//
// description : Release lock to specified port.
//
// : Release lock to port specified by transfer start function
// of Stream Function Module
// Releasing is only can be done for device which had been locked.
//
// argument : USHORT portNumber Port number
//
// return : LONG Process result
// STATUS_SUCCESS Success
// STATU_NO_EXISTENCE_PORT Specified port is not exist
// STATU_EXECUTION_PORT Specified port number is on acting
////////////////////////////////////////////////////////////////////////
*/
LONG CPUDMA_IFUnlockPort( USHORT portNumber )
{
/* Check Port Exec */
if( DmaPort[portNumber].execState != STOP ) {
return STATUS_EXECUTION_PORT;
}
/* Unlock Port */
DmaPort[portNumber].portStatus = CPUDMA_IF_PORT_UNLOCK;
/* Complete */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: CPUDMA_IFSetConfig
// description : Configuration setting
// argument : UCHAR portNumber Port number
// PCPUDMA_IFDMA_INFO pDmaInfo DMA setting information
//
// return : LONG Process result
// STATUS_SUCCESS Success
// STATUS_INVALID_PARAMETER Parameter error
// STATUS_UNLOCK_PORT Port is not locked
// STATUS_EXECUTION_PORT Port is on execution
////////////////////////////////////////////////////////////////////////
*/
LONG CPUDMA_IFSetConfig ( UCHAR portNumber, const PCPUDMA_IFDMA_INFO pDmaInfo )
{
/* Port Lock Check */
if( DmaPort[portNumber].portStatus != CPUDMA_IF_PORT_LOCK )
{
return STATUS_UNLOCK_PORT;
}
/* Exec State Check */
if( DmaPort[portNumber].execState != STOP ) {
return STATUS_EXECUTION_PORT;
}
/* param check */
if( pDmaInfo == NULL )
{
return STATUS_INVALID_PARAMETER;
}
// Setting
if (pDmaInfo->bExeMode == CPUDMA_IF_FREE_RUN) {
RegModify(REG08_DMAx_Config(portNumber),MASK_FreeRun,BIT_FreeRun_FreeRun);
} else {
RegModify(REG08_DMAx_Config(portNumber),MASK_FreeRun,BIT_FreeRun_CountMode);
}
if (pDmaInfo->bMode == CPUDMA_IF_MODE_NOMAL) {
RegModify(REG08_DMAx_Config(portNumber),MASK_DMA_Mode,BIT_DMA_Mode_NormalMode);
} else {
RegModify(REG08_DMAx_Config(portNumber),MASK_DMA_Mode,BIT_DMA_Mode_AddressDecodeMode);
}
RegModify(REG08_DMAx_Config(portNumber),MASK_ReqAssertCount,pDmaInfo->bReqAsrtCnt);
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: CPUDMA_IFStart
// description : Begin DMA.
//
// argument : UCHAR portNumber Port number
// ULONG size Number of transfer
// return : LONG Process result
// STATUS_SUCCESS Success
// STATUS_INVALID_PARAMETER Parameter error
// STATUS_UNLOCK_PORT Port is not locked
// STATUS_EXECUTION_PORT Port is on execution
////////////////////////////////////////////////////////////////////////
*/
LONG CPUDMA_IFStart ( UCHAR portNumber, ULONG size )
{
/* Port Lock Check */
if( DmaPort[portNumber].portStatus != CPUDMA_IF_PORT_LOCK )
{
return STATUS_UNLOCK_PORT;
}
/* Exec State Check */
if( DmaPort[portNumber].execState != STOP ) {
return STATUS_EXECUTION_PORT;
}
/* Parameter check */
if( size == 0 )
{
return STATUS_INVALID_PARAMETER;
}
DmaPort[portNumber].execState = EXEC;
if (portNumber == 0) {
RegWrite(REG08_DMA0_Count_HH,(size >> 24) & 0xFF);
RegWrite(REG08_DMA0_Count_HL,(size >> 16) & 0xFF);
RegWrite(REG08_DMA0_Count_LH,(size >> 8) & 0xFF);
RegWrite(REG08_DMA0_Count_LL,size & 0xFF);
RegSet(REG08_DMA0_Control,BIT_DMA_Go);
} else {
RegWrite(REG08_DMA1_Count_HH,(size >> 24) & 0xFF);
RegWrite(REG08_DMA1_Count_HL,(size >> 16) & 0xFF);
RegWrite(REG08_DMA1_Count_LH,(size >> 8) & 0xFF);
RegWrite(REG08_DMA1_Count_LL,size & 0xFF);
RegSet(REG08_DMA1_Control,BIT_DMA_Go);
}
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: CPUDMA_IFStop
// argument : UCHAR portNumber Port number
//
// return : LONG Process result
// STATUS_SUCCESS Success
////////////////////////////////////////////////////////////////////////
*/
LONG CPUDMA_IFStop ( UCHAR portNumber )
{
/* Port Lock Check */
if( DmaPort[portNumber].portStatus != CPUDMA_IF_PORT_LOCK )
{
return STATUS_UNLOCK_PORT;
}
/* Exec State Check */
if( DmaPort[portNumber].execState != EXEC ) {
return STATUS_EXECUTION_PORT;
}
DmaPort[portNumber].execState = STOP;
if (portNumber == 0) {
RegWrite(REG08_DMA0_Control,BIT_DMA_Stop);
} else {
RegWrite(REG08_DMA1_Control,BIT_DMA_Stop);
}
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name:CPUDMA_IFSetIntEvent
// description : Interrupt setting process
// argument : UCHAR event Interrupt event
// UCHAR flag Flag of ON/OFF
//
// return : LONG
// STATUS_SUCCESS
////////////////////////////////////////////////////////////////////////
*/
LONG CPUDMA_IFSetIntEvent (UCHAR event,UCHAR flag)
{
if( flag == CPUDMA_IF_EVENTON )
{
if( event & CPUDMA_IF_DMA1_COUNTUP )
{
/* Make DMA1 Countup be valid */
RegWrite(REG08_CPU_IntStat,CPUDMA_IF_DMA1_COUNTUP); /* Clear the CPU DMA1 Coutup */
CLR_BIT(IntStat[IS_CPU_INT_STAT], CPUDMA_IF_DMA1_COUNTUP);
SET_BIT(CPU_IntEnb, CPUDMA_IF_DMA1_COUNTUP);
RegSet(REG08_MainIntEnb,BIT_EnCPU_IntStat);
RegSet(REG08_CPU_IntEnb,BIT_EnDMA1_CountUp);
}
if( event & CPUDMA_IF_DMA1_CMP )
{
/* Make DMA1 Countup be valid */
RegWrite(REG08_CPU_IntStat,CPUDMA_IF_DMA1_CMP); /* Clear the CPU DMA1 Cmp */
CLR_BIT(IntStat[IS_CPU_INT_STAT], CPUDMA_IF_DMA1_CMP);
SET_BIT(CPU_IntEnb, CPUDMA_IF_DMA1_CMP);
RegSet(REG08_MainIntEnb,BIT_EnCPU_IntStat);
RegSet(REG08_CPU_IntEnb,BIT_EnDMA1_Cmp);
}
if( event & CPUDMA_IF_DMA0_COUNTUP )
{
/* Make DMA1 Countup be valid */
RegWrite(REG08_CPU_IntStat,CPUDMA_IF_DMA0_COUNTUP); /* Clear the CPU DMA1 Coutup */
CLR_BIT(IntStat[IS_CPU_INT_STAT], CPUDMA_IF_DMA0_COUNTUP);
SET_BIT(CPU_IntEnb, CPUDMA_IF_DMA0_COUNTUP);
RegSet(REG08_MainIntEnb,BIT_EnCPU_IntStat);
RegSet(REG08_CPU_IntEnb,BIT_EnDMA0_CountUp);
}
if( event & CPUDMA_IF_DMA0_CMP )
{
/* Make DMA1 Countup be valid */
RegWrite(REG08_CPU_IntStat,CPUDMA_IF_DMA0_CMP); /* Clear the CPU DMA1 Cmp */
CLR_BIT(IntStat[IS_CPU_INT_STAT], CPUDMA_IF_DMA0_CMP);
SET_BIT(CPU_IntEnb, CPUDMA_IF_DMA0_CMP);
RegSet(REG08_MainIntEnb,BIT_EnCPU_IntStat);
RegSet(REG08_CPU_IntEnb,BIT_EnDMA0_Cmp);
}
}
else
{
if( event & CPUDMA_IF_DMA1_COUNTUP )
{
/* Make DMA1 Countup be invalid */
RegClear(REG08_MainIntEnb,BIT_EnCPU_IntStat);
CLR_BIT(CPU_IntEnb, CPUDMA_IF_DMA1_COUNTUP);
}
if( event & CPUDMA_IF_DMA1_CMP )
{
/* Make DMA1 Countup be invalid */
RegClear(REG08_MainIntEnb,BIT_EnCPU_IntStat);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -