#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
// Адреса регистров для программирования A29040B
#define COMMAND_REGISTER 0x5555
#define COMMAND_REGISTER2 0x2AAA
#define DATA_REGISTER 0x0000
// Команды для программирования
#define CMD_UNLOCK1 0xAA
#define CMD_UNLOCK2 0x55
#define CMD_PROGRAM 0xA0
#define CMD_ERASE 0x80
#define CMD_CHIP_ERASE 0x10
#define CMD_SECTOR_ERASE 0x30
#define CMD_RESET 0xF0
// Функция для записи байта в память
void write_byte(uint32_t address, uint8_t data) {
// Разблокировка последовательности
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_UNLOCK1;
*((volatile uint8_t*)COMMAND_REGISTER2) = CMD_UNLOCK2;
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_PROGRAM;
// Запись данных
*((volatile uint8_t*)address) = data;
// Ожидание завершения программирования
while ((*((volatile uint8_t*)address) & 0x80) != (data & 0x80));
}
// Функция стирания сектора
void erase_sector(uint32_t sector_address) {
// Разблокировка последовательности
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_UNLOCK1;
*((volatile uint8_t*)COMMAND_REGISTER2) = CMD_UNLOCK2;
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_ERASE;
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_UNLOCK1;
*((volatile uint8_t*)COMMAND_REGISTER2) = CMD_UNLOCK2;
// Стирание сектора
*((volatile uint8_t*)sector_address) = CMD_SECTOR_ERASE;
// Ожидание завершения стирания
while ((*((volatile uint8_t*)sector_address) & 0x80) != 0x80);
}
// Функция полного стирания чипа
void chip_erase(void) {
// Разблокировка последовательности
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_UNLOCK1;
*((volatile uint8_t*)COMMAND_REGISTER2) = CMD_UNLOCK2;
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_ERASE;
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_UNLOCK1;
*((volatile uint8_t*)COMMAND_REGISTER2) = CMD_UNLOCK2;
// Стирание всего чипа
*((volatile uint8_t*)COMMAND_REGISTER) = CMD_CHIP_ERASE;
// Ожидание завершения стирания
while ((*((volatile uint8_t*)DATA_REGISTER) & 0x80) != 0x80);
}
// Функция чтения байта из памяти
uint8_t read_byte(uint32_t address) {
return *((volatile uint8_t*)address);
}
// Функция сброса в режим чтения
void reset_to_read_mode(void) {
*((volatile uint8_t*)DATA_REGISTER) = CMD_RESET;
}
// Пример использования
int main() {
uint32_t address = 0x1000; // Адрес для записи
uint8_t data_to_write = 0xAB;
uint8_t read_back_data;
printf("Программа для работы с A29040B-70\n");
// Сброс в режим чтения
reset_to_read_mode();
// Чтение исходных данных
printf("Чтение данных по адресу 0x%04X: 0x%02X\n",
address, read_byte(address));
// Стирание сектора (если необходимо)
printf("Стирание сектора...\n");
erase_sector(address & 0xFFF0); // Выравнивание по границе сектора
// Запись данных
printf("Запись данных 0x%02X по адресу 0x%04X...\n",
data_to_write, address);
write_byte(address, data_to_write);
// Чтение для проверки
read_back_data = read_byte(address);
printf("Прочитано обратно: 0x%02X\n", read_back_data);
// Проверка результата
if (read_back_data == data_to_write) {
printf("Запись успешна!\n");
} else {
printf("Ошибка записи!\n");
}
// Возврат в режим чтения
reset_to_read_mode();
return 0;
}
/////////////////////////
AMD/Fujitsu 29-серия (прямые аналоги)
· AM29F010 (128K x 8)
· AM29F040 (512K x 8)
· AM29F080 (1M x 8)
· AM29F016 (2M x 8)
2. SST 39-серия (совместимы по командам)
· SST39SF010 (128K x 8)
· SST39SF020 (256K x 8)
· SST39SF040 (512K x 8)
3. Atmel 29/49-серия
· AT29C010 (128K x 8)
· AT29C020 (256K x 8)
· AT29C040 (512K x 8)
· AT49F001 (128K x 8)
· AT49F002 (256K x 8)
4. Macronix 29-серия
· MX29F001 (128K x 8)
· MX29F002 (256K x 8)
· MX29F004 (512K x 8)
5. Winbond 29/39-серия
· W29EE011 (128K x 8)
· W29C010 (128K x 8)
· W39L010 (128K x 8)