My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ctrl_access.c 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. /*****************************************************************************
  2. *
  3. * \file
  4. *
  5. * \brief Abstraction layer for memory interfaces.
  6. *
  7. * This module contains the interfaces:
  8. * - MEM <-> USB;
  9. * - MEM <-> RAM;
  10. * - MEM <-> MEM.
  11. *
  12. * This module may be configured and expanded to support the following features:
  13. * - write-protected globals;
  14. * - password-protected data;
  15. * - specific features;
  16. * - etc.
  17. *
  18. * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
  19. *
  20. * \asf_license_start
  21. *
  22. * \page License
  23. *
  24. * Redistribution and use in source and binary forms, with or without
  25. * modification, are permitted provided that the following conditions are met:
  26. *
  27. * 1. Redistributions of source code must retain the above copyright notice,
  28. * this list of conditions and the following disclaimer.
  29. *
  30. * 2. Redistributions in binary form must reproduce the above copyright notice,
  31. * this list of conditions and the following disclaimer in the documentation
  32. * and/or other materials provided with the distribution.
  33. *
  34. * 3. The name of Atmel may not be used to endorse or promote products derived
  35. * from this software without specific prior written permission.
  36. *
  37. * 4. This software may only be redistributed and used in connection with an
  38. * Atmel microcontroller product.
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  41. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  42. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  43. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  44. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  49. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  50. * POSSIBILITY OF SUCH DAMAGE.
  51. *
  52. * \asf_license_stop
  53. *
  54. ******************************************************************************/
  55. /*
  56. * Support and FAQ: visit <a href="https://www.atmel.com/design-support/">Atmel Support</a>
  57. */
  58. #ifdef ARDUINO_ARCH_SAM
  59. //_____ I N C L U D E S ____________________________________________________
  60. #include "compiler.h"
  61. #include "preprocessor.h"
  62. #ifdef FREERTOS_USED
  63. #include "FreeRTOS.h"
  64. #include "semphr.h"
  65. #endif
  66. #include "ctrl_access.h"
  67. //_____ D E F I N I T I O N S ______________________________________________
  68. #ifdef FREERTOS_USED
  69. /*! \name LUN Access Protection Macros
  70. */
  71. //! @{
  72. /*! \brief Locks accesses to LUNs.
  73. *
  74. * \return \c true if the access was successfully locked, else \c false.
  75. */
  76. #define Ctrl_access_lock() ctrl_access_lock()
  77. /*! \brief Unlocks accesses to LUNs.
  78. */
  79. #define Ctrl_access_unlock() xSemaphoreGive(ctrl_access_semphr)
  80. //! @}
  81. //! Handle to the semaphore protecting accesses to LUNs.
  82. static xSemaphoreHandle ctrl_access_semphr = NULL;
  83. #else
  84. /*! \name LUN Access Protection Macros
  85. */
  86. //! @{
  87. /*! \brief Locks accesses to LUNs.
  88. *
  89. * \return \c true if the access was successfully locked, else \c false.
  90. */
  91. #define Ctrl_access_lock() true
  92. /*! \brief Unlocks accesses to LUNs.
  93. */
  94. #define Ctrl_access_unlock()
  95. //! @}
  96. #endif // FREERTOS_USED
  97. #if MAX_LUN
  98. /*! \brief Initializes an entry of the LUN descriptor table.
  99. *
  100. * \param lun Logical Unit Number.
  101. *
  102. * \return LUN descriptor table entry initializer.
  103. */
  104. #if ACCESS_USB == true && ACCESS_MEM_TO_RAM == true
  105. #define Lun_desc_entry(lun) \
  106. {\
  107. TPASTE3(Lun_, lun, _test_unit_ready),\
  108. TPASTE3(Lun_, lun, _read_capacity),\
  109. TPASTE3(Lun_, lun, _unload),\
  110. TPASTE3(Lun_, lun, _wr_protect),\
  111. TPASTE3(Lun_, lun, _removal),\
  112. TPASTE3(Lun_, lun, _usb_read_10),\
  113. TPASTE3(Lun_, lun, _usb_write_10),\
  114. TPASTE3(Lun_, lun, _mem_2_ram),\
  115. TPASTE3(Lun_, lun, _ram_2_mem),\
  116. TPASTE3(LUN_, lun, _NAME)\
  117. }
  118. #elif ACCESS_USB == true
  119. #define Lun_desc_entry(lun) \
  120. {\
  121. TPASTE3(Lun_, lun, _test_unit_ready),\
  122. TPASTE3(Lun_, lun, _read_capacity),\
  123. TPASTE3(Lun_, lun, _unload),\
  124. TPASTE3(Lun_, lun, _wr_protect),\
  125. TPASTE3(Lun_, lun, _removal),\
  126. TPASTE3(Lun_, lun, _usb_read_10),\
  127. TPASTE3(Lun_, lun, _usb_write_10),\
  128. TPASTE3(LUN_, lun, _NAME)\
  129. }
  130. #elif ACCESS_MEM_TO_RAM == true
  131. #define Lun_desc_entry(lun) \
  132. {\
  133. TPASTE3(Lun_, lun, _test_unit_ready),\
  134. TPASTE3(Lun_, lun, _read_capacity),\
  135. TPASTE3(Lun_, lun, _unload),\
  136. TPASTE3(Lun_, lun, _wr_protect),\
  137. TPASTE3(Lun_, lun, _removal),\
  138. TPASTE3(Lun_, lun, _mem_2_ram),\
  139. TPASTE3(Lun_, lun, _ram_2_mem),\
  140. TPASTE3(LUN_, lun, _NAME)\
  141. }
  142. #else
  143. #define Lun_desc_entry(lun) \
  144. {\
  145. TPASTE3(Lun_, lun, _test_unit_ready),\
  146. TPASTE3(Lun_, lun, _read_capacity),\
  147. TPASTE3(Lun_, lun, _unload),\
  148. TPASTE3(Lun_, lun, _wr_protect),\
  149. TPASTE3(Lun_, lun, _removal),\
  150. TPASTE3(LUN_, lun, _NAME)\
  151. }
  152. #endif
  153. //! LUN descriptor table.
  154. static const struct
  155. {
  156. Ctrl_status (*test_unit_ready)(void);
  157. Ctrl_status (*read_capacity)(U32 *);
  158. bool (*unload)(bool);
  159. bool (*wr_protect)(void);
  160. bool (*removal)(void);
  161. #if ACCESS_USB == true
  162. Ctrl_status (*usb_read_10)(U32, U16);
  163. Ctrl_status (*usb_write_10)(U32, U16);
  164. #endif
  165. #if ACCESS_MEM_TO_RAM == true
  166. Ctrl_status (*mem_2_ram)(U32, void *);
  167. Ctrl_status (*ram_2_mem)(U32, const void *);
  168. #endif
  169. const char *name;
  170. } lun_desc[MAX_LUN] =
  171. {
  172. #if LUN_0 == ENABLE
  173. # ifndef Lun_0_unload
  174. # define Lun_0_unload NULL
  175. # endif
  176. Lun_desc_entry(0),
  177. #endif
  178. #if LUN_1 == ENABLE
  179. # ifndef Lun_1_unload
  180. # define Lun_1_unload NULL
  181. # endif
  182. Lun_desc_entry(1),
  183. #endif
  184. #if LUN_2 == ENABLE
  185. # ifndef Lun_2_unload
  186. # define Lun_2_unload NULL
  187. # endif
  188. Lun_desc_entry(2),
  189. #endif
  190. #if LUN_3 == ENABLE
  191. # ifndef Lun_3_unload
  192. # define Lun_3_unload NULL
  193. # endif
  194. Lun_desc_entry(3),
  195. #endif
  196. #if LUN_4 == ENABLE
  197. # ifndef Lun_4_unload
  198. # define Lun_4_unload NULL
  199. # endif
  200. Lun_desc_entry(4),
  201. #endif
  202. #if LUN_5 == ENABLE
  203. # ifndef Lun_5_unload
  204. # define Lun_5_unload NULL
  205. # endif
  206. Lun_desc_entry(5),
  207. #endif
  208. #if LUN_6 == ENABLE
  209. # ifndef Lun_6_unload
  210. # define Lun_6_unload NULL
  211. # endif
  212. Lun_desc_entry(6),
  213. #endif
  214. #if LUN_7 == ENABLE
  215. # ifndef Lun_7_unload
  216. # define Lun_7_unload NULL
  217. # endif
  218. Lun_desc_entry(7)
  219. #endif
  220. };
  221. #endif
  222. #if GLOBAL_WR_PROTECT == true
  223. bool g_wr_protect;
  224. #endif
  225. /*! \name Control Interface
  226. */
  227. //! @{
  228. #ifdef FREERTOS_USED
  229. bool ctrl_access_init(void)
  230. {
  231. // If the handle to the protecting semaphore is not valid,
  232. if (!ctrl_access_semphr)
  233. {
  234. // try to create the semaphore.
  235. vSemaphoreCreateBinary(ctrl_access_semphr);
  236. // If the semaphore could not be created, there is no backup solution.
  237. if (!ctrl_access_semphr) return false;
  238. }
  239. return true;
  240. }
  241. /*! \brief Locks accesses to LUNs.
  242. *
  243. * \return \c true if the access was successfully locked, else \c false.
  244. */
  245. static bool ctrl_access_lock(void)
  246. {
  247. // If the semaphore could not be created, there is no backup solution.
  248. if (!ctrl_access_semphr) return false;
  249. // Wait for the semaphore.
  250. while (!xSemaphoreTake(ctrl_access_semphr, portMAX_DELAY));
  251. return true;
  252. }
  253. #endif // FREERTOS_USED
  254. U8 get_nb_lun(void)
  255. {
  256. #if MEM_USB == ENABLE
  257. # ifndef Lun_usb_get_lun
  258. # define Lun_usb_get_lun() host_get_lun()
  259. # endif
  260. U8 nb_lun;
  261. if (!Ctrl_access_lock()) return MAX_LUN;
  262. nb_lun = MAX_LUN + Lun_usb_get_lun();
  263. Ctrl_access_unlock();
  264. return nb_lun;
  265. #else
  266. return MAX_LUN;
  267. #endif
  268. }
  269. U8 get_cur_lun(void)
  270. {
  271. return LUN_ID_0;
  272. }
  273. Ctrl_status mem_test_unit_ready(U8 lun)
  274. {
  275. Ctrl_status status;
  276. if (!Ctrl_access_lock()) return CTRL_FAIL;
  277. status =
  278. #if MAX_LUN
  279. (lun < MAX_LUN) ? lun_desc[lun].test_unit_ready() :
  280. #endif
  281. #if LUN_USB == ENABLE
  282. Lun_usb_test_unit_ready(lun - LUN_ID_USB);
  283. #else
  284. CTRL_FAIL;
  285. #endif
  286. Ctrl_access_unlock();
  287. return status;
  288. }
  289. Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector)
  290. {
  291. Ctrl_status status;
  292. if (!Ctrl_access_lock()) return CTRL_FAIL;
  293. status =
  294. #if MAX_LUN
  295. (lun < MAX_LUN) ? lun_desc[lun].read_capacity(u32_nb_sector) :
  296. #endif
  297. #if LUN_USB == ENABLE
  298. Lun_usb_read_capacity(lun - LUN_ID_USB, u32_nb_sector);
  299. #else
  300. CTRL_FAIL;
  301. #endif
  302. Ctrl_access_unlock();
  303. return status;
  304. }
  305. U8 mem_sector_size(U8 lun)
  306. {
  307. U8 sector_size;
  308. if (!Ctrl_access_lock()) return 0;
  309. sector_size =
  310. #if MAX_LUN
  311. (lun < MAX_LUN) ? 1 :
  312. #endif
  313. #if LUN_USB == ENABLE
  314. Lun_usb_read_sector_size(lun - LUN_ID_USB);
  315. #else
  316. 0;
  317. #endif
  318. Ctrl_access_unlock();
  319. return sector_size;
  320. }
  321. bool mem_unload(U8 lun, bool unload)
  322. {
  323. bool unloaded;
  324. #if !MAX_LUN || !defined(Lun_usb_unload)
  325. UNUSED(lun);
  326. #endif
  327. if (!Ctrl_access_lock()) return false;
  328. unloaded =
  329. #if MAX_LUN
  330. (lun < MAX_LUN) ?
  331. (lun_desc[lun].unload ?
  332. lun_desc[lun].unload(unload) : !unload) :
  333. #endif
  334. #if LUN_USB == ENABLE
  335. # if defined(Lun_usb_unload)
  336. Lun_usb_unload(lun - LUN_ID_USB, unload);
  337. # else
  338. !unload; /* Can not unload: load success, unload fail */
  339. # endif
  340. #else
  341. false; /* No mem, unload/load fail */
  342. #endif
  343. Ctrl_access_unlock();
  344. return unloaded;
  345. }
  346. bool mem_wr_protect(U8 lun)
  347. {
  348. bool wr_protect;
  349. if (!Ctrl_access_lock()) return true;
  350. wr_protect =
  351. #if MAX_LUN
  352. (lun < MAX_LUN) ? lun_desc[lun].wr_protect() :
  353. #endif
  354. #if LUN_USB == ENABLE
  355. Lun_usb_wr_protect(lun - LUN_ID_USB);
  356. #else
  357. true;
  358. #endif
  359. Ctrl_access_unlock();
  360. return wr_protect;
  361. }
  362. bool mem_removal(U8 lun)
  363. {
  364. bool removal;
  365. #if MAX_LUN==0
  366. UNUSED(lun);
  367. #endif
  368. if (!Ctrl_access_lock()) return true;
  369. removal =
  370. #if MAX_LUN
  371. (lun < MAX_LUN) ? lun_desc[lun].removal() :
  372. #endif
  373. #if LUN_USB == ENABLE
  374. Lun_usb_removal();
  375. #else
  376. true;
  377. #endif
  378. Ctrl_access_unlock();
  379. return removal;
  380. }
  381. const char *mem_name(U8 lun)
  382. {
  383. #if MAX_LUN==0
  384. UNUSED(lun);
  385. #endif
  386. return
  387. #if MAX_LUN
  388. (lun < MAX_LUN) ? lun_desc[lun].name :
  389. #endif
  390. #if LUN_USB == ENABLE
  391. LUN_USB_NAME;
  392. #else
  393. NULL;
  394. #endif
  395. }
  396. //! @}
  397. #if ACCESS_USB == true
  398. /*! \name MEM <-> USB Interface
  399. */
  400. //! @{
  401. Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector)
  402. {
  403. Ctrl_status status;
  404. if (!Ctrl_access_lock()) return CTRL_FAIL;
  405. memory_start_read_action(nb_sector);
  406. status =
  407. #if MAX_LUN
  408. (lun < MAX_LUN) ? lun_desc[lun].usb_read_10(addr, nb_sector) :
  409. #endif
  410. CTRL_FAIL;
  411. memory_stop_read_action();
  412. Ctrl_access_unlock();
  413. return status;
  414. }
  415. Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector)
  416. {
  417. Ctrl_status status;
  418. if (!Ctrl_access_lock()) return CTRL_FAIL;
  419. memory_start_write_action(nb_sector);
  420. status =
  421. #if MAX_LUN
  422. (lun < MAX_LUN) ? lun_desc[lun].usb_write_10(addr, nb_sector) :
  423. #endif
  424. CTRL_FAIL;
  425. memory_stop_write_action();
  426. Ctrl_access_unlock();
  427. return status;
  428. }
  429. //! @}
  430. #endif // ACCESS_USB == true
  431. #if ACCESS_MEM_TO_RAM == true
  432. /*! \name MEM <-> RAM Interface
  433. */
  434. //! @{
  435. Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram)
  436. {
  437. Ctrl_status status;
  438. #if MAX_LUN==0
  439. UNUSED(lun);
  440. #endif
  441. if (!Ctrl_access_lock()) return CTRL_FAIL;
  442. memory_start_read_action(1);
  443. status =
  444. #if MAX_LUN
  445. (lun < MAX_LUN) ? lun_desc[lun].mem_2_ram(addr, ram) :
  446. #endif
  447. #if LUN_USB == ENABLE
  448. Lun_usb_mem_2_ram(addr, ram);
  449. #else
  450. CTRL_FAIL;
  451. #endif
  452. memory_stop_read_action();
  453. Ctrl_access_unlock();
  454. return status;
  455. }
  456. Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram)
  457. {
  458. Ctrl_status status;
  459. #if MAX_LUN==0
  460. UNUSED(lun);
  461. #endif
  462. if (!Ctrl_access_lock()) return CTRL_FAIL;
  463. memory_start_write_action(1);
  464. status =
  465. #if MAX_LUN
  466. (lun < MAX_LUN) ? lun_desc[lun].ram_2_mem(addr, ram) :
  467. #endif
  468. #if LUN_USB == ENABLE
  469. Lun_usb_ram_2_mem(addr, ram);
  470. #else
  471. CTRL_FAIL;
  472. #endif
  473. memory_stop_write_action();
  474. Ctrl_access_unlock();
  475. return status;
  476. }
  477. //! @}
  478. #endif // ACCESS_MEM_TO_RAM == true
  479. #if ACCESS_STREAM == true
  480. /*! \name Streaming MEM <-> MEM Interface
  481. */
  482. //! @{
  483. #if ACCESS_MEM_TO_MEM == true
  484. #include "fat.h"
  485. Ctrl_status stream_mem_to_mem(U8 src_lun, U32 src_addr, U8 dest_lun, U32 dest_addr, U16 nb_sector)
  486. {
  487. COMPILER_ALIGNED(4)
  488. static U8 sector_buf[FS_512B];
  489. Ctrl_status status = CTRL_GOOD;
  490. while (nb_sector--)
  491. {
  492. if ((status = memory_2_ram(src_lun, src_addr++, sector_buf)) != CTRL_GOOD) break;
  493. if ((status = ram_2_memory(dest_lun, dest_addr++, sector_buf)) != CTRL_GOOD) break;
  494. }
  495. return status;
  496. }
  497. #endif // ACCESS_MEM_TO_MEM == true
  498. Ctrl_status stream_state(U8 id)
  499. {
  500. UNUSED(id);
  501. return CTRL_GOOD;
  502. }
  503. U16 stream_stop(U8 id)
  504. {
  505. UNUSED(id);
  506. return 0;
  507. }
  508. //! @}
  509. #endif // ACCESS_STREAM
  510. #endif // ARDUINO_ARCH_SAM