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