/*
Пример псевдо-подпрограмм для работы с Compact Flash(CF) в True IDE Mode (16 bit Data Bus)
Общение с CF через порты ввода/вывода микроллера
Используемая CF: Nikon EC-8CF 8MB HITACHI
Для большей производительности рекомендуется подключить CF к интерфейсу внешней памяти микроллера
*/
void Address(unsigned char _) //Установка адреса
{
<установка/сброс битов I/O порта, отвечающих за установку адреса регистра ATA(IDE)>
}
void CE1(unsigned char _) //Чипселект ¹1
{
<установка/сброс бита I/O порта, отвечающего за CE1>
}
void CE2(unsigned char _) //Чипселект ¹2
{
<установка/сброс бита I/O порта, отвечающего за CE2>
}
void IORD(unsigned char _) //Строб чтения
{
<установка/сброс бита I/O порта, отвечающего за чтение CF>
}
void IOWR(unsigned char _) //Строб записи
{
<установка/сброс бита I/O порта, отвечающего за запись CF>
}
void OutDataPort(unsigned short int d) //Запись в 16-битный регистр данных ATA(IDE)
{
CE2(1);
CE1(0); //Разрешаем работу с CF
Address(0); //0-й регистр
<Далее пишем в порты данных старший и младший байты d>
<порт вывода Low>=d; //пишем младший байт
<порт вывода High>=(d>>8); //пишем старший байт
IOWR(0); //строб записи в 0 - разрешаем запись
IOWR(1); //строб записи в 1 - запрещаем запись
CE2(1); //Запрещаем работу с CF
CE1(1);
}
unsigned short int InDataPort(void) //Чтение 16-разрядного регистра данных ATA(IDE)
{
unsigned short int r;
CE2(1);
CE1(0); //Разрешаем работу с CF
Address(0); //0-й регистр
<настраиваем порты данных на ввод>
IORD(0); //строб чтения в 0 - разрешаем чтение
<Далее читаем порты данных(младший и старший байты) и формируем значение r>
r=<сформированное значение>
IORD(1); //строб чтения в 1 - запрещаем чтение
<настраиваем порты данных на вывод>
CE2(1); //Запрещаем работу с CF
CE1(1);
return r;
}
void OutPort(unsigned char a,unsigned char d) //Запись данных в регистр ATA(IDE)
{
CE2(1);
CE1(0); //Разрешаем работу с CF
Address(a); //Адрес регистра
<порт вывода>=d; //Данные
IOWR(0); //строб записи в 0 - разрешаем запись
IOWR(1); //строб записи в 1 - запрещаем запись
CE2(1); //Запрещаем работу с CF
CE1(1);
}
unsigned char Status(void) //Возвращает состояние CF
{
unsigned char r;
CE2(0); //Разрешаем работу с CF
CE1(1); //АЛЬТЕРНАТИВНЫЙ РЕГИСТР СТАТУСА ATA(IDE) С обычным ничё не выйдет!
Address(6); //6-й регистр
<настраиваем порт данных на ввод>
IORD(0); //строб чтения в 0 - разрешаем чтение
r=<порт ввода>; //Читаем
IORD(1); //строб чтения в 1 - запрещаем чтение
<настраиваем порт данных на вывод>
CE2(1); //Запрещаем работу с CF
CE1(1);
return r;
}
unsigned char Buffer[512]; //Буфер сектора
void InSector(unsigned long Sector) //Чтение сектора
{
unsigned short int i;
OutPort(6,(Sector>>24)|0xE0); //LBA 24..27 Используем LBA вместо CHS
OutPort(5, Sector>>16); //LBA 16..23
OutPort(4, Sector>> 8); //LBA 8..15
OutPort(3, Sector ); //LBA 0.. 7
OutPort(2,1); //One Sector
OutPort(7,0x20); //Read Sector(s) Command
while(!((Status()>>3)&1)); //Ждём подготовки данных CF
for(i=0;i<512;i+=2) *(unsigned short int*)(Buffer+i)=InDataPort(); //Читаем сектор в буфер
while((Status()>>7)&1); //Ждём освобождения CF
}
void OutSector(unsigned long Sector) //Запись сектора
{
unsigned short int i;
OutPort(6,(Sector>>24)|0xE0); //LBA 24..27 Используем LBA вместо CHS
OutPort(5, Sector>>16); //LBA 16..23
OutPort(4, Sector>> 8); //LBA 8..15
OutPort(3, Sector ); //LBA 0.. 7
OutPort(2,1); //One Sector
OutPort(7,0x30); //Write Sector(s) Command
while(!((Status()>>3)&1)); //Ждём требования данных CF
for(i=0;i<512;i+=2) OutDataPort(*(unsigned short int*)(Buffer+i)); //Пишем сектор из буфера
while((Status()>>7)&1); //Ждём освобождения CF
}
int main(void) //Пример: копируем нулевой сектор в первый
{
<инициализируем I/O порты микроллера, настраиваем их на вывод первоначально>
InSector(0); //Читаем из нулевого сектора в буфер
OutSector(1); //Пишем в первый сектор из буфера
}
Одного только не пойму - нафига столько контактов делать с CF?
Оставили бы один IDE(ATA)-режим и забили на всё остальное!
16-бит данные, 3-бита адрес ну и плюс несколько управляющих...
Даже такая конфигурация отлично вписывается в интерфей внешней памяти. Много контактов не используются - занулены, подтянуты к питанию или вообще висят.
Будет время - обязательно вложу схему подключения...
А я делал эмуль винта на CF для ноута.
CF на 512Мб успешно работает в 486ом ноуте на работе в связке с PTS-DOS 32.
Romanich wrote:Одного только не пойму - нафига столько контактов делать с CF?
Оставили бы один IDE(ATA)-режим и забили на всё остальное!
16-бит данные, 3-бита адрес ну и плюс несколько управляющих...
Даже такая конфигурация отлично вписывается в интерфей внешней памяти. Много контактов не используются - занулены, подтянуты к питанию или вообще висят.
Будет время - обязательно вложу схему подключения...
Эх ты, не шаришь в колбасных обрезках! Это же АТА разъем! Только для носимой аппаратуры. CF - это только накопитель, а вообще там можно подтыкать любые девайсы: сетевушки, накопители и микродрайвы, USB хосты и т.д. Знакомые девайсы для Пальмов? А эти "зануленные" контакты конкретно у CF - старшие адреса, ибо при включении режима True IDE старшие адреса зануляются. Это в доке на CF дано, если у кого нету - могу дать, если тут не выкладывал.
HardWareMan wrote:
Эх ты, не шаришь в колбасных обрезках! Это же АТА разъем!...
Ну это я знал! Просто считаю, что при приведении к стандарту не следует сваливать всё в одну большую свалку! Биты a3..a10 точно нафиг выкинуть можно - всеравно все одновременно не используются