📄 devio.c
字号:
/* Copyright 1997-2002, ESS Technology, Inc. */
/* SCCSID @(#)devio.c 1.1 09/30/04 */
/********************************************************************
Copyright (C) 2003 UBiSYS Technology Limited.
All rights reserved.
author : dahlsse
created : 2004-08-16
filename : DevIO.c
purpose : Device Interface Layer for UBi9021
target mcu: ES 6218S
notes :
history :
*********************************************************************/
#ifdef UBI9021
#include "common.h"
#include "mvd.h"
#include "util.h"
#include "ioport.h"
#include "debug.h"
#include "ubicmn.h"
#include "ubi9021_.h"
#include "DevIO.h"
//#define GL812_base_ptr 0x14000000
extern volatile unsigned char* GL812_base_ptr;
#ifdef REC_FMM
#define GL812_CS ((volatile unsigned char*)GL812_base_ptr+0x604)
#define GL812_ALE_down ((volatile unsigned char*)GL812_base_ptr+0x600)
#define GL812_deselect ((volatile unsigned char*)GL812_base_ptr+0x606)
#define GL812_data_port ((volatile unsigned char*)GL812_base_ptr+0x200)
#elif defined(BD_VIPER)
#define GL812_CS ((volatile unsigned char*)GL812_base_ptr+0x1c)
#define GL812_ALE_down ((volatile unsigned char*)GL812_base_ptr+0x18)
#define GL812_deselect ((volatile unsigned char*)GL812_base_ptr+0x1e)
#define GL812_data_port ((volatile unsigned char*)GL812_base_ptr+0x10)
#else
#define GL812_CS ((volatile unsigned char*)GL812_base_ptr+0xc)
#define GL812_ALE_down ((volatile unsigned char*)GL812_base_ptr+0x8)
#define GL812_deselect ((volatile unsigned char*)GL812_base_ptr+0xe)
#define GL812_data_port ((volatile unsigned char*)GL812_base_ptr+0x0)
#endif
//-------------------------------------------------------------------------------
// gloable variables
//-------------------------------------------------------------------------------
U8 gBUF[512]; //sector buffer (available for other jobs, if not accessing USB)
//..must be aligned to DWORD(?)
U8* pBUF; //pointer to gBUF
U32 gWaitPktTicks = UMO_WAIT_USB_PKT_TICKS; //timeout value for usb packet waiting
U8 gInitState = IS_NO_INIT;
//-------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------
void DEV_WriteReg(U8 addr, U8 data)
{
*GL812_ALE_down= 0xff;
*GL812_data_port= addr;
RISC_sleep_cycles(25);
//*GL812_deselect=0xff;
*GL812_CS= 0xff;
*GL812_data_port= data;
RISC_sleep_cycles(25);
*GL812_deselect=0xff;
}
U8 DEV_ReadReg(U8 addr)
{
register U8 data;
*GL812_ALE_down= 0xff;
*GL812_data_port= addr;
RISC_sleep_cycles(20);
//*GL812_deselect=0xff;
*GL812_CS= 0xff;
data =*GL812_data_port;
RISC_sleep_cycles(20);
*GL812_deselect=0xff;
return data;
}
void DEV_WriteRegMulti(U8 addr, U16 cnt, U8* buf)
{
unsigned short i;
unsigned char *dptr;
dptr = buf;
*GL812_ALE_down= 0xff;
*GL812_data_port= addr;
RISC_sleep_cycles(25);
//*GL812_deselect=0xff;
*GL812_CS= 0xff;
for(i=0x0;i<cnt;i++) {
*GL812_data_port= *dptr++;
RISC_sleep_cycles(25);
}
*GL812_deselect=0xff;
}
U8 DEV_ReadRegMulti(U8 addr, U16 cnt, U8* buf)
{
unsigned short i;
register U8 data;
*GL812_ALE_down= 0xff;
*GL812_data_port= addr;
RISC_sleep_cycles(20);
//*GL812_deselect=0xff;
*GL812_CS= 0xff;
if(buf!=TxNULL){
for(i=0x0;i<cnt;i++) {
*buf++ =*GL812_data_port;
RISC_sleep_cycles(20);
}
}
else{
for(i=0x0;i<cnt;i++) {
data =*GL812_data_port;
RISC_sleep_cycles(20);
}
}
*GL812_deselect= 0xff;
return data;
}
//_____________________________________________________________________________
//
// UBi9021 Register Read / Write Test Routine
//
// * When you confirm register read and write, *
// * you must plug-in the usb mass storage device. *
// * Because when usb device is not connected, *
// * UBi9021 registers are not working. *
//_____________________________________________________________________________
//
#if defined(DEV_IO_TEST)
R8 DEV_TEST_Exit(void)
{
U8 volatile i=1;
while(i);
return RES_ERR;
}
/******************************************************************************
*
* DSESCRIPION:
* write to an UBi9021 register..
* and compare with read value
*
* INPUT:
* - reg: register address
* - iterCnt: interation count
*
* RETURN:
* RES_OK:
* RES_ERR:
*
******************************************************************************/
R8 DEV_TEST_1_RegRW(U8 reg, U16 iterCnt)
{
U16 i;
if(iterCnt==0)iterCnt=1;
else if(iterCnt>256)iterCnt=256;
for(i=0;i<iterCnt;i++){
DEV_WriteReg(reg,i);
if(DEV_ReadReg(reg)!=i){
return RES_ERR;
}
}
return RES_OK;
}
/******************************************************************************
*
* DSESCRIPION:
* UBi9021 SOF interrupt test
*
* RETURN:
* RES_OK:
* RES_ERR: timeout
*
******************************************************************************/
R8 DEV_TEST_2_SOF_n_Interrupt(void)
{
U16 ticks;
DEV_WriteReg(RH_CHIP_CTR2,0x20); //reset
DEV_WriteReg(RD_CHIP_CTR,0x40); //host mode
DEV_WriteReg(RH_CHIP_CTR2,0x10); //enable SOF
DEV_WriteReg(RH_INT_EN,UH_IRQ_SOF); //enable SOF interrupt
for(ticks=0;ticks<30000;ticks++)
{
if(UBi9021_IRQ_PENDING())
{
U8 irqSts = DEV_ReadReg(RH_INT_STS);
if(irqSts&UH_IRQ_SOF) return RES_OK;
}
}
return RES_ERR;
}
/******************************************************************************
*
* DSESCRIPION:
* write "rwSize" bytes to UBi9021 FIFO
* and read ,, then compare both values
*
* INPUT:
* - mode : 1=using multiple-read-write,
* 0=using singe-read-write
* - iterCnt : interation count (1~256)
* - rwSize : read-write byte size (1~512)
*
* RETURN:
* RES_OK:
* RES_ERR:
*
******************************************************************************/
R8 DEV_TEST_3_FifoRW(U8 mode, U16 iterCnt, U16 rwSize)
{
U16 i,j;
if(iterCnt==0)iterCnt=1;
else if(iterCnt>256)iterCnt=256;
if(rwSize==0)rwSize=1;
else if(rwSize>512)rwSize=512;
for (i=0; i<iterCnt; i++)
{
//FIFO write
//
for(j=0;j<rwSize;j++)gBUF[j]=j+i;
DEV_WriteReg(0x06,0x08);//fifo pointer: 0, fifo direction : out
if(mode==1){//using Multiple-Read-Write Routine
DEV_WriteRegMulti(0x0B,rwSize,gBUF);
}
else{//using Single-Read-Write Routine
for(j=0;j<rwSize;j++) DEV_WriteReg(0x0B,j+i);
}
//FIFO read
//
for(j=0;j<10;j++)NOOP();//idle
DEV_WriteReg(0x06,0x09);//fifo pointer: 0, fifo direction : in
if(mode==1){//using Multiple-Read-Write Routine
DEV_ReadRegMulti(0x0B,rwSize,gBUF);
}
else{//using Single-Read-Write Routine
for(j=0;j<rwSize;j++) gBUF[j]=DEV_ReadReg(0x0B);
}
//compare
//
for(j=0;j<rwSize;j++){
if(gBUF[j]!=(U8)(j+i)){
return RES_ERR;
}
}
}
return RES_OK;
}
/******************************************************************************
* get "gWaitPktTicks"(interation count between specified SOF interrupt)
*
* RETURN:
* - 0
* - Wait ticks value
*
******************************************************************************/
XD U8 usbIrq, pktSts;
U32 DEV_TEST_4_GetWaitPacketTicks(U16 sofCount)
{
volatile U16 sofCnt;
volatile U32 ticks;
if(!UH_DEV_IS_PLUGGEDIN()) return 0;
DEV_WriteReg(RH_CHIP_CTR2,0x20); //reset
DEV_WriteReg(RD_CHIP_CTR,0x40); //host mode
DEV_WriteReg(RH_CHIP_CTR2,0x10); //enable SOF
DEV_WriteReg(RH_INT_EN,UH_IRQ_SOF);
while(!UBi9021_IRQ_PENDING());
for(usbIrq=0,ticks=0,sofCnt=0; ticks<0x70000000; ticks++)
{
/*
* Intentionally made similar to "DEV_WaitTicks"
* so that delay effects can be same as far as possible.
*/
if(UBi9021_IRQ_PENDING()){
GET_UBi9021_IRQ_STS(usbIrq);
}
if(usbIrq&UH_IRQ_SOF){
if(++sofCnt>=(U16)sofCount){
DEV_WriteReg(RH_INT_EN,0);
return ticks;
}
}
//pktSts = DEV_ReadReg(RH_LAST_PKT_STS);
//if(pktSts&UH_LST_PKT_STS_NAK) pktSts=0;
usbIrq = 0;
if(ISERR(DEV_CheckDeviceConnection())) break;
UBi9021_SLEEP_BETWEEN_IRQ_CHECK(); //if any, maximum 100usec (?)
}
return 0;
}
#if 0
void main(void)
{
U8 res;
#if defined(CASPO64)
output(XMCRA,(XMCRA|0x4c));
output(XMCRB,(XMCRB&0));
output(MCUCR,(MCUCR|0x80));
#else
ERROR: need initialization for 9021 interfacing!!
#endif
res = DEV_TEST_1_RegRW(0x0C,256);//RH_FIFO_SZ_LO
if(ISERR(res))DEV_TEST_Exit();
res = DEV_TEST_2_SOF_n_Interrupt();
if(ISERR(res))DEV_TEST_Exit();
res = DEV_TEST_3_FifoRW(1,256,512);
if(ISERR(res))DEV_TEST_Exit();
//
// get initial value for "gWaitPktTicks"
// set macro UMO_WAIT_USB_PKT_TICKS in "DevIO.h" as this value.
//
gWaitPktTicks = DEV_TEST_4_GetWaitPacketTicks(200);
while(1);
}
#endif//1
#endif//DEV_IO_TEST
#if 0
U32 DEV_TEST_4_GetWaitPacketTicks(U16 sofCount)
{
volatile U16 usbIrq, pktSts;
volatile U16 sofCnt;
volatile U32 ticks;
usbIrq = 0;
if(!UH_DEV_IS_PLUGGEDIN()) return 0;
DEV_WriteReg(RH_CHIP_CTR2,0x20); //reset
DEV_WriteReg(RD_CHIP_CTR,0x40); //host mode
DEV_WriteReg(RH_CHIP_CTR2,0x10); //enable SOF
DEV_WriteReg(RH_INT_EN,UH_IRQ_SOF);
for(ticks=0,sofCnt=0; ticks<0x10000000; ticks++)
{
/*
* Intentionally made similar to "DEV_WaitTicks"
* so that delay effects is similar.
*/
if(UBi9021_IRQ_PENDING())
{
GET_UBi9021_IRQ_STS(usbIrq);
pktSts = DEV_ReadReg(RH_LAST_PKT_STS);
if(usbIrq&UH_IRQ_SOF){
if(sofCnt++>=sofCount){
DEV_WriteReg(RH_INT_EN,0);
return ticks;
}
}
if(pktSts&UH_LST_PKT_STS_NAK){
pktSts = 0;
}
else if(pktSts&UH_LST_PKT_STS_STALL){
pktSts = 0;
}
else if(pktSts==UH_LST_PKT_STS_ACK){
pktSts = 0;
}
usbIrq = 0;
}
RISC_sleep_nsec(WFIRQ_SLEEP_TIME);
}
return 0;
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -