Skip to content

Commit

Permalink
Merge pull request #16 from djuseeq/SAMD
Browse files Browse the repository at this point in the history
Supports new architectures, enhancements
  • Loading branch information
djuseeq authored Dec 22, 2019
2 parents f6c6860 + 8359063 commit 00c6e31
Show file tree
Hide file tree
Showing 13 changed files with 611 additions and 280 deletions.
118 changes: 116 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
# Arduino library for CH376 file manage control chip
Support read/write files on USB flash drive. The chip support FAT16, FAT32 and FAT12 file system
Support read/write files on USB flash drive. The chip support FAT12, FAT16 and FAT32 file system

## Getting Started
Configure the jumpers on the module depending on which communication protocol you are using
Configure the jumpers on the module depending on which communication protocol you are using(see API reference)

![Alt text](extras/JumperSelect.png?raw=true "Setting")

## Versioning
v1.4.1 Dec 22, 2019
- supports more architectures(see Tested boards table below) - issue #11
- constructor update (BUSY pin is not longer used)
- improved logic to the mount/unmount flash drive
- directory support ( cd(); function )
- use advanced file listing with (*) wildcard character(API reference, listDir() function)

v1.4.0 Sep 26, 2019
- new functions
- getTotalSectors() - returns a unsigned long number, total sectors on the drive
Expand All @@ -31,6 +38,113 @@ v1.2 Apr 20, 2019
v1.1 Feb 25, 2019
- initial version with UART communication

## API Reference
```C++
//The SPI communication speed is reduced to 125 kHz because of stability if long cables or breadboard is used.
//Possible speed options(Hz): 125000,250000,500000,1000000,2000000,4000000
//To change, edit /src/Ch376msc.h file. Find the #define SPICLKRATE line and change the value.
//CONSTRUCTORS
//UART
//For hardware serial leave the communication settings on the module at default speed (9600bps)
Ch376msc(HardwareSerial, speed);//Select the serial port to which the module is connected and the desired speed(9600, 19200, 57600, 115200)

//For software serial select the desired communication speed on the module(look on the picture above)
Ch376msc(SoftwareSerial);

//SPI
//If no other device is connected to the SPI port it`s possible to save one MCU pin
Ch376msc(spiSelect);// ! Don`t use this if the SPI port is shared with other devices

//If the SPI port is shared with other devices, use this constructor and one extra MCU pin need to be sacrificed for the INT pin
Ch376msc(spiSelect, interruptPin);
////////////////////

// Must be initialized before any other command are called from this class.
init();

// call frequently to get any interrupt message of the module(attach/detach drive)
checkDrive(); //return TRUE if an interrupt request has been received, FALSE if not.

// can call before any file operation
driveReady(); //returns FALSE if no drive is present or TRUE if drive is attached and ready.

// check the communication between MCU and the CH376
pingDevice(); //returns FALSE if there is a communication failure, TRUE if communication is ok

// 8.3 filename, also called a short filename is accepted
setFileName(filename);//8 char long name + 3 char long extension

// open file before any file operation. Use first setFileName() function
openFile();

// always call this after finishing with file operations otherwise data loss or file corruption may occur
closeFile();

// repeatedly call this function to read data to buffer until the return value is TRUE
readFile(buffer, length);// buffer - char array, buffer size`

// repeatedly call this function to write data to the drive until there is no more data for write or the return value is FALSE
writeFile(buffer, length);// buffer - char array, string size in the buffer

setYear(year); // 1980 - 2099
setMonth(month);// 1 - 12
setDay(day);// 1 - 31
setHour(hour);// 0 - 23
setMinute(minute);// 0 - 59
setSecond(second);// 0 - 59 saved with 2 second resolution (0, 2, 4 ... 58)

// when new file is created the defult file creation date/time is (2004-1-1 0.0.0),
// it is possible to change date/time with this function, use first set functions above to set the file attributes
saveFileAttrb();

// move the file cursor to specified position
moveCursor(position);// 00000000h - FFFFFFFFh

// delete the specified file, use first setFileName() function
deleteFile();

// repeatedly call this function with getFileName until the return value is TRUE to get the file names from the current directory
// limited possibility to use with wildcard character e.g. listDir("AB*") will list files with names starting with AB
// listDir("*AB") will not work, wildcard char+string must to be less than 8 character long
// if no argument is passed while calling listDir(), all files will be printed from the current directory
listDir();// returns FALSE if no more file is in the current directory

//dirPath = e.g. "/DIR1/DIR2/DIR3" , "/" - root dir
//CreateDir = 0(open directories if they not exist, don`t create them) or 1(create directories if they do not exist and open them)
//if working in subfolders, before file operations ALWAYS call this function with the full directory path
//limited to 3 subfolders depth (see /src/Ch376msc.h file. MAXDIRDEPTH) and 8 character long directory names
cd(dirPath,CreateDir);// returns byte value,see example .ino

getFreeSectors();// returns unsigned long value
getTotalSectors();// returns unsigned long value
getFileSize();// returns unsigned long value (byte)
getYear();// returns int value
getMonth();// returns int value
getDay();// returns int value
getHour();// returns int value
getMinute();// returns int value
getSecond();// returns int value

getFileSystem();// returns byte value, 01h-FAT12, 02h-FAT16, 03h-FAT32
getFileName();// returns the file name in a 11+1 character long string value
getFileSizeStr();// returns file size in a formatted 9+1 character long string value
getFileAttrb();// returns byte value, see /src/CommDef.h , (File attributes)


```
## Tested boards
|Board(arch) | SPI | HW Serial | SW Serial|
|:---|:---:|:---:|:---:|
|Arduino (AVR)|OK|OK|OK|
|DUE (SAM)|OK(with INT pin)|OK|NO|
|ZERO (SAMD)|?compile ok|?|NO|
|*STM32 cores|OK|*NO|NO|
|**STM32duino|OK|OK|NO|
// * Tested on NUCLEO F446RE(no signal at all on UART ports)
// ** Tested on Generic STM32F103C alias Blue pill with STM32duino bootloader
### Acknowledgments
Thanks for the idea to Scott C , https://arduinobasics.blogspot.com/2015/05/ch376s-usb-readwrite-module.html
Expand Down
96 changes: 65 additions & 31 deletions examples/basicUsageHwSerial/basicUsageHwSerial.ino
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ unsigned long freeSect = 0;
byte percentg = 0;
byte tmpCommand; //used to store data coming from serial port
boolean readMore;

static char helpString[]= {"h:Print this help\n\n1:Create\n2:Append\n3:Read\n4:Read date/time\n"
"5:Modify date/time\n6:Delete\n7:List dir\n8:Print free space"
"\n9:Open/Create folder(s)/subfolder(s)"};

void setup() {
Serial.begin(115200);
flashDrive.init();
printInfo("h:Print this help\n\n1:Create\n2:Append\n3:Read\n4:Read date/time\n"
"5:Modify date/time\n6:Delete\n7:List dir\n8:Print free space");
printInfo(helpString);
}

void loop() {
Expand All @@ -58,15 +59,15 @@ void loop() {
case 50: //2
printInfo("COMMAND2: Append data to file: TEST1.TXT"); // Append data to the end of the file.
flashDrive.setFileName("TEST1.TXT"); //set the file name
flashDrive.openFile(); //open the file
flashDrive.moveCursor(CURSOREND); //move the "virtual" cursor at end of the file, with CURSORBEGIN we actually rewrite our old file
//flashDrive.moveCursor(flashDrive.getFileSize()); // is almost the same as CURSOREND, because we put our cursor at end of the file

if(flashDrive.openFile() == ANSW_USB_INT_SUCCESS){ //open the file
flashDrive.moveCursor(CURSOREND); //if the file exist, move the "virtual" cursor at end of the file, with CURSORBEGIN we actually rewrite our old file
//flashDrive.moveCursor(flashDrive.getFileSize()); // is almost the same as CURSOREND, because we put our cursor at end of the file
}
for(int a = 0; a < 20; a++){ //write text from string(adat) to flash drive 20 times
if(flashDrive.getFreeSectors()){ //check the free space on the drive
flashDrive.writeFile(adat2, strlen(adat2)); //string, string length
} else {
Serial.println("Disk full");
printInfo("Disk full");
}
}
flashDrive.closeFile(); //at the end, close the file
Expand Down Expand Up @@ -115,13 +116,13 @@ void loop() {
flashDrive.openFile(); //open the file

flashDrive.setYear(2019);
flashDrive.setMonth(2);
flashDrive.setDay(24);
flashDrive.setHour(15);
flashDrive.setMinute(47);
flashDrive.setSecond(26);
flashDrive.setMonth(12);
flashDrive.setDay(19);
flashDrive.setHour(03);
flashDrive.setMinute(38);
flashDrive.setSecond(42);

flashDrive.dirInfoSave(); //save the changed data
flashDrive.saveFileAttrb(); //save the changed data
flashDrive.closeFile(); //and yes again, close the file after when you don`t use it
printInfo("Done!");
break;
Expand All @@ -134,13 +135,18 @@ void loop() {
break;
//*****************************************************************************************************************************************************
case 55: //7
printInfo("COMMAND7: List root directory"); //Print all file names in the current directory
printInfo("COMMAND7: List directory"); //Print all file names in the current directory
while(flashDrive.listDir()){ // reading next file
Serial.print(flashDrive.getFileName()); // get the actual file name
Serial.print(" : ");
Serial.print(flashDrive.getFileSize()); // get the actual file size in bytes
Serial.print(" >>>\t");
Serial.println(flashDrive.getFileSizeStr()); // get the actual file size in formatted string
if(flashDrive.getFileAttrb() == ATTR_DIRECTORY){//directory
Serial.print('/');
Serial.println(flashDrive.getFileName()); // get the actual file name
} else {
Serial.print(flashDrive.getFileName()); // get the actual file name
Serial.print(" : ");
Serial.print(flashDrive.getFileSize()); // get the actual file size in bytes
Serial.print(" >>>\t");
Serial.println(flashDrive.getFileSizeStr()); // get the actual file size in formatted string
}
}
printInfo("Done!");
break;
Expand All @@ -163,28 +169,55 @@ void loop() {
} else {
Serial.print(freeSect * SECTORSIZE);
}
Serial.print("\tDisk usage :");
Serial.print(F("\tDisk usage :"));
Serial.print(percentg);
Serial.print("%");
Serial.print(F("%"));
switch (flashDrive.getFileSystem()) { //1-FAT12, 2-FAT16, 3-FAT32
case 1:
Serial.print("\tFAT12 partition");
Serial.print(F("\tFAT12 partition"));
break;
case 2:
Serial.print("\tFAT16 partition");
Serial.print(F("\tFAT16 partition"));
break;
case 3:
Serial.println("\tFAT32 partition");
Serial.println(F("\tFAT32 partition"));
break;
default:
Serial.print("\tNo valid partition");
Serial.print(F("\tNo valid partition"));
break;
}
break;
//*****************************************************************************************************************************************************
case 57: //9
switch(flashDrive.cd("/DIR1/DIR2/DIR3",1)){
case ERR_LONGFILENAME: //0x01
Serial.println(F("Directory name is too long"));
break;

case ANSW_USB_INT_SUCCESS: //0x14
Serial.println(F("Directory created successfully"));
break;

case ANSW_ERR_OPEN_DIR: //0x41
Serial.println(F("Directory opened successfully"));
break;

case ANSW_ERR_MISS_FILE: //0x42
Serial.println(F("Directory doesn`t exist"));
break;

case ANSW_ERR_FOUND_NAME: //0x43
Serial.println(F("File exist with the given name"));
break;

default:

break;
}
break;
//*****************************************************************************************************************************************************
case 104: //h
printInfo("h:Print this help\n\n1:Create\n2:Append\n3:Read\n4:Read date/time\n"
"5:Modify date/time\n6:Delete\n7:List dir\n8:Print free space");
printInfo(helpString);
break;
default:
break;
Expand All @@ -195,14 +228,15 @@ void loop() {
}//end loop

//Print information
void printInfo(const char* info){
void printInfo(char info[]){
char * infoPtr = info;
int infoLength = 0;
while(*infoPtr){
infoPtr++;
infoLength++;
if(infoLength > 40) break;
}
Serial.print("\n\n");
Serial.print(F("\n\n"));
for(int a = 0; a < infoLength; a++){
Serial.print('*');
}
Expand All @@ -211,5 +245,5 @@ void printInfo(const char* info){
for(int a = 0; a < infoLength; a++){
Serial.print('*');
}
Serial.print("\n\n");
Serial.print(F("\n\n"));
}
Loading

0 comments on commit 00c6e31

Please sign in to comment.