AT45DB321D_LL.c 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935
  1. // Файл с низкоуровневыми коммандами для AT45DB321D.
  2. // v 1.4 от 28/07/15
  3. // Автор: Сычев А.
  4. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  5. // №№№№№№№№№№№№№№№№№№№№№№ НИЗКОУРОВНЕВЫЕ НЕБЕЗОПАСНЫЕ ФУНКЦИИ №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  6. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  7. #define AT45DB321D_LOWLEVEL
  8. #include "drivers\flash\common\AT45DBXXX_TYP.h"
  9. #include "drivers\flash\common\AT45DBXXX_HAL.h" // аппаратная абстрация от SSP
  10. #include "drivers\flash\lowlevel\AT45DB321D_LL.h" // определения для AT45DB321D
  11. #include "drivers\flash\lowlevel\AT45DB321D_LL_func.h" // прототипы LL-функций
  12. // ########################################################################################################
  13. // Глобальные переменные
  14. #pragma pack( push, 1 )
  15. #ifdef FLASH_RAM_PLACE
  16. _PLACEIN( FLASH_RAM_PLACE )
  17. #endif
  18. static union /* __flash_global */
  19. {
  20. __FLASH_BYTE alloc_place[ __FLASH_LL_SVCMEM_SIZE ];
  21. struct /* __flash_var */
  22. {
  23. // __FLASH_BYTE pagebuffer[ __FULL_PAGE_SIZE ]; // НЕ ТРЕБУЕТСЯ! буфер под чтение/запись страниц
  24. union
  25. {
  26. __FLASH_BYTE protectbuffer[ __SECTORS_TYPICAL ]; // буфер под чтение/запись байтов защиты секторов
  27. __flash_protectionregister_t protectionregister;
  28. };
  29. __FLASH_BYTE cmdbuffer [ __FLASH_LL_COMMAND_MAXSIZE ]; // буфер для выполения команд
  30. };
  31. };
  32. #pragma pack( pop )
  33. __flash_protectionregister_t * __flash_internal_getbuffer_protect() { return &protectionregister; }
  34. // ########################################################################################################
  35. // ########################################################################################################
  36. // ########################################################################################################
  37. // ########################################################################################################
  38. // ########################################################################################################
  39. // ########################################################################################################
  40. // служебные функции управления CS
  41. // установка сигнала ChipSelect в активное состояние
  42. static inline void chip_sel_active()
  43. {
  44. __FLASH_HAL_CS_LO();
  45. __FLASH_WAITus(_TIME_CSCLR_us);
  46. }
  47. // установка сигнала ChipSelect в неактивное состояние
  48. static inline void chip_sel_inactive()
  49. {
  50. __FLASH_WAITus(_TIME_CSSET_us);
  51. __FLASH_HAL_CS_HI();
  52. __FLASH_WAITus(_TIME_CSHLD_us); // минимальное время между командами
  53. }
  54. #ifndef __imp_ssp_io_rev
  55. // Функция обращения порядка байтов и передачи по SPI
  56. //
  57. // @count не может быть 0. Функция не проверяет параметр!
  58. static void __int_ssp_io_rev( __FLASH_BYTE * pBuffer, __FLASH_WORD count )
  59. {
  60. // обмениваем половину из count байт, т.к. вторая будет обменяна автоматически
  61. // вычитаем count-- чтобы прерватить count в индекс конеца буфера
  62. __FLASH_DWORD c = (count--) >> 1;
  63. // начианем обмен
  64. for( int i = 0; i < c; ++i )
  65. {
  66. // Обмениваем pBuffer[i] с pBuffer[count-i]
  67. pBuffer[i] ^= pBuffer[count-i];
  68. pBuffer[count-i] ^= pBuffer[i];
  69. pBuffer[i] ^= pBuffer[count-i];
  70. }
  71. // используем штатую функцию передачи байт по SPI
  72. __FLASH_HAL_WR( pBuffer, ++count );
  73. }
  74. #endif
  75. #if AT45DBXXX_NO_MS_DELAYS == 1
  76. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  77. // __int_sys_delayms - служебная функция ожидания в мс, если аналог отсутствует у пользователя.
  78. // Опция AT45DBXXX_NO_MS_DELAYS позволяет заменить задержку в мс на задержку в мкс.
  79. static inline void __int_sys_delayms( __FLASH_WORD timeout )
  80. {
  81. __imp_sys_delayus( timeout * 1000 );
  82. }
  83. #endif
  84. // --------------------------------------------------------------------------------------------------------
  85. // __flash_smart_waitms - комбинированая функция ожидания заданного количества миллисекунд с
  86. // проверкой состояния чипа на предмет того, занят он, или нет. Если не занят,
  87. // функция возвращает управление сразу же. Если занят все указанное время,
  88. // функция возвратит управление через указанный таймаут (не меньший, но, возможно, больший).
  89. //
  90. // * не изменяет содержимое внутренних SRAM буферов
  91. // * использует системные вызовы для определения количества прошедшего времени
  92. // * потоко-небезопасная функция
  93. // * производит опрос чипа командой "Запрос статусного регистра" (Status Register Read)
  94. // * функция использует вызов функций бесконечного чтения статуса
  95. //
  96. static void __flash_hal__part_statusread_stage1( __flash_status_t * pcReadRegister );
  97. static void __flash_hal__part_statusread_stage2( __flash_status_t * pcReadRegister );
  98. static void __flash_hal__part_statusread_stage3( __flash_status_t * pcReadRegister );
  99. //
  100. // * функция возвращает 1, если достоверно известно, что флаг BUSY сброшен (устройство готово), иначе 0 (требуется повторная проверка)
  101. //
  102. int __flash_smart_waitms( __FLASH_WORD wTimems )
  103. {
  104. __flash_status_t r_status; // статус-регистр
  105. __flash_hal__part_statusread_stage1( &r_status ); // начинаем считывать
  106. // -- -- -- -- -- -- для коротких задержек -- -- -- -- -- -- -- -- -- --
  107. #ifdef FLASH_CHECKSTATUS_DENSITYCODE
  108. #if FLASH_CHECKSTATUS_DENSITYCODE == 1
  109. if ( r_status.cDensity == __FLASH_STATUS_DENSITY_SIGN ) // Дополнительная проверка на код Density
  110. #endif
  111. #endif
  112. if ( r_status.bReady ) // сразу проверяем, если устройство свободно, возвращаем управление
  113. {
  114. __flash_hal__part_statusread_stage3( 0 ); // завершаем чтение регистра
  115. return 1;
  116. }
  117. if ( wTimems < __FLASH_SMART_WAIT_THRESHOLD ) // для малых времен ожидания накладно опрашивать чип постоянно
  118. {
  119. __FLASH_WAITms(wTimems); // выжидаем указанное время
  120. __flash_hal__part_statusread_stage3( &r_status ); // проверяем регистр
  121. #ifdef FLASH_CHECKSTATUS_DENSITYCODE
  122. #if FLASH_CHECKSTATUS_DENSITYCODE == 1
  123. if ( r_status.cDensity == __FLASH_STATUS_DENSITY_SIGN ) // Дополнительная проверка на код Density
  124. #endif
  125. #endif
  126. if ( r_status.bReady ) // если свободно - вернем 1
  127. return 1;
  128. return 0; // если занято - вернем 0
  129. }
  130. // -- -- -- -- -- -- для длинных задержек -- -- -- -- -- -- -- -- -- --
  131. __FLASH_DWORD dwStartCounter = __FLASH_SMART_GETTIMER(); // получаем отметку времени
  132. for(/*|*/ __FLASH_DWORD dwDeltaCounter = 0; // счетчик задержки
  133. /*|*/ dwDeltaCounter < wTimems; // проверяем, задержались ли мы на указанное время или еще нет
  134. /*|*/ dwDeltaCounter = ( __FLASH_SMART_GETTIMER() - dwStartCounter ) ) // обновляем счетчик задержки
  135. {
  136. __flash_hal__part_statusread_stage2( &r_status ); // читаем статус
  137. #ifdef FLASH_CHECKSTATUS_DENSITYCODE
  138. #if FLASH_CHECKSTATUS_DENSITYCODE == 1
  139. if ( r_status.cDensity == __FLASH_STATUS_DENSITY_SIGN ) // Дополнительная проверка на код Density
  140. #endif
  141. #endif
  142. if ( r_status.bReady ) // проверяем, не освободился ли чип?
  143. {
  144. __flash_hal__part_statusread_stage3( 0 ); // да, освободился, завершаем чтение
  145. return 1; // возвращаем 1 (освободился)
  146. }
  147. __FLASH_WAITms(1); // выжидаем квант времени
  148. }
  149. __flash_hal__part_statusread_stage3( &r_status ); // время вышло, завершаем чтение
  150. if ( r_status.bReady ) // последний раз проверяем статус
  151. return 1; // свободен!
  152. return 0; // чип до сих пор занят
  153. }
  154. // ########################################################################################################
  155. // --------------------------------------------------------------------------------------------------------
  156. // __flash_hal__part_statusread - группа скрытых низкоуровневых функций, позволяющая осуществлять постоянное сканирование регистра
  157. // статуса. Чип предоставляет возможность считывать регистр статуса без отправки команды на чтение при повторном чтении,
  158. // до установки CS в неактивное положение. Т.О возможно передать команду один раз, затем читать статус бесконечно.
  159. // Функции должны вызываться в порядке нумерации, при этом стадия 2 может быть пропущена. Функии проверяют параметр
  160. // pcReadRegister на NULL, если он отличен от NULL, считывают в него содержмое регистра, иначе ничего не считывают.
  161. // Пример ожидания завершения операции стирания:
  162. // [code]
  163. //
  164. // __flash_status_t status; // статус-регистр
  165. //
  166. // __flash_hal_pageerase( 0 ); // стираем 0 страницу
  167. // __flash_hal__part_statusread_stage1( &status ); // иницируем чтение статуса
  168. //
  169. // while( !status.bReady )
  170. // __flash_hal__part_statusread_stage2( &status ); // повторяем чтение статуса
  171. //
  172. // __flash_hal__part_statusread_stage3( 0 ); // завершаем чтение статуса
  173. //
  174. // [/code]
  175. // __flash_hal__part_statusread_stage1 - 1 стадия (начальная) команды бесконечного чтения статуса занятости
  176. // __flash_hal__part_statusread_stage2 - 2 стадия (промежуточная) команды бесконечного чтения статуса занятости
  177. // __flash_hal__part_statusread_stage3 - 3 стадия (заключительная) команды бесконечного чтения статуса занятости
  178. //
  179. // * потоко-небезопасная функция
  180. // * НЕ задерживает выполнение: требуется внешний цикл для организации сканирования
  181. static void __flash_hal__part_statusread_stage1( __flash_status_t * pcReadRegister )
  182. {
  183. chip_sel_active();
  184. ( (__flash_packet_statusread_t*) cmdbuffer )->opcode = _ACMD_STATREAD;
  185. // отправляем команду
  186. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_statusread_t) );
  187. if( pcReadRegister )
  188. // читаем регистр
  189. __FLASH_HAL_RD( pcReadRegister, sizeof(__flash_status_t) );
  190. }
  191. //----- ------- ------ ------ ------ ------- ------
  192. static void __flash_hal__part_statusread_stage2( __flash_status_t * pcReadRegister )
  193. {
  194. if( pcReadRegister )
  195. // читаем регистр
  196. __FLASH_HAL_RD( pcReadRegister, sizeof(__flash_status_t) );
  197. }
  198. //----- ------- ------ ------ ------ ------- ------
  199. static void __flash_hal__part_statusread_stage3( __flash_status_t * pcReadRegister )
  200. {
  201. if( pcReadRegister )
  202. // читаем регистр
  203. __FLASH_HAL_RD( pcReadRegister, sizeof(__flash_status_t) );
  204. chip_sel_inactive();
  205. }
  206. // --------------------------------------------------------------------------------------------------------
  207. // ########################################################################################################
  208. // __flash_hal__getpagesize - получение размера страницы 512/528 байт
  209. //
  210. __flash_pagesize_t __flash_hal__getpagesize( )
  211. {
  212. __flash_status_t status;
  213. __flash_hal__statusread( &status );
  214. if( status.bPageSize == __fps_512 )
  215. return __fps_512;
  216. return __fps_528;
  217. }
  218. // --------------------------------------------------------------------------------------------------------
  219. // ########################################################################################################
  220. // __flash_hal__getreadyfast - проверка занятости без ожидания
  221. //
  222. // # Возвращаемое значение: FLERR_SUCCESS если свободен, иначе FLERR_TIMEOUT
  223. flash_err_t __flash_hal__getreadyfast( )
  224. {
  225. __flash_status_t status;
  226. __flash_hal__statusread( &status );
  227. if( status.bReady )
  228. return FLERR_SUCCESS;
  229. return FLERR_TIMEOUT;
  230. }
  231. // --------------------------------------------------------------------------------------------------------
  232. // ########################################################################################################
  233. // __flash_hal__getcompareresult - проверка результата сравнения (бит COMP / bMismatch)
  234. //
  235. // # Возвращаемое значение: FLERR_SUCCESS если совпадает, иначе FLERR_VERIFY_ERROR
  236. flash_err_t __flash_hal__getcompareresult( )
  237. {
  238. __flash_status_t status;
  239. __flash_hal__statusread( &status );
  240. if( status.bMismatch )
  241. return FLERR_VERIFY_ERROR;
  242. return FLERR_SUCCESS;
  243. }
  244. // --------------------------------------------------------------------------------------------------------
  245. // ########################################################################################################
  246. // __flash_hal__getprotectstate - получение состояния общего бита защиты
  247. //
  248. // # Возвращаемое значение - FLERR_PROTECT_ENABLED, если бит защиты установлен, иначе FLERR_PROTECT_DISABLED
  249. flash_err_t __flash_hal__getprotectstate( )
  250. {
  251. __flash_status_t status;
  252. __flash_hal__statusread( &status );
  253. if( status.bProtect )
  254. return FLERR_PROTECT_ENABLED;
  255. return FLERR_PROTECT_DISABLED;
  256. }
  257. // --------------------------------------------------------------------------------------------------------
  258. // ########################################################################################################
  259. // __flash_hal__detect - Низкоуровневое определение наличия чипа (доступности)
  260. // Используется во время первичной инициализации в flash_initialize().
  261. flash_err_t __flash_hal__detect()
  262. {
  263. // сначала пытаемся прочитать идентификатор:
  264. // чтение регистра информации
  265. __FLASH_DWORD flashID = __flash_hal__manufactureridread( 0 );
  266. // определяем наличие флешки по идентификатору
  267. if( ((__flash_rvid_t*) &flashID)->FullId == __FLASH_INVALID_ID )
  268. {
  269. // похоже, что чипа нет, обнаружить не удалось
  270. return FLERR_LL_INITFAIL_NOTFOUND;
  271. }
  272. __flash_securityregister_t securityRegister;
  273. if( !__flash_hal__securityregister_validate( &securityRegister ) )
  274. {
  275. // похоже, что чипа нет, обнаружить не удалось
  276. return FLERR_LL_INITFAIL_NOTFOUND;
  277. }
  278. // еще не все, нужно убедиться, что устройство отвечает:
  279. // читаем статус
  280. if( ! __flash_smart_waitms( _TIME_FLASHAPI_TIMEOUT ) )
  281. {
  282. // либо статус не читается, либо устройство занято.
  283. // т.к. функция предназначена для использования во время инициализации,
  284. // предполагается, что чип должен быть свободен.
  285. // Поэтому возвращаем ошибку
  286. return FLERR_UNEXPECTED_BUSY;
  287. }
  288. return FLERR_SUCCESS;
  289. }
  290. // --------------------------------------------------------------------------------------------------------
  291. // --------------------------------------------------------------------------------------------------------
  292. // ########################################################################################################
  293. // __flash_hal__finalize_prepare - Низкоуровневая функция для подготовки флешпамяти к деинициализации драйвера
  294. // Выполняет действия, направленные на завершение работы с флешпамятью и подготовки ее к выключению
  295. // Вызывается в момент окончательной остановки работы с флешпамятью
  296. flash_err_t __flash_hal__finalize_prepare()
  297. {
  298. // Сначала требуется проверить режим защиты записи:
  299. // если разрешено управление аппаратным сигналом защиты записи
  300. #if AT45DB321D_HW_WR_PROTECT
  301. // если аппаратная защита записи отключена в настройках
  302. #if AT45DB321D_HW_WR_PROTECT_KEEPUNPROTECTED == 1
  303. // требуется установить аппаратную защиту записи после деинициализации драйвера
  304. __imp_flash_hwwrprotect_assert();
  305. #endif
  306. #endif
  307. // Потом проверяем статус готовности
  308. if( ! (__flash_smart_waitms( _TIME_FLASHAPI_TIMEOUT ) ) )
  309. {
  310. // устройство занято.
  311. return FLERR_UNEXPECTED_BUSY;
  312. }
  313. return FLERR_SUCCESS;
  314. }
  315. // --------------------------------------------------------------------------------------------------------
  316. void __flash_hal__use512page();
  317. // --------------------------------------------------------------------------------------------------------
  318. // ########################################################################################################
  319. // __flash_hal__initialize - Низкоуровневая инициализация драйвера флешпамяти
  320. //
  321. // * определение наличия подключенной микросхемы
  322. // * чтение идентификатора и определение производителя
  323. // * контроль правильности:
  324. // - идентификатора производителя
  325. // - типа устройства, семейства (DevId)
  326. // - размера чипа
  327. // * установка и проверка размера страницы
  328. //
  329. // # Возвращаемое значние - код выполнения
  330. flash_err_t __flash_hal__initialize()
  331. {
  332. // если разрешено управление питанием
  333. #if AT45DB321D_POWER_MANAGEMENT
  334. // подать питание на микросхему
  335. __flash_hal__power_on();
  336. __FLASH_WAITus( _TIME_STRUP_us );
  337. #endif
  338. // если разрешено управление питанием
  339. #if AT45DB321D_RESET_MANAGEMENT
  340. // снять сигнлал сброса с чипа
  341. __flash_hal__reset_release();
  342. __FLASH_WAITus( _TIME_RSTRC_us );
  343. #endif
  344. // пробуждаем чип, если тот находится в режиме сна
  345. // иначе он не будет воспринимать команды.
  346. // Неизвестно, был ли чип в режиме гибернации, но это не важно
  347. __flash_hal__wakeup();
  348. // предварительный таймаут запуска - ждем максимальное время до готовности записи во флеш
  349. __FLASH_WAITms( _TIME_START_ms );
  350. // пробуем "грязное" чтение идентификатора.
  351. // Результат чтения не сохраняется, требуется обнаружить
  352. // лишь присуствие на шине и определить готовность
  353. // Поэтому как остуствие на шине, так и занятость чипа расценивается
  354. // как ошибка.
  355. flash_err_t dirty_status = __flash_hal__detect();
  356. if( FLASH_ERROR(dirty_status) )
  357. {
  358. // если разрешено управление сигналом сброса
  359. #if AT45DB321D_RESET_MANAGEMENT
  360. // Формируем импульс сброса:
  361. __flash_hal__reset_pulse();
  362. #else
  363. // управление сигналом сброса недоступно
  364. // а управление питанием доступно?
  365. #if AT45DB321D_RESET_MANAGEMENT
  366. // Формируем импульс подачи питания
  367. __flash_hal__power_pulse( _TIME_COOLDOWN_ms, _TIME_START_ms );
  368. #else
  369. // Проверка доступности вернула ошибку.
  370. // Управление питанием и сигналом сброса недоступно
  371. // Возвращаем ошибку
  372. return dirty_status;
  373. #endif
  374. #endif
  375. }
  376. // чтение регистра информации
  377. __FLASH_DWORD flashID = __flash_hal__manufactureridread( 0 );
  378. // определяем наличие флешки по идентификатору
  379. if( ((__flash_rvid_t*) &flashID)->FullId == __FLASH_INVALID_ID )
  380. {
  381. return FLERR_LL_INITFAIL_NOTFOUND;
  382. }
  383. // проверяем ID производителя
  384. #ifdef FLASH_DESIRED_ID
  385. if( ((__flash_rvid_t*) &flashID)->LowId != FLASH_DESIRED_ID )
  386. {
  387. return FLERR_LL_INITFAIL_WRONGID;
  388. }
  389. #endif
  390. // проверяем вместимость чипа
  391. #ifdef FLASH_DESIRED_DENSITY
  392. if( ((__flash_rvid_t*) &flashID)->DevId.Density != FLASH_DESIRED_DENSITY )
  393. {
  394. return FLERR_LL_INITFAIL_WRONGDENSITY;
  395. }
  396. #endif
  397. // проверяем семейство чипа
  398. #ifdef FLERR_LL_INITFAIL_WRONGFAMILY
  399. if( ((__flash_rvid_t*) &flashID)->DevId.Family != FLASH_DESIRED_FAMILY )
  400. {
  401. return FLERR_LL_INITFAIL_WRONGFAMILY;
  402. }
  403. #endif
  404. // если разрешено управление аппаратным сигналом защиты записи
  405. #if AT45DB321D_HW_WR_PROTECT
  406. // если аппаратная защита записи отключена в настройках
  407. #if AT45DB321D_HW_WR_PROTECT_KEEPUNPROTECTED == 1
  408. // требуется снять аппаратную защиту записи на всё время работы драйвера
  409. __imp_flash_hwwrprotect_release();
  410. #endif
  411. #endif
  412. // определить размер страницы: если выбран AT45DB321D_EMU512, а во флешке AT45DB321D_PRM512 - лочимся
  413. // установить размер страницы если выбран AT45DB321D_PRM512
  414. #ifdef AT45DB321D_PRM512
  415. // выбран режим страницы 512.
  416. // перепрограммируем чип на страницы по 512 байт.
  417. // операция не отменяемая, чип программируется один раз.
  418. // проверяем текущий размер страницы.
  419. if( __fps_512 != __flash_hal__getpagesize();
  420. {
  421. // если 528 - перепрограммируем
  422. __flash_hal__use512page();
  423. #if AT45DB321D_BKGOPERATIONS
  424. __FLASH_SMART_WAITms(_TIME_PGPRG_ms);
  425. #endif
  426. // для изменения размера страницы по документации требуется
  427. // отключить питание чипа и подать снова.
  428. #if AT45DB321D_POWER_MANAGEMENT
  429. // если доступно управление питанием, используем его
  430. __flash_hal__power_pulse( _TIME_COOLDOWN_ms, _TIME_START_ms );
  431. #else
  432. // если управление питанием недоступно, используем callback-процедуру пользователя
  433. // функция вызывается для отключения питания чипа в случае если программа
  434. // обнаруживает, что установлен режим не 512 байт. Сначала функция __flash_hal__use512page
  435. // переключает размер страницы, затем вызывает эту функцию.
  436. __imp_flash_powercycle();
  437. // ожидание готовности запуска
  438. __FLASH_WAITms( _TIME_START_ms );
  439. #endif
  440. }
  441. // # для применения нового размера требуется ОТКЛЮЧЕНИЕ ПИТАНИЯ!
  442. // проверяем текущий размер страницы.
  443. if( __fps_512 != __flash_hal__getpagesize();
  444. {
  445. // Ошибку выдаем: просили установить 512 байт, но не сработало.
  446. return FLERR_LL_INITFAIL_PAGESIZE;
  447. }
  448. #else
  449. #ifdef AT45DB321D_EMU512
  450. // выбран режим ЭМУЛЯЦИИ страниц по 512 байт
  451. // Если в чипе прошит размер 512 байт, то это уже не эмуляция.
  452. if( __fps_512 == __flash_hal__getpagesize() )
  453. {
  454. // Но ошибку не выдаем, т.к. все должно работать.
  455. }
  456. #else
  457. // выбран обычный режим без эмуляции размера страницы 512 байт.
  458. // предполагается использование странцы 528 байт.
  459. if( __fps_512 == __flash_hal__getpagesize() )
  460. {
  461. // в чипе прошит размер 512 - выдем ошибку, т.к. невозможно перенастроить чип
  462. return FLERR_LL_INITFAIL_PAGESIZE;
  463. }
  464. #endif
  465. #endif
  466. return FLERR_SUCCESS;
  467. }
  468. // ########################################################################################################
  469. // ########################################################################################################
  470. // ########################################################################################################
  471. // ########################################################################################################
  472. // ########################################################################################################
  473. // ########################################################################################################
  474. // --------------------------------------------------------------------------------------------------------
  475. // __flash_hal__statusread - чтение регистра статуса
  476. //
  477. // * не проверяет правильность переданных параметров
  478. // * потоко-небезопасная функция
  479. // * НЕ задерживает выполнение
  480. void __flash_hal__statusread( __flash_status_t * pcReadRegister // буфер для чтения статус-регистра
  481. )
  482. {
  483. chip_sel_active();
  484. ( (__flash_packet_statusread_t*) cmdbuffer )->opcode = _ACMD_STATREAD;
  485. // отправляем команду
  486. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_statusread_t) );
  487. // читаем регистр
  488. __FLASH_HAL_RD( pcReadRegister, sizeof(__flash_status_t) );
  489. chip_sel_inactive();
  490. }
  491. // --------------------------------------------------------------------------------------------------------
  492. // --------------------------------------------------------------------------------------------------------
  493. // __flash_hal__page_read - чтение одной страницы
  494. //
  495. // * не изменяет содержимое внутренних SRAM буферов
  496. // * не проверяет правильность переданных параметров
  497. // * потоко-небезопасная функция
  498. //
  499. void __flash_hal__page_read( __FLASH_WORD wPageNum, // номер страницы для чтения
  500. __FLASH_WORD wPageOfs, // адрес начала чтения в странице
  501. __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
  502. __FLASH_WORD wCntToRead ) // количество данных на чтение
  503. {
  504. chip_sel_active();
  505. ( (__flash_packet_pageread_t*) cmdbuffer )->opcode = _RCMD_PAGEREAD;
  506. ( (__flash_packet_pageread_t*) cmdbuffer )->page = wPageNum;
  507. ( (__flash_packet_pageread_t*) cmdbuffer )->offset = wPageOfs;
  508. ( (__flash_packet_pageread_t*) cmdbuffer )->__reserved = 0;
  509. ( (__flash_packet_pageread_t*) cmdbuffer )->__reserved2 = 0;
  510. // отправляем команду
  511. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pageread_t) );
  512. // читаем данные
  513. __FLASH_HAL_RD( pDataRead, wCntToRead );
  514. chip_sel_inactive();
  515. }
  516. // --------------------------------------------------------------------------------------------------------
  517. #ifndef AT45DB321D_EMU512
  518. // --------------------------------------------------------------------------------------------------------
  519. // __flash_hal__array_read - последовательное чтение (массив)
  520. //
  521. // * не изменяет содержимое внутренних SRAM буферов
  522. // * не проверяет правильность переданных параметров
  523. // * потоко-небезопасная функция
  524. // * недоступна в режиме программной эмуляции 512-байтных страниц (AT45DB321D_EMU512)
  525. void __flash_hal__array_read ( __FLASH_WORD wPageNum, // номер начальной страницы для чтения
  526. __FLASH_WORD wPageOfs, // адрес начала чтения в начальной странице
  527. __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
  528. __FLASH_WORD wCntToRead ) // количество данных на чтение
  529. {
  530. chip_sel_active();
  531. ( (__flash_packet_arrayread_t*) cmdbuffer )->opcode = _RCMD_ARRYREAD;
  532. ( (__flash_packet_arrayread_t*) cmdbuffer )->page = wPageNum;
  533. ( (__flash_packet_arrayread_t*) cmdbuffer )->offset = wPageOfs;
  534. ( (__flash_packet_arrayread_t*) cmdbuffer )->__reserved = 0;
  535. ( (__flash_packet_arrayread_t*) cmdbuffer )->__reserved2 = 0;
  536. // отправляем команду
  537. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_arrayread_t) );
  538. // читаем данные
  539. __FLASH_HAL_RD( pDataRead, wCntToRead );
  540. chip_sel_inactive();
  541. }
  542. // --------------------------------------------------------------------------------------------------------
  543. #else
  544. #warning В режиме эмуляции страницы 512 байт функция последовательного чтения недоступна.
  545. // Эмуляция размера страницы в 512 байт достигается неполной записью и неполным чтением страницы микросхемы.
  546. // При этом операции чтения/записи буферизируются драйвером памяти таким образом, что для программы высокого
  547. // уровня этот процесс остается прозрачным. Однако команда последовательного чтения использует иной алгоритм
  548. // чтения: автоматическое инкрементирование указателя чтения без буферизации. Таким образом при использовании
  549. // команды последовательного чтения в режиме эмуляции на каждую читаемую страницу будет приходиться дополнительные
  550. // 16 байт мусорной информации, сохраненной в чипе, но никогда не перезаписываемой драйвером (в режиме эмуляции).
  551. // Поэтому без специальной обработки (прореживания) команда не имеет смысла - вместо прореживания используется
  552. // повторная передача адреса уже следующей страницы на чтение. Таким образом осуществляется чтение больших
  553. // объемов данных в режиме эмуляции.
  554. //
  555. // Реальное положение page N page N+1 page N+2 ......
  556. // дел. Распределение +----------+----------+----------+
  557. // данных по страницам. | 512 | 16 | 512 | 16 | 512 | 16 | ....
  558. // +----------+----------+----------+
  559. // \ \ | | / /
  560. // \ \ | | / /
  561. // ----------------------------------------------------------------------------------
  562. // \ \| |/ /
  563. // Эмуляция размера страниц +-----+-----+-----+ Так представляются страницы чипа в режиме
  564. // режим эмуляции 512 байт. | 512 | 512 | 512 | эмуляции. Однако последовательное чтение
  565. // +-----+-----+-----+ выдает 16 байтное дополнение м/у ними.
  566. // page N page N+2
  567. // page N+1
  568. #endif
  569. #ifdef AT45DB321D_PRM512
  570. #ifndef AT45DB321D_EMU512
  571. // --------------------------------------------------------------------------------------------------------
  572. // __flash_hal__use512page - сконфигурировать чип на работу со стандартной страницей 512 байт
  573. //
  574. // # НАВСЕГДА изменяет размер страницы!
  575. // * потоко-небезопасная функция
  576. // * недоступна в режиме программной эмуляции 512-байтных страниц (AT45DB321D_EMU512)
  577. // # для применения нового размера требуется ОТКЛЮЧЕНИЕ ПИТАНИЯ!
  578. void __flash_hal__use512page()
  579. {
  580. chip_sel_active();
  581. ( (__flash_packet_pagecnfg_t*) cmdbuffer )->opcode = _PCMD_PGSZCNFG;
  582. // отправляем команду
  583. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pagecnfg_t) );
  584. chip_sel_inactive();
  585. #if AT45DB321D_BKGOPERATIONS == 0
  586. __FLASH_SMART_WAITms(_TIME_PGPRG_ms);
  587. #endif
  588. }
  589. #endif
  590. #endif
  591. // --------------------------------------------------------------------------------------------------------
  592. // --------------------------------------------------------------------------------------------------------
  593. // __flash_hal__buffer1_read - чтение буфера 1 (up to 66 MHz)
  594. //
  595. // * не изменяет содержимое внутренних SRAM буферов
  596. // * не проверяет правильность переданных параметров
  597. // * потоко-небезопасная функция
  598. void __flash_hal__buffer1_read( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
  599. __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
  600. __FLASH_WORD wCntToRead ) // количество данных на чтение
  601. {
  602. chip_sel_active();
  603. ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->opcode = _RCMD_BUF1READ;
  604. ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->offset = wBuffOfs;
  605. ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->__reserved = 0;
  606. ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->__reserved2 = 0;
  607. // отправляем команду
  608. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferread_fast_t) );
  609. // читаем данные
  610. __FLASH_HAL_RD( pDataRead, wCntToRead );
  611. chip_sel_inactive();
  612. }
  613. // --------------------------------------------------------------------------------------------------------
  614. // --------------------------------------------------------------------------------------------------------
  615. // __flash_hal__buffer2_read - чтение буфера 2 (up to 66 MHz)
  616. //
  617. // * не изменяет содержимое внутренних SRAM буферов
  618. // * не проверяет правильность переданных параметров
  619. // * потоко-небезопасная функция
  620. void __flash_hal__buffer2_read( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
  621. __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
  622. __FLASH_WORD wCntToRead ) // количество данных на чтение
  623. {
  624. chip_sel_active();
  625. ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->opcode = _RCMD_BUF2READ;
  626. ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->offset = wBuffOfs;
  627. ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->__reserved = 0;
  628. ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->__reserved2 = 0;
  629. // отправляем команду
  630. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferread_fast_t) );
  631. // читаем данные
  632. __FLASH_HAL_RD( pDataRead, wCntToRead );
  633. chip_sel_inactive();
  634. }
  635. // --------------------------------------------------------------------------------------------------------
  636. // --------------------------------------------------------------------------------------------------------
  637. // __flash_hal__buffer1_read_slow - чтение буфера 1 (up to 33 MHz)
  638. //
  639. // * не изменяет содержимое внутренних SRAM буферов
  640. // * не проверяет правильность переданных параметров
  641. // * потоко-небезопасная функция
  642. void __flash_hal__buffer1_read_slow( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
  643. __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
  644. __FLASH_WORD wCntToRead ) // количество данных на чтение
  645. {
  646. chip_sel_active();
  647. ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->opcode = _RCMD_BUF1READ;
  648. ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->offset = wBuffOfs;
  649. ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->__reserved = 0;
  650. // отправляем команду
  651. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferread_slow_t) );
  652. // читаем данные
  653. __FLASH_HAL_RD( pDataRead, wCntToRead );
  654. chip_sel_inactive();
  655. }
  656. // --------------------------------------------------------------------------------------------------------
  657. // --------------------------------------------------------------------------------------------------------
  658. // __flash_hal__buffer2_read_slow - чтение буфера 2 (up to 33 MHz)
  659. //
  660. // * не изменяет содержимое внутренних SRAM буферов
  661. // * не проверяет правильность переданных параметров
  662. // * потоко-небезопасная функция
  663. void __flash_hal__buffer2_read_slow( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
  664. __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
  665. __FLASH_WORD wCntToRead ) // количество данных на чтение
  666. {
  667. chip_sel_active();
  668. ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->opcode = _RCMD_BUF2READ;
  669. ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->offset = wBuffOfs;
  670. ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->__reserved = 0;
  671. // отправляем команду
  672. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferread_slow_t) );
  673. // читаем данные
  674. __FLASH_HAL_RD( pDataRead, wCntToRead );
  675. chip_sel_inactive();
  676. }
  677. // --------------------------------------------------------------------------------------------------------
  678. // --------------------------------------------------------------------------------------------------------
  679. // __flash_hal__buffer1_write - запись буфера 1
  680. //
  681. // * ИЗМЕНЯЕТ содержимое внутренних SRAM буферов
  682. // * не проверяет правильность переданных параметров
  683. // * потоко-небезопасная функция
  684. void __flash_hal__buffer1_write( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
  685. __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
  686. __FLASH_WORD wCntToWrite ) // количество данных на запись
  687. {
  688. chip_sel_active();
  689. ( (__flash_packet_bufferwrite_t*) cmdbuffer )->opcode = _WCMD_BUF1WRIT;
  690. ( (__flash_packet_bufferwrite_t*) cmdbuffer )->offset = wBuffOfs;
  691. ( (__flash_packet_bufferwrite_t*) cmdbuffer )->__reserved = 0;
  692. // отправляем команду
  693. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferwrite_t) );
  694. // пишем данные
  695. __FLASH_HAL_WR( pDataWrite, wCntToWrite );
  696. chip_sel_inactive();
  697. }
  698. // --------------------------------------------------------------------------------------------------------
  699. // --------------------------------------------------------------------------------------------------------
  700. // __flash_hal__buffer2_write - запись буфера 2
  701. //
  702. // * ИЗМЕНЯЕТ содержимое внутренних SRAM буферов
  703. // * не проверяет правильность переданных параметров
  704. // * потоко-небезопасная функция
  705. void __flash_hal__buffer2_write( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
  706. __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
  707. __FLASH_WORD wCntToWrite ) // количество данных на запись
  708. {
  709. chip_sel_active();
  710. ( (__flash_packet_bufferwrite_t*) cmdbuffer )->opcode = _WCMD_BUF2WRIT;
  711. ( (__flash_packet_bufferwrite_t*) cmdbuffer )->offset = wBuffOfs;
  712. ( (__flash_packet_bufferwrite_t*) cmdbuffer )->__reserved = 0;
  713. // отправляем команду
  714. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferwrite_t) );
  715. // пишем данные
  716. __FLASH_HAL_WR( pDataWrite, wCntToWrite );
  717. chip_sel_inactive();
  718. }
  719. // --------------------------------------------------------------------------------------------------------
  720. // --------------------------------------------------------------------------------------------------------
  721. // __flash_hal__buffer1_program - программирование буфера 1 в страницу со стиранием
  722. //
  723. // * не проверяет правильность переданных параметров
  724. // * потоко-небезопасная функция
  725. // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
  726. void __flash_hal__buffer1_program( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
  727. )
  728. {
  729. chip_sel_active();
  730. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->opcode = _WCMD_BUF1PROG;
  731. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->page = wPageNum;
  732. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved = 0;
  733. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved2 = 0;
  734. // отправляем команду
  735. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferprogram_t) );
  736. chip_sel_inactive();
  737. #if AT45DB321D_BKGOPERATIONS == 0
  738. __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
  739. #endif
  740. }
  741. // --------------------------------------------------------------------------------------------------------
  742. // --------------------------------------------------------------------------------------------------------
  743. // __flash_hal__buffer2_program - программирование буфера 2 в страницу со стиранием
  744. //
  745. // * не проверяет правильность переданных параметров
  746. // * потоко-небезопасная функция
  747. // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
  748. void __flash_hal__buffer2_program( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
  749. )
  750. {
  751. chip_sel_active();
  752. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->opcode = _WCMD_BUF2PROG;
  753. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->page = wPageNum;
  754. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved = 0;
  755. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved2 = 0;
  756. // отправляем команду
  757. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferprogram_t) );
  758. chip_sel_inactive();
  759. #if AT45DB321D_BKGOPERATIONS == 0
  760. __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
  761. #endif
  762. }
  763. // --------------------------------------------------------------------------------------------------------
  764. // --------------------------------------------------------------------------------------------------------
  765. // __flash_hal__buffer1_program_wo_erase - программирование буфера 1 в страницу без стирания
  766. //
  767. // * не проверяет правильность переданных параметров
  768. // * потоко-небезопасная функция
  769. // * задерживает выполнение на ЕДИНИЦЫ МИЛЛИСЕКУНД
  770. void __flash_hal__buffer1_program_wo_erase( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
  771. )
  772. {
  773. chip_sel_active();
  774. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->opcode = _WCMD_BUF1PRGx;
  775. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->page = wPageNum;
  776. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved = 0;
  777. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved2 = 0;
  778. // отправляем команду
  779. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferprogram_t) );
  780. chip_sel_inactive();
  781. #if AT45DB321D_BKGOPERATIONS == 0
  782. __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
  783. #endif
  784. }
  785. // --------------------------------------------------------------------------------------------------------
  786. // --------------------------------------------------------------------------------------------------------
  787. // __flash_hal__buffer2_program_wo_erase - программирование буфера 2 в страницу без стирания
  788. //
  789. // * не проверяет правильность переданных параметров
  790. // * потоко-небезопасная функция
  791. // * задерживает выполнение на ЕДИНИЦЫ МИЛЛИСЕКУНД
  792. void __flash_hal__buffer2_program_wo_erase( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
  793. )
  794. {
  795. chip_sel_active();
  796. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->opcode = _WCMD_BUF2PRGx;
  797. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->page = wPageNum;
  798. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved = 0;
  799. ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved2 = 0;
  800. // отправляем команду
  801. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferprogram_t) );
  802. chip_sel_inactive();
  803. #if AT45DB321D_BKGOPERATIONS == 0
  804. __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
  805. #endif
  806. }
  807. // --------------------------------------------------------------------------------------------------------
  808. // --------------------------------------------------------------------------------------------------------
  809. // __flash_hal__page_erase - стирание страницы
  810. //
  811. // * не проверяет правильность переданных параметров
  812. // * потоко-небезопасная функция
  813. // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
  814. void __flash_hal__page_erase( __FLASH_WORD wPageNum // номер стираемой страницы
  815. )
  816. {
  817. chip_sel_active();
  818. ( (__flash_packet_pageerase_t*) cmdbuffer )->opcode = _ECMD_PAGERASE;
  819. ( (__flash_packet_pageerase_t*) cmdbuffer )->page = wPageNum;
  820. ( (__flash_packet_pageerase_t*) cmdbuffer )->__reserved = 0;
  821. ( (__flash_packet_pageerase_t*) cmdbuffer )->__reserved2 = 0;
  822. // отправляем команду
  823. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pageerase_t) );
  824. chip_sel_inactive();
  825. #if AT45DB321D_BKGOPERATIONS == 0
  826. __FLASH_SMART_WAITms( _TIME_PGERS_ms );
  827. #endif
  828. }
  829. // --------------------------------------------------------------------------------------------------------
  830. // --------------------------------------------------------------------------------------------------------
  831. // __flash_hal__block_erase - стирание блока
  832. //
  833. // * не проверяет правильность переданных параметров
  834. // * потоко-небезопасная функция
  835. // * задерживает выполнение на СОТНИ МИЛЛИСЕКУНД
  836. void __flash_hal__block_erase( __FLASH_WORD wBlockNum // номер стираемого блока
  837. )
  838. {
  839. chip_sel_active();
  840. ( (__flash_packet_blockerase_t*) cmdbuffer )->opcode = _ECMD_BLKERASE;
  841. ( (__flash_packet_blockerase_t*) cmdbuffer )->block = wBlockNum;
  842. ( (__flash_packet_blockerase_t*) cmdbuffer )->__reserved = 0;
  843. ( (__flash_packet_blockerase_t*) cmdbuffer )->__reserved2 = 0;
  844. // отправляем команду
  845. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_blockerase_t) );
  846. chip_sel_inactive();
  847. #if AT45DB321D_BKGOPERATIONS == 0
  848. __FLASH_SMART_WAITms( _TIME_BKERS_ms );
  849. #endif
  850. }
  851. // --------------------------------------------------------------------------------------------------------
  852. // --------------------------------------------------------------------------------------------------------
  853. // __flash_hal__sector0_erase - стирание секторов 0a и 0b
  854. //
  855. // * не проверяет правильность переданных параметров
  856. // * потоко-небезопасная функция
  857. // * задерживает выполнение на СЕКУНДЫ
  858. void __flash_hal__sector0_erase( __FLASH_WORD wSubSector // номер подсектора 0 или 1
  859. )
  860. {
  861. chip_sel_active();
  862. ( (__flash_packet_sector0erase_t*) cmdbuffer )->opcode = _ECMD_SCTERASE;
  863. ( (__flash_packet_sector0erase_t*) cmdbuffer )->subsector = wSubSector;
  864. ( (__flash_packet_sector0erase_t*) cmdbuffer )->__reserved = 0;
  865. ( (__flash_packet_sector0erase_t*) cmdbuffer )->__reserved2 = 0;
  866. ( (__flash_packet_sector0erase_t*) cmdbuffer )->__reserved3 = 0;
  867. // отправляем команду
  868. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_sector0erase_t) );
  869. chip_sel_inactive();
  870. #if AT45DB321D_BKGOPERATIONS == 0
  871. __FLASH_SMART_WAITms( _TIME_SCERS_ms );
  872. #endif
  873. }
  874. // --------------------------------------------------------------------------------------------------------
  875. // --------------------------------------------------------------------------------------------------------
  876. // __flash_hal__sector_erase - стирание секторов с номером 1 и выше
  877. //
  878. // * не проверяет правильность переданных параметров
  879. // * потоко-небезопасная функция
  880. // * задерживает выполнение на СЕКУНДЫ
  881. void __flash_hal__sector_erase( __FLASH_WORD wSector // номер сектора 1-63
  882. )
  883. {
  884. chip_sel_active();
  885. ( (__flash_packet_sectorerase_t*) cmdbuffer )->opcode = _ECMD_SCTERASE;
  886. ( (__flash_packet_sectorerase_t*) cmdbuffer )->sector = wSector;
  887. ( (__flash_packet_sectorerase_t*) cmdbuffer )->__reserved = 0;
  888. ( (__flash_packet_sectorerase_t*) cmdbuffer )->__reserved2 = 0;
  889. // отправляем команду
  890. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_sectorerase_t) );
  891. chip_sel_inactive();
  892. #if AT45DB321D_BKGOPERATIONS == 0
  893. __FLASH_SMART_WAITms( _TIME_SCERS_ms );
  894. #endif
  895. }
  896. // --------------------------------------------------------------------------------------------------------
  897. // --------------------------------------------------------------------------------------------------------
  898. // __flash_hal__page_write_via_buffer1 - запись страницы через буфер 1
  899. //
  900. // * не проверяет правильность переданных параметров
  901. // * потоко-небезопасная функция
  902. // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
  903. void __flash_hal__page_write_via_buffer1( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
  904. __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
  905. __FLASH_WORD wCntToWrite, // количество данных на запись
  906. __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
  907. )
  908. {
  909. chip_sel_active();
  910. ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->opcode = _WCMD_PGB1WRIT;
  911. ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->offset = wBuffOfs;
  912. ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->page = wPageNum;
  913. ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->__reserved= 0;
  914. // отправляем команду
  915. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pagewriteviabuffer_t) );
  916. // пишем данные
  917. __FLASH_HAL_WR( pDataWrite, wCntToWrite );
  918. chip_sel_inactive();
  919. #if AT45DB321D_BKGOPERATIONS == 0
  920. __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
  921. #endif
  922. }
  923. // --------------------------------------------------------------------------------------------------------
  924. // --------------------------------------------------------------------------------------------------------
  925. // __flash_hal__page_write_via_buffer2 - запись страницы через буфер 2
  926. //
  927. // * не проверяет правильность переданных параметров
  928. // * потоко-небезопасная функция
  929. // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
  930. void __flash_hal__page_write_via_buffer2( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
  931. __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
  932. __FLASH_WORD wCntToWrite, // количество данных на запись
  933. __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
  934. )
  935. {
  936. chip_sel_active();
  937. ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->opcode = _WCMD_PGB2WRIT;
  938. ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->offset = wBuffOfs;
  939. ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->page = wPageNum;
  940. ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->__reserved= 0;
  941. // отправляем команду
  942. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pagewriteviabuffer_t) );
  943. // пишем данные
  944. __FLASH_HAL_WR( pDataWrite, wCntToWrite );
  945. chip_sel_inactive();
  946. #if AT45DB321D_BKGOPERATIONS == 0
  947. __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
  948. #endif
  949. }
  950. // --------------------------------------------------------------------------------------------------------
  951. // --------------------------------------------------------------------------------------------------------
  952. // __flash_hal__pagetobuffer1 - загрузка содержимого страницы в буфер 1
  953. //
  954. // * не проверяет правильность переданных параметров
  955. // * потоко-небезопасная функция
  956. // * задерживает выполнение на СОТНИ МИКРОСЕКУНД
  957. void __flash_hal__pagetobuffer1( __FLASH_WORD wPageNum // номер страницы для загрузки
  958. )
  959. {
  960. chip_sel_active();
  961. ( (__flash_packet_bufferload_t*) cmdbuffer )->opcode = _ACMD_BUF1LOAD;
  962. ( (__flash_packet_bufferload_t*) cmdbuffer )->page = wPageNum;
  963. ( (__flash_packet_bufferload_t*) cmdbuffer )->__reserved =0;
  964. ( (__flash_packet_bufferload_t*) cmdbuffer )->__reserved2=0;
  965. // отправляем команду
  966. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferload_t) );
  967. chip_sel_inactive();
  968. #if AT45DB321D_BKGOPERATIONS == 0
  969. __FLASH_WAITus( _TIME_BLDCM_us );
  970. #endif
  971. }
  972. // --------------------------------------------------------------------------------------------------------
  973. // --------------------------------------------------------------------------------------------------------
  974. // __flash_hal__pagetobuffer2 - загрузка содержимого страницы в буфер 2
  975. //
  976. // * не проверяет правильность переданных параметров
  977. // * потоко-небезопасная функция
  978. // * задерживает выполнение на СОТНИ МИКРОСЕКУНД
  979. void __flash_hal__pagetobuffer2( __FLASH_WORD wPageNum // номер страницы для загрузки
  980. )
  981. {
  982. chip_sel_active();
  983. ( (__flash_packet_bufferload_t*) cmdbuffer )->opcode = _ACMD_BUF2LOAD;
  984. ( (__flash_packet_bufferload_t*) cmdbuffer )->page = wPageNum;
  985. ( (__flash_packet_bufferload_t*) cmdbuffer )->__reserved =0;
  986. ( (__flash_packet_bufferload_t*) cmdbuffer )->__reserved2=0;
  987. // отправляем команду
  988. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferload_t) );
  989. chip_sel_inactive();
  990. #if AT45DB321D_BKGOPERATIONS == 0
  991. __FLASH_WAITus( _TIME_BLDCM_us );
  992. #endif
  993. }
  994. // --------------------------------------------------------------------------------------------------------
  995. // --------------------------------------------------------------------------------------------------------
  996. // __flash_hal__pagetobuffer1 - сравнение содержимого страницы с буфером 1
  997. //
  998. // * не проверяет правильность переданных параметров
  999. // * потоко-небезопасная функция
  1000. // * задерживает выполнение на СОТНИ МИКРОСЕКУНД
  1001. void __flash_hal__buffer1_compare( __FLASH_WORD wPageNum // номер страницы для сравнения
  1002. )
  1003. {
  1004. chip_sel_active();
  1005. ( (__flash_packet_buffercompare_t*) cmdbuffer )->opcode = _ACMD_BUF1CMPR;
  1006. ( (__flash_packet_buffercompare_t*) cmdbuffer )->page = wPageNum;
  1007. ( (__flash_packet_buffercompare_t*) cmdbuffer )->__reserved =0;
  1008. ( (__flash_packet_buffercompare_t*) cmdbuffer )->__reserved2=0;
  1009. // отправляем команду
  1010. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_buffercompare_t) );
  1011. chip_sel_inactive();
  1012. #if AT45DB321D_BKGOPERATIONS == 0
  1013. __FLASH_WAITus( _TIME_BLDCM_us );
  1014. #endif
  1015. }
  1016. // --------------------------------------------------------------------------------------------------------
  1017. // --------------------------------------------------------------------------------------------------------
  1018. // __flash_hal__pagetobuffer2 - сравнение содержимого страницы с буфером 2
  1019. //
  1020. // * не проверяет правильность переданных параметров
  1021. // * потоко-небезопасная функция
  1022. // * задерживает выполнение на СОТНИ МИКРОСЕКУНД
  1023. void __flash_hal__buffer2_compare( __FLASH_WORD wPageNum // номер страницы для сравнения
  1024. )
  1025. {
  1026. chip_sel_active();
  1027. ( (__flash_packet_buffercompare_t*) cmdbuffer )->opcode = _ACMD_BUF2CMPR;
  1028. ( (__flash_packet_buffercompare_t*) cmdbuffer )->page = wPageNum;
  1029. ( (__flash_packet_buffercompare_t*) cmdbuffer )->__reserved =0;
  1030. ( (__flash_packet_buffercompare_t*) cmdbuffer )->__reserved2=0;
  1031. // отправляем команду
  1032. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_buffercompare_t) );
  1033. chip_sel_inactive();
  1034. #if AT45DB321D_BKGOPERATIONS == 0
  1035. __FLASH_WAITus( _TIME_BLDCM_us );
  1036. #endif
  1037. }
  1038. // --------------------------------------------------------------------------------------------------------
  1039. // --------------------------------------------------------------------------------------------------------
  1040. // __flash_hal__autopagerewrite1 - обновление страницы через буфер 1
  1041. //
  1042. // * не проверяет правильность переданных параметров
  1043. // * потоко-небезопасная функция
  1044. // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
  1045. void __flash_hal__autopagerewrite1( __FLASH_WORD wPageNum // номер обновляемой страницы
  1046. )
  1047. {
  1048. chip_sel_active();
  1049. ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->opcode = _ACMD_PAGEREF1;
  1050. ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->page = wPageNum;
  1051. ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->__reserved = 0;
  1052. ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->__reserved2 = 0;
  1053. // отправляем команду
  1054. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_autopagerewrite_t) );
  1055. chip_sel_inactive();
  1056. #if AT45DB321D_BKGOPERATIONS == 0
  1057. __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
  1058. #endif
  1059. }
  1060. // --------------------------------------------------------------------------------------------------------
  1061. // --------------------------------------------------------------------------------------------------------
  1062. // __flash_hal__autopagerewrite2 - обновление страницы через буфер 2
  1063. //
  1064. // * не проверяет правильность переданных параметров
  1065. // * потоко-небезопасная функция
  1066. // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
  1067. void __flash_hal__autopagerewrite2( __FLASH_WORD wPageNum // номер обновляемой страницы
  1068. )
  1069. {
  1070. chip_sel_active();
  1071. ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->opcode = _ACMD_PAGEREF2;
  1072. ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->page = wPageNum;
  1073. ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->__reserved = 0;
  1074. ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->__reserved2 = 0;
  1075. // отправляем команду
  1076. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_autopagerewrite_t) );
  1077. chip_sel_inactive();
  1078. #if AT45DB321D_BKGOPERATIONS == 0
  1079. __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
  1080. #endif
  1081. }
  1082. // --------------------------------------------------------------------------------------------------------
  1083. // --------------------------------------------------------------------------------------------------------
  1084. // __flash_hal__sleepmode - переход в режим пониженного энергопотребления
  1085. //
  1086. // * потоко-небезопасная функция
  1087. // # переводит устройство в режим, когда все команды, кроме __flash_hal__wakeup игнорируются
  1088. void __flash_hal__sleepmode()
  1089. {
  1090. chip_sel_active();
  1091. ( (__flash_packet_powerdown_t*) cmdbuffer )->opcode = _ACMD_EPWRDOWN;
  1092. // отправляем команду
  1093. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_powerdown_t) );
  1094. chip_sel_inactive();
  1095. __FLASH_WAITus( _TIME_EDPDM_us );
  1096. }
  1097. // --------------------------------------------------------------------------------------------------------
  1098. // --------------------------------------------------------------------------------------------------------
  1099. // __flash_hal__wakeup - выход из режима пониженного энергопотребления
  1100. //
  1101. // * потоко-небезопасная функция
  1102. // # выводит устройство из режима, когда все команды, кроме __flash_hal__wakeup игнорируются
  1103. void __flash_hal__wakeup()
  1104. {
  1105. chip_sel_active();
  1106. // если флеш находилась во сне, необходимо ждать _TIME_RDPDM_us
  1107. __FLASH_WAITus(_TIME_RDPDM_us);
  1108. ( (__flash_packet_powerdown_t*) cmdbuffer )->opcode = _ACMD_LPWRDOWN;
  1109. // отправляем команду
  1110. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_powerdown_t) );
  1111. chip_sel_inactive();
  1112. __FLASH_WAITus( _TIME_RDPDM_us );
  1113. }
  1114. // --------------------------------------------------------------------------------------------------------
  1115. // --------------------------------------------------------------------------------------------------------
  1116. // __flash_hal__manufactureridread - чтение идентификатора производителя
  1117. //
  1118. // * потоко-небезопасная функция
  1119. // * может использоваться для опеределения типа чипа для выяснения его вместимости
  1120. // * функция принимает параметр @pManufacturerID типа __flash_id_t. Этот параметр будет содержать
  1121. // информацию о чипе, если параметр не NULL. Кроме того, для того, чтобы прочитать расширенную
  1122. // информацию производителя (extended device information), поля pManufacturerID->pExtBf и
  1123. // pManufacturerID->ExtLen должны быть проининциализированны указателем на принимающий буфер
  1124. // и длинной этого буфера соответственно. При наличии расширенной информации поле ExtLen будет
  1125. // перезаписано, и будет содержать длинну расширенной информации, сохраненной по указателю pExtBf.
  1126. // Память по указателю pExtBf должна быть выделена заранее перед вызовом функции. Нуль-символ не
  1127. // добавляется. Память, начиная с ExtLen байта, не перезаписывается (остается мусор).
  1128. // * параметр @pManufacturerID может быть равен NULL. Для того, чтобы НЕ читать расширенную информацию,
  1129. // передайте NULL вместо pManufacturerID, или, если передаете pManufacturerID, обнулите в нем поля pExtBf и ExtLen.
  1130. // * функция способна определять расширенный Manufacturer ID согласно JEDEC JEP-106. Таким образом, кроме
  1131. // стандартного ID производителя длинной 1 байт, производитель может использовать т.н. Continuation Code - 0x7F
  1132. // Если стандартный код читается как 7F, функия продолжает чтение идентификатора до тех пор, пока не будет
  1133. // принят байт, отличный от 7F, причем количество таких кодов 7F будет сохранено (не более 255)
  1134. // и интерпретироваться как HighId. Если функция обнаружит более 255 кодов 7F, они подсчитаны не будут, при этом
  1135. // HighId будет равен 255, а LowId - первый найденный не-7F код (даже после более 255 кодов 7F).
  1136. // * вовзращаемое значение - DWORD, "откушенный" по младшему адресу от структуры __flash_id_t - содержит
  1137. // DevId, LowId, HighId.
  1138. __FLASH_DWORD __flash_hal__manufactureridread( __flash_id_t * pManufacturerID // необязательный параметр-буфер для приема расширенной информации
  1139. )
  1140. {
  1141. // локальные переменные функции объединены с возвращаемым значением, чтобы вернуть
  1142. // часть информации в виде DWORD
  1143. union
  1144. {
  1145. struct
  1146. {
  1147. __FLASH_BYTE LowId; // стандартный байт ID (не расширенный)
  1148. __FLASH_BYTE HighId; // расширенный байт ID (количество 0x7F Continuation Code) (JEDEC JEP-106)
  1149. union
  1150. {
  1151. __FLASH_WORD DevId; // код устройства
  1152. struct
  1153. {
  1154. __FLASH_BYTE LDevId; // код устройства (Low)
  1155. __FLASH_BYTE HDevId; // код устройства (High)
  1156. };
  1157. };
  1158. };
  1159. __FLASH_DWORD ReturnValue; // возвращаемое значение
  1160. };
  1161. DevId = 0;
  1162. LDevId = 0;
  1163. HDevId = 0;
  1164. LowId = 0;
  1165. HighId = 0;
  1166. ReturnValue = 0;
  1167. //-----------
  1168. chip_sel_active();
  1169. //-----------
  1170. ( (__flash_packet_manufactureridread_t*) cmdbuffer )->opcode = _ACMD_MFIDREAD;
  1171. // отправляем команду
  1172. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_manufactureridread_t) );
  1173. //-----------
  1174. // чтение Manufacturer ID
  1175. do
  1176. {
  1177. __FLASH_HAL_RD( &LowId, sizeof( LowId ) );
  1178. if( HighId < 255 ) HighId += ( (__FLASH_MANIDEX_OPCODE == LowId)? 1 : 0 );
  1179. }
  1180. while( (__FLASH_MANIDEX_OPCODE == LowId) );
  1181. //-----------
  1182. // чтение Device ID
  1183. __FLASH_HAL_RD( &LDevId, sizeof( LDevId ) );
  1184. __FLASH_HAL_RD( &HDevId, sizeof( HDevId ) );
  1185. //-----------
  1186. // чтение расширенной информации только если нам передали структуру для заполнения
  1187. if( pManufacturerID )
  1188. {
  1189. // заполняем поля в переданной нам структуре
  1190. pManufacturerID->DevId = DevId; // device ID
  1191. pManufacturerID->LowId = LowId; // Manufacturer ID (Standart)
  1192. pManufacturerID->HighId = HighId; // Manufacturer ID (Extended - Continuation Code 0x7F count)
  1193. // записываем длинну расширенной информации
  1194. {
  1195. __FLASH_BYTE ExtLen;
  1196. // читаем длинну расширенной информации
  1197. __FLASH_HAL_RD( &ExtLen, sizeof( ExtLen ) );
  1198. // записываем длинну расширенной информации
  1199. pManufacturerID->ExtLen = ExtLen;
  1200. // если есть куда записать расширенную информацию
  1201. if( pManufacturerID->pExtBf )
  1202. {
  1203. // если на чипе есть расширенная информация
  1204. if( ExtLen )
  1205. {
  1206. // ограничиваем емкость буфера по размеру расширенной информации
  1207. if( pManufacturerID->ExtLen > ExtLen )
  1208. {
  1209. pManufacturerID->ExtLen = ExtLen;
  1210. }
  1211. // сначала считываем доступное количество байт (определяется значением ExtLen в ВЫХОДНОЙ структуре
  1212. __FLASH_HAL_RD( pManufacturerID->pExtBf, sizeof( pManufacturerID->ExtLen ) );
  1213. // затем перезаписываем длинну в выходную структуру
  1214. pManufacturerID->ExtLen = ExtLen;
  1215. }
  1216. else
  1217. // нет расширенной информации
  1218. {
  1219. pManufacturerID->ExtLen = 0; // обнуляем длинну расширенной информации в выходной структуре
  1220. }
  1221. }
  1222. }
  1223. }
  1224. //-----------
  1225. chip_sel_inactive();
  1226. //-----------
  1227. return ReturnValue;
  1228. }
  1229. // --------------------------------------------------------------------------------------------------------
  1230. // --------------------------------------------------------------------------------------------------------
  1231. // __flash_hal__writeprotect_enable - включить программную защиту от записи/стирания
  1232. //
  1233. // * потоко-небезопасная функция
  1234. // # переводит устройство в режим, когда невозможно стирать/записывать некоторые секторы
  1235. void __flash_hal__writeprotect_enable()
  1236. {
  1237. chip_sel_active();
  1238. ( (__flash_packet_protecttoggle_t*) cmdbuffer )->opcode = _SCMD_4SCTPREN;
  1239. // отправляем команду
  1240. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protecttoggle_t) );
  1241. chip_sel_inactive();
  1242. // если разрешено управление аппаратным сигналом защиты записи
  1243. #if AT45DB321D_HW_WR_PROTECT
  1244. // если аппаратная защита записи не отключена в настройках
  1245. #if AT45DB321D_HW_WR_PROTECT_KEEPUNPROTECTED == 0
  1246. // установить аппаратную защиту записи
  1247. __imp_flash_hwwrprotect_assert();
  1248. #endif
  1249. #endif
  1250. }
  1251. // --------------------------------------------------------------------------------------------------------
  1252. // --------------------------------------------------------------------------------------------------------
  1253. // __flash_hal__writeprotect_disable - выключить программную защиту от записи/стирания
  1254. //
  1255. // * потоко-небезопасная функция
  1256. // # выводит устройство из режима, когда невозможно стирать/записывать некоторые секторы (если нет аппаратной защиты)
  1257. void __flash_hal__writeprotect_disable()
  1258. {
  1259. // если разрешено управление аппаратным сигналом защиты записи
  1260. #if AT45DB321D_HW_WR_PROTECT
  1261. // если аппаратная защита записи не отключена в настройках
  1262. #if AT45DB321D_HW_WR_PROTECT_KEEPUNPROTECTED == 0
  1263. // снять аппаратную защиту записи
  1264. __imp_flash_hwwrprotect_release();
  1265. #endif
  1266. #endif
  1267. chip_sel_active();
  1268. ( (__flash_packet_protecttoggle_t*) cmdbuffer )->opcode = _SCMD_4SCTPRDS;
  1269. // отправляем команду
  1270. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protecttoggle_t) );
  1271. chip_sel_inactive();
  1272. }
  1273. // --------------------------------------------------------------------------------------------------------
  1274. // --------------------------------------------------------------------------------------------------------
  1275. // __flash_hal__protectregister_erase - стирает регистр защиты, помечая ВСЕ сектора как защищенные
  1276. //
  1277. // * потоко-небезопасная функция
  1278. // # после выдачи этой команды и последующей __flash_hal__writeprotect_enable все сектора будут защищены от записи/стирания
  1279. // # если включена программная защита от записи, все операции стирания/записи для всех секторов будут заблокированы до ее отключения
  1280. // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
  1281. void __flash_hal__protectregister_erase()
  1282. {
  1283. chip_sel_active();
  1284. ( (__flash_packet_protectregistererase_t*) cmdbuffer )->opcode = _SCMD_4PRREGER;
  1285. // отправляем команду
  1286. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protectregistererase_t) );
  1287. chip_sel_inactive();
  1288. #if AT45DB321D_BKGOPERATIONS == 0
  1289. __FLASH_SMART_WAITms( _TIME_PGERS_ms );
  1290. #endif
  1291. }
  1292. // --------------------------------------------------------------------------------------------------------
  1293. // --------------------------------------------------------------------------------------------------------
  1294. // __flash_hal__protectregister_write - записывает регистр защиты
  1295. //
  1296. // * потоко-небезопасная функция
  1297. // * параметр @contents не может быть NULL - укажите содержимое регистра защиты (см. __flash_protectionregister_t)
  1298. // # требуется предварительное стирание! (__flash_hal__protectregister_erase)
  1299. // * задерживает выполнение на МИЛЛИСЕКУНДЫ
  1300. // * ИЗМЕНЯЕТ СОДЕРЖИМОЕ ВСТРОЕННОГО БУФЕРА 1
  1301. void __flash_hal__protectregister_write( __flash_protectionregister_t * contents // содержимое регистра защиты для записи
  1302. )
  1303. {
  1304. if( !contents ) return;
  1305. chip_sel_active();
  1306. ( (__flash_packet_protectregisterwrite_t*) cmdbuffer )->opcode = _SCMD_4PRREGWR;
  1307. // отправляем команду
  1308. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protectregisterwrite_t) );
  1309. // пишем регистр защиты
  1310. __FLASH_HAL_WR( contents, sizeof(__flash_protectionregister_t) );
  1311. chip_sel_inactive();
  1312. #if AT45DB321D_BKGOPERATIONS == 0 //!
  1313. __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
  1314. #endif
  1315. }
  1316. // --------------------------------------------------------------------------------------------------------
  1317. // --------------------------------------------------------------------------------------------------------
  1318. // __flash_hal__protectregister_read - прочитывает регистр защиты
  1319. //
  1320. // * потоко-небезопасная функция
  1321. // * параметр @contents не может быть NULL - укажите буфер для содержимого регистра защиты (см. __flash_protectionregister_t)
  1322. void __flash_hal__protectregister_read( __flash_protectionregister_t * contents // буфер-приемник содержимого регистра защиты
  1323. )
  1324. {
  1325. if( !contents ) return;
  1326. chip_sel_active();
  1327. ( (__flash_packet_protectregisterread_t*) cmdbuffer )->opcode = _SCMD_PRTREGRD;
  1328. ( (__flash_packet_protectregisterread_t*) cmdbuffer )->__reserved = 0;
  1329. // отправляем команду
  1330. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protectregisterwrite_t) );
  1331. // читаем регистр защиты
  1332. __FLASH_HAL_RD( contents, sizeof(__flash_protectionregister_t) );
  1333. chip_sel_inactive();
  1334. }
  1335. // --------------------------------------------------------------------------------------------------------
  1336. // --------------------------------------------------------------------------------------------------------
  1337. // __flash_hal__sectorlockdown - постоянная блокировка сектора от записи/стирания
  1338. //
  1339. // * потоко-небезопасная функция
  1340. // # блокирует сектор навсегда: он становится "только для чтения"
  1341. // * укажите адрес, принадлежащий сектору в параметре @address
  1342. // * задерживает выполнение на МИЛЛИСЕКУНДЫ
  1343. void __flash_hal__sectorlockdown( __FLASH_DWORD address // адрес внутри блокируемого сектора
  1344. )
  1345. {
  1346. chip_sel_active();
  1347. ( (__flash_packet_sectorlockdown_t*) cmdbuffer )->opcode = _SCMD_4SCTLKDN;
  1348. // заполняем адрес
  1349. ( (__flash_packet_sectorlockdown_t*) cmdbuffer )->laddress = address & 0x0000FFFF;
  1350. ( (__flash_packet_sectorlockdown_t*) cmdbuffer )->haddress = (address >> 16) & 0x000000FF;
  1351. // отправляем команду
  1352. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_sectorlockdown_t) );
  1353. chip_sel_inactive();
  1354. #if AT45DB321D_BKGOPERATIONS == 0
  1355. __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
  1356. #endif
  1357. }
  1358. // --------------------------------------------------------------------------------------------------------
  1359. // --------------------------------------------------------------------------------------------------------
  1360. // __flash_hal__lockdownregister_read - прочитывает регистр блокировки
  1361. //
  1362. // * потоко-небезопасная функция
  1363. // * параметр @contents не может быть NULL - укажите буфер для содержимого регистра блокировки (см. __flash_lockdownregister_t)
  1364. void __flash_hal__lockdownregister_read( __flash_lockdownregister_t * contents // буфер-приемник содержимого регистра блокировки
  1365. )
  1366. {
  1367. if( !contents ) return;
  1368. chip_sel_active();
  1369. ( (__flash_packet_lockdownregisterread_t*) cmdbuffer )->opcode = _SCMD_LKDNRGRD;
  1370. ( (__flash_packet_lockdownregisterread_t*) cmdbuffer )->__reserved = 0;
  1371. // отправляем команду
  1372. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_lockdownregisterread_t) );
  1373. // читаем регистр блокировки
  1374. __FLASH_HAL_RD( contents, sizeof(__flash_lockdownregister_t) );
  1375. chip_sel_inactive();
  1376. }
  1377. // --------------------------------------------------------------------------------------------------------
  1378. // --------------------------------------------------------------------------------------------------------
  1379. // __flash_hal__securityregister_write - записывает регистр безопасности
  1380. //
  1381. // * потоко-небезопасная функция
  1382. // * параметр @contents не может быть равен NULL
  1383. // * ИЗМЕНЯЕТ СОДЕРЖИМОЕ ВСТРОЕННОГО БУФЕРА 1
  1384. // * записывает только ПОЛЬЗОВАТЕЛЬСКУЮ часть
  1385. // # РЕГИСТР БЕЗОПАСНОСТИ МОЖЕТ БЫТЬ ЗАПИСАН ТОЛЬКО ОДИН РАЗ!
  1386. void __flash_hal__securityregister_write( __flash_usersecurityregister_t * contents // содержимое регистра безопасности (часть, доступная для записи пользователю)
  1387. )
  1388. {
  1389. if( !contents ) return;
  1390. chip_sel_active();
  1391. ( (__flash_packet_securityregisterwrite_t*) cmdbuffer )->opcode = _SCMD_4SECRGWR;
  1392. // отправляем команду
  1393. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_securityregisterwrite_t) );
  1394. // записываем регистр безопасности
  1395. __FLASH_HAL_WR( contents, sizeof(__flash_usersecurityregister_t) );
  1396. #if AT45DB321D_BKGOPERATIONS == 0
  1397. __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
  1398. #endif
  1399. chip_sel_inactive();
  1400. }
  1401. // --------------------------------------------------------------------------------------------------------
  1402. // --------------------------------------------------------------------------------------------------------
  1403. // __flash_hal__securityregister_read - прочитывает регистр безопасности
  1404. //
  1405. // * потоко-небезопасная функция
  1406. // * параметр @contents не может быть NULL - укажите буфер-приемние для сохранения содержимого регистра блокировки (см. __flash_securityregister_t)
  1407. // * считывает как пользовательскую часть, так и запрограммированную производителем
  1408. void __flash_hal__securityregister_read( __flash_securityregister_t * contents // буфер-приемник содержимого регистра блокировки
  1409. )
  1410. {
  1411. if( !contents ) return;
  1412. chip_sel_active();
  1413. ( (__flash_packet_securityregisterread_t*) cmdbuffer )->opcode = _SCMD_4SECRGRD;
  1414. // отправляем команду
  1415. __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_securityregisterread_t) );
  1416. // читаем регистр безопасности
  1417. __FLASH_HAL_RD( contents, sizeof(__flash_securityregister_t) );
  1418. chip_sel_inactive();
  1419. }
  1420. // --------------------------------------------------------------------------------------------------------
  1421. // --------------------------------------------------------------------------------------------------------
  1422. // __flash_hal__securityregister_read - прочитывает регистр безопасности и выполняет
  1423. // проверку осмысленности прочитанного заводского идентификатора.
  1424. // Функция расценивает индентификатор состоящий из одних 0xFF или 0x00 как невозможный.
  1425. // В этом случае имеет место ошибка, функция возвращает false.
  1426. bool __flash_hal__securityregister_validate( __flash_securityregister_t * contents // буфер-приемник содержимого регистра блокировки
  1427. )
  1428. {
  1429. if( NULL != contents )
  1430. {
  1431. __flash_hal__securityregister_read( contents );
  1432. __FLASH_DWORD n00 = 0;
  1433. __FLASH_DWORD nFF = 0;
  1434. for( __FLASH_DWORD i = 0; i < __FLASH_FACT_SECURITY_BYTES; ++i )
  1435. {
  1436. if( 0xFF == contents->FactoryPart.UserId[i] ) ++nFF;
  1437. if( 0x00 == contents->FactoryPart.UserId[i] ) ++n00;
  1438. }
  1439. if( (n00 != __FLASH_FACT_SECURITY_BYTES)
  1440. &&
  1441. (nFF != __FLASH_FACT_SECURITY_BYTES) )
  1442. {
  1443. return true;
  1444. }
  1445. }
  1446. return false;
  1447. }
  1448. // --------------------------------------------------------------------------------------------------------
  1449. #if AT45DB321D_POWER_MANAGEMENT > 0
  1450. // --------------------------------------------------------------------------------------------------------
  1451. // __flash_hal__power_on - реализует управление питанием микросхемы памяти (подает питание)
  1452. //
  1453. void __flash_hal__power_on()
  1454. {
  1455. // снять сигнал выбора чипа (чип не выбран, режим idle)
  1456. chip_sel_inactive();
  1457. // подать питание
  1458. __imp_flash_poweron();
  1459. }
  1460. // --------------------------------------------------------------------------------------------------------
  1461. // __flash_hal__power_off - реализует управление питанием микросхемы памяти (снимает питание)
  1462. //
  1463. void __flash_hal__power_off()
  1464. {
  1465. // снять питание
  1466. __imp_flash_poweroff();
  1467. }
  1468. // --------------------------------------------------------------------------------------------------------
  1469. // __flash_hal__power_pulse - реализует управление питанием микросхемы - формирует импульс перезагрузки
  1470. void __flash_hal__power_pulse( __FLASH_WORD nCooldownTime_ms, __FLASH_WORD nStartupTime_ms )
  1471. {
  1472. // снять питание
  1473. __imp_flash_poweroff();
  1474. // снять сигнал выбора чипа (чип не выбран, режим idle)
  1475. chip_sel_inactive();
  1476. if( nCooldownTime_ms > 0 )
  1477. {
  1478. // немного подождем, пока остынет :)
  1479. __FLASH_WAITms( _TIME_COOLDOWN_ms );
  1480. }
  1481. else
  1482. {
  1483. // ждем совсем немного
  1484. __FLASH_WAITus( _TIME_STRUP_us );
  1485. }
  1486. // подать питание
  1487. __imp_flash_poweron();
  1488. // если разрешено управление режимом сброса
  1489. #if AT45DB321D_RESET_MANAGEMENT
  1490. // сформировать импульс сброса микросхемы
  1491. __flash_hal__reset_pulse();
  1492. #endif
  1493. if( nStartupTime_ms > 0 )
  1494. {
  1495. // ожидать готовности
  1496. __FLASH_WAITms( _TIME_START_ms );
  1497. }
  1498. else
  1499. {
  1500. // ждем совсем немного
  1501. __FLASH_WAITus( _TIME_STRUP_us );
  1502. }
  1503. }
  1504. #endif
  1505. #if AT45DB321D_RESET_MANAGEMENT > 0
  1506. // --------------------------------------------------------------------------------------------------------
  1507. // __flash_hal__reset_assert - реализует управление сигналом сброса микросхемы памяти (устанавливает сигнал сброса)
  1508. //
  1509. void __flash_hal__reset_assert()
  1510. {
  1511. // снять сигнал выбора чипа (чип не выбран, режим idle)
  1512. chip_sel_inactive();
  1513. // установить сигнал сброса
  1514. __imp_flash_reset_assert();
  1515. }
  1516. // --------------------------------------------------------------------------------------------------------
  1517. // __flash_hal__reset_release - реализует управление сигналом сброса микросхемы памяти (снимает сигнал сброса)
  1518. //
  1519. void __flash_hal__reset_release()
  1520. {
  1521. // снять сигнал сброса
  1522. __imp_flash_reset_release();
  1523. }
  1524. // --------------------------------------------------------------------------------------------------------
  1525. // __flash_hal__reset_pulse - реализует управление сигналом сброса микросхемы памяти (подает законченный импульс сброса)
  1526. //
  1527. void __flash_hal__reset_pulse()
  1528. {
  1529. // формируем импульс сброса
  1530. // сначала снимаем сигнал сброса
  1531. __imp_flash_reset_release();
  1532. // после снятия сигнала сброса необходимо ожидать время восстановления
  1533. __FLASH_WAITus(_TIME_RSTRC_us);
  1534. // потом ставим сигнал сброса
  1535. __flash_hal__reset_assert();
  1536. // ожидание: требуется время для реакции на сигнал сброса
  1537. __FLASH_WAITus(_TIME_RSTWD_us);
  1538. // потом снова снимаем
  1539. __flash_hal__reset_release();
  1540. // после снятия сигнала сброса необходимо ожидать время восстановления
  1541. __FLASH_WAITus(_TIME_RSTRC_us);
  1542. }
  1543. #endif