DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber (0) */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Sector number (LBA) */ UINT count /* Sector count (1..128) */ ) { if (pdrv || !count) return RES_PARERR; if (Stat & STA_NOINIT) return RES_NOTRDY; /* Issue Write Setor(s) command */ if (!issue_rwcmd(CMD_WRITE, sector, count)) return RES_ERROR; /* Send data blocks */ do { if (!wait_stat(2000, DRQ)) return RES_ERROR; write_block(buff); buff += 512; } while (--count); /* Wait for end of write process */ if (!wait_stat(1000, 0)) return RES_ERROR; read_ata(REG_ALTSTAT); read_ata(REG_STATUS); return RES_OK; }
DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber (0) */ ) { if (pdrv) return STA_NOINIT; /* Supports only single drive */ power_off(); /* Power off */ Stat |= STA_NOINIT; if (Stat & STA_NODISK) return Stat; /* Exit if socket is empty */ power_on(); /* Initialize CFC control port and socket power on */ write_ata(REG_DEVCTRL, SRST); /* Set software reset */ delay_ms(20); write_ata(REG_DEVCTRL, 0); /* Release software reset */ delay_ms(20); if (!wait_stat(3000, 0)) return Stat; /* Select device 0 */ write_ata(REG_DEV, 0); if (!wait_stat(3000, DRDY)) return Stat; write_ata(REG_FEATURES, 0x03); /* Set default PIO mode wo IORDY */ write_ata(REG_COUNT, 0x01); write_ata(REG_COMMAND, CMD_SETFEATURES); if (!wait_stat(3000, DRDY)) return Stat; write_ata(REG_FEATURES, 0x01); /* Select 8-bit PIO transfer mode */ write_ata(REG_COMMAND, CMD_SETFEATURES); if (!wait_stat(1000, DRDY)) return Stat; Stat &= ~STA_NOINIT; /* Initialization succeeded */ return Stat; }
DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive nmuber (0) */ BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive data block */ ) { BYTE n, w, ofs, dl, dh, *ptr = (BYTE*)buff; if (pdrv) return RES_PARERR; if (Stat & STA_NOINIT) return RES_NOTRDY; switch (cmd) { case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */ *(DWORD*)buff = 128; return RES_OK; case CTRL_SYNC : /* Nothing to do */ return RES_OK; } switch (cmd) { case GET_SECTOR_COUNT : ofs = 60; w = 2; n = 0; break; case ATA_GET_REV : /* Get firmware revision (8 chars) */ ofs = 23; w = 4; n = 4; break; case ATA_GET_MODEL : /* Get model name (40 chars) */ ofs = 27; w = 20; n = 20; break; case ATA_GET_SN : /* Get serial number (20 chars) */ ofs = 10; w = 10; n = 10; break; default: return RES_PARERR; } if (!wait_stat(1000, DRDY)) return RES_ERROR; write_ata(REG_COMMAND, CMD_IDENTIFY); /* Get device ID data block */ if (!wait_stat(1000, DRQ)) return RES_ERROR; /* Wait for data ready */ read_block_part(ptr, ofs, w); /* Get a part of data block */ while (n--) { /* Swap byte order */ dl = *ptr++; dh = *ptr--; *ptr++ = dh; *ptr++ = dl; } read_ata(REG_ALTSTAT); read_ata(REG_STATUS); return RES_OK; }
unsigned char i2c_write(unsigned addr, unsigned char eeaddr, unsigned char dat) { unsigned char rv=0; restart: begin: if(!i2c_start(addr, eeaddr)) goto quit; TWDR = dat; TWCR = _BV(TWINT) | _BV(TWEN); switch(wait_stat()){ case TW_MT_DATA_ACK: break; case TW_MT_ARB_LOST: goto begin; case TW_MT_DATA_NACK: default: goto quit; } rv = 1; quit: i2c_stop(); wait_us(50); // 1命令ごとに余裕を見て50usウェイトします。 return rv; }
unsigned char i2c_start(unsigned char addr, unsigned char eeaddr) { i2c_restart: i2c_start_retry: TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); switch(wait_stat()){ case TW_REP_START: case TW_START: break; case TW_MT_ARB_LOST: goto i2c_start_retry; default: return 0; } TWDR = addr | TW_WRITE; TWCR = _BV(TWINT) | _BV(TWEN); switch(wait_stat()){ case TW_MT_SLA_ACK: break; case TW_MT_SLA_NACK: goto i2c_restart; case TW_MT_ARB_LOST: goto i2c_start_retry; default: return 0; } TWDR = eeaddr; TWCR = _BV(TWINT) | _BV(TWEN); switch(wait_stat()){ case TW_MT_DATA_ACK: break; case TW_MT_DATA_NACK: i2c_stop(); return 0; case TW_MT_ARB_LOST: goto i2c_start_retry; default: return 0; } return 1; }
int main(int argc, char *argv[]) { int wtime, rtime, iotime; // int i; //uncomment to check runnning time (1) if(fork() == 0){ // for(i=0; i<=5000; i++) //uncomment to check runnning time (2) // print_nonsense(); //uncomment to check runnning time (3) char buf[3]; //uncomment to check sleeping time (1) printf(1, "Enter a sole char (any char) and press enter: (the longer you wait, the bigger sleeping time will be)\n"); //uncomment to check sleeping time (2) read(0, buf, 3); //uncomment to check sleeping time (3) exit(0); } wait_stat(&wtime, &rtime, &iotime); printf(2, "ready (runnable) time is: %d\n", wtime); printf(2, "running time is: %d\n", rtime); printf(2, "sleeping (waiting for io) time is: %d\n", iotime); exit(0); }
static int issue_rwcmd ( BYTE cmd, DWORD sector, UINT count ) { if (!wait_stat(1000, DRDY)) return 0; write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA); write_ata(REG_CYLH, (BYTE)(sector >> 16)); write_ata(REG_CYLL, (BYTE)(sector >> 8)); write_ata(REG_SECTOR, (BYTE)sector); write_ata(REG_COUNT, (BYTE)count); write_ata(REG_COMMAND, cmd); return 1; }
DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber (0) */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector number (LBA) */ UINT count /* Sector count (1..128) */ ) { if (pdrv || !count) return RES_PARERR; if (Stat & STA_NOINIT) return RES_NOTRDY; /* Issue Read Setor(s) command */ if (!issue_rwcmd(CMD_READ, sector, count)) return RES_ERROR; /* Receive data blocks */ do { if (!wait_stat(2000, DRQ)) return RES_ERROR; read_block(buff); buff += 512; } while (--count); read_ata(REG_ALTSTAT); read_ata(REG_STATUS); return RES_OK; }
int sys_wait_stat(void){ struct perf *perfStat; if (argptr(0, (char**)&perfStat, sizeof(perfStat)) < 0) return -1; return wait_stat(perfStat); }