mirror of
https://github.com/joeycastillo/second-movement.git
synced 2026-02-11 06:25:58 +00:00
156 lines
4.8 KiB
C
156 lines
4.8 KiB
C
/*
|
|
* USB mass storage class driver that mimics littlefs to FAT12 file system.
|
|
*
|
|
* Copyright 2024, Hiroyuki OYAMA. All rights reserved.
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
* - Redistributions in binary form must reproduce the above copyright notice, this
|
|
* list of conditions and the following disclaimer in the documentation and/or
|
|
* other materials provided with the distribution.
|
|
* - Neither the name of the copyright holder nor the names of its contributors may
|
|
* be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <tusb.h>
|
|
#include "mimic_fat.h"
|
|
#include "pins.h"
|
|
|
|
|
|
extern const struct lfs_config watch_lfs_cfg;
|
|
static bool ejected = false;
|
|
static bool is_initialized = false;
|
|
|
|
|
|
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
|
|
(void)lun;
|
|
|
|
if (!is_initialized) {
|
|
mimic_fat_init(&watch_lfs_cfg);
|
|
mimic_fat_update_usb_device_is_enabled(true);
|
|
mimic_fat_create_cache();
|
|
is_initialized = true;
|
|
}
|
|
|
|
const char vid[] = "littlefs";
|
|
const char pid[] = "Mass Storage";
|
|
const char rev[] = "1.0";
|
|
|
|
memcpy(vendor_id , vid, strlen(vid));
|
|
memcpy(product_id , pid, strlen(pid));
|
|
memcpy(product_rev, rev, strlen(rev));
|
|
}
|
|
|
|
bool tud_msc_test_unit_ready_cb(uint8_t lun) {
|
|
(void)lun;
|
|
return true;
|
|
}
|
|
|
|
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
|
|
(void)lun;
|
|
|
|
*block_count = mimic_fat_total_sector_size();
|
|
*block_size = DISK_SECTOR_SIZE;
|
|
|
|
printf("Block count: %lu\nBlock size: %d\n", *block_count, *block_size);
|
|
}
|
|
|
|
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) {
|
|
(void)lun;
|
|
(void)power_condition;
|
|
|
|
if (load_eject) {
|
|
if (start) {
|
|
// load disk storage
|
|
} else {
|
|
// unload disk storage
|
|
ejected = true;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
|
|
(void)lun;
|
|
(void)offset;
|
|
|
|
mimic_fat_read(lun, lba, buffer, bufsize);
|
|
|
|
return (int32_t)bufsize;
|
|
}
|
|
|
|
bool tud_msc_is_writable_cb (uint8_t lun) {
|
|
(void) lun;
|
|
return false;
|
|
}
|
|
|
|
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) {
|
|
(void)offset;
|
|
|
|
mimic_fat_write(lun, lba, buffer, bufsize);
|
|
return bufsize;
|
|
}
|
|
|
|
int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) {
|
|
void const *response = NULL;
|
|
int32_t resplen = 0;
|
|
|
|
// most scsi handled is input
|
|
bool in_xfer = true;
|
|
|
|
switch (scsi_cmd[0]) {
|
|
default:
|
|
// Set Sense = Invalid Command Operation
|
|
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
|
// negative means error -> tinyusb could stall and/or response with failed status
|
|
resplen = -1;
|
|
break;
|
|
}
|
|
|
|
// return resplen must not larger than bufsize
|
|
if (resplen > bufsize) resplen = bufsize;
|
|
|
|
if (response && (resplen > 0)) {
|
|
if(in_xfer) {
|
|
memcpy(buffer, response, (size_t) resplen);
|
|
} else {
|
|
; // SCSI output
|
|
}
|
|
}
|
|
return (int32_t)resplen;
|
|
}
|
|
|
|
void tud_mount_cb(void) {
|
|
printf("\e[45mmount\e[0m\n");
|
|
/*
|
|
* NOTE:
|
|
* This callback must be returned immediately. Time-consuming processing
|
|
* here will cause TinyUSB to PANIC `ep 0 in was already available`.
|
|
*/
|
|
is_initialized = false;
|
|
}
|
|
|
|
void tud_suspend_cb(bool remote_wakeup_en) {
|
|
(void)remote_wakeup_en;
|
|
|
|
printf("\e[45msuspend\e[0m\n");
|
|
mimic_fat_cleanup_cache();
|
|
mimic_fat_update_usb_device_is_enabled(false);
|
|
}
|