00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #ifdef FREERTOS_USED
00055 #include "FreeRTOS.h"
00056 #include "semphr.h"
00057 #endif
00058 #include "ctrl_access.h"
00059
00060
00061
00062
00063 #ifdef FREERTOS_USED
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #define Ctrl_access_lock() ctrl_access_lock()
00074
00075
00076
00077 #define Ctrl_access_unlock() xSemaphoreGive(ctrl_access_semphr)
00078
00079
00080
00081
00082 static xSemaphoreHandle ctrl_access_semphr = NULL;
00083
00084 #else
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 #define Ctrl_access_lock() true
00095
00096
00097
00098 #define Ctrl_access_unlock()
00099
00100
00101
00102 #endif // FREERTOS_USED
00103
00104
00105 #if MAX_LUN
00106
00107
00108
00109
00110
00111
00112
00113 #if ACCESS_USB == true && ACCESS_MEM_TO_RAM == true
00114 #define Lun_desc_entry(lun) \
00115 {\
00116 TPASTE3(Lun_, lun, _test_unit_ready),\
00117 TPASTE3(Lun_, lun, _read_capacity),\
00118 TPASTE3(Lun_, lun, _unload),\
00119 TPASTE3(Lun_, lun, _wr_protect),\
00120 TPASTE3(Lun_, lun, _removal),\
00121 TPASTE3(Lun_, lun, _usb_read_10),\
00122 TPASTE3(Lun_, lun, _usb_write_10),\
00123 TPASTE3(Lun_, lun, _mem_2_ram),\
00124 TPASTE3(Lun_, lun, _ram_2_mem),\
00125 TPASTE3(LUN_, lun, _NAME)\
00126 }
00127 #elif ACCESS_USB == true
00128 #define Lun_desc_entry(lun) \
00129 {\
00130 TPASTE3(Lun_, lun, _test_unit_ready),\
00131 TPASTE3(Lun_, lun, _read_capacity),\
00132 TPASTE3(Lun_, lun, _unload),\
00133 TPASTE3(Lun_, lun, _wr_protect),\
00134 TPASTE3(Lun_, lun, _removal),\
00135 TPASTE3(Lun_, lun, _usb_read_10),\
00136 TPASTE3(Lun_, lun, _usb_write_10),\
00137 TPASTE3(LUN_, lun, _NAME)\
00138 }
00139 #elif ACCESS_MEM_TO_RAM == true
00140 #define Lun_desc_entry(lun) \
00141 {\
00142 TPASTE3(Lun_, lun, _test_unit_ready),\
00143 TPASTE3(Lun_, lun, _read_capacity),\
00144 TPASTE3(Lun_, lun, _unload),\
00145 TPASTE3(Lun_, lun, _wr_protect),\
00146 TPASTE3(Lun_, lun, _removal),\
00147 TPASTE3(Lun_, lun, _mem_2_ram),\
00148 TPASTE3(Lun_, lun, _ram_2_mem),\
00149 TPASTE3(LUN_, lun, _NAME)\
00150 }
00151 #else
00152 #define Lun_desc_entry(lun) \
00153 {\
00154 TPASTE3(Lun_, lun, _test_unit_ready),\
00155 TPASTE3(Lun_, lun, _read_capacity),\
00156 TPASTE3(Lun_, lun, _unload),\
00157 TPASTE3(Lun_, lun, _wr_protect),\
00158 TPASTE3(Lun_, lun, _removal),\
00159 TPASTE3(LUN_, lun, _NAME)\
00160 }
00161 #endif
00162
00163
00164 static const struct {
00165 Ctrl_status (*test_unit_ready)(void);
00166 Ctrl_status (*read_capacity)(uint32_t *);
00167 bool (*unload)(bool);
00168 bool (*wr_protect)(void);
00169 bool (*removal)(void);
00170 #if ACCESS_USB == true
00171 Ctrl_status (*usb_read_10)(uint32_t, U16);
00172 Ctrl_status (*usb_write_10)(uint32_t, U16);
00173 #endif
00174 #if ACCESS_MEM_TO_RAM == true
00175 Ctrl_status (*mem_2_ram)(uint32_t, void *);
00176 Ctrl_status (*ram_2_mem)(uint32_t, const void *);
00177 #endif
00178 const char *name;
00179 } lun_desc[MAX_LUN] = {
00180 #if LUN_0 == ENABLE
00181 # ifndef Lun_0_unload
00182 # define Lun_0_unload NULL
00183 # endif
00184 Lun_desc_entry(0),
00185 #endif
00186 #if LUN_1 == ENABLE
00187 # ifndef Lun_1_unload
00188 # define Lun_1_unload NULL
00189 # endif
00190 Lun_desc_entry(1),
00191 #endif
00192 #if LUN_2 == ENABLE
00193 # ifndef Lun_2_unload
00194 # define Lun_2_unload NULL
00195 # endif
00196 Lun_desc_entry(2),
00197 #endif
00198 #if LUN_3 == ENABLE
00199 # ifndef Lun_3_unload
00200 # define Lun_3_unload NULL
00201 # endif
00202 Lun_desc_entry(3),
00203 #endif
00204 #if LUN_4 == ENABLE
00205 # ifndef Lun_4_unload
00206 # define Lun_4_unload NULL
00207 # endif
00208 Lun_desc_entry(4),
00209 #endif
00210 #if LUN_5 == ENABLE
00211 # ifndef Lun_5_unload
00212 # define Lun_5_unload NULL
00213 # endif
00214 Lun_desc_entry(5),
00215 #endif
00216 #if LUN_6 == ENABLE
00217 # ifndef Lun_6_unload
00218 # define Lun_6_unload NULL
00219 # endif
00220 Lun_desc_entry(6),
00221 #endif
00222 #if LUN_7 == ENABLE
00223 # ifndef Lun_7_unload
00224 # define Lun_7_unload NULL
00225 # endif
00226 Lun_desc_entry(7)
00227 #endif
00228 };
00229
00230 #endif
00231
00232
00233 #if GLOBAL_WR_PROTECT == true
00234 bool g_wr_protect;
00235 #endif
00236
00237
00238
00239
00240
00241
00242
00243 #ifdef FREERTOS_USED
00244
00245 bool ctrl_access_init(void)
00246 {
00247
00248 if (!ctrl_access_semphr) {
00249
00250 vSemaphoreCreateBinary(ctrl_access_semphr);
00251
00252
00253 if (!ctrl_access_semphr) return false;
00254 }
00255
00256 return true;
00257 }
00258
00259
00260
00261
00262
00263
00264 static bool ctrl_access_lock(void)
00265 {
00266
00267 if (!ctrl_access_semphr) return false;
00268
00269
00270 while (!xSemaphoreTake(ctrl_access_semphr, portMAX_DELAY));
00271
00272 return true;
00273 }
00274
00275 #endif // FREERTOS_USED
00276
00277
00278 uint8_t get_nb_lun(void)
00279 {
00280 #if MEM_USB == ENABLE
00281 # ifndef Lun_usb_get_lun
00282 # define Lun_usb_get_lun() host_get_lun()
00283 # endif
00284 uint8_t nb_lun;
00285
00286 if (!Ctrl_access_lock()) return MAX_LUN;
00287
00288 nb_lun = MAX_LUN + Lun_usb_get_lun();
00289
00290 Ctrl_access_unlock();
00291
00292 return nb_lun;
00293 #else
00294 return MAX_LUN;
00295 #endif
00296 }
00297
00298
00299 uint8_t get_cur_lun(void)
00300 {
00301 return LUN_ID_0;
00302 }
00303
00304
00305 Ctrl_status mem_test_unit_ready(uint8_t lun)
00306 {
00307 Ctrl_status status;
00308
00309 if (!Ctrl_access_lock()) return CTRL_FAIL;
00310
00311 status =
00312 #if MAX_LUN
00313 (lun < MAX_LUN) ? lun_desc[lun].test_unit_ready() :
00314 #endif
00315 #if LUN_USB == ENABLE
00316 Lun_usb_test_unit_ready(lun - LUN_ID_USB);
00317 #else
00318 CTRL_FAIL;
00319 #endif
00320
00321 Ctrl_access_unlock();
00322
00323 return status;
00324 }
00325
00326
00327 Ctrl_status mem_read_capacity(uint8_t lun, uint32_t *u32_nb_sector)
00328 {
00329 Ctrl_status status;
00330
00331 if (!Ctrl_access_lock()) return CTRL_FAIL;
00332
00333 status =
00334 #if MAX_LUN
00335 (lun < MAX_LUN) ? lun_desc[lun].read_capacity(u32_nb_sector) :
00336 #endif
00337 #if LUN_USB == ENABLE
00338 Lun_usb_read_capacity(lun - LUN_ID_USB, u32_nb_sector);
00339 #else
00340 CTRL_FAIL;
00341 #endif
00342
00343 Ctrl_access_unlock();
00344
00345 return status;
00346 }
00347
00348
00349 uint8_t mem_sector_size(uint8_t lun)
00350 {
00351 uint8_t sector_size;
00352
00353 if (!Ctrl_access_lock()) return 0;
00354
00355 sector_size =
00356 #if MAX_LUN
00357 (lun < MAX_LUN) ? 1 :
00358 #endif
00359 #if LUN_USB == ENABLE
00360 Lun_usb_read_sector_size(lun - LUN_ID_USB);
00361 #else
00362 0;
00363 #endif
00364
00365 Ctrl_access_unlock();
00366
00367 return sector_size;
00368 }
00369
00370
00371 bool mem_unload(uint8_t lun, bool unload)
00372 {
00373 bool unloaded;
00374 #if !MAX_LUN || !defined(Lun_usb_unload)
00375 UNUSED(lun);
00376 #endif
00377
00378 if (!Ctrl_access_lock()) return false;
00379
00380 unloaded =
00381 #if MAX_LUN
00382 (lun < MAX_LUN) ?
00383 (lun_desc[lun].unload ?
00384 lun_desc[lun].unload(unload) : !unload) :
00385 #endif
00386 #if LUN_USB == ENABLE
00387 # if defined(Lun_usb_unload)
00388 Lun_usb_unload(lun - LUN_ID_USB, unload);
00389 # else
00390 !unload;
00391 # endif
00392 #else
00393 false;
00394 #endif
00395
00396 Ctrl_access_unlock();
00397
00398 return unloaded;
00399 }
00400
00401 bool mem_wr_protect(uint8_t lun)
00402 {
00403 bool wr_protect;
00404
00405 if (!Ctrl_access_lock()) return true;
00406
00407 wr_protect =
00408 #if MAX_LUN
00409 (lun < MAX_LUN) ? lun_desc[lun].wr_protect() :
00410 #endif
00411 #if LUN_USB == ENABLE
00412 Lun_usb_wr_protect(lun - LUN_ID_USB);
00413 #else
00414 true;
00415 #endif
00416
00417 Ctrl_access_unlock();
00418
00419 return wr_protect;
00420 }
00421
00422
00423 bool mem_removal(uint8_t lun)
00424 {
00425 bool removal;
00426 #if MAX_LUN==0
00427 UNUSED(lun);
00428 #endif
00429
00430 if (!Ctrl_access_lock()) return true;
00431
00432 removal =
00433 #if MAX_LUN
00434 (lun < MAX_LUN) ? lun_desc[lun].removal() :
00435 #endif
00436 #if LUN_USB == ENABLE
00437 Lun_usb_removal();
00438 #else
00439 true;
00440 #endif
00441
00442 Ctrl_access_unlock();
00443
00444 return removal;
00445 }
00446
00447
00448 const char *mem_name(uint8_t lun)
00449 {
00450 #if MAX_LUN==0
00451 UNUSED(lun);
00452 #endif
00453 return
00454 #if MAX_LUN
00455 (lun < MAX_LUN) ? lun_desc[lun].name :
00456 #endif
00457 #if LUN_USB == ENABLE
00458 LUN_USB_NAME;
00459 #else
00460 NULL;
00461 #endif
00462 }
00463
00464
00465
00466
00467
00468 #if ACCESS_USB == true
00469
00470
00471
00472
00473
00474
00475 Ctrl_status memory_2_usb(uint8_t lun, uint32_t addr, U16 nb_sector)
00476 {
00477 Ctrl_status status;
00478
00479 if (!Ctrl_access_lock()) return CTRL_FAIL;
00480
00481 memory_start_read_action(nb_sector);
00482 status =
00483 #if MAX_LUN
00484 (lun < MAX_LUN) ? lun_desc[lun].usb_read_10(addr, nb_sector) :
00485 #endif
00486 CTRL_FAIL;
00487 memory_stop_read_action();
00488
00489 Ctrl_access_unlock();
00490
00491 return status;
00492 }
00493
00494
00495 Ctrl_status usb_2_memory(uint8_t lun, uint32_t addr, U16 nb_sector)
00496 {
00497 Ctrl_status status;
00498
00499 if (!Ctrl_access_lock()) return CTRL_FAIL;
00500
00501 memory_start_write_action(nb_sector);
00502 status =
00503 #if MAX_LUN
00504 (lun < MAX_LUN) ? lun_desc[lun].usb_write_10(addr, nb_sector) :
00505 #endif
00506 CTRL_FAIL;
00507 memory_stop_write_action();
00508
00509 Ctrl_access_unlock();
00510
00511 return status;
00512 }
00513
00514
00515
00516
00517 #endif // ACCESS_USB == true
00518
00519
00520 #if ACCESS_MEM_TO_RAM == true
00521
00522
00523
00524
00525
00526
00527 Ctrl_status memory_2_ram(uint8_t lun, uint32_t addr, void *ram)
00528 {
00529 Ctrl_status status;
00530 #if MAX_LUN==0
00531 UNUSED(lun);
00532 #endif
00533
00534 if (!Ctrl_access_lock()) return CTRL_FAIL;
00535
00536 memory_start_read_action(1);
00537 status =
00538 #if MAX_LUN
00539 (lun < MAX_LUN) ? lun_desc[lun].mem_2_ram(addr, ram) :
00540 #endif
00541 #if LUN_USB == ENABLE
00542 Lun_usb_mem_2_ram(addr, ram);
00543 #else
00544 CTRL_FAIL;
00545 #endif
00546 memory_stop_read_action();
00547
00548 Ctrl_access_unlock();
00549
00550 return status;
00551 }
00552
00553
00554 Ctrl_status ram_2_memory(uint8_t lun, uint32_t addr, const void *ram)
00555 {
00556 Ctrl_status status;
00557 #if MAX_LUN==0
00558 UNUSED(lun);
00559 #endif
00560
00561 if (!Ctrl_access_lock()) return CTRL_FAIL;
00562
00563 memory_start_write_action(1);
00564 status =
00565 #if MAX_LUN
00566 (lun < MAX_LUN) ? lun_desc[lun].ram_2_mem(addr, ram) :
00567 #endif
00568 #if LUN_USB == ENABLE
00569 Lun_usb_ram_2_mem(addr, ram);
00570 #else
00571 CTRL_FAIL;
00572 #endif
00573 memory_stop_write_action();
00574
00575 Ctrl_access_unlock();
00576
00577 return status;
00578 }
00579
00580
00581
00582
00583 #endif // ACCESS_MEM_TO_RAM == true
00584
00585
00586 #if ACCESS_STREAM == true
00587
00588
00589
00590
00591
00592
00593 #if ACCESS_MEM_TO_MEM == true
00594
00595 #include "fat.h"
00596
00597 Ctrl_status stream_mem_to_mem(uint8_t src_lun, uint32_t src_addr,
00598 uint8_t dest_lun, uint32_t dest_addr, U16 nb_sector)
00599 {
00600 COMPILER_ALIGNED(4)
00601 static uint8_t sector_buf[FS_512B];
00602 Ctrl_status status = CTRL_GOOD;
00603
00604 while (nb_sector--) {
00605 if ((status = memory_2_ram(src_lun, src_addr++,
00606 sector_buf)) != CTRL_GOOD) break;
00607
00608 if ((status = ram_2_memory(dest_lun, dest_addr++,
00609 sector_buf)) != CTRL_GOOD) break;
00610 }
00611
00612 return status;
00613 }
00614
00615 #endif // ACCESS_MEM_TO_MEM == true
00616
00617
00618 Ctrl_status stream_state(uint8_t id)
00619 {
00620 UNUSED(id);
00621 return CTRL_GOOD;
00622 }
00623
00624
00625 U16 stream_stop(uint8_t id)
00626 {
00627 UNUSED(id);
00628 return 0;
00629 }
00630
00631
00632
00633
00634 #endif // ACCESS_STREAM == true