ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CH376 USB MSC 다루는 방법
    DEVICE 2021. 1. 2. 21:15

    MCU에 따라 MSC를 직접 구현할 조건이 안되는 경우가 많다.

    중국의 IC중 CH376S CH376T가 이를 다룰 수 있으며,

    FAT32 아마 32GBytes까지일 것이다.

    해외에서 아두이노 소스가 잘 나왔던 블로그가 있었는데 막혔다.

    그때 했던 파일을 받아놓은게 있어서 다행이다.

     

    msc.c
    0.02MB

     

    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);

     

    결과

     

    댓글

Designed by Tistory.