W25Q16JV_GLOB.h 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. // Файл с основными определениями для W25Q16JV.
  2. // v 1.0 от 08/10/20
  3. // Автор: Сычев А.
  4. // используйте следующие макросы перед подключением этого заголовочного файла
  5. // W25Q16JV_APILEVEL - для доступа к структурам и типам низокуровневых функций
  6. // W25Q16JV_LOWLEVEL - для доступа ко всем низкоуровневым определениям
  7. //
  8. // например: # файл c API для работы с флешкой использует
  9. // только интерфейсы, ему достаточно только W25Q16JV_APILEVEL
  10. // # файл, который реализует низкоуровневые команды требует W25Q16JV_LOWLEVEL
  11. // # пользовательский файл высокоуровневой программы вообще не требует этих макросов
  12. #ifndef W25Q16JV_H
  13. #define W25Q16JV_H
  14. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  15. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ ВВЕДЕНИЕ №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  16. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  17. // ВНИМАНИЕ! Здесь и далее вводится замена "Сектор" => "Блок" и наоборот, т.к. данный драйвер основан
  18. // драйвере для чипа AT45, где под сектором понимается самый большой кусок данных, под блоком - кусок
  19. // по меньше, и под страницей - самый меньший. В W25Q под блоком наоборт - самый большой, а под сектором
  20. // самый малый, а страниц нет вообще. Для унификации для W25Q вводим замену понятия Блок - в даташите
  21. // блок это самый большой кусок, а в драйвере - будет самый малый. В даташите - сектор - самый малый
  22. // в данном драйвере - самый большой.
  23. // Такая замена необходима для сохранения внутренней структуры драйвера, функций и макросов.
  24. // W25Q16JV - чип энергонезависимой памяти емкостью 16 мегабит.
  25. // Чип W25Q16JV состоит из 32 секторов, 2 особенных и 30 обычных. Каждый сектор делится на 16 блоков
  26. // размером 4KB. Особенность 2 секторов заключается в том, как работает блочная защита от записи.
  27. // Особенные сектора расположены: один в начале памяти, один в конце.
  28. // Чип обладает 2 программными способами защиты от записи: индивидуальная защита секторов и групповая.
  29. // Индивидуальная защита позволяет заблокировать независимо каждый из 30 обычных секторов и независимо
  30. // каждый блок из 2 особенных секторов. В итоге есть возможность защитить 62 элемента: 30 по секторам
  31. // (все 16 блоков каждого из 30 секторов) и 32 по блокам (16+16 из 2 секторов). Групповая защита
  32. // строится на регистре защиты, где выбирается определенная часть защищаемого пространства от начала
  33. // памяти или от конца памяти. По умолчанию выбрана групповая схема защиты.
  34. //
  35. // Защита от записи:
  36. // -переходит в состояние сбороса если питание снижено до предела
  37. // -разрешает запись только после прошествии защитного итервала после выхода их сброса (либо при подаче питания)
  38. // -программная защита от записи активируется после каждой операции записи/стирания
  39. // -имеется HW и SW защита регистра статуса
  40. // -возможность индивидуальной защиты блока
  41. // -возможность защиты по защелке: защита снимается только после Power-up (пробуждения)
  42. // -возможность одноразового программирования: OTP
  43. //
  44. // Производитель обращает внимание на особенность, связанную с защитой от записи при формировании
  45. // сигнала выбора (CS): управляющий контроллер должен отслеживать уровень питания чипа с тем,
  46. // чтобы выставлять CS только когда уровень питания находится в допустимой зоне после старта,
  47. // а также перед выключнием, чтобы исключить выбор устройства вблизи границы напряжения питания.
  48. //
  49. // Чип позволяет использовать дополнительные линии передачи данных совместно с DO,
  50. // а именно Dual-Output и Quad-Output, для чего использутся отдельные команды.
  51. // Данная библиотека НЕ ПОДДЕРЖИВАЕТ данные режимы.
  52. /* <CONFIG> */
  53. #include <stdint.h>
  54. #include <stddef.h>
  55. #include "drivers\flash\w25q\config\W25Q16JV_CONF.h"
  56. #include "drivers\flash\base\bitbuffer.h"
  57. #ifndef W25QXXX_API_TIMEOUT
  58. #define W25QXXX_API_TIMEOUT _TIME_FLASHAPI_TIMEOUT
  59. #endif
  60. /* </CONFIG> */
  61. // Библиотека позволяет исключить циклы ожидания после
  62. // длительных команд, переложив ожидание ПОСЛЕ команды
  63. // в ожидание ПЕРЕД командой - активное ожидание освобождения
  64. // устройства через сканирования флага BUSY в статусном регистре.
  65. // Библиотека в любом случае использует чтение флага перед
  66. // каждой низкоуровневой командой, но делает это обычно 1 раз,
  67. // возвращая ошибку после неудачи. Используйте макрос W25QXXX_BKGOPERATIONS=1,
  68. // для того, чтобы использовать постоянное сканирование флага
  69. // перед командой вместо ожидания в конце команды. Используя данный режим,
  70. // будьте внимательны при сохранении данных перед выключением питания.
  71. // Библиотека позволяет использовать "умные" задержки после длительных
  72. // операций. Это означает, что ожидание после команды представляет собой
  73. // периодическое сканирование флага BUSY. Заданная в спецификации задержка
  74. // разбивается на квантованные промежутки времени, через которые происходит
  75. // опрос занятости устройства. Так предположительно длительная задержка
  76. // может быть сокращена при досрочном освобождении устройства. По умолчанию
  77. // режим "умных" задержек включен. Для выключения объявите макрос W25Q16JV_DONTUSESMARTDELAY=1
  78. // Режим "умных" задержек используется для обеспечения МИЛЛИСЕКУНДНЫХ задержек более W25QXXX_SMART_WAIT_THRESHOLD миллисекунд
  79. #define __FLASH_PAGE_WRITECYCLES 100000 // main datasheet
  80. #define __FLASH_STATUSREGISTER_WRITECYCLES 100000 // AN0000016 August 7, 2019 Revision 2.0
  81. /* <CONFIG> */
  82. //#define W25Q16JV_DONTUSESMARTDELAY 0 // отключение "умной" задержки
  83. //#define W25QXXX_BKGOPERATIONS 0 // отключение задержек операций | ВНИМАНИЕ! Только для ОПЫТНЫХ пользователей (-: !!!
  84. /* </CONFIG> */
  85. //--------------------------------------------------------------
  86. // Иерархия распределения блоков и секторов
  87. // Номера секторов - отнисительно блока секторов
  88. //--------------------------------------------------------------
  89. // W25Q16JV
  90. // _________
  91. // |
  92. // |-[-] Сектор 0 / Специальный сектор, содержит 16 блоков 4КБ
  93. // | | _____
  94. // | |___ Блок 0 }-----------------------------------------------+ [ 0] | |
  95. // | |___ Блок 1 }-----------------------------------------------+ [ 1] | |
  96. // | . | | I |
  97. // | . . | N |
  98. // | . | | D |
  99. // | |___ Блок 15 }-----------------------------------------------+ [15] | I |
  100. // | | | V |
  101. // | | | I |
  102. // |-[-] Сектор 1 / Обычный Сектор, содержит 16 блоков 4КБ }------+ [16] | D |
  103. // | | | | U |
  104. // | |___ Блок 0 | | A |
  105. // | |___ Блок 1 | | L |
  106. // | . . | |
  107. // | . . | S |
  108. // | . . | E |
  109. // | |___ Блок 15 | | C |
  110. // | | | T |
  111. // | | | O |
  112. // |-[-] Сектор 2 / Обычный Сектор, содержит 16 блоков 4КБ }------+ [17] | R |
  113. // | | | | / |
  114. // | |___ Блок 0 | | B |
  115. // | |___ Блок 1 | | L |
  116. // | . . | O |
  117. // | . . | C |
  118. // | . . | K |
  119. // | |___ Блок 15 | | |
  120. // . . | P |
  121. // . . | R |
  122. // . . | O |
  123. // |-[-] Сектор 30 / Обычный Сектор, содержит 16 блоков 4КБ }------+ [58] | T |
  124. // | | | | E |
  125. // | |___ Блок 0 | | C |
  126. // | |___ Блок 1 | | T |
  127. // | . . | I |
  128. // | . . | O |
  129. // | . . | N |
  130. // | |___ Блок 15 | | |
  131. // | | | R |
  132. // | | | E |
  133. // |-[-] Сектор 31 / Специальный Сектор, содержит 16 блоков 4КБ | | G |
  134. // | | | | I |
  135. // | |___ Блок 0 }-----------------------------------------------+ [59] | S |
  136. // | |___ Блок 1 }-----------------------------------------------+ [60] | T |
  137. // | . . | E |
  138. // | . . | R |
  139. // | . . | |
  140. // | |___ Блок 15 }-----------------------------------------------+ [61] |___|
  141. //
  142. //----------------------------------------------------------------------------------------------------------
  143. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  144. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ Внутренние определения №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  145. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  146. // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__##
  147. // ## ##
  148. // ## Распределение памяти ##
  149. // ## ##
  150. // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__##
  151. // размер страницы
  152. #define __FULL_PAGE_SIZE 4096
  153. #define __PROG_PAGE_SIZE 256 // размер страницы при программировании
  154. // страницы (=сектора) стандартные - каждая страница имеет 4096 байт данных
  155. #define __PAGE_SIZE __FULL_PAGE_SIZE // размер страницы: для API
  156. #define __PAGE_SIZE_USER __PAGE_SIZE // размер страницы: для пользователя
  157. // размер блока
  158. #define __PAGES_PER_BLOCK 1
  159. #define __BLOCK_SIZE ( __PAGES_PER_BLOCK * __PAGE_SIZE )
  160. #define __BLOCK_SIZE_USER ( __PAGES_PER_BLOCK * __PAGE_SIZE_USER )
  161. // Количество секторов, блоков
  162. #define __SECTORS_TYPICAL 30 // количество обычных секторов
  163. #define __SECTORS_SPECIAL 2 // количество особенных секторов
  164. #define __SECTORS_FULL (__SECTORS_TYPICAL + __SECTORS_SPECIAL) // полное количество секторов
  165. #define __SECTORS __SECTORS_FULL
  166. #define __BLOCKS 512 // полное количество блоков
  167. #define __BLOCKS_PER_SECTOR 16 // количество блоков в секторе
  168. #define __FULL_PAGES (__BLOCKS * __PAGES_PER_BLOCK)
  169. #define __PAGES_PER_SECTOR (__BLOCKS_PER_SECTOR * __PAGES_PER_BLOCK )
  170. #define __PROT_SECTOR_FLAGS (__SECTORS_TYPICAL + (__SECTORS_SPECIAL) * (__BLOCKS_PER_SECTOR) )
  171. #define __PROT_SECTOR_TO_ADDRESS(n) W25Q16JV_prot_sector_to_address(n)
  172. #define __SECTOR_TO_PROTSECTOR(n,m) W25Q16JV_sector_to_protsector(n,&m)
  173. // размеры секторов
  174. #define __SECTOR_STD_SIZE 0x10000 // 64K
  175. #define __SECTOR0_SIZE __SECTOR_STD_SIZE
  176. #define __SECTOR1_SIZE __SECTOR_STD_SIZE
  177. #define __SECTOR2_SIZE __SECTOR_STD_SIZE
  178. #define __SECTOR3_SIZE __SECTOR_STD_SIZE
  179. #define __SECTOR4_SIZE __SECTOR_STD_SIZE
  180. #define __SECTOR5_SIZE __SECTOR_STD_SIZE
  181. #define __SECTOR6_SIZE __SECTOR_STD_SIZE
  182. #define __SECTOR7_SIZE __SECTOR_STD_SIZE
  183. #define __SECTOR8_SIZE __SECTOR_STD_SIZE
  184. #define __SECTOR9_SIZE __SECTOR_STD_SIZE
  185. #define __SECTOR10_SIZE __SECTOR_STD_SIZE
  186. #define __SECTOR11_SIZE __SECTOR_STD_SIZE
  187. #define __SECTOR12_SIZE __SECTOR_STD_SIZE
  188. #define __SECTOR13_SIZE __SECTOR_STD_SIZE
  189. #define __SECTOR14_SIZE __SECTOR_STD_SIZE
  190. #define __SECTOR15_SIZE __SECTOR_STD_SIZE
  191. #define __SECTOR16_SIZE __SECTOR_STD_SIZE
  192. #define __SECTOR17_SIZE __SECTOR_STD_SIZE
  193. #define __SECTOR18_SIZE __SECTOR_STD_SIZE
  194. #define __SECTOR19_SIZE __SECTOR_STD_SIZE
  195. #define __SECTOR20_SIZE __SECTOR_STD_SIZE
  196. #define __SECTOR21_SIZE __SECTOR_STD_SIZE
  197. #define __SECTOR22_SIZE __SECTOR_STD_SIZE
  198. #define __SECTOR23_SIZE __SECTOR_STD_SIZE
  199. #define __SECTOR24_SIZE __SECTOR_STD_SIZE
  200. #define __SECTOR25_SIZE __SECTOR_STD_SIZE
  201. #define __SECTOR26_SIZE __SECTOR_STD_SIZE
  202. #define __SECTOR27_SIZE __SECTOR_STD_SIZE
  203. #define __SECTOR28_SIZE __SECTOR_STD_SIZE
  204. #define __SECTOR29_SIZE __SECTOR_STD_SIZE
  205. #define __SECTOR30_SIZE __SECTOR_STD_SIZE
  206. #define __SECTOR31_SIZE __SECTOR_STD_SIZE
  207. #define __FULL_CHIP_SIZE (__BLOCKS * __PAGES_PER_BLOCK * __FULL_PAGE_SIZE)
  208. #define __FULL_DATA_SIZE (__FULL_CHIP_SIZE)
  209. // переводит НОМЕР защищаемого сектора в адрес
  210. // Защищаемый сектор - не всегда сектор 64КБ, для 0 и 31 секторов 64К из них
  211. // выводятся биты защиты для каждого блока 4К
  212. //
  213. // используется для команд индивидуальной защиты секторов/блоков
  214. static inline size_t W25Q16JV_prot_sector_to_address(size_t protsector)
  215. {
  216. size_t w24Address = 0;
  217. if( protsector > 0 && protsector < __PROT_SECTOR_FLAGS )
  218. {
  219. // проверка на первый специальный сектор, состоящий из __BLOCKS_PER_SECTOR
  220. // каждый блок такого сектора представлен отдельным битом защиты
  221. // Это сектор 0
  222. if( protsector < __BLOCKS_PER_SECTOR )
  223. {
  224. // адрес наращивается для каждого блока 4К в секторе 64К
  225. w24Address = (protsector * __BLOCK_SIZE);
  226. }
  227. else
  228. // Это обычные сектора 1..30, каждый сектора представлен одним битом защиты, без разбиения на блоки
  229. if( protsector >= __BLOCKS_PER_SECTOR && protsector < __BLOCKS_PER_SECTOR + __SECTORS_TYPICAL )
  230. {
  231. w24Address = (__SECTOR0_SIZE) + (protsector - __BLOCKS_PER_SECTOR) * (__SECTOR_STD_SIZE);
  232. }
  233. // Это опять особенный, последний, сектор, разделенный на защищаемые блоки
  234. else
  235. {
  236. w24Address = (protsector - __BLOCKS_PER_SECTOR - __SECTORS_TYPICAL) * (__BLOCK_SIZE) + (__SECTOR_STD_SIZE)*(__SECTORS - 1);
  237. }
  238. }
  239. return w24Address;
  240. }
  241. // вычисляет начальный номер protection-sector-block для сектора 64КБ
  242. // используется для команд индивидуальной защиты секторов/блоков
  243. static inline size_t W25Q16JV_sector_to_protsector(size_t nSector, size_t * pCount )
  244. {
  245. size_t nStartProtSector = 0;
  246. if( nSector == 0 )
  247. {
  248. nStartProtSector = 0;
  249. *pCount = __BLOCKS_PER_SECTOR; // количество protsectors в секторе 64КБ = 16 для особенного сектора
  250. }
  251. else if( nSector == __SECTORS - 1 )
  252. {
  253. nStartProtSector = __BLOCKS_PER_SECTOR + __SECTORS_TYPICAL;
  254. *pCount = __BLOCKS_PER_SECTOR; // количество protsectors в секторе 64КБ = 16 для особенного сектора
  255. }
  256. else
  257. {
  258. nStartProtSector = __BLOCKS_PER_SECTOR + nSector - 1;
  259. *pCount = 1; // количество protsectors в секторе 64КБ = 1 для обычного сектора
  260. }
  261. return nStartProtSector; // начальный номер protsector-а для сектора 64КБ
  262. }
  263. #include "drivers\flash\base\flash_api_types.h"
  264. #ifdef W25Q16JV_LOWLEVEL
  265. //---------------------------------------------------------------
  266. // Чип имеет 2 встроенных SRAM буфера по 528 байт для проведения
  267. // операций чтения/записи и сравнения. Чип позволяет читать
  268. // данные последовательно, страницу за страницей (послед. чтение).
  269. // Также возможна запись содержимого буфера в память со стиранием,
  270. // при этом стирание происходит автоматически.
  271. //---------------------------------------------------------------
  272. // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__##
  273. // ## ##
  274. // ## команды обмена ##
  275. // ## ##
  276. // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__##
  277. // чтение
  278. #define _RCMD_ARRYREAD 0x03 // последовательное чтение
  279. #define _LCMD_ARRYREAD 0x03 // последовательное чтение (до 50MHz)
  280. #define _HCMD_ARRYREAD 0x0B // последовательное чтение (до 133MHz)
  281. // запись
  282. #define _WCMD_PGWRIT 0x02 // Запись страницы
  283. // Стирание: Чип позволяет стирать память по-странично, и по-блочно
  284. #define _ECMD_PAGERASE 0x20 // Стирание страницы
  285. #define _ECMD_BLKERASE32 0x52 // Стирание 8 страниц
  286. // по-секторно
  287. #define _ECMD_SCTERASE 0xD8 // Стирание сектора
  288. // или целиком (последовательность 4 команд-байт)
  289. #define _ECMD_CHPERASE 0xC7 // Стрирание чипа
  290. // энергосберегающий режим, сброс
  291. #define _ACMD_EPWRDOWN 0xB9 // переход в спящий режим
  292. #define _ACMD_LPWRDOWN 0xAB // выход их спящего режима
  293. #define _ACMD_ENARESET 0x66 // разрешение сброса чипа
  294. #define _ACMD_DORESET 0x99 // команда сброса чипа (Требуется предварительная 0x66)
  295. // команды чтения/записи "статусных" регистров
  296. #define _ACMD_STATREAD_1 0x05 // чтение статусного регистра 1
  297. #define _ACMD_STATREAD_2 0x35 // чтение статусного регистра 2
  298. #define _ACMD_STATREAD_3 0x15 // чтение статусного регистра 3
  299. #define _ACMD_STATWRIT_1 0x01 // запись статусного регистра 1
  300. #define _ACMD_STATWRIT_2 0x31 // запись статусного регистра 2
  301. #define _ACMD_STATWRIT_3 0x11 // запись статусного регистра 3
  302. // команды идентификации
  303. #define _ACMD_MFIDREAD 0x9F // чтение информации о производителе и ID микросхемы
  304. #define _ACMD_SFDPREAD 0x5A // чтение регистра Serial Flash Discoverable Parameter (Информация о производителе и устройстве)
  305. #define _ACMD_UIDRREAD 0x4B // чтение регистра Unique ID
  306. // команды защиты
  307. #define _SCMD_WRENABLE 0x06 // разрешение записи
  308. #define _SCMD_WRDISABLE 0x04 // разрешение записи
  309. #define _SCMD_WRENVOL 0x50 // разрешение записи (только для статусных регистров, без сохранения)
  310. #define _SCMD_SECRGERS 0x44 // стирание регистра защиты
  311. #define _SCMD_SECRGWRT 0x42 // запись регистра защиты
  312. #define _SCMD_SECRGRD 0x48 // чтение регистра защиты
  313. #define _SCMD_GLBLLK 0x7E // глобальная блокировка блоков
  314. #define _SCMD_GLBLUNLK 0x98 // глобальная разблокировка блоков
  315. #define _SCMD_BLKLKRD 0x3D // чтение регистра индивидуальной блокировки сектора/блока
  316. #define _SCMD_BLKLOCK 0x36 // индивидуальная блокировка сектора/блока
  317. #define _SCMD_BLKULOCK 0x39 // индивидуальная разблокировка сектора/блока
  318. #define _SCMD_ERPGSUSP 0x75 // заморозить процесс стирания/записи
  319. #define _SCMD_ERPGRESM 0x7A // разморозить процесс стирания/записи
  320. #endif
  321. #if defined(W25Q16JV_APILEVEL) || defined(W25Q16JV_LOWLEVEL)
  322. // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__##
  323. // ## ##
  324. // ## максимальные времена ##
  325. // ## ##
  326. // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__##
  327. //
  328. // из колонки MAX таблицы временных характеристик чипа
  329. #define _TIME_CSSET_us 1 // время на установление CS в 1
  330. #define _TIME_CSCLR_us 1 // время на установление CS в 0
  331. #define _TIME_CSHLD_us 1 // минимальное время CS в неактивном состоянии м/у командами
  332. #define _TIME_EDPDM_us 3 // вход в спящий режим
  333. #define _TIME_RDPDM_us 4 // выход из спящего режима
  334. #define _TIME_RSTRC_us 30 // время восстановления после сброса
  335. #define _TIME_RSTWD_us 10 // время удержания сигнала сброса
  336. #define _TIME_STRUP_us 20 // время готовности после подачи питания (но чип все еще не готов записывать данные)
  337. #define _TIME_PGPRG_ms 3 // программирование страницы
  338. #define _TIME_STPRG_ms 15 // программирование статусного регистра
  339. #define _TIME_START_ms 7 // ожидание запуска чипа до полной готовности
  340. #define _TIME_COOLDOWN_ms 20 // ожидание "остывания" чипа после выключения питания
  341. #define _TIME_PGERS_ms 400 // стирание страницы (=блока 4KB)
  342. #define _TIME_BKERS_ms 400 // стирание блока (=страницы 4KB)
  343. #define _TIME_SCERS_ms 2000 // стирание сектора (64KB)
  344. #define _TIME_FLASHAPI_TIMEOUT 10 // стандартный таймаут ожидания API-функций
  345. #endif
  346. #if defined(W25Q16JV_LOWLEVEL) || defined(W25Q16JV_APILEVEL)
  347. // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__##
  348. // ## ##
  349. // ## ДРУГИЕ ОПРЕДЕЛЕНИЯ ##
  350. // ## ##
  351. // ##__##__##__##__##__##__##__##__##__##__##__##__##__##__##__##
  352. /* <CONFIG> */
  353. #include "drivers\flash\w25q\config\W25Q16JV_CONF.h"
  354. /* </CONFIG> */
  355. // чтение идентификатора
  356. #define __FLASH_WINBOND_ID 0xEF // индентификатор фирмы WINBOND в поле Manufacturer ID
  357. #define __FLASH_INVALID_ID 0xFF // неверно прочитанный идентификатор Manufacturer ID
  358. #define __FLASH_DENSITY_16MB 0x15 // идентификатор объема накопителя 16МБит
  359. #define __FLASH_MEMORYID_Q 0x40 // идентификатор типа чипа W25Q16JV-IQ/JQ
  360. #define __FLASH_MEMORYID_M 0x70 // идентификатор типа чипа W25Q16JV-IM*/JM*
  361. #endif
  362. #if defined(W25Q16JV_APILEVEL) || defined(W25Q16JV_LOWLEVEL)
  363. // регистр защиты - байты защиты
  364. #define __FLASH_PROTECTION_REG_ENABLE 0xFF // байт регистра защиты - сектор защищен
  365. #define __FLASH_PROTECTION_REG_DISABLE 0x00 // байт регистра защиты - сектор НЕ защищен
  366. #endif
  367. #ifdef W25Q16JV_LOWLEVEL
  368. // оперативная память
  369. #define __FLASH_LL_COMMAND_MAXSIZE 8 // максимальное количество байт, выделяемое для буфера команд
  370. // максимальное количество байт, выделяемое для буфера команд + буфера страницы
  371. #define __FLASH_LL_SVCMEM_SIZE ( __FLASH_LL_COMMAND_MAXSIZE + __SECTORS_FULL ) // alloc_place содержит protectbuffer[] байт
  372. #endif
  373. #if defined(W25Q16JV_APILEVEL) || defined(W25Q16JV_LOWLEVEL)
  374. // регистр безопасности
  375. #define __FLASH_USER_SECURITY_BYTES 256 // количество байт, доступных для программирования в регистре безопасности
  376. #endif
  377. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  378. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ структуры и типы №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  379. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  380. //
  381. #if defined(W25Q16JV_LOWLEVEL) || defined(W25Q16JV_APILEVEL)
  382. //-------------------------------------------
  383. #pragma pack( push, 1 )
  384. // РЕГИСТРЫ СТАТУСА
  385. union __flash_status_register_st_1 { // [W25Q OK]
  386. struct
  387. {
  388. __FLASH_BYTE bBusy : 1; // BUSY бит занятости BUSY: занят(1)/свободен(0), WIP (Write In Progress)
  389. __FLASH_BYTE bWrEnLatch: 1; // WEL индикатор возможности записи после Write Enable Instruction: (1) разрешена / (0) запрещена
  390. __FLASH_BYTE cBlkProt : 3; // BP индикаторы и установки групповой защиты блоков
  391. __FLASH_BYTE bTopBot : 1; // TB бит переключения групповой защиты с начала (bTopBot=0) или конца (bTopBot=1) памяти
  392. __FLASH_BYTE bSectBlk : 1; // SEC бит переключения групповой защиты на блоки 4КБ (bSectBlk=1) или 64КБ секторы (bSectBlk=0) [sic!]
  393. __FLASH_BYTE bStatProt : 1; // SRP бит аппаратной защиты статусного регистра: (1) - запись возможна если аппаратный сигнал ~WP=0 (asserted), (0) - без защиты
  394. };
  395. __FLASH_BYTE status;
  396. };
  397. union __flash_status_register_st_2 { // [W25Q OK]
  398. struct
  399. {
  400. __FLASH_BYTE bStatLock : 1; // SRL блокировка стаусного регистра: (1) - заблокировать до следующего цикла подачи питания, (0) - нет блокировки
  401. __FLASH_BYTE bQuadEn : 1; // разрешение режима Quad SPI (обмен по 4 линиям IO). (1) - разрешен, (0) - запрещен
  402. __FLASH_BYTE bRes1 : 1; // зарезервировано, RO, =0
  403. __FLASH_BYTE bLockSec1 : 1; // LB1 бит защиты Security Register 1: блокировка записи SR1, OTP, не снимается!
  404. __FLASH_BYTE bLockSec2 : 1; // LB2 бит защиты Security Register 2: блокировка записи SR2, OTP, не снимается!
  405. __FLASH_BYTE bLockSec3 : 1; // LB3 бит защиты Security Register 3: блокировка записи SR3, OTP, не снимается!
  406. __FLASH_BYTE bCmpProt : 1; // CMP бит комплиментарности групповой защиты: позволяет проинвертировать признаки групповой защиты блоков, CMP=0 - нет инверсии
  407. __FLASH_BYTE bSuspended: 1; // SYS индикатор Suspend State, SYS=1 если одна из команд записи/стирания находится на паузе
  408. };
  409. __FLASH_BYTE status;
  410. };
  411. union __flash_status_register_st_3 { // [W25Q OK]
  412. struct
  413. {
  414. __FLASH_BYTE cRes_0 : 2; // зарезервировано, RO, =0
  415. __FLASH_BYTE bWPSel : 1; // WPS выбор схемы защиты от записи, WPS=0 групповая защита {CMP, SEC, TB, BP[2:0]}, WPS=1 индивидуальная защита секторов/блоков
  416. __FLASH_BYTE cRes_1 : 2; // зарезервировано, RO, =0
  417. __FLASH_BYTE cDrvStr : 2; // DRV настройка тока выходного драйвера: 00 = 100%, 11 = 25% (по умолчанию)
  418. __FLASH_BYTE bRes : 1; // зарезервировано, RO, =0
  419. };
  420. __FLASH_BYTE status;
  421. };
  422. #define __FLASH_WPS_GROUP_PROTECT 0 // bWPSel=0, групповая защита секторов
  423. #define __FLASH_WPS_INDIVIDUAL_PROTECT 1 // bWPSel=1, индивидуальная защита секторов
  424. #define __FLASH_DRS_DEFAULT 3 // cDrvStr=11, Driver Strength = 25%
  425. #define __FLASH_SRP_WP_ENABLE 1 // bStatProt=1, разрешение аппаратного ~WP
  426. #define __FLASH_SRP_WP_DISABLE 0 // bStatProt=0, запрещение аппаратного ~WP
  427. #if W25QXXX_HW_WR_PROTECT
  428. #define __FLASH_SRP_WP_DEFAULT __FLASH_SRP_WP_ENABLE
  429. #else
  430. #define __FLASH_SRP_WP_DEFAULT __FLASH_SRP_WP_DISABLE
  431. #endif
  432. #define __FLASH_SRL_LOCKED 1 // bStatLock=1, запись в статусные регистры запрещена по следующего цикла включения питания
  433. #define __FLASH_SRL_UNLOCKED 0 // bStatLock=0, запись в статусные регистры разрешена
  434. #define __FLASH_QUAD_ENABLED 1 // bQuadEn=1, разрешен режим Quad SPI
  435. #define __FLASH_QUAD_DISABLED 0 // bQuadEn=0, запрещен режим Quad SPI
  436. #define __FLASH_SYS_ENABLED 1 // bSuspended=1, задействован режим suspend
  437. #define __FLASH_BP_RESET 0 // cBlkProt=0, все индикаторы групповой защиты сброшены
  438. #define __FLASH_BP_SET 7 // cBlkProt=7, все индикаторы групповой защиты установлены
  439. #define __FLASH_CMP_ENABLE 1 // bCmpProt=1, режим комплиментарной защиты включен
  440. #define __FLASH_CMP_DISABLE 0 // bCmpProt=0, режим комплиментарной защиты выключен
  441. #pragma pack( pop )
  442. typedef union __flash_status_register_st_1 __flash_status1_t;
  443. typedef union __flash_status_register_st_2 __flash_status2_t;
  444. typedef union __flash_status_register_st_3 __flash_status3_t;
  445. //-------------------------------------------
  446. #pragma pack( push, 1 )
  447. // ИНДЕТИФИКАТОР ПРОИЗВОДИТЕЛЯ
  448. struct __flash_deviceid_st // [W25Q OK]
  449. {
  450. __FLASH_BYTE Family; // семейство памяти, в зависимости от модели
  451. __FLASH_BYTE Density : 6; // вместимость чипа, для линейки W25Q: значение [10h ... 20h]
  452. __FLASH_BYTE Reserved: 2; //
  453. };
  454. typedef struct __flash_deviceid_st flash_deviceid_t;
  455. struct __flash_manufacturerid_st // [W25Q OK]
  456. {
  457. union {
  458. struct {
  459. __FLASH_BYTE LowId; // стандартный байт ID (не расширенный)
  460. __FLASH_BYTE Reserved; // зарезервировано, всегда 0.
  461. // Поле использовалось под расширенный байт ID, Continuation Code, JEDEC JEP-106,
  462. // но семейство W25Q не поддерживает подобный формат.
  463. };
  464. __FLASH_WORD FullId; // полный ID
  465. };
  466. __FLASH_WORD DevId; // код устройства [flash_deviceid_t]
  467. // W25Q не поддерживает расширение поля ID в соответствии с JEDEC JEP-106,
  468. // однако поддерживает другой стандарт Serial Flash Discoverable Parameter Structure (JESD216D.01)
  469. // Поля ExtLen и pExtBf будут использованы для выдачи информации о чипе в этом формате
  470. __FLASH_BYTE ExtLen; // длинна расширенной информации
  471. __FLASH_BYTE * pExtBf; // указатель на буфер приемник расширенной информации
  472. };
  473. struct __flash_manufacturerid_ex_st // [W25Q OK]
  474. {
  475. union {
  476. struct {
  477. __FLASH_BYTE LowId; // стандартный байт ID (не расширенный)
  478. __FLASH_BYTE Reserved; // зарезервировано, всегда 0.
  479. // Поле использовалось под расширенный байт ID, Continuation Code, JEDEC JEP-106,
  480. // но семейство W25Q не поддерживает подобный формат.
  481. };
  482. __FLASH_WORD FullId; // полный ID
  483. };
  484. flash_deviceid_t DevId; // код устройства
  485. // W25Q не поддерживает расширение поля ID в соответствии с JEDEC JEP-106,
  486. // однако поддерживает другой стандарт Serial Flash Discoverable Parameter Structure (JESD216D.01)
  487. // Поля ExtLen и pExtBf будут использованы для выдачи информации о чипе в этом формате
  488. __FLASH_BYTE ExtLen; // длинна расширенной информации
  489. __FLASH_BYTE * pExtBf; // указатель на буфер приемник расширенной информации
  490. };
  491. struct __flash_manufacturerid_returnvalue_st // [W25Q OK]
  492. {
  493. union {
  494. struct {
  495. __FLASH_BYTE LowId; // стандартный байт ID (не расширенный)
  496. __FLASH_BYTE HighId; // зарезервировано, всегда 0.
  497. };
  498. __FLASH_WORD FullId; // полный ID
  499. };
  500. flash_deviceid_t DevId; // код устройства
  501. };
  502. typedef struct __flash_manufacturerid_returnvalue_st __flash_rvid_t;
  503. typedef struct __flash_manufacturerid_st __flash_id_t;
  504. typedef struct __flash_manufacturerid_ex_st __flash_exid_t;
  505. #pragma pack( pop )
  506. #pragma pack( push, 1 )
  507. // РЕГИСТРЫ ЗАЩИТЫ/БЛОКИРОВКИ СЕКТОРОВ/БЛОКОВ
  508. struct __flash_protect_register_st // [W25Q OK]
  509. {
  510. // байты защиты секторов 0-62 (__FLASH_PROTECTION_REG_ENABLE / __FLASH_PROTECTION_REG_DISABLE )
  511. __FLASH_BYTE bSectors[ BITBUFFER_SIZE(__PROT_SECTOR_FLAGS) ];
  512. };
  513. typedef struct __flash_protect_register_st __flash_protectionregister_t;
  514. struct __flash_protect_sector_register_st // [W25Q OK]
  515. {
  516. // байты защиты секторов 0-31 (__FLASH_PROTECTION_REG_ENABLE / __FLASH_PROTECTION_REG_DISABLE )
  517. // Группировка по секторам 64К !
  518. __FLASH_BYTE bSectors[ BITBUFFER_SIZE(__SECTORS) ];
  519. };
  520. typedef struct __flash_protect_sector_register_st __flash_sectorprotectionregister_t;
  521. #pragma pack( pop )
  522. #define FLASH_PROTECTION_REGISTER_CHECK(bSectors,n) BITBUFFER_CHECK(bSectors,n)
  523. #define FLASH_PROTECTION_REGISTER_SET( bSectors,n) BITBUFFER_SET( bSectors,n)
  524. #define FLASH_PROTECTION_REGISTER_CLEAR(bSectors,n) BITBUFFER_CLEAR(bSectors,n)
  525. //-------------------------------------------
  526. // РЕГИСТРЫ БЕЗОПАСНОСТИ ПОЛЬЗОВАТЕЛЯ
  527. #pragma pack( push, 1 )
  528. struct __flash_security_register_st // [W25Q OK]
  529. {
  530. __FLASH_BYTE content[ __FLASH_USER_SECURITY_BYTES ]; // доступные для однократного программирования байты в регистре безопасности
  531. };
  532. typedef struct __flash_security_register_st __flash_securityregister_t;
  533. #pragma pack( pop )
  534. //-------------------------------------------
  535. // РЕГИСТРЫ ИДЕНТИФИКАТОРОВ
  536. #pragma pack( push, 1 )
  537. struct __flash_uniqueid_register_st // [W25Q OK]
  538. {
  539. __FLASH_BYTE uid[8]; // 8-байтовый уникальный идентификатор в пределах модели
  540. };
  541. typedef struct __flash_uniqueid_register_st __flash_uniqueidregister_t;
  542. #pragma pack( pop )
  543. //-------------------------------------------
  544. // ВНУТРЕННИЕ СЛУЖЕБНЫЕ СТРУКТУРЫ И ТИПЫ
  545. typedef const __FLASH_BYTE (*__flash_pageprogramptr_t)[ __PROG_PAGE_SIZE ];
  546. typedef enum
  547. {
  548. fibufSectorFlags, // буфер флагов защиты секторов 64К
  549. fibufSectorFlags_2, // буфер флагов защиты секторов 64К (еще один буфер)
  550. fibufProtSectorFlags, // буфер флагов защиты секторов/блоков (protSector)
  551. fibufPageIO, // буфер ввода/вывода страницы
  552. }
  553. __flash_internal_buffer_type_t;
  554. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  555. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ преобразования адресов №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  556. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  557. //
  558. #if defined(W25Q16JV_LOWLEVEL) || defined(W25Q16JV_APILEVEL)
  559. #define __FLASH_ADDRESS2SECTOR(addr) ((addr)/__SECTOR_STD_SIZE) // __FLASH_ADDRESS2SECTOR - преобразует адрес в номер сектора с учетом используемого размера страницы
  560. #define __FLASH_ADDRESS2PAGE(addr) ((addr)/__PAGE_SIZE_USER) // __FLASH_ADDRESS2PAGE - преобразует адрес в номер страницы с учетом используемого размера страницы
  561. #define __FLASH_PAGE2ADDRESS(page) ((page)*__PAGE_SIZE_USER) // __FLASH_PAGE2ADDRESS - преобразует номер страницы в адрес с учетом используемого размера страницы
  562. #define __FLASH_PAGE2BLOCK(page) ((page)/__PAGES_PER_BLOCK) // __FLASH_PAGE2BLOCK - преобразует номер страницы в номер блока
  563. #define __FLASH_PAGE2SECTOR(page) ((page)/__PAGES_PER_SECTOR) // __FLASH_PAGE2SECTOR - преобразует номер страницы в номер сектора
  564. #define __FLASH_ADDRESSOFFSETPAGE(addr) ((addr)%__PAGE_SIZE_USER) // __FLASH_ADDRESSOFFSETPAGE - получает смещение адреса относительно начала страницы
  565. // __FLASH_DATAREMAININGINPAGE - вычисляет, какое количество байт осталось до конца страницы
  566. #define __FLASH_DATAREMAININGINPAGE(addr) ( __PAGE_SIZE_USER - __FLASH_ADDRESSOFFSETPAGE( address ) )
  567. // В линейке чипов Winbind серии W25Q существуют чипы емкостью от 1МБит до 512МБит
  568. // Код емкости: 10h - 512KBit, 11h - 1Mbit, 12h - 2Mbit, ..., 19h - 256MBit, и 20h - 512MBit
  569. // Чип емкостью 512МБит выбивается из общего правила, т.к. имеет код не 1Ah, а 20h.
  570. // __W25Q_density
  571. // Возвращает емкость в Мегабитах
  572. static inline int __W25Q_density(int density)
  573. {
  574. if( 0x11 <= density && density <= 0x19 )
  575. return (1 << ((density & 0xF) - 1));
  576. switch( density )
  577. {
  578. case 0x10: return 0; // 512KBit
  579. case 0x20: return 512; // 512MBit
  580. }
  581. return 0; // undefined
  582. }
  583. #define __FLASH_DENSITY2CAPACITY(density) __W25Q_density(density)
  584. // __FLASH_PAGESINRANGE - вычисляет, какое количество страниц находится на промежутке длинной size начиная с адреса address
  585. #define __FLASH_PAGESINRANGE(address,size) \
  586. ((address+size)/__PAGE_SIZE_USER - \
  587. (address)/__PAGE_SIZE_USER + \
  588. (((address+size)%__PAGE_SIZE_USER)?1:0)) //
  589. // __FLASH_PAGE_ARRAGED_BY_BLOCK - проверяет, выровнена ли страница на размер блока
  590. #define __FLASH_PAGE_ARRAGED_BY_BLOCK(pg) (!( pg % W25QFLASH_PAGES_PER_BLOCK ))
  591. // __FLASH_PAGE_ARRAGED_BY_SECTOR - проверяет, выровнена ли страница на размер сектора
  592. #define __FLASH_PAGE_ARRAGED_BY_SECTOR(pg) (!( pg % W25QFLASH_PAGES_PER_SECTOR ))
  593. #endif
  594. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  595. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ экпортируемые макросы №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  596. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  597. //
  598. // для экспорта функций используйте заголовочный файл "W25Q16JV_LL_func.h"
  599. #define W25QFLASH_WINBOND_ID __FLASH_WINBOND_ID // Winbond' Manufacturer ID
  600. #define W25QFLASH_DENSITY_16MB __FLASH_DENSITY_16MB // Winbond' Density for 16Mbit
  601. #define W25QFLASH_FAMILYDATAFLASHQ __FLASH_MEMORYID_Q // Winbond' Family code
  602. #define W25QFLASH_FAMILYDATAFLASHM __FLASH_MEMORYID_M // Winbond' Family code
  603. #define W25QFLASH_CHIP_SIZE __FULL_CHIP_SIZE // полный объем чипа
  604. #define W25QFLASH_DATA_SIZE __FULL_DATA_SIZE // полный объем данных (с учетом или без учета сервисных байтов)
  605. #define W25QFLASH_SECTORS __SECTORS // количество секторов
  606. #define W25QFLASH_PAGE_SIZE __PAGE_SIZE_USER // размер страницы (зависит от использования сервисных секторов)
  607. #define W25QFLASH_BLOCKS __BLOCKS // количество блоков
  608. #define W25QFLASH_BLOCK_SIZE __BLOCK_SIZE_USER // размер блока (зависит от использования сервисных секторов)
  609. #define W25QFLASH_PAGES __FULL_PAGES // количество страниц
  610. #define W25QFLASH_BLOCKS_PER_SECTOR __BLOCKS_PER_SECTOR // количество блоков в секторе
  611. #define W25QFLASH_PAGES_PER_SECTOR __PAGES_PER_SECTOR // количество страниц в стандартном секторе
  612. #define W25QFLASH_PAGES_PER_BLOCK __PAGES_PER_BLOCK
  613. //-------------------------------------------
  614. // размеры секторов
  615. #define W25QFLASH_SECTOR0_SIZE __SECTOR0_SIZE
  616. #define W25QFLASH_SECTOR1_SIZE __SECTOR1_SIZE
  617. #define W25QFLASH_SECTOR2_SIZE __SECTOR2_SIZE
  618. #define W25QFLASH_SECTOR3_SIZE __SECTOR3_SIZE
  619. #define W25QFLASH_SECTOR4_SIZE __SECTOR4_SIZE
  620. #define W25QFLASH_SECTOR5_SIZE __SECTOR5_SIZE
  621. #define W25QFLASH_SECTOR6_SIZE __SECTOR6_SIZE
  622. #define W25QFLASH_SECTOR7_SIZE __SECTOR7_SIZE
  623. #define W25QFLASH_SECTOR8_SIZE __SECTOR8_SIZE
  624. #define W25QFLASH_SECTOR9_SIZE __SECTOR9_SIZE
  625. #define W25QFLASH_SECTOR10_SIZE __SECTOR10_SIZE
  626. #define W25QFLASH_SECTOR11_SIZE __SECTOR11_SIZE
  627. #define W25QFLASH_SECTOR12_SIZE __SECTOR12_SIZE
  628. #define W25QFLASH_SECTOR13_SIZE __SECTOR13_SIZE
  629. #define W25QFLASH_SECTOR14_SIZE __SECTOR14_SIZE
  630. #define W25QFLASH_SECTOR15_SIZE __SECTOR15_SIZE
  631. #define W25QFLASH_SECTOR16_SIZE __SECTOR16_SIZE
  632. #define W25QFLASH_SECTOR17_SIZE __SECTOR17_SIZE
  633. #define W25QFLASH_SECTOR18_SIZE __SECTOR18_SIZE
  634. #define W25QFLASH_SECTOR19_SIZE __SECTOR19_SIZE
  635. #define W25QFLASH_SECTOR20_SIZE __SECTOR20_SIZE
  636. #define W25QFLASH_SECTOR21_SIZE __SECTOR21_SIZE
  637. #define W25QFLASH_SECTOR22_SIZE __SECTOR22_SIZE
  638. #define W25QFLASH_SECTOR23_SIZE __SECTOR23_SIZE
  639. #define W25QFLASH_SECTOR24_SIZE __SECTOR24_SIZE
  640. #define W25QFLASH_SECTOR25_SIZE __SECTOR25_SIZE
  641. #define W25QFLASH_SECTOR26_SIZE __SECTOR26_SIZE
  642. #define W25QFLASH_SECTOR27_SIZE __SECTOR27_SIZE
  643. #define W25QFLASH_SECTOR28_SIZE __SECTOR28_SIZE
  644. #define W25QFLASH_SECTOR29_SIZE __SECTOR29_SIZE
  645. #define W25QFLASH_SECTOR30_SIZE __SECTOR30_SIZE
  646. #define W25QFLASH_SECTOR31_SIZE __SECTOR31_SIZE
  647. // количество циклов перезаписи регистра статуса
  648. #define W25QFLASH_STATREG_WRITECOUNT __FLASH_STATUSREGISTER_WRITECYCLES
  649. // количество циклов перезаписи страницы 4К
  650. #define W25QFLASH_PAGE_WRITECOUNT __FLASH_PAGE_WRITECYCLES
  651. // зарезервированная область в начале адресного пространства
  652. #define W25QFLASH_MINIMUM_ADDRESS (0x20000) // указано 128K для совместимости с AT45, но если не требуется => указать 0
  653. // максимально возможный адрес
  654. #define W25QFLASH_MAXIMUM_ADDRESS (W25QFLASH_PAGES * __PAGE_SIZE_USER )
  655. //-------------------------------------------
  656. #endif
  657. #endif