AT45DB321D_API.c 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394
  1. // Файл с API функциями работы с FLASH-чипом AT45DB321D
  2. // v 1.6 от 16/04/19
  3. // Автор: Сычев А.
  4. #define AT45DB321D_API_C
  5. #define AT45DB321D_APILEVEL // использование интерфейса низкоуровневых функций
  6. #include "drivers\flash\lowlevel\AT45DB321D_GLOB.h"
  7. #include "drivers\flash\lowlevel\AT45DB321D_LL_func.h"
  8. #include "drivers\flash\api\AT45DB321D_API.h"
  9. #include "drivers\flash\common\AT45DBXXX_HAL.h"
  10. #include "drivers\flash\api\AT45DB321D_APIfunc.h"
  11. const flash_properties_t FlashProperties =
  12. {
  13. .minAddress = AT45FLASH_MINIMUM_ADDRESS,
  14. .maxAddress = AT45FLASH_MAXIMUM_ADDRESS,
  15. .maxSectors = AT45FLASH_SECTORS,
  16. .sectorSize = (AT45FLASH_PAGES_PER_SECTOR * AT45FLASH_PAGE_SIZE),
  17. };
  18. // Enter() и Return(.) - макросы блокировки ресурса в многозадачных ОС
  19. // При входе в критический участок кода - выполнение API функции - вызывается Enter(),
  20. // блокируя ресурс, при выходе - Leave() или Return(.) ( для выхода из функции )
  21. #define Enter() { __FLASH_LOCK(); }
  22. #define Leave() { __FLASH_UNLOCK(); }
  23. #define Return(code) { __FLASH_UNLOCK(); return (code); }
  24. //#define ret __FLASH_UNLOCK(); return
  25. // Done:
  26. // flash_initialize(...) // Высокоуровневая инициализация памяти (установка размера страницы, установка параметров защиты секторов...)
  27. // flash_erase(...) // стирание памяти (блоками, страницами или секторами)
  28. // flash_read(...) // чтение памяти по адресу
  29. // flash_protect(...) // защита секторов (модификация конфигурации защищаемых секторов)
  30. // flash_unprotect(...) // снятие защиты (модификация конфигурации защищаемых секторов)
  31. // flash_service(...) // получение информации о производителе, расширенной информации, размере памяти, размере страницы, количестве секторов, блоков, страниц и т.п.
  32. // flash_write(...) // запись памяти по адресу
  33. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  34. // flash_getready - проверка готовности устройства (со стандартным таймаутом)
  35. //
  36. // # Функция возвращает FLERR_SUCCESS, еслиу устройство готово, иначе FLERR_TIMEOUT
  37. static flash_err_t flash_getready()
  38. {
  39. Enter();
  40. if( __flash_smart_waitms( _TIME_FLASHAPI_TIMEOUT ) )
  41. {
  42. Return(FLERR_SUCCESS);
  43. }
  44. Return(FLERR_TIMEOUT);
  45. }
  46. static flash_err_t flash_getready_time( __FLASH_WORD timeout )
  47. {
  48. Enter();
  49. if( __flash_smart_waitms( timeout ) )
  50. {
  51. Return(FLERR_SUCCESS);
  52. }
  53. Return(FLERR_TIMEOUT);
  54. }
  55. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  56. // flash_initialize - инициализация драйвера и API работы с устройством
  57. //
  58. // # Функция возвращает FLERR_SUCCESS. Только в этом случае гарантируется нормальная работа.
  59. // # Функция возвращает ошибку инициализации при появлении сбоев или при непрохождении проверки (см файл конфигурации AT45DB321D_CONF.h)
  60. flash_err_t flash_initialize()
  61. {
  62. // производим нисзкоуровневую инициализацию: подаем питание и будим, проверяем наличие чипа, серию, производителя, размер...
  63. flash_err_t success = __flash_hal__initialize();
  64. if( FLASH_ERROR(success) )
  65. {
  66. // что-то пошло не так: ай печаль-печаль.
  67. return(success);
  68. }
  69. // отключаем защиту секторов при инициализации (общий бит защиты)
  70. success = flash_unprotect( 0 );
  71. if( FLASH_ERROR(success) )
  72. {
  73. // что-то пошло не так: ай печаль-печаль.
  74. return(success);
  75. }
  76. // считываем статус
  77. if( ! __flash_smart_waitms( _TIME_FLASHAPI_TIMEOUT ) )
  78. {
  79. // что-то пошло не так: ай печаль-печаль.
  80. return(success);
  81. }
  82. return(FLERR_SUCCESS);
  83. }
  84. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  85. // flash_finalize - безопасная де-инициализация драйвера
  86. // Функция завершает работу с флеш-памятью, отключаяя ее или переводя в режим гибернации
  87. // @bHibernate: булевый флаг, показывает, что нужно перевести флеш-память в режим гибернации,
  88. // если false - драйвер попытается отключить питание микросхемы, если разрешено управление питанием (AT45DB321D_POWER_MANAGEMENT)
  89. // если false и управление питанием запрещено, будет возвращена ошибка FLERR_INVALID_PARAMETER.
  90. // @bForce: насильное выполнение финализации в случае, если флеш-память занята незаконченной операцией.
  91. // если false и драйвер детектирует незаконченную операцию, будет возвращена ошибка FLERR_UNEXPECTED_BUSY.
  92. // Если выбран режим гибернации, после выдачи команды функция проверяет, уснула ли микросхема через чтение статуса.
  93. // Если в этом случае обнаруживается, что статус все еще считывается, генерируется ошибка FLERR_GENERIC_ERROR.
  94. // Данную проверку можно отключить опцией AT45DB321D_DONOTCHECK_HIBERNATE=1.
  95. // Внимание: проверка не реализуется если bHibernate=false.
  96. // # Функция возвращает FLERR_SUCCESS всегда, за исключением вышеописанных случаев.
  97. flash_err_t flash_finalize( bool bHibernate, bool bForce )
  98. {
  99. Enter();
  100. // подготовка к деинициализации
  101. flash_err_t status = __flash_hal__finalize_prepare();
  102. if( FLASH_ERROR(status) )
  103. {
  104. // ошибка, обнаружена проблема - устройство не готово
  105. // проверяем, разрешено ли принудительное завершение?
  106. if( bForce )
  107. {
  108. // разрешено, сначала производим сброс
  109. // доступно управление сигналом сброса?
  110. #if AT45DB321D_RESET_MANAGEMENT
  111. // да, производим сброс чипа
  112. __flash_hal__reset_pulse();
  113. #else
  114. // нет, а доступно управление питанием?
  115. #if AT45DB321D_POWER_MANAGEMENT
  116. // да, производим быстрый сброс чипа по питанию
  117. __flash_hal__power_pulse( 0, 0 );
  118. #else
  119. // нет, управление питанием тоже недоступно
  120. // возвращаем ошибку FLERR_INVALID_PARAMETER - невозможно выполнить принудительное отключение
  121. Return(FLERR_INVALID_PARAMETER);
  122. #endif
  123. #endif
  124. }
  125. else
  126. {
  127. // нет, принудительное завершение запрещено
  128. // возвращаем ошибку
  129. Return(status);
  130. }
  131. }
  132. // все нормально, продолжаем
  133. // выбран режим гибернации?
  134. if( bHibernate )
  135. {
  136. // отправляем микросхему поспать
  137. __flash_hal__sleepmode();
  138. #if AT45DB321D_DONOTCHECK_HIBERNATE == 0
  139. // проверяем, ответит ли микросхема?
  140. if( __flash_smart_waitms( _TIME_FLASHAPI_TIMEOUT ) )
  141. {
  142. // отвечает - бит готовности прочитался...
  143. // Может это просто подтянутый сигнал к +VCC?
  144. // попробуем по другому:
  145. if( FLASH_SUCCESS(__flash_hal__detect()) )
  146. {
  147. // ответила! значит точно не ложилась спать - ошибка
  148. Return(FLERR_GENERIC_ERROR);
  149. }
  150. }
  151. #endif
  152. }
  153. else
  154. {
  155. // доступно управление питанием?
  156. #if AT45DB321D_POWER_MANAGEMENT == 0
  157. // нет, недоступно, нечего делать, генерируем ошибку
  158. Return(FLERR_INVALID_PARAMETER);
  159. #else
  160. // Доступно, отключаем питание.
  161. __flash_hal__power_off();
  162. // не проверяем доступность, доверяем функции отключения питания
  163. #endif
  164. }
  165. Return(FLERR_SUCCESS);
  166. }
  167. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  168. // flash_service - функция получения общих сведений об флеш-памяти.
  169. // Полный список возможных запросов приведен ниже:
  170. // ЗАПРОС РАЗМЕР ТИП ТИП ИНФОРМАИИ
  171. // БУФЕРА ЗНАЧНИЯ
  172. // fsvc_getVendorId 2 __FLASH_WORD ID производителя
  173. // fsvc_getDeviceId 2 flash_deviceid_t ID устройства
  174. // fsvc_getExtInfo * __FLASH_BYTE[] расширенную информацию производителя
  175. // fsvc_getExtInfoLen 1 __FLASH_BYTE длинну расширенной информации производителя
  176. // fsvc_getCapacity 4 __FLASH_DWORD заявляемая по документации емкость устройства (MBit-s)
  177. // fsvc_getFullCapacity 4 __FLASH_DWORD полная емкость устройства (в байтах)
  178. // fsvc_getDataCapacity 4 __FLASH_DWORD доступная емкость устройства (в байтах)
  179. // fsvc_getProtect 1 __FLASH_BYTE информацию о защите секторов (общий бит защиты 0x00 или 0x01)
  180. // fsvc_getSectorsCount 2 __FLASH_WORD количество секторов
  181. // fsvc_getPagesCount 2 __FLASH_WORD количество страниц
  182. // fsvc_getBlocksCount 2 __FLASH_WORD количество блоков
  183. // fsvc_getPageSize 2 __FLASH_WORD размер страницы
  184. // fsvc_getReadyState 1 __FLASH_BYTE готовность устройства
  185. // fsvc_getMinAddress 4 __FLASH_DWORD минимально возможный линейный адрес
  186. // fsvc_getMaxAddress 4 __FLASH_DWORD максимально возможный линейный адрес
  187. //
  188. // * Параметр @si задает тип запроса (см. flash_service_info_t)
  189. // * Параметр @pdata должен указывать на заранее выделенный буфер памяти для сохранения
  190. // получаемых данных. Размер буфера зависит от типа запроса. Параметр не может быть NULL
  191. // * Параметр @pbufsize должен указывать на размер буфера, на который указывает pdata.
  192. // Параметр не может быть 0. Значение по указателю @pbufsize не может быть 0.
  193. // При успешном выполнении функции, по указателю @pbufsize будет записано фактическое количество
  194. // записанных в буфер данных.
  195. //
  196. // * Функция НЕ ОБНУЛЯЕТ память по указателю @pdata в случае, если передан слишком большой буфер.
  197. //
  198. // # Функция вернет ошибку FLERR_INVALID_PARAMETER при некорректном запросе @si
  199. // # Функция вернет ошибку FLERR_INVALID_PARAMETER если @pdata или @bufsize равны 0.
  200. // # Функция вернет ошибку FLERR_INVALID_BUFFER если размер буфера @size не достаточен для сохранения данных
  201. //
  202. // # Функция вернет FLERR_SUCCESS при отсутствии ошибок
  203. //
  204. flash_err_t flash_service( flash_service_info_t si, void * pdata, __FLASH_WORD * pbufsize )
  205. {
  206. if( !pdata || !pbufsize || !*pbufsize ) return(FLERR_INVALID_PARAMETER);
  207. Enter();
  208. switch( si )
  209. {
  210. case fsvc_getVendorId: // ID производителя
  211. case fsvc_getDeviceId: // ID устройства
  212. case fsvc_getCapacity: // заявляемая по документации емкость устройства (MBit-s)
  213. case fsvc_getDataCapacity: // доступная емкость устройства
  214. case fsvc_getFullCapacity: // полная емкость устройства
  215. {
  216. __FLASH_DWORD flashID = __flash_hal__manufactureridread( 0 );
  217. switch( si )
  218. {
  219. case fsvc_getVendorId: if( sizeof( __FLASH_WORD ) > *pbufsize )
  220. Return(FLERR_INVALID_BUFFER);
  221. *((__FLASH_WORD*)(pdata)) = ((__flash_rvid_t*) &flashID)->FullId;
  222. *pbufsize = sizeof(__FLASH_WORD);
  223. Return(FLERR_SUCCESS);
  224. //-------------------------
  225. case fsvc_getDeviceId: if( sizeof( __FLASH_WORD ) > *pbufsize )
  226. Return(FLERR_INVALID_BUFFER);
  227. *((flash_deviceid_t*)(pdata)) = ((__flash_rvid_t*) &flashID)->DevId;
  228. *pbufsize = sizeof(__FLASH_WORD);
  229. Return(FLERR_SUCCESS);
  230. //-------------------------
  231. case fsvc_getCapacity: if( sizeof( __FLASH_DWORD ) > *pbufsize )
  232. Return(FLERR_INVALID_BUFFER);
  233. *((__FLASH_DWORD*)(pdata)) = __FLASH_DENSITY2CAPACITY( ((flash_deviceid_t*)&((__flash_rvid_t*) &flashID)->DevId)->Density );
  234. *pbufsize = sizeof(__FLASH_DWORD);
  235. Return(FLERR_SUCCESS);
  236. //-------------------------
  237. case fsvc_getDataCapacity: if( sizeof( __FLASH_DWORD ) > *pbufsize )
  238. Return(FLERR_INVALID_BUFFER);
  239. *((__FLASH_DWORD*)(pdata)) = (AT45FLASH_MAXIMUM_ADDRESS - AT45FLASH_MINIMUM_ADDRESS);
  240. *pbufsize = sizeof(__FLASH_DWORD);
  241. Return(FLERR_SUCCESS);
  242. //-------------------------
  243. case fsvc_getFullCapacity: if( sizeof( __FLASH_DWORD ) > *pbufsize )
  244. Return(FLERR_INVALID_BUFFER);
  245. *((__FLASH_DWORD*)(pdata)) = (AT45FLASH_MAXIMUM_ADDRESS);
  246. *pbufsize = sizeof(__FLASH_DWORD);
  247. Return(FLERR_SUCCESS);
  248. }
  249. }
  250. break;
  251. case fsvc_getMinAddress:
  252. {
  253. if( sizeof( __FLASH_DWORD ) > *pbufsize )
  254. Return(FLERR_INVALID_BUFFER);
  255. *((__FLASH_DWORD*)(pdata)) = (AT45FLASH_MINIMUM_ADDRESS);
  256. *pbufsize = sizeof(__FLASH_DWORD);
  257. Return(FLERR_SUCCESS);
  258. }
  259. break;
  260. case fsvc_getMaxAddress:
  261. {
  262. if( sizeof( __FLASH_DWORD ) > *pbufsize )
  263. Return(FLERR_INVALID_BUFFER);
  264. *((__FLASH_DWORD*)(pdata)) = (AT45FLASH_MAXIMUM_ADDRESS);
  265. *pbufsize = sizeof(__FLASH_DWORD);
  266. Return(FLERR_SUCCESS);
  267. }
  268. break;
  269. //-------------------------
  270. case fsvc_getExtInfoLen: // длинну расширенной информации производителя
  271. case fsvc_getExtInfo: // расширенную информацию производителя
  272. {
  273. __flash_id_t mid;
  274. switch( si )
  275. {
  276. case fsvc_getExtInfoLen:
  277. if( sizeof( __FLASH_BYTE ) > *pbufsize )
  278. Return(FLERR_INVALID_BUFFER);
  279. mid.pExtBf = 0;
  280. mid.ExtLen = 0;
  281. // получение ДЛИННЫ расширенной информации
  282. __flash_hal__manufactureridread( &mid );
  283. *((__FLASH_BYTE*)(pdata)) = mid.ExtLen;
  284. *pbufsize = sizeof(__FLASH_BYTE);
  285. Return(FLERR_SUCCESS);
  286. case fsvc_getExtInfo:
  287. if( 1 * sizeof( __FLASH_BYTE ) > *pbufsize )
  288. Return(FLERR_INVALID_BUFFER);
  289. mid.pExtBf = pdata;
  290. mid.ExtLen = *pbufsize;
  291. // получение расширенной информации
  292. __flash_hal__manufactureridread( &mid );
  293. *pbufsize = mid.ExtLen;
  294. Return(FLERR_SUCCESS);
  295. }
  296. }
  297. Return(FLERR_INVALID_BUFFER);
  298. case fsvc_getReadyState: // готовность устройства
  299. {
  300. if( sizeof( __FLASH_BYTE ) <= *pbufsize )
  301. {
  302. *((__FLASH_BYTE*)(pdata)) = ( FLASH_SUCCESS( __flash_hal__getreadyfast() ) )? 0x01: 0x00;
  303. *pbufsize = sizeof(__FLASH_BYTE);
  304. Return(FLERR_SUCCESS);
  305. }
  306. }
  307. Return(FLERR_INVALID_BUFFER);
  308. case fsvc_getProtect: // информацию о защите секторов
  309. {
  310. if( sizeof( __FLASH_BYTE ) <= *pbufsize )
  311. {
  312. flash_err_t status = flash_getprotect(0);
  313. switch( status )
  314. {
  315. case FLERR_PROTECT_DISABLED:
  316. *pbufsize = sizeof(__FLASH_BYTE);
  317. *((__FLASH_BYTE*)(pdata)) = 0;
  318. Return(FLERR_SUCCESS);
  319. case FLERR_PROTECT_ENABLED:
  320. *pbufsize = sizeof(__FLASH_BYTE);
  321. *((__FLASH_BYTE*)(pdata)) = 1;
  322. Return(FLERR_SUCCESS);
  323. }
  324. Return(status); // Ошибка?
  325. }
  326. }
  327. Return(FLERR_INVALID_BUFFER);
  328. case fsvc_getPageSize: // размер страницы
  329. {
  330. if( sizeof( __FLASH_WORD ) >= *pbufsize )
  331. {
  332. *((__FLASH_WORD*)(pdata)) = AT45FLASH_PAGE_SIZE;
  333. *pbufsize = sizeof(__FLASH_WORD);
  334. Return(FLERR_SUCCESS);
  335. }
  336. }
  337. Return(FLERR_INVALID_BUFFER);
  338. case fsvc_getSectorsCount: // количество секторов
  339. {
  340. if( sizeof( __FLASH_WORD ) <= *pbufsize ) // 16.04.19 Bug Fixed: changed condition ">=" to "<="
  341. {
  342. *((__FLASH_WORD*)(pdata)) = AT45FLASH_SECTORS;
  343. *pbufsize = sizeof(__FLASH_WORD);
  344. Return(FLERR_SUCCESS);
  345. }
  346. }
  347. Return(FLERR_INVALID_BUFFER);
  348. case fsvc_getPagesCount: // количество страниц
  349. {
  350. if( sizeof( __FLASH_WORD ) >= *pbufsize )
  351. {
  352. *((__FLASH_WORD*)(pdata)) = AT45FLASH_PAGES;
  353. *pbufsize = sizeof(__FLASH_WORD);
  354. Return(FLERR_SUCCESS);
  355. }
  356. }
  357. Return(FLERR_INVALID_BUFFER);
  358. case fsvc_getBlocksCount: // количество блоков
  359. {
  360. if( sizeof( __FLASH_WORD ) >= *pbufsize )
  361. {
  362. *((__FLASH_WORD*)(pdata)) = AT45FLASH_BLOCKS;
  363. *pbufsize = sizeof(__FLASH_WORD);
  364. Return(FLERR_SUCCESS);
  365. }
  366. }
  367. Return(FLERR_INVALID_BUFFER);
  368. }
  369. Return(FLERR_INVALID_PARAMETER);
  370. }
  371. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  372. // flash_protect_ex - установить/снять защиту секторов
  373. // Поробности см. описание flash_protect() / flash_unprotect()
  374. //
  375. // @mode: flash_sector_unprotected - вызов из flash_unprotect()
  376. // @mode: flash_sector_protected - вызов из flash_protect()
  377. //
  378. flash_err_t flash_protect_ex( flash_api_protect_t * content, flash_api_protect_bits mode )
  379. {
  380. Enter();
  381. // проверяем устройство на занятость
  382. if( FLERR_TIMEOUT == flash_getready() ) Return(FLERR_TIMEOUT);
  383. // проверяем на NULL переданный параметр
  384. if( !content )
  385. {
  386. if( mode == flash_sector_unprotected )
  387. {
  388. // параметр NULL - значит СНИМАЕМ общий бит защиты
  389. __flash_hal__writeprotect_disable();
  390. // проверяем, сборсился ли бит защиты
  391. if( __flash_hal__getprotectstate() != FLERR_PROTECT_DISABLED )
  392. Return(FLERR_GENERIC_ERROR);
  393. }
  394. else
  395. {
  396. // параметр NULL - значит УСТАНАВЛИВАЕМ общий бит защиты
  397. __flash_hal__writeprotect_enable();
  398. // проверяем, установился ли бит защиты
  399. if( __flash_hal__getprotectstate() != FLERR_PROTECT_ENABLED )
  400. Return(FLERR_GENERIC_ERROR);
  401. }
  402. Return(FLERR_SUCCESS);
  403. }
  404. else
  405. {
  406. // режим модификации общего бита защиты
  407. switch( content->protection_modify )
  408. {
  409. case flash_sector_protect_nomodify:
  410. // не трогаем общий бит защиты
  411. break;
  412. case flash_sector_protect_modify:
  413. // flash_sector_protected
  414. if( content->protection_enabled )
  415. {
  416. // устанавливаем защиту
  417. __flash_hal__writeprotect_enable();
  418. if( __flash_hal__getprotectstate() != FLERR_PROTECT_ENABLED )
  419. Return(FLERR_GENERIC_ERROR);
  420. }
  421. // flash_sector_unprotected
  422. else
  423. {
  424. // снимаем защиту
  425. __flash_hal__writeprotect_disable();
  426. if( __flash_hal__getprotectstate() != FLERR_PROTECT_DISABLED )
  427. Return(FLERR_GENERIC_ERROR);
  428. }
  429. break;
  430. default:
  431. // неправильный параметр в поле protection_modify
  432. Return(FLERR_INVALID_PARAMETER);
  433. }
  434. // получаем указатель на буфер драйвера
  435. __flash_protectionregister_t * pReg = __flash_internal_getbuffer_protect();
  436. // зануляем память
  437. __FLASH_ZEROMEMORY( pReg, sizeof(__flash_protectionregister_t) );
  438. // считываем байты защиты
  439. __flash_hal__protectregister_read( pReg );
  440. //------------------------------------------------------
  441. // модифицируем значения регистра защиты
  442. // индивидуально для сектора 0a,0b
  443. if( content->sectors.s0 ) // flash_sector_protect_pick
  444. {
  445. // сектор выбран: устанавливаем или снимаем биты защиты
  446. if( mode == flash_sector_unprotected )
  447. {
  448. pReg->Sector0.prot_0a = __FLASH_PROTECTION_REG_S0_DISABLE;
  449. pReg->Sector0.prot_0b = __FLASH_PROTECTION_REG_S0_DISABLE;
  450. }
  451. else
  452. {
  453. pReg->Sector0.prot_0a = __FLASH_PROTECTION_REG_S0_ENABLE;
  454. pReg->Sector0.prot_0b = __FLASH_PROTECTION_REG_S0_ENABLE;
  455. }
  456. pReg->Sector0.reserved= 0;
  457. } else { /* не модифицировать статус защиты сектора */ }
  458. // модифицируем байты защиты
  459. for( int s = 1; s < __SECTORS_TYPICAL; ++s )
  460. {
  461. if( (content->sectors.bytes[ s/8 ]) & ( 1<<(s%8)) )
  462. {
  463. // сектор выбран: устанавливаем или снимаем биты защиты
  464. if( mode == flash_sector_unprotected )
  465. pReg->Sectors[ s ] = __FLASH_PROTECTION_REG_DISABLE;
  466. else
  467. pReg->Sectors[ s ] = __FLASH_PROTECTION_REG_ENABLE;
  468. } else { /* не модифицировать статус защиты сектора */ }
  469. }
  470. //------------------------------------------------------
  471. //
  472. // стираем регистр защиты
  473. __flash_hal__protectregister_erase();
  474. // проверяем готовность устройства
  475. #if AT45DB321D_BKGOPERATIONS
  476. if( FLERR_TIMEOUT == flash_getready_time( _TIME_PGERS_ms ) )
  477. #else
  478. if( FLERR_TIMEOUT == flash_getready() )
  479. #endif
  480. {
  481. // фатальная ошибка: регистр защиты стерт
  482. // устройство занято. продолжать не можем
  483. //
  484. // для восстановления регистра защиты необходимо
  485. // вызвать функцию flash_error_restore()
  486. //
  487. Return(FLERR_UNEXPECTED_BUSY);
  488. }
  489. // записываем регистр защиты
  490. __flash_hal__protectregister_write( pReg );
  491. //------------------------------------------------------
  492. //
  493. // проверяем готовность устройства
  494. #if AT45DB321D_BKGOPERATIONS
  495. if( FLERR_TIMEOUT == flash_getready_time( _TIME_PGPRG_ms ) )
  496. #else
  497. if( FLERR_TIMEOUT == flash_getready() )
  498. #endif
  499. {
  500. // Ошибка: запись длится дольше положенного времени
  501. Return(FLERR_TIMEOUT);
  502. }
  503. //------------------------------------------------------
  504. { // №№№№№№ ПРОВЕРКА №№№№№№
  505. // считываем байты защиты
  506. __flash_hal__protectregister_read( pReg );
  507. // индивидуально для сектора 0a,0b
  508. if( content->sectors.s0 ) // flash_sector_protect_pick
  509. {
  510. // сектор выбран: проверяем биты защиты
  511. if( mode == flash_sector_unprotected )
  512. {
  513. if( pReg->Sector0.prot_0a != __FLASH_PROTECTION_REG_S0_DISABLE ||
  514. pReg->Sector0.prot_0b != __FLASH_PROTECTION_REG_S0_DISABLE )
  515. {
  516. Return(FLERR_GENERIC_ERROR);
  517. }
  518. }
  519. else
  520. {
  521. if( pReg->Sector0.prot_0a != __FLASH_PROTECTION_REG_S0_ENABLE ||
  522. pReg->Sector0.prot_0b != __FLASH_PROTECTION_REG_S0_ENABLE )
  523. {
  524. Return(FLERR_GENERIC_ERROR);
  525. }
  526. }
  527. }
  528. // проверяем байты защиты
  529. for( int s = 1; s < __SECTORS_TYPICAL; ++s )
  530. {
  531. if( (content->sectors.bytes[ s/8 ]) & ( 1<<(s%8)) )
  532. {
  533. // сектор выбран: проверяем биты защиты
  534. if( mode == flash_sector_unprotected )
  535. {
  536. if( pReg->Sectors[ s ] != __FLASH_PROTECTION_REG_DISABLE )
  537. Return(FLERR_GENERIC_ERROR);
  538. }
  539. else
  540. {
  541. if( pReg->Sectors[ s ] != __FLASH_PROTECTION_REG_ENABLE )
  542. Return(FLERR_GENERIC_ERROR);
  543. }
  544. }
  545. }
  546. }
  547. //------------------------------------------------------
  548. // успех.
  549. Return(FLERR_SUCCESS);
  550. }
  551. }
  552. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  553. // flash_protect - установить защиту секторов
  554. //
  555. // Функция модифицирует флаги защиты сектров выбранных пользователем в состояние "защищен".
  556. // Установите соответствующие флаги в структуре @content в состояние "1" для защиты сектора.
  557. // Функция также может модифицировать общий флаг защиты выбранных секторов. Для этого установите
  558. // желаемое состояние защиты в поле protection_enabled ( 0 - не защищено, 1 - защищено ) и установите поле
  559. // protection_modify в состояние "flash_sector_protect_modify" для того, чтобы общий флаг защиты был
  560. // изменен.
  561. //
  562. // * Для того, чтобы модифицировать только флаги защиты секторов без изменения общего флага защиты,
  563. // установите поле protection_modify в состояние "flash_sector_protect_nomodify".
  564. //
  565. // * параметр @content может быть равен NULL
  566. //
  567. // * Для того, чтобы модифицировать только общий бит защиты
  568. // БЕЗ модификации частных флагов защиты сектров:
  569. // - Для УСТАНОВКИ общего бита защиты передайте NULL вместо параметра @content
  570. // - Для УСТАНОВКИ/СНЯТИЯ общего бита защиты установите ВСЕ поля частных флагов защиты
  571. // секторов (s0...s63) в состояние flash_sector_protect_nomodify, поле protection_modify
  572. // установите в "flash_sector_protect_modify", а поле protection_enabled в желаемое
  573. // состояние флага защиты: flash_sector_protected или flash_sector_unprotected
  574. //
  575. // # Функция вернет FLERR_SUCCESS, если в процессе операции не произошло ошибок.
  576. // # Функция вернет FLERR_INVALID_PARAMETER в случае, если обнаружит ошибку в переданном параметре
  577. // # Функция вернет FLERR_UNEXPECTED_BUSY в случае, если процесс выполнения был прерван из-за неожиданного отказа устройства
  578. // # Функция вернет FLERR_GENERIC_ERROR в случае, если общий бит защиты не был установлен из-за ошибки
  579. // # Функция вернет FLERR_GENERIC_ERROR в случае, если хотя бы один из выбранных битов защиты не был установлен/сброшен
  580. //
  581. flash_err_t flash_protect( flash_api_protect_t * content )
  582. {
  583. return( flash_protect_ex( content, flash_sector_protected ));
  584. }
  585. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  586. // flash_protect - снять защиту секторов. Функция аналогичная flash_protect(),
  587. // только имеет обратный эффект - снятие защиты с выбранных секторов.
  588. //
  589. // Функция модифицирует флаги защиты сектров выбранных пользователем в состояние "не защищен".
  590. // Установите соответствующие флаги в структуре @content в состояние "1" для снятия защиты сектора.
  591. // Функция также может модифицировать общий флаг защиты выбранных секторов. Для этого установите
  592. // желаемое состояние защиты в поле protection_enabled ( 0 - не защищено, 1 - защищено ) и установите поле
  593. // protection_modify в состояние "flash_sector_protect_modify" для того, чтобы общий флаг защиты был
  594. // изменен.
  595. //
  596. // * Для того, чтобы модифицировать только флаги защиты секторов без изменения общего флага защиты,
  597. // установите поле protection_modify в состояние "flash_sector_protect_nomodify".
  598. //
  599. // * параметр @content может быть равен NULL
  600. //
  601. // * Для того, чтобы модифицировать только общий бит защиты
  602. // БЕЗ модификации частных флагов защиты сектров:
  603. // - Для СНЯТИЯ общего бита защиты передайте NULL вместо параметра @content
  604. // - Для УСТАНОВКИ/СНЯТИЯ общего бита защиты установите ВСЕ поля частных флагов защиты
  605. // секторов (s0...s63) в состояние flash_sector_protect_nomodify, поле protection_modify
  606. // установите в "flash_sector_protect_modify", а поле protection_enabled в желаемое
  607. // состояние флага защиты: flash_sector_protected или flash_sector_unprotected
  608. //
  609. // # Функция вернет FLERR_SUCCESS, если в процессе операции не произошло ошибок.
  610. // # Функция вернет FLERR_INVALID_PARAMETER в случае, если обнаружит ошибку в переданном параметре
  611. // # Функция вернет FLERR_UNEXPECTED_BUSY в случае, если процесс выполнения был прерван из-за неожиданного отказа устройства
  612. // # Функция вернет FLERR_GENERIC_ERROR в случае, если общий бит защиты не был установлен из-за ошибки
  613. // # Функция вернет FLERR_GENERIC_ERROR в случае, если хотя бы один из выбранных битов защиты не был установлен/сброшен
  614. //
  615. flash_err_t flash_unprotect( flash_api_protect_t * content )
  616. {
  617. return( flash_protect_ex( content, flash_sector_unprotected ));
  618. }
  619. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  620. // flash_getprotect - получить информацию о защищенных секторах.
  621. // * Указатель @content может быть NULL.
  622. // # Возвращаемое значение - общий бит защиты protection_enabled.
  623. // Если защита установлена - будет возвращен код FLERR_PROTECT_ENABLED
  624. // Если защита снята - будет возвращен код FLERR_PROTECT_DISABLED
  625. // Если указатель @content не NULL, по адресу будет записана структура типа flash_api_getprotect_t,
  626. // содержащая информацию о защите сектора (один сектор на один бит), а поле protection_enabled
  627. // будет содержать общий бит защиты - flash_sector_protected (установлена) или flash_sector_unprotected (снята).
  628. flash_err_t flash_getprotect( flash_api_getprotect_t * content )
  629. {
  630. Enter();
  631. __flash_status_t status;
  632. // пользователь хочет получить детализацию по защите секторов
  633. if( content )
  634. {
  635. if( FLERR_TIMEOUT == flash_getready() ) Return(FLERR_TIMEOUT);
  636. // получаем указатель на буфер драйвера
  637. __flash_protectionregister_t * pReg = __flash_internal_getbuffer_protect();
  638. // зануляем память
  639. __FLASH_ZEROMEMORY( pReg, sizeof(__flash_protectionregister_t) );
  640. // считываем байты защиты
  641. __flash_hal__protectregister_read( pReg );
  642. if( pReg->Sector0.prot_0a == __FLASH_PROTECTION_REG_S0_ENABLE ||
  643. pReg->Sector0.prot_0b == __FLASH_PROTECTION_REG_S0_ENABLE )
  644. content->sectors.s0 = 1;
  645. else content->sectors.s0 = 0;
  646. for( int s = 1; s < __SECTORS_TYPICAL; ++s )
  647. {
  648. if( pReg->Sectors[ s ] == __FLASH_PROTECTION_REG_ENABLE )
  649. content->sectors.bytes[ s/8 ] |= ( 1<<(s%8) );
  650. else
  651. content->sectors.bytes[ s/8 ] &= ~( 1<<(s%8) );
  652. }
  653. }
  654. __flash_hal__statusread(&status);
  655. if( status.bProtect )
  656. {
  657. if( NULL != content ) // fixed: 22/05/19
  658. content->protection_enabled = flash_sector_protected;
  659. Return(FLERR_PROTECT_ENABLED);
  660. }
  661. if( NULL != content ) // fixed: 22/05/19
  662. content->protection_enabled = flash_sector_unprotected;
  663. Return(FLERR_PROTECT_DISABLED);
  664. }
  665. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  666. // flash_erase - мультирежимное стирание данных
  667. // * Параметр @mode задает режим стирания:
  668. // mode==fem_byaddress - начальное смещение задается адресом в параметре @start, длинна отрезка - @count в байтах
  669. // При этом минимальный стираемый диапазон - размер страницы.
  670. // Страница, которой принадлежит адрес @start стирается полностью
  671. // Страница, которой принадлежит адрес @start + @count также стирается полность
  672. // @start не может быть меньше AT45FLASH_MINIMUM_ADDRESS
  673. // mode==fem_bypage - начальное смещение задается номером страницы в параметре @start.
  674. // Количество стираемых страниц задается параметром @count
  675. // @start не может быть меньше AT45FLASH_PAGES_PER_SECTOR
  676. //
  677. // mode==fem_byblock - начальное смещение задается номером блока в параметре @start
  678. // Количество стираемых блоков задается параметром @count
  679. // @start не может быть меньше AT45FLASH_BLOCKS_PER_SECTOR
  680. //
  681. // mode==fem_bysector - начальное смещение задается номером сектора в параметре @start
  682. // Количество стираемых секторов задается параметром @count.
  683. // @start не может быть равен 0.
  684. //
  685. // Адресное пространство с 0 по AT45FLASH_MINIMUM_ADDRESS является зарезервированным. Попытка стирания элементов
  686. // в этом диапазоне приведет к ошибке.
  687. //
  688. // * Параметр @count не может быть 0.
  689. // Параметр @start не должен указывать на зарезервированную область.
  690. //
  691. // ! Функция НЕ проверяет защиту секторов !
  692. //
  693. // # Функция возвращает FLERR_SUCCESS если не произошло ошибок.
  694. // # Функция вернет FLERR_INVALID_PARAMETER если @start указывает на зарезервированную область.
  695. // # Функция вернет FLERR_INVALID_PARAMETER если диапазон стирания выходит за границу адресного пространства
  696. // # Функция вернет FLERR_INVALID_PARAMETER если @count равняется 0.
  697. // # Функция вернет FLERR_INVALID_PARAMETER если @mode имеет значение, отличное от перечисленных.
  698. // # Функция вернет FLERR_UNEXPECTED_BUSY если во время операции устройство перестало отвечать
  699. //
  700. flash_err_t flash_erase( flash_erase_mode_t mode, __FLASH_DWORD start, __FLASH_DWORD count )
  701. {
  702. if( !count || !start ) return(FLERR_INVALID_PARAMETER);
  703. Enter();
  704. switch( mode )
  705. {
  706. case fem_byaddress: // стирание по адресу
  707. if( start < AT45FLASH_MINIMUM_ADDRESS ) Return(FLERR_INVALID_PARAMETER);
  708. if( start + count > AT45FLASH_MAXIMUM_ADDRESS ) Return(FLERR_INVALID_PARAMETER);
  709. case fem_bypage: // стирание по страницам
  710. {
  711. __FLASH_DWORD PagesToErase=0;
  712. __FLASH_DWORD PageBegin =0;
  713. if( mode == fem_byaddress )
  714. {
  715. // стирание по адресу
  716. PagesToErase = __FLASH_PAGESINRANGE( start , count );
  717. PageBegin = __FLASH_ADDRESS2PAGE( start );
  718. }
  719. else
  720. {
  721. // стирание по страницам
  722. if( start < AT45FLASH_PAGES_PER_SECTOR ) Return(FLERR_INVALID_PARAMETER);
  723. if( start + count > __FULL_PAGES ) Return(FLERR_INVALID_PARAMETER);
  724. PagesToErase = count;
  725. PageBegin = start;
  726. }
  727. while( PagesToErase )
  728. {
  729. // проверяем, нельзя ли использовать блочное стирание?
  730. if( __FLASH_PAGE_ARRAGED_BY_BLOCK ( PageBegin ) && // проверяем выравниваение
  731. ( PagesToErase >= AT45FLASH_PAGES_PER_BLOCK ) ) // проверяем количество страниц
  732. {
  733. // можно!
  734. // стираем блок - это быстрее
  735. __flash_hal__block_erase( __FLASH_PAGE2BLOCK( PageBegin ) );
  736. #if AT45DB321D_BKGOPERATIONS
  737. if( FLERR_TIMEOUT == flash_getready_time( _TIME_BKERS_ms ) )
  738. #else
  739. if( FLERR_TIMEOUT == flash_getready() )
  740. #endif
  741. {
  742. // фатальная ошибка: устройство занято дольше обычного
  743. Return(FLERR_UNEXPECTED_BUSY);
  744. }
  745. PageBegin += __PAGES_PER_BLOCK;
  746. PagesToErase -= __PAGES_PER_BLOCK;
  747. }
  748. else
  749. {
  750. // нельзя
  751. __flash_hal__page_erase( PageBegin );
  752. #if AT45DB321D_BKGOPERATIONS
  753. if( FLERR_TIMEOUT == flash_getready_time( _TIME_PGERS_ms ) )
  754. #else
  755. if( FLERR_TIMEOUT == flash_getready() )
  756. #endif
  757. {
  758. // фатальная ошибка: устройство занято дольше обычного
  759. Return(FLERR_UNEXPECTED_BUSY);
  760. }
  761. PageBegin ++;
  762. PagesToErase --;
  763. }
  764. }
  765. }
  766. break;
  767. case fem_byblock: // стирание по блокам
  768. {
  769. if( start < AT45FLASH_PAGES_PER_SECTOR ) Return(FLERR_INVALID_PARAMETER);
  770. if( start + count > __BLOCKS ) Return(FLERR_INVALID_PARAMETER);
  771. while( count )
  772. {
  773. __flash_hal__block_erase( start );
  774. #if AT45DB321D_BKGOPERATIONS
  775. if( FLERR_TIMEOUT == flash_getready_time( _TIME_BKERS_ms ) )
  776. #else
  777. if( FLERR_TIMEOUT == flash_getready() )
  778. #endif
  779. {
  780. // фатальная ошибка: устройство занято дольше обычного
  781. Return(FLERR_UNEXPECTED_BUSY);
  782. }
  783. start ++;
  784. count --;
  785. }
  786. }
  787. break;
  788. case fem_bysector: // стирание по секторам
  789. {
  790. if( start == 0 ) Return(FLERR_INVALID_PARAMETER); // сектор 0 - зарезервирован
  791. if( start + count > __SECTORS ) Return(FLERR_INVALID_PARAMETER);
  792. while( count )
  793. {
  794. __flash_hal__sector_erase( start );
  795. #if AT45DB321D_BKGOPERATIONS
  796. if( FLERR_TIMEOUT == flash_getready_time( _TIME_SCERS_ms ) )
  797. #else
  798. if( FLERR_TIMEOUT == flash_getready() )
  799. #endif
  800. {
  801. // фатальная ошибка: устройство занято дольше обычного
  802. Return(FLERR_UNEXPECTED_BUSY);
  803. }
  804. start ++;
  805. count --;
  806. }
  807. }
  808. break;
  809. default: Return(FLERR_INVALID_PARAMETER);
  810. }
  811. // успех.
  812. Return(FLERR_SUCCESS);
  813. }
  814. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  815. // flash_write - мультирежимная запись данных по адресу
  816. //
  817. // * Параметр @address указывает линейный адрес в адресном пространстве чипа.
  818. // Область 0 - AT45FLASH_MINIMUM_ADDRESS является зарезервированной, все попытки записи в эту область вызовут ошибку.
  819. // * Параметр @pBuffer - должен указывать на буфер-источник данных для записи. Не может быть NULL.
  820. // * Параметр @size - должен указывать на размер данных на запись. Не может быть равен 0.
  821. // * Параметр @mode - задает режим записи. Доступны следующий режимы:
  822. // - fwm_safewrite - режим безопасной записи. Медленный режим, когда запись/стирание происходит
  823. // постранично с верификацией. В случае ошибки верификации запись прекращается,
  824. // остальная (незаписанная) часть данных не переписывается/не стрирается,
  825. // При этом функция возвращает ошибку FLERR_VERIFY_ERROR
  826. //
  827. // - fwm_fastwrite - режим быстрой записи. Стирание происходит по блокам (8 станиц, см. заголовочный файл)
  828. // Запись постраничная. Верификация данных не проводится.
  829. //
  830. // - fwm_compatible режим ускоренной записи. НЕ РЕАЛИЗОВАН. ИСПОЛЬЗУЕТСЯ fwm_fastwrite.
  831. // Нечто среднее между режимамаи безопасной и быстрой записи.
  832. // Стирание происходит по блокам, запись по страницам. По завершении записи/стирания
  833. // всего объема данных происходит верификация. При обнаружении ошибки возвращается код FLERR_VERIFY_ERROR.
  834. //
  835. //
  836. // # Функция возвращает FLERR_SUCCESS, если не произшло никаких ошибок.
  837. // # Функция возвращает FLERR_UNEXPECTED_BUSY, если во время записи произошел отказ устройства.
  838. // # Функция возвращает FLERR_VERIFY_ERROR, если обнаружена ошибка верификации данных.
  839. // # Функция возвращает FLERR_INVALID_PARAMETER, если указан неверный параметр:
  840. // - @address указывает на зарезервированную область, либо область записи выходит за границу адресного пространства;
  841. // - @pBuffer или @size равны 0;
  842. // - @mode имеет значение, отличное от перечисленных
  843. //
  844. // # Для быстрой работы требует включения режима AT45DB321D_BKGOPERATIONS
  845. // Функция использует три различные монорежимные функции записи:
  846. static flash_err_t flash_write_fast( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size );
  847. static flash_err_t flash_write_safe( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size );
  848. static flash_err_t flash_write_comp( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size );
  849. flash_err_t flash_write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size, flash_write_mode_t mode )
  850. {
  851. if( address < AT45FLASH_MINIMUM_ADDRESS ) return(FLERR_INVALID_PARAMETER);
  852. if( !size || !pBuffer ) return(FLERR_INVALID_PARAMETER);
  853. if( address + size > AT45FLASH_MAXIMUM_ADDRESS ) return(FLERR_INVALID_PARAMETER);
  854. switch( mode )
  855. {
  856. case fwm_safewrite: //режим безопасной записи.
  857. // > Данные страницы прочитываются в буфер 1 чипа ( если запись страницы неполная )
  858. // > Данные страницы прочитываются в буфер 2 чипа ( если запись страницы неполная )
  859. // > Производится модификация данных в буфере 1 (запись в буфер со смещением)
  860. // > Используется команда стирание+запись страницы (буфер 1)
  861. // > Производится модификация данных в буфере 2 (пока идет запись)
  862. // > Производится сравнение записанной страницы с буфером 2
  863. // > Если данные совпадают - запись без ошибок
  864. /* ______________________
  865. / \
  866. | Slow Moderate Fast |
  867. | \ | / |
  868. | \ |
  869. | \ |
  870. | \ |
  871. | __\____ |
  872. \_____________________/
  873. */
  874. return(flash_write_safe( address, pBuffer, size ));
  875. case fwm_compatible: //режим ускоренной записи
  876. // > Данные блока считываются во временный буфер контроллера
  877. // > Производится стирание блока
  878. // > Пока блок стирается, модифицируем данные в буфере
  879. // > Постранично записываем данные в чип
  880. // > Поочередно загружаем в буфер 1 и буфер 2 страницы для сравнения
  881. // > Пока один буфер производит сравнение, записываем данные во второй
  882. // > При обнаружении расхождения генерируется ошибка
  883. /* ______________________
  884. / \
  885. | Slow Moderate Fast |
  886. | \ | / |
  887. | | |
  888. | | |
  889. | | |
  890. | ___|___ |
  891. \_____________________/
  892. */
  893. return(flash_write_comp( address, pBuffer, size ));
  894. case fwm_fastwrite: //режим быстрой записи.
  895. // > Данные страницы прочитываются в буфер 1 чипа ( если запись страницы неполная )
  896. // > Если возможно, производится стирание блока
  897. // > Пока блок стирается, модифицируем данные в буфере 1
  898. // > Постранично записываем данные в чип (если требуется, стриание+запись)
  899. // > Готово.
  900. /* ______________________
  901. / \
  902. | Slow Moderate Fast |
  903. | \ | / |
  904. | / |
  905. | / |
  906. | / |
  907. | _____/_ [!] |
  908. \_____________________/
  909. */
  910. return(flash_write_fast( address, pBuffer, size ));
  911. default:;
  912. }
  913. return(FLERR_INVALID_PARAMETER);
  914. }
  915. //----------
  916. // flash_write_safe() - обеспечивает режим записи fwm_safewrite
  917. // # НЕ ПРОВЕРЯЕТ ПЕРЕДАННЫЕ ПАРАМЕТРЫ
  918. // # Для быстрой работы требует включения режима AT45DB321D_BKGOPERATIONS
  919. static flash_err_t flash_write_safe( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
  920. {
  921. // > Данные страницы прочитываются в буфер 1 чипа ( если запись страницы неполная )
  922. // > Данные страницы прочитываются в буфер 2 чипа ( если запись страницы неполная )
  923. // > Производится модификация данных в буфере 1 (запись в буфер со смещением)
  924. // > Используется команда стирание+запись страницы (буфер 1)
  925. // > Производится модификация данных в буфере 2 (пока идет запись)
  926. // > Производится сравнение записанной страницы с буфером 2
  927. // > Если данные совпадают - запись без ошибок
  928. __FLASH_DWORD pageBegin = __FLASH_ADDRESS2PAGE( address ); // вычисляем номер первой страницы
  929. __FLASH_DWORD PagesToWrite = __FLASH_PAGESINRANGE( address, size ); // вычисляем количество затрагиваемых страниц
  930. __FLASH_DWORD BytesToWrite = __FLASH_DATAREMAININGINPAGE( address ); // вычисляем для первой страницы
  931. Enter();
  932. do
  933. {
  934. //---------------------
  935. // ПЕРВАЯ и ПОСЛЕДНЯЯ страницы могут записываться частично: требуется предварительное чтение
  936. if( __FLASH_ADDRESSOFFSETPAGE( address ) || PagesToWrite<=1 )
  937. {
  938. // Данные страницы прочитываются в буфер 1 чипа
  939. __flash_hal__pagetobuffer1( pageBegin );
  940. #if AT45DB321D_BKGOPERATIONS
  941. __FLASH_WAITus( _TIME_BLDCM_us );
  942. #endif
  943. if( FLASH_ERROR( __flash_hal__getreadyfast() ) ) Return(FLERR_UNEXPECTED_BUSY);
  944. // Данные страницы прочитываются в буфер 2 чипа
  945. __flash_hal__pagetobuffer2( pageBegin );
  946. #if AT45DB321D_BKGOPERATIONS
  947. __FLASH_WAITus( _TIME_BLDCM_us );
  948. #endif
  949. if( FLASH_ERROR( __flash_hal__getreadyfast() ) ) Return(FLERR_UNEXPECTED_BUSY);
  950. }
  951. //---------------------
  952. if( size < BytesToWrite ) BytesToWrite = size;
  953. //---------------------
  954. // Производится модификация данных в буфере 1 (запись в буфер со смещением)
  955. __flash_hal__buffer1_write( __FLASH_ADDRESSOFFSETPAGE( address ), // смещение в буфере
  956. pBuffer, // данные
  957. BytesToWrite ); // количество данных на запись
  958. //---------------------
  959. // идет запись: СТИРАНИЕ + ПРОГРАММИРОВАНИЕ
  960. __flash_hal__buffer1_program( pageBegin );
  961. #if AT45DB321D_BKGOPERATIONS == 0
  962. if( FLASH_ERROR( __flash_hal__getreadyfast() ) ) Return(FLERR_UNEXPECTED_BUSY);
  963. #endif
  964. //---------------------
  965. // Производится модификация данных в буфере 2 (запись в буфер со смещением)
  966. __flash_hal__buffer2_write( __FLASH_ADDRESSOFFSETPAGE( address ), // смещение в буфере
  967. pBuffer, // данные
  968. BytesToWrite ); // количество данных на запись
  969. //---------------------
  970. // дожидаемся завершения записи
  971. #if AT45DB321D_BKGOPERATIONS
  972. if( FLASH_ERROR( flash_getready_time( _TIME_PGEPR_ms ) ) ) Return(FLERR_UNEXPECTED_BUSY);
  973. #endif
  974. //---------------------
  975. // Производится сравнение записанной страницы с буфером 2
  976. __flash_hal__buffer1_compare( pageBegin );
  977. #if AT45DB321D_BKGOPERATIONS
  978. __FLASH_WAITus( _TIME_BLDCM_us );
  979. #endif
  980. //---------------------
  981. // Если данные совпадают - запись без ошибок
  982. if( FLASH_ERROR( __flash_hal__getcompareresult() ) ) Return(FLERR_VERIFY_ERROR);
  983. //---------------------
  984. pageBegin++;
  985. address += BytesToWrite;
  986. pBuffer += BytesToWrite;
  987. size -= BytesToWrite;
  988. BytesToWrite = __FLASH_DATAREMAININGINPAGE( address );
  989. }
  990. while( --PagesToWrite );
  991. Return(FLERR_SUCCESS);
  992. }
  993. //----------
  994. // flash_write_safe() - обеспечивает режим записи fwm_fastwrite
  995. // # НЕ ПРОВЕРЯЕТ ПЕРЕДАННЫЕ ПАРАМЕТРЫ
  996. // # Для быстрой работы требует включения режима AT45DB321D_BKGOPERATIONS
  997. static flash_err_t flash_write_fast( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
  998. {
  999. // > Данные страницы прочитываются в буфер 1 чипа ( если запись страницы неполная )
  1000. // > Если возможно, производится стирание блока
  1001. // > Пока блок стирается, модифицируем данные в буфере 1
  1002. // > Постранично записываем данные в чип (если требуется, стриание+запись)
  1003. // > Готово.
  1004. __FLASH_DWORD pageBegin = __FLASH_ADDRESS2PAGE( address ); // вычисляем номер первой страницы
  1005. __FLASH_DWORD PagesToWrite = __FLASH_PAGESINRANGE( address, size ); // вычисляем количество затрагиваемых страниц
  1006. __FLASH_DWORD BytesToWrite = __FLASH_DATAREMAININGINPAGE( address ); // вычисляем для первой страницы
  1007. __FLASH_DWORD PagesErased = 0; // количество заранее стретых страниц (блочное стирание)
  1008. Enter();
  1009. do
  1010. {
  1011. //---------------------
  1012. // ПЕРВАЯ и ПОСЛЕДНЯЯ страницы могут записываться частично: требуется предварительное чтение
  1013. if( __FLASH_ADDRESSOFFSETPAGE( address ) || PagesToWrite<=1 )
  1014. {
  1015. // Данные страницы прочитываются в буфер 1 чипа
  1016. __flash_hal__pagetobuffer1( pageBegin );
  1017. #if AT45DB321D_BKGOPERATIONS
  1018. __FLASH_WAITus( _TIME_BLDCM_us );
  1019. #endif
  1020. if( FLASH_ERROR( __flash_hal__getreadyfast() ) ) Return(FLERR_UNEXPECTED_BUSY);
  1021. }
  1022. //---------------------
  1023. if( size < BytesToWrite ) BytesToWrite = size;
  1024. //---------------------
  1025. // Производится стирание блока
  1026. if( __FLASH_PAGE_ARRAGED_BY_BLOCK( pageBegin ) && PagesToWrite >= AT45FLASH_PAGES_PER_BLOCK )
  1027. {
  1028. __flash_hal__block_erase( __FLASH_PAGE2BLOCK( pageBegin ) );
  1029. PagesErased = AT45FLASH_PAGES_PER_BLOCK; // запоминаем, что много-много страниц стерто
  1030. }
  1031. //---------------------
  1032. // Производится модификация данных в буфере 1 (запись в буфер со смещением)
  1033. __flash_hal__buffer1_write( __FLASH_ADDRESSOFFSETPAGE( address ), // смещение в буфере
  1034. pBuffer, // данные
  1035. BytesToWrite ); // количество данных на запись
  1036. #if AT45DB321D_BKGOPERATIONS
  1037. //---------------------
  1038. // дожидаемся окончания стирания блока
  1039. if( AT45FLASH_PAGES_PER_BLOCK == PagesErased ) // Только если только что стерли.
  1040. if( FLASH_ERROR( flash_getready_time( _TIME_BKERS_ms ) ) ) Return(FLERR_UNEXPECTED_BUSY);
  1041. #endif
  1042. //---------------------
  1043. // если стерто много страниц (блочное стирание )
  1044. if( PagesErased )
  1045. // идет запись: ПРОГРАММИРОВАНИЕ БЕЗ СТИРАНИЯ
  1046. {
  1047. __flash_hal__buffer1_program_wo_erase( pageBegin );
  1048. PagesErased--;
  1049. }
  1050. else
  1051. // идет запись: СТИРАНИЕ + ПРОГРАММИРОВАНИЕ
  1052. __flash_hal__buffer1_program( pageBegin );
  1053. #if AT45DB321D_BKGOPERATIONS == 0
  1054. if( FLASH_ERROR( __flash_hal__getreadyfast() ) ) Return(FLERR_UNEXPECTED_BUSY);
  1055. #endif
  1056. //---------------------
  1057. // дожидаемся завершения записи
  1058. #if AT45DB321D_BKGOPERATIONS
  1059. if( FLASH_ERROR( flash_getready_time( _TIME_PGEPR_ms ) ) ) Return(FLERR_UNEXPECTED_BUSY);
  1060. #endif
  1061. // ***************************************************************
  1062. // * NOTE: строго говоря, можно было еще больше соптимизировать *
  1063. // * и записывать в свободный второй буфер во время записи пер- *
  1064. // * вого. Но это потребует переключения команд записи страниц *
  1065. // * ( __flash_hal__buffer1_program_wo_erase и *
  1066. // * __flash_hal__buffer1_program), а также команд записи *
  1067. // * в буфер __flash_hal__pagetobuffer1, на ходу, потребуется *
  1068. // * запоминать, какой буфер свободен. *
  1069. // * В целях упрощения решено так не делать. *
  1070. // ***************************************************************
  1071. pageBegin++;
  1072. address += BytesToWrite;
  1073. pBuffer += BytesToWrite;
  1074. size -= BytesToWrite;
  1075. BytesToWrite = __FLASH_DATAREMAININGINPAGE( address );
  1076. }
  1077. while( --PagesToWrite );
  1078. Return(FLERR_SUCCESS);
  1079. }
  1080. //----------
  1081. // flash_write_safe() - обеспечивает режим записи fwm_compatible
  1082. // # НЕ ПРОВЕРЯЕТ ПЕРЕДАННЫЕ ПАРАМЕТРЫ
  1083. // # Для быстрой работы требует включения режима AT45DB321D_BKGOPERATIONS
  1084. //
  1085. // # РЕЖИМ НЕ РЕАЛИЗОВАН
  1086. //
  1087. #warning Режим записи fwm_fastwrite не реализован
  1088. static flash_err_t flash_write_comp( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
  1089. {
  1090. // > Данные страницы прочитываются в буфер 1 чипа ( если запись страницы неполная )
  1091. // > Если возможно, производится стирание блока
  1092. // > Пока блок стирается, модифицируем данные в буфере 1
  1093. // > Постранично записываем данные в чип (если требуется, стриание+запись)
  1094. // ---------------------------------
  1095. // Вызываем алгоритм быстрой записи fwm_fastwrite
  1096. flash_err_t success = flash_write_fast( address, pBuffer, size );
  1097. // если были ошибки - сообщаем
  1098. if( FLASH_ERROR( success ) ) return(success);
  1099. // ---------------------------------
  1100. // Приступаем к верификации:
  1101. // > Поочередно загружаем в буфер 1 и буфер 2 страницы для сравнения
  1102. // > Пока один буфер производит сравнение, записываем данные во второй
  1103. // > При обнаружении расхождения генерируется ошибка
  1104. //
  1105. // ВОПРОС: а будет ли это быстрее, чем сравнивать на ходу?! А может просто прочитать массив на борт CPU и использовать memcmp() ?
  1106. //
  1107. // функторы действий
  1108. // void ( * buffer_write )(__FLASH_WORD,__FLASH_BYTE*,__FLASH_WORD) = __flash_hal__buffer1_write; // сначала выбираем буфер 1
  1109. // void ( * buffer_compare )(__FLASH_WORD) = __flash_hal__buffer1_compare; //
  1110. return(FLERR_SUCCESS);
  1111. }
  1112. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  1113. // flash_read - чтение данных по адресу
  1114. //
  1115. // * Функция проверяет правильность переданных параметров
  1116. // * Параметр @address задает линейный адрес внутри адресного пространства устройства.
  1117. // Адресное пространство с адреса 0 до AT45FLASH_MINIMUM_ADDRESS (не включительно) является
  1118. // зарезервированным. При попытке чтения из этого диапазона функция вернет ошибку.
  1119. // Параметр @pvBuffer должен указывать на буфер-приемник для прочитанных данных.
  1120. // Параметр @size должен указывать на размер буфер-приемника. Параметр показывает
  1121. // количество байт для чтения в буфер.
  1122. // # Если параметр @address указывает на адрес в диапазоне 0...AT45FLASH_MINIMUM_ADDRESS, функция вернет ошибку FLERR_INVALID_PARAMETER
  1123. // # Если параметр @pvBuffer равен NULL, функция вернет ошибку FLERR_INVALID_PARAMETER
  1124. // # Если параметр @size равен 0, функция вернет ошибку FLERR_INVALID_PARAMETER
  1125. flash_err_t flash_read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
  1126. {
  1127. // проверяем входные параметры
  1128. if( address < AT45FLASH_MINIMUM_ADDRESS ) return(FLERR_INVALID_PARAMETER);
  1129. if( !pBuffer || !size ) return(FLERR_INVALID_PARAMETER);
  1130. #ifndef AT45DB321D_EMU512
  1131. // проверяем диапазон чтения
  1132. if( address + size > __FULL_CHIP_SIZE ) return(FLERR_INVALID_PARAMETER);
  1133. #endif
  1134. // получаем начальную страницу
  1135. #ifdef AT45DB321D_EMU512
  1136. __FLASH_DWORD PagesToRead = __FLASH_PAGESINRANGE( address , size );
  1137. #endif
  1138. __FLASH_DWORD PageBegin = __FLASH_ADDRESS2PAGE( address );
  1139. __FLASH_DWORD PageOffset = __FLASH_ADDRESSOFFSETPAGE( address );
  1140. Enter();
  1141. // проверям готовность устройства
  1142. if( FLERR_TIMEOUT == flash_getready() ) Return(FLERR_TIMEOUT);
  1143. #ifndef AT45DB321D_EMU512
  1144. // работа без эмуляции страниц по 512 байт
  1145. __flash_hal__array_read( PageBegin, PageOffset, pBuffer, size );
  1146. Return(FLERR_SUCCESS);
  1147. #else
  1148. // эмуляция размера страниц 512 байт
  1149. // проверяем диапазон чтения
  1150. if( PagesToRead + PageBegin > __FULL_PAGES ) Return(FLERR_INVALID_PARAMETER);
  1151. // постраничное чтение
  1152. while( size && PagesToRead )
  1153. {
  1154. __FLASH_DWORD BytesToRead = __PAGE_SIZE_USER - __FLASH_ADDRESSOFFSETPAGE( address );
  1155. if( BytesToRead > size ) BytesToRead = size; // 22/09/15 - ErrorFix
  1156. __flash_hal__page_read( PageBegin, PageOffset, pBuffer, BytesToRead );
  1157. pBuffer += BytesToRead;
  1158. address += BytesToRead;
  1159. size -= BytesToRead;
  1160. PageBegin++;
  1161. PagesToRead--;
  1162. PageOffset = 0;
  1163. }
  1164. Return(FLERR_SUCCESS);
  1165. #endif
  1166. }
  1167. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  1168. // flash_sleepmode - переход в режим пониженного энергопотребления
  1169. // # переводит устройство в режим, когда все команды, кроме flash_wakeup игнорируются
  1170. flash_err_t flash_sleepmode()
  1171. {
  1172. Enter();
  1173. __flash_hal__sleepmode();
  1174. Return(FLERR_SUCCESS);
  1175. }
  1176. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
  1177. // flash_wakeup - выход из режима пониженного энергопотребления
  1178. // # выводит устройство из режима, когда все команды, кроме flash_wakeup игнорируются
  1179. flash_err_t flash_wakeup()
  1180. {
  1181. Enter();
  1182. __flash_hal__wakeup();
  1183. if( __flash_smart_waitms( _TIME_FLASHAPI_TIMEOUT ) )
  1184. {
  1185. Return(FLERR_SUCCESS);
  1186. }
  1187. Return(FLERR_TIMEOUT);
  1188. }
  1189. // №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№