// Файл с основными определениями для AT45DB321D. // v 1.11 от 20/07/15 // Автор: Сычев А. // используйте следующие макросы перед подключением этого заголовочного файла // AT45DB321D_APILEVEL - для доступа к структурам и типам низокуровневых функций // AT45DB321D_LOWLEVEL - для доступа ко всем низкоуровневым определениям // // например: # файл c API для работы с флешкой использует // только интерфейсы, ему достаточно только AT45DB321D_APILEVEL // # файл, который реализует низкоуровневые команды требует AT45DB321D_LOWLEVEL // # пользовательский файл высокоуровневой программы вообще не требует этих макросов #ifndef AT45DB321D_H #define AT45DB321D_H // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ ВВЕДЕНИЕ №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // Чип состоит из 65 секторов, в т.ч. 2 уникальных и 63 обычных. Первые 2 считаются за 1. // Уникальные сектора - это разбитый на 2 части обычные, он меньше обычного по размеру. // В даташите эти секторы называются sector 0a и sector 0b. Остальные // секторы нумеруются как обычно, 1...63. // // Сектор содержит от 1 до 16 блоков, обычный всегда содержит 16 блоков // Блок содержит всегда 8 страниц по 512+16 байт. // Первые 2 сектора - подсекторы 0го, 0a и 0b - уникальные. Первый (сектор 0a) содержит один блок (8страниц) // Второй уникальный (сектор 0b) - 15 блоков. Остальные сектора (1,3,4...63) - содержат // по 16 блоков // Чип позволяет хранить дополнительные 16 байт на каждые 512 байт в каждой странице // Это используется, например, для хранения контрольных сумм и кодов исправления ошибок. // Эти данные доступны при простом чтении страницы или последовательном чтении. // Однако можно запретить доступ к этим данным: программная эмуляция и аппаратная эмуляция // Программная эмуляция - эмуляция программными средствами API драйвера памяти. Она заключается // в том, что при чтении страницы читаются только первые 512 байт. Внимание! В этом режиме // недоступна команда последовательного чтения! Аппаратная эмуляция - использование // опции power of two чипа памяти, опция включается один раз, и более не выключается. // В этом режиме команда последовательного чтения работает. // Для того, чтобы включить программную эмуляцию 512 байтной страницы // объявите макрос AT45DB321D_EMU512=1 // Для того, чтобы использовать опцию Power of two и навсегда установить // размер страницы 512 байт, объявите макрос AT45DB321D_PRM512 // Используйте только один из макросов! // Чип позволяет прогаммно защищать секторы от стирания/записи. Для этого используются // команды снятия/установки защиты на выбранные секторы. При этом выбор секторов для защиты // осуществляется через специальный регистр защиты, содержимое которого определяет, какие // секторы будут защищены. Сам регистр защиты можно защитить только аппарано (пин WP). // Т.О. защита осуществляется в 2 этапа: изменение регистра защиты (стирание+запись) и // включение защиты. Причем не обязательно в этом порядке: можно не снимая защиты модифицировать // содержимое регистра не снимая защиты. Именно так рекомендуют действовать Atmel. // При стирании регистра защиты все секторы становятся защищены. Количество операций // записи/стирания регистра ограничено числом #define __FLASH_PROTECTREGISTER_WRITECYCLES 10000 /* */ //#define AT45DB321D_EMU512 // включение/выключение сервисных байтов //#define AT45DB321D_PRM512 // запрещение сервисных байтов #include "drivers\flash\config\AT45DB321D_CONF.h" #ifndef FLASH_API_TIMEOUT #define FLASH_API_TIMEOUT _TIME_FLASHAPI_TIMEOUT #endif /* */ // Библиотека позволяет исключить циклы ожидания после // длительных команд, переложив ожидание ПОСЛЕ команды // в ожидание ПЕРЕД командой - активное ожидание освобождения // устройства через сканирования флага BUSY в статусном регистре. // Библиотека в любом случае использует чтение флага перед // каждой низкоуровневой командой, но делает это обычно 1 раз, // возвращая ошибку после неудачи. Используйте макрос AT45DB321D_BKGOPERATIONS=1, // для того, чтобы использовать постоянное сканирование флага // перед командой вместо ожидания в конце команды. Используя данный режим, // будьте внимательны при сохранении данных перед выключением питания. // Библиотека позволяет использовать "умные" задержки после длительных // операций. Это означает, что ожидание после команды представляет собой // периодическое сканирование флага BUSY. Заданная в спецификации задержка // разбивается на квантованные промежутки времени, через которые происходит // опрос занятости устройства. Так предположительно длительная задержка // может быть сокращена при досрочном освобождении устройства. По умолчанию // режим "умных" задержек включен. Для выключения объявите макрос AT45DB321D_DONTUSESMARTDELAY=1 // Режим "умных" задержек используется для обеспечения МИЛЛИСЕКУНДНЫХ задержек более __FLASH_SMART_WAIT_THRESHOLD миллисекунд /* */ //#define AT45DB321D_DONTUSESMARTDELAY 0 // отключение "умной" задержки //#define AT45DB321D_BKGOPERATIONS 0 // отключение задержек операций | ВНИМАНИЕ! Только для ОПЫТНЫХ пользователей (-: !!! /* */ //-------------------------------------------------------------- // Иерархия распределения секторов, блоков и страниц. // Номера блоков - отнисительно сектора // Номера страниц - отнисительно блока //-------------------------------------------------------------- // AT45DB321D // _________ // | // |-[-] Сектор 0a / Уникальный сектор, содержит только 1 блок // | | // | |-[-] Блок 0 // | |___ Страница 0, блок 0 сектора 0 // | . // | . // | . // | |___ Страница 7, блок 0 сектора 0 // | // | // |-[-] Сектор 0b / Уникальный сектор, содержит только 63 блока // | | // | |-[-] Блок 0 // | | |___ Страница 0, блок 0 сектора 1 // | | . // | | |___ Страница 7, блок 0 сектора 1 // | | // | |-[-] Блок 1 // | | |___ Страница 0, блок 1 сектора 1 // | | |___ Страница 1, блок 1 сектора 1 // | | . // | | . // | | . // | | |___ Страница 7, блок 1 сектора 1 // | . // | . // | . // | |-[-] Блок 14 // | | // | |___ Страница 0, блок 62 сектора 1 // | . // | . // | . // | |___ Страница 7, блок 62 сектора 1 // | // | // |-[-] Сектор 1 / Обычный сектор, содержит 64 блока // | | // | |-[-] Блок 0 // | | | // | | |___ Страница 0, блок 0 сектора 2 // | | . // | | . // | | . // | | |___ Страница 7, блок 0 сектора 2 // | | // | |-[-] Блок 1 // | | | // | | |___ Страница 0, блок 1 сектора 2 // | | . // | | . // | | . // | | |___ Страница 7, блок 1 сектора 2 // | | // | |-[+] Блок 2 // | . // | . // | . // | |-[+] Блок 14 // | |-[+] Блок 15 // | // |-[+] Сектор 2 / Обычный сектор, содержит 16 блоков // |-[+] Сектор 3 / Обычный сектор, содержит 16 блоков // . // . // . // |-[+] Сектор 63 / Обычный сектор, содержит 16 блоков // //---------------------------------------------------------------------------------------------------------- // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ Внутренние определения №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__## // ## ## // ## Распределение памяти ## // ## ## // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__## // размер страницы #define __FULL_PAGE_SIZE 528 // размер страницы дополнен 16-ю байтами для служебной информации #define __DATA_PAGE_SIZE 512 // страницы не совсем стандартные - каждая страница имеет 512 байт данных и 16 байт служебной информации // Все эти байты читаются и пишутся обычным образом. Но для замены стандартных решений (вроде AT25XXX), удобнее // эмулировать наличие 512 байт в странице, отбросив 16 служебных. #if defined(AT45DB321D_EMU512) || defined(AT45DB321D_PRM512) #ifdef AT45DB321D_PRM512 #define __PAGE_SIZE __DATA_PAGE_SIZE // размер страницы: для API #else #define __PAGE_SIZE __FULL_PAGE_SIZE // размер страницы: для API #endif #define __PAGE_SIZE_USER __DATA_PAGE_SIZE // размер страницы: для пользователя #else #define __PAGE_SIZE __FULL_PAGE_SIZE // размер страницы: для API #define __PAGE_SIZE_USER __FULL_PAGE_SIZE // размер страницы: для пользователя #endif // размер блока #define __PAGES_PER_BLOCK 8 #define __BLOCK_SIZE ( __PAGES_PER_BLOCK * __PAGE_SIZE ) #define __BLOCK_SIZE_USER ( __PAGES_PER_BLOCK * __PAGE_SIZE_USER ) // Количество секторов, блоков // Сектора разного размера: всего их 65 (1+1+63) // Первый и второй - имеют хитрый размер, остальные - одинаковые, по 16 блоков, т.е. по 128 страниц #define __SECTORS_FULL 65 // полное количество секторов (нулевой состоит из двух) #define __SECTORS_TYPICAL 64 // типовое количество секторов #define __SECTORS __SECTORS_TYPICAL #define __BLOCKS 1024 // полное количество блоков #define __BLOCKS_PER_SECTOR 16 // количество блоков в секторе #define __FULL_PAGES (__BLOCKS * __PAGES_PER_BLOCK) #define __PAGES_PER_SECTOR (__BLOCKS_PER_SECTOR * __PAGES_PER_BLOCK ) // размеры секторов #if defined(AT45DB321D_PRM512) || defined(AT45DB321D_EMU512) #define __SECTOR_STD_SIZE 0x10000 // 64K #define __SECTOR0_A_SIZE 0x1000 // 4K #define __SECTOR0_B_SIZE 0xF000 // 60K #else #define __SECTOR_STD_SIZE 0x10800 // 64K + 2K #define __SECTOR0_A_SIZE 0x1080 // 4K + 128 #define __SECTOR0_B_SIZE 0xF780 // 60K + 1920 #endif #define __SECTOR1_SIZE __SECTOR_STD_SIZE #define __SECTOR2_SIZE __SECTOR_STD_SIZE #define __SECTOR3_SIZE __SECTOR_STD_SIZE #define __SECTOR4_SIZE __SECTOR_STD_SIZE #define __SECTOR5_SIZE __SECTOR_STD_SIZE #define __SECTOR6_SIZE __SECTOR_STD_SIZE #define __SECTOR7_SIZE __SECTOR_STD_SIZE #define __SECTOR8_SIZE __SECTOR_STD_SIZE #define __SECTOR9_SIZE __SECTOR_STD_SIZE #define __SECTOR10_SIZE __SECTOR_STD_SIZE #define __SECTOR11_SIZE __SECTOR_STD_SIZE #define __SECTOR12_SIZE __SECTOR_STD_SIZE #define __SECTOR13_SIZE __SECTOR_STD_SIZE #define __SECTOR14_SIZE __SECTOR_STD_SIZE #define __SECTOR15_SIZE __SECTOR_STD_SIZE #define __SECTOR16_SIZE __SECTOR_STD_SIZE #define __SECTOR17_SIZE __SECTOR_STD_SIZE #define __SECTOR18_SIZE __SECTOR_STD_SIZE #define __SECTOR19_SIZE __SECTOR_STD_SIZE #define __SECTOR20_SIZE __SECTOR_STD_SIZE #define __SECTOR21_SIZE __SECTOR_STD_SIZE #define __SECTOR22_SIZE __SECTOR_STD_SIZE #define __SECTOR23_SIZE __SECTOR_STD_SIZE #define __SECTOR24_SIZE __SECTOR_STD_SIZE #define __SECTOR25_SIZE __SECTOR_STD_SIZE #define __SECTOR26_SIZE __SECTOR_STD_SIZE #define __SECTOR27_SIZE __SECTOR_STD_SIZE #define __SECTOR28_SIZE __SECTOR_STD_SIZE #define __SECTOR29_SIZE __SECTOR_STD_SIZE #define __SECTOR30_SIZE __SECTOR_STD_SIZE #define __SECTOR31_SIZE __SECTOR_STD_SIZE #define __SECTOR32_SIZE __SECTOR_STD_SIZE #define __SECTOR33_SIZE __SECTOR_STD_SIZE #define __SECTOR34_SIZE __SECTOR_STD_SIZE #define __SECTOR35_SIZE __SECTOR_STD_SIZE #define __SECTOR36_SIZE __SECTOR_STD_SIZE #define __SECTOR37_SIZE __SECTOR_STD_SIZE #define __SECTOR38_SIZE __SECTOR_STD_SIZE #define __SECTOR39_SIZE __SECTOR_STD_SIZE #define __SECTOR40_SIZE __SECTOR_STD_SIZE #define __SECTOR41_SIZE __SECTOR_STD_SIZE #define __SECTOR42_SIZE __SECTOR_STD_SIZE #define __SECTOR43_SIZE __SECTOR_STD_SIZE #define __SECTOR44_SIZE __SECTOR_STD_SIZE #define __SECTOR45_SIZE __SECTOR_STD_SIZE #define __SECTOR46_SIZE __SECTOR_STD_SIZE #define __SECTOR47_SIZE __SECTOR_STD_SIZE #define __SECTOR48_SIZE __SECTOR_STD_SIZE #define __SECTOR49_SIZE __SECTOR_STD_SIZE #define __SECTOR50_SIZE __SECTOR_STD_SIZE #define __SECTOR51_SIZE __SECTOR_STD_SIZE #define __SECTOR52_SIZE __SECTOR_STD_SIZE #define __SECTOR53_SIZE __SECTOR_STD_SIZE #define __SECTOR54_SIZE __SECTOR_STD_SIZE #define __SECTOR55_SIZE __SECTOR_STD_SIZE #define __SECTOR56_SIZE __SECTOR_STD_SIZE #define __SECTOR57_SIZE __SECTOR_STD_SIZE #define __SECTOR58_SIZE __SECTOR_STD_SIZE #define __SECTOR59_SIZE __SECTOR_STD_SIZE #define __SECTOR60_SIZE __SECTOR_STD_SIZE #define __SECTOR61_SIZE __SECTOR_STD_SIZE #define __SECTOR62_SIZE __SECTOR_STD_SIZE #define __SECTOR63_SIZE __SECTOR_STD_SIZE #define __FULL_CHIP_SIZE (__BLOCKS * __PAGES_PER_BLOCK * __FULL_PAGE_SIZE) #define __FULL_DATA_SIZE (__BLOCKS * __PAGES_PER_BLOCK * __DATA_PAGE_SIZE) #include "drivers\flash\common\AT45DBXXX_TYP.h" #ifdef AT45DB321D_LOWLEVEL //--------------------------------------------------------------- // Чип имеет 2 встроенных SRAM буфера по 528 байт для проведения // операций чтения/записи и сравнения. Чип позволяет читать // данные последовательно, страницу за страницей (послед. чтение). // Также возможна запись содержимого буфера в память со стиранием, // при этом стирание происходит автоматически. //--------------------------------------------------------------- // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__## // ## ## // ## команды обмена ## // ## ## // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__## // чтение #define _RCMD_ARRYREAD 0xE8 // последовательное чтение #define _LCMD_ARRYREAD 0x03 // последовательное чтение (до 33MHz) #define _HCMD_ARRYREAD 0x0B // последовательное чтение (до 66MHz) #define _RCMD_PAGEREAD 0xD2 // чтение одной страницы #define _RCMD_BUF1READ 0xD4 // чтение содержимого буфера 1 #define _RCMD_BUF2READ 0xD6 // чтение содержимого буфера 2 #define _LCMD_BUF1READ 0xD1 // чтение содержимого буфера 1 (до 33MHz) #define _LCMD_BUF2READ 0xD3 // чтение содержимого буфера 2 (до 33MHz) // запись #define _WCMD_BUF1WRIT 0x84 // Запись в буфер 1 #define _WCMD_BUF2WRIT 0x87 // Запись в буфер 2 #define _WCMD_BUF1PROG 0x83 // Запись содержимого буфера 1 в страницу #define _WCMD_BUF2PROG 0x86 // Запись содержимого буфера 2 в страницу #define _WCMD_BUF1PRGx 0x88 // Запись содержимого буфера 1 в страницу БЕЗ стирания #define _WCMD_BUF2PRGx 0x89 // Запись содержимого буфера 2 в страницу БЕЗ стирания // можно писать в страницу без дополнительных буферных команд, пропуская данные через буфер 1 или 2 #define _WCMD_PGB1WRIT 0x82 // Запись страницы через буфер 1 (Запись в буфер+Стирание страницы+Запись буфера) #define _WCMD_PGB2WRIT 0x85 // Запись страницы через буфер 2 (Запись в буфер+Стирание страницы+Запись буфера) // Стирание: Чип позволяет стирать память по-странично, и по-блочно #define _ECMD_PAGERASE 0x81 // Стирание страницы #define _ECMD_BLKERASE 0x50 // Стирание блока из 8 страниц (удобно использовать вместе с __CMD_PRGxBUF1 и __CMD_PRGxBUF2 ) // по-секторнор #define _ECMD_SCTERASE 0x7C // Стирание сектора 0a,0b,1-63 // или целиком (последовательность 4 команд-байт) #define _ECMD_CHPERAS0 0xC7 // Стрирание чипа, байт №0 #define _ECMD_CHPERAS1 0x94 // Стрирание чипа, байт №1 #define _ECMD_CHPERAS2 0x80 // Стрирание чипа, байт №2 #define _ECMD_CHPERAS3 0x9A // Стрирание чипа, байт №3 #define _ECMD_CHPERASE 0xC794809A // Стрирание чипа (обратный порядок байт) #define _ECMD_CHPERASE_DIRECT 0x9A8094C7 // Стрирание чипа // дополнительные команды // Можно сравнивать фрагменты в буферах со страницами в памяти #define _ACMD_BUF1LOAD 0x53 // Загрузка страницы в буфер 1 (предварительное чтение, используется, например, для сравнения) #define _ACMD_BUF2LOAD 0x55 // Загрузка страницы в буфер 2 (предварительное чтение, используется, например, для сравнения __CMD_BUF1CMPR/__CMD_BUF2CMPR) #define _ACMD_BUF1CMPR 0x60 // Сравнение содержимого буфера 1 со страницей #define _ACMD_BUF2CMPR 0x61 // Сравнение содержимого буфера 2 со страницей // Производитель требует хотябы однажды за каждые 20000 операций записи/стирания страницы // в секторе проводить перезапись всех остальных страниц в секторе. Для этого введена специальная // команда обновления страницы __CMD_PAGEREF1 (__CMD_PAGEREF2), использующая буфер 1 или 2 для // чтения страницы и записи ее на то же место (обновление страницы) /* To preserve data integrity, each page of an Atmel DataFlash sector must be updated/rewritten at least once within every 20,000 cumulative page erase and program operations. */ #define _ACMD_PAGEREF1 0x58 // Обновление страницы через буфер 1 #define _ACMD_PAGEREF2 0x59 // Обновление страницы через буфер 2 // чип поддерживает энергосберегающий режим #define _ACMD_EPWRDOWN 0xB9 // переход в спящий режим #define _ACMD_LPWRDOWN 0xAB // выход их спящего режима #define _ACMD_STATREAD 0xD7 // чтение статусного регистра #define _ACMD_MFIDREAD 0x9F // чтение информации о производителе и ID микросхемы // команды совместимости со старыми чипами #define _OCMD_BUF1READ 0x54 // чтение содержимого буфера 1 (совместимость) #define _OCMD_BUF2READ 0x56 // чтение содержимого буфера 2 (совместимость) #define _OCMD_PAGEREAD 0x52 // чтение одной страницы (совместимость) #define _OCMD_ARRYREAD 0x68 // последовательное чтение (совместимость) #define _OCMD_STATREAD 0x57 // чтение статусного регистра (совместимость) // команды защиты #define _SCMD_4SCTPREN 0x3D2A7FA9 // включить защиту секторов (обратный порядок байт) #define _SCMD_4SCTPRDS 0x3D2A7F9A // выкючить защиту секторов (обратный порядок байт) #define _SCMD_4PRREGER 0x3D2A7FCF // стереть регистр защиты стирания (protect) (обратный порядок байт) #define _SCMD_4PRREGWR 0x3D2A7FFC // Записать регистр защиты стирания (protect) (обратный порядок байт) #define _SCMD_PRTREGRD 0x32 // прочитать регистр защиты стирания (protect) #define _SCMD_4SCTLKDN 0x3D2A7F30 // постоянная блокировка сектора (навсегда) (обратный порядок байт) #define _SCMD_LKDNRGRD 0x35 // прочитать регистр постоянной блокировки #define _SCMD_4SECRGWR 0x9B000000 // запись регистра безопасности (security) (обратный порядок байт) #define _SCMD_4SECRGRD 0x77000000 // чтение регистра безопасности (security) (обратный порядок байт) #define _PCMD_PGSZCNFG 0x3D2A80A6 // перепрограммирование размера страницы на 512 байт (НАВЕСГДА) (обратный порядок байт) #define _SCMD_4SCTPREN_DIRECT 0xA97F2A3D // включить защиту секторов #define _SCMD_4SCTPRDS_DIRECT 0x9A7F2A3D // выкючить защиту секторов #define _SCMD_4PRREGER_DIRECT 0xCF7F2A3D // стереть регистр защиты стирания (protect) #define _SCMD_4PRREGWR_DIRECT 0xFC7F2A3D // Записать регистр защиты стирания (protect) #define _SCMD_4SCTLKDN_DIRECT 0x307F2A3D // постоянная блокировка сектора (навсегда) #define _SCMD_4SECRGWR_DIRECT 0x0000009B // запись регистра безопасности (security) #define _SCMD_4SECRGRD_DIRECT 0x00000077 // чтение регистра безопасности (security) #define _PCMD_PGSZCNFG_DIRECT 0xA6802A3D // перепрограммирование размера страницы на 512 байт (НАВЕСГДА) #endif #if defined(AT45DB321D_APILEVEL) || defined(AT45DB321D_LOWLEVEL) // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__## // ## ## // ## максимальные времена ## // ## ## // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__## // // из колонки MAX таблицы временных характеристик чипа #define _TIME_CSSET_us 1 // время на установление CS в 1 #define _TIME_CSCLR_us 1 // время на установление CS в 0 #define _TIME_CSHLD_us 1 // минимальное время CS в неактивном состоянии м/у командами #define _TIME_EDPDM_us 3 // вход в спящий режим #define _TIME_RDPDM_us 35 // выход из спящего режима #define _TIME_BLDCM_us 300 // загрузка/сравнение буфера #define _TIME_RSTRC_us 1 // время восстановления после сброса #define _TIME_RSTWD_us 10 // время удержания сигнала сброса #define _TIME_STRUP_us 100 // время готовности после подачи питания (чип все еще не готов записывать данные) #define _TIME_PGPRG_ms 15/*6*/ // программирование страницы #define _TIME_START_ms 20 // ожидание запуска чипа до полной готовности #define _TIME_COOLDOWN_ms 20 // ожидание "остывания" чипа после выключения питания #define _TIME_PGERS_ms 35 // стирание страницы #define _TIME_PGEPR_ms 40 // стирание страницы + программирование страницы #define _TIME_BKERS_ms 100 // стирание блока #define _TIME_SCERS_ms 5000 // стирание сектора #define _TIME_FLASHAPI_TIMEOUT 10 // стандартный таймаут ожидания API-функций #endif #ifdef AT45DB321D_LOWLEVEL // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__## // ## ## // ## ДРУГИЕ ОПРЕДЕЛЕНИЯ ## // ## ## // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__## /* */ // положение всех используемых гломальных переменных в памяти RAM (секция) //#define FLASH_RAM_PLACE ".at45" // укажите имя секции в кавычках для размещения всех связанных с AT45DB321D данных в ней // ожидание освобождения устройства //#define __FLASH_SMART_WAIT_THRESHOLD 10 // порог в мс, выше которого функция __flash_smart_waitms начнет опрашивать чип на предмет его занятости. #include "drivers\flash\config\AT45DB321D_CONF.h" /* */ // чтение идентификатора #define __FLASH_MANIDEX_OPCODE 0x7F // Contunuation Code при чтении Manufacturer ID #define __FLASH_ATMEL_ID 0x001F // индентификатор фирмы Atmel в поле Manufacturer ID #define __FLASH_INVALID_ID 0x00FF // индентификатор фирмы Atmel в поле Manufacturer ID #define __FLASH_DENSITY_32MB 0x7 // Atmel' Density for 32Mbit: 00111 #define __FLASH_FAMILY_DATAFLASH 0x1 // Atmel' Family for DataFlash: 001 #define __FLASH_STATUS_DENSITY_SIGN 0xD // комбинационный код Density в регистре статуса #endif #if defined(AT45DB321D_APILEVEL) || defined(AT45DB321D_LOWLEVEL) // регистр защиты - байты защиты #define __FLASH_PROTECTION_REG_ENABLE 0xFF // байт регистра защиты - сектор защищен #define __FLASH_PROTECTION_REG_DISABLE 0x00 // байт регистра защиты - сектор НЕ защищен #define __FLASH_PROTECTION_REG_S0_ENABLE 0x3 // поле 0го байта регистра защиты - сектор 0 защищен #define __FLASH_PROTECTION_REG_S0_DISABLE 0x0 // поле 0го байта регистра защиты - сектор 0 НЕ защищен #endif #ifdef AT45DB321D_LOWLEVEL // оперативная память #define __FLASH_LL_COMMAND_MAXSIZE 8 // максимальное количество байт, выделяемое для буфера команд // максимальное количество байт, выделяемое для буфера команд + буфера страницы //#define __FLASH_LL_SVCMEM_SIZE ( __FULL_PAGE_SIZE + __FLASH_LL_COMMAND_MAXSIZE + __SECTORS_TYPICAL ) #define __FLASH_LL_SVCMEM_SIZE ( __FLASH_LL_COMMAND_MAXSIZE + __SECTORS_TYPICAL ) #endif #if defined(AT45DB321D_APILEVEL) || defined(AT45DB321D_LOWLEVEL) // регистр безопасности #define __FLASH_USER_SECURITY_BYTES 64 // количество байт, доступных для программирования в регистре безопасности #define __FLASH_FACT_SECURITY_BYTES 64 // количество байт, запрограммированых в регистре безопасности производиелем #endif // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ структуры и типы №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // #if defined(AT45DB321D_LOWLEVEL) || defined(AT45DB321D_APILEVEL) //------------------------------------------- #pragma pack( push, 1 ) // РЕГИСТР СТАТУСА struct __flash_status_register_st { __FLASH_BYTE bPageSize : 1; // размер страницы 512(1)/528(0) __FLASH_BYTE bProtect : 1; // защита секторов установлена(1)/снята(0) __FLASH_BYTE cDensity : 4; // информация о размере памяти (устарело, см. даташит) __FLASH_BYTE bMismatch : 1; // бит "несовпадение" буфера и страницы (команда сравнения) __FLASH_BYTE bReady : 1; // бит занятости BUSY. занят(0)/свободен(1) }; #pragma pack( pop ) typedef struct __flash_status_register_st __flash_status_t; //------------------------------------------- #pragma pack( push, 1 ) // ИНДЕТИФИКАТОР ПРОИЗВОДИТЕЛЯ struct __flash_deviceid_st { __FLASH_BYTE Density : 5; // вместимость чипа (32Mbit=00111) __FLASH_BYTE Family : 3; // семейство памяти (DataFlash=001) __FLASH_BYTE Revision: 5; // аппаратная версия __FLASH_BYTE CellType: 3; // тип ячейки памяти (SLC(single-level-cell),MLC(multi-level-cell),TLC(tripple-level-cell)); MLC: 000=1bit/cell }; typedef struct __flash_deviceid_st flash_deviceid_t; struct __flash_manufacturerid_st { union { struct { __FLASH_BYTE LowId; // стандартный байт ID (не расширенный) __FLASH_BYTE HighId; // расширенный байт ID (количество 0x7F Continuation Code) (JEDEC JEP-106) }; __FLASH_WORD FullId; // полный ID }; __FLASH_WORD DevId; // код устройства __FLASH_BYTE ExtLen; // длинна расширенной информации __FLASH_BYTE * pExtBf; // указатель на буфер приемник расширенной информации }; struct __flash_manufacturerid_ex_st { union { struct { __FLASH_BYTE LowId; // стандартный байт ID (не расширенный) __FLASH_BYTE HighId; // расширенный байт ID (количество 0x7F Continuation Code) (JEDEC JEP-106) }; __FLASH_WORD FullId; // полный ID }; flash_deviceid_t DevId; // код устройства __FLASH_BYTE ExtLen; // длинна расширенной информации __FLASH_BYTE * pExtBf; // указатель на буфер приемник расширенной информации }; struct __flash_manufacturerid_returnvalue_st { union { struct { __FLASH_BYTE LowId; // стандартный байт ID (не расширенный) __FLASH_BYTE HighId; // расширенный байт ID (количество 0x7F Continuation Code) (JEDEC JEP-106) }; __FLASH_WORD FullId; // полный ID }; flash_deviceid_t DevId; // код устройства }; typedef struct __flash_manufacturerid_returnvalue_st __flash_rvid_t; typedef struct __flash_manufacturerid_st __flash_id_t; typedef struct __flash_manufacturerid_ex_st __flash_exid_t; #pragma pack( pop ) //------------------------------------------- #pragma pack( push, 1 ) // РЕГИСТРЫ ЗАЩИТЫ/БЛОКИРОВКИ СЕКТОРОВ struct __flash_protect_register_sector0_st { __FLASH_BYTE prot_0a : 2; // секция защиты сектора 0A (0-7 pages) __FLASH_BYTE prot_0b : 2; // секция защиты сектора 0B (8-127 pages) __FLASH_BYTE reserved: 4; // не используется }; typedef struct __flash_protect_register_sector0_st __flash_protreg_s0_t; union __flash_protect_register_st { __flash_protreg_s0_t Sector0; // байт защиты сектора 0 ( __FLASH_PROTECTION_REG_S0_ENABLE / __FLASH_PROTECTION_REG_S0_DISABLE ) // байты защиты секторов 0-63 (__FLASH_PROTECTION_REG_ENABLE / __FLASH_PROTECTION_REG_DISABLE ) __FLASH_BYTE Sectors[ __SECTORS_TYPICAL ]; }; typedef union __flash_protect_register_st __flash_protectionregister_t; typedef union __flash_protect_register_st __flash_lockdownregister_t; #pragma pack( pop ) //------------------------------------------- // РЕГИСТРЫ БЕЗОПАСНОСТИ #pragma pack( push, 1 ) struct __flash_usersecurity_register_st { __FLASH_BYTE UserId[ __FLASH_USER_SECURITY_BYTES ]; }; typedef struct __flash_usersecurity_register_st __flash_usersecurityregister_t; struct __flash_factorysecurity_register_st { __FLASH_BYTE UserId[ __FLASH_FACT_SECURITY_BYTES ]; }; typedef struct __flash_factorysecurity_register_st __flash_factorysecurityregister_t; struct __flash_security_register_st { __flash_usersecurityregister_t UserPart; // доступные для однократного программирования байты в регистре безопасности __flash_factorysecurityregister_t FactoryPart; // запрограммированные производителем байты в регистре безопасности }; typedef struct __flash_security_register_st __flash_securityregister_t; #pragma pack( pop ) //------------------------------------------- // РЕГИСТРЫ КОНФИГУРАЦИИ: бит enum __flash_enum_pagesize { __fps_528 = 0, // размер страницы - 528 байт (по умолчанию) __fps_512 = 1, // размер страницы - 512 байт (по умолчанию) __fps_default = __fps_528, // 528 bytes / размер по умолчанию (с завода) __fps_standart = __fps_512, // 512 байт / стандартный размер }; typedef enum __flash_enum_pagesize __flash_pagesize_t; // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ преобразования адресов №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // #if defined(AT45DB321D_LOWLEVEL) || defined(AT45DB321D_APILEVEL) // На размер страницы влияет макрос AT45DB321D_PRM512 // На размер страниые НЕ влияет макрос AT45DB321D_EMU512 //#define __FLASH_ADDRESS2SECTOR(addr) ((addr)/__SECTOR_STD_SIZE) // __FLASH_ADDRESS2SECTOR - преобразует адрес в номер сектора с учетом используемого размера страницы #define __FLASH_ADDRESS2PAGE(addr) ((addr)/__PAGE_SIZE_USER) // __FLASH_ADDRESS2PAGE - преобразует адрес в номер страницы с учетом используемого размера страницы #define __FLASH_PAGE2BLOCK(page) ((page)/__PAGES_PER_BLOCK) // __FLASH_PAGE2BLOCK - преобразует номер страницы в номер блока #define __FLASH_ADDRESSOFFSETPAGE(addr) ((addr)%__PAGE_SIZE_USER) // __FLASH_ADDRESSOFFSETPAGE - получает смещение адреса относительно начала страницы // __FLASH_DATAREMAININGINPAGE - вычисляет, какое количество байт осталось до конца страницы #define __FLASH_DATAREMAININGINPAGE(addr) ( __PAGE_SIZE_USER - __FLASH_ADDRESSOFFSETPAGE( address ) ) #define __FLASH_BASE_DENSITY 0x40000 // 256Kbit #define __FLASH_DENSITY2CAPACITY(density) (__FLASH_BASE_DENSITY << (density) ) // __FLASH_PAGESINRANGE - вычисляет, какое количество страниц находится на промежутке длинной size начиная с адреса address #define __FLASH_PAGESINRANGE(address,size) \ ((address+size)/__PAGE_SIZE_USER - \ (address)/__PAGE_SIZE_USER + \ (((address+size)%__PAGE_SIZE_USER)?1:0)) // // __FLASH_PAGE_ARRAGED_BY_BLOCK - проверяет, выровнена ли страница на размер блока #define __FLASH_PAGE_ARRAGED_BY_BLOCK(pg) (!( pg % AT45FLASH_PAGES_PER_BLOCK )) #endif // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ экпортируемые макросы №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ // // для экспорта функций используйте заголовочный файл "AT45DB321D_LL_func.h" #define AT45FLASH_ATMEL_ID __FLASH_ATMEL_ID // Atmel' Manufacturer ID #define AT45FLASH_DENSITY_32MB __FLASH_DENSITY_32MB // Atmel' Density for 32Mbit #define AT45FLASH_FAMILY_DATAFLASH __FLASH_FAMILY_DATAFLASH // Atmel' Family code #define AT45FLASH_CHIP_SIZE __FULL_CHIP_SIZE // полный объем чипа #define AT45FLASH_DATA_SIZE __FULL_DATA_SIZE // полный объем данных (с учетом или без учета сервисных байтов) #define AT45FLASH_SECTORS __SECTORS // количество секторов #define AT45FLASH_PAGE_SIZE __PAGE_SIZE_USER // размер страницы (зависит от использования сервисных секторов) #define AT45FLASH_BLOCKS __BLOCKS // количество блоков #define AT45FLASH_BLOCK_SIZE __BLOCK_SIZE_USER // размер блока (зависит от использования сервисных секторов) #define AT45FLASH_PAGES __FULL_PAGES // количество страниц #define AT45FLASH_BLOCKS_PER_SECTOR __BLOCKS_PER_SECTOR // количество блоков в секторе #define AT45FLASH_PAGES_PER_SECTOR __PAGES_PER_SECTOR // количество страниц в стандартном секторе #define AT45FLASH_PAGES_PER_BLOCK __PAGES_PER_BLOCK //------------------------------------------- // размеры секторов #define AT45FLASH_SECTOR0_SIZE (__SECTOR0_A_SIZE + __SECTOR0_B_SIZE) #define AT45FLASH_SECTOR0A_SIZE __SECTOR0_A_SIZE #define AT45FLASH_SECTOR0B_SIZE __SECTOR0_B_SIZE #define AT45FLASH_SECTOR1_SIZE __SECTOR1_SIZE #define AT45FLASH_SECTOR2_SIZE __SECTOR2_SIZE #define AT45FLASH_SECTOR3_SIZE __SECTOR3_SIZE #define AT45FLASH_SECTOR4_SIZE __SECTOR4_SIZE #define AT45FLASH_SECTOR5_SIZE __SECTOR5_SIZE #define AT45FLASH_SECTOR6_SIZE __SECTOR6_SIZE #define AT45FLASH_SECTOR7_SIZE __SECTOR7_SIZE #define AT45FLASH_SECTOR8_SIZE __SECTOR8_SIZE #define AT45FLASH_SECTOR9_SIZE __SECTOR9_SIZE #define AT45FLASH_SECTOR10_SIZE __SECTOR10_SIZE #define AT45FLASH_SECTOR11_SIZE __SECTOR11_SIZE #define AT45FLASH_SECTOR12_SIZE __SECTOR12_SIZE #define AT45FLASH_SECTOR13_SIZE __SECTOR13_SIZE #define AT45FLASH_SECTOR14_SIZE __SECTOR14_SIZE #define AT45FLASH_SECTOR15_SIZE __SECTOR15_SIZE #define AT45FLASH_SECTOR16_SIZE __SECTOR16_SIZE #define AT45FLASH_SECTOR17_SIZE __SECTOR17_SIZE #define AT45FLASH_SECTOR18_SIZE __SECTOR18_SIZE #define AT45FLASH_SECTOR19_SIZE __SECTOR19_SIZE #define AT45FLASH_SECTOR20_SIZE __SECTOR20_SIZE #define AT45FLASH_SECTOR21_SIZE __SECTOR21_SIZE #define AT45FLASH_SECTOR22_SIZE __SECTOR22_SIZE #define AT45FLASH_SECTOR23_SIZE __SECTOR23_SIZE #define AT45FLASH_SECTOR24_SIZE __SECTOR24_SIZE #define AT45FLASH_SECTOR25_SIZE __SECTOR25_SIZE #define AT45FLASH_SECTOR26_SIZE __SECTOR26_SIZE #define AT45FLASH_SECTOR27_SIZE __SECTOR27_SIZE #define AT45FLASH_SECTOR28_SIZE __SECTOR28_SIZE #define AT45FLASH_SECTOR29_SIZE __SECTOR29_SIZE #define AT45FLASH_SECTOR30_SIZE __SECTOR30_SIZE #define AT45FLASH_SECTOR31_SIZE __SECTOR31_SIZE #define AT45FLASH_SECTOR32_SIZE __SECTOR32_SIZE #define AT45FLASH_SECTOR33_SIZE __SECTOR33_SIZE #define AT45FLASH_SECTOR34_SIZE __SECTOR34_SIZE #define AT45FLASH_SECTOR35_SIZE __SECTOR35_SIZE #define AT45FLASH_SECTOR36_SIZE __SECTOR36_SIZE #define AT45FLASH_SECTOR37_SIZE __SECTOR37_SIZE #define AT45FLASH_SECTOR38_SIZE __SECTOR38_SIZE #define AT45FLASH_SECTOR39_SIZE __SECTOR39_SIZE #define AT45FLASH_SECTOR40_SIZE __SECTOR40_SIZE #define AT45FLASH_SECTOR41_SIZE __SECTOR41_SIZE #define AT45FLASH_SECTOR42_SIZE __SECTOR42_SIZE #define AT45FLASH_SECTOR43_SIZE __SECTOR43_SIZE #define AT45FLASH_SECTOR44_SIZE __SECTOR44_SIZE #define AT45FLASH_SECTOR45_SIZE __SECTOR45_SIZE #define AT45FLASH_SECTOR46_SIZE __SECTOR46_SIZE #define AT45FLASH_SECTOR47_SIZE __SECTOR47_SIZE #define AT45FLASH_SECTOR48_SIZE __SECTOR48_SIZE #define AT45FLASH_SECTOR49_SIZE __SECTOR49_SIZE #define AT45FLASH_SECTOR50_SIZE __SECTOR50_SIZE #define AT45FLASH_SECTOR51_SIZE __SECTOR51_SIZE #define AT45FLASH_SECTOR52_SIZE __SECTOR52_SIZE #define AT45FLASH_SECTOR53_SIZE __SECTOR53_SIZE #define AT45FLASH_SECTOR54_SIZE __SECTOR54_SIZE #define AT45FLASH_SECTOR55_SIZE __SECTOR55_SIZE #define AT45FLASH_SECTOR56_SIZE __SECTOR56_SIZE #define AT45FLASH_SECTOR57_SIZE __SECTOR57_SIZE #define AT45FLASH_SECTOR58_SIZE __SECTOR58_SIZE #define AT45FLASH_SECTOR59_SIZE __SECTOR59_SIZE #define AT45FLASH_SECTOR60_SIZE __SECTOR60_SIZE #define AT45FLASH_SECTOR61_SIZE __SECTOR61_SIZE #define AT45FLASH_SECTOR62_SIZE __SECTOR62_SIZE #define AT45FLASH_SECTOR63_SIZE __SECTOR63_SIZE // количество циклов перезаписи регистра защиты #define AT45FLASH_PROTREG_WRITECOUNT __FLASH_PROTECTREGISTER_WRITECYCLES // зарезервированная область в начале адресного пространства #define AT45FLASH_MINIMUM_ADDRESS (AT45FLASH_SECTOR0_SIZE) // максимально возможный адрес #define AT45FLASH_MAXIMUM_ADDRESS (AT45FLASH_PAGES * __PAGE_SIZE_USER ) //------------------------------------------- // блок проверки режима эмуляции #ifdef AT45DB321D_EMU512 #ifdef AT45DB321D_PRM512 #undef AT45DB321D_PRM512 #error Внимание! Вы неправильно объявили режим эмуляции страницы 512 байт. #endif #endif #if defined( AT45DB321D_APILEVEL ) #ifdef AT45DB321D_EMU512 #warning Внимание! Выбран режим программной эмуляции страниц 512 байт #endif #ifdef AT45DB321D_PRM512 #warning Внимание! Выбран режим аппаратной эмуляции страниц 512 байт #warning Будьте внимательны! После первого запуска отключить данный режим будет невозможно! #endif #endif #endif #endif