| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272 |
- // Файл с низкоуровневыми коммандами для AT45DB161E.
- // v 1.4 от 28/07/15
- // v 1.5 от 13/10/20
- // Автор: Сычев А.
- // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
- // №№№№№№№№№№№№№№№№№№№№№№ НИЗКОУРОВНЕВЫЕ НЕБЕЗОПАСНЫЕ ФУНКЦИИ №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
- // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
- #define AT45DB161E_LOWLEVEL
- #include "drivers\flash\base\flash_api_types.h"
- #include "drivers\flash\at45\common\AT45DBXXX_HAL.h" // аппаратная абстрация от SSP
- #include "drivers\flash\at45\lowlevel\AT45DB161E_LL.h" // определения для AT45DB161E
- #include "drivers\flash\at45\lowlevel\AT45DB161E_LL_func.h" // прототипы LL-функций
- // ########################################################################################################
- // Прототипы низкоуровневых функций драйвера
- // __flash_hal__statusread - чтение регистра статуса
- static void __flash_hal__statusread( __flash_status_t * pcReadRegister // буфер для чтения статус-регистра
- );
- // __flash_hal__page_read - чтение одной страницы
- static void __flash_hal__page_read( __FLASH_WORD wPageNum, // номер страницы для чтения
- __FLASH_WORD wPageOfs, // адрес начала чтения в странице
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ); // количество данных на чтение
- // __flash_hal__array_read - последовательное чтение (массив)
- // * недоступна в режиме программной эмуляции 512-байтных страниц (AT45DB161E_EMU512)
- #ifndef AT45DB161E_EMU512
- static void __flash_hal__array_read ( __FLASH_WORD wPageNum, // номер начальной страницы для чтения
- __FLASH_WORD wPageOfs, // адрес начала чтения в начальной странице
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ); // количество данных на чтение
- #endif
- #ifdef AT45DB161E_PRM512
- #ifndef AT45DB161E_EMU512
- // __flash_hal__use512page - сконфигурировать чип на работу со стандартной страницей 512 байт
- // # НАВСЕГДА изменяет размер страницы!
- // * недоступна в режиме программной эмуляции 512-байтных страниц (AT45DB161E_EMU512)
- static void __flash_hal__use512page();
- #endif
- #endif
- // __flash_hal__buffer1_read - чтение буфера 1 (up to 66 MHz)
- static void __flash_hal__buffer1_read( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ); // количество данных на чтение
- // __flash_hal__buffer2_read - чтение буфера 2 (up to 66 MHz)
- static void __flash_hal__buffer2_read( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ); // количество данных на чтение
- // __flash_hal__buffer1_read_slow - чтение буфера 1 (up to 33 MHz)
- static void __flash_hal__buffer1_read_slow( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ); // количество данных на чтение
- // __flash_hal__buffer2_read_slow - чтение буфера 2 (up to 33 MHz)
- static void __flash_hal__buffer2_read_slow( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ); // количество данных на чтение
- // __flash_hal__buffer1_write - запись буфера 1
- static void __flash_hal__buffer1_write( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
- __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
- __FLASH_WORD wCntToWrite ); // количество данных на запись
- // __flash_hal__buffer2_write - запись буфера 2
- static void __flash_hal__buffer2_write( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
- __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
- __FLASH_WORD wCntToWrite ); // количество данных на запись
- // __flash_hal__buffer1_program - программирование буфера 1 в страницу со стиранием
- static void __flash_hal__buffer1_program( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- );
- // __flash_hal__buffer2_program - программирование буфера 2 в страницу со стиранием
- void __flash_hal__buffer2_program( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- );
- // __flash_hal__buffer1_program_wo_erase - программирование буфера 1 в страницу без стирания
- static void __flash_hal__buffer1_program_wo_erase( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- );
- // __flash_hal__buffer2_program_wo_erase - программирование буфера 2 в страницу без стирания
- static void __flash_hal__buffer2_program_wo_erase( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- );
- // __flash_hal__page_erase - стирание страницы
- static void __flash_hal__page_erase( __FLASH_WORD wPageNum // номер стираемой страницы
- );
- // __flash_hal__block_erase - стирание блока
- static void __flash_hal__block_erase( __FLASH_WORD wBlockNum // номер стираемого блока
- );
- // __flash_hal__sector0_erase - стирание секторов 0a и 0b
- static void __flash_hal__sector0_erase( __FLASH_WORD wSubSector // номер подсектора 0 или 1
- );
- // __flash_hal__sector_erase - стирание секторов с номером 1 и выше
- static void __flash_hal__sector_erase( __FLASH_WORD wSector // номер сектора 1-63
- );
- // __flash_hal__page_write_via_buffer1 - запись страницы через буфер 1
- static void __flash_hal__page_write_via_buffer1( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
- __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
- __FLASH_WORD wCntToWrite, // количество данных на запись
- __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- );
- // __flash_hal__page_write_via_buffer2 - запись страницы через буфер 2
- static void __flash_hal__page_write_via_buffer2( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
- __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
- __FLASH_WORD wCntToWrite, // количество данных на запись
- __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- );
- // __flash_hal__pagetobuffer1 - загрузка содержимого страницы в буфер 1
- static void __flash_hal__pagetobuffer1( __FLASH_WORD wPageNum // номер страницы для загрузки
- );
- // __flash_hal__pagetobuffer2 - загрузка содержимого страницы в буфер 2
- static void __flash_hal__pagetobuffer2( __FLASH_WORD wPageNum // номер страницы для загрузки
- );
- // __flash_hal__pagetobuffer1 - сравнение содержимого страницы с буфером 1
- static void __flash_hal__buffer1_compare( __FLASH_WORD wPageNum // номер страницы для сравнения
- );
- // __flash_hal__pagetobuffer2 - сравнение содержимого страницы с буфером 2
- static void __flash_hal__buffer2_compare( __FLASH_WORD wPageNum // номер страницы для сравнения
- );
- // __flash_hal__autopagerewrite - обновление страницы через буфер 1
- static void __flash_hal__autopagerewrite1( __FLASH_WORD wPageNum // номер обновляемой страницы
- );
- // __flash_hal__autopagerewrite - обновление страницы через буфер 2
- static void __flash_hal__autopagerewrite2( __FLASH_WORD wPageNum // номер обновляемой страницы
- );
- // __flash_hal__sleepmode - переход в режим пониженного энергопотребления
- // # переводит устройство в режим, когда все команды, кроме __flash_hal__wakeup игнорируются
- static void __flash_hal__sleepmode();
- // __flash_hal__wakeup - выход из режима пониженного энергопотребления
- // # выводит устройство из режима, когда все команды, кроме __flash_hal__wakeup игнорируются
- static void __flash_hal__wakeup();
- // __flash_hal__manufactureridread - чтение идентификатора производителя
- // * возвращаемое значение - первые 4 байта структуры __flash_id_t
- __FLASH_DWORD __flash_hal__manufactureridread( __flash_id_t * pManufacturerID // необязательный параметр-буфер для приема расширенной информации
- );
- // __flash_hal__writeprotect_enable - включить программную защиту от записи/стирания
- static void __flash_hal__writeprotect_enable();
- // __flash_hal__writeprotect_disable - выключить программную защиту от записи/стирания
- static void __flash_hal__writeprotect_disable();
- // __flash_hal__protectregister_erase - стирает регистр защиты, помечая ВСЕ сектора как защищенные
- // # если включена программная защита от записи, все операции стирания/записи для всех секторов будут заблокированы до ее отключения
- static void __flash_hal__protectregister_erase();
- // __flash_hal__protectregister_write - записывает регистр защиты
- static void __flash_hal__protectregister_write( __flash_protectionregister_t * contents // содержимое регистра защиты для записи
- );
- // __flash_hal__protectregister_read - прочитывает регистр защиты
- static void __flash_hal__protectregister_read( __flash_protectionregister_t * contents // буфер-приемник содержимого регистра защиты
- );
- // __flash_hal__sectorlockdown - постоянная блокировка сектора от записи/стирания
- static void __flash_hal__sectorlockdown( __FLASH_DWORD address // адрес внутри блокируемого сектора
- );
- // __flash_hal__lockdownregister_read - прочитывает регистр блокировки
- static void __flash_hal__lockdownregister_read( __flash_lockdownregister_t * contents // буфер-приемник содержимого регистра блокировки
- );
- // __flash_hal__securityregister_write - записывает регистр безопасности
- // * записывает только ПОЛЬЗОВАТЕЛЬСКУЮ часть
- // # РЕГИСТР БЕЗОПАСНОСТИ МОЖЕТ БЫТЬ ЗАПИСАН ТОЛЬКО ОДИН РАЗ!
- static void __flash_hal__securityregister_write( __flash_usersecurityregister_t * contents // содержимое регистра безопасности (часть, доступная для записи пользователю)
- );
- // __flash_hal__securityregister_read - прочитывает регистр безопасности
- static void __flash_hal__securityregister_read( __flash_securityregister_t * contents // буфер-приемник содержимого регистра блокировки
- );
- // __flash_hal__securityregister_validate - прочитывает регистр безопасности и выполняет
- // проверку осмысленности прочитанного заводского идентификатора.
- static bool __flash_hal__securityregister_validate( __flash_securityregister_t * contents // буфер-приемник содержимого регистра блокировки
- );
- // __flash_hal__getprotectstate - получение состояния общего бита защиты
- static flash_err_t __flash_hal__getprotectstate( );
- // __flash_hal__getreadyfast - проверка занятости без ожидания
- static flash_err_t __flash_hal__getreadyfast( );
- // __flash_hal__getcompareresult - проверка результата сравнения (бит COMP / bMismatch)
- static flash_err_t __flash_hal__getcompareresult( );
- // __flash_hal__initialize - Низкоуровневая инициализация флешпамяти );
- // # возвращает 0, если все успешно, или код ошибки
- static flash_err_t __flash_hal__initialize();
- // __flash_hal__dirtyDetect - Упрощенное низкоуровневое определение наличия чипа (доступности)
- // Используется для обнаружения состояния чипа (Standby/Sleep)
- static flash_err_t __flash_hal__dirtyDetect();
- // __flash_hal__startupDetect - Низкоуровневое определение наличия чипа (доступности)
- // Используется верхним уровнем API для определения модели установленного чипа памяти
- static flash_err_t __flash_hal__startupDetect();
- // служебные функции доступа к памяти драйвера
- //
- static __flash_protectionregister_t * __flash_internal_getbuffer_protect();
- // служебная функция для проверки готовности чипа
- static int __flash_smart_waitms( __FLASH_WORD wTimems );
- #if AT45DBXXX_POWER_MANAGEMENT > 0
- // __flash_hal__power_on - реализует управление питанием микросхемы памяти (подает питание)
- static void __flash_hal__power_on();
- // __flash_hal__power_off - реализует управление питанием микросхемы памяти (снимает питание)
- static void __flash_hal__power_off();
- // __flash_hal__power_pulse - реализует управление питанием микросхемы - формирует импульс перезагрузки
- static void __flash_hal__power_pulse( __FLASH_WORD nCooldownTime_ms, __FLASH_WORD nStartupTime_ms );
- #endif
- #if AT45DBXXX_RESET_MANAGEMENT > 0
- // __flash_hal__reset_assert - реализует управление сигналом сброса микросхемы памяти (устанавливает сигнал сброса)
- static void __flash_hal__reset_assert();
- // __flash_hal__reset_release - реализует управление сигналом сброса микросхемы памяти (снимает сигнал сброса)
- static void __flash_hal__reset_release();
- // __flash_hal__reset_pulse - реализует управление сигналом сброса микросхемы памяти (подает законченный импульс сброса)
- static void __flash_hal__reset_pulse();
- #endif
- // __flash_hal__finalize_prepare - Низкоуровневая функция для подготовки флешпамяти к деинициализации драйвера
- static flash_err_t __flash_hal__finalize_prepare();
- // ########################################################################################################
- // Глобальные переменные
- const AT45_LL_Routines_t AT45_LL_Routines =
- {
- .statusread = __flash_hal__statusread,
- .page_read = __flash_hal__page_read,
- #ifndef AT45DB161E_EMU512
- .array_read = __flash_hal__array_read,
- #endif
- #ifdef AT45DB161E_PRM512
- #ifndef AT45DB161E_EMU512
- .use512page = __flash_hal__use512page,
- #endif
- #endif
- .buffer1_read = __flash_hal__buffer1_read,
- .buffer2_read = __flash_hal__buffer2_read,
- .buffer1_read_slow = __flash_hal__buffer1_read_slow,
- .buffer2_read_slow = __flash_hal__buffer2_read_slow,
- .buffer1_write = __flash_hal__buffer1_write,
- .buffer2_write = __flash_hal__buffer2_write,
- .buffer1_program = __flash_hal__buffer1_program,
- .buffer2_program = __flash_hal__buffer2_program,
- .buffer1_program_wo_erase = __flash_hal__buffer1_program_wo_erase,
- .buffer2_program_wo_erase = __flash_hal__buffer2_program_wo_erase,
- .page_erase = __flash_hal__page_erase,
- .block_erase = __flash_hal__block_erase,
- .sector0_erase = __flash_hal__sector0_erase,
- .sector_erase = __flash_hal__sector_erase,
- .page_write_via_buffer1 = __flash_hal__page_write_via_buffer1,
- .page_write_via_buffer2 = __flash_hal__page_write_via_buffer2,
- .pagetobuffer1 = __flash_hal__pagetobuffer1,
- .pagetobuffer2 = __flash_hal__pagetobuffer2,
- .buffer1_compare = __flash_hal__pagetobuffer1,
- .buffer2_compare = __flash_hal__pagetobuffer2,
- .autopagerewrite1 = __flash_hal__autopagerewrite1,
- .autopagerewrite2 = __flash_hal__autopagerewrite2,
- .sleepmode = __flash_hal__sleepmode,
- .wakeup = __flash_hal__wakeup,
- .manufactureridread = __flash_hal__manufactureridread,
- .writeprotect_enable = __flash_hal__writeprotect_enable,
- .writeprotect_disable = __flash_hal__writeprotect_disable,
- .protectregister_erase = __flash_hal__protectregister_erase,
- .protectregister_write = __flash_hal__protectregister_write,
- .protectregister_read = __flash_hal__protectregister_read,
- .sectorlockdown = __flash_hal__sectorlockdown,
- .lockdownregister_read = __flash_hal__lockdownregister_read,
- .securityregister_write = __flash_hal__securityregister_write,
- .securityregister_read = __flash_hal__securityregister_read,
- .securityregister_validate = __flash_hal__securityregister_validate,
- .getprotectstate = __flash_hal__getprotectstate,
- .getreadyfast = __flash_hal__getreadyfast,
- .getcompareresult = __flash_hal__getcompareresult,
- .startupDetect = __flash_hal__startupDetect,
- .initialize = __flash_hal__initialize,
- .dirtyDetect = __flash_hal__dirtyDetect,
- .internal_getbuffer_protect = __flash_internal_getbuffer_protect,
- .smart_waitms = __flash_smart_waitms,
- #if AT45DBXXX_POWER_MANAGEMENT > 0
- .power_on = __flash_hal__power_on,
- .power_off = __flash_hal__power_off,
- .power_pulse = __flash_hal__power_pulse,
- #endif
- #if AT45DBXXX_RESET_MANAGEMENT > 0
- .reset_assert = __flash_hal__reset_assert,
- .reset_release = __flash_hal__reset_release,
- .reset_pulse = __flash_hal__reset_pulse,
- #endif
- .finalize_prepare = __flash_hal__finalize_prepare,
- };
- #pragma pack( push, 1 )
- #ifdef AT45DBXXX_FLASH_RAM_PLACE
- _PLACEIN( AT45DBXXX_FLASH_RAM_PLACE )
- #endif
- static union /* __flash_global */
- {
- __FLASH_BYTE alloc_place[ __FLASH_LL_SVCMEM_SIZE ];
- struct /* __flash_var */
- {
- // __FLASH_BYTE pagebuffer[ __FULL_PAGE_SIZE ]; // НЕ ТРЕБУЕТСЯ! буфер под чтение/запись страниц
- union
- {
- __FLASH_BYTE protectbuffer[ __SECTORS_TYPICAL ]; // буфер под чтение/запись байтов защиты секторов
- __flash_protectionregister_t protectionregister;
- };
- __FLASH_BYTE cmdbuffer [ __FLASH_LL_COMMAND_MAXSIZE ]; // буфер для выполения команд
- };
- };
- #pragma pack( pop )
- __flash_protectionregister_t * __flash_internal_getbuffer_protect() { return &protectionregister; }
- // ########################################################################################################
- // ########################################################################################################
- // ########################################################################################################
- // ########################################################################################################
- // ########################################################################################################
- // ########################################################################################################
- // служебные функции управления CS
- // установка сигнала ChipSelect в активное состояние
- static inline void chip_sel_active()
- {
- __FLASH_HAL_CS_LO();
- __FLASH_WAITus(_TIME_CSCLR_us);
- }
- // установка сигнала ChipSelect в неактивное состояние
- static inline void chip_sel_inactive()
- {
- __FLASH_WAITus(_TIME_CSSET_us);
- __FLASH_HAL_CS_HI();
- __FLASH_WAITus(_TIME_CSHLD_us); // минимальное время между командами
- }
- #ifndef __imp_ssp_io_rev
- // Функция обращения порядка байтов и передачи по SPI
- //
- // @count не может быть 0. Функция не проверяет параметр!
- static void __int_ssp_io_rev( __FLASH_BYTE * pBuffer, __FLASH_WORD count )
- {
- // обмениваем половину из count байт, т.к. вторая будет обменяна автоматически
- // вычитаем count-- чтобы прерватить count в индекс конеца буфера
- __FLASH_DWORD c = (count--) >> 1;
- // начианем обмен
- for( int i = 0; i < c; ++i )
- {
- // Обмениваем pBuffer[i] с pBuffer[count-i]
- pBuffer[i] ^= pBuffer[count-i];
- pBuffer[count-i] ^= pBuffer[i];
- pBuffer[i] ^= pBuffer[count-i];
- }
- // используем штатую функцию передачи байт по SPI
- __FLASH_HAL_WR( pBuffer, ++count );
- }
- #endif
- #if AT45DBXXX_NO_MS_DELAYS == 1
- // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
- // __int_sys_delayms - служебная функция ожидания в мс, если аналог отсутствует у пользователя.
- // Опция AT45DBXXX_NO_MS_DELAYS позволяет заменить задержку в мс на задержку в мкс.
- static inline void __int_sys_delayms( __FLASH_WORD timeout )
- {
- __imp_sys_delayus( timeout * 1000 );
- }
- #endif
- // --------------------------------------------------------------------------------------------------------
- // __flash_smart_waitms - комбинированая функция ожидания заданного количества миллисекунд с
- // проверкой состояния чипа на предмет того, занят он, или нет. Если не занят,
- // функция возвращает управление сразу же. Если занят все указанное время,
- // функция возвратит управление через указанный таймаут (не меньший, но, возможно, больший).
- //
- // * не изменяет содержимое внутренних SRAM буферов
- // * использует системные вызовы для определения количества прошедшего времени
- // * потоко-небезопасная функция
- // * производит опрос чипа командой "Запрос статусного регистра" (Status Register Read)
- // * функция использует вызов функций бесконечного чтения статуса
- //
- static void __flash_hal__part_statusread_stage1( __flash_status_t * pcReadRegister );
- static void __flash_hal__part_statusread_stage2( __flash_status_t * pcReadRegister );
- static void __flash_hal__part_statusread_stage3( __flash_status_t * pcReadRegister );
- //
- // * функция возвращает 1, если достоверно известно, что флаг BUSY сброшен (устройство готово), иначе 0 (требуется повторная проверка)
- //
- static int __flash_smart_waitms( __FLASH_WORD wTimems )
- {
- __flash_status_t r_status; // статус-регистр
- __flash_hal__part_statusread_stage1( &r_status ); // начинаем считывать
- // -- -- -- -- -- -- для коротких задержек -- -- -- -- -- -- -- -- -- --
- #ifdef AT45DB161E_CHECKSTATUS_DENSITYCODE
- #if AT45DB161E_CHECKSTATUS_DENSITYCODE == 1
- if ( r_status.cDensity == __FLASH_STATUS_DENSITY_SIGN ) // Дополнительная проверка на код Density
- #endif
- #endif
- if ( r_status.bReady ) // сразу проверяем, если устройство свободно, возвращаем управление
- {
- __flash_hal__part_statusread_stage3( 0 ); // завершаем чтение регистра
- return 1;
- }
- if ( wTimems < AT45DBXXX_SMART_WAIT_THRESHOLD ) // для малых времен ожидания накладно опрашивать чип постоянно
- {
- __FLASH_WAITms(wTimems); // выжидаем указанное время
- __flash_hal__part_statusread_stage3( &r_status ); // проверяем регистр
- #ifdef AT45DB161E_CHECKSTATUS_DENSITYCODE
- #if AT45DB161E_CHECKSTATUS_DENSITYCODE == 1
- if ( r_status.cDensity == __FLASH_STATUS_DENSITY_SIGN ) // Дополнительная проверка на код Density
- #endif
- #endif
- if ( r_status.bReady ) // если свободно - вернем 1
- return 1;
- return 0; // если занято - вернем 0
- }
- // -- -- -- -- -- -- для длинных задержек -- -- -- -- -- -- -- -- -- --
- __FLASH_DWORD dwStartCounter = __FLASH_SMART_GETTIMER(); // получаем отметку времени
- for(/*|*/ __FLASH_DWORD dwDeltaCounter = 0; // счетчик задержки
- /*|*/ dwDeltaCounter < wTimems; // проверяем, задержались ли мы на указанное время или еще нет
- /*|*/ dwDeltaCounter = ( __FLASH_SMART_GETTIMER() - dwStartCounter ) ) // обновляем счетчик задержки
- {
- __flash_hal__part_statusread_stage2( &r_status ); // читаем статус
- #ifdef AT45DB161E_CHECKSTATUS_DENSITYCODE
- #if AT45DB161E_CHECKSTATUS_DENSITYCODE == 1
- if ( r_status.cDensity == __FLASH_STATUS_DENSITY_SIGN ) // Дополнительная проверка на код Density
- #endif
- #endif
- if ( r_status.bReady ) // проверяем, не освободился ли чип?
- {
- __flash_hal__part_statusread_stage3( 0 ); // да, освободился, завершаем чтение
- return 1; // возвращаем 1 (освободился)
- }
- __FLASH_WAITms(1); // выжидаем квант времени
- }
- __flash_hal__part_statusread_stage3( &r_status ); // время вышло, завершаем чтение
- if ( r_status.bReady ) // последний раз проверяем статус
- return 1; // свободен!
- return 0; // чип до сих пор занят
- }
- // ########################################################################################################
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__part_statusread - группа скрытых низкоуровневых функций, позволяющая осуществлять постоянное сканирование регистра
- // статуса. Чип предоставляет возможность считывать регистр статуса без отправки команды на чтение при повторном чтении,
- // до установки CS в неактивное положение. Т.О возможно передать команду один раз, затем читать статус бесконечно.
- // Функции должны вызываться в порядке нумерации, при этом стадия 2 может быть пропущена. Функии проверяют параметр
- // pcReadRegister на NULL, если он отличен от NULL, считывают в него содержмое регистра, иначе ничего не считывают.
- // Пример ожидания завершения операции стирания:
- // [code]
- //
- // __flash_status_t status; // статус-регистр
- //
- // __flash_hal_pageerase( 0 ); // стираем 0 страницу
- // __flash_hal__part_statusread_stage1( &status ); // иницируем чтение статуса
- //
- // while( !status.bReady )
- // __flash_hal__part_statusread_stage2( &status ); // повторяем чтение статуса
- //
- // __flash_hal__part_statusread_stage3( 0 ); // завершаем чтение статуса
- //
- // [/code]
- // __flash_hal__part_statusread_stage1 - 1 стадия (начальная) команды бесконечного чтения статуса занятости
- // __flash_hal__part_statusread_stage2 - 2 стадия (промежуточная) команды бесконечного чтения статуса занятости
- // __flash_hal__part_statusread_stage3 - 3 стадия (заключительная) команды бесконечного чтения статуса занятости
- //
- // * потоко-небезопасная функция
- // * НЕ задерживает выполнение: требуется внешний цикл для организации сканирования
- static void __flash_hal__part_statusread_stage1( __flash_status_t * pcReadRegister )
- {
- chip_sel_active();
- ( (__flash_packet_statusread_t*) cmdbuffer )->opcode = _ACMD_STATREAD;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_statusread_t) );
- if( pcReadRegister )
- // читаем регистр
- __FLASH_HAL_RD( pcReadRegister, sizeof(__flash_status_t) );
- }
- //----- ------- ------ ------ ------ ------- ------
- static void __flash_hal__part_statusread_stage2( __flash_status_t * pcReadRegister )
- {
- if( pcReadRegister )
- // читаем регистр
- __FLASH_HAL_RD( pcReadRegister, sizeof(__flash_status_t) );
- }
- //----- ------- ------ ------ ------ ------- ------
- static void __flash_hal__part_statusread_stage3( __flash_status_t * pcReadRegister )
- {
- if( pcReadRegister )
- // читаем регистр
- __FLASH_HAL_RD( pcReadRegister, sizeof(__flash_status_t) );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // ########################################################################################################
- // __flash_hal__getpagesize - получение размера страницы 512/528 байт
- //
- static __flash_pagesize_t __flash_hal__getpagesize( )
- {
- __flash_status_t status;
- __flash_hal__statusread( &status );
- if( status.bPageSize == __fps_512 )
- return __fps_512;
- return __fps_528;
- }
- // --------------------------------------------------------------------------------------------------------
- // ########################################################################################################
- // __flash_hal__getreadyfast - проверка занятости без ожидания
- //
- // # Возвращаемое значение: FLERR_SUCCESS если свободен, иначе FLERR_TIMEOUT
- static flash_err_t __flash_hal__getreadyfast( )
- {
- __flash_status_t status;
- __flash_hal__statusread( &status );
- if( status.bReady )
- return FLERR_SUCCESS;
- return FLERR_TIMEOUT;
- }
- // --------------------------------------------------------------------------------------------------------
- // ########################################################################################################
- // __flash_hal__getcompareresult - проверка результата сравнения (бит COMP / bMismatch)
- //
- // # Возвращаемое значение: FLERR_SUCCESS если совпадает, иначе FLERR_VERIFY_ERROR
- static flash_err_t __flash_hal__getcompareresult( )
- {
- __flash_status_t status;
- __flash_hal__statusread( &status );
- if( status.bMismatch )
- return FLERR_VERIFY_ERROR;
- return FLERR_SUCCESS;
- }
- // --------------------------------------------------------------------------------------------------------
- // ########################################################################################################
- // __flash_hal__getprotectstate - получение состояния общего бита защиты
- //
- // # Возвращаемое значение - FLERR_PROTECT_ENABLED, если бит защиты установлен, иначе FLERR_PROTECT_DISABLED
- static flash_err_t __flash_hal__getprotectstate( )
- {
- __flash_status_t status;
- __flash_hal__statusread( &status );
- if( status.bProtect )
- return FLERR_PROTECT_ENABLED;
- return FLERR_PROTECT_DISABLED;
- }
- // --------------------------------------------------------------------------------------------------------
- // ########################################################################################################
- // __flash_hal__dirtyDetect - Низкоуровневое определение наличия чипа (доступности)
- // Используется для обнаружения состояния чипа (Standby/Sleep)
- static flash_err_t __flash_hal__dirtyDetect()
- {
- // сначала пытаемся прочитать идентификатор:
- // чтение регистра информации
- __FLASH_DWORD flashID = __flash_hal__manufactureridread( 0 );
- // определяем наличие флешки по идентификатору
- if( ((__flash_rvid_t*) &flashID)->FullId == __FLASH_INVALID_ID )
- {
- // похоже, что чипа нет, обнаружить не удалось
- return FLERR_LL_INITFAIL_NOTFOUND;
- }
- // еще не все, нужно убедиться, что устройство отвечает:
- // читаем статус
- if( ! __flash_smart_waitms( AT45DBXXX_API_TIMEOUT ) )
- {
- // либо статус не читается, либо устройство занято.
- // т.к. функция предназначена для использования во время инициализации,
- // предполагается, что чип должен быть свободен.
- // Поэтому возвращаем ошибку
- return FLERR_UNEXPECTED_BUSY;
- }
- return FLERR_SUCCESS;
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // ########################################################################################################
- // __flash_hal__finalize_prepare - Низкоуровневая функция для подготовки флешпамяти к деинициализации драйвера
- // Выполняет действия, направленные на завершение работы с флешпамятью и подготовки ее к выключению
- // Вызывается в момент окончательной остановки работы с флешпамятью
- static flash_err_t __flash_hal__finalize_prepare()
- {
- // Сначала требуется проверить режим защиты записи:
- // если разрешено управление аппаратным сигналом защиты записи
- #if AT45DBXXX_HW_WR_PROTECT
- // если аппаратная защита записи отключена в настройках
- #if AT45DBXXX_HW_WR_PROTECT_KEEPUNPROTECTED == 1
- // требуется установить аппаратную защиту записи после деинициализации драйвера
- __imp_flash_hwwrprotect_assert();
- #endif
- #endif
- // Потом проверяем статус готовности
- if( ! (__flash_smart_waitms( AT45DBXXX_API_TIMEOUT ) ) )
- {
- // устройство занято.
- return FLERR_UNEXPECTED_BUSY;
- }
- return FLERR_SUCCESS;
- }
- // --------------------------------------------------------------------------------------------------------
- static void __flash_hal__use512page();
- // --------------------------------------------------------------------------------------------------------
- // ########################################################################################################
- // __flash_hal__initialize - Низкоуровневое детектирование чипа флешпамяти
- // Производит начальную настройку аппаратуры для возможности определения наличия чипа на шине
- static flash_err_t __flash_hal__startupDetect()
- {
- // если разрешено управление питанием
- #if AT45DBXXX_POWER_MANAGEMENT
- // подать питание на микросхему
- __flash_hal__power_on();
- __FLASH_WAITus( _TIME_STRUP_us );
- #endif
- // если разрешено управление питанием
- #if AT45DBXXX_RESET_MANAGEMENT
- // снять сигнлал сброса с чипа
- __flash_hal__reset_release();
- __FLASH_WAITus( _TIME_RSTRC_us );
- #endif
- // пробуждаем чип, если тот находится в режиме сна
- // иначе он не будет воспринимать команды.
- // Неизвестно, был ли чип в режиме гибернации, но это не важно
- __flash_hal__wakeup();
- // предварительный таймаут запуска - ждем максимальное время до готовности записи во флеш
- __FLASH_WAITms( _TIME_START_ms );
- // производится несколько две попытки достучаться до чипа
- flash_err_t dirty_status = FLERR_GENERIC_ERROR;
- for( size_t attempt = 0; attempt < 2; ++attempt )
- {
- // пробуем "грязное" чтение идентификатора.
- // Результат чтения не сохраняется, требуется обнаружить
- // лишь присуствие на шине и определить готовность
- // Поэтому как остуствие на шине, так и занятость чипа расценивается
- // как ошибка.
- dirty_status = __flash_hal__dirtyDetect();
- if( FLASH_ERROR(dirty_status) )
- {
- // если первая попытка провалена, и __flash_hal__dirtyDetect после сброса
- // дает ошибку - значит возвращаем ошибку
- if( attempt > 0 )
- return dirty_status;
- // если разрешено управление сигналом сброса
- #if AT45DBXXX_RESET_MANAGEMENT
- // Формируем импульс сброса:
- __flash_hal__reset_pulse();
- #else
- // управление сигналом сброса недоступно
- // а управление питанием доступно?
- #if AT45DBXXX_POWER_MANAGEMENT
- // Формируем импульс подачи питания
- __flash_hal__power_pulse( _TIME_COOLDOWN_ms, _TIME_START_ms );
- #else
- // Проверка доступности вернула ошибку.
- // Управление питанием и сигналом сброса недоступно
- // Возвращаем ошибку
- return dirty_status;
- #endif
- #endif
- } else break;
- }
- if( FLASH_ERROR(dirty_status) )
- return dirty_status;
- // чтение регистра информации
- __FLASH_DWORD flashID = __flash_hal__manufactureridread( 0 );
- // определяем наличие флешки по идентификатору
- if( ((__flash_rvid_t*) &flashID)->FullId == __FLASH_INVALID_ID )
- {
- return FLERR_LL_INITFAIL_NOTFOUND;
- }
- __flash_securityregister_t securityRegister;
- if( !__flash_hal__securityregister_validate( &securityRegister ) )
- {
- // похоже, что чипа нет, обнаружить не удалось
- return FLERR_LL_INITFAIL_NOTFOUND;
- }
- // проверяем ID производителя
- #ifdef AT45DBXXX_FLASH_DESIRED_ID
- if( ((__flash_rvid_t*) &flashID)->LowId != AT45DBXXX_FLASH_DESIRED_ID )
- {
- return FLERR_LL_INITFAIL_WRONGID;
- }
- #endif
- // проверяем вместимость чипа
- #ifdef AT45DBXXX_FLASH_DESIRED_DENSITY
- if( ((__flash_rvid_t*) &flashID)->DevId.Density != AT45DBXXX_FLASH_DESIRED_DENSITY )
- {
- return FLERR_LL_INITFAIL_WRONGDENSITY;
- }
- #endif
- // проверяем семейство чипа
- #ifdef AT45DBXXX_FLASH_DESIRED_FAMILY
- if( ((__flash_rvid_t*) &flashID)->DevId.Family != AT45DBXXX_FLASH_DESIRED_FAMILY )
- {
- return FLERR_LL_INITFAIL_WRONGFAMILY;
- }
- #endif
- return FLERR_SUCCESS;
- }
- // --------------------------------------------------------------------------------------------------------
- // ########################################################################################################
- // __flash_hal__initialize - Низкоуровневая инициализация драйвера флешпамяти
- //
- // * определение наличия подключенной микросхемы
- // * чтение идентификатора и определение производителя
- // * контроль правильности:
- // - идентификатора производителя
- // - типа устройства, семейства (DevId)
- // - размера чипа
- // * установка и проверка размера страницы
- //
- // # Возвращаемое значние - код выполнения
- static flash_err_t __flash_hal__initialize()
- {
- // первичная инициализация шины и чипа
- flash_err_t detectStatus = __flash_hal__startupDetect();
- if( FLASH_ERROR(detectStatus) )
- return detectStatus;
- // если разрешено управление аппаратным сигналом защиты записи
- #if AT45DBXXX_HW_WR_PROTECT
- // если аппаратная защита записи отключена в настройках
- #if AT45DBXXX_HW_WR_PROTECT_KEEPUNPROTECTED == 1
- // требуется снять аппаратную защиту записи на всё время работы драйвера
- __imp_flash_hwwrprotect_release();
- #endif
- #endif
- // определить размер страницы: если выбран AT45DB161E_EMU512, а во флешке AT45DB161E_PRM512 - лочимся
- // установить размер страницы если выбран AT45DB161E_PRM512
- #ifdef AT45DB161E_PRM512
- // выбран режим страницы 512.
- // перепрограммируем чип на страницы по 512 байт.
- // операция не отменяемая, чип программируется один раз.
- // проверяем текущий размер страницы.
- if( __fps_512 != __flash_hal__getpagesize();
- {
- // если 528 - перепрограммируем
- __flash_hal__use512page();
- #if AT45DB161E_BKGOPERATIONS
- __FLASH_SMART_WAITms(_TIME_PGPRG_ms);
- #endif
- // для изменения размера страницы по документации требуется
- // отключить питание чипа и подать снова.
- #if AT45DBXXX_POWER_MANAGEMENT
- // если доступно управление питанием, используем его
- __flash_hal__power_pulse( _TIME_COOLDOWN_ms, _TIME_START_ms );
- #else
- // если управление питанием недоступно, используем callback-процедуру пользователя
- // функция вызывается для отключения питания чипа в случае если программа
- // обнаруживает, что установлен режим не 512 байт. Сначала функция __flash_hal__use512page
- // переключает размер страницы, затем вызывает эту функцию.
- __imp_flash_powercycle();
- // ожидание готовности запуска
- __FLASH_WAITms( _TIME_START_ms );
- #endif
- }
- // # для применения нового размера требуется ОТКЛЮЧЕНИЕ ПИТАНИЯ!
- // проверяем текущий размер страницы.
- if( __fps_512 != __flash_hal__getpagesize();
- {
- // Ошибку выдаем: просили установить 512 байт, но не сработало.
- return FLERR_LL_INITFAIL_PAGESIZE;
- }
- #else
- #ifdef AT45DB161E_EMU512
- // выбран режим ЭМУЛЯЦИИ страниц по 512 байт
- // Если в чипе прошит размер 512 байт, то это уже не эмуляция.
- if( __fps_512 == __flash_hal__getpagesize() )
- {
- // Но ошибку не выдаем, т.к. все должно работать.
- }
- #else
- // выбран обычный режим без эмуляции размера страницы 512 байт.
- // предполагается использование странцы 528 байт.
- if( __fps_512 == __flash_hal__getpagesize() )
- {
- // в чипе прошит размер 512 - выдем ошибку, т.к. невозможно перенастроить чип
- return FLERR_LL_INITFAIL_PAGESIZE;
- }
- #endif
- #endif
- return FLERR_SUCCESS;
- }
- // ########################################################################################################
- // ########################################################################################################
- // ########################################################################################################
- // ########################################################################################################
- // ########################################################################################################
- // ########################################################################################################
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__statusread - чтение регистра статуса
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * НЕ задерживает выполнение
- static void __flash_hal__statusread( __flash_status_t * pcReadRegister // буфер для чтения статус-регистра
- )
- {
- chip_sel_active();
- ( (__flash_packet_statusread_t*) cmdbuffer )->opcode = _ACMD_STATREAD;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_statusread_t) );
- // читаем регистр
- __FLASH_HAL_RD( pcReadRegister, sizeof(__flash_status_t) );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__page_read - чтение одной страницы
- //
- // * не изменяет содержимое внутренних SRAM буферов
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- //
- static void __flash_hal__page_read( __FLASH_WORD wPageNum, // номер страницы для чтения
- __FLASH_WORD wPageOfs, // адрес начала чтения в странице
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ) // количество данных на чтение
- {
- chip_sel_active();
- ( (__flash_packet_pageread_t*) cmdbuffer )->opcode = _RCMD_PAGEREAD;
- ( (__flash_packet_pageread_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_pageread_t*) cmdbuffer )->offset = wPageOfs;
- ( (__flash_packet_pageread_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_pageread_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pageread_t) );
- // читаем данные
- __FLASH_HAL_RD( pDataRead, wCntToRead );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- #ifndef AT45DB161E_EMU512
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__array_read - последовательное чтение (массив)
- //
- // * не изменяет содержимое внутренних SRAM буферов
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * недоступна в режиме программной эмуляции 512-байтных страниц (AT45DB161E_EMU512)
- static void __flash_hal__array_read ( __FLASH_WORD wPageNum, // номер начальной страницы для чтения
- __FLASH_WORD wPageOfs, // адрес начала чтения в начальной странице
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ) // количество данных на чтение
- {
- chip_sel_active();
- ( (__flash_packet_arrayread_t*) cmdbuffer )->opcode = _RCMD_ARRYREAD;
- ( (__flash_packet_arrayread_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_arrayread_t*) cmdbuffer )->offset = wPageOfs;
- ( (__flash_packet_arrayread_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_arrayread_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_arrayread_t) );
- // читаем данные
- __FLASH_HAL_RD( pDataRead, wCntToRead );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- #else
- #warning В режиме эмуляции страницы 512 байт функция последовательного чтения недоступна.
- // Эмуляция размера страницы в 512 байт достигается неполной записью и неполным чтением страницы микросхемы.
- // При этом операции чтения/записи буферизируются драйвером памяти таким образом, что для программы высокого
- // уровня этот процесс остается прозрачным. Однако команда последовательного чтения использует иной алгоритм
- // чтения: автоматическое инкрементирование указателя чтения без буферизации. Таким образом при использовании
- // команды последовательного чтения в режиме эмуляции на каждую читаемую страницу будет приходиться дополнительные
- // 16 байт мусорной информации, сохраненной в чипе, но никогда не перезаписываемой драйвером (в режиме эмуляции).
- // Поэтому без специальной обработки (прореживания) команда не имеет смысла - вместо прореживания используется
- // повторная передача адреса уже следующей страницы на чтение. Таким образом осуществляется чтение больших
- // объемов данных в режиме эмуляции.
- //
- // Реальное положение page N page N+1 page N+2 ......
- // дел. Распределение +----------+----------+----------+
- // данных по страницам. | 512 | 16 | 512 | 16 | 512 | 16 | ....
- // +----------+----------+----------+
- // \ \ | | / /
- // \ \ | | / /
- // ----------------------------------------------------------------------------------
- // \ \| |/ /
- // Эмуляция размера страниц +-----+-----+-----+ Так представляются страницы чипа в режиме
- // режим эмуляции 512 байт. | 512 | 512 | 512 | эмуляции. Однако последовательное чтение
- // +-----+-----+-----+ выдает 16 байтное дополнение м/у ними.
- // page N page N+2
- // page N+1
- #endif
- #ifdef AT45DB161E_PRM512
- #ifndef AT45DB161E_EMU512
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__use512page - сконфигурировать чип на работу со стандартной страницей 512 байт
- //
- // # НАВСЕГДА изменяет размер страницы!
- // * потоко-небезопасная функция
- // * недоступна в режиме программной эмуляции 512-байтных страниц (AT45DB161E_EMU512)
- // # для применения нового размера требуется ОТКЛЮЧЕНИЕ ПИТАНИЯ!
- static void __flash_hal__use512page()
- {
- chip_sel_active();
- ( (__flash_packet_pagecnfg_t*) cmdbuffer )->opcode = _PCMD_PGSZCNFG;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pagecnfg_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms(_TIME_PGPRG_ms);
- #endif
- }
- #endif
- #endif
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer1_read - чтение буфера 1 (up to 66 MHz)
- //
- // * не изменяет содержимое внутренних SRAM буферов
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- static void __flash_hal__buffer1_read( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ) // количество данных на чтение
- {
- chip_sel_active();
- ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->opcode = _RCMD_BUF1READ;
- ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->offset = wBuffOfs;
- ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferread_fast_t) );
- // читаем данные
- __FLASH_HAL_RD( pDataRead, wCntToRead );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer2_read - чтение буфера 2 (up to 66 MHz)
- //
- // * не изменяет содержимое внутренних SRAM буферов
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- static void __flash_hal__buffer2_read( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ) // количество данных на чтение
- {
- chip_sel_active();
- ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->opcode = _RCMD_BUF2READ;
- ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->offset = wBuffOfs;
- ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_bufferread_fast_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferread_fast_t) );
- // читаем данные
- __FLASH_HAL_RD( pDataRead, wCntToRead );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer1_read_slow - чтение буфера 1 (up to 33 MHz)
- //
- // * не изменяет содержимое внутренних SRAM буферов
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- static void __flash_hal__buffer1_read_slow( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ) // количество данных на чтение
- {
- chip_sel_active();
- ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->opcode = _RCMD_BUF1READ;
- ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->offset = wBuffOfs;
- ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->__reserved = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferread_slow_t) );
- // читаем данные
- __FLASH_HAL_RD( pDataRead, wCntToRead );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer2_read_slow - чтение буфера 2 (up to 33 MHz)
- //
- // * не изменяет содержимое внутренних SRAM буферов
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- static void __flash_hal__buffer2_read_slow( __FLASH_WORD wBuffOfs, // адрес начала чтения в буфере
- __FLASH_BYTE * pDataRead, // указатель на буфер-приемник данных
- __FLASH_WORD wCntToRead ) // количество данных на чтение
- {
- chip_sel_active();
- ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->opcode = _RCMD_BUF2READ;
- ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->offset = wBuffOfs;
- ( (__flash_packet_bufferread_slow_t*) cmdbuffer )->__reserved = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferread_slow_t) );
- // читаем данные
- __FLASH_HAL_RD( pDataRead, wCntToRead );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer1_write - запись буфера 1
- //
- // * ИЗМЕНЯЕТ содержимое внутренних SRAM буферов
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- static void __flash_hal__buffer1_write( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
- __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
- __FLASH_WORD wCntToWrite ) // количество данных на запись
- {
- chip_sel_active();
- ( (__flash_packet_bufferwrite_t*) cmdbuffer )->opcode = _WCMD_BUF1WRIT;
- ( (__flash_packet_bufferwrite_t*) cmdbuffer )->offset = wBuffOfs;
- ( (__flash_packet_bufferwrite_t*) cmdbuffer )->__reserved = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferwrite_t) );
- // пишем данные
- __FLASH_HAL_WR( pDataWrite, wCntToWrite );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer2_write - запись буфера 2
- //
- // * ИЗМЕНЯЕТ содержимое внутренних SRAM буферов
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- static void __flash_hal__buffer2_write( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
- __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
- __FLASH_WORD wCntToWrite ) // количество данных на запись
- {
- chip_sel_active();
- ( (__flash_packet_bufferwrite_t*) cmdbuffer )->opcode = _WCMD_BUF2WRIT;
- ( (__flash_packet_bufferwrite_t*) cmdbuffer )->offset = wBuffOfs;
- ( (__flash_packet_bufferwrite_t*) cmdbuffer )->__reserved = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferwrite_t) );
- // пишем данные
- __FLASH_HAL_WR( pDataWrite, wCntToWrite );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer1_program - программирование буфера 1 в страницу со стиранием
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
- static void __flash_hal__buffer1_program( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- )
- {
- chip_sel_active();
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->opcode = _WCMD_BUF1PROG;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferprogram_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer2_program - программирование буфера 2 в страницу со стиранием
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
- static void __flash_hal__buffer2_program( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- )
- {
- chip_sel_active();
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->opcode = _WCMD_BUF2PROG;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferprogram_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer1_program_wo_erase - программирование буфера 1 в страницу без стирания
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ЕДИНИЦЫ МИЛЛИСЕКУНД
- static void __flash_hal__buffer1_program_wo_erase( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- )
- {
- chip_sel_active();
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->opcode = _WCMD_BUF1PRGx;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferprogram_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__buffer2_program_wo_erase - программирование буфера 2 в страницу без стирания
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ЕДИНИЦЫ МИЛЛИСЕКУНД
- static void __flash_hal__buffer2_program_wo_erase( __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- )
- {
- chip_sel_active();
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->opcode = _WCMD_BUF2PRGx;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_bufferprogram_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferprogram_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__page_erase - стирание страницы
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
- static void __flash_hal__page_erase( __FLASH_WORD wPageNum // номер стираемой страницы
- )
- {
- chip_sel_active();
- ( (__flash_packet_pageerase_t*) cmdbuffer )->opcode = _ECMD_PAGERASE;
- ( (__flash_packet_pageerase_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_pageerase_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_pageerase_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pageerase_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGERS_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__block_erase - стирание блока
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на СОТНИ МИЛЛИСЕКУНД
- static void __flash_hal__block_erase( __FLASH_WORD wBlockNum // номер стираемого блока
- )
- {
- chip_sel_active();
- ( (__flash_packet_blockerase_t*) cmdbuffer )->opcode = _ECMD_BLKERASE;
- ( (__flash_packet_blockerase_t*) cmdbuffer )->block = wBlockNum;
- ( (__flash_packet_blockerase_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_blockerase_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_blockerase_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_BKERS_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__sector0_erase - стирание секторов 0a и 0b
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на СЕКУНДЫ
- static void __flash_hal__sector0_erase( __FLASH_WORD wSubSector // номер подсектора 0 или 1
- )
- {
- chip_sel_active();
- ( (__flash_packet_sector0erase_t*) cmdbuffer )->opcode = _ECMD_SCTERASE;
- ( (__flash_packet_sector0erase_t*) cmdbuffer )->subsector = wSubSector;
- ( (__flash_packet_sector0erase_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_sector0erase_t*) cmdbuffer )->__reserved2 = 0;
- ( (__flash_packet_sector0erase_t*) cmdbuffer )->__reserved3 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_sector0erase_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_SCERS_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__sector_erase - стирание секторов с номером 1 и выше
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на СЕКУНДЫ
- static void __flash_hal__sector_erase( __FLASH_WORD wSector // номер сектора 1-63
- )
- {
- chip_sel_active();
- ( (__flash_packet_sectorerase_t*) cmdbuffer )->opcode = _ECMD_SCTERASE;
- ( (__flash_packet_sectorerase_t*) cmdbuffer )->sector = wSector;
- ( (__flash_packet_sectorerase_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_sectorerase_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_sectorerase_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_SCERS_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__page_write_via_buffer1 - запись страницы через буфер 1
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
- static void __flash_hal__page_write_via_buffer1( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
- __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
- __FLASH_WORD wCntToWrite, // количество данных на запись
- __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- )
- {
- chip_sel_active();
- ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->opcode = _WCMD_PGB1WRIT;
- ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->offset = wBuffOfs;
- ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->__reserved= 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pagewriteviabuffer_t) );
- // пишем данные
- __FLASH_HAL_WR( pDataWrite, wCntToWrite );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__page_write_via_buffer2 - запись страницы через буфер 2
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
- static void __flash_hal__page_write_via_buffer2( __FLASH_WORD wBuffOfs, // адрес начала записи в буфере-приемнике (чип)
- __FLASH_BYTE * pDataWrite, // указатель на буфер-источник данных
- __FLASH_WORD wCntToWrite, // количество данных на запись
- __FLASH_WORD wPageNum // номер страницы, куда произвести программирование
- )
- {
- chip_sel_active();
- ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->opcode = _WCMD_PGB2WRIT;
- ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->offset = wBuffOfs;
- ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_pagewriteviabuffer_t*) cmdbuffer )->__reserved= 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_pagewriteviabuffer_t) );
- // пишем данные
- __FLASH_HAL_WR( pDataWrite, wCntToWrite );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__pagetobuffer1 - загрузка содержимого страницы в буфер 1
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на СОТНИ МИКРОСЕКУНД
- static void __flash_hal__pagetobuffer1( __FLASH_WORD wPageNum // номер страницы для загрузки
- )
- {
- chip_sel_active();
- ( (__flash_packet_bufferload_t*) cmdbuffer )->opcode = _ACMD_BUF1LOAD;
- ( (__flash_packet_bufferload_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_bufferload_t*) cmdbuffer )->__reserved =0;
- ( (__flash_packet_bufferload_t*) cmdbuffer )->__reserved2=0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferload_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_WAITus( _TIME_BLDCM_us );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__pagetobuffer2 - загрузка содержимого страницы в буфер 2
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на СОТНИ МИКРОСЕКУНД
- static void __flash_hal__pagetobuffer2( __FLASH_WORD wPageNum // номер страницы для загрузки
- )
- {
- chip_sel_active();
- ( (__flash_packet_bufferload_t*) cmdbuffer )->opcode = _ACMD_BUF2LOAD;
- ( (__flash_packet_bufferload_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_bufferload_t*) cmdbuffer )->__reserved =0;
- ( (__flash_packet_bufferload_t*) cmdbuffer )->__reserved2=0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_bufferload_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_WAITus( _TIME_BLDCM_us );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__pagetobuffer1 - сравнение содержимого страницы с буфером 1
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на СОТНИ МИКРОСЕКУНД
- static void __flash_hal__buffer1_compare( __FLASH_WORD wPageNum // номер страницы для сравнения
- )
- {
- chip_sel_active();
- ( (__flash_packet_buffercompare_t*) cmdbuffer )->opcode = _ACMD_BUF1CMPR;
- ( (__flash_packet_buffercompare_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_buffercompare_t*) cmdbuffer )->__reserved =0;
- ( (__flash_packet_buffercompare_t*) cmdbuffer )->__reserved2=0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_buffercompare_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_WAITus( _TIME_BLDCM_us );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__pagetobuffer2 - сравнение содержимого страницы с буфером 2
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на СОТНИ МИКРОСЕКУНД
- static void __flash_hal__buffer2_compare( __FLASH_WORD wPageNum // номер страницы для сравнения
- )
- {
- chip_sel_active();
- ( (__flash_packet_buffercompare_t*) cmdbuffer )->opcode = _ACMD_BUF2CMPR;
- ( (__flash_packet_buffercompare_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_buffercompare_t*) cmdbuffer )->__reserved =0;
- ( (__flash_packet_buffercompare_t*) cmdbuffer )->__reserved2=0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_buffercompare_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_WAITus( _TIME_BLDCM_us );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__autopagerewrite1 - обновление страницы через буфер 1
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
- static void __flash_hal__autopagerewrite1( __FLASH_WORD wPageNum // номер обновляемой страницы
- )
- {
- chip_sel_active();
- ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->opcode = _ACMD_PAGEREF1;
- ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_autopagerewrite_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__autopagerewrite2 - обновление страницы через буфер 2
- //
- // * не проверяет правильность переданных параметров
- // * потоко-небезопасная функция
- // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
- static void __flash_hal__autopagerewrite2( __FLASH_WORD wPageNum // номер обновляемой страницы
- )
- {
- chip_sel_active();
- ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->opcode = _ACMD_PAGEREF2;
- ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->page = wPageNum;
- ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->__reserved = 0;
- ( (__flash_packet_autopagerewrite_t*) cmdbuffer )->__reserved2 = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_autopagerewrite_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGEPR_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__sleepmode - переход в режим пониженного энергопотребления
- //
- // * потоко-небезопасная функция
- // # переводит устройство в режим, когда все команды, кроме __flash_hal__wakeup игнорируются
- static void __flash_hal__sleepmode()
- {
- chip_sel_active();
- ( (__flash_packet_powerdown_t*) cmdbuffer )->opcode = _ACMD_EPWRDOWN;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_powerdown_t) );
- chip_sel_inactive();
- __FLASH_WAITus( _TIME_EDPDM_us );
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__wakeup - выход из режима пониженного энергопотребления
- //
- // * потоко-небезопасная функция
- // # выводит устройство из режима, когда все команды, кроме __flash_hal__wakeup игнорируются
- static void __flash_hal__wakeup()
- {
- chip_sel_active();
- // если флеш находилась во сне, необходимо ждать _TIME_RDPDM_us
- __FLASH_WAITus(_TIME_RDPDM_us);
- ( (__flash_packet_powerdown_t*) cmdbuffer )->opcode = _ACMD_LPWRDOWN;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_powerdown_t) );
- chip_sel_inactive();
- __FLASH_WAITus( _TIME_RDPDM_us );
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__manufactureridread - чтение идентификатора производителя
- //
- // * потоко-небезопасная функция
- // * может использоваться для опеределения типа чипа для выяснения его вместимости
- // * функция принимает параметр @pManufacturerID типа __flash_id_t. Этот параметр будет содержать
- // информацию о чипе, если параметр не NULL. Кроме того, для того, чтобы прочитать расширенную
- // информацию производителя (extended device information), поля pManufacturerID->pExtBf и
- // pManufacturerID->ExtLen должны быть проининциализированны указателем на принимающий буфер
- // и длинной этого буфера соответственно. При наличии расширенной информации поле ExtLen будет
- // перезаписано, и будет содержать длинну расширенной информации, сохраненной по указателю pExtBf.
- // Память по указателю pExtBf должна быть выделена заранее перед вызовом функции. Нуль-символ не
- // добавляется. Память, начиная с ExtLen байта, не перезаписывается (остается мусор).
- // * параметр @pManufacturerID может быть равен NULL. Для того, чтобы НЕ читать расширенную информацию,
- // передайте NULL вместо pManufacturerID, или, если передаете pManufacturerID, обнулите в нем поля pExtBf и ExtLen.
- // * функция способна определять расширенный Manufacturer ID согласно JEDEC JEP-106. Таким образом, кроме
- // стандартного ID производителя длинной 1 байт, производитель может использовать т.н. Continuation Code - 0x7F
- // Если стандартный код читается как 7F, функия продолжает чтение идентификатора до тех пор, пока не будет
- // принят байт, отличный от 7F, причем количество таких кодов 7F будет сохранено (не более 255)
- // и интерпретироваться как HighId. Если функция обнаружит более 255 кодов 7F, они подсчитаны не будут, при этом
- // HighId будет равен 255, а LowId - первый найденный не-7F код (даже после более 255 кодов 7F).
- // * вовзращаемое значение - DWORD, "откушенный" по младшему адресу от структуры __flash_id_t - содержит
- // DevId, LowId, HighId.
- static __FLASH_DWORD __flash_hal__manufactureridread( __flash_id_t * pManufacturerID // необязательный параметр-буфер для приема расширенной информации
- )
- {
- // локальные переменные функции объединены с возвращаемым значением, чтобы вернуть
- // часть информации в виде DWORD
- union
- {
- struct
- {
- __FLASH_BYTE LowId; // стандартный байт ID (не расширенный)
- __FLASH_BYTE HighId; // расширенный байт ID (количество 0x7F Continuation Code) (JEDEC JEP-106)
- union
- {
- __FLASH_WORD DevId; // код устройства
- struct
- {
- __FLASH_BYTE LDevId; // код устройства (Low)
- __FLASH_BYTE HDevId; // код устройства (High)
- };
- };
- };
- __FLASH_DWORD ReturnValue; // возвращаемое значение
- };
- DevId = 0;
- LDevId = 0;
- HDevId = 0;
- LowId = 0;
- HighId = 0;
- ReturnValue = 0;
- //-----------
- chip_sel_active();
- //-----------
- ( (__flash_packet_manufactureridread_t*) cmdbuffer )->opcode = _ACMD_MFIDREAD;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_manufactureridread_t) );
- //-----------
- // чтение Manufacturer ID
- do
- {
- __FLASH_HAL_RD( &LowId, sizeof( LowId ) );
- if( HighId < 255 ) HighId += ( (__FLASH_MANIDEX_OPCODE == LowId)? 1 : 0 );
- }
- while( (__FLASH_MANIDEX_OPCODE == LowId) );
- //-----------
- // чтение Device ID
- __FLASH_HAL_RD( &LDevId, sizeof( LDevId ) );
- __FLASH_HAL_RD( &HDevId, sizeof( HDevId ) );
- //-----------
- // чтение расширенной информации только если нам передали структуру для заполнения
- if( pManufacturerID )
- {
- // заполняем поля в переданной нам структуре
- pManufacturerID->DevId = DevId; // device ID
- pManufacturerID->LowId = LowId; // Manufacturer ID (Standart)
- pManufacturerID->HighId = HighId; // Manufacturer ID (Extended - Continuation Code 0x7F count)
- // записываем длинну расширенной информации
- {
- __FLASH_BYTE ExtLen;
- // читаем длинну расширенной информации
- __FLASH_HAL_RD( &ExtLen, sizeof( ExtLen ) );
- // записываем длинну расширенной информации
- pManufacturerID->ExtLen = ExtLen;
- // если есть куда записать расширенную информацию
- if( pManufacturerID->pExtBf )
- {
- // если на чипе есть расширенная информация
- if( ExtLen )
- {
- // ограничиваем емкость буфера по размеру расширенной информации
- if( pManufacturerID->ExtLen > ExtLen )
- {
- pManufacturerID->ExtLen = ExtLen;
- }
- // сначала считываем доступное количество байт (определяется значением ExtLen в ВЫХОДНОЙ структуре
- __FLASH_HAL_RD( pManufacturerID->pExtBf, sizeof( pManufacturerID->ExtLen ) );
- // затем перезаписываем длинну в выходную структуру
- pManufacturerID->ExtLen = ExtLen;
- }
- else
- // нет расширенной информации
- {
- pManufacturerID->ExtLen = 0; // обнуляем длинну расширенной информации в выходной структуре
- }
- }
- }
- }
- //-----------
- chip_sel_inactive();
- //-----------
- return ReturnValue;
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__writeprotect_enable - включить программную защиту от записи/стирания
- //
- // * потоко-небезопасная функция
- // # переводит устройство в режим, когда невозможно стирать/записывать некоторые секторы
- static void __flash_hal__writeprotect_enable()
- {
- chip_sel_active();
- ( (__flash_packet_protecttoggle_t*) cmdbuffer )->opcode = _SCMD_4SCTPREN;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protecttoggle_t) );
- chip_sel_inactive();
- // если разрешено управление аппаратным сигналом защиты записи
- #if AT45DBXXX_HW_WR_PROTECT
- // если аппаратная защита записи не отключена в настройках
- #if AT45DBXXX_HW_WR_PROTECT_KEEPUNPROTECTED == 0
- // установить аппаратную защиту записи
- __imp_flash_hwwrprotect_assert();
- #endif
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__writeprotect_disable - выключить программную защиту от записи/стирания
- //
- // * потоко-небезопасная функция
- // # выводит устройство из режима, когда невозможно стирать/записывать некоторые секторы (если нет аппаратной защиты)
- static void __flash_hal__writeprotect_disable()
- {
- // если разрешено управление аппаратным сигналом защиты записи
- #if AT45DBXXX_HW_WR_PROTECT
- // если аппаратная защита записи не отключена в настройках
- #if AT45DBXXX_HW_WR_PROTECT_KEEPUNPROTECTED == 0
- // снять аппаратную защиту записи
- __imp_flash_hwwrprotect_release();
- #endif
- #endif
- chip_sel_active();
- ( (__flash_packet_protecttoggle_t*) cmdbuffer )->opcode = _SCMD_4SCTPRDS;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protecttoggle_t) );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__protectregister_erase - стирает регистр защиты, помечая ВСЕ сектора как защищенные
- //
- // * потоко-небезопасная функция
- // # после выдачи этой команды и последующей __flash_hal__writeprotect_enable все сектора будут защищены от записи/стирания
- // # если включена программная защита от записи, все операции стирания/записи для всех секторов будут заблокированы до ее отключения
- // * задерживает выполнение на ДЕСЯТКИ МИЛЛИСЕКУНД
- static void __flash_hal__protectregister_erase()
- {
- chip_sel_active();
- ( (__flash_packet_protectregistererase_t*) cmdbuffer )->opcode = _SCMD_4PRREGER;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protectregistererase_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGERS_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__protectregister_write - записывает регистр защиты
- //
- // * потоко-небезопасная функция
- // * параметр @contents не может быть NULL - укажите содержимое регистра защиты (см. __flash_protectionregister_t)
- // # требуется предварительное стирание! (__flash_hal__protectregister_erase)
- // * задерживает выполнение на МИЛЛИСЕКУНДЫ
- // * ИЗМЕНЯЕТ СОДЕРЖИМОЕ ВСТРОЕННОГО БУФЕРА 1
- static void __flash_hal__protectregister_write( __flash_protectionregister_t * contents // содержимое регистра защиты для записи
- )
- {
- if( !contents ) return;
- chip_sel_active();
- ( (__flash_packet_protectregisterwrite_t*) cmdbuffer )->opcode = _SCMD_4PRREGWR;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protectregisterwrite_t) );
- // пишем регистр защиты
- __FLASH_HAL_WR( contents, sizeof(__flash_protectionregister_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0 //!
- __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__protectregister_read - прочитывает регистр защиты
- //
- // * потоко-небезопасная функция
- // * параметр @contents не может быть NULL - укажите буфер для содержимого регистра защиты (см. __flash_protectionregister_t)
- static void __flash_hal__protectregister_read( __flash_protectionregister_t * contents // буфер-приемник содержимого регистра защиты
- )
- {
- if( !contents ) return;
- chip_sel_active();
- ( (__flash_packet_protectregisterread_t*) cmdbuffer )->opcode = _SCMD_PRTREGRD;
- ( (__flash_packet_protectregisterread_t*) cmdbuffer )->__reserved = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_protectregisterwrite_t) );
- // читаем регистр защиты
- __FLASH_HAL_RD( contents, sizeof(__flash_protectionregister_t) );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__sectorlockdown - постоянная блокировка сектора от записи/стирания
- //
- // * потоко-небезопасная функция
- // # блокирует сектор навсегда: он становится "только для чтения"
- // * укажите адрес, принадлежащий сектору в параметре @address
- // * задерживает выполнение на МИЛЛИСЕКУНДЫ
- static void __flash_hal__sectorlockdown( __FLASH_DWORD address // адрес внутри блокируемого сектора
- )
- {
- chip_sel_active();
- ( (__flash_packet_sectorlockdown_t*) cmdbuffer )->opcode = _SCMD_4SCTLKDN;
- // заполняем адрес
- ( (__flash_packet_sectorlockdown_t*) cmdbuffer )->laddress = address & 0x0000FFFF;
- ( (__flash_packet_sectorlockdown_t*) cmdbuffer )->haddress = (address >> 16) & 0x000000FF;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_sectorlockdown_t) );
- chip_sel_inactive();
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
- #endif
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__lockdownregister_read - прочитывает регистр блокировки
- //
- // * потоко-небезопасная функция
- // * параметр @contents не может быть NULL - укажите буфер для содержимого регистра блокировки (см. __flash_lockdownregister_t)
- static void __flash_hal__lockdownregister_read( __flash_lockdownregister_t * contents // буфер-приемник содержимого регистра блокировки
- )
- {
- if( !contents ) return;
- chip_sel_active();
- ( (__flash_packet_lockdownregisterread_t*) cmdbuffer )->opcode = _SCMD_LKDNRGRD;
- ( (__flash_packet_lockdownregisterread_t*) cmdbuffer )->__reserved = 0;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_lockdownregisterread_t) );
- // читаем регистр блокировки
- __FLASH_HAL_RD( contents, sizeof(__flash_lockdownregister_t) );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__securityregister_write - записывает регистр безопасности
- //
- // * потоко-небезопасная функция
- // * параметр @contents не может быть равен NULL
- // * ИЗМЕНЯЕТ СОДЕРЖИМОЕ ВСТРОЕННОГО БУФЕРА 1
- // * записывает только ПОЛЬЗОВАТЕЛЬСКУЮ часть
- // # РЕГИСТР БЕЗОПАСНОСТИ МОЖЕТ БЫТЬ ЗАПИСАН ТОЛЬКО ОДИН РАЗ!
- static void __flash_hal__securityregister_write( __flash_usersecurityregister_t * contents // содержимое регистра безопасности (часть, доступная для записи пользователю)
- )
- {
- if( !contents ) return;
- chip_sel_active();
- ( (__flash_packet_securityregisterwrite_t*) cmdbuffer )->opcode = _SCMD_4SECRGWR;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_securityregisterwrite_t) );
- // записываем регистр безопасности
- __FLASH_HAL_WR( contents, sizeof(__flash_usersecurityregister_t) );
- #if AT45DB161E_BKGOPERATIONS == 0
- __FLASH_SMART_WAITms( _TIME_PGPRG_ms );
- #endif
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__securityregister_read - прочитывает регистр безопасности
- //
- // * потоко-небезопасная функция
- // * параметр @contents не может быть NULL - укажите буфер-приемние для сохранения содержимого регистра блокировки (см. __flash_securityregister_t)
- // * считывает как пользовательскую часть, так и запрограммированную производителем
- static void __flash_hal__securityregister_read( __flash_securityregister_t * contents // буфер-приемник содержимого регистра блокировки
- )
- {
- if( !contents ) return;
- chip_sel_active();
- ( (__flash_packet_securityregisterread_t*) cmdbuffer )->opcode = _SCMD_4SECRGRD;
- // отправляем команду
- __FLASH_HAL_WRCMD( &cmdbuffer, sizeof(__flash_packet_securityregisterread_t) );
- // читаем регистр безопасности
- __FLASH_HAL_RD( contents, sizeof(__flash_securityregister_t) );
- chip_sel_inactive();
- }
- // --------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__securityregister_read - прочитывает регистр безопасности и выполняет
- // проверку осмысленности прочитанного заводского идентификатора.
- // Функция расценивает индентификатор состоящий из одних 0xFF или 0x00 как невозможный.
- // В этом случае имеет место ошибка, функция возвращает false.
- static bool __flash_hal__securityregister_validate( __flash_securityregister_t * contents // буфер-приемник содержимого регистра блокировки
- )
- {
- if( NULL != contents )
- {
- __flash_hal__securityregister_read( contents );
- __FLASH_DWORD n00 = 0;
- __FLASH_DWORD nFF = 0;
- for( __FLASH_DWORD i = 0; i < __FLASH_FACT_SECURITY_BYTES; ++i )
- {
- if( 0xFF == contents->FactoryPart.UserId[i] ) ++nFF;
- if( 0x00 == contents->FactoryPart.UserId[i] ) ++n00;
- }
- if( (n00 != __FLASH_FACT_SECURITY_BYTES)
- &&
- (nFF != __FLASH_FACT_SECURITY_BYTES) )
- {
- return true;
- }
- }
- return false;
- }
- // --------------------------------------------------------------------------------------------------------
- #if AT45DBXXX_POWER_MANAGEMENT > 0
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__power_on - реализует управление питанием микросхемы памяти (подает питание)
- //
- static void __flash_hal__power_on()
- {
- // снять сигнал выбора чипа (чип не выбран, режим idle)
- chip_sel_inactive();
- // подать питание
- __imp_flash_poweron();
- }
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__power_off - реализует управление питанием микросхемы памяти (снимает питание)
- //
- static void __flash_hal__power_off()
- {
- // снять питание
- __imp_flash_poweroff();
- }
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__power_pulse - реализует управление питанием микросхемы - формирует импульс перезагрузки
- static void __flash_hal__power_pulse( __FLASH_WORD nCooldownTime_ms, __FLASH_WORD nStartupTime_ms )
- {
- // снять питание
- __imp_flash_poweroff();
- // снять сигнал выбора чипа (чип не выбран, режим idle)
- chip_sel_inactive();
- if( nCooldownTime_ms > 0 )
- {
- // немного подождем, пока остынет :)
- __FLASH_WAITms( _TIME_COOLDOWN_ms );
- }
- else
- {
- // ждем совсем немного
- __FLASH_WAITus( _TIME_STRUP_us );
- }
- // подать питание
- __imp_flash_poweron();
- // если разрешено управление режимом сброса
- #if AT45DBXXX_RESET_MANAGEMENT
- // сформировать импульс сброса микросхемы
- __flash_hal__reset_pulse();
- #endif
- if( nStartupTime_ms > 0 )
- {
- // ожидать готовности
- __FLASH_WAITms( _TIME_START_ms );
- }
- else
- {
- // ждем совсем немного
- __FLASH_WAITus( _TIME_STRUP_us );
- }
- }
- #endif
- #if AT45DBXXX_RESET_MANAGEMENT > 0
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__reset_assert - реализует управление сигналом сброса микросхемы памяти (устанавливает сигнал сброса)
- //
- static void __flash_hal__reset_assert()
- {
- // снять сигнал выбора чипа (чип не выбран, режим idle)
- chip_sel_inactive();
- // установить сигнал сброса
- __imp_flash_reset_assert();
- }
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__reset_release - реализует управление сигналом сброса микросхемы памяти (снимает сигнал сброса)
- //
- static void __flash_hal__reset_release()
- {
- // снять сигнал сброса
- __imp_flash_reset_release();
- }
- // --------------------------------------------------------------------------------------------------------
- // __flash_hal__reset_pulse - реализует управление сигналом сброса микросхемы памяти (подает законченный импульс сброса)
- //
- static void __flash_hal__reset_pulse()
- {
- // формируем импульс сброса
- // сначала снимаем сигнал сброса
- __imp_flash_reset_release();
- // после снятия сигнала сброса необходимо ожидать время восстановления
- __FLASH_WAITus(_TIME_RSTRC_us);
- // потом ставим сигнал сброса
- __flash_hal__reset_assert();
- // ожидание: требуется время для реакции на сигнал сброса
- __FLASH_WAITus(_TIME_RSTWD_us);
- // потом снова снимаем
- __flash_hal__reset_release();
- // после снятия сигнала сброса необходимо ожидать время восстановления
- __FLASH_WAITus(_TIME_RSTRC_us);
- }
- #endif
|