AT45DB161E_LL.c 96 KB

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