/**************************************************************************** * This file is part of the WLAN-Ethernut driver. * * Copyright (c) 2004 by Michael Fischer. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * **************************************************************************** * History: * * 07.02.04 mifi First Version for the XC9572-PC84 ONLY! * The BASE_ADDRESS is 0x8800!! ****************************************************************************/ #define __PCMCIA_C__ /* * The PCMCIA interface works with a Xilinx XC9572-PC84 CPLD. * All the lines like CE1, CE2, WE, OE and so on must be control * separate by the latch. * */ #include #include #include /*==========================================================*/ /* DEFINE: All Structures and Common Constants */ /*==========================================================*/ /* * Address offset, register index of the CPLD */ #define BASE_ADDRESS 0x8800 #define DATA_LOW 0 #define DATA_HIGH 1 #define ADDRESS_LOW 2 #define ADDRESS_HIGH 3 #define CTRL 4 /* * CTRL bit definition */ #define CTRL_CE1 0x01 #define CTRL_CE2 0x02 #define CTRL_OE 0x04 #define CTRL_WE 0x08 #define CTRL_IORD 0x10 #define CTRL_IOWR 0x20 #define CTRL_REGS 0x40 #define CTRL_DATA_OUT 0x80 #define DATA_LOW_REG *((volatile BYTE *)BASE_ADDRESS+DATA_LOW) #define DATA_HIGH_REG *((volatile BYTE *)BASE_ADDRESS+DATA_HIGH) #define ADDRESS_LOW_REG *((volatile BYTE *)BASE_ADDRESS+ADDRESS_LOW) #define ADDRESS_HIGH_REG *((volatile BYTE *)BASE_ADDRESS+ADDRESS_HIGH) #define CTRL_REG *((volatile BYTE *)BASE_ADDRESS+CTRL) /* * Some delay values */ #define DELAY_CE_WRITE() #define DELAY_WRITE() #define DELAY_WRITE_CE() #define DELAY_CE_READ() #define DELAY_READ() _NOP();_NOP(); _NOP();_NOP() #define DELAY_READ_CE() typedef enum { TYPE_IO = 0, TYPE_MEM } MEMORY_TYPE; /*==========================================================*/ /* DEFINE: Prototypes */ /*==========================================================*/ /*==========================================================*/ /* DEFINE: Definition of all local Data */ /*==========================================================*/ //static volatile BYTE *pCPLD = (volatile BYTE *) BASE_ADDRESS; //static BYTE gbCTRLValue = 0x7C; /*==========================================================*/ /* DEFINE: Definition of all local Procedures */ /*==========================================================*/ /************************************************************/ /* WriteXXX */ /************************************************************/ static void WriteXXX(WORD wAddress, WORD wData, MEMORY_TYPE eIO) { cli(); /* * set ADDRESS */ ADDRESS_LOW_REG = LOBYTE(wAddress); ADDRESS_HIGH_REG = HIBYTE(wAddress); /* * set DATA */ DATA_LOW_REG = LOBYTE(wData); DATA_HIGH_REG = HIBYTE(wData); /* * set CE1, CE2 */ CTRL_REG = (CTRL_CE1 | CTRL_CE2 | CTRL_OE | CTRL_WE | CTRL_IORD | CTRL_IOWR | CTRL_DATA_OUT); DELAY_CE_WRITE(); /* * set WR/IOWR */ if (eIO == TYPE_MEM) { CTRL_REG = (CTRL_CE1 | CTRL_CE2 | CTRL_OE | CTRL_IORD | CTRL_IOWR | CTRL_DATA_OUT); } else { CTRL_REG = (CTRL_CE1 | CTRL_CE2 | CTRL_OE | CTRL_WE | CTRL_IORD | CTRL_DATA_OUT); } DELAY_WRITE(); /* * check the WAIT signal */ /* * remove WR/IOWR */ CTRL_REG = (CTRL_CE1 | CTRL_CE2 | CTRL_OE | CTRL_WE | CTRL_IORD | CTRL_IOWR | CTRL_DATA_OUT); DELAY_WRITE_CE(); /* * remove CE1, CE2 */ CTRL_REG = (CTRL_OE | CTRL_WE | CTRL_IORD | CTRL_IOWR); sei(); } /************************************************************/ /* ReadXXX */ /************************************************************/ static WORD ReadXXX(WORD wAddress, MEMORY_TYPE eIO) { BYTE bLow; BYTE bHigh; WORD wData; cli(); /* * set ADDRESS */ ADDRESS_LOW_REG = LOBYTE(wAddress); ADDRESS_HIGH_REG = HIBYTE(wAddress); /* * set CE1, CE2 */ CTRL_REG = (CTRL_CE1 | CTRL_CE2 | CTRL_OE | CTRL_WE | CTRL_IORD | CTRL_IOWR); DELAY_CE_READ(); /* * set OE/IORD */ if (eIO == TYPE_MEM) { CTRL_REG = (CTRL_CE1 | CTRL_CE2 | CTRL_WE | CTRL_IORD | CTRL_IOWR); } else { CTRL_REG = (CTRL_CE1 | CTRL_CE2 | CTRL_OE | CTRL_WE | CTRL_IOWR); } DELAY_READ(); /* * check the WAIT signal */ bLow = DATA_LOW_REG; bHigh = DATA_HIGH_REG; /* * remove OE/IORD */ CTRL_REG = (CTRL_CE1 | CTRL_CE2 | CTRL_OE | CTRL_WE | CTRL_IORD | CTRL_IOWR | CTRL_DATA_OUT); DELAY_READ_CE(); /* * remove CE1, CE2 */ CTRL_REG = (CTRL_OE | CTRL_WE | CTRL_IORD | CTRL_IOWR); wData = (WORD) bHigh; wData = (wData << 8) | (WORD) bLow; sei(); return (wData); } /*==========================================================*/ /* DEFINE: All code exported */ /*==========================================================*/ /************************************************************/ /* pcmcia_WriteMem */ /************************************************************/ void pcmcia_WriteMem(WORD wAddress, WORD wData) { WriteXXX(wAddress, wData, TYPE_MEM); } /************************************************************/ /* pcmcia_WriteReg */ /************************************************************/ void pcmcia_WriteReg(WORD wAddress, WORD wData) { WriteXXX(wAddress, wData, TYPE_IO); } /************************************************************/ /* pcmcia_ReadMem */ /************************************************************/ WORD pcmcia_ReadMem(WORD wAddress) { return (ReadXXX(wAddress, TYPE_MEM)); } /************************************************************/ /* pcmcia_ReadReg */ /************************************************************/ WORD pcmcia_ReadReg(WORD wAddress) { return (ReadXXX(wAddress, TYPE_IO)); }