Initial files
This commit is contained in:
parent
4432d3252f
commit
10ad74f50c
BIN
Documentation/20250905 - NameCheap.pdf
Normal file
BIN
Documentation/20250905 - NameCheap.pdf
Normal file
Binary file not shown.
192
Frontend/Demo.ino/Demo.ino.ino
Normal file
192
Frontend/Demo.ino/Demo.ino.ino
Normal file
@ -0,0 +1,192 @@
|
||||
#ifndef ARDUINO_USB_MODE
|
||||
#error This ESP32 SoC has no Native USB interface
|
||||
#elif ARDUINO_USB_MODE == 1
|
||||
#warning This sketch should be used when USB is in OTG mode
|
||||
void setup() {}
|
||||
void loop() {}
|
||||
#else
|
||||
#include "USB.h"
|
||||
#include "USBMSC.h"
|
||||
|
||||
USBMSC MSC;
|
||||
|
||||
#define FAT_U8(v) ((v) & 0xFF)
|
||||
#define FAT_U16(v) FAT_U8(v), FAT_U8((v) >> 8)
|
||||
#define FAT_U32(v) FAT_U8(v), FAT_U8((v) >> 8), FAT_U8((v) >> 16), FAT_U8((v) >> 24)
|
||||
#define FAT_MS2B(s, ms) FAT_U8(((((s) & 0x1) * 1000) + (ms)) / 10)
|
||||
#define FAT_HMS2B(h, m, s) FAT_U8(((s) >> 1) | (((m) & 0x7) << 5)), FAT_U8((((m) >> 3) & 0x7) | ((h) << 3))
|
||||
#define FAT_YMD2B(y, m, d) FAT_U8(((d) & 0x1F) | (((m) & 0x7) << 5)), FAT_U8((((m) >> 3) & 0x1) | ((((y) - 1980) & 0x7F) << 1))
|
||||
#define FAT_TBL2B(l, h) FAT_U8(l), FAT_U8(((l >> 8) & 0xF) | ((h << 4) & 0xF0)), FAT_U8(h >> 4)
|
||||
|
||||
const char README_CONTENTS[] = "This is tinyusb's MassStorage Class demo.\r\n\r\nIf you find any bugs or get any questions, feel free to file an\r\nissue at github.com/hathach/tinyusb";
|
||||
|
||||
static const uint32_t DISK_SECTOR_COUNT = 500 * 8; // 8KB is the smallest size that windows allow to mount
|
||||
static const uint16_t DISK_SECTOR_SIZE = 512; // Should be 512
|
||||
static const uint16_t DISC_SECTORS_PER_TABLE = 1; //each table sector can fit 170KB (340 sectors)
|
||||
|
||||
static uint8_t* msc_disk[DISK_SECTOR_COUNT];
|
||||
|
||||
//static uint8_t msc_disk[DISK_SECTOR_COUNT][DISK_SECTOR_SIZE] = {
|
||||
const uint8_t sector0[512] =
|
||||
//------------- Block0: Boot Sector -------------//
|
||||
{ // Header (62 bytes)
|
||||
0xEB, 0x3C, 0x90, //jump_instruction
|
||||
'M', 'S', 'D', 'O', 'S', '5', '.', '0', //oem_name
|
||||
FAT_U16(DISK_SECTOR_SIZE), //bytes_per_sector
|
||||
FAT_U8(1), //sectors_per_cluster
|
||||
FAT_U16(1), //reserved_sectors_count
|
||||
FAT_U8(1), //file_alloc_tables_num
|
||||
FAT_U16(16), //max_root_dir_entries
|
||||
FAT_U16(DISK_SECTOR_COUNT), //fat12_sector_num
|
||||
0xF8, //media_descriptor
|
||||
FAT_U16(DISC_SECTORS_PER_TABLE), //sectors_per_alloc_table;//FAT12 and FAT16
|
||||
FAT_U16(1), //sectors_per_track;//A value of 0 may indicate LBA-only access
|
||||
FAT_U16(1), //num_heads
|
||||
FAT_U32(0), //hidden_sectors_count
|
||||
FAT_U32(0), //total_sectors_32
|
||||
0x00, //physical_drive_number;0x00 for (first) removable media, 0x80 for (first) fixed disk
|
||||
0x00, //reserved
|
||||
0x29, //extended_boot_signature;//should be 0x29
|
||||
FAT_U32(0x1234), //serial_number: 0x1234 => 1234
|
||||
'N', 'e', 't', 'F', 'l', 'o', 'p', 'p', 'y', ' ', ' ', //volume_label padded with spaces (0x20)
|
||||
'F', 'A', 'T', '1', '2', ' ', ' ', ' ', //file_system_type padded with spaces (0x20)
|
||||
|
||||
// Zero up to 2 last bytes of FAT magic code (448 bytes)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
//boot signature (2 bytes)
|
||||
0x55, 0xAA
|
||||
};
|
||||
|
||||
const uint8_t sector1[] = //------------- Block1: FAT12 Table -------------//
|
||||
{
|
||||
FAT_TBL2B(0xFF8, 0xFFF), FAT_TBL2B(0xFFF, 0x000) // first 2 entries must be 0xFF8 0xFFF, third entry is cluster end of readme file
|
||||
};
|
||||
|
||||
const uint8_t sector2[512] = //------------- Block2: Root Directory -------------//
|
||||
{
|
||||
// first entry is volume label
|
||||
'N', 'e', 't', 'F', 'l', 'o', 'p', 'p', 'y', ' ', ' ',
|
||||
0x08, //FILE_ATTR_VOLUME_LABEL
|
||||
0x00, FAT_MS2B(0, 0), FAT_HMS2B(0, 0, 0), FAT_YMD2B(0, 0, 0), FAT_YMD2B(0, 0, 0), FAT_U16(0), FAT_HMS2B(13, 42, 30), //last_modified_hms
|
||||
FAT_YMD2B(2025, 8, 26), //last_modified_ymd
|
||||
FAT_U16(0), FAT_U32(0),
|
||||
|
||||
// second entry is readme file
|
||||
'F', 'i', 'l', 'e', ' ', '1', ' ', ' ', //file_name[8]; padded with spaces (0x20)
|
||||
'T', 'X', 'T', //file_extension[3]; padded with spaces (0x20)
|
||||
0x20, //file attributes: FILE_ATTR_ARCHIVE
|
||||
0x00, //ignore
|
||||
FAT_MS2B(1, 980), //creation_time_10_ms (max 199x10 = 1s 990ms)
|
||||
FAT_HMS2B(13, 42, 36), //create_time_hms [5:6:5] => h:m:(s/2)
|
||||
FAT_YMD2B(2018, 11, 5), //create_time_ymd [7:4:5] => (y+1980):m:d
|
||||
FAT_YMD2B(2020, 11, 5), //last_access_ymd
|
||||
FAT_U16(0), //extended_attributes
|
||||
FAT_HMS2B(13, 44, 16), //last_modified_hms
|
||||
FAT_YMD2B(2019, 11, 5), //last_modified_ymd
|
||||
FAT_U16(2), //start of file in cluster
|
||||
FAT_U32(sizeof(README_CONTENTS) - 1) //file size
|
||||
};
|
||||
//};
|
||||
|
||||
static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize)
|
||||
{
|
||||
Serial.printf("MSC WRITE: lba: %lu, offset: %lu, bufsize: %lu\n", lba, offset, bufsize);
|
||||
memcpy(msc_disk[lba] + offset, buffer, bufsize);
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
static int32_t onRead(uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) {
|
||||
Serial.printf("MSC READ: lba: %lu, offset: %lu, bufsize: %lu\n", lba, offset, bufsize);
|
||||
memcpy(buffer, msc_disk[lba] + offset, bufsize);
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
static bool onStartStop(uint8_t power_condition, bool start, bool load_eject)
|
||||
{
|
||||
Serial.printf("MSC START/STOP: power: %u, start: %u, eject: %u\n", power_condition, start, load_eject);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void usbEventCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
|
||||
if (event_base == ARDUINO_USB_EVENTS)
|
||||
{
|
||||
arduino_usb_event_data_t *data = (arduino_usb_event_data_t *)event_data;
|
||||
|
||||
switch (event_id) {
|
||||
case ARDUINO_USB_STARTED_EVENT: Serial.println("USB PLUGGED"); break;
|
||||
case ARDUINO_USB_STOPPED_EVENT: Serial.println("USB UNPLUGGED"); break;
|
||||
case ARDUINO_USB_SUSPEND_EVENT: Serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en); break;
|
||||
case ARDUINO_USB_RESUME_EVENT: Serial.println("USB RESUMED"); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
|
||||
// Allocate each disk sector in PSRAM
|
||||
for (uint x=0; x < DISK_SECTOR_COUNT; x++)
|
||||
{
|
||||
msc_disk[x] = (uint8_t*)ps_malloc(DISK_SECTOR_SIZE * sizeof(uint8_t));
|
||||
|
||||
if (!msc_disk[x])
|
||||
{
|
||||
Serial.println("Unable to allocate memory");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(msc_disk[0], sector0, 512);
|
||||
memcpy(msc_disk[1], sector1, 6);
|
||||
memcpy(msc_disk[2], sector2, 512);
|
||||
memcpy(msc_disk[3], README_CONTENTS, 512);
|
||||
|
||||
USB.onEvent(usbEventCallback);
|
||||
MSC.vendorID("ACIT"); //max 8 chars
|
||||
MSC.productID("NetFloppy"); //max 16 chars
|
||||
MSC.productRevision("1.0"); //max 4 chars
|
||||
|
||||
MSC.onStartStop(onStartStop);
|
||||
MSC.onRead(onRead);
|
||||
MSC.onWrite(onWrite);
|
||||
MSC.mediaPresent(true);
|
||||
MSC.isWritable(true); // true if writable, false if read-only
|
||||
|
||||
MSC.begin(DISK_SECTOR_COUNT, DISK_SECTOR_SIZE);
|
||||
USB.begin();
|
||||
|
||||
Serial.print("Total PSRAM:");
|
||||
Serial.println(ESP.getPsramSize());
|
||||
Serial.print("Free PSRAM: ");
|
||||
Serial.println(ESP.getFreePsram());
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//
|
||||
}
|
||||
#endif /* ARDUINO_USB_MODE */
|
||||
5
Frontend/Demo.ino/ci.json
Normal file
5
Frontend/Demo.ino/ci.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"requires": [
|
||||
"CONFIG_SOC_USB_OTG_SUPPORTED=y"
|
||||
]
|
||||
}
|
||||
@ -28,7 +28,6 @@
|
||||
#include <FS.h>
|
||||
#include <LittleFS.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include "esp_tinyusb.h"
|
||||
#include "tusb.h"
|
||||
|
||||
// ---------------- GPIO Configuration ----------------
|
||||
@ -94,23 +93,29 @@ static const char* wifi_state() {
|
||||
}
|
||||
|
||||
// ---------------- USB MSC (TinyUSB) ----------------
|
||||
extern "C" {
|
||||
int32_t tud_msc_read10_cb (uint8_t, uint32_t lba, uint32_t off, void* buf, uint32_t len){
|
||||
if(!mscFile) return -1; uint64_t a=(uint64_t)lba*BYTES_PER_SECTOR + off;
|
||||
if(!mscFile.seek(a)) return -1; return (int32_t)mscFile.read((uint8_t*)buf, len);
|
||||
}
|
||||
int32_t tud_msc_write10_cb(uint8_t, uint32_t lba, uint32_t off, uint8_t const* buf, uint32_t len){
|
||||
if(!mscFile) return -1; uint64_t a=(uint64_t)lba*BYTES_PER_SECTOR + off;
|
||||
if(!mscFile.seek(a)) return -1; return (int32_t)mscFile.write((const uint8_t*)buf, len);
|
||||
}
|
||||
bool tud_msc_is_writable_cb(uint8_t){ return true; }
|
||||
bool tud_msc_test_unit_ready_cb(uint8_t){ return mscReady && mscFile; }
|
||||
void tud_msc_capacity_cb(uint8_t, uint32_t* bc, uint16_t* bs){ *bc=mscBlocks; *bs=BYTES_PER_SECTOR; }
|
||||
bool tud_msc_start_stop_cb(uint8_t, uint8_t, bool start, bool load_eject){
|
||||
mscReady = (start && !load_eject && mscFile); return true;
|
||||
}
|
||||
//extern "C" {
|
||||
//int32_t tud_msc_read10_cb (uint8_t, uint32_t lba, uint32_t off, void* buf, uint32_t len){
|
||||
// if(!mscFile) return -1; uint64_t a=(uint64_t)lba*BYTES_PER_SECTOR + off;
|
||||
// if(!mscFile.seek(a)) return -1; return (int32_t)mscFile.read((uint8_t*)buf, len);
|
||||
// }
|
||||
//int32_t tud_msc_write10_cb(uint8_t, uint32_t lba, uint32_t off, uint8_t const* buf, uint32_t len){
|
||||
// if(!mscFile) return -1; uint64_t a=(uint64_t)lba*BYTES_PER_SECTOR + off;
|
||||
// if(!mscFile.seek(a)) return -1; return (int32_t)mscFile.write((const uint8_t*)buf, len);
|
||||
// }
|
||||
//bool tud_msc_is_writable_cb(uint8_t){ return true; }
|
||||
//bool tud_msc_test_unit_ready_cb(uint8_t){ return mscReady && mscFile; }
|
||||
//void tud_msc_capacity_cb(uint8_t, uint32_t* bc, uint16_t* bs){ *bc=mscBlocks; *bs=BYTES_PER_SECTOR; }
|
||||
//bool tud_msc_start_stop_cb(uint8_t, uint8_t, bool start, bool load_eject)
|
||||
//{
|
||||
// mscReady = (start && !load_eject && mscFile); return true;
|
||||
//}
|
||||
//}
|
||||
static void usb_init()
|
||||
{
|
||||
tinyusb_config_t cfg={};
|
||||
tusb_init(&cfg);
|
||||
mscReady=false;
|
||||
}
|
||||
static void usb_init(){ tinyusb_config_t cfg={}; tusb_init(&cfg); mscReady=false; }
|
||||
|
||||
static bool vol_open(){
|
||||
if(mscFile) mscFile.close();
|
||||
@ -234,9 +239,9 @@ static bool https_post_volume(const String& id){
|
||||
url += "/api/volume?id="; url += id;
|
||||
|
||||
WiFiClientSecure client;
|
||||
client.setCACert(SERVER_CA_PEM);
|
||||
client.setCertificate(CLIENT_CRT_PEM);
|
||||
client.setPrivateKey(CLIENT_KEY_PEM);
|
||||
//client.setCACert(SERVER_CA_PEM);
|
||||
//client.setCertificate(CLIENT_CRT_PEM);
|
||||
//client.setPrivateKey(CLIENT_KEY_PEM);
|
||||
|
||||
HTTPClient https; if(!https.begin(client, url)){ lastNote="begin fail"; return false; }
|
||||
https.addHeader("Content-Type","application/octet-stream");
|
||||
@ -322,7 +327,7 @@ static void h_remount(){
|
||||
static void enter_loaded(){
|
||||
// Read tag
|
||||
uint64_t tag=0;
|
||||
if(!rfid_read_tag(tag, 3000)){ lastNote="no tag"; return; }
|
||||
//if(!rfid_read_tag(tag, 3000)){ lastNote="no tag"; return; }
|
||||
String id = hex64(tag);
|
||||
if(!https_fetch_volume(id)) return;
|
||||
if(!vol_open()) return;
|
||||
5
Frontend/ESP32_Firmware/test1.ino/ci.json
Normal file
5
Frontend/ESP32_Firmware/test1.ino/ci.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"requires": [
|
||||
"CONFIG_SOC_USB_OTG_SUPPORTED=y"
|
||||
]
|
||||
}
|
||||
192
Frontend/ESP32_Firmware/test1.ino/test1.ino.ino
Normal file
192
Frontend/ESP32_Firmware/test1.ino/test1.ino.ino
Normal file
@ -0,0 +1,192 @@
|
||||
#ifndef ARDUINO_USB_MODE
|
||||
#error This ESP32 SoC has no Native USB interface
|
||||
#elif ARDUINO_USB_MODE == 1
|
||||
#warning This sketch should be used when USB is in OTG mode
|
||||
void setup() {}
|
||||
void loop() {}
|
||||
#else
|
||||
#include "USB.h"
|
||||
#include "USBMSC.h"
|
||||
|
||||
USBMSC MSC;
|
||||
|
||||
#define FAT_U8(v) ((v) & 0xFF)
|
||||
#define FAT_U16(v) FAT_U8(v), FAT_U8((v) >> 8)
|
||||
#define FAT_U32(v) FAT_U8(v), FAT_U8((v) >> 8), FAT_U8((v) >> 16), FAT_U8((v) >> 24)
|
||||
#define FAT_MS2B(s, ms) FAT_U8(((((s) & 0x1) * 1000) + (ms)) / 10)
|
||||
#define FAT_HMS2B(h, m, s) FAT_U8(((s) >> 1) | (((m) & 0x7) << 5)), FAT_U8((((m) >> 3) & 0x7) | ((h) << 3))
|
||||
#define FAT_YMD2B(y, m, d) FAT_U8(((d) & 0x1F) | (((m) & 0x7) << 5)), FAT_U8((((m) >> 3) & 0x1) | ((((y) - 1980) & 0x7F) << 1))
|
||||
#define FAT_TBL2B(l, h) FAT_U8(l), FAT_U8(((l >> 8) & 0xF) | ((h << 4) & 0xF0)), FAT_U8(h >> 4)
|
||||
|
||||
const char README_CONTENTS[] = "This is tinyusb's MassStorage Class demo.\r\n\r\nIf you find any bugs or get any questions, feel free to file an\r\nissue at github.com/hathach/tinyusb";
|
||||
|
||||
static const uint32_t DISK_SECTOR_COUNT = 500 * 8; // 8KB is the smallest size that windows allow to mount
|
||||
static const uint16_t DISK_SECTOR_SIZE = 512; // Should be 512
|
||||
static const uint16_t DISC_SECTORS_PER_TABLE = 1; //each table sector can fit 170KB (340 sectors)
|
||||
|
||||
static uint8_t* msc_disk[DISK_SECTOR_COUNT];
|
||||
|
||||
//static uint8_t msc_disk[DISK_SECTOR_COUNT][DISK_SECTOR_SIZE] = {
|
||||
const uint8_t sector0[512] =
|
||||
//------------- Block0: Boot Sector -------------//
|
||||
{ // Header (62 bytes)
|
||||
0xEB, 0x3C, 0x90, //jump_instruction
|
||||
'M', 'S', 'D', 'O', 'S', '5', '.', '0', //oem_name
|
||||
FAT_U16(DISK_SECTOR_SIZE), //bytes_per_sector
|
||||
FAT_U8(1), //sectors_per_cluster
|
||||
FAT_U16(1), //reserved_sectors_count
|
||||
FAT_U8(1), //file_alloc_tables_num
|
||||
FAT_U16(16), //max_root_dir_entries
|
||||
FAT_U16(DISK_SECTOR_COUNT), //fat12_sector_num
|
||||
0xF8, //media_descriptor
|
||||
FAT_U16(DISC_SECTORS_PER_TABLE), //sectors_per_alloc_table;//FAT12 and FAT16
|
||||
FAT_U16(1), //sectors_per_track;//A value of 0 may indicate LBA-only access
|
||||
FAT_U16(1), //num_heads
|
||||
FAT_U32(0), //hidden_sectors_count
|
||||
FAT_U32(0), //total_sectors_32
|
||||
0x00, //physical_drive_number;0x00 for (first) removable media, 0x80 for (first) fixed disk
|
||||
0x00, //reserved
|
||||
0x29, //extended_boot_signature;//should be 0x29
|
||||
FAT_U32(0x1234), //serial_number: 0x1234 => 1234
|
||||
'N', 'e', 't', 'F', 'l', 'o', 'p', 'p', 'y', ' ', ' ', //volume_label padded with spaces (0x20)
|
||||
'F', 'A', 'T', '1', '2', ' ', ' ', ' ', //file_system_type padded with spaces (0x20)
|
||||
|
||||
// Zero up to 2 last bytes of FAT magic code (448 bytes)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
//boot signature (2 bytes)
|
||||
0x55, 0xAA
|
||||
};
|
||||
|
||||
const uint8_t sector1[] = //------------- Block1: FAT12 Table -------------//
|
||||
{
|
||||
FAT_TBL2B(0xFF8, 0xFFF), FAT_TBL2B(0xFFF, 0x000) // first 2 entries must be 0xFF8 0xFFF, third entry is cluster end of readme file
|
||||
};
|
||||
|
||||
const uint8_t sector2[512] = //------------- Block2: Root Directory -------------//
|
||||
{
|
||||
// first entry is volume label
|
||||
'N', 'e', 't', 'F', 'l', 'o', 'p', 'p', 'y', ' ', ' ',
|
||||
0x08, //FILE_ATTR_VOLUME_LABEL
|
||||
0x00, FAT_MS2B(0, 0), FAT_HMS2B(0, 0, 0), FAT_YMD2B(0, 0, 0), FAT_YMD2B(0, 0, 0), FAT_U16(0), FAT_HMS2B(13, 42, 30), //last_modified_hms
|
||||
FAT_YMD2B(2025, 8, 26), //last_modified_ymd
|
||||
FAT_U16(0), FAT_U32(0),
|
||||
|
||||
// second entry is readme file
|
||||
'F', 'i', 'l', 'e', ' ', '1', ' ', ' ', //file_name[8]; padded with spaces (0x20)
|
||||
'T', 'X', 'T', //file_extension[3]; padded with spaces (0x20)
|
||||
0x20, //file attributes: FILE_ATTR_ARCHIVE
|
||||
0x00, //ignore
|
||||
FAT_MS2B(1, 980), //creation_time_10_ms (max 199x10 = 1s 990ms)
|
||||
FAT_HMS2B(13, 42, 36), //create_time_hms [5:6:5] => h:m:(s/2)
|
||||
FAT_YMD2B(2018, 11, 5), //create_time_ymd [7:4:5] => (y+1980):m:d
|
||||
FAT_YMD2B(2020, 11, 5), //last_access_ymd
|
||||
FAT_U16(0), //extended_attributes
|
||||
FAT_HMS2B(13, 44, 16), //last_modified_hms
|
||||
FAT_YMD2B(2019, 11, 5), //last_modified_ymd
|
||||
FAT_U16(2), //start of file in cluster
|
||||
FAT_U32(sizeof(README_CONTENTS) - 1) //file size
|
||||
};
|
||||
//};
|
||||
|
||||
static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize)
|
||||
{
|
||||
Serial.printf("MSC WRITE: lba: %lu, offset: %lu, bufsize: %lu\n", lba, offset, bufsize);
|
||||
memcpy(msc_disk[lba] + offset, buffer, bufsize);
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
static int32_t onRead(uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) {
|
||||
Serial.printf("MSC READ: lba: %lu, offset: %lu, bufsize: %lu\n", lba, offset, bufsize);
|
||||
memcpy(buffer, msc_disk[lba] + offset, bufsize);
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
static bool onStartStop(uint8_t power_condition, bool start, bool load_eject)
|
||||
{
|
||||
Serial.printf("MSC START/STOP: power: %u, start: %u, eject: %u\n", power_condition, start, load_eject);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void usbEventCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
|
||||
if (event_base == ARDUINO_USB_EVENTS)
|
||||
{
|
||||
arduino_usb_event_data_t *data = (arduino_usb_event_data_t *)event_data;
|
||||
|
||||
switch (event_id) {
|
||||
case ARDUINO_USB_STARTED_EVENT: Serial.println("USB PLUGGED"); break;
|
||||
case ARDUINO_USB_STOPPED_EVENT: Serial.println("USB UNPLUGGED"); break;
|
||||
case ARDUINO_USB_SUSPEND_EVENT: Serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en); break;
|
||||
case ARDUINO_USB_RESUME_EVENT: Serial.println("USB RESUMED"); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
|
||||
// Allocate each disk sector in PSRAM
|
||||
for (uint x=0; x < DISK_SECTOR_COUNT; x++)
|
||||
{
|
||||
msc_disk[x] = (uint8_t*)ps_malloc(DISK_SECTOR_SIZE * sizeof(uint8_t));
|
||||
|
||||
if (!msc_disk[x])
|
||||
{
|
||||
Serial.println("Unable to allocate memory");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(msc_disk[0], sector0, 512);
|
||||
memcpy(msc_disk[1], sector1, 6);
|
||||
memcpy(msc_disk[2], sector2, 512);
|
||||
memcpy(msc_disk[3], README_CONTENTS, 512);
|
||||
|
||||
USB.onEvent(usbEventCallback);
|
||||
MSC.vendorID("ACIT"); //max 8 chars
|
||||
MSC.productID("NetFloppy"); //max 16 chars
|
||||
MSC.productRevision("1.0"); //max 4 chars
|
||||
|
||||
MSC.onStartStop(onStartStop);
|
||||
MSC.onRead(onRead);
|
||||
MSC.onWrite(onWrite);
|
||||
MSC.mediaPresent(true);
|
||||
MSC.isWritable(true); // true if writable, false if read-only
|
||||
|
||||
MSC.begin(DISK_SECTOR_COUNT, DISK_SECTOR_SIZE);
|
||||
USB.begin();
|
||||
|
||||
Serial.print("Total PSRAM:");
|
||||
Serial.println(ESP.getPsramSize());
|
||||
Serial.print("Free PSRAM: ");
|
||||
Serial.println(ESP.getFreePsram());
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//
|
||||
}
|
||||
#endif /* ARDUINO_USB_MODE */
|
||||
8
Frontend/ESP32_Firmware/test2_ino/.theia/launch.json
Normal file
8
Frontend/ESP32_Firmware/test2_ino/.theia/launch.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
]
|
||||
}
|
||||
5
Frontend/ESP32_Firmware/test2_ino/ci.json
Normal file
5
Frontend/ESP32_Firmware/test2_ino/ci.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"requires": [
|
||||
"CONFIG_SOC_USB_OTG_SUPPORTED=y"
|
||||
]
|
||||
}
|
||||
362
Frontend/ESP32_Firmware/test2_ino/test2_ino.ino
Normal file
362
Frontend/ESP32_Firmware/test2_ino/test2_ino.ino
Normal file
@ -0,0 +1,362 @@
|
||||
// ESP32-S2/S3 native USB MSC RAM disk for Arduino-ESP32 3.3.0
|
||||
// Uses USB.h / USBMSC.h (no Adafruit_TinyUSB)
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#include "USB.h"
|
||||
#include "USBMSC.h"
|
||||
#include <WiFi.h>
|
||||
#include <Preferences.h>
|
||||
|
||||
#define LED_ON 2
|
||||
#define LED_TX 43
|
||||
#define LED_RX 44
|
||||
#define BUTTON 0
|
||||
#define WS2812 48
|
||||
|
||||
// ---- Disk parameters ----
|
||||
static const uint32_t DISK_SECTOR_SIZE = 512; // 512 bytes/sector
|
||||
static const uint32_t DISK_SECTOR_COUNT = 1000 * 8; // ~2 MB (4000 * 512)
|
||||
static const uint32_t DISK_BYTE_SIZE = DISK_SECTOR_COUNT * DISK_SECTOR_SIZE;
|
||||
|
||||
static uint8_t* msc_disk = nullptr;
|
||||
static volatile bool media_ready = false;
|
||||
|
||||
USBMSC msc;
|
||||
Adafruit_NeoPixel pixels(1, WS2812, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
// Utility: bounds check for (lba, offset, len)
|
||||
static inline bool in_range(uint32_t lba, uint32_t offset, uint32_t len)
|
||||
{
|
||||
uint64_t start = (uint64_t)lba * DISK_SECTOR_SIZE + offset;
|
||||
uint64_t end = start + len;
|
||||
return end <= (uint64_t)DISK_BYTE_SIZE;
|
||||
}
|
||||
|
||||
// ---------- Settings ----------
|
||||
static const uint32_t SERIAL_BAUD = 115200;
|
||||
static const uint32_t CONNECT_TIMEOUT_MS = 20000; // 20s
|
||||
|
||||
|
||||
Preferences prefs;
|
||||
String ssid = "";
|
||||
String pass = "";
|
||||
bool autoConnect = false;
|
||||
|
||||
void loadPrefs()
|
||||
{
|
||||
prefs.begin("wifi", true); // read-only
|
||||
ssid = prefs.getString("ssid", "Barriball - Automation");
|
||||
pass = prefs.getString("pass", "password123abc");
|
||||
autoConnect = prefs.getBool("auto", true);
|
||||
prefs.end();
|
||||
}
|
||||
|
||||
|
||||
void savePrefs()
|
||||
{
|
||||
prefs.begin("wifi", false);
|
||||
prefs.putString("ssid", ssid);
|
||||
prefs.putString("pass", pass);
|
||||
prefs.putBool("auto", autoConnect);
|
||||
prefs.end();
|
||||
}
|
||||
|
||||
|
||||
void forgetPrefs()
|
||||
{
|
||||
prefs.begin("wifi", false);
|
||||
prefs.remove("ssid");
|
||||
prefs.remove("pass");
|
||||
prefs.remove("auto");
|
||||
prefs.end();
|
||||
ssid = "";
|
||||
pass = "";
|
||||
autoConnect = false;
|
||||
}
|
||||
|
||||
|
||||
void showStatus()
|
||||
{
|
||||
wl_status_t st = WiFi.status();
|
||||
|
||||
Serial.println("\n=== WiFi Status ===");
|
||||
Serial.printf("Mode: %s\n", WiFi.getMode() == WIFI_MODE_STA ? "STA" : "Other");
|
||||
Serial.printf("Saved SSID: %s\n", ssid.c_str());
|
||||
Serial.printf("Auto-connect: %s\n", autoConnect ? "ON" : "OFF");
|
||||
Serial.printf("Runtime status: %d\n", (int)st);
|
||||
|
||||
if (st == WL_CONNECTED)
|
||||
{
|
||||
Serial.printf("Connected SSID: %s\n", WiFi.SSID().c_str());
|
||||
Serial.printf("IP: %s\n", WiFi.localIP().toString().c_str());
|
||||
Serial.printf("RSSI: %d dBm\n", WiFi.RSSI());
|
||||
}
|
||||
|
||||
Serial.println("===================\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void changeMediaStatus(bool mediaPresent)
|
||||
{
|
||||
|
||||
if (mediaPresent != media_ready)
|
||||
{
|
||||
media_ready = mediaPresent;
|
||||
|
||||
msc.mediaPresent(mediaPresent);
|
||||
|
||||
if (mediaPresent)
|
||||
{
|
||||
Serial.printf("Mount disk\n");
|
||||
// Set the size of the disk
|
||||
// initialiseDisk();
|
||||
|
||||
showGreenLed();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.printf("Unmount Disk\n");
|
||||
// msc.end();
|
||||
|
||||
showOrangeLed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void showGreenLed()
|
||||
{
|
||||
pixels.setPixelColor(0, pixels.Color(0, 150, 0));
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void showOrangeLed()
|
||||
{
|
||||
pixels.setPixelColor(0, pixels.Color(150, 150, 0));
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void showRedLed()
|
||||
{
|
||||
pixels.setPixelColor(0, pixels.Color(150, 0, 0));
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void showBlueLed()
|
||||
{
|
||||
pixels.setPixelColor(0, pixels.Color(0, 0, 150));
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void usbEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool onStartStop(uint8_t power_condition, bool start, bool load_eject)
|
||||
{
|
||||
(void)power_condition;
|
||||
|
||||
// start: true = mount/open; false = stop
|
||||
// load_eject: true when host is (eject) requesting unload
|
||||
|
||||
Serial.printf("StartStop: pwr=%u start=%u load_eject=%u\n", power_condition, start, load_eject);
|
||||
|
||||
|
||||
if (load_eject && !start)
|
||||
{
|
||||
Serial.printf("Eject");
|
||||
|
||||
// Zero out storage area
|
||||
//memset(msc_disk, 0x00, DISK_BYTE_SIZE);
|
||||
|
||||
// Host requested eject
|
||||
changeMediaStatus(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (load_eject && start)
|
||||
{
|
||||
Serial.printf("Insert");
|
||||
|
||||
// Re-insert
|
||||
changeMediaStatus(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (!load_eject && !start)
|
||||
{
|
||||
Serial.printf("Stop");
|
||||
|
||||
//showRedLed();
|
||||
// Stop (could flush if backing store were non-volatile)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.printf("Start");
|
||||
|
||||
// Start
|
||||
changeMediaStatus(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void initialiseDisk()
|
||||
{
|
||||
// Zero out storage area
|
||||
memset(msc_disk, 0x00, DISK_BYTE_SIZE);
|
||||
|
||||
// Bring up native USB (CDC + MSC share the device)
|
||||
//USB.onEvent(usbEvent)
|
||||
USB.begin();
|
||||
|
||||
// int32_t (*msc_read_cb)(uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
|
||||
msc.onRead([](uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) -> int32_t
|
||||
{
|
||||
if (!media_ready)
|
||||
{
|
||||
//Serial.println("READ: media not ready");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!in_range(lba, offset, bufsize))
|
||||
{
|
||||
Serial.printf("READ OOB: lba=%lu off=%lu len=%lu\n", lba, offset, bufsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(buffer, msc_disk + (lba * DISK_SECTOR_SIZE) + offset, bufsize);
|
||||
//Serial.printf("READ lba=%lu off=%lu len=%lu\n", lba, offset, bufsize);
|
||||
return (int32_t)bufsize;
|
||||
});
|
||||
|
||||
// int32_t (*msc_write_cb)(uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
|
||||
msc.onWrite([](uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) -> int32_t
|
||||
{
|
||||
if (!media_ready)
|
||||
{
|
||||
//Serial.println("WRITE: media not ready");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!in_range(lba, offset, bufsize))
|
||||
{
|
||||
Serial.printf("WRITE OOB: lba=%lu off=%lu len=%lu\n", lba, offset, bufsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(msc_disk + (lba * DISK_SECTOR_SIZE) + offset, buffer, bufsize);
|
||||
//Serial.printf("WRITE lba=%lu off=%lu len=%lu\n", lba, offset, bufsize);
|
||||
return (int32_t)bufsize;
|
||||
});
|
||||
|
||||
msc.onStartStop(onStartStop);
|
||||
|
||||
// Set disks properties
|
||||
msc.vendorID("ACIT");
|
||||
msc.productID("NetFloppy");
|
||||
msc.productRevision("1.0");
|
||||
msc.isWritable(true);
|
||||
msc.mediaPresent(true);
|
||||
|
||||
// Set the size of the disk
|
||||
if (!msc.begin(DISK_SECTOR_COUNT, DISK_SECTOR_SIZE))
|
||||
{
|
||||
Serial.println("Error: Could not initialise USB disk");
|
||||
}
|
||||
|
||||
changeMediaStatus(true);
|
||||
// No setUnitReady() / onReady() in this API; readiness handled inside callbacks.
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
Serial.begin(SERIAL_BAUD);
|
||||
|
||||
while (!Serial)
|
||||
{
|
||||
delay(10);
|
||||
}
|
||||
|
||||
delay(200);
|
||||
|
||||
Serial.flush();
|
||||
|
||||
pinMode(LED_ON, OUTPUT);
|
||||
|
||||
digitalWrite(LED_ON, LOW);
|
||||
|
||||
pixels.begin();
|
||||
showBlueLed();
|
||||
|
||||
Serial.printf("\n\n+=====================================+\n");
|
||||
Serial.printf("| NetFloppy |\n");
|
||||
Serial.printf("| Version 1.0 |\n");
|
||||
Serial.printf("| Copyright Aqua Cube IT Limited 2025 |\n");
|
||||
Serial.printf("+=====================================+\n\n");
|
||||
|
||||
uint32_t chipId = 0;
|
||||
|
||||
for (int i = 0; i < 17; i = i + 8)
|
||||
{
|
||||
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||||
}
|
||||
|
||||
Serial.printf("ESP32 Chip model = %s Rev %d\n", ESP.getChipModel(), ESP.getChipRevision());
|
||||
Serial.printf("This chip has %d cores\n", ESP.getChipCores());
|
||||
Serial.print("Chip ID: ");
|
||||
Serial.println(chipId);
|
||||
|
||||
|
||||
Serial.printf("Initialising...\n");
|
||||
Serial.printf("Allocating memory...\n");
|
||||
|
||||
// Allocate ramdisk in PSRAM
|
||||
msc_disk = (uint8_t*) ps_malloc(DISK_BYTE_SIZE);
|
||||
|
||||
if (!msc_disk)
|
||||
{
|
||||
Serial.println("PSRAM alloc FAILED\n");
|
||||
}
|
||||
|
||||
Serial.printf("Allocated %u bytes of %u - %u Free\n", (unsigned)DISK_BYTE_SIZE, ESP.getPsramSize(), ESP.getFreePsram());
|
||||
|
||||
|
||||
loadPrefs();
|
||||
|
||||
if (ssid == "")
|
||||
{
|
||||
ssid = "Barriball - Automation";
|
||||
pass = "password123abc";
|
||||
autoConnect = true;
|
||||
|
||||
Serial.printf("SSID: '%s', Pass: '%s', Auto: %u\n", ssid.c_str(), pass.c_str(), autoConnect);
|
||||
|
||||
savePrefs();
|
||||
}
|
||||
|
||||
if (autoConnect && ssid.length())
|
||||
{
|
||||
Serial.printf("Connecting to WIFI '%s'...\n", ssid.c_str());
|
||||
//connectWiFi(ssid, pass);
|
||||
WiFi.begin(ssid.c_str(), pass.c_str());
|
||||
|
||||
showStatus();
|
||||
}
|
||||
|
||||
initialiseDisk();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Simple heartbeat
|
||||
//digitalWrite(LED_ON, !digitalRead(LED_ON));
|
||||
delay(10);
|
||||
}
|
||||
0
Frontend/test.ino
Normal file
0
Frontend/test.ino
Normal file
Loading…
Reference in New Issue
Block a user