Home        Archives        Search        Feedback        Subscribe        Analog Devices 

Volume 37 January 2003

USING THE ADSP-2191 EZ-KIT LITE FOR COMPACTFLASH™ PROTOTYPING

Note: This article provides the detailed implementation of an interface described in "Glue-less, Hot-Swappable CompactFlash™ Storage-Card Interface with the ADSP-2191M Digital Signal Processor". To read this article, click here

CF Interfacing to ADSP-2191M
Using the EZ-KIT Lite, all eleven address lines on the CF header are connected to the DSP. However, the CF's A8, A7, A6, A5, and A4 pins can be tied to the GND pin on the CF 50-pin male header, since these are always driven to zero by the DSP for accessing common and attribute memory—they are also labeled as "don't care" in the CompactFlash Association specification. Since accesses to the card are performed at 8 bits, the DSP's D[7:0] pins are simply connected to CF's D[7:0] pins. The DSP's RD and WR, pins are connected to OE and WE, respectively. To read and write internal control/status registers and read data sectors, the DSP performs asynchronous READ/WRITE cycles by driving the CF card's OE and WE strobes low. Additional DSP address lines, A11, A12, A13, are used as additional card select lines. A11 is connected to REG, A12 is connected to CE1, and A13 is connected to CE2. When performing 8-bit accesses, by simply driving A[13:11] to certain combinations (see Table 1), we can control whether the access is to attribute or common memory, and whether the even or odd sector data byte is accessed.

So far, we have discussed the CF's address, data, and control strobes. Now consider the remaining CF pins required to complete the interface. One general-purpose I/O flag pin is used for CF card detection when it is inserted into the CF slot. The CF's CD2 and CD1 (card detect pins) are grounded internally to indicate that the CF card has been inserted. In this interface, the DSP's PF2 flag pin is connected to the CD1 pin. When the state of the CD1 pin is '0,' the DSP recognizes the insertion of the card. A pull-up resistor is recommended on CD1 to keep PF2 high and prevent it from floating when the card is not inserted.

The CF's RDY/BSY pin can be connected to another programmable flag pin (PF0) to test whether the card is ready for data transfer or is busy performing internal operations. However, the BUSY and RDY bits can also be polled in the ATA Status or Alternate Status registers to detect whether the host is locked out or ready for data transfer; this removes the requirement for a physical connection to RDY/BSY.

Finally, the CF's WAIT pin can be optionally connected to ACK to delay the completion of a RD or WR access by the DSP. This also is optional, because the ADSP-2191's MSxCTL register can be programmed to add wait states and divide the external port clock to meet the CompactFlash maximum read- or write-cycle times. By slowing down the DSP's external asynchronous read or write cycle to meet or exceed worst case CF access times, one can guarantee that data will be valid or latched upon release of the DSP's RD or WR memory strobes. To summarize, only 18 interconnections are required to develop a functional interface between the DSP and the CF.

To allow for the card to be reset under software control, while also providing access to the card's ATA registers, I mapped the CompactFlash card's common and attribute memory banks. Bank 1 (MS1) was mapped to common memory to access ATA registers, while Bank 2 (MS2) was used to access attribute memory to make it feasible to perform a reset of the card under software control. This made unnecessary a hardwire connection of the CF's RESET line to a DSP flag pin. Notice, however, that while the CF card is mapped to two different DSP external memory spaces, the MS1 and MS2 pins are not physically connected to the card's chip/memory enable pins (REG, CD2, CD1) on the card. Simply generating the proper bank addresses will ensure whether attribute or common memory is being accessed (since REG is connected to the A11 address pin and can be activated or deactivated regardless of bank address). The mapping to two different banks is necessary—as the two memory spaces have different read/write timing requirements, complying with the CFA's specification. Therefore, both memory banks are programmed using different wait states and peripheral clock divide values.

Adapting the ADSP-2191 EZ-KIT Lite
Figure 6 shows the CF prototype system developed using the ADSP-2191 EZ-KIT Lite. Connecting the CF to the EZ-KIT is accomplished through the use of a PLCC-to-PGA adapter mounted over the EZ-KIT's PLCC boot flash, and a row of 0.1-inch headers to connect to some GPIO pins and also supply 3.3 volt power and GND to the card.

Figure 6. Sycard CompactFlash CF Extend 180 CIB to the ADSP-2191 EZ-KIT Lite.

The CompactFlash development board chosen for the interface was the CF Extend 180 Card Interface Board (CIB), manufactured by Sycard Technology (part #: 180CIB, which can be ordered on-line at www.sycard.com). The Sycard Technology card interface board allows for easy prototyping with a host processor and a CompactFlash card. The CompactFlash to be tested is simply inserted into the CIB's 50-pin CF male header. The CIB routes all CF signals to four sets of 0.1 inch standard 26-pin headers, providing easy access for soldering connections to a host and for mounting to a perforated board with 0.1-inch spaced holes. The connections were soldered, but I encountered no noise or signal integrity problems to interfere with the operation of the CF card (the CIB is a four-layer board with a separate VDD and GND plane for supplying power to the CF card).

To connect the accessed CF pins on the Sycard CIB to the ADSP-2191 on the EZ-KIT Lite, I chose to use a 32-pin PLCC-to-PGA LoClip adapter from Ironwood Electronics (part # LC-PLCC32-01, available at www.ironwoodelectronics.com). Figure 7 shows a top-, bottom-, and side view of the adapter, and the way it is inserted over the EZ-KIT's ST Micro boot flash (M29W040B). The top PGA pins provided by the adapter are used to wire up to the Sycard CIB.

Figure 7. Ironwood Electronics PGA-to-PLCC Adapter.

Figure 8. Ironwood Electronics PLCC-to-PGA adapter pin
connections used for CompactFlash access.

Why was this adapter chosen—instead of accessing the external bus pins available on the EZ-KIT Lite? The EZ-KIT EMI external port P9/P10 headers (which provide access to all external port address and data bus pins) are not populated on currently shipping 2191 EZ-KITs, which offers a significant design challenge for wiring up a CompactFlash—otherwise a 16-bit data bus interface would have been chosen. However, with the use of the handy 32-pin PLCC-to-PGA LoClip connected over the boot flash on the EZ-KIT, we could then easily access data pins D[7:0], address pins A[18:0], RD, and WR through standard 0.1-inch PGA headers; this is sufficient to enable 8-bit CompactFlash accesses (refer to Figure 8 for actual location of PGA pins used on the adapter).

The Ironwood Electronics LoClip allows the required number of DSP-to-CF interconnections to be kept to a minimum. As with a 16-bit data bus, 8-bit accesses provide the capability to address all data on the card, just by doubling accesses from 256 to 512 sector read/write cycles. In the case of MP3 playback on the ADSP-2191, 8-bit accesses are fast enough to meet MP3 input data-fill requirements, as the MP3 playback data rates (44.1 kHz) are much slower than the 160-MHz internal core clock rate. The MP3 block decoder is running in the background and accesses the card only when the next 4 sectors of data are needed in the input MP3 buffer. In fact, the FAT16 file system used here for reading MP3 file data clusters takes only about 2% of the ADSP-2191's 160 available MIPS.

Figure 9 shows the remaining connections needed by the CompactFlash via the EZ-KIT P9 and P14 headers. P9 provides access to the DSP's PF[7:0] pins through standard 0.1-inch headers. P9 is used to connect the CF's CD1 and RDY/BSY pins to PF2 and PF0, respectively. BR on the DSP is connected to PF6. No pull-up is needed since the board already ties BR to 3.3 V through a 10 kΩ pull-up resistor. Lastly, to complete the connections between the card and the DSP, 3.3 V VDD supply and GND are supplied through header P14 to the CompactFlash VDD and GND pins.

Figure 9. Signal connections required on EZ-KIT Lite
P9 and P14 headers for supplying power.

Examples of Assembly-Language Program for ATA Read/Write-Sector Command Implementation
The following ADSP-2191 assembly language subroutines demonstrate how to program the ATA interface to transfer sectors of data between the DSP and a CompactFlash storage card. These routines use the C/H/S mode of addressing (versus logical block addressing) to access the CompactFlash storage card's memory. As lowest-level access routines, they do not include any error or timeout code. They can serve as a basis for developing a standard file system format, such as FAT-16 used on PC-DOS/Windows machines.

/////// ATA register name DM address ///////
#define DATA_REGISTER 0x402800
#define ERROR_REGISTER 0x402801
#define FEATURE_REGISTER 0x402801
#define SECTOR_COUNT_REG 0x402802
#define SECTOR_NUMBER_REG 0x402803
#define CYLINDER_LOW_REG 0x402804
#define CYLINDER_HI_REG 0x402805
#define DRIVE_HEAD_REG 0x402806
#define STATUS_REGISTER 0x402807
#define COMMAND_REGISTER 0x402807
#define READ_DATA_REG_EVEN_BYTE 0x402808
#define READ_DATA_REG_ODD_BYTE 0x402809
#define WRITE_DATA_REG_EVEN_BYTE 0x402808
#define WRITE_DATA_REG_ODD_BYTE 0x402809
#define ALTERNATE_STATUS_REG 0x40280E
#define DEVICE_CONTROL_REG 0x40280E
#define DRIVE_ADDRESS_REG 0x40280F

/////// ATA COMMANDS (COMMAND REGISTER VALUE) ///////
#define IDENTIFY_DRIVE 0xEC
#define READ_SECTORS 0x20
#define WRITE_SECTORS 0x30

/////// ATA Status Register bit definitions ///////
#define BUSY 7
#define RDY 6
#define DRQ 3
#define ERR 0

.SECTION /dm data1;

.VAR Read_Buffer[256];
.VAR Write_Buffer[256];
.VAR SectorCount;
.VAR SectorNumber;
.VAR HeadNumber;
.VAR CylinderLow;
.VAR CylinderHigh;
.VAR DriveHead;


.SECTION /pm program;

CF_readwrite_sector_test:
/* Write data to CF at C/H/S addr 16/4/64 */
DMPG1 = Access_Internal_DM;
ar = 0x01; DM(SectorCount) = ar;
ar = 0x10; DM(SectorNumber) = ar;
ar = 0x04; DM(HeadNumber) = ar;
ar = 0x40; DM(CylinderLow) = ar;
ar = 0x00; DM(CylinderHigh) = ar;
call Write_Sector_CF;

/* Verify newly written data from CF at CHS =
16/4/64
DMPG1 = Access_Internal_DM;
ar = 0x01; DM(SectorCount) = ar;
ar = 0x10; DM(SectorNumber) = ar;
ar = 0x04; DM(HeadNumber) = ar;
ar = 0x40; DM(CylinderLow) = ar;
ar = 0x00; DM(CylinderHigh) = ar;
call Read_Sector_CF;

RTS;

//////////////////////////////////////////////////////////////////////////////////////
// Subroutine to read 512 bytes from CompactFlash //
/////////////////////////////////////////////////////////////////////////////////////

Read_Sector_CF:
DMPG1 = Access_Internal_DM; nop; nop;

// Read CF ATA Drive Parameters
ax0 = DM(SectorCount);
ax1 = DM(SectorNumber);
mx0 = DM(HeadNumber);
ay0 = DM(CylinderLow);
ay1 = DM(CylinderHigh);

CALL Check_CF_Busy;

DMPG1 = Access_Common_Memory; nop; nop;

CALL Check_CF_RDY_Status;

DM(SECTOR_COUNT_REG) = ax0;
CALL Check_CF_RDY_Status;
DM(SECTOR_NUMBER_REG) = ax1;
CALL Check_CF_RDY_Status;
DM(CYLINDER_LOW_REG) = ay0;
CALL Check_CF_RDY_Status;
DM(CYLINDER_HI_REG) = ay1;
CALL Check_CF_RDY_Status;

ax0 = 0xA0;
ar = ax0 OR mx0;
DM(DRIVE_HEAD_REG) = ar;
CALL Check_CF_RDY_Status;

ar = READ_SECTORS;
DM(COMMAND_REGISTER) = ar;
CALL Check_CF_RDY_Status;

CALL Check_CF_DRQ_Status;

i3 = Read_Buffer;
l3 = 0;

CNTR = 256;

Do get_cfdata UNTIL CE;
DMPG1 = Access_Common_Memory;
ay0 = DM(READ_DATA_REG_ODD_BYTE);
sr = LSHIFT ay0 BY 8 (LO);
ay1 = DM(READ_DATA_REG_EVEN_BYTE);
ar = sr0 OR ay1;
DMPG1 = Access_Internal_DM;
get_cfdata:
DM(I3, 1) = ar;

RTS;

/////////////////////////////////////////////////////////////////////////////////
// Subroutine to write 512 bytes to CompactFlash //
/////////////////////////////////////////////////////////////////////////////////
Write_Sector_CF:
DMPG1 = Access_Internal_DM; nop; nop;

/* Read CF ATA Drive Parameters */
ax0 = DM(SectorCount);
ax1 = DM(SectorNumber);
mx0 = DM(HeadNumber);
ay0 = DM(CylinderLow);
ay1 = DM(CylinderHigh);

CALL Check_CF_Busy;

DMPG1 = Access_Common_Memory; nop; nop;

CALL Check_CF_RDY_Status;

DM(SECTOR_COUNT_REG) = ax0;
CALL Check_CF_RDY_Status;
DM(SECTOR_NUMBER_REG) = ax1;
CALL Check_CF_RDY_Status;
DM(CYLINDER_LOW_REG) = ay0;
CALL Check_CF_RDY_Status;
DM(CYLINDER_HI_REG) = ay1;
CALL Check_CF_RDY_Status;

ax0 = 0xA0;
ar = ax0 OR mx0;
DM(DRIVE_HEAD_REG) = ar;
CALL Check_CF_RDY_Status;

ar = WRITE_SECTORS;
DM(COMMAND_REGISTER) = ar;
CALL Check_CF_RDY_Status;

CALL Check_CF_DRQ_Status;

i3 = Write_Buffer;
l3 = 0;

CNTR = 256;
Do put_cfdata UNTIL CE;
DMPG1 = Access_Internal_DM;
ay0 = DM(I3, 1);
DMPG1 = Access_Common_Memory;
ay1 = 0xFF00;
ar = ay0 AND ay1;
sr = LSHIFT ar BY -8 (HI);
DM(WRITE_DATA_REG_ODD_BYTE) = sr1;
ay1 = 0x00FF;
ar = ay0 AND ay1;
put_cfdata:
DM(WRITE_DATA_REG_EVEN_BYTE) = ar;

RTS;


/*------------------------------------------------*/

Check_CF_RDY_Status:
/* Check for RDY bit = 1 */
/* If set then OK to access registers */
dis int;
DMPG1 = Access_Common_Memory;

RDY_wait_valid:
ar = DM(STATUS_REGISTER);
ar = TSTBIT RDY of ar;
IF EQ JUMP RDY_wait_valid;
RTS;

/*------------------------------------------------*/

Check_CF_Busy:
/* Check for BUSY bit = 1 */
/* If cleared then OK to access registers */
dis int;
DMPG1 = Access_Common_Memory;
ar = DM(STATUS_REGISTER);
ar = TSTBIT BUSY of ar;
IF NE JUMP Check_CF_Busy;
RTS;

/*------------------------------------------------*/

Check_CF_DRQ_Status:
/* Check for DRQ bit = 1 */
/* If set then Data Register R/W ready */
DMPG1 = Access_Common_Memory;

DRQ_wait_valid:
ena int; nop; nop; nop; nop; nop; nop; nop;
dis int;
ar = DM(STATUS_REGISTER);
ar = TSTBIT DRQ of ar;
IF EQ JUMP DRQ_wait_valid;
RTS;

Note: This article provides the detailed implementation of an interface described in "Glue-less, Hot-Swappable CompactFlash™ Storage-Card Interface with the ADSP-2191M Digital Signal Processor". To read this article, click here


top of page

Copyright 1995- Analog Devices, Inc. All rights reserved.