In memory-mapped mode, the required hardware connections between the Mega128 and CF/IDE board are as follows:To use the CF/IDE board to connect IDE hard disks and CF memory cards to your AVR processor, also do the following:
- Connect Mega128 PORTC to CF/IDE ADDR[8-15]
- Connect Mega128 PORTA to CF/IDE DATA[0-7]
- Connect Mega128 /WR signal (PORTG0) to CF/IDE /WR signal (CTRL1 header)
- Connect Mega128 /RD signal (PORTG1) to CF/IDE /RD signal (CTRL1 header)
- Connect Mega128 ALE signal (PORTG2) to CF/IDE ALE signal (CTRL1 header)
- Place jumper on CF/IDE CSEL pins 1,2 (sets ATA device to master if Cable Select)
- Place jumper on CF/IDE CSEL pins 3,4 (sets CF device to master if Cable Select)
- Place jumper on CF/IDE CTRL2 pins 7,9 (sets CF device to ATA/IDE mode)
With the above connections made, both the CF and IDE interfaces will now appear in your Mega128’s memory map. You will need to enable the external memory bus in the processor by setting the SRE bit in MCUCR. Depending on your CPU clock frequency, you may also need to enable some wait-states to keep bus timing within spec for the IDE bus.
Block Size Address Range Active Device 4K 0x0000-0x0FFFATA/IDE Interface I/O Bank 0 (ATA bus CS0 asserted) 4K 0x1000-0x1FFFATA/IDE Interface I/O Bank 0 (ATA bus CS0 asserted) 4K 0x2000-0x2FFFN/A 4K 0x3000-0x3FFFN/A 4K 0x4000-0x4FFFCF Interface I/O Bank 0 (CF CS0 asserted) 4K 0x5000-0x5FFFCF Interface MEM Bank 0 (CF CS0 asserted) 4K 0x6000-0x6FFFCF Interface I/O Bank 1 (CF CS1 asserted) 4K 0x7000-0x7FFFCF Interface MEM Bank 1 (CF CS1 asserted)
Most operations with ATA/IDE hard disks and CF cards are 8-bit, and these can be done as normal 8-bit memory read/writes on the Mega128. However some operations, like IDE data transfer, are 16-bit. The CF/IDE board includes a 8-to-16bit translator to make simulaneous 16-bit access possible with an 8-bit microcontroller. The CF/IDE adapter does this by storing the upper 8-bits of a 16-bit access in a memory-mapped latch. Here's a code example:
unsigned char foo,bar; unsigned short data; bar = *((unsigned char*)0x0004); // simple 8-bit read from IDE Cylinder register *((unsigned char*)0x0004)= foo; // simple 8-bit write to IDE Cylinder register // example 16-bit read from IDE Data register data = *((unsigned char*)0x0000); // First: do 8-bit read to get the low-order byte // The bus translator latches the high-order byte for us data |= *((unsigned char*)0x0800)<<8; // Second: read the high-order byte from the bus translator // example 16-bit write to IDE Data Register *((unsigned char*)0x0800) = data>>8; // First: latch the high-order byte into the bus translator *((unsigned char*)0x0000) = data; // Second: write the low-order byte // The bus translator automatically writes the previously // stored high-order byte at the same time.