// Файл с основными определениями для 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