-
CH376 USB MSC 다루는 방법DEVICE 2021. 1. 2. 21:15
MCU에 따라 MSC를 직접 구현할 조건이 안되는 경우가 많다.
중국의 IC중 CH376S CH376T가 이를 다룰 수 있으며,
FAT32 아마 32GBytes까지일 것이다.
해외에서 아두이노 소스가 잘 나왔던 블로그가 있었는데 막혔다.
그때 했던 파일을 받아놓은게 있어서 다행이다.
MCU에 따라 MSC를 직접 구현할 조건이 안되는 경우가 많다.
중국의 IC중 CH376S CH376T가 이를 다룰 수 있으며,
FAT32 아마 32GBytes까지일 것이다.
해외에서 아두이노 소스가 잘 나왔던 블로그가 있었는데 막혔다.
그때 했던 파일을 받아놓은게 있어서 다행이다.
다뤄보니, 이슈가 굉장히 많다.
1. Write를 할 수 있는 최대 버퍼는 한번에 256Bytes이다.
2. 그 이상의 데이터를 덧붙일때 에러가 간헐적으로 생겨서 이상한 글자가 생긴다.
3. 2번을 해결하기 위해 파일 Pointer를 움직이는 명령을 썼으나 이 또한 256Bytes까지만 쓸 수 있다.
즉, 모든 데이터 Write는 256까지가 버퍼인것 같다.
따라서, 써야할 내용이 많다면 다음과 같이 해야한다.
1. Write를 한 후 피드백 받는 데이터의 길이를 저장한다.
2. 피드백 받은 갯수가 내가 쓴 길이에 못미쳤을 시 그 시점에서 데이터 포인터를 End에 위치명령을 보내야한다.
이렇지 않으면 경우에 따라 다시 이어쓸때 긴 공백이 생길 때가 있다.
3. 소실된 시점부터의 데이터를 다시 쓴다.
아래에서 대부분의 내용이 인터럽트 통신위주로 내용이 변경되었으나, 로직 위주로 보면 된다.
//0. USB 초기화,마운팅 lUsb_ptr = 0; resetALL(); //Reset the module set_USB_Mode(0x06); //Set to USB Mode diskConnectionStatus(); //Check that communication with the USB device is possible USBdiskMount(); //Prepare the USB for reading/writing - you need to mount the USB disk for proper read/write operations. setFileName(file_name); //Set File name if(fileCreate()){ //Try to create a new file. If file creation is successful DelayMs(10); for(nTemp = 0; nTemp < 100; nTemp++) { sprintf((char*)gszMsg_temp, " 1234567890123456789012345678901234567890123456723456789012345678901234567890123456789012345678901231234567890 : %0d\n", nTemp); for(nTemp_sub = byUsb_len; nTemp_sub < sizeof(gszMsg_temp); nTemp_sub++) { gszMsg[nTemp_sub-byUsb_len] = gszMsg_temp[nTemp_sub]; } //1. 데이터 길이 전송 gbyRx7_index = 0; USBwrite(0x57); USBwrite(0xAB); USBwrite(0x3C); USBwrite((byte)strlen(gszMsg)); USBwrite((byte)0x00); if(waitForResponse("setting data Length")){ // Wait for an acknowledgement from the CH376S module before trying to send data to it if(getResponseFromUSB()==0x1E){ // 0x1E indicates that the USB device is in write mode. //2. 데이터 내용 전송 gbyRx7_index = 0; USBwrite(0x57); USBwrite(0xAB); USBwrite(0x2D); USBprint(gszMsg); // write the data to the file if(waitForResponse("writing data to file")){ // wait for an acknowledgement from the CH376S module } byUsb_len = gbyaRx7_buf[gbyRx7_index-1]; sprintf((char*)gbyaTx1_buf, "Write code.. (number bytes): %x\n", byUsb_len); LPUART_WriteBlocking(DEF_LPUART1, (uint8_t *)gbyaTx1_buf, strlen((char *)gbyaTx1_buf)); //3. 데이터 사이즈 업데이트 gbyRx7_index = 0; USBwrite(0x57); USBwrite(0xAB); USBwrite(0x3D); // This is used to update the file size. Not sure if this is necessary for successful writing. if(waitForResponse("updating file size")){ // wait for an acknowledgement from the CH376S module } sprintf((char*)gbyaTx1_buf, "get code.. (0x14): %x\n", gbyaRx7_buf[gbyRx7_index-1]); LPUART_WriteBlocking(DEF_LPUART1, (uint8_t *)gbyaTx1_buf, strlen((char *)gbyaTx1_buf)); //4. 피드백 받은 데이터 쓰기 갯수가 목표에 맞지 않으면 포인터 뒤로 하고 새로 저장 시작함 if(byUsb_len == (byte)strlen(gszMsg)) { byUsb_len = 0; } else { //5.덧붙이는 작업을 할때는 공백이 생길 수 있으므로 포인터를 마지막에 둠 USBwrite(0x57); USBwrite(0xAB); USBwrite(0x39); USBwrite(0xFF); //end of file USBwrite(0xFF); USBwrite(0xFF); USBwrite(0xFF); //DelayMs(100); if(waitForResponse("setting file pointer")){ //wait for a response from the CH376S. if(getResponseFromUSB()==0x14){ //CH376S will send 0x14 if this command was successful DebugPrint("Pointer successfully applied"); } } --nTemp; } } } } } else { DebugPrint("File could not be created, or it already exists"); } fileClose(0x01);
결과
'DEVICE' 카테고리의 다른 글
STM32 TIMER PWM NEGATIVE 동작 안할때 (0) 2023.02.24 STM32F0에서 IWDG가 작동하지 않을때 (0) 2023.01.16 WINDOWS에서 ESP-IDF 사용하기 VSCODE (0) 2023.01.14 Nanopc-T3 개발 세팅 (0) 2022.09.28 라즈베리파이 win32Diskimager를 이용해 덮어쓰기 (0) 2021.01.08