Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs AN015401-1103 ZiLOG Worldwide Headquarters * 532 Race Street * San Jose, CA 95126 Telephone: 408.558.8500 * Fax: 408.558.8300 * www.ZiLOG.com Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs This publication is subject to replacement by a later edition. To determine whether a later edition exists, or to request copies of publications, contact: ZiLOG Worldwide Headquarters 532 Race Street San Jose, CA 95126 Telephone: 408.558.8500 Fax: 408.558.8300 www.zilog.com ZiLOG is a registered trademark of ZiLOG Inc. in the United States and in other countries. CompactFlash is a registered trademark of Sandisk Corp. All other products and/or service names mentioned herein may be trademarks of the companies with which they are associated. Information Integrity The information contained within this document has been verified according to the general principles of electrical and mechanical engineering. Any applicable source code illustrated in the document was either written by an authorized ZiLOG employee or licensed consultant. Permission to use these codes in any form, besides the intended application, must be approved through a license agreement between both parties. ZiLOG will not be responsible for any code(s) used beyond the intended application. Contact the local ZiLOG Sales Office to obtain necessary license agreements. Document Disclaimer (c)2003 by ZiLOG, Inc. All rights reserved. Information in this publication concerning the devices, applications, or technology described is intended to suggest possible uses and may be superseded. ZiLOG, INC. DOES NOT ASSUME LIABILITY FOR OR PROVIDE A REPRESENTATION OF ACCURACY OF THE INFORMATION, DEVICES, OR TECHNOLOGY DESCRIBED IN THIS DOCUMENT. ZiLOG ALSO DOES NOT ASSUME LIABILITY FOR INTELLECTUAL PROPERTY INFRINGEMENT RELATED IN ANY MANNER TO USE OF INFORMATION, DEVICES, OR TECHNOLOGY DESCRIBED HEREIN OR OTHERWISE. Except with the express written approval ZiLOG, use of information, devices, or technology as critical components of life support systems is not authorized. No licenses or other rights are conveyed, implicitly or otherwise, by this document under any intellectual property rights. AN015401-1103 Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs iii Table of Contents List of Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv List of Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .v Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 eZ80Acclaim!TM Flash MCU Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 CompactFlash(R) Storage Card . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Modes of Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Developing the CompactFlash(R) Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Hardware Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Software Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 AN015401-1103 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Equipment Used . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Test Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Test Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 10 11 11 12 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Appendix A--References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Appendix B--Flowchart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Appendix C--Schematic Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Appendix D--Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Assembly File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Header Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Appendix E--API Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 13 14 15 18 18 46 48 54 Table of Contents Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs iv List of Figures Figure 1. Structure of a CompactFlash Storage Card . . . . . . . . . . . . . . . . . . . 2 Figure 2. System Connections for the CompactFlash Interface with an eZ80Acclaim! MCU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Figure 3. Flowchart for CompactFlash APIs . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Figure 4. Schematic for Connections between Development Board and Expansion Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Figure 5. Schematic for Interface Logic on the CompactFlash Expansion Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Figure 6. Schematic for CompactFlash Connector . . . . . . . . . . . . . . . . . . . . . 17 AN015401-1103 List of Figures Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs v List of Tables Table 1. Table 2. Table 3. Table 4. Table 5. Table 6. AN015401-1103 eZ80F91 Address Bits and CompactFlash Pins - Connection Details 5 Demultiplexer Logic Truth Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Port B GPIO Interface to CompactFlash Control Signals . . . . . . . . . . 7 Derived Addresses for the CompactFlash Registers . . . . . . . . . . . . . 7 List of References. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 CompactFlash Interface APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 List of Tables Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 1 Abstract This Application Note illustrates an interface between an eZ80Acclaim!TM MCU and a CompactFlash(R) Storage Card. The CompactFlash card is accessed in the following modes of operation: the memory mode, the contiguous I/O mode, the primary I/O mode, and the secondary I/O mode. The AN0154-SC01.zip file contains the source code associated with this Application Note and is available on the ZiLOG website. eZ80Acclaim!TM Flash MCU Overview The eZ80Acclaim! on-chip Flash Microcontrollers are an exceptional value for customers designing high performance, 8-bit MCU-based systems. With speeds upto 50 MHz and an on-chip Ethernet MAC (eZ80F91 only), designers have the performance necessary to execute complex applications quickly and efficiently. Combining Flash and SRAM, eZ80Acclaim! devices provide the memory required to implement communication protocol stacks and achieve flexibility when performing in-system updates of application firmware. The eZ80Acclaim! Flash MCU can operate in full 24-bit linear mode addressing 16MB without a Memory Management Unit. Additionally, support for the Z80compatible mode allows Z80/Z180 customers to execute legacy code within multiple 64KB memory blocks with minimum modifications. With an external bus supporting eZ80, Z80, Intel, and Motorola bus modes and a rich set of serial communications peripherals, designers have several options when interfacing to external devices. Some of the many applications suitable for eZ80Acclaim! devices include vending machines, point-of-sale terminals, security systems, automation, communications, industrial control and facility monitoring, and remote control. Discussion The CompactFlash interface is a vendor-independent specification that can be implemented to develop CompactFlash products that are compatible with a wide range of user applications and across a gamut of manufacturers. The early CompactFlash cards were meant exclusively for Flash data storage; however, currently under the CF+ specification, they support various I/O devices, such as Ethernet cards and fax/modem cards, to name a few. AN015401-1103 Abstract Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 2 CompactFlash(R) Storage Card Figure 1 illustrates a CompactFlash Storage Card that contains a dedicated controller and Flash memory module(s). The controller interfaces with a host system, allowing data to be written to and read from the Flash memory module(s). The host interface consists of address lines from A0:A10, data lines from D0:D15 and control signals. HOST INTERFACE CompactFlash Storage Card Data In/Out Controller Control Flash Module Figure 1. Structure of a CompactFlash Storage Card The address space requirement for interfacing a CompactFlash Storage Card is just 2 KB, irrespective of the storage capacity of the card. The data bus can be interfaced as an 8-bit or a 16-bit bus, depending on the host support. The Flash modules are not directly accessible to the host, even at the byte level. The controller transfers the data to and from the Flash modules in blocks of 512 bytes. The host essentially communicates with the controller, which contains control/status registers and a data buffer mapped within the 2 KB address space of the host. Description of the CompactFlash(R) Storage Card The CompactFlash Storage Card used in this application is a 64 MB card from Kingston Technology. Internal to the card, the memory is divided into three different sections: the attribute memory, the command/status tuple, and the storage memory. Attribute Memory. The attribute memory is a set of registers that store card identification and configuration information. The card can be configured in the memory and I/O modes using these registers. The starting address of these registers is fixed at an offset of 0x200. Command/Status Tuple. The command/status tuple are sequentially addressed control registers with different starting addresses depending upon the mode of operation. When a host writes to the tuple, it behaves as a set of registers that AN015401-1103 CompactFlash(R) Storage Card Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 3 holds the command parameters and the command. It is essential to write the command parameters before the command because the controller executes the command according to the parameters present in other registers. Similarly, when a host reads to the command/status tuple, the tuple behaves as a set of registers that holds the status information about the last executed command. The start address of the command/status tuple is 0x000.The first register at address 0x000 is for the data register, which does not contribute to the actual command/status information. Storage Memory. Storage memory is a large area of Flash memory. Access to this space is handled by the controller in a manner that is transparent to the host. The address space requirement for interfacing a CompactFlash Storage Card is just 2 KB, irrespective of the storage capacity of the card. Note: The addresses of attribute memory, control/status, and data registers lie within the 2 KB space. Modes of Operation The CompactFlash operates in several modes. Two of these modes are relevant to this Application Note and are briefly discussed in this section. Memory Mode. This mode is the default mode of operation for the CompactFlash. The CompactFlash card enters this mode at Power On or RESET, if the OE pin is held at a logic HIGH (1). I/O Mode(s). There are three distinct I/O modes: the primary I/O mode, the sec- ondary I/O mode, and the contiguous I/O mode. To enter into any of the I/O modes, it is necessary to enter into the memory mode first and then modify the card configuration register (in the attribute memory space) accordingly. Developing the CompactFlash(R) Interface The hardware architecture and the software implementation to develop the CompactFlash Storage Card interface for the eZ80Acclaim! MCU is described in this section. Hardware Architecture The CompactFlash Storage Card consists of pins that operate according to the mode in which the card is operated, resulting in different interfaces for different modes. The architecture suggested in Figure 2 considers a superset of these requirements to illustrate all the three modes with the same hardware setup. The block diagram in Figure 2 is the basis for the schematics in the Appendix C on page 15. AN015401-1103 Modes of Operation Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 4 eZ80Acclaim!TM MCU A[0:10] INTERFACE BLOCK CF CARD A[0:10] D[0:7] D[0:7] CS3 CE1 CE2 A[11:14] PB7 PB6 PB5 PB4 OE WE IORD IOWR WAIT PB3 PB2 PB1 PB0 RDY/BSY CD1 CD2 Figure 2. System Connections for the CompactFlash Interface with an eZ80Acclaim! MCU The hardware is designed to interface with the CompactFlash in the modes of operation mentioned previously. It is therefore necessary to understand the hardware requirements for entering and operating the different modes. These requirements are described under two domains: requirements common to all the modes of operation, and requirements that vary for different modes. The common requirements are described first, followed by the varied requirements. Common Requirements At the outset, it is necessary to determine that a card is present in the slot for operation. Two signals are located at the two extremes of the CompactFlash connector to facilitate card detection (-CD1, -CD2) and correct insertion. These signals are pulled low inside the card. An OR-gate (74LVC32AD) combines these card detect signals to derive one signal that is connected to the Port B pin0 (PB0) of the eZ80F91 MCU. PB0 is polled by the software to determine if the CompactFlash card is present. The eZ80F91 data bus is byte wide, therefore the D[0:7] data bus is connected to the corresponding data lines/pins of the CompactFlash. The CompactFlash HIGH data bus, D[8:15], is not connected. AN015401-1103 Hardware Architecture Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 5 The eZ80F91 address bus, A[0:23], is described as different groups of address lines. The 11 least significant bits of the eZ80F91 address bus, A[0:10], are connected directly to A[0:10] of the CompactFlash connector. This address area defines a space for 2 KB (2048) addresses. The address lines, A[11:14], are used in the manner depicted in Table 1. Table 1. eZ80F91 Address Bits and CompactFlash Pins - Connection Details F91 Address Bit CompactFlash Pin (number) A11 REG A12 CE1/CE1/CS0 A13 CE2/CE2/CS1 A14 CSEL A15 Not used The 8 most significant bits, A[16:23], decide the chip select, providing the programmer flexibility to map the 2 KB address space anywhere within the 16 MB area supported by the eZ80F91 device. For this CompactFlash Interface application, the A[16:23] byte is assigned the value of 0xA8. Finally, as per the CompactFlash specification, 10 K W resistors are used to pull up each of the following signals to VDD: * * * * * * * * READY INPACK WAIT WP VS1 VS2 BVD1 BVD2 Varied Requirements Some of the control signals in the CompactFlash card are used for multiple purposes while some of the signals differ for different modes. All of these signals require additional hardware and pins from the CompactFlash host. AN015401-1103 Hardware Architecture Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 6 As described in the Modes of Operation section on page 3, the change from memory mode to any of the I/O modes is achieved through the software. However, such a mode change also requires a change in hardware. In the memory mode, the RD and WR strobes from the host are connected to the OE and WE signals of the CompactFlash card. In the I/O modes, the host signals are connected to IORD and IOWR signals of the CompactFlash card. The switching functionality is achieved through the use of a de-mux (de-multiplexer). The chip select (as decided by the A[16:23]) and PB7 pin control the action of the de-mux. When the chip select is asserted, the PB7 pin is HIGH for the memory mode, and LOW for other modes of CompactFlash operation. For all modes other than the memory mode, the de-mux routes RD and WR signals from the eZ80F91 to IORD and IOWR, respectively. For the memory mode, the de-mux routes the WR signal directly to the CompactFlash WE signal. The RD signal, however, is not directly connected to the OE pin because the OE pin also handles the other functionality, such as determining if the CompactFlash card resets into the memory mode or the TrueIDE mode at RESET. The RD signal is therefore routed out of the de-mux and is referred to as MEM_MODE. Table 2. Demultiplexer Logic Truth Table CSx PB7 WR RD 0 0 1 0 IORD = RD 0 0 0 1 IOWR = WR 0 1 1 0 MEM_MODE = RD 0 1 0 1 WE = WR Action Remarks If PB6 = 1, then OE = MEM_MODE The memory mode is the default mode of operation. If the OE signal is not grounded, this default mode of operation is functional at power ON or RESET. However, if the OE pin is grounded, the CompactFlash card enters the True IDE mode on RESET. Thus, the hardware must be able to perform the following operations. To RESET the CompactFlash Storage Card at Run-time. To achieve this functional- ity, the eZ80F91 port pin, PB4, is connected directly to the CompactFlash RESET pin. By toggling PB4, the CompactFlash card can be RESET at any point of time. To Control the OE pin at RESET. To achieve this functionality, the eZ80F91 port pin, PB6, and the MEM_MODE signal issuing out of the de-multiplexer are ANDed, using the AND gate (74LVC08AD), to control the OE pin. The AND operation forces a 0 (LOW) on the OE that is held at 1 (HIGH) when there are no RD transactions on the CompactFlash. AN015401-1103 Hardware Architecture Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 7 Thus, a mode conversion can be achieved by forcing a 0 on PB6 and toggling the PB4 for a RESET. The port B GPIO lines used to interface the CompactFlash control signals are summarized in Table 3. Table 3. Port B GPIO Interface to CompactFlash Control Signals Bit Direction Functionality PB7 Output To route (RD, WR) from eZ80F91 to either (OE, WE) or (IORD, IOWR) depending on the memory or IO/IDE mode respectively. PB6 Output To select the True IDE mode of operation for the CompactFlash PB5 Output To indicate successful transfers/debug PB4 Output To RESET the CompactFlash card through software - useful in IDE Master/Slave modes. PB3 Input BVD1/STSCHG/PDIAG PB2 Input BVD2/SPKR/DASP PB1 Input RDY BSY/IREQ/INTRQ PB0 Input Combined Card Detect signal The Interface Block The CompactFlash card-eZ80Acclaim! interface logic comprises of a single ORgate, a single AND-gate and a de-mux (74LVC139AD), (see Figure 2). Table 4 lists the derived addresses for the CompactFlash registers based on the discussions in the sections on Common Requirements on page 4, and Varied Requirements on page 5. Table 4. Derived Addresses for the CompactFlash Registers Mode A23-16 A15-12 A11-8 A7-4 A3-0 Memory A8h xx10 10xx xxxx 0h - 7h A82800h A82807h Contiguous I/O A8h xx10 0x00 0000 0h - 7h A82000h A82007h Primary I/O xx10 0x01 1111 0h - 7h A821F0h A821F7h A8h Complete Range Note: x : Indicates "don't care" condition. All 'x' are replaced by zeros h : Indicates the preceding value to be a hexadecimal AN015401-1103 Hardware Architecture Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 8 Table 4. Derived Addresses for the CompactFlash Registers (Continued) Mode A23-16 A15-12 Secondary I/O A8h xx10 A11-8 A7-4 A3-0 0x01 0111 0h - 7h Complete Range A82170h A82177h Note: x : Indicates "don't care" condition. All 'x' are replaced by zeros h : Indicates the preceding value to be a hexadecimal Software Implementation The CompactFlash Interface software is implemented as a set of API functions to perform the following operations: * * * * * * Initialize and set the CompactFlash mode Write to a CompactFlash sector Identify the CompactFlash drive Set features for the CompactFlash card in terms of mode specifications Read from a CompactFlash sector Erase a CompactFlash sector Refer to Appendix E on page 54 for details on the API functions. In addition to the API functions, several supporting functions are implemented that may be useful while using the CompactFlash card. These include - * * * * Software block data transfer (DMA operation) Delay generation (for various CompactFlash-specified delays) Card detection/Error checking Function to receive the sector, head and cylinder information As discussed in the Command/Status Tuple section on page 2, the CompactFlash interface works with the command tuple. The registers in the tuple are addressed in a sequential manner. Therefore, it is sufficient to determine the address of the first register in a specified mode. These addresses are hardware- and modedependent and are hard-coded in the software for every mode. The CompactFlash operating modes supported by the current CompactFlash Interface application are the Memory mode and the I/O modes (contiguous/primary/secondary). When the user selects a particular mode of operation, the addresses, being mode-dependent, are loaded into the appropriate pointer and the user is prompted for an operation to be performed on the CompactFlash. When the command to perform an operation is received, the corresponding regis- AN015401-1103 Software Implementation Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 9 ters in the tuple are loaded with the required command parameters. This is followed by a block transfer of data to/from the CompactFlash. Two buffers, of 512 bytes each, are implemented in the CompactFlash Interface software to transmit and receive data to/from the CompactFlash. Switching between Modes Because the default mode of operation for the CompactFlash card is the memory mode, all the commands for this mode can be run directly. The CompactFlash attributes are set to an 8-bit mode. They are marked as the 0th drive through the set_features() API, such that the CompactFlash card can be switched to any mode of operation. To switch to any of the I/O modes, the appropriate bits are written in the configuration register as follows: Bit I/O Mode 1 Contiguous I/O 2 Primary I/O, 3 Secondary I/O While switching to the I/O mode, the RD and WR signals from the eZ80F91 must be connected to the IORD and IOWR signals of the CompactFlash card. To revert to the memory mode, a 0x00 is written to the configuration register. Processing the Commands Commands are issued to the CompactFlash card when it is in the required mode. The user provides the starting sector, cylinder, and head for the read_sectors() and write_sectors() APIs. These APIs feed the values provided by the user into appropriate command tuple registers and write the command word (0x20 for READ and 0x30 for WRITE) in the command register. For the READ command, the CompactFlash interface fills the buffer with one sector of data (512 bytes) and prompts the user for action through the status registers. The CompactFlash features a FIFO like structure that requires the host (eZ80F91) to read the data from the same location repeatedly. For a WRITE command, the entire data is first written to the CompactFlash buffer before the CompactFlash interface starts writing the data in the designated sector. When the data is completely written into the sector, the CompactFlash interface informs the host through its status registers. AN015401-1103 Software Implementation Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 10 The algorithm for the read_sector() API, which is the sequence of events for reading from a sector, is outlined below. 1. Select the CompactFlash mode 2. Load the pointers for command/status tuple, and read buffers 3. Get the sector, cylinder, and head from where reading must begin on the CompactFlash card 4. Load values from 5 to the appropriate command registers in the command tuple 5. Load the read command in the command register 6. Wait for the CompactFlash card to be ready 7. Read 512 bytes from the CompactFlash data register 8. Indicate success/error The algorithm for the write_sector() API, which is the sequence of events for writing to a sector, is outlined below. 1. Select the CompactFlash mode 2. Load the pointers for command/status tuple, and write buffers 3. Get the data in the write buffer 4. Get the sector, cylinder, and head from where writing must begin on the CompactFlash card 5. Load values from 5 to the appropriate command registers in the command tuple 6. Load the write command in the command register 7. Wait for the CompactFlash card to be ready 8. Write 512 bytes from the CompactFlash data register 9. Indicate success/error Testing This section describes the setup, requirements, and the procedure followed to demonstrate the CompactFlash Interface application using the eZ80F91 MCU. Setup The CompactFlash Storage Card is mounted on the CompactFlash Expansion Board connectors of the eZ80F91 Development Kit (connectors J6 and J8). The AN015401-1103 Testing Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 11 EX_SEL jumper (J19) on the eZ80 Development Board is connected in order to short MEM_EN2 to CS_EX. The schematics for the connections between the eZ80 Development Board, the CompactFlash Expansion Board, and the CompactFlash connector are presented in Appendix C on page 15. Equipment Used * * * * * eZ80F91 Development Kit (eZ80F910200ZC0) CompactFlash Interface Expansion Board (developed indigenously) ZDSII-IDE for eZ80Acclaim! MCUs, v4.6.0 CompactFlash Storage Card from Kingston technology with 64 MB memory PC with HyperTerminal; HyperTerminal is configured for 9600bps, 8 bit, noparity, 1 Stop bit, and No flow control. Test Procedure The procedure to demonstrate the CompactFlash Interface application is outlined below. AN015401-1103 1. The connections between the Development Board, the CompactFlash Expansion Board, and the CompactFlash Connector are made according to the schematics (Refer to Appendix C on page 15). 2. The CompactFlash Storage Card is fitted into the CompactFlash Connector. 3. The PC is connected to the eZ80 Development Board through ZPAKII. 4. Launch the ZDSII-IDE, build the program using the application code (AN0154-SC01.zip file), and download the resulting .hex file to the eZ80F91 on-chip Flash. 5. Launch the HyperTerminal. The command menu appears below the CF>> prompt. 6. Enter m to select the mode. From the sub-menu, enter the appropriate character for the required mode. The mode is selected and the command menu appears again. 7. Enter i to identify the CompactFlash Storage Card. This operation tests the identify_drive() API, which reads the CompactFlash parameters and compares them with the CompactFlash datasheet. 8. At the CF>> prompt, enter w to write to a CompactFlash sector. This operation tests the write_sector() API. The write sub-menu appears. 9. Enter values for Track, Head, and Sector within the prompted range. Equipment Used Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 12 10. At the CF>> prompt, enter r to read to a CompactFlash sector. This operation tests the read_sector() API. The read sub-menu appears. 11. Enter the same values as in step 9. The data that was previously written to the CompactFlash sector is read by the eZ80F91 processor and displayed on the HyperTerminal. Test Results The CompactFlash card was identified with the identify_drive() API. The format of the information received was found to be in agreement with CompactFlash specification. Data transfer to and from the CompactFlash card was performed and found to be error free. Summary This Application Note illustrates an interface between an eZ80Acclaim! MCU and the CompactFlash Storage Card. It provides a designer with the basic building block to develop a slew of applications using the eZ80Acclaim! as a webserver. The user can benefit from all the advantages that the CompactFlash technology offers, namely a power efficient and flexible way of storing digital data such as web-pages, audio/video files, or simple log data. AN015401-1103 Test Results Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 13 Appendix A--References Further information regarding eZ80Acclaim! Flash Microcontrollers, and the CompactFlash can be found in the references listed in Table 5. Table 5. List of References Topic Document Name & Document ID eZ80Acclaim! eZ80F92/eZ80F93 Flash Module Product Specification, PS0189 eZ80F91 Flash MCU with Ethernet MAC Product Specification, PS0192 CompactFlash Specification CF+ and CompactFlash Specification Revision 1.4, available at www.compactflash.org CompactFlash Storage Card Kingston CompactFlash, MKF-260, available at www.kingston.com/ products/cf_white_paper.pdf CompactFlash Storage Card, THNCF064MM, available at www.toshiba.com/taec AN015401-1103 Appendix A--References Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 14 Appendix B--Flowchart The flowchart for CompactFlash Interface APIs is illustrated in Figure 3. API START Load the specific command parameters in to the command Tuple Registers 1-6 Load the command word in command Tuple Register 7 Wait for the CF storage card to become READY or generate Error Transfer data to and from the CF storage card Wait for the CF storage card to become READY or generate Error Inform the API calling function of the Status/ Error API RETURN Figure 3. Flowchart for CompactFlash APIs AN015401-1103 Appendix B--Flowchart Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 15 Appendix C--Schematic Diagrams Figure 4 is a schematic diagram for connections between the eZ80F91 Development Board and the CompactFlash Expansion Board. J1 TO PG 2 OF 3 26 -CD1 27 28 29 30 31 J8-18 -CE2/-CE2/-CS1 FROM PG 2 OF 3 -VS1 FROM PG 2 OF 3 -IOWR FROM PG 2 OF 3 -WE RDY-BSY/IREQ/INT RQ FROM PG 1 OF 3 J8-19 J6-46 VDD -CSEL -VS2 FROM PG 2 OF 3 RESET /RESET /-RESET J6-13 34 35 36 PB1 37 VDD 38 A14 39 40 PB4 J6-50 J6-48 41 42 -WAIT /-WAIT /IORDY 43 -INPACK J8-16 32 33 -IORD FROM PG 2 OF 3 J6-52 A13 A11 -REG BVD2/-SPKR/-DASP BVD1/-ST SCHG/-PDIAG 44 PB2 45 PB3 46 47 48 49 FROM PG 1 OF 3 GND GND 50 1 GND 2 3 4 5 6 7 A12 GND FROM PG 1 OF 3 D3 J8-46 D4 J8-47 D5 J8-48 D6 J8-49 D7 J8-50 A14 A13 A12 A11 8 A10 J8-15 9 -O E/ -O E/-A TA _S EL FROM 10 A09 J8-14 A08 J8-13 11 12 13 14 15 16 17 18 19 20 21 22 23 VDD PG 2 OF 3 VDD GND VDD GND A07 J8-10 VDD FROM PG 1 OF 3 A06 J8-9 A05 J8-8 VDD VDD A04 J8-7 A03 J8-6 A02 J8-5 A01 J8-4 C13 C14 C15 10uF 0.1uF 0.1uF GND A00 J8-3 D0 J8-43 D1 J8-44 D2 J8-45 24 25 PB4 PB3 PB2 PB1 J8-17 -CE1/-CE 1/ -CS 0 WP/-IOIS16/-IOIS16 TO PG 2 OF 3 -CD2 Compact Flash Connec tor Title Size CompactFlash Interface for eZ80Acclaim! MCU Document Number: AN0154 Rev A Date: THURSDAY JULY 24, 2003 Sheet 3 OF 3 Figure 4. Schematic for Connections between Development Board and Expansion Board AN015401-1103 Appendix C--Schematic Diagrams Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 16 Figure 5 is the schematic diagram for the Interface Logic on the CompactFlash Expansion Board. VDD PG 2 of 3 - RD J1-21 J1-23 J1-3 J1-5 GND D0 D2 D4 D6 GND VDD 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 GND A0 1 J1-19 A0 3 J1-17 A0 5 J1-15 A0 7 J1-12 GND A0 9 J1-10 A1 1 J1-44 A1 3 J1-32 VDD GND VDD GND - WAIT/- WAIT/IORDY GND MWAIT J1-42 GND GND VDD - WR J6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 GND 55 56 GND 57 58 GND 59 60 HEADER 30X2 VDD Connects to eZ80 eval board 60 pin header (J6) J1-20 J1-18 J1-16 J1-14 J1-11 J1-08 J1-07 J1-39 Connects to eZ80 eval board 60 pin header (J8) J8 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 VDD A0 0 A0 2 A0 4 A0 6 GND A0 8 A1 0 A1 2 A1 4 GND PG 2 of 3 GND GND J1-22 D1 D3 J1-2 D5 J1-4 D7 J1-6 GND - CSX GND PG 2 of 3 GND GND GND Header 30x2 VDD GND GND PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0 PG 2 of PG 2 of PG 2 of J1-41 J1-46 J1-45 J1-37 PG 2 of 3 3 3 3 VDD VDD C11 10uF GND C7 0.1uF VDD C8 0.1uF GND C12 C9 C10 10uF 0.1uF 0.1uF GND Title COMPACT FLASH INTERFACE FOR eZ80Acclaim! MCUs Size Doc ument Numbe r: AN0154 Rev A Date:Thursday July 24, ,2003 Sheet: 1 of 3 Figure 5. Schematic for Interface Logic on the CompactFlash Expansion Board AN015401-1103 Appendix C--Schematic Diagrams Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 17 Figure 6 is the schematic diagram for the CompactFlash Connector. CF Spec requirements VDD 74LVC139/SO VDD GND J8-34 -WR J8-56 J6-40 -CSX PB7 1 - WR - CSX PB7 EN 3 2 A1 A0 Y3 Y2 Y1 Y0 7 6 5 4 - WE - IOWR J1-36 J1-35 -WE -IOWR U4A 10K 10K 10K 10K 10K 10K 10K VCC GND THE I C FOOTPRI NT CONNEC TS TO VC C AND NOT VDD. R1 R2 R3 R4 R5 R6 R7 R8 10K PB7 = 1 is for Memory m ode. PB7 = 0 is for IO mode. Interface Logic VDD 74LVC139/SO J8-33 PB3 PB2 PB1 MWAIT BVD1/-STSCHG/-PDIAG J6-48 BVD2/-SPKR/-DASP J6-50 -VS1 J1-33 -VS2 J1-40 RDY-BSY/IREQ/INTRQ J6-52 -INPACK J1-43 -WAIT/-WAIT /IORDY J6-13 WP/-IOIS16/-IOIS16 J1-24 -RD J8-56 J6-40 - RD 15 - CSX PB7 13 14 EN A1 A0 9 10 11 - MEM_MODE - IOR D 12 Y3 Y2 Y1 Y0 U4B J1-34 -IORD SOJ.0 50/16/WB. 300/L.425 U2A 74LVC08/SO J6-42 PB6 - MEM_MODE 1 PB6 2 3 -OE/-OE/-ATA_SEL VDD J1-9 Indicators/ Test Points R13 10K U3A 74LVC32/SO VDD R9 470E R10 470E R11 470E LED D2 LED D3 R12 470E PB0 J6-54 Success PB5 PB1 LED D4 Power - CD1 2 - CD2 VDD C1 LED D1 1 3 PB0 R14 10K 0.1uF J1-26 -CD1 J1-25 -CD2 VDD C3 C2 0.1uF 0.1uF VDD C4 0.1uF C5 0.1uF C6 0.1uF J6-44 PB1 Title Activity - Memory modeJ6-52 PB0 Card Present J6-54 COMPACT FLASH INTERFACE FOR eZ80Acclaim! MCUs Size Doc ume ntN umbe r: AN0154 Rev A Date : Thursday July 24, 2003 Sh eet: 2 of 3 Figure 6. Schematic for CompactFlash Connector AN015401-1103 Appendix C--Schematic Diagrams Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 18 Appendix D--Source Code This appendix provides a listing of the source code associated with the CompactFlash Interface application described in the document. The source code file, AN0154-SC01.zip is available along with this Application Note, on the ZiLOG website. C Files The following C files are listed in this section: * * * * * * CF-interface.c Z_FNC_CF.c Z_API_CF.c Z_CF_SUPPORT.c UserIf.c utility.c /* ********************************************************* * File : CF-interface.c * Description : Contains main() function. * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ include #include #include #include "UserIF.h" #include "Z_API_CF.h" AN015401-1103 Appendix D--Source Code Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 19 void init_F91(void); // // // // // // // // // void init_UserIF(void); void init_parameters(void); Initializes CSx registers and Port B Initializes the UART and UserIF related portion This can be removed if HyperTerminal is not used Initializes the data structures and global variables extern char current_mode; main() { char command, result; init_F91(); init_parameters(); init_UserIF(); // // // // // Initializes the CSx registers and Port B Initializes the data structures and global variables Initializes the UART and UserIF related portion welcome(); display_mode(current_mode); while(1) { display_menu(); display_prompt(); command = getch(); putch(command); // Displays current mode of CF // operation // // // // Displays all the options or commands supported Prompts user to enter a command // Wait for User input // and store the same // echo switch (command) { case 'm' : fn_mode_select(); break; case 'i' : fn_identify_drive(); break; case 's' : fn_ AN015401-1103 // Function Mode selection // Function Identify Drive Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 20 (); case 'r' : case 'w' : case 'e' : default : // Function Set Features break; fn_read_sectors(); // Function Read Sector break; fn_write_sectors(); // Function Write Sector break; fn_erase_sectors(); // Function Erase Sector break; printf("\n Command not known.\n Please enter from m,i,s,r,w,e\n"); break; } } } /********************************************************* ***************** end of file **************************** *********************************************************/ /* ********************************************************* * File : Z_FNC_CF.c * Description : * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ #include #include #include #include "Z_API_CF.h" "UserIF.h" "utility.h" // Referring to the assembly code AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 21 // Defining data buffers extern extern extern extern char char char char rd_buffer[]; wr_buffer[]; cmd_tuple[]; sta_tuple[]; extern char current_mode; // // // // From From From From RD_WR_BUF_ADDR to +511 +512 to +1023 +1023 to +1031 +1032 to +1039 // Global mode code // Move such definitions to the .h files. extern int blkcopy(char *, char *, int); extern char attr_mem, current_mode; /* ******************************** ** Main Functions are listed here *********************************** */ void fn_mode_select(void) { char mode, result; display_mode(current_mode); display_mode_select(); display_prompt(); // // // // First display the curent mode Next, offer different modes for selection Prompt the user mode = getch(); // Get user selection //current_mode = load_CF_mode(mode); result = load_CF_mode(mode); if (result == SUCCESS) { display_mode(current_mode); } else { proc_result(result); // // // // This is be used This is be used the API.It can sans the display the API.It can sans the display // Reflect the new // current_mode // Find and display // appropriate Error } AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 22 } // ********************************************************* void fn_identify_drive(void) { char result; result = identify_drive(); if (result == SUCCESS) { // // // // ------------------------------------------------------------Parse the read Buffer for useful information Note: Only some information is extracted as an illustration -------------------------------------------------------------s_temp = POINTER_FOR_SHORT; d_cylinders = *(s_temp + 1); d_heads d_sect_per_trk = *(s_temp + 3); = *(s_temp + 6); d_sect_per_card_1 d_sect_per_card_1 d_sect_per_card_2 d_sect_per_card_2 d_sect_per_card = = *(s_temp + 7); // MSW of a long word &= 0x0000FFFF; = *(s_temp + 8); // LSW of a long word &= 0x0000FFFF; ((d_sect_per_card_1 << 16)|(d_sect_per_card_2)); c_cylinders c_heads c_sect_per_trk // This is taking just // one byte = *(s_temp + 54); = *(s_temp + 55); = *(s_temp + 56); c_capacity_1 = *(s_temp + 57); c_capacity_1 &= 0x0000FFFF; c_capacity_2 = *(s_temp + 58); // MSW of a double // word variable // LSW of a double // word variable c_capacity_2 &= 0x0000FFFF; c_capacity = ((c_capacity_1 << 16) | (c_capacity_2)); // ----------------------------------// Display the information extracted AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 23 printf("\n ------------------------------------------- \n"); printf("\n\r printf("\n\r printf("\n\r printf("\n\r Default Default Default Default number of cylinders = %d \t", d_cylinders); number of heads = %d \t", d_heads); sectors per Track = %d \t", d_sect_per_trk); sectors per card = %d \t", d_sect_per_card); printf("\n\r printf("\n\r printf("\n\r printf("\n\r Current Current Current Current number of cylinders = %d \t", c_cylinders); number of heads = %d \t", c_heads); sectors per Track = %d \t", c_sect_per_trk); capacity in sectors = %d \t", c_capacity); printf("\n ------------------------------------------- \n"); } else { proc_result(result); // Find and display // appropriate Error } } // ********************************************************* void fn_set_features(void) { // ------------// Settings required are // 8-bit data transfers: Enable / Disable // Power Level 1 commands: Enable / Disable // POR defaults with soft reset: Enable / Disable // -------------// Since most of the features are default and can NOT be altered // for the present hardware, we will skip this API for time being. // char result; result = set_features(); if (result == SUCCESS) { printf("\n *** 8-bit data, Drive# = 0. \n"); } else { AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 24 proc_result(result); // Find and display appropriate error } } // ********************************************************* void fn_read_sectors(void) { char result; int sector, head, track; // Get the starting sector do { printf("\n\r Please enter the starting sector (0x01-0x20):\t"); sector = ScanHex(2); // Use HyperTerminal Echo in // place of printing } while (sector < 0x01 || sector > 0x20); // Get the Head information do { printf("\n\r Please enter the Head Number (0x0-0x3):\t"); head = ScanHex(1); // Use HyperTerminal Echo in // place of printing } while (head > 0x03); // Get the Track do { printf("\n\r Please enter the Track number (0x000-0x3d2):\t"); track = ScanHex(3); // Use HyperTerminal Echo in // place of printing } while (track > 0x3d2); // Call API with this info. result = read_sectors(sector, head, track); // API Call if (result == SUCCESS) { display_read_buffer(); } AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 25 else { proc_result(result); // Find and display // appropriate Error } } // ********************************************************* void fn_write_sectors(void) { volatile char result; int sector, head, track; char test_array[] = "ZiLOG India is a software design center with the charter to fulfill the software needs of ZiLOG, Inc and those of it's customers by enabling creative, comprehensive solutions using ZiLOG semiconductor family offerings for new and traditional markets. ZiLOG India provides state of art embedded software solutions that complement ZiLOG semiconductor solutions with the specific goals of improving productivity, time-to-market, affordability, quality and other such major concerns of our customers worldwide.- ZiLOG"; result = blkcopy(wr_buffer, test_array, 512); // Prepare to call API. // Get the starting sector; Check for Error do { printf("\n\r Please enter the starting sector (0x01-0x20):\t"); sector = ScanHex(2); // Use HyperTerminal Echo // in place of printing } while (sector < 0x01 || sector > 0x20); // Get the Head information; Check for Error do { printf("\n\r Please enter the Head Number (0x0-0x3):\t"); head = ScanHex(1); // Use HyperTerminal Echo // in place of printing } while (head > 0x03); // Get the Track information; Check for Error do { AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 26 printf("\n\r Please enter the Track number (0x000-0x3d2):\t"); track = ScanHex(3); // Use HyperTerminal Echo // in place of printing } while (track > 0x3d2); // With the information obtained call the API result = write_sectors(sector, head, track); // API Call if (result == SUCCESS) { display_write_buffer(); } else { // printf("\n FNC result \t %x \t %d \n",result, result); proc_result(result); // Find and display appropriate Error } } // ********************************************************* void fn_erase_sectors(void) { volatile char result; int sector, head, track; // Prepare to call API. // Get the starting sector; Check for Error do { printf("\n\r Please enter the starting sector (0x01-0x20):\t"); sector = ScanHex(2); // Use HyperTerminal Echo // in place of printing } while (sector < 0x01 || sector > 0x20); // Get the Head information; Check for Error do { printf("\n\r Please enter the Head Number (0x0-0x3):\t"); head = ScanHex(1); // Use HyperTerminal Echo // in place of printing } while (head > 0x03); // Get the Track information; Check for Error do AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 27 { printf("\n\r Please enter the Track number (0x000-0x3d2):\t"); track = ScanHex(3); // Use HyperTerminal Echo // in place of printing } while (track > 0x3d2); // With the information obtained call the API result = erase_sectors(sector, head, track); // API Call if (result == SUCCESS) { printf("\n Sector erase complete \n"); } else { proc_result(result); // Find and display // appropriate Error } } /********************************************************* ***************** end of file *************************** *********************************************************/ /* ********************************************************* * File : Z_API_CF.c * Description : * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 28 #include #include #include #include "Z_API_CF.h" "UserIF.h" // --------------------------------------------------// Refer to the assembly code in data_structure_def.s // --------------------------------------------------extern extern extern extern char char char char rd_buffer[]; wr_buffer[]; cmd_tuple[]; sta_tuple[]; char *cmd_dest; char *attr_mem; extern char current_mode; // // // // From From From From RD_WR_BUF_ADDR to +511 +512 to +1023 +1023 to +1031 +1032 to +1039 // cmd_dest is a pointer to a character. /* ********************* ** ** APIs are listed here. ************************* */ char load_CF_mode(char mode) { // // This API does not interact with the CF. It loads tuple pointers with // appropriate addresses. // Returns 1 for success, or error_code otherwise. Updates the // current_mode global variable. // char result; int i; result = check_card(); if (result == 1) return (NO_CARD); // // // // Check presence of the card Card not found - Send Error code attr_mem = ATTRIBUTE_MEMORY; switch(mode) { AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 29 case 'm' : PB_DR = 0xE0; // Memory mode // Set ~OE to 1 through PB6; PB7 // = 1 for MUX control cmd_dest = MEMORY_MODE_REG0; // Mode dependent, global, presently Memory mode *(attr_mem) = 0x80; *(attr_mem) = 0x00; // Soft Reset started // Soft Reset finished // Wait for busy to start and clear while ((PB_DR & 0x02) == SET); // Wait till CF // starts the RESET while ((PB_DR & 0x02) == RESET); // Wait till CF // completes RESET for (i = 1; i > 20000; i++); *(attr_mem + 0x00) = 0x00; // Load Memory mode if required from IO mode current_mode = *(attr_mem); // read the config // register -OE reqd current_mode &= 0x3F; // Get the specific in PB_DR =0xC0; break; // PB5 for test only case 'c': // Contiguous IO mode // First switch mode from memory to I/O // Then load pointers for IO mode PB_DR = 0xE0; // ~OE = 1, RD/WR = OE/WE cmd_dest = MEMORY_MODE_REG0; // Mode dependent, global *(attr_mem) = 0x80; *(attr_mem) = 0x00; // Soft Reset started // Soft Reset finished // Wait for busy to start and clear while ((PB_DR & 0x02) == SET); // Wait till CF starts // the RESET while ((PB_DR & 0x02) == RESET); // Wait till the CF // completes RESET for (i = 1; i > 20000; i++); *(attr_mem + 0x00) = 0x01; AN015401-1103 // Load Contiguous IO mode // to Attribute Memory Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 30 current_mode = *(attr_mem); current_mode &= 0x3F; PB_DR = 0x40; cmd_dest = CON_IO_MODE_REG0; // // // // // // // read the config register -OE reqd Get the specific in Switch Mux output to ~IORD, ~IOWR Loading base pointer for the IO mode break; case 'p': // Primary IO mode // First switch mode from memory to I/O // Then load pointers for IO mode PB_DR = 0xE0; // ~OE = 1, RD/WR = OE/WE cmd_dest = MEMORY_MODE_REG0; // Mode dependent, global *(attr_mem) = 0x80; // Start RESET *(attr_mem) = 0x00; // End RESET // Wait for busy to start and clear while ((PB_DR & 0x02) == SET); // Wait till CF starts // the RESET while ((PB_DR & 0x02) == RESET); // Wait till the CF // completes RESET for (i = 1; i > 20000; i++); *(attr_mem) = 0x02; // // current_mode = *(attr_mem); // // current_mode &= 0x3F; // PB_DR = 0x40; // Switch Mux cmd_dest = PRI_IO_MODE_REG0; // // break; case 's': Load Primary IO mode to Attribute Memory read the config register -OE reqd Get the specific in output to ~IORD, ~IOWR Loading base pointer for the IO mode // Secondary IO mode // First switch mode from memory to I/O // Then load pointers for IO mode PB_DR = 0xE0; // ~OE = 1, RD/WR = OE/WE cmd_dest = MEMORY_MODE_REG0; // Mode dependent, global *(attr_mem) = 0x80; // Start RESET *(attr_mem) = 0x00; // End RESET // Wait for busy to start and clear while ((PB_DR & 0x02) == SET); // Wait till CF starts AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 31 // the RESET while ((PB_DR & 0x02) == RESET); // Wait till the CF // completes RESET for (i = 1; i > 20000; i++); *(attr_mem) = 0x03; // Load Secondary IO mode // to Attribute Memory current_mode = *(attr_mem); // read the config register // -OE reqd current_mode &= 0x3F; // Get the specific in PB_DR = 0x40; // Switch Mux output to ~IORD, ~IOWR cmd_dest = SEC_IO_MODE_REG0; // Loading base pointer for // the IO mode break; default:printf("\n Mode not known.\n Please enter from m,c,p,s\n"); break; } for (i = 1; i > 20000; i++); result = *(cmd_dest + 1); return(SUCCESS); // Inform upper layer of completion/failure } // ********************************************************* char identify_drive(void) { // // // // // // This command does not take any parameters. After execution by the CF card, the CF buffer is read. Later, the information in the buffer is analyzed and results are displayed on HyperTerminal through a Support Function. char result, error; int i; unsigned unsigned unsigned unsigned long short d_cylinders, d_heads, d_sect_per_trk; long d_sect_per_card; short c_cylinders, c_heads, c_sect_per_trk; long c_capacity; d_sect_per_card_1, d_sect_per_card_2, d_sect_per_card_3, d_sect_per_card_4; AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 32 long c_capacity_1, c_capacity_2, c_capacity_3, c_capacity_4; short *s_temp; // POINTER_FOR_SHORT; short is 2 bytes. // Check presence of the card. result = check_card(); if (result == 1) return (NO_CARD); // Check presence of the card // Card not found - Send // Error code *(cmd_dest + 6) = 0x00; *(cmd_dest + 7) = 0xEC; // Drive is zero // Command code 0xEC is Identify // Drive wait(cmd_dest); // wait for DRQ and BUSY, abort // if any Error for (i = 0; i < BUF_SIZE; i++) { *(rd_buffer+i) = *(cmd_dest); // Read from same address, // increment destination } error = *(cmd_dest + 1); return(error); /* // // // // // // Debug only // Inform upper layer of // completion/failure ------------------------------------------------------------The Buffer is read from CF into the SRAM Now we need to parse it for useful information. Note: Only some information is extracted as an illustration. -------------------------------------------------------------- s_temp = POINTER_FOR_SHORT; d_cylinders = *(s_temp + 1); d_heads d_sect_per_trk = *(s_temp + 3); = *(s_temp + 6); d_sect_per_card_1 d_sect_per_card_1 d_sect_per_card_2 d_sect_per_card_2 = *(s_temp + 7); & = 0x0000FFFF; = *(s_temp + 8); & = 0x0000FFFF; AN015401-1103 // This is taking just one // byte // MSW of a long word // LSW of a long word Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 33 d_sect_per_card = ((d_sect_per_card_1 << 16)|(d_sect_per_card_2)); c_cylinders = *(s_temp + 54); c_heads = *(s_temp + 55); c_sect_per_trk = *(s_temp + 56); c_capacity_1 = *(s_temp + 57); // MSW of a double word variable c_capacity_1 & = 0x0000FFFF; c_capacity_2 = *(s_temp + 58); // LSW of a double word variable c_capacity_2 & = 0x0000FFFF; c_capacity = ((c_capacity_1 << 16) | (c_capacity_2)); // ----------------------------------// Display the information extracted. printf("\n -------------------------------------------- \n"); printf("\n\r printf("\n\r printf("\n\r printf("\n\r Default Default Default Default number of cylinders number of heads sectors per Track sectors per card = = = = %d %d %d %d \t", \t", \t", \t", d_cylinders); d_heads); d_sect_per_trk); d_sect_per_card); printf("\n\r printf("\n\r printf("\n\r printf("\n\r Current Current Current Current number of cylinders number of heads sectors per Track capacity in sectors = = = = %d %d %d %d \t", \t", \t", \t", c_cylinders); c_heads); c_sect_per_trk); c_capacity); printf("\n -------------------------------------------- \n"); return(error) ; */ } // Indicate successful completion // ********************************************************* char set_features(void) { char result, error; int i; result = check_card(); if (result == 1) return (NO_CARD); // Check presence of the card // Card not found - Send // Error code // Card found, Load command tuple AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 34 *(cmd_dest + 1) = 0x69; *(cmd_dest + 6) = 0x00; *(cmd_dest + 7) = 0xEF; // // // // // Enable 8-bit data transfer FEATURES Drive is zero Command code 0xEF is set features // Wait for busy to start and clear while ((PB_DR & 0x02) == SET); // Wait till CF sets BUSY to // avoid false trigger while ((PB_DR & 0x02) == RESET); // Wait till the BUSY is // RESET, CF is ready now. for (i = 1; i < 20000; i++); error = *(cmd_dest + 1); //printf("\n API error %x \t %d \n", error, error); // Debug only return(error); // Inform upper layer of // completion/ failure } // ********************************************************* char read_sectors(int sector, int head, int track) { int cylinder_low, cylinder_high; volatile char result, error; int i; result = check_card(); if (result == 1) return (NO_CARD); // Check presence of the card // Card not found - Send // Error code // Prepare command data cylinder_low = track & 0x00F; cylinder_high = track >> 8; // Get the lower byte from Tracks // Get the higher byte from the // Tracks // Load command data to command tuple *(cmd_dest + 2) = 0x01; // Most of the CF cards support // one sector per request *(cmd_dest + 3) = sector; // Starting sector as received // from the API call *(cmd_dest + 4) = cylinder_low; *(cmd_dest + 5) = cylinder_high; AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 35 *(cmd_dest + 6) = (0xA0 | head);// No LBA, Drive 0, Head as // received from API call *(cmd_dest + 7) = 0x20; // Command code 0x20 or 0x21 is // Read Sectors wait(cmd_dest); // wait for DRQ and BUSY, abort if in Error for (i = 0; i < BUF_SIZE; i++) { *(rd_buffer+i) = *(cmd_dest); // Read from same address, // increment destination } error = *(cmd_dest + 1); return(error); // Debug only // Inform upper layer of completion/ failure } // ********************************************************* char write_sectors(int sector, int head, int track) { int cylinder_low, cylinder_high; volatile char result, error; int i; result = check_card(); if (result == 1) return (NO_CARD); // Prepare command data cylinder_low = track & 0x00F; cylinder_high = track >> 8; // Load command data to command tuple *(cmd_dest + 2) = 0x01; *(cmd_dest + 3) = sector; *(cmd_dest + 4) = cylinder_low; *(cmd_dest + 5) = cylinder_high; *(cmd_dest + 6) = (0xA0 | head); *(cmd_dest + 7) = 0x30; // Check presence of the card. // Card not found - Send // Error code // Get the lower byte from Tracks // Get the higher byte from the // Tracks // // // // // // // // Number of sectors is 1 Starting sector Cylinder Low Cylinder High No LBA, Drive 0, Head as received from API call Command code 0x30 or 0x31 is Write Sectors //error = *(cmd_dest + 1); AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 36 //error &= 0xFF; //printf("\n API 1st error \t %x \t %d \n", error, error); wait(cmd_dest); for (i = 0; i < BUF_SIZE; i++) { *(cmd_dest) = *(wr_buffer + i); // wait for DRQ and BUSY, abort // if in Error // // // // As CF controller implements a FIFO, Data is written to the same address and source is incremented // // // // Wait till CF sets BUSY to avoid false trigger Wait till the BUSY is RESET, CF is ready now } //Wait for busy to start and clear while ((PB_DR & 0x02) == SET); while ((PB_DR & 0x02) == RESET); for (i = 1; i < 20000; i++); error = *(cmd_dest + 1); // Read CF error register error &= 0xFF; //printf("\n API 2nd error \t %x \t %d \n", error, error); return(error); // Inform upper layer of completion/ failure } // ********************************************************* char erase_sectors(int sector, int head, int track) { // Same as write sectors fills the sector with 0xFF int cylinder_low, cylinder_high; volatile char result, error; int i; result = check_card(); if (result == 1) return (NO_CARD); // Prepare command data cylinder_low = track & 0x00F; cylinder_high = track >> 8; AN015401-1103 // Check presence of the card // Card not found - Send Error // code // // // // Get the lower byte from Tracks Get the higher byte from the Tracks Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 37 // Load command data to command tuple *(cmd_dest + 2) = 0x01; *(cmd_dest + 3) = sector; *(cmd_dest + 4) = cylinder_low; *(cmd_dest + 5) = cylinder_high; *(cmd_dest + 6) = (0xA0 | head); *(cmd_dest + 7) = 0x30; // // // // // // // // Number of sectors is 1 Starting sector Cylinder Low Cylinder High No LBA, Drive 0, Head as received from API call Command code 0x30 or 0x31 is Write Sectors error = *(cmd_dest + 1); //error &= 0xFF; //printf("\n API 1st error \t %x \t %d \n", error, error); wait(cmd_dest); // wait for DRQ and BUSY, abort if in Error for (i = 0; i < BUF_SIZE; i++) { *(cmd_dest) = 0xFF; // Write to the same address // constant data of 0xFF } //Wait for busy to start and clear while ((PB_DR & 0x02) == SET); while ((PB_DR & 0x02) == RESET); // // // // Wait till CF sets BUSY to avoid false trigger Wait till the BUSY is RESET, CF is ready now for (i = 1; i < 20000; i++); error = *(cmd_dest + 1); //error &= 0xFF; //printf("\n API 2nd error \t %x \t %d \n", error, error); return(error); // Inform upper layer of // completion/ failure } /********************************************************* ***************** end of file *************************** *********************************************************/ /* ********************************************************* * File : Z_CF_SUPPORT.c * Description : * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 38 * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ #include #include #include #include #include "Z_API_CF.h" "UserIF.h" "utility.h" // Referring to the assembly code extern char rd_buffer[]; // extern char wr_buffer[]; // extern char cmd_tuple[]; // extern char sta_tuple[]; // extern char *cmd_dest; From From From From RD_WR_BUF_ADDR to +511 +512 to +1023 +1023 to +1031 +1032 to +1039 char current_mode; void init_F91(void) { // Initialize Port B for CF application. PB_ALT1 = 0x00; // RESET default PB_ALT2 = 0x00; // RESET default PB_DDR = 0x0F; // Upper nibble as output, lower nibble as input PB_DR = 0xE0; // This is for CF Memory mode. 0b1110---} void init_parameters(void) { // Initialize the parameters/flags required for this appnote. current_mode = 0xFF; // current_mode is global. Initialize // to memory mode (0) cmd_dest = MEMORY_MODE_REG0; // Mode dependent, global AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 39 } char check_card(void) { char card_detect; card_detect = (PB_DR & 0x01); return (card_detect); // Check PB0 for "~CD1 OR ~CD2" // If card is present // then the PB0 is ZERO. // 0 = present; 1 = absent } void wait(char *cmd_dest) { char wait, wait_busy, wait_drq, error; do { wait = *(cmd_dest + 0x07); error = wait & 0x01; if (error == 1) return; wait_busy = wait & 0x80; } while (wait_busy == 0x80); // Read status register // Error occurred, abort wait // Wait for BUSY to RESET do { wait = *(cmd_dest + 0x07); error = wait & 0x01; if (error == 1) return; wait_drq = wait & 0x08; } while (wait_drq == 0x00); // Read status register // Error occurred, abort wait. // Wait for DRQ to SET } void proc_result(char result) { volatile char error; if (result == NO_CARD) printf("\n ! Card not found \n"); error = result & 0x80; AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 40 if (error == 0x80) printf("\n Bad block detected. "); error = result & 0x40; if (error == 0x40) printf("\n Uncorrectable Error Encountered."); error = result & 0x10; if (error == 0x10) printf("\n Wrong Sector ID or Sector not found."); error = result & 0x01; if (error == 0x01) printf("\n General Error."); error = result & 0x04; if (error == 0x04) printf("\n Command Aborted \n"); // // // printf("Error Code:\t %x \n", result); printf("Error Code:\t %d \n", result); putchar(result); } /********************************************************* ***************** end of file *************************** *********************************************************/ /* ********************************************************* * File : UserIf.c * Description : * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 41 *********************************************************** */ #include #include #include #include #include #include "Z_API_CF.h" "UserIF.h" "utility.h" "SIO.h" // ----------------------------------char mode_select(void); void display_error(char); void welcome (void); // ----------------------------------extern char rd_buffer[]; // From extern char wr_buffer[]; // From extern char cmd_tuple[]; // From extern char sta_tuple[]; // From // ----------------------------------- RD_WR_BUF_ADDR to +511 +512 to +1023 +1023 to +1031 +1032 to +1039 void welcome(void) { printf("\n \n \n-----------------------\n"); printf("Welcome to eZ80 Acclaim!\n"); printf("Compact Flash Interface\n"); printf("-----------------------\n"); } void display_menu(void) { printf("%s\n", menu0); printf("%s\n", menu1); printf("%s\n", menu2); printf("%s\n", menu3); printf("%s\n", menu4); printf("%s\n", menu5); //printf("%s\n", menu6); //printf("%s\n", menu7); } // // // // // // Mode Select Identify Drive Set Features Read Sector Write Sector Erase sector void display_prompt(void) { printf(prompt); AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 42 } void display_mode_select(void) { printf("%s\n", mode0); printf("%s\n", mode1); printf("%s\n", mode2); printf("%s\n", mode3); //printf("%s\n", mode4); } // // // // // Memory mode Contiguous I/O mode Primary I/O Secondary I/O True IDE void display_read_buffer(void) { int j; printf("\n\n ------- Read buffer ----------\n"); for (j = 0; j < BUF_SIZE; j++) { putchar(*(rd_buffer+j)); } printf("\n ------- Read buffer ----------\n\n"); } void display_write_buffer(void) { int j; printf("\n\n ------- Write buffer ----------\n"); for (j = 0; j < BUF_SIZE; j++) { putchar(*(wr_buffer+j)); } printf("\n ------- Write buffer ----------\n\n"); } void display_mode(char mode) { switch (mode) { case 0: printf("\n Current mode is: \t Memory mode \n"); break; case 1: printf("\n Current mode is: \t Contiguous IO mode \n"); break; AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 43 case 2: printf("\n break; case 3: printf("\n break; case 4: printf("\n break; default:printf("\n break; Current mode is: \t Primary IO mode \n"); Current mode is: \t Secondary IO mode \n"); Current mode is: \t True IDE mode \n"); Current mode is: Default - Memory"); } } /********************************************************* ***************** end of file *************************** *********************************************************/ /* ********************************************************* * File : utility.c * Description : * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ #include "SIO.h" #include int ascii_to_hex(int chr) { if((chr >= '0') && (chr <= '9')) return chr - '0'; else if((chr >= 'A') && (chr <= 'F')) return chr - 'A' + 10; AN015401-1103 Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 44 else if((chr >= 'a') && (chr <= 'f')) return chr - 'a' + 10; else return -1; } void printhex(unsigned int num) { unsigned char i=5; unsigned char str[6]; str[5] = '\0'; do { int temp = num & 0x00000F; if(temp < 10) temp += '0'; else temp += 'A'-10; str[--i] = temp; num >>= 4; } while (num); while (i < 6) putch(str[i++]); } unsigned int ScanHex (unsigned char num) { unsigned char ch; unsigned int addr; int temp1, temp2, temp3, temp4, temp5; do { ch=getch(); temp1 = ascii_to_hex(ch); } while (temp1 < 0); printhex(temp1); if (num == 1) { ch = temp1 & 0x0F; return (ch); } do AN015401-1103 // Get pressed key from keyboard // Ignore invalid keypress Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 45 { ch=getch(); temp2 = ascii_to_hex(ch); } while (temp2 < 0); printhex(temp2); if (num == 2) { ch = (temp1 << 4) & 0xF0; ch = (ch | temp2) & 0xFF; return (ch); } do { ch=getch(); temp3 = ascii_to_hex(ch); } while (temp3 < 0); printhex(temp3); if (num == 3) { addr = 0x0000; addr = (temp1 << 4) & 0x00F0; addr = (addr | temp2); addr = (addr << 4) & 0x0FF0; addr = (addr | temp3) & 0x0FFF; return (addr); } do { ch=getch(); temp4 = ascii_to_hex(ch); } while (temp4 < 0); printhex(temp4); if (num == 4) { addr = 0x0000; addr = (temp1 << 4) & 0x00F0; addr = (addr | temp2); addr = (addr << 4) & 0x0FF0; addr = (addr | temp3); addr = (addr << 4) & 0xFFF0; addr = (addr | temp4) & 0xFFFF; return (addr); } do AN015401-1103 // why & ??? Appendix D--C Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 46 { ch=getch(); temp5 = ascii_to_hex(ch); } while (temp5 < 0); printhex(temp5); addr = 0x000000; addr = (temp1 << 4) & 0x0000F0; addr = (addr | temp2); addr = (addr << 4) & 0x000FF0; addr = (addr | temp3); addr = (addr << 4) & 0x00FFF0; addr = (addr | temp4) & 0x00FFFF; addr = (addr << 4) & 0x0FFFF0; addr = (addr | temp5) & 0x0FFFFF; return (addr); } /********************************************************* ***************** end of file *************************** *********************************************************/ Assembly File The following assembly file is listed in this section: * data_structure_def.s /* ********************************************************* * File : data_structure_def.s * Description : * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ AN015401-1103 Appendix D--Assembly File Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 47 ; public__exit ; extern_main ; ; .include"ez80F91.inc" ; RD_WR_BUF_ADDR: .equ %C30000 ; This is the starting address of the ; buffer section. These map to CS1 mapped ; RAM located on the Module board. The RAM ; is 512KBytes and we are reserving ;1040 bytes here ;********************************************************************* ;* Define global arrays for read and write data buffers. ;* Define global arrays for command/status Tuple data ;********************************************************************* define segment xdef _buffer_section, SPACE =RAM, ORG = RD_WR_BUF_ADDR _buffer_section _rd_buffer, _wr_buffer, _cmd_tuple, _sta_tuple _rd_buffer: ds 512 _wr_buffer: ds 512 _cmd_tuple: ds 8 _sta_tuple: ds 8 ; ; ; .assume adl = 1 segment CODE .def XDEF ; ; ; ; From From From From RD_WR_BUF_ADDR to +511 +512 to +1023 +1023 to +1031 +1032 to +1039 ;, SPACE = ROM _blkcopy _blkcopy ;***C Function Prototype: ; int blkcopy( BYTE * p_dest, BYTE * p_source, TRIO Length ); ; return OK (1) if successful ; _blkcopy: push ld add ld AN015401-1103 ix ix, 0 ix, sp de, (ix+6) Appendix D--Assembly File Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 48 ld ld hl, (ix+9) bc, (ix+12) push ld or adc pop jr hl hl, 0 a , a hl, bc hl z, done_copy ldir ld hl,1 done_copy: ld pop ret sp, ix ix ; /********************************************************* ***************** end of assembly file ******************* *********************************************************/ Header Files The following header files are listed in this section: * userif.h /* ********************************************************* * File : userif.h * Description : Function Prototypes * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * AN015401-1103 Appendix D--Header Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 49 * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ void void void void display_prompt(void); display_mode(char); display_menu(void); display_error(char); // Function prototypes for individual sub-command menu void display_mode_select(void); void display_read_buffer(void); void display_write_buffer(void); void welcome (void); /* ************************************* ** Define various string constants here **************************************** */ static const char menu0[] = "\n\r m.\tMode Select"; static const char menu1[] = "\n\r i.\tIdentify Drive"; static const char menu2[] = "\n\r s.\tSet Features"; static const char menu3[] = "\n\r r.\tRead Sector"; static const char menu4[] = "\n\r w.\tWrite Sector"; static const char menu5[] = "\n\r e.\tErase Sector"; // static const char menu6[] = "\n\r 6.\tDisplay Read Buffer"; // static const char menu7[] = "\n\r 7.\tDisplay Write Buffer"; static const char mode0[] = static const char mode1[] = static const char mode2[] = static const char mode3[] = // static const char mode4[] "\n\r m.\tMemory Mode"; "\n\r c.\tContiguous I/O mode"; "\n\r p.\tPrimary I/O mode"; "\n\r s.\tSecondary I/O mode"; = "\n\r t.\tTrue IDE mode"; static const char prompt[] = "\nCF >>\t"; // Error messages /*************************************************************** ******************* End of userif.h file ********************* ***************************************************************/ AN015401-1103 Appendix D--Header Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 50 /* ********************************************************* * File : Z_API_CF.h * Description : Function Prototypes * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ void void void void void void void test_temp(void); fn_mode_select(void); fn_identify_drive(void); fn_set_features(void); fn_read_sectors(void); fn_write_sectors(void); fn_erase_sectors(void); // API declarations char load_CF_mode(char); char identify_drive(void); char read_sectors(int,int,int); char write_sectors(int,int,int); char erase_sectors(int,int,int); char set_features(void); // Support function declarations char load_CF_command(char); char process_result(char); char load_CF_command(char); void init_F91(void); void command_select(void); void init_parameters(void); AN015401-1103 Appendix D--Header Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 51 void proc_result(char); char check_card(void); // char check_busy(void); void wait(char *); /* ****************************************************** Store starting address of command tuple in various modes ********************************************************* */ // #define ATTRIBUTE_MEMORY // #define ATTRIBUTE_MEMORY #define ATTRIBUTE_MEMORY (char *)0xA82800 (char *)0xA82A00 (char *)0xA82200; // -REG(A-11) is zero // ------------------------------------------#define MEMORY_MODE_REG0(char *)0xA82800; // #define CON_IO_MODE_REG0(char *)0xA82000; // #define PRI_IO_MODE_REG0(char *)0xA821F0; // #define SEC_IO_MODE_REG0(char *)0xA82170; // -REG(A-11) -REG(A-11) -REG(A-11) -REG(A-11) is is is is one. zero zero zero /* #define CON_IO_MODE_REG0(char *)0xA82800 #define PRI_IO_MODE_REG0(char *)0xA829F0 #define SEC_IO_MODE_REG0(char *)0xA82970 */ // ------------------------------------------#define IDE_MODE_REG0 (char *)0xA82800// -REG(A-11) is one. A3-A10 are '0' #define POINTER_FOR_SHORT #define POINTER_FOR_LONG (short *)0xC30000 (long *)0xC30000 /* ********************************* * Miscellaneous information storage ********************************* */ #define BUF_SIZE 512 /* ************************************************************ Error codes are defined here. ************************************************************ */ #define UNKNOWN_COMMAND #define UNKNOWN_MODE AN015401-1103 0xFF 0xFF Appendix D--Header Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 52 //#define RESELECT_MODE //#define RESELECT_COMMAND #define NO_CARD #define SUCCESS 0x00 0x00 0xFE 0x00 // Success is equivalent to // error = 0 /* ************************************ ** Command parameters are defined here. *************************************** */ #define DRIVE_ID 0xAA #define SET 0x01 #define RESET 0x00 /*************************************************************** ******************* End of Z_API_CF.h file ******************* ***************************************************************/ /* ********************************************************* * File : utility.h * Description : Prototype Definitions * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ void clear_screen (void); unsigned int ScanHex (unsigned char num); int ascii_to_hex(int chr); void printhex(unsigned int num); void myputs(const char* mystring); /*************************************************************** AN015401-1103 Appendix D--Header Files Application Note CompactFlash(R) Interface for eZ80Acclaim!TM MCUs 53 ******************* End of utility.h file ******************* ***************************************************************/ /* ********************************************************* * File : sio.h * Description : Function Prototypes * * Copyright 2003 ZiLOG Inc. ALL RIGHTS RESERVED. * * The source code in this file was written by an * authorized ZiLOG employee or a licensed consultant. * The source code has been verified to the fullest * extent possible. * * Permission to use this code is granted on a royalty-free * basis. However users are cautioned to authenticate the * code contained herein. * * ZiLOG DOES NOT GUARANTEE THE VERACITY OF THE SOFTWARE. *********************************************************** */ void init_UserIF(void); char putch(char c); int kbhit(void); char getch(void); /*************************************************************** ******************* End of sio.h file ************************ ***************************************************************/ AN015401-1103 Appendix D--Header Files Application Note CompactFlash Interface for eZ80Acclaim!TM MCUs 54 Appendix E--API Description This appendix provides a description of the APIs used to interface the eZ80F91 MCU with the CompactFlash interface described in this Application Note. Table 6 presents a list of CompactFlash Interface APIs for quick reference. Details are provided in this section--use the hyperlinks below to jump quickly to one of these APIs. Table 6. CompactFlash Interface APIs API Name Description char load_CF_mode() Selects the CompactFlash mode char identify_drive() Identifies the CompactFlash card char read_sectors() Reads specified sector on the CompactFlash card char write_sectors() Writes to a specified sector on the CompactFlash card char erase_sectors() Erases specified sector on the CompactFlash card char set_features() Displays/sets features for the CompactFlash card In general, all of the above mentioned APIs receive relevant information from corresponding calling functions from the host, and load the CompactFlash command tuple with the received parameters and command words. The APIs handle the data transfer (when required) between the CompactFlash card and the eZ80Acclaim! microcontroller. Finally the APIs check the error register and report the success and failure of the operation to the calling function. Descriptions for the CompactFlash Interface APIs begin on the next page. AN015401-0903 Appendix E--API Description Application Note CompactFlash Interface for eZ80Acclaim!TM MCUs 55 char load_CF_mode() char load_CF_mode(char mode) Description The load_CF_mode() API initializes the CompactFlash card in a specified mode of operation. It also modifies the pointers to the command tuple. The mode parameter takes m, c, p, or s as values to reset the CompactFlash card to the memory mode, the contiguous I/O mode, the primary I/O mode or the secondary I/O mode, respectively. Parameters char mode The mode to which the CompactFlash is to be reset Returns 0 error_codes On Success On Failure Usage result = load_CF_mode(mode); AN015401-0903 Appendix E--API Description Application Note CompactFlash Interface for eZ80Acclaim!TM MCUs 56 char identify_drive() char identify_drive(void) Description The identify_drive() API reads the CompactFlash memory structure (number of heads, sectors, tracks and so on) and the manufacturer's information from the CompactFlash Storage Card and copies the information into the read buffer for the host to use. The host calling function parses the read buffer and displays the information on the HyperTerminal. Parameters void Returns 0 error_codes On Success On Failure Usage result = identify_drive(); AN015401-0903 Appendix E--API Description Application Note CompactFlash Interface for eZ80Acclaim!TM MCUs 57 char read_sectors() char read_sectors(int sector,int head,int track) Description The read_sectors() API receives the track, head, and sector number of the sector to be read from the host. The API then transfers the data residing in the specified location from the CompactFlash card to the host's read buffer. On completing the operation, the API returns a success or a failure. Parameters int sector The sector number from where data is to be read int head The head number from where data is to be read int track The track number from where data is to be read Returns 0 error_code On Success On Failure Usage result = read_sectors(sector,head,track); AN015401-0903 Appendix E--API Description Application Note CompactFlash Interface for eZ80Acclaim!TM MCUs 58 char write_sectors() char write_sectors(int sector,int head,int track) Description The write_sectors() API receives the track, head, and sector number of the sector where the host requires to write the data. The API then transfers the data from the host's write buffer to the CompactFlash card. On completing the operation, the API returns a success or a failure. Parameters int sector The sector number where data is to be written on the CompactFlash card int head The head number where data is to be written on the CompactFlash card int track The track number where data is to be written on the CompactFlash card Returns: 0 error_code On Success On Failure Usage result = write_sectors(sector,head,track); AN015401-0903 Appendix E--API Description Application Note CompactFlash Interface for eZ80Acclaim!TM MCUs 59 char erase_sectors() char erase_sectors(int sector,int head,int track) Description The erase_sectors() API is used to erase previously written data in a specified sector. Functionally, this API is similar to the write_sectors() API, except that instead of the transferring data from the host buffer to the specified sector, the erase_sector() API populates the specified sector with 0xFF. Parameters int sector The sector number from where data is to be erased int head The head number from where data is to be erased int track The track number from where data is to be erased Returns 0 error_code On Success On Failure Usage result = erase_sectors(sector,head,track); AN015401-0903 Appendix E--API Description Application Note CompactFlash Interface for eZ80Acclaim!TM MCUs 60 char set_features() char set_features(void) Description The set_features() API is used by the host to establish or select certain features of the CompactFlash card. Parameters void Returns 0 error_code On Success On Failure Usage result = set_features(); AN015401-0903 Appendix E--API Description