/** @brief Flush any caches beneath the file system. @param bVolNum The volume number of the volume whose block device is being flushed. @return A negated ::REDSTATUS code indicating the operation result. @retval 0 Operation was successful. */ static REDSTATUS DiskFlush( uint8_t bVolNum) { REDSTATUS ret; DRESULT result; result = disk_ioctl(bVolNum, CTRL_SYNC, NULL); if(result == RES_OK) { ret = 0; } else { ret = -RED_EIO; } return ret; }
//***************************************************************************** // // This function opens the drive number and prepares it for use by the Mass // storage class device. // // /param ulDrive is the driver number to open. // // This function is used to initialize and open the physical drive number // associated with the parameter /e ulDrive. The function will return zero if // the drive could not be opened for some reason. In the case of removable // device like an SD card this function should return zero if the SD card is // not present. // // /return Returns a pointer to data that should be passed to other APIs or it // will return 0 if no drive was found. // //***************************************************************************** void * USBDMSCStorageOpen(unsigned long ulDrive) { unsigned char ucPower; unsigned long ulTemp; ASSERT(ulDrive == 0); // // Return if already in use. // if(g_sDriveInformation.ulFlags & SDCARD_IN_USE) { return(0); } // // Initialize the drive if it is present. // ulTemp = disk_initialize(0); if(ulTemp == RES_OK) { // // Power up the card. // ucPower = 1; disk_ioctl(0, CTRL_POWER, &ucPower); // // Card is present and in use. // g_sDriveInformation.ulFlags = SDCARD_PRESENT | SDCARD_IN_USE; } else if(ulTemp == STA_NODISK) { // // Allocate the card but it is not present. // g_sDriveInformation.ulFlags = SDCARD_IN_USE; } else { return(0); } return((void *)&g_sDriveInformation); }
//***************************************************************************** // // This function will return the number of blocks present on a device. // // /param pvDrive is the pointer that was returned from a call to // USBDMSCStorageOpen(). // // This function is used to return the total number of blocks on a physical // device based on the /e pvDrive parameter. // // /return Returns the number of blocks that are present in a device. // //***************************************************************************** unsigned int USBDMSCStorageNumBlocks(void * pvDrive) { unsigned int ulSectorCount = 0; // // Read the number of sectors. // disk_ioctl(0, GET_SECTOR_COUNT, &ulSectorCount); return(ulSectorCount); }
/**************************************************************************//** * @brief * Initialize the storage media interface. *****************************************************************************/ bool MSDDMEDIA_Init( void ) { #if ( MSD_MEDIA != MSD_SDCARD_MEDIA ) && ( MSD_MEDIA != MSD_NORFLASH_MEDIA ) numSectors = MEDIA_SIZE / 512; #endif #if ( MSD_MEDIA == MSD_PSRAM_MEDIA ) storage = (uint8_t*)EBI_BankAddress( EBI_BANK2 ); storage[0] = 0; /* To force new "format disk" when host detects disk. */ #endif #if ( MSD_MEDIA == MSD_SDCARD_MEDIA ) /* Enable SPI access to MicroSD card */ BSP_PeripheralAccess( BSP_MICROSD, true ); MICROSD_Init(); if ( disk_initialize( 0 ) != 0 ) return false; /* Get numSectors from media. */ if ( disk_ioctl( 0, GET_SECTOR_COUNT, &numSectors ) != RES_OK ) return false; #endif #if ( MSD_MEDIA == MSD_FLASH_MEDIA ) flashStatus.pendingWrite = false; MSC_Init(); /* Unlock and calibrate flash timing */ MSC_Deinit(); /* Lock flash */ #endif #if ( MSD_MEDIA == MSD_NORFLASH_MEDIA ) flashStatus.pendingWrite = false; NORFLASH_Init(); /* Initialize NORFLASH interface */ storage = (uint8_t*)NORFLASH_DeviceInfo()->baseAddress; flashPageSize = NORFLASH_DeviceInfo()->sectorSize; /* Use external PSRAM as page (flash sector) buffer */ flashPageBuf = (uint8_t*)EBI_BankAddress( EBI_BANK2 ); numSectors = NORFLASH_DeviceInfo()->deviceSize / 512; #endif return true; }
//***************************************************************************** // // This function close the drive number in use by the mass storage class device. // // /param pvDrive is the pointer that was returned from a call to // USBDMSCStorageOpen(). // // This function is used to close the physical drive number associated with the // parameter /e pvDrive. This function will return 0 if the drive was closed // successfully and any other value will indicate a failure. // // /return Returns 0 if the drive was successfully closed or non-zero for a // failure. // //***************************************************************************** void USBDMSCStorageClose(void * pvDrive) { unsigned char ucPower; ASSERT(pvDrive != 0); // // Clear all flags. // g_sDriveInformation.ulFlags = 0; // // Power up the card. // ucPower = 0; // // Turn off the power to the card. // disk_ioctl(0, CTRL_POWER, &ucPower); }
// This function checks for insertion/removal of the card. If either is detected, it informs the API // by calling USBMSC_updateMediaInfo(). Whether it detects it or not, it returns non-zero if the card // is present, or zero if not present BYTE checkInsertionRemoval(void) { BYTE newCardStatus = detectCard(); // Check card status -- there or not? if((newCardStatus) && (mediaInfo.mediaPresent == kUSBMSC_MEDIA_NOT_PRESENT)) { // An insertion has been detected -- inform the API mediaInfo.mediaPresent = kUSBMSC_MEDIA_PRESENT; mediaInfo.mediaChanged = 0x01; DRESULT SDCard_result = disk_ioctl(0,GET_SECTOR_COUNT,&mediaInfo.lastBlockLba); // Get the size of this new medium USBMSC_updateMediaInfo(1, &mediaInfo); } if ((!newCardStatus) && (mediaInfo.mediaPresent == kUSBMSC_MEDIA_PRESENT)) { // A removal has been detected -- inform the API mediaInfo.mediaPresent = kUSBMSC_MEDIA_NOT_PRESENT; mediaInfo.mediaChanged = 0x01; USBMSC_updateMediaInfo(1, &mediaInfo); } return newCardStatus; }
/* * This function initializes the MSC data variables */ void USBMSC_initMSC(void) { //SD-cards must go through a setup sequence after powerup. //This FatFs call does this. disk_initialize(0); //The API maintains an instance of the USBMSC_RWbuf_Info structure.This is // a shared resource between the API and application; the application must //request the pointer. RWbuf_info = USBMSC_fetchInformationStructure(); //USBMSC_updateMediaInformation() must be called prior to USB connection. We //check if the card is present, and if so, pull its size and bytes per //block. if (detectCard()){ mediaInfo.mediaPresent = USBMSC_MEDIA_PRESENT; } else { mediaInfo.mediaPresent = USBMSC_MEDIA_NOT_PRESENT; } mediaInfo.mediaChanged = 0x00; mediaInfo.writeProtected = 0x00; //Returns the number of blocks (sectors) in the media. disk_ioctl(0,GET_SECTOR_COUNT,&mediaInfo.lastBlockLba); //Block size will always be 512 mediaInfo.bytesPerBlock = BYTES_PER_BLOCK; USBMSC_updateMediaInformation(0, &mediaInfo); //The data interchange buffer (used when handling SCSI READ/WRITE) is //declared by the application, and registered with the API using this //function. This allows it to be assigned dynamically, giving //the application more control over memory management. USBMSC_registerBufferInformation(0, &RWbuf[0], NULL, sizeof(RWbuf)); }
void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop the watchdog __enable_interrupt(); // Enable general interrupts Board_init(); // Configure's the F5529 EXP board's I/Os // Initialize power/clocks for use with USB SetVCore(3); // The USB module requires that VCore be set to highest setting, independent of MCLK freq ClockUSB(); disk_initialize(0); // SD-cards must go through a setup sequence after powerup. This FatFs call does this. USB_init(); // Initializes the USB API, and prepares the USB module to detect USB insertion/removal events USB_setEnabledEvents(kUSB_allUsbEvents); // Enable all USB events // The data interchange buffer (used when handling SCSI READ/WRITE) is declared by the application, and // registered with the API using this function. This allows it to be assigned dynamically, giving // the application more control over memory management. USBMSC_registerBufInfo(&RW_dataBuf[0], NULL, sizeof(RW_dataBuf)); // The API maintains an instance of the USBMSC_RWbuf_Info structure. If double-buffering were used, it would // maintain one for both the X and Y side. (This version of the API only supports single-buffering, // so only one structure is maintained.) This is a shared resource between the API and application; the // application must request the pointers. RWbuf_info = USBMSC_fetchInfoStruct(); // USBMSC_updateMediaInfo() must be called prior to USB connection. We check if the card is present, and if so, pull its size // and bytes per block. // LUN0 mediaInfo.mediaPresent = 0x01; // The medium is present, because internal flash is non-removable. mediaInfo.mediaChanged = 0x00; // It can't change, because it's in internal memory, which is always present. mediaInfo.writeProtected = 0x00; // It's not write-protected mediaInfo.lastBlockLba = 774; // 774 blocks in the volume. (This number is also found twice in the volume itself; see mscFseData.c. They should match.) mediaInfo.bytesPerBlock = BYTES_PER_BLOCK; // 512 bytes per block. (This number is also found in the volume itself; see mscFseData.c. They should match.) USBMSC_updateMediaInfo(0, &mediaInfo); // LUN1 if(detectCard()) mediaInfo.mediaPresent = kUSBMSC_MEDIA_PRESENT; else mediaInfo.mediaPresent = kUSBMSC_MEDIA_NOT_PRESENT; mediaInfo.mediaChanged = 0x00; mediaInfo.writeProtected = 0x00; disk_ioctl(0,GET_SECTOR_COUNT,&mediaInfo.lastBlockLba); // Returns the number of blocks (sectors) in the media. mediaInfo.bytesPerBlock = BYTES_PER_BLOCK; // Block size will always be 512 USBMSC_updateMediaInfo(1, &mediaInfo); // At compile-time for this demo, there will be one file on the volume. The root directory and data cluster // for this file need to be initialized. //flashWrite_LBA(Root_Dir, (BYTE*)Root_Dir_init); //flashWrite_LBA(Data559, (BYTE*)Data559_init); // Configure Timer_A0 to prompt detection of the SD card every second TA0CCTL0 = CCIE; // Enable interrupt TA0CCR0 = 32768; // Clock will be 32kHz, so we set the int to occur when it counts to 32768 TA0CTL = TASSEL_1 + MC_1 + TACLR; // ACLK = 32kHz, up mode, clear TAR... go! // If USB is already connected when the program starts up, then there won't be a USB_handleVbusOnEvent(). // So we need to check for it, and manually connect if the host is already present. if (USB_connectionInfo() & kUSB_vbusPresent) { if (USB_enable() == kUSB_succeed) { USB_reset(); USB_connect(); } } while(1) { BYTE ReceiveError=0, SendError=0; WORD count; switch(USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 until VBUS-on event // Check if the reason we woke was a button press; and if so, log a new piece of data. if(fS1ButtonEvent) { // Build string char str[14] = "Data entry #0\n"; str[12] = logCnt++; // Number the entries 0 through....? memcpy(RW_dataBuf, Data559, BYTES_PER_BLOCK); // Copy data block 559 from flash to RAM buffer memcpy(&RW_dataBuf[DataCnt], str, sizeof(str)); // Write the new entry to the RAM buffer flashWrite_LBA((PBYTE)Data559, RW_dataBuf); // Copy it back to flash DataCnt += sizeof(str); // Increment the index past the new entry if((DataCnt + sizeof(str)>= BYTES_PER_BLOCK)) // Roll index back to 0, if no more room in the block DataCnt = 0; fS1ButtonEvent = 0; } break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: // Call USBMSC_poll() to initiate handling of any received SCSI commands. Disable interrupts // during this function, to avoid conflicts arising from SCSI commands being received from the host // AFTER decision to enter LPM is made, but BEFORE it's actually entered (in other words, avoid // sleeping accidentally). __disable_interrupt(); if((USBMSC_poll() == kUSBMSC_okToSleep) && (!bDetectCard)) { __bis_SR_register(LPM0_bits + GIE); // Enable interrupts atomically with LPM0 entry } __enable_interrupt(); // If the API needs the application to process a buffer, it will keep the CPU awake by returning kUSBMSC_processBuffer // from USBMSC_poll(). The application should then check the 'operation' field of all defined USBMSC_RWbuf_Info // structure instances. If any of them is non-null, then an operation needs to be processed. A value of // kUSBMSC_READ indicates the API is waiting for the application to fetch data from the storage volume, in response // to a SCSI READ command from the USB host. After the application does this, it must indicate whether the // operation succeeded, and then close the buffer operation by calling USBMSC_bufferProcessed(). while(RWbuf_info->operation == kUSBMSC_READ) { switch(RWbuf_info->lun) { case 0: RWbuf_info->returnCode = Read_LBA(RWbuf_info->lba, RWbuf_info->bufferAddr, RWbuf_info->lbCount); // Fetch a block from the medium, using file system emulation USBMSC_bufferProcessed(); // Close the buffer operation break; case 1: read_LUN1(); break; } } // Everything in this section is analogous to READs. Reference the comments above. while(RWbuf_info->operation == kUSBMSC_WRITE) { switch(RWbuf_info->lun) { case 0: RWbuf_info->returnCode = Write_LBA(RWbuf_info->lba, RWbuf_info->bufferAddr, RWbuf_info->lbCount); // Write the block to the medium, using file system emulation USBMSC_bufferProcessed(); // Close the buffer operation break; case 1: write_LUN1(); break; } } // Every second, the Timer_A ISR sets this flag. The checking can't be done from within the timer ISR, because the // checking enables interrupts, and this is not a recommended practice due to the risk of nested interrupts. if(bDetectCard) { checkInsertionRemoval(); bDetectCard = 0x00; // Clear the flag, until the next timer ISR } if(bHID_DataReceived_event) //Message is received from HID application { bHID_DataReceived_event = FALSE; // Clear flag early -- just in case execution breaks below because of an error count = hidReceiveDataInBuffer((BYTE*)dataBuffer,BUFFER_SIZE,HID0_INTFNUM); strncat(wholeString," \r\nRx->",7); strncat(wholeString,(char*)dataBuffer,count); strncat(wholeString," \r\n ",4); if(cdcSendDataInBackground((BYTE*)wholeString,strlen(wholeString),CDC0_INTFNUM,1)) // Send message to other CDC App { SendError = 0x01; break; } memset(wholeString,0,MAX_STR_LENGTH); // Clear wholeString } if(bCDC_DataReceived_event) //Message is received from CDC application { bCDC_DataReceived_event = FALSE; // Clear flag early -- just in case execution breaks below because of an error cdcReceiveDataInBuffer((BYTE*)wholeString,MAX_STR_LENGTH,CDC0_INTFNUM); ASCII(wholeString); if(hidSendDataInBackground((BYTE*)wholeString,strlen(wholeString),HID0_INTFNUM,1)) // Send message to HID App { SendError = 0x01; // Something went wrong -- exit break; } memset(wholeString,0,MAX_STR_LENGTH); // Clear wholeString } break; case ST_ENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3, until a resume or VBUS-off event break; case ST_ENUM_IN_PROGRESS: break; case ST_ERROR: break; default:; } if(ReceiveError || SendError) { //TO DO: User can place code here to handle error } } }
/** @brief Initialize a disk. @param bVolNum The volume number of the volume whose block device is being initialized. @param mode The open mode, indicating the type of access required. @return A negated ::REDSTATUS code indicating the operation result. @retval 0 Operation was successful. @retval -RED_EIO A disk I/O error occurred. */ static REDSTATUS DiskOpen( uint8_t bVolNum, BDEVOPENMODE mode) { DSTATUS status; uint32_t ulTries; REDSTATUS ret = 0; /* With some implementations of disk_initialize(), such as the one implemented by Atmel for the ASF, the first time the disk is opened, the SD card can take a while to get ready, in which time disk_initialize() returns an error. Try numerous times, waiting half a second after each failure. Empirically, this has been observed to succeed on the second try, so trying 10x more than that provides a margin of error. */ for(ulTries = 0U; ulTries < 20U; ulTries++) { /* Assuming that the volume number is also the correct drive number. If this is not the case in your environment, a static constant array can be declared to map volume numbers to the correct driver number. */ status = disk_initialize(bVolNum); if(status == 0) { break; } vTaskDelay(500U / portTICK_PERIOD_MS); } if(status != 0) { ret = -RED_EIO; } /* Retrieve the sector size and sector count to ensure they are compatible with our compile-time geometry. */ if(ret == 0) { WORD wSectorSize; DWORD dwSectorCount; DRESULT result; result = disk_ioctl(bVolNum, GET_SECTOR_SIZE, &wSectorSize); if(result == RES_OK) { result = disk_ioctl(bVolNum, GET_SECTOR_COUNT, &dwSectorCount); if(result == RES_OK) { if( (wSectorSize != gaRedVolConf[bVolNum].ulSectorSize) || (dwSectorCount < gaRedVolConf[bVolNum].ullSectorCount)) { ret = -RED_EINVAL; } } else { ret = -RED_EIO; } } else { ret = -RED_EIO; } } return ret; }
extern void fatfs_umount(void) { f_mount(0, 0); disk_ioctl(0, CTRL_POWER, 0); //power off }
int mcdioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) { struct mcd_softc *sc = device_lookup_private(&mcd_cd, MCDUNIT(dev)); int error; int part; #ifdef __HAVE_OLD_DISKLABEL struct disklabel newlabel; #endif MCD_TRACE("ioctl: cmd=0x%lx\n", cmd); if ((sc->flags & MCDF_LOADED) == 0) return EIO; error = disk_ioctl(&sc->sc_dk, dev, cmd, addr, flag, l); if (error != EPASSTHROUGH) return error; part = MCDPART(dev); switch (cmd) { case DIOCWDINFO: case DIOCSDINFO: #ifdef __HAVE_OLD_DISKLABEL case ODIOCWDINFO: case ODIOCSDINFO: #endif { struct disklabel *lp; if ((flag & FWRITE) == 0) return EBADF; #ifdef __HAVE_OLD_DISKLABEL if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) { memset(&newlabel, 0, sizeof newlabel); memcpy(&newlabel, addr, sizeof (struct olddisklabel)); lp = &newlabel; } else #endif lp = addr; mutex_enter(&sc->sc_lock); sc->flags |= MCDF_LABELLING; error = setdisklabel(sc->sc_dk.dk_label, lp, /*sc->sc_dk.dk_openmask : */0, sc->sc_dk.dk_cpulabel); if (error == 0) { } sc->flags &= ~MCDF_LABELLING; mutex_exit(&sc->sc_lock); return error; } case DIOCWLABEL: return EBADF; case DIOCGDEFLABEL: mcdgetdefaultlabel(sc, addr); return 0; #ifdef __HAVE_OLD_DISKLABEL case ODIOCGDEFLABEL: mcdgetdefaultlabel(sc, &newlabel); if (newlabel.d_npartitions > OLDMAXPARTITIONS) return ENOTTY; memcpy(addr, &newlabel, sizeof (struct olddisklabel)); return 0; #endif case CDIOCPLAYTRACKS: return mcd_playtracks(sc, addr); case CDIOCPLAYMSF: return mcd_playmsf(sc, addr); case CDIOCPLAYBLOCKS: return mcd_playblocks(sc, addr); case CDIOCREADSUBCHANNEL: { struct cd_sub_channel_info info; error = mcd_read_subchannel(sc, addr, &info); if (error != 0) { struct ioc_read_subchannel *ch = addr; error = copyout(&info, ch->data, ch->data_len); } return error; } case CDIOCREADSUBCHANNEL_BUF: return mcd_read_subchannel(sc, addr, &((struct ioc_read_subchannel_buf *)addr)->info); case CDIOREADTOCHEADER: return mcd_toc_header(sc, addr); case CDIOREADTOCENTRYS: { struct cd_toc_entry entries[MCD_MAXTOCS]; struct ioc_read_toc_entry *te = addr; int count; if (te->data_len > sizeof entries) return EINVAL; error = mcd_toc_entries(sc, te, entries, &count); if (error == 0) /* Copy the data back. */ error = copyout(entries, te->data, min(te->data_len, count * sizeof(struct cd_toc_entry))); return error; } case CDIOREADTOCENTRIES_BUF: { struct ioc_read_toc_entry_buf *te = addr; int count; if (te->req.data_len > sizeof te->entry) return EINVAL; return mcd_toc_entries(sc, &te->req, te->entry, &count); } case CDIOCSETPATCH: case CDIOCGETVOL: case CDIOCSETVOL: case CDIOCSETMONO: case CDIOCSETSTEREO: case CDIOCSETMUTE: case CDIOCSETLEFT: case CDIOCSETRIGHT: return EINVAL; case CDIOCRESUME: return mcd_resume(sc); case CDIOCPAUSE: return mcd_pause(sc); case CDIOCSTART: return EINVAL; case CDIOCSTOP: return mcd_stop(sc); case DIOCEJECT: if (*(int *)addr == 0) { /* * Don't force eject: check that we are the only * partition open. If so, unlock it. */ if ((sc->sc_dk.dk_openmask & ~(1 << part)) == 0 && sc->sc_dk.dk_bopenmask + sc->sc_dk.dk_copenmask == sc->sc_dk.dk_openmask) { error = mcd_setlock(sc, MCD_LK_UNLOCK); if (error) return (error); } else { return (EBUSY); } } /* FALLTHROUGH */ case CDIOCEJECT: /* FALLTHROUGH */ case ODIOCEJECT: return mcd_eject(sc); case CDIOCALLOW: return mcd_setlock(sc, MCD_LK_UNLOCK); case CDIOCPREVENT: return mcd_setlock(sc, MCD_LK_LOCK); case DIOCLOCK: return mcd_setlock(sc, (*(int *)addr) ? MCD_LK_LOCK : MCD_LK_UNLOCK); case CDIOCSETDEBUG: sc->debug = 1; return 0; case CDIOCCLRDEBUG: sc->debug = 0; return 0; case CDIOCRESET: return mcd_hard_reset(sc); default: return ENOTTY; } #ifdef DIAGNOSTIC panic("mcdioctl: impossible"); #endif }
/******************************************************************************* * Function Name : MAL_GetStatus * Description : Get status * Input : None * Output : None * Return : None *******************************************************************************/ uint16_t MAL_GetStatus (uint8_t lun) { #ifdef USE_STM3210E_EVAL NAND_IDTypeDef NAND_ID; uint32_t DeviceSizeMul = 0, NumberOfBlocks = 0; #else //uint32_t temp_block_mul = 0; //SD_CSD SD_csd; //uint32_t DeviceSizeMul = 0; #endif /* USE_STM3210E_EVAL */ if (lun == 0) { #ifdef USE_STM3210E_EVAL if (SD_Init() == SD_OK) { SD_GetCardInfo(&mSDCardInfo); SD_SelectDeselect((uint32_t) (mSDCardInfo.RCA << 16)); DeviceSizeMul = (mSDCardInfo.SD_csd.DeviceSizeMul + 2); if(mSDCardInfo.CardType == SDIO_HIGH_CAPACITY_SD_CARD) { Mass_Block_Count[0] = (mSDCardInfo.SD_csd.DeviceSize + 1) * 1024; } else { NumberOfBlocks = ((1 << (mSDCardInfo.SD_csd.RdBlockLen)) / 512); Mass_Block_Count[0] = ((mSDCardInfo.SD_csd.DeviceSize + 1) * (1 << DeviceSizeMul) << (NumberOfBlocks/2)); } Mass_Block_Size[0] = 512; Status = SD_SelectDeselect((uint32_t) (mSDCardInfo.RCA << 16)); Status = SD_EnableWideBusOperation(SDIO_BusWide_4b); if ( Status != SD_OK ) { return MAL_FAIL; } Status = SD_SetDeviceMode(SD_DMA_MODE); if ( Status != SD_OK ) { return MAL_FAIL; } #else //SD_GetCSDRegister(&SD_csd); //DeviceSizeMul = SD_csd.DeviceSizeMul + 2; //temp_block_mul = (1 << SD_csd.RdBlockLen)/ 512;/* Physical drive number (0) */ while(Sd_Spi_Called_From_USB_MSC){;} if(disk_ioctl (0, GET_SECTOR_COUNT, &Mass_Block_Count[0]))//Sectors are the same as blocks and 512 bytes long? return MAL_FAIL; //Mass_Block_Count[0] = ((SD_csd.DeviceSize + 1) * (1 << (DeviceSizeMul))) * temp_block_mul; Mass_Block_Size[0] = 512; #endif /* USE_STM3210E_EVAL */ Mass_Memory_Size[0] = Mass_Block_Count[0] * Mass_Block_Size[0]; #ifdef CRT GREEN_LED_ON; #else STM_EVAL_LEDOn(LED2); #endif return MAL_OK; #ifdef USE_STM3210E_EVAL } #endif /* USE_STM3210E_EVAL */ } #ifdef USE_STM3210E_EVAL else { FSMC_NAND_ReadID(&NAND_ID); if (NAND_ID.Device_ID != 0 ) { /* only one zone is used */ Mass_Block_Count[1] = NAND_ZONE_SIZE * NAND_BLOCK_SIZE * NAND_MAX_ZONE ; Mass_Block_Size[1] = NAND_PAGE_SIZE; Mass_Memory_Size[1] = (Mass_Block_Count[1] * Mass_Block_Size[1]); return MAL_OK; } } #endif /* USE_STM3210E_EVAL */ #ifdef CRT GREEN_LED_OFF; #else STM_EVAL_LEDOff(LED2); #endif return MAL_FAIL; }
void camera_task(void *pv) { vTaskDelay(100); /* Camera_Cmd(ENABLE); Camera_Record_Snippet(4000); vTaskDelay(1000); Camera_Cmd(DISABLE); */ vTaskDelay(100); vTaskDelay(100); { FATFS fs; FIL file; if(f_mount(0, &fs) != FR_OK) while(1) ; if(f_open(&file, "temp1.txt", FA_WRITE | FA_OPEN_ALWAYS) != FR_OK) while(1) ; uint32_t bytes_written = 0; f_write(&file, "test\r\n", 6, &bytes_written); f_sync(&file); f_close(&file); f_mount(0, NULL); uint8_t cmd = 0; disk_ioctl(0, CTRL_POWER, &cmd); if(f_mount(0, &fs) != FR_OK) while(1) ; if(f_open(&file, "temp2.txt", FA_WRITE | FA_OPEN_ALWAYS) != FR_OK) while(1) ; bytes_written = 0; f_write(&file, "test\r\n", 6, &bytes_written); f_sync(&file); f_close(&file); f_mount(0, NULL); } vTaskDelay(100); vTaskDelay(100); /* Camera_Cmd(ENABLE); Camera_Record_Snippet(4000); vTaskDelay(1000); Camera_Cmd(DISABLE); vTaskDelay(100); */ vTaskSuspend(NULL); }
int edmcaioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l) { struct ed_softc *ed = device_lookup_private(&ed_cd, DISKUNIT(dev)); int error; ATADEBUG_PRINT(("edioctl\n"), DEBUG_FUNCS); if ((ed->sc_flags & WDF_LOADED) == 0) return EIO; error = disk_ioctl(&ed->sc_dk, dev, xfer, addr, flag, l); if (error != EPASSTHROUGH) return error; switch (xfer) { case DIOCWDINFO: case DIOCSDINFO: { struct disklabel *lp; lp = (struct disklabel *)addr; if ((flag & FWRITE) == 0) return EBADF; mutex_enter(&ed->sc_dk.dk_openlock); ed->sc_flags |= WDF_LABELLING; error = setdisklabel(ed->sc_dk.dk_label, lp, /*wd->sc_dk.dk_openmask : */0, ed->sc_dk.dk_cpulabel); if (error == 0) { #if 0 if (wd->drvp->state > RECAL) wd->drvp->drive_flags |= ATA_DRIVE_RESET; #endif if (xfer == DIOCWDINFO) error = writedisklabel(EDLABELDEV(dev), edmcastrategy, ed->sc_dk.dk_label, ed->sc_dk.dk_cpulabel); } ed->sc_flags &= ~WDF_LABELLING; mutex_exit(&ed->sc_dk.dk_openlock); return (error); } case DIOCKLABEL: if (*(int *)addr) ed->sc_flags |= WDF_KLABEL; else ed->sc_flags &= ~WDF_KLABEL; return 0; case DIOCWLABEL: if ((flag & FWRITE) == 0) return EBADF; if (*(int *)addr) ed->sc_flags |= WDF_WLABEL; else ed->sc_flags &= ~WDF_WLABEL; return 0; case DIOCGDEFLABEL: edgetdefaultlabel(ed, (struct disklabel *)addr); return 0; #if 0 case DIOCWFORMAT: if ((flag & FWRITE) == 0) return EBADF; { register struct format_op *fop; struct iovec aiov; struct uio auio; fop = (struct format_op *)addr; aiov.iov_base = fop->df_buf; aiov.iov_len = fop->df_count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_resid = fop->df_count; auio.uio_segflg = 0; auio.uio_offset = fop->df_startblk * wd->sc_dk.dk_label->d_secsize; auio.uio_lwp = l; error = physio(wdformat, NULL, dev, B_WRITE, minphys, &auio); fop->df_count -= auio.uio_resid; fop->df_reg[0] = wdc->sc_status; fop->df_reg[1] = wdc->sc_error; return error; } #endif default: return ENOTTY; } #ifdef DIAGNOSTIC panic("edioctl: impossible"); #endif }
bool storage_init() { uint8_t res; GpioSetPull(SD_IN, gpio_pull_up); GpioSetDirection(SD_IN, INPUT); DEBUG("SD_IN %d\n", GpioRead(SD_IN)); if (!SD_CARD_DETECT) return false; //power spi & sdcard SD_EN_ON; SD_SPI_PWR_ON; DEBUG("Mounting SD card ... "); for (uint8_t i = 0; i < 5; i++) { //power spi & sdcard SD_EN_ON; SD_SPI_PWR_ON; res = f_mount(&FatFs, "", 1); /* Give a work area to the default drive */ DEBUG("%d ", i + 1); if (res == RES_OK) break; sd_spi_usart.Stop(); //power spi & sdcard SD_EN_OFF; SD_SPI_PWR_OFF; for (uint8_t j = 0; j < i +1; j++) _delay_ms(10); } if (res != RES_OK) { DEBUG("Error %02X\n", res); sd_spi_usart.Stop(); //power spi & sdcard SD_EN_OFF; SD_SPI_PWR_OFF; sd_avalible = false; return false; } DEBUG("OK\n"); uint32_t size; FATFS * FatFs1; res = f_getfree("", &size, &FatFs1); // DEBUG1("f_getfree res = %d, size = %lu MiB", res, size / 256); uint32_t sector_count; res = disk_ioctl(0, GET_SECTOR_COUNT, §or_count); // DEBUG1("GET_SECTOR_COUNT res = %d, size = %lu", res, sector_count); uint16_t sector_size; res = disk_ioctl(0, GET_SECTOR_SIZE, §or_size); // DEBUG1("GET_SECTOR_SIZE res = %d, size = %u", res, sector_size); storage_space = sector_count * sector_size; storage_free_space = size * 4 * 1024; DEBUG("Disk info\n"); DEBUG(" sector size %12u\n", sector_size); DEBUG(" sector count %12lu\n", sector_count); DEBUG(" total space %12lu\n", storage_space); DEBUG(" free space %12lu\n", storage_free_space); sd_avalible = true; return true; }
uint32_t diskdrive_sector_size() { uint32_t sectorsize = 0; disk_ioctl(current_drive, GET_SECTOR_SIZE, §orsize); return sectorsize; }
int8_t FLASH_STORAGE_PreventAllowMediumRemoval(uint8_t lun, uint8_t param) { // sync the flash so that the cache is cleared and the device can be unplugged/turned off disk_ioctl(0, CTRL_SYNC, NULL); return 0; }
void sd_status(void) { long p2; PF_BYTE res, b; const PF_BYTE ft[] = { 0, 12, 16, 32 }; CDCprintln("\nf_getfree(): "); res = f_getfree("/", (DWORD*) &p2, &Fat); if (!res) { CDCprintln(" FAT type = FAT%u", ft[Fat->fs_type & 3]); CDCprintln(" Bytes/Cluster = %u", Fat->csize * 512UL); CDCprintln(" Number of FATs = %u", Fat->n_fats); CDCprintln(" Root DIR entries = %u", Fat->n_rootdir); CDCprintln(" Sectors/FAT = %u", Fat->fsize); CDCprintln(" Number of clusters = %u", Fat->n_fatent - 2); CDCprintln(" FAT start (lba) = %u", Fat->fatbase); CDCprintln(" DIR start (lba,cluster) = %u", Fat->dirbase); CDCprintln(" Data start (lba) = %u", Fat->database); #ifdef SD_DEBUG } else { put_rc(res); #endif } AccSize = AccFiles = AccDirs = 0; CDCprintln("\nscan_files(): "); res = scan_files("/"); if (!res) { CDCprintln(" %u files, %u bytes.", AccFiles, AccSize); CDCprintln(" %u folders.", AccDirs); CDCprintln(" %u KB total disk space.", (Fat->n_fatent - 2) * (Fat->csize / 2)); CDCprintln(" %u KB available.\r\n", p2 * (Fat->csize / 2)); #ifdef SD_DEBUG } else { CDCprintln("Failed!"); put_rc(res); #endif } if ((res = disk_ioctl(0, MMC_GET_TYPE, &b)) == RES_OK) { CDCprintln("MMC/SDC type: %u", b); #ifdef SD_DEBUG } else { CDCprintf("Could not determine card type. "); put_rc(res); #endif } if ((res = disk_ioctl(0, GET_SECTOR_COUNT, &p2)) == RES_OK) { CDCprintln("Drive size: %u sectors", p2); #ifdef SD_DEBUG } else { CDCprintf("Could not determine drive size. "); put_rc(res); #endif } if ((res = disk_ioctl(0, GET_BLOCK_SIZE, &p2)) == RES_OK) { CDCprintln("Erase block: %u sectors", p2); #ifdef SD_DEBUG } else { CDCprintf("Could not determine Erase block size. "); put_rc(res); #endif } }
uint8_t diskdrive_card_type() { uint8_t cardtype = 255; disk_ioctl(current_drive, MMC_GET_TYPE, &cardtype); return cardtype; }
int main(int oargc, char* oargv[]) { int ret; int argc = oargc - 1; char** argv = oargv + 1; // first parameter must be the image file. if (argc == 0) { fprintf(stderr, "Error: First parameter must be a filename.\n"); PRINT_HELP_AND_QUIT(); } if (is_command(argv[0])) { fprintf(stderr, "Error: First parameter must be a filename, found '%s' instead.\n", argv[0]); PRINT_HELP_AND_QUIT(); } if (disk_openimage(0, argv[0])) { fprintf(stderr, "Error: Could not open image file '%s'.\n", argv[0]); ret = 1; goto exit; } argc--; argv++; while (argc > 0) { char* parg = *argv; int nargs = 0; int i = 0; if (!is_command(parg)) { fprintf(stderr, "Error: Expected a command, found '%s' instead.\n", parg); PRINT_HELP_AND_QUIT(); } parg++; argv++; argc--; // find next command, to calculare number of args while ((argv[i] != NULL) && !is_command(argv[i++])) nargs++; if (strcmp(parg, "format") == 0) { // NOTE: The fs driver detects which FAT format fits best based on size int sectors; NEED_PARAMS(1, 2); // Arg 1: number of sectors sectors = atoi(argv[0]); if (sectors <= 0) { fprintf(stderr, "Error: Sectors must be > 0\n"); ret = 1; goto exit; } if (disk_ioctl(0, SET_SECTOR_COUNT, §ors)) { fprintf(stderr, "Error: Failed to set sector count to %d.\n", sectors); ret = 1; goto exit; } NEED_MOUNT(); ret = f_mkfs("0:", 1, sectors < 4096 ? 1 : 8); if (ret) { fprintf(stderr, "Error: Formatting drive: %d.\n", ret); goto exit; } // Arg 2: custom header label (optional) if (nargs > 1) { #define FAT_VOL_LABEL_LEN 11 char vol_label[2 + FAT_VOL_LABEL_LEN + 1]; // Null-terminated buffer char* label = vol_label + 2; // The first two characters are reserved for the drive number "0:" char ch; int i, invalid = 0; int len = strlen(argv[1]); if (len <= FAT_VOL_LABEL_LEN) { // Verify each character (should be printable ASCII) // and copy it in uppercase. for (i = 0; i < len; i++) { ch = toupper(argv[1][i]); if ((ch < 0x20) || !isprint(ch)) { invalid = 1; break; } label[i] = ch; } if (!invalid) { // Pad the label with spaces while (len < FAT_VOL_LABEL_LEN) { label[len++] = ' '; } } } else { invalid = 1; } if (invalid) { fprintf(stderr, "Error: Header label is limited to 11 printable uppercase ASCII symbols."); ret = 1; goto exit; } if (disk_read(0, buff, 0, 1)) { fprintf(stderr, "Error: Unable to read existing boot sector from image."); ret = 1; goto exit; } if (g_Filesystem.fs_type == FS_FAT32) { memcpy(buff + 71, label, FAT_VOL_LABEL_LEN); } else { memcpy(buff + 43, label, FAT_VOL_LABEL_LEN); } if (disk_write(0, buff, 0, 1)) { fprintf(stderr, "Error: Unable to write new boot sector to image."); ret = 1; goto exit; } // Set also the directory volume label memcpy(vol_label, "0:", 2); vol_label[2 + FAT_VOL_LABEL_LEN] = '\0'; if (f_setlabel(vol_label)) { fprintf(stderr, "Error: Unable to set the volume label."); ret = 1; goto exit; } } } else if (strcmp(parg, "boot") == 0) { FILE* fe; BYTE* temp = buff + 1024; NEED_PARAMS(1, 1); // Arg 1: boot file fe = fopen(argv[0], "rb"); if (!fe) { fprintf(stderr, "Error: Unable to open external file '%s' for reading.", argv[0]); ret = 1; goto exit; } if (!fread(buff, 512, 1, fe)) { fprintf(stderr, "Error: Unable to read boot sector from file '%s'.", argv[0]); fclose(fe); ret = 1; goto exit; } fclose(fe); NEED_MOUNT(); if (disk_read(0, temp, 0, 1)) { fprintf(stderr, "Error: Unable to read existing boot sector from image."); ret = 1; goto exit; } if (g_Filesystem.fs_type == FS_FAT32) { printf("TODO: Writing boot sectors for FAT32 images not yet supported."); ret = 1; goto exit; } else { #define FAT16_HEADER_START 3 #define FAT16_HEADER_END 62 memcpy(buff + FAT16_HEADER_START, temp + FAT16_HEADER_START, FAT16_HEADER_END - FAT16_HEADER_START); } if (disk_write(0, buff, 0, 1)) { fprintf(stderr, "Error: Unable to write new boot sector to image."); ret = 1; goto exit; } } else if (strcmp(parg, "add") == 0) { FILE* fe; FIL fv = { 0 }; UINT rdlen = 0; UINT wrlen = 0; NEED_PARAMS(2, 2); NEED_MOUNT(); // Arg 1: external file to add // Arg 2: virtual filename fe = fopen(argv[0], "rb"); if (!fe) { fprintf(stderr, "Error: Unable to open external file '%s' for reading.", argv[0]); ret = 1; goto exit; } if (f_open(&fv, argv[1], FA_WRITE | FA_CREATE_ALWAYS)) { fprintf(stderr, "Error: Unable to open file '%s' for writing.", argv[1]); fclose(fe); ret = 1; goto exit; } while ((rdlen = fread(buff, 1, sizeof(buff), fe)) > 0) { if (f_write(&fv, buff, rdlen, &wrlen) || wrlen < rdlen) { fprintf(stderr, "Error: Unable to write '%d' bytes to disk.", wrlen); ret = 1; goto exit; } } fclose(fe); f_close(&fv); } else if (strcmp(parg, "extract") == 0) { FIL fe = { 0 }; FILE* fv; UINT rdlen = 0; UINT wrlen = 0; NEED_PARAMS(2, 2); NEED_MOUNT(); // Arg 1: virtual file to extract // Arg 2: external filename if (f_open(&fe, argv[0], FA_READ)) { fprintf(stderr, "Error: Unable to open file '%s' for reading.", argv[0]); ret = 1; goto exit; } fv = fopen(argv[1], "wb"); if (!fv) { fprintf(stderr, "Error: Unable to open external file '%s' for writing.", argv[1]); f_close(&fe); ret = 1; goto exit; } while ((f_read(&fe, buff, sizeof(buff), &rdlen) == 0) && (rdlen > 0)) { if (fwrite(buff, 1, rdlen, fv) < rdlen) { fprintf(stderr, "Error: Unable to write '%d' bytes to file.", rdlen); ret = 1; goto exit; } } f_close(&fe); fclose(fv); } else if (strcmp(parg, "move") == 0) { NEED_PARAMS(2, 2); NEED_MOUNT(); // Arg 1: src path & filename // Arg 2: new path & filename if (f_rename(argv[0], argv[1])) { fprintf(stderr, "Error: Unable to move/rename '%s' to '%s'", argv[0], argv[1]); ret = 1; goto exit; } } else if (strcmp(parg, "copy") == 0) { FIL fe = { 0 }; FIL fv = { 0 }; UINT rdlen = 0; UINT wrlen = 0; NEED_PARAMS(2, 2); NEED_MOUNT(); // Arg 1: src path & filename // Arg 2: new path & filename if (f_open(&fe, argv[0], FA_READ)) { fprintf(stderr, "Error: Unable to open file '%s' for reading.", argv[0]); ret = 1; goto exit; } if (f_open(&fv, argv[1], FA_WRITE | FA_CREATE_ALWAYS)) { fprintf(stderr, "Error: Unable to open file '%s' for writing.", argv[1]); f_close(&fe); ret = 1; goto exit; } while ((f_read(&fe, buff, sizeof(buff), &rdlen) == 0) && (rdlen > 0)) { if (f_write(&fv, buff, rdlen, &wrlen) || wrlen < rdlen) { fprintf(stderr, "Error: Unable to write '%d' bytes to disk.", wrlen); ret = 1; goto exit; } } f_close(&fe); f_close(&fv); } else if (strcmp(parg, "mkdir") == 0) { NEED_PARAMS(1, 1); NEED_MOUNT(); // Arg 1: folder path if (f_mkdir(argv[0])) { fprintf(stderr, "Error: Unable to create directory."); ret = 1; goto exit; } } else if (strcmp(parg, "delete") == 0) { NEED_PARAMS(1, 1); NEED_MOUNT(); // Arg 1: file/folder path (cannot delete non-empty folders) if (f_unlink(argv[0])) { fprintf(stderr, "Error: Unable to delete file or directory."); ret = 1; goto exit; } } else if (strcmp(parg, "list") == 0) { char* root = "/"; DIR dir = { 0 }; FILINFO info = { 0 }; char lfname[257]; NEED_PARAMS(0, 1); // Arg 1: folder path (optional) if (nargs == 1) { root = argv[0]; } if (f_opendir(&dir, root)) { fprintf(stderr, "Error: Unable to opening directory '%s' for listing.\n", root); ret = 1; goto exit; } printf("Listing directory contents of: %s\n", root); info.lfname = lfname; info.lfsize = sizeof(lfname)-1; while ((!f_readdir(&dir, &info)) && (strlen(info.fname) > 0)) { if (strlen(info.lfname) > 0) printf(" - %s (%s)\n", info.lfname, info.fname); else printf(" - %s\n", info.fname); } } else { fprintf(stderr, "Error: Unknown or invalid command: %s\n", argv[-1]); PRINT_HELP_AND_QUIT(); } argv += nargs; argc -= nargs; } ret = 0; exit: disk_cleanup(0); return ret; }
int dk_ioctl(struct dk_softc *dksc, dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver; struct disklabel *lp; struct disk *dk = &dksc->sc_dkdev; #ifdef __HAVE_OLD_DISKLABEL struct disklabel newlabel; #endif int error; DPRINTF_FOLLOW(("%s(%s, %p, 0x%"PRIx64", 0x%lx)\n", __func__, dksc->sc_xname, dksc, dev, cmd)); /* ensure that the pseudo disk is open for writes for these commands */ switch (cmd) { case DIOCSDINFO: case DIOCWDINFO: #ifdef __HAVE_OLD_DISKLABEL case ODIOCSDINFO: case ODIOCWDINFO: #endif case DIOCKLABEL: case DIOCWLABEL: case DIOCAWEDGE: case DIOCDWEDGE: case DIOCSSTRATEGY: if ((flag & FWRITE) == 0) return EBADF; } /* ensure that the pseudo-disk is initialized for these */ switch (cmd) { case DIOCGDINFO: case DIOCSDINFO: case DIOCWDINFO: case DIOCGPARTINFO: case DIOCKLABEL: case DIOCWLABEL: case DIOCGDEFLABEL: case DIOCAWEDGE: case DIOCDWEDGE: case DIOCLWEDGES: case DIOCMWEDGES: case DIOCCACHESYNC: #ifdef __HAVE_OLD_DISKLABEL case ODIOCGDINFO: case ODIOCSDINFO: case ODIOCWDINFO: case ODIOCGDEFLABEL: #endif if ((dksc->sc_flags & DKF_INITED) == 0) return ENXIO; } error = disk_ioctl(dk, dev, cmd, data, flag, l); if (error != EPASSTHROUGH) return error; else error = 0; switch (cmd) { case DIOCWDINFO: case DIOCSDINFO: #ifdef __HAVE_OLD_DISKLABEL case ODIOCWDINFO: case ODIOCSDINFO: #endif #ifdef __HAVE_OLD_DISKLABEL if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) { memset(&newlabel, 0, sizeof newlabel); memcpy(&newlabel, data, sizeof (struct olddisklabel)); lp = &newlabel; } else #endif lp = (struct disklabel *)data; mutex_enter(&dk->dk_openlock); dksc->sc_flags |= DKF_LABELLING; error = setdisklabel(dksc->sc_dkdev.dk_label, lp, 0, dksc->sc_dkdev.dk_cpulabel); if (error == 0) { if (cmd == DIOCWDINFO #ifdef __HAVE_OLD_DISKLABEL || cmd == ODIOCWDINFO #endif ) error = writedisklabel(DKLABELDEV(dev), dkd->d_strategy, dksc->sc_dkdev.dk_label, dksc->sc_dkdev.dk_cpulabel); } dksc->sc_flags &= ~DKF_LABELLING; mutex_exit(&dk->dk_openlock); break; case DIOCKLABEL: if (*(int *)data != 0) dksc->sc_flags |= DKF_KLABEL; else dksc->sc_flags &= ~DKF_KLABEL; break; case DIOCWLABEL: if (*(int *)data != 0) dksc->sc_flags |= DKF_WLABEL; else dksc->sc_flags &= ~DKF_WLABEL; break; case DIOCGDEFLABEL: dk_getdefaultlabel(dksc, (struct disklabel *)data); break; #ifdef __HAVE_OLD_DISKLABEL case ODIOCGDEFLABEL: dk_getdefaultlabel(dksc, &newlabel); if (newlabel.d_npartitions > OLDMAXPARTITIONS) return ENOTTY; memcpy(data, &newlabel, sizeof (struct olddisklabel)); break; #endif case DIOCGSTRATEGY: { struct disk_strategy *dks = (void *)data; mutex_enter(&dksc->sc_iolock); strlcpy(dks->dks_name, bufq_getstrategyname(dksc->sc_bufq), sizeof(dks->dks_name)); mutex_exit(&dksc->sc_iolock); dks->dks_paramlen = 0; return 0; } case DIOCSSTRATEGY: { struct disk_strategy *dks = (void *)data; struct bufq_state *new; struct bufq_state *old; if (dks->dks_param != NULL) { return EINVAL; } dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */ error = bufq_alloc(&new, dks->dks_name, BUFQ_EXACT|BUFQ_SORT_RAWBLOCK); if (error) { return error; } mutex_enter(&dksc->sc_iolock); old = dksc->sc_bufq; bufq_move(new, old); dksc->sc_bufq = new; mutex_exit(&dksc->sc_iolock); bufq_free(old); return 0; } default: error = ENOTTY; } return error; }
//####### //CAMERA //####### void camera_task(void *pv) { fprintf(stdout, "Begin camera_task.\n"); vTaskDelay(100); fprintf(stderr, "CAMERA TASK: Enabling camera\n"); Camera_Cmd(ENABLE); fprintf(stderr, "CAMERA TASK: Beginning recording\n"); Camera_Record_Snippet(10000); vTaskDelay(10000); fprintf(stderr, "CAMERA TASK: Disabling camera\n"); Camera_Cmd(DISABLE); vTaskDelay(100); vTaskDelay(100); fprintf(stdout, "Begin FS write.\n"); //{ FATFS fs; FIL file; if(f_mount(0, &fs) != FR_OK){ fprintf(stderr, "ERROR: could noit mount file system.\n"); while(1) ; } if(f_open(&file, "temp1.txt", FA_WRITE | FA_OPEN_ALWAYS) != FR_OK){ fprintf(stderr, "ERROR: could not open temp1.txt.\n"); while(1) ; } uint32_t bytes_written = 0; f_write(&file, "test\r\n", 6, &bytes_written); f_sync(&file); f_close(&file); f_mount(0, NULL); uint8_t cmd = 0; disk_ioctl(0, CTRL_POWER, &cmd); if(f_mount(0, &fs) != FR_OK) while(1) ; if(f_open(&file, "temp2.txt", FA_WRITE | FA_OPEN_ALWAYS) != FR_OK) while(1) ; bytes_written = 0; f_write(&file, "test\r\n", 6, &bytes_written); f_sync(&file); f_close(&file); f_mount(0, NULL); //} vTaskDelay(100); fprintf(stdout, "End FS write.\n"); /* //NEVER REACHED vTaskDelay(100); fprintf(stderr, "Enabling camera\n"); Camera_Cmd(ENABLE); Camera_Record_Snippet(4000); vTaskDelay(1000); Camera_Cmd(DISABLE); fprintf(stderr, "Disabling camera\n"); vTaskDelay(100);*/ vTaskSuspend(NULL); }
static void usb_host_mass_test_storage ( void ) { /* Body */ static USB_STATUS status = USB_OK; static uint_8 bLun = 0; static INQUIRY_DATA_FORMAT inquiry; static MASS_STORAGE_READ_CAPACITY_CMD_STRUCT_INFO read_capacity; static CAPACITY_LIST capacity_list; static REQ_SENSE_DATA_FORMAT req_sense; static FORMAT_UNIT_PARAMETER_BLOCK formatunit = { 0}; static CBW_STRUCT_PTR cbw_ptr; static CSW_STRUCT_PTR csw_ptr; uint_8 res; switch(test) { case 0: cbw_ptr = pCmd.CBW_PTR; csw_ptr = pCmd.CSW_PTR; memset(buff_in, 0, BUFF_IN_SIZE); memset(buff_out, 0, 0x0F); memset(pCmd.CSW_PTR, 0, sizeof(CSW_STRUCT)); memset(pCmd.CBW_PTR, 0, sizeof(CBW_STRUCT)); memset(&pCmd, 0, sizeof(COMMAND_OBJECT_STRUCT)); pCmd.CBW_PTR = cbw_ptr; pCmd.CSW_PTR = csw_ptr; pCmd.LUN = bLun; pCmd.CALL_PTR = (pointer)&mass_device.class_intf; pCmd.CALLBACK = callback_bulk_pipe; printf("\n ================ START OF A NEW SESSION ================"); test++; ontest = 1; count = 0; break; case 1: count++; /* Send standard commands once, after each enumeration in order to * communicate well with most usb sticks */ if(count == 1){ #if 0 /* Read LUN info (type, and some strings) */ res = disk_ioctl(0, UFI_INQUIRY, NULL); //res = disk_ioctl(0, UFI_READ_FORMAT_CAPACITY, NULL); res = disk_ioctl(0, UFI_REQUEST_SENSE, NULL); //res = disk_ioctl(0, UFI_READ_FORMAT_CAPACITY, NULL); #endif #if 1 res = disk_ioctl(0, UFI_INQUIRY, NULL); res = disk_ioctl(0, UFI_TEST_UNIT_READY, NULL); //res = disk_ioctl(0, UFI_READ_CAPACITY, NULL); printf(""); #endif } /* Test the GET MAX LUN command */ if (1 == ontest) { printf("\n Testing: GET MAX LUN Command"); bCallBack = FALSE; status = usb_class_mass_getmaxlun_bulkonly( (pointer)&mass_device.class_intf, &bLun, usb_host_mass_ctrl_callback); ontest = 0; } else { if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED)) { printf (".......................ERROR"); return; } else { /* Wait till command comes back */ if (!bCallBack) {break;} if (!bStatus) { printf("..........................OK\n"); test++; ontest = 1; } else { printf("...Unsupported (bStatus=0x%08x)\n", (unsigned int)bStatus); test++; ontest = 1; } } } break; case 2: if (1 == ontest) { printf(" Testing: TEST UNIT READY Command"); bCallBack = FALSE; status = usb_mass_ufi_test_unit_ready(&pCmd); ontest = 0; } else { if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED)) { printf ("...................ERROR"); return; } else { /* Wait till command comes back */ if (!bCallBack) {break;} if (!bStatus) { printf("......................OK\n"); test++; ontest = 1; } else { printf("...Unsupported(bStatus=0x%08x)\n", (unsigned int)bStatus); test++; ontest = 1; } } } break; case 3: printf(" Testing: REQUEST SENSE Command"); res = disk_ioctl(0, UFI_REQUEST_SENSE, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: INQUIRY Command"); res = disk_ioctl(0, UFI_INQUIRY, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: REQUEST SENSE Command"); res = disk_ioctl(0, UFI_REQUEST_SENSE, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); time_delay(2000); printf(" Testing: READ CAPACITY Command"); res = disk_ioctl(0, UFI_READ_CAPACITY, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: REQUEST SENSE Command"); res = disk_ioctl(0, UFI_REQUEST_SENSE, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: READ FORMAT CAPACITIES Command"); res = disk_ioctl(0, UFI_READ_FORMAT_CAPACITY, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: REQUEST SENSE Command"); res = disk_ioctl(0, UFI_REQUEST_SENSE, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: MODE SENSE Command"); res = disk_ioctl(0, UFI_MODE_SENSE, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: PREVENT-ALLOW MEDIUM REMOVAL Command"); res = disk_ioctl(0, UFI_PREVENT_ALLOW_MEDIUM_ROMVAL, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: REQUEST SENSE Command"); res = disk_ioctl(0, UFI_REQUEST_SENSE, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: VERIFY Command"); res = disk_ioctl(0, UFI_VERIFY, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: WRITE(10) Command"); res = disk_ioctl(0, UFI_WRITE10, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: REQUEST SENSE Command"); printf(" Testing: REQUEST SENSE Command"); res = disk_ioctl(0, UFI_REQUEST_SENSE, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: READ(10) Command"); res = disk_ioctl(0, UFI_READ10, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); printf(" Testing: START-STOP UNIT Command"); res = disk_ioctl(0, UFI_START_STOP, NULL); if(!res) printf("......................OK\n"); else printf("FAILED(%x)\n\r", res); /* ------------------------------------------------------------------ */ test++; break; case 4: printf("\n Test done!\n"); test++; break; default: break; } /* End of switch */ /* ------------------------------------------------------------------ */ if(test == 19) { } } /* Endbody */
void main (void) { FIL f1, f2; /* 文件对象 */ FRESULT res; /* FatFs 函数公共结果代码 */ char cmd[100]; TCHAR *ptr, *ptr2, pool[50]; long p1, p2, p3; BYTE *buf; UINT s1, s2, cnt; WORD w; DWORD dw, ofs = 0, sect = 0, drv = 0; static const BYTE ft[] = {0, 12, 16, 32}; FATFS *fs; /* Pointer to file system object */ DIR dir; /* Directory object */ FIL file[2]; /* File objects */ while(1){ ptr=cmd; printf(">"); scanf("%s",ptr); switch (*ptr++){ case 'q': return 0; case '?': printf("%s\n",HelpStr ); break; case 'd' : /* Disk I/O command */ switch (*ptr++) { /* 第二个指令 */ case 'd' : /* dd [<pd#> <sect>] - Dump a secrtor */ if (!xatoi(&ptr, &p1)) { p1 = drv; p2 = sect; } else { if (!xatoi(&ptr, &p2)) break; } res = disk_read((BYTE)p1, Buff, p2, 1); if (res) { printf("rc=%d\n", (WORD)res); break; } printf("Drive:%u Sector:%lu\n", p1, p2); if (disk_ioctl((BYTE)p1, GET_SECTOR_SIZE, &w) != RES_OK) break; sect = p2 + 1; drv = p1; for (buf = Buff, ofs = 0; ofs < w; buf += 16, ofs += 16) put_dump(buf, ofs, 16); break; case 'i' : /* di <pd#> - 磁盘初始化 */ if (!xatoi(&ptr, &p1)) break; res = disk_initialize((BYTE)p1); printf("rc=%d\n", res); if (disk_ioctl((BYTE)p1, GET_SECTOR_SIZE, &w) == RES_OK) printf("Sector size = %u\n", w); if (disk_ioctl((BYTE)p1, GET_SECTOR_COUNT, &dw) == RES_OK) printf("Number of sectors = %u\n", dw); break; case 's': if (!xatoi(&ptr, &p1)) break; if (disk_ioctl((BYTE)p1, GET_SECTOR_SIZE, &w) == RES_OK) printf("Sector size = %u\n", w); if (disk_ioctl((BYTE)p1, GET_SECTOR_COUNT, &dw) == RES_OK) printf("Number of sectors = %u\n", dw); } case 'f' : /* FatFs test command */ switch (*ptr++) { /* Branch by secondary command character */ case 'i':/*挂载fi <ld#> [<mount>]*/ if (!xatoi(&ptr, &p1) || (UINT)p1 > 9) break; if (!xatoi(&ptr, &p2)) p2 = 0; sprintf(ptr, "%d:", p1); res=f_mount(&FatFs[p1], ptr, (BYTE)p2); printf("%d\n",res ); break; case 's':/*状态fs [<path>]*/ while (*ptr == ' ') ptr++; ptr2 = ptr; #if _FS_READONLY res = f_opendir(&dir, ptr); if (res) { fs = dir.fs; f_closedir(&dir); } #else res = f_getfree(ptr, (DWORD*)&p1, &fs); #endif if (res) { put_rc(res); break; } printf("FAT type = FAT%u\nNumber of FATs = %u\n", ft[fs->fs_type & 3], fs->n_fats); printf("Cluster size = %u sectors, %lu bytes\n", #if _MAX_SS != 512 fs->csize, (DWORD)fs->csize * fs->ssize); #else fs->csize, (DWORD)fs->csize * 512); #endif if (fs->fs_type != FS_FAT32) printf("Root DIR entries = %u\n", fs->n_rootdir); printf("Sectors/FAT = %lu\nNumber of clusters = %lu\nVolume start sector = %lu\nFAT start sector = %lu\nRoot DIR start %s = %lu\nData start sector = %lu\n\n", fs->fsize, fs->n_fatent - 2, fs->volbase, fs->fatbase, fs->fs_type == FS_FAT32 ? _T("cluster") : _T("sector"), fs->dirbase, fs->database); #if _USE_LABEL res = f_getlabel(ptr2, pool, &dw); if (res) { put_rc(res); break; } _tprintf(pool[0] ? _T("Volume name is %s\n") : _T("No volume label\n"), pool); _tprintf(_T("Volume S/N is %04X-%04X\n"), dw >> 16, dw & 0xFFFF); #endif printf("..."); AccSize = AccFiles = AccDirs = 0; res = scan_files(ptr); if (res) { put_rc(res); break; } p2 = (fs->n_fatent - 2) * fs->csize; p3 = p1 * fs->csize; #if _MAX_SS != 512 p2 *= fs->ssize / 512; p3 *= fs->ssize / 512; #endif p2 /= 2; p3 /= 2; printf("\r%u files, %I64u bytes.\n%u folders.\n%lu KiB total disk space.\n", AccFiles, AccSize, AccDirs, p2); #if !FS_READONLY printf("%lu KiB available.\n", p3); #endif break; } } } /* 为逻辑驱动器注册工作区 */ printf("%d\n",f_mount(&fs[0],"",1)); printf("%d\n",f_mkfs("",0,0) ); getch(); printf("%d\n",f_mkdir("test")); printf("%d\n",f_mkdir("test\\test1")); f_open(&f1, "message.txt", FA_CREATE_NEW); printf("%d\n",f_mkdir("test2")); return; }