예제 #1
0
FRESULT pf_write (
	const void* buff,	/* Pointer to the data to be written */
	UINT btw,			/* Number of bytes to write (0:Finalize the current write operation) */
	UINT* bw			/* Pointer to number of bytes written */
)
{
	CLUST clst;
	DWORD sect, remain;
	const BYTE *p = buff;
	BYTE cs;
	UINT wcnt;
	FATFS *fs = FatFs;


	*bw = 0;
	if (!fs) return FR_NOT_ENABLED;		/* Check file system */
	if (!(fs->flag & FA_OPENED))		/* Check if opened */
		return FR_NOT_OPENED;

	if (!btw) {		/* Finalize request */
		if ((fs->flag & FA__WIP) && disk_writep(0, 0)) ABORT(FR_DISK_ERR);
		fs->flag &= ~FA__WIP;
		return FR_OK;
	} else {		/* Write data request */
		if (!(fs->flag & FA__WIP))		/* Round-down fptr to the sector boundary */
			fs->fptr &= 0xFFFFFE00;
	}
	remain = fs->fsize - fs->fptr;
	if (btw > remain) btw = (UINT)remain;			/* Truncate btw by remaining bytes */

	while (btw)	{									/* Repeat until all data transferred */
		if ((UINT)fs->fptr % 512 == 0) {			/* On the sector boundary? */
			cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1));	/* Sector offset in the cluster */
			if (!cs) {								/* On the cluster boundary? */
				if (fs->fptr == 0)					/* On the top of the file? */
					clst = fs->org_clust;
				else
					clst = get_fat(fs->curr_clust);
				if (clst <= 1) ABORT(FR_DISK_ERR);
				fs->curr_clust = clst;				/* Update current cluster */
			}
			sect = clust2sect(fs->curr_clust);		/* Get current sector */
			if (!sect) ABORT(FR_DISK_ERR);
			fs->dsect = sect + cs;
			if (disk_writep(0, fs->dsect)) ABORT(FR_DISK_ERR);	/* Initiate a sector write operation */
			fs->flag |= FA__WIP;
		}
		wcnt = 512 - (UINT)fs->fptr % 512;			/* Number of bytes to write to the sector */
		if (wcnt > btw) wcnt = btw;
		if (disk_writep(p, wcnt)) ABORT(FR_DISK_ERR);	/* Send data to the sector */
		fs->fptr += wcnt; p += wcnt;				/* Update pointers and counters */
		btw -= wcnt; *bw += wcnt;
		if ((UINT)fs->fptr % 512 == 0) {
			if (disk_writep(0, 0)) ABORT(FR_DISK_ERR);	/* Finalize the currtent secter write operation */
			fs->flag &= ~FA__WIP;
		}
	}

	return FR_OK;
}
예제 #2
0
FRESULT pf_write (
	const void* buff,	/* Pointer to the data to be written */
	u16 btw,			/* Number of bytes to write (0:Finalize the current write operation) */
	u16* bw			/* Pointer to number of bytes written */
)
{
	CLUST clst;
	u32 sect, remain;
	const u8 *p = buff;
	u16 wcnt;
	FATFS *fs = FatFs;

	*bw = 0;
	if (!fs) return FR_NOT_ENABLED;		/* Check file system */
	if (!(fs->flag & FA_OPENED))		/* Check if opened */
		return FR_NOT_OPENED;

	if (!btw) {		/* Finalize request */
		if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort;
		fs->flag &= ~FA__WIP;
		return FR_OK;
	} else {		/* Write data request */
		if (!(fs->flag & FA__WIP))		/* Round down fptr to the sector boundary */
			fs->fptr &= 0xFFFFFE00;
	}
	remain = fs->fsize - fs->fptr;
	if (btw > remain) btw = (u16)remain;			/* Truncate btw by remaining bytes */
	while (btw)	{									/* Repeat until all data transferred */
		if (((u16)fs->fptr % 512) == 0) {				/* On the sector boundary? */
			if ((fs->fptr / 512 % fs->csize) == 0) {	/* On the cluster boundary? */
				clst = (fs->fptr == 0) ?			/* On the top of the file? */
					fs->org_clust : get_fat(fs->curr_clust);
				if (clst <= 1) goto fw_abort;
				fs->curr_clust = clst;				/* Update current cluster */
				fs->csect = 0;						/* Reset sector offset in the cluster */
			}
			sect = clust2sect(fs->curr_clust);		/* Get current sector */
			if (!sect) goto fw_abort;
			fs->dsect = sect + fs->csect++;
			if (disk_writep(0, fs->dsect)) goto fw_abort;	/* Initiate a sector write operation */
			fs->flag |= FA__WIP;
		}
		wcnt = 512 - ((u16)fs->fptr % 512);		/* Number of bytes to write to the sector */
		if (wcnt > btw) wcnt = btw;
		if (disk_writep(p, wcnt)) goto fw_abort;	/* Send data to the sector */
		fs->fptr += wcnt; p += wcnt;				/* Update pointers and counters */
		btw -= wcnt; *bw += wcnt;
		if (((u16)fs->fptr % 512) == 0) {
			if (disk_writep(0, 0)) goto fw_abort;	/* Finalize the currtent secter write operation */
			fs->flag &= ~FA__WIP;
		}
	}

	return FR_OK;

fw_abort:
	fs->flag = 0;
	return FR_DISK_ERR;
}
예제 #3
0
파일: mmc.c 프로젝트: Aliandrana/uzebox
DSTATUS disk_initialize (void)
{
	BYTE n, cmd, ty, ocr[4];
	UINT tmr;

#if _PF_USE_WRITE
	if (CardType && MMC_SEL) disk_writep(0, 0);	/* Finalize write process if it is in progress */
#endif

	init_spi();		/* Initialize ports to control MMC */
	DESELECT();
	for (n = 100; n; n--) rcv_spi();	/* 80*10 dummy clocks with CS=H */

	ty = 0;
	if (send_cmd(CMD0, 0) == 1) {			/* Enter Idle state */

		if (send_cmd(CMD8, 0x1AA) == 1) {	/* SDv2 */

			for (n = 0; n < 4; n++) ocr[n] = rcv_spi();		/* Get trailing return value of R7 resp */
		
			if (ocr[2] == 0x01 && ocr[3] == 0xAA) {			/* The card can work at vdd range of 2.7-3.6V */
				for (tmr = 10000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) dly_100us();	/* Wait for leaving idle state (ACMD41 with HCS bit) */
				
			
				if (tmr && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */


					for (n = 0; n < 4; n++) ocr[n] = rcv_spi();

					ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* SDv2 (HC or SC) */
				}
			}
		} else {							/* SDv1 or MMCv3 */
			if (send_cmd(ACMD41, 0) <= 1) 	{
				ty = CT_SD1; cmd = ACMD41;	/* SDv1 */
			} else {
				ty = CT_MMC; cmd = CMD1;	/* MMCv3 */
			}
			for (tmr = 10000; tmr && send_cmd(cmd, 0); tmr--) dly_100us();	/* Wait for leaving idle state */
			if (!tmr || send_cmd(CMD16, 512) != 0)			/* Set R/W block length to 512 */
				ty = 0;
		}

	}
	CardType = ty;
	DESELECT();
	rcv_spi();

	//full speed SPI
	SPCR = (1<<MSTR)|(1<<SPE);
	SPSR = 0x01;				/* SPI clk 2X */


	return ty ? 0 : STA_NOINIT;
}
예제 #4
0
FRESULT pf_write (
	const void* buff,	/* Pointer to the data to be written */
	WORD btw,			/* Number of bytes to write (0:Finalize the current write operation) */
	WORD* bw			/* Pointer to number of bytes written */
)
{
	DRESULT dr;
	CLUST clst;
	DWORD sect, remain;
	WORD rcnt;
	BYTE cs;
	const BYTE *rbuff = buff;
	FATFS *fs = FatFs;


	*bw = 0;
	if (!fs) return FR_NOT_ENABLED;		/* Check file system */
	if (!(fs->flag & FA_OPENED))		/* Check if opened */
		return FR_NOT_OPENED;

	remain = fs->fsize - fs->fptr;
	if (btw > remain) btw = (WORD)remain;			/* Truncate btr by remaining bytes */

	while (btw)	{									/* Repeat until all data transferred */
		if ((fs->fptr % 512) == 0) {				/* On the sector boundary? */
			cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1));	/* Sector offset in the cluster */
			if (!cs) {								/* On the cluster boundary? */
				clst = (fs->fptr == 0) ?			/* On the top of the file? */
					fs->org_clust : get_fat(fs->curr_clust);
				if (clst <= 1) goto fr_abort;
				fs->curr_clust = clst;				/* Update current cluster */
			}
			sect = clust2sect(fs->curr_clust);		/* Get current sector */
			if (!sect) goto fr_abort;
			fs->dsect = sect + cs;
		}
		rcnt = (WORD)(512 - (fs->fptr % 512));		/* Get partial sector data from sector buffer */
		if (rcnt > btw) rcnt = btw;
		dr = disk_writep(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);
		if (dr) goto fr_abort;
		fs->fptr += rcnt; rbuff += rcnt;			/* Update pointers and counters */
		btw -= rcnt; *bw += rcnt;
	}

	return FR_OK;

fr_abort:
	fs->flag = 0;
	return FR_DISK_ERR;
}
예제 #5
0
파일: diskio.c 프로젝트: NewBornSun/Energia
DSTATUS disk_initialize ()
{
	BYTE n, cmd, ty, ocr[4];
	UINT tmr;
	
	//spi_initialize();
	
#if _USE_WRITE
	if (CardType && MMC_SEL) disk_writep(0, 0);	/* Finalize write process if it is in progress */
#endif
	//SPI_SET_DIVIDER(128);  // 16MHz / 128 = 125kHz

	DESELECT();
	for (n = 10; n; n--) SPI_RECEIVE();	/* 80 dummy clocks with CS=H */

	ty = 0;
	if (send_cmd(CMD0, 0) == 1) {			/* Enter Idle state */
		if (send_cmd(CMD8, 0x1AA) == 1) {	/* SDv2 */
			for (n = 0; n < 4; n++) ocr[n] = SPI_RECEIVE();		/* Get trailing return value of R7 resp */
			if (ocr[2] == 0x01 && ocr[3] == 0xAA) {			/* The card can work at vdd range of 2.7-3.6V */
				for (tmr = 10000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) DLY100U();//delayMicroseconds(100); //DELAY_100US();	/* Wait for leaving idle state (ACMD41 with HCS bit) */
				if (tmr && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */
					for (n = 0; n < 4; n++) ocr[n] = SPI_RECEIVE();
					ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* SDv2 (HC or SC) */
				}
			}
		} else {							/* SDv1 or MMCv3 */
			if (send_cmd(ACMD41, 0) <= 1) 	{
				ty = CT_SD1; cmd = ACMD41;	/* SDv1 */
			} else {
				ty = CT_MMC; cmd = CMD1;	/* MMCv3 */
			}
			for (tmr = 10000; tmr && send_cmd(cmd, 0); tmr--) DLY100U();//delayMicroseconds(100); //DELAY_100US();	/* Wait for leaving idle state */
			if (!tmr || send_cmd(CMD16, 512) != 0)			/* Set R/W block length to 512 */
				ty = 0;
		}
	}
	CardType = ty;
	
	DESELECT();
	SPI_RECEIVE();
		
	return ty ? 0 : STA_NOINIT;
}
예제 #6
0
파일: mmc.c 프로젝트: v-bryzgalin/led_panel
//--------------------------------------------------------------------------
// Initialize Disk Drive                                                 
//--------------------------------------------------------------------------
DSTATUS disk_initialize (void)
{
	BYTE n, cmd, ty, ocr[4];
	WORD tmr;


	INIT_SPI();

	if ((PINB&_BV(SD_INS))!=0x00) return STA_NOINIT;

#if _WRITE_FUNC
	if (MMC_SEL) disk_writep(0, 0);		// Finalize write process if it is in progress 
#endif
	for (n = 100; n; n--) rcv_spi();	// Dummy clocks 

	ty = 0;
	if (send_cmd(CMD0, 0) == 1) {			// Enter Idle state 
		if (send_cmd(CMD8, 0x1AA) == 1) {	// SDv2 
			for (n = 0; n < 4; n++) ocr[n] = rcv_spi();		// Get trailing return value of R7 resp 
			if (ocr[2] == 0x01 && ocr[3] == 0xAA) {				// The card can work at vdd range of 2.7-3.6V 
				for (tmr = 12000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) ;	// Wait for leaving idle state (ACMD41 with HCS bit) 
				if (tmr && send_cmd(CMD58, 0) == 0) {		// Check CCS bit in the OCR 
					for (n = 0; n < 4; n++) ocr[n] = rcv_spi();
					ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	// SDv2 (HC or SC) 
				}
			}
		} else {							// SDv1 or MMCv3 
			if (send_cmd(ACMD41, 0) <= 1) 	{
				ty = CT_SD1; cmd = ACMD41;	// SDv1 
			} else {
				ty = CT_MMC; cmd = CMD1;	// MMCv3 
			}
			for (tmr = 25000; tmr && send_cmd(cmd, 0); tmr--) ;	// Wait for leaving idle state 
			if (!tmr || send_cmd(CMD16, 512) != 0)			// Set R/W block length to 512 
				ty = 0;
		}
	}
	CardType = ty;
	release_spi();

	return ty ? 0 : STA_NOINIT;
}
예제 #7
0
DSTATUS mmc_initialize (void)
{
   BYTE n, cmd, ty, ocr[4];
   WORD tmr;

   GREENLEDON();

   INIT_SPI();

#if _WRITE_FUNC
   if (MMC_SEL) disk_writep(0, 0);     /* Finalize write process if it is in progress */
#endif
   for (n = 11; n; --n) XFER_SPI(0xff);   /* Dummy clocks */

   ty = 0;
   if (send_cmd(CMD0, 0) == 1)
   {
      /* Enter Idle state */
      if (send_cmd(CMD8, 0x1AA) == 1)
      {  /* SDv2 */
         for (n = 0; n < 4; n++)
         {
            ocr[n] = XFER_SPI(0xff);      /* Get trailing return value of R7 resp */
         }
         if (ocr[2] == 0x01 && ocr[3] == 0xAA)
         {
            /* The card can work at vdd range of 2.7-3.6V */
            for (tmr = 12000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) ; /* Wait for leaving idle state (ACMD41 with HCS bit) */

            if (tmr && send_cmd(CMD58, 0) == 0)
            {
               /* Check CCS bit in the OCR */
               for (n = 0; n < 4; n++) ocr[n] = XFER_SPI(0xff);
               ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */
            }
         }
      }
      else
      {                    /* SDv1 or MMCv3 */
         if (send_cmd(ACMD41, 0) <= 1)
         {
            ty = CT_SD1; cmd = ACMD41; /* SDv1 */
         }
         else
         {
            ty = CT_MMC; cmd = CMD1;   /* MMCv3 */
         }
         for (tmr = 25000; tmr && send_cmd(cmd, 0); tmr--) ;   /* Wait for leaving idle state */

         if (!tmr || send_cmd(CMD16, 512) != 0)       /* Set R/W block length to 512 */
         {
            ty = 0;
         }
      }
   }
   CardType = ty;
   release_spi();

   GREENLEDOFF();

   return ty ? 0 : STA_NOINIT;
}