示例#1
0
void Signature_WriteHexNibble(char nibble)
{
    if (nibble >= 10)
        f_putc(nibble + 'a' - 10, &Main_file);
    else
        f_putc(nibble + '0', &Main_file);
}
示例#2
0
void writeHeader()
{
#if defined(RTCLOCK)
  f_puts("Date,Time,", &g_oLogFile);
#else
  f_puts("Time,", &g_oLogFile);
#endif

#if defined(FRSKY)
#if !defined(CPUARM)
  f_puts("Buffer,RX,TX,A1,A2,", &g_oLogFile);
#if defined(FRSKY_HUB)
  if (IS_USR_PROTO_FRSKY_HUB()) {
    f_puts("GPS Date,GPS Time,Long,Lat,Course,GPS Speed(kts),GPS Alt,Baro Alt(", &g_oLogFile);
    f_puts(TELEMETRY_BARO_ALT_UNIT, &g_oLogFile);
    f_puts("),Vertical Speed,Air Speed(kts),Temp1,Temp2,RPM,Fuel," TELEMETRY_CELLS_LABEL "Current,Consumption,Vfas,AccelX,AccelY,AccelZ,", &g_oLogFile);
  }
#endif
#if defined(WS_HOW_HIGH)
  if (IS_USR_PROTO_WS_HOW_HIGH()) {
    f_puts("WSHH Alt,", &g_oLogFile);
  }
#endif
#endif

#if defined(CPUARM)
  char label[TELEM_LABEL_LEN+7];
  for (int i=0; i<MAX_SENSORS; i++) {
    TelemetrySensor & sensor = g_model.telemetrySensors[i];
    if (sensor.logs) {
      memset(label, 0, sizeof(label));
      zchar2str(label, sensor.label, TELEM_LABEL_LEN);
      if (sensor.unit != UNIT_RAW && sensor.unit != UNIT_GPS && sensor.unit != UNIT_DATETIME) {
        strcat(label, "(");
        strncat(label, STR_VTELEMUNIT+1+3*sensor.unit, 3);
        strcat(label, ")");
      }
      strcat(label, ",");
      f_puts(label, &g_oLogFile);
    }
  }
#endif
#endif

#if defined(PCBTARANIS)
  for (uint8_t i=1; i<NUM_STICKS+NUM_POTS+1; i++) {
    const char * p = STR_VSRCRAW + i * STR_VSRCRAW[0] + 2;
    for (uint8_t j=0; j<STR_VSRCRAW[0]-1; ++j) {
      if (!*p) break;
      f_putc(*p, &g_oLogFile);
      ++p;
    }
    f_putc(',', &g_oLogFile);
  }
  f_puts("SA,SB,SC,SD,SE,SF,SG,SH\n", &g_oLogFile);
#else
  f_puts("Rud,Ele,Thr,Ail,P1,P2,P3,THR,RUD,ELE,3POS,AIL,GEA,TRN\n", &g_oLogFile);
#endif
}
示例#3
0
文件: sd.c 项目: smitra/TicTocTrac
unsigned int loadSettings(void){
	char bl_ct[5];
	char time[25];
	char MinInterval[10];
	char MaxInterval[10];


	f_mount(0, &FileSystemObject);
	FRESULT res = f_open(&settingsFile, "/settings.dat", FA_WRITE | FA_READ | FA_OPEN_EXISTING);
	if(res)	return res; // File opening failed!
	//loop through file 
	f_gets(bl_ct, 5, &settingsFile);	
	f_gets(time, 25, &settingsFile);
	f_gets(MinInterval, 10, &settingsFile);
	f_gets(MaxInterval, 10, &settingsFile);
	
	
	if (bl_ct[0] == 'B'){ 			// Bootload if proper flag is set
		f_lseek(&settingsFile, 0); 	// Jump to beginning of file
		f_putc('*', &settingsFile); // Disable bootload flag
		f_sync(&settingsFile);		// Make sure the file is saved
		f_close(&settingsFile);
		f_mount(0,0);
		// Bootload by forcing reset using the watchdog timer
		cli();
		wdt_enable(WDTO_4S);
		while(1);
	}
	 
	if (bl_ct[1] == 'T'){			// Set the current time if proper flag is set
		f_lseek(&settingsFile, 1); 	// Jump proper position in file
		f_putc('*', &settingsFile);	// Disable set time flag
 		//set time on RTC		
		unsigned int sec;
		unsigned int min;
		unsigned int hr;
		unsigned int day;
		unsigned int month;
		unsigned int year;
		//YYYY-MM-DD hh:mm:ss
		sscanf(time, "CT %4u-%2u-%2u %2u:%2u:%2u", &year, &month, &day, &hr, &min, &sec);
		setTime((unsigned char)sec, (unsigned char)min, (unsigned char)hr, 0, (unsigned char)day, (unsigned char)month, year);
		f_sync(&settingsFile); // Make sure file is synched
	}
	// Load in the max and min duration creation test settings
	unsigned int min;
	unsigned int max;
	sscanf(MinInterval, "min %2u", &min);
	sscanf(MaxInterval, "max %2u", &max);

	// Close out and return the max and min duration creation test settings
	f_close(&settingsFile);
	f_mount(0,0);
	return (max<<8)|min;
}
示例#4
0
int serial_printf (const char* str, ... )
{
    va_list arp;
    UCHAR c, f, r;
    ULONG val;
    char s[16];
    int i, w, res, cc;


    va_start(arp, str);

    SERIAL_FIFO_LOCK();
    for (cc = res = 0; cc != EOF; res += cc) {
        c = *str++;
        if (c == 0) break;            /* End of string */
        if (c != '%') {                /* Non escape cahracter */
            cc = f_putc(c, fil);
            if (cc != EOF) cc = 1;
            continue;
        }
        w = f = 0;
        c = *str++;
        if (c == '%') {             /* print '%' _Dong */
            cc = f_putc(c, fil);
            continue;
        }
        if (c == '0') {                /* Flag: '0' padding */
            f = 1; c = *str++;
        }
        if (c == ' ') {             /* Flag: ' ' padding _Dong */
            c = *str++;
        }
        while (c >= '0' && c <= '9') {    /* Precision */
            w = w * 10 + (c - '0');
            c = *str++;
        }
        if (c == 'l') {                /* Prefix: Size is long int */
            f |= 2; c = *str++;
        }
        if (c == 's') {                /* Type is string */
            cc = f_puts(va_arg(arp, char*), fil);
            continue;
        }
        if (c == 'c') {                /* Type is character */
            cc = f_putc(va_arg(arp, int), fil);
            if (cc != EOF) cc = 1;
            continue;
        }
static void prvCreateDemoFileUsing_f_putc( void )
{
unsigned char ucReturn;
int iByte, iReturned;
F_FILE *pxFile;
char cFileName[ fsMAX_FILE_NAME_LEN ];

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

	/* Create a sub directory. */
	ucReturn = f_mkdir( pcDirectory1 );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Move into the created sub-directory. */
	ucReturn = f_chdir( pcDirectory1 );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

	/* Create a subdirectory in the new directory. */
	ucReturn = f_mkdir( pcDirectory2 );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Move into the directory just created - now two directories down from
	the root. */
	ucReturn = f_chdir( pcDirectory2 );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
	configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 );

	/* Generate the file name. */
	sprintf( cFileName, "%s.txt", pcDirectory2 );

	/* Print out the file name and the directory into which the file is being
	written. */
	pxFile = f_open( cFileName, "w" );

	/* Create a file 1 byte at a time.  The file is filled with incrementing
	ascii characters starting from '0'. */
	for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )
	{
		iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile );
		configASSERT( iReturned ==  ( ( int ) '0' + iByte ) );
	}

	/* Finished so close the file. */
	f_close( pxFile );

	/* Move back to the root directory. */
	ucReturn = f_chdir( "../.." );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
	configASSERT( strcmp( cRAMBuffer, pcRoot ) == 0 );
}
示例#6
0
文件: format.c 项目: logicmoo/yap-6.3
static bool format_synch(int sno, int sno0, format_info *fg ) {
  int (*f_putc)(int, int);
  const char *s;
  int n;
  
  f_putc = GLOBAL_Stream[sno0].stream_putc;
#if MAY_WRITE
  if (fflush(GLOBAL_Stream[sno].file) == 0) {
    s = GLOBAL_Stream[sno].nbuf;
    n = ftell(GLOBAL_Stream[sno].file);
  } else
    return false;
#else
  s = GLOBAL_Stream[sno].u.mem_string.buf;
  n =  GLOBAL_Stream[sno].u.mem_string.pos;
#endif
  while (n--)
    f_putc(sno0, *s++);
#if MAY_WRITE
  rewind(GLOBAL_Stream[sno].file);
#else
  GLOBAL_Stream[sno].u.mem_string.pos = 0;
#endif
  GLOBAL_Stream[sno].linecount = 1;
  GLOBAL_Stream[sno].linepos = 0;
  GLOBAL_Stream[sno].charcount = 0;
  fg->lstart = 0;
  fg->phys_start=0;
  fg->gapi=0;
  return true;
}
示例#7
0
文件: cfg.c 项目: Skarsnik/sd2snes
int cfg_validity_check_recent_games() {
  int err = 0, index, index_max, write_indices[10], rewrite_lastfile = 0;
  TCHAR fntmp[10][256];
  file_open(LAST_FILE, FA_READ);
  if(file_status == FILE_ERR) {
    return 0;
  }
  for(index = 0; index < 10 && !f_eof(&file_handle); index++) {
    f_gets(fntmp[index], 255, &file_handle);
  }
  if(!f_eof(&file_handle))
    index_max = 10;
  else
    index_max = index;
  file_close();
  for(index = 0; index < index_max; index++) {
    file_open((uint8_t*)fntmp[index], FA_READ);
    write_indices[index] = file_status;
    if(file_status != FILE_OK)
      rewrite_lastfile = 1;
    file_close();
  }
  if(rewrite_lastfile) {
    f_rename ((TCHAR*)LAST_FILE, (TCHAR*)LAST_FILE_BAK);
    file_open(LAST_FILE, FA_CREATE_ALWAYS | FA_WRITE);
    for(index = 0; index < index_max; index++) {
      if(write_indices[index] == FILE_OK) {
        err = f_puts(fntmp[index], &file_handle);
        err = f_putc(0, &file_handle);
      }
    }
    file_close();
  }
  return err;
}
示例#8
0
文件: mmc.c 项目: Bob4ik888/WebRadio
void ini_stripfile(FIL *file, unsigned int pos, unsigned int len)
{
  FRESULT res;
  unsigned int rd;
  unsigned char c;

  if((pos+len) >= file->fsize)
  {
    f_lseek(file, pos);
  }
  else
  {
    for(; (pos+len)<file->fsize; pos++)
    {
      f_lseek(file, pos+len);
      res = f_read(file, &c, 1, &rd);
      if((res != FR_OK) || (rd != 1))
      {
        break;
      }
      f_lseek(file, pos);
      f_putc(c, file);
    }
  }
  f_truncate(file);

  return;
}
示例#9
0
文件: cfg.c 项目: Skarsnik/sd2snes
int cfg_add_last_game(uint8_t *fn) {
  int err = 0, index, index2, found = 0, foundindex = 0, written = 0;
  TCHAR fqfn[256];
  TCHAR fntmp[10][256];
  file_open(LAST_FILE, FA_READ);
  fqfn[0] = 0;
  if(fn[0] !=  '/') {
    strncpy(fqfn, (const char*)file_path, 256);
  }
  strncat(fqfn, (const char*)fn, 256);
  for(index = 0; index < 10; index++) {
    f_gets(fntmp[index], 255, &file_handle);
    if((*fntmp[index] == 0) || (*fntmp[index] == '\n')) {
      break; /* last entry found */
    }
    if(!strncasecmp((TCHAR*)fqfn, fntmp[index], 255)) {
      found = 1; /* file already in list */
      foundindex = index;
    }
  }
  file_close();
  file_open(LAST_FILE, FA_CREATE_ALWAYS | FA_WRITE);
  /* always put new entry on top of list */
  err = f_puts((const TCHAR*)fqfn, &file_handle);
  err = f_putc(0, &file_handle);
  written++;
  if(index > 9 + found) index = 9 + found; /* truncate oldest entry */
  /* allow number of destination entries to be the same as source in case
   * we're only moving a previous entry to top */
  for(index2 = 0; index2 < index; index2++) {
    if(found && (index2 == foundindex)){
      continue; /* omit found entry here to prevent dupe */
    }
    err = f_puts(fntmp[index2], &file_handle);
    err = f_putc(0, &file_handle);
    written++;
  }
  file_close();
  return err;
}
SDFS_status_type SDFS_writeString(FIL* fp, char* text) {
	SDFS_status_type ret_wert = SDFS_WRITE_ERR;
	int check = 0;

	check = f_puts(text, fp);

	if (check >= 0) {
		ret_wert = SDFS_OK;
		f_putc('\n', fp);
	} else {
		ret_wert = SDFS_WRITE_ERR;
	}

	return (ret_wert);
}
示例#11
0
文件: mmc.c 项目: Bob4ik888/WebRadio
void ini_extendfile(FIL *file, unsigned int pos, unsigned int len)
{
  FRESULT res;
  unsigned int i, rd;
  unsigned char c;

  if(pos < file->fsize)
  {
    for(i=file->fsize-1; i>pos; i--)
    {
      f_lseek(file, i);
      res = f_read(file, &c, 1, &rd);
      if((res != FR_OK) || (rd != 1))
      {
        break;
      }
      f_lseek(file, i+len);
      f_putc(c, file);
    }
  }

  return;
}
示例#12
0
文件: Road.c 项目: rmnsfx/Pion
long rod_CreateFile_edit (void)
{

  s32 i = 0;  		
	FIL Fil;
	FIL Fil2;
	FRESULT result;	
	FATFS   fls;          
	FILINFO fno;
	long res = 0;
	char t_str[25];
	

	__disable_irq();
	__disable_fiq(); 
	
	IWDG_ReloadCounter();
	
	res = f_mount(&fls, "0:", 1);
				
	res = f_open(&Fil,"0:Road.0", FA_CREATE_ALWAYS | FA_WRITE);	
	f_printf(&Fil,"%s", "без маршрута   ");		
	f_putc(0,&Fil);
	
		
//	f_open(&Fil,"0:Road.000", FA_OPEN_ALWAYS | FA_WRITE);	
//	f_lseek(&Fil, 16);
	
	for(i=1;i<500;i++)
	{
			{
					f_printf(&Fil,"%s %03u      ","точка",i);				
					f_putc(i,&Fil);
	
			}									
	}		
	//Получаем размер 
	res = f_size(&Fil);		
	f_close(&Fil);

	IWDG_ReloadCounter();	
	
	//Только чтение
	f_chmod("0:Road.0", AM_RDO, AM_RDO | AM_ARC);	
	
	f_open(&Fil,"0:Road.log", FA_CREATE_ALWAYS | FA_WRITE);
	f_printf(&Fil,"%s", "Road.0");
	f_close(&Fil);
	
	f_open(&Fil2,"0:Roads.txt", FA_CREATE_ALWAYS | FA_WRITE);
	f_printf(&Fil2,"%s", "Road.0");
	f_close(&Fil2);	

	
//	//Проверяем размер 
//	f_open(&Fil,"0:Road.100", FA_OPEN_ALWAYS);				
//	//if (f_size(&Fil) == 16000) res = 1;			
//	res = f_size(&Fil);
//	f_close(&Fil);	
	
	f_mount(0,"0:", 0);	
	
	__enable_irq();
	__enable_fiq();
	
  return res;		 
}
示例#13
0
文件: vbit.c 项目: BackupGGCode/vbit
/* Command interpreter for VBIT,
	The leading SO and trailing carriage return are already removed
	The X command returns 2
	Other good commands return 0 and bad commands return 1.
	Also after a P command if selecting a single page fails, the page is created and 8 is the return code 
	*/
static int vbit_command(char *Line)
{
	static uint8_t firstLine=true;
	static uint16_t SRAMAddress;	// The address pointer into the FIFO serial ram
	unsigned char rwmode;
	unsigned char returncode=0;
	int pagecount;
	uint8_t directorySteps;
	int8_t sign; // 1=plus -1=minus
	char ch;
	unsigned char valid;
	long n;
	unsigned char i;
	char str[80];
	char *ptr;
	char *dest;
	str[0]='O';
	str[1]='K';
	str[2]='\0';
	// char data[80];
	
	// This stuff is to do with locating pages in the display list (Directory command)
	// (also shared with ee/ea command for uploading pages)
	NODEPTR np;
	DISPLAYNODE node;
	PAGEINDEXRECORD ixRec;
	uint16_t charcount;	
	uint8_t res;
	DWORD fileptr;		// Used to save the file pointer to the body of the ttx file	
	PAGE page;
	// ee/ea specific variable
	static DWORD StartOfPage;
	DWORD EndOfPage;	// Records the start and end of the new page
	PAGEINDEXRECORD pageindex;
	uint16_t ix;

	char packet[45];
	static uint8_t row;	// Teletext row counter for JA/JZ/JW command
	// tba
	
	// Read, Update or not
	switch (Line[2])
	{
	case 'R' : rwmode=CMD_MODE_READ; break;
	case 'U' : rwmode=CMD_MODE_WRITE;break;
	default:
		rwmode=CMD_MODE_NONE;
	}
	/* Is there actually any data */
	if (*Line==0)
		returncode=1;
	else
	switch (Line[1])
	{
	case 'b': // Dump the current page
		dumpPage();
		break;
	case 'C': // Create magazine lists
		// TODO: Kill video
		// TODO: C<pages to pre-allocate> // this would speed up the process immensely
		// It only needs to be approximate as FatFS will extend the file as needed.
		
		cli();
		pagecount=300;
		for (i=1;i<=1;i++) // TODO: Do we need more lists? Probably can find a way around it.
			SDCreateLists(i,pagecount);
		sei();
		break;
	case 'D': // Directory - D[<F|L>][<+|->][<n>]
		// Where F=first, L=Last, +=next, -=prev, n=number of pages to step (default 1)
		//xprintf(PSTR("D Command needs to be written"));
		// It would probably be a good idea to save the seek pointer
		// do the reading required
		// and then reset it. This would save memory.
		// If the ee command is active, don't allow D to mess the page variable.
		if (firstLine)
		{
			returncode=1; // ee command is busy. 
			break;
		}
		directorySteps=0;
		sign=1;
		for (i=2;Line[i];i++)
		{
			ch=Line[i];
			// xprintf(PSTR("Processing Line[%d]=%c\n\r"),i,Line[i]);
			switch (ch)
			{
			case 'F' : ; // Set the first item
				DirectoryFirst();
				break;
			case 'L' : ; // Set the last item
				DirectoryLast();
				break;
			case '+' : ; // Next item
				directorySteps=1;
				sign=1;
				// xprintf(PSTR("D+ not implemented"));
				break;
			case '-' : ; // Previous item
				directorySteps=1;
				sign=-1;
				// xprintf(PSTR("D- not implemented"));
				break;
			default: // Number of steps (TODO: Extend to a generic decimal)
				if (ch>='0' && ch <='9')
				{
					directorySteps=ch;
				}
				Line[i]=0;// Force this to be the last option
				break;	// Break because this must be the last option
			}
			// Find the page
			if (LocatePage(directorySteps*sign)==NULLPTR)
			{
				// Probably want to set an error value as we failed to iterate
				// But I don't think that we return anything different.
				// We rely on TED scheduler to remember the count returned by the P command and NOT overrun
			}
			// TODO: Work out what to do with the rest of the parameters
			np=GetNodePtr(&currentPage);
			// TODO: Handle sub pages
			GetNode(&node,np);
			// Instead treat the page like a single page
			f_lseek(&listFIL,(node.pageindex)*sizeof(PAGEINDEXRECORD));	// Seek the page index
			f_read(&listFIL,&ixRec,sizeof(PAGEINDEXRECORD),&charcount);	// and read it	
			// Now seek the actual page that we are referencing
			res=f_open(&PageF,"pages.all",FA_READ);					// Now look for the relevant page
			f_lseek(&PageF,ixRec.seekptr);	// Seek the actual page
			// Now we have the page, we need to seek through it to get
			// the data
			while (PageF.fptr<(ixRec.seekptr+ixRec.pagesize))
			{
				fileptr=PageF.fptr;		// Save the file pointer in case we found "OL"
				f_gets(str,sizeof(str),&PageF);
				if (str[0]=='O' && str[1]=='L')
				{
					f_lseek (&PageF, fileptr);	// Step back to the OL line
					break;
				}
				if (ParseLine(&page, str))
				{
					xprintf(PSTR("[insert]file error handler needed:%s\n"),str);
					// At this point we are stuffed.
					f_close(&PageF);
					returncode=1;
					break; // what else should we do if we get here?
				}
			}	
			// bb mpp qq cc tttt ssss n xxxxxxx
			// Leading zeros rely on PRINTF_LIB_FLOAT in makefile!!!
			sprintf_P(str,PSTR("%02X %03X %02d %02X %04X 0000 %1d 00000000"),
			3, // seconds (hex)
			0x100+(currentPage/2), // mpp
			page.subpage, // ss
			page.control, // S
			page.time,  // Cycle time (secs)
			(currentPage>>8)+1); // Mag
			f_close(&PageF);
		}
		// str[0]=0;	// might return the directory paramaters here
		break;
	case 'E' : // EO, ES, EN, EP, EL, EM - examine 
		switch (Line[2])
		{
		case 'M': // EM - Return Miscellaneous flags
			{
				// These are BFLSU. The code below is not correct
				n = ini_getl("service", "serialmode", 0, inifile);	
				if (n)
					xputs(PSTR("20"));
				else
					xputs(PSTR("00"));
				break;
			}
				break;
			default:
				returncode=1;
		case 'O': // EO - Output dataline actions set by QO
			// 18 characters on a line, but odd ignores last action
			n = ini_gets("service", "outputodd", "111Q2233P445566778", str, sizearray(str), inifile);	
			n = ini_gets("service", "outputeven", "111Q2233P445566778", str, sizearray(str), inifile);	
			xprintf(PSTR("%s"),str);
			break;
		}		
		break; // E commands
	case 'e' : // ea or ee : Upload page(s).
		// These pages add the lines at the end of the page file, and patch the index.
		// Warning. "page" is shared with the directory command
		// directory calls are blocked until you do ee.
		switch (Line[2])
		{
		case 'a' : // Add a page, line at a time.
			passBackspace=true;
			if (firstLine)
			{
				firstLine=false;
				ClearPage(&page); // Clear out our Page object
				res=f_open(&PageF,"pages.all",FA_READ| FA_WRITE);	// Ready to write
				// TODO: check the value of res
				//xprintf(PSTR("Size of pages.all=%ul\n\r"),PageF.fsize);
				/* Move to end of pages.all to append data */
				res=f_lseek(&PageF, PageF.fsize);				
				//xprintf(PSTR("lseek res=%d\n\r"),res);
				StartOfPage=PageF.fptr;  // We need the Start Of Page for the index
			}
			// uh fellows, Although we get \r => Ctrl-P, we need to map it to 0x8d which is the file format.
			for (ptr=&Line[4];*ptr;ptr++)
				if (*ptr==0x10)
					*ptr=0x8d;
			f_puts(&Line[4],&PageF);	// The rest of the line is the file contents
			f_putc('\n',&PageF);	// Add the LF that the interpreter strips out			
			xprintf(PSTR("Now writing:%s\n\r"),&Line[4]);
			// Don't unencode the line, pages.all should follow MRG \r => ctrl-P substitutions
			// Probably can ignore Viewdata escapes.
			// Write the rest of the line to pages.all
			// Parse the line so we have all the page details so we know where to put it in the array/node
			if (ParseLine(&page, &Line[4]))
			{
				xprintf(PSTR("Your page sucks. Unable to parse this nonsense\n\r"));
				returncode=1;	// failed
				// TODO: implement the break
				// break;
			}
			break; // a
		case 'e' : // We finished. End the update
			passBackspace=false;
			EndOfPage=PageF.fptr;
			f_close(&PageF);		// We are done with pages.all
			// We need to refresh the transmission file object so close and re-open it
			f_close(&pagefileFIL);
			res=f_open(&pagefileFIL,"pages.all",FA_READ);		// Only need to open this once!			
			// Or are we all done? We need to write the page to Pmpp.TTI so that we can rebuild the index later
			pageindex.seekptr=StartOfPage;
			pageindex.pagesize=(uint16_t)(EndOfPage-StartOfPage); // Warning! 16 bit file size limits to about 50 subpages.
		    xprintf(PSTR("seek %ld size %d \n\r"),pageindex.seekptr,pageindex.pagesize);
			// 1: Append pages.idx with the file start/end (append pageindex)
			f_close(&listFIL); // TODO: Perhaps we should check that this is actually opened first?
			res=f_open(&listFIL,"pages.idx",FA_READ| FA_WRITE);	// Ready to write // TODO: check the value of res
			ix=listFIL.fsize;		// This is the address in the file
			res=f_lseek(&listFIL, ix);	// Locate the end of the file
			// Now append the page index
			f_write(&listFIL,&(pageindex.seekptr),4,&charcount);	// 4 byte seek pointer
			f_write(&listFIL,&(pageindex.pagesize),2,&charcount);	// 2 byte file size 			
			// Now restore the file to the previous opened readonly state
			f_close(&listFIL);
		    res=f_open(&listFIL,"pages.idx",FA_READ);			
			// 2: Add the page to the page array. (Or we could rebuild just by doing a restart)
			ix=ix/sizeof(pageindex);
			xprintf(PSTR("New page mag=%d page=%02X --> added at ix=%d\n\r"),page.mag,page.page,ix);
			LinkPage(page.mag, page.page, page.subcode, ix);
			// TODO:
			// 3: Add the page to the node list.  (ditto)
			// TODO:
			firstLine=true;		// and reset ready for the next file
			break; // e
		default:
			str[0]=0;
			returncode=1;
		}
		break; // e commands
	case 'G': /* G - Packet 8/30 format 1 [p830f1]*/
		if (rwmode==CMD_MODE_NONE)
		{
			str[0]=0;
			returncode=1;
			break;
		}
		/* C, L N, T, D */
		switch (Line[3])
		{
		case 'C' : /* Code. 1=format 1 */
			//xputs(PSTR("GUC command not implemented. Why would we need it\n"));
			// It should always default to 0
			/** Where is the initial page done? The code below is wrong */
			//SetInitialPage(pkt830,str1,str2); // nb. Hard coded to 100
			break;
		case 'D' : /* up to 20 characters label*/
			if (rwmode==CMD_MODE_READ)
			{			
				n = ini_gets("p830f1", "label", "VBITFax             ", str, sizearray(str), inifile);			
				xprintf(PSTR("%s"),str);
			}
			if (rwmode==CMD_MODE_WRITE)
			{
				n = ini_puts("p830f1", "label", &Line[4], inifile);	
				SetStatusLabel(pkt830,&Line[4]);
			}			
			break;
		case 'L' : /* Link */
			xputs(PSTR("GUL command\n"));
			/* Alrighty. The MAG is already in the MRAG. All we actually need is 
			ppssss where pp=hex page number and ssss=hex subcode */
			n = ini_gets("p830f1", "initialpage", "003F7F", str, MAXSTR, inifile);
			break;
		case 'N' : /* Net IC  */
			if (rwmode==CMD_MODE_READ)
			{
				n = ini_gets("p830f1", "nic", "fa6f", str, sizearray(str), inifile);			
				xprintf(PSTR("%s"),str);
			}
			if (rwmode==CMD_MODE_WRITE)
			{
				n = ini_puts("p830f1", "nic", &Line[4], inifile);	
				SetNIC1(pkt830,&Line[4]);
			}
			break;
		case 'T' : /* Time */
			xputs(PSTR("GUT command\n"));
			i2c_init();			
			break;
		default:
			str[0]=0;
			returncode=1;	
		}
		break;
	case 'H': // H or HO. Set header
		if (Line[3]=='\0' || Line[5]=='\0') // Don't get confused by checksums
		{
			strcpy_P(str,PSTR("      "));
			strncat(str,g_Header,32);	// Just readback the header. TODO. Get the correct length
			str[40]=0;
		}
		else
		{
			strncpy(g_Header,&Line[9],32); // accept new header
			//g_Header[32]=0;					// Make sure it is capped
			n = ini_puts("service", "header", g_Header, inifile);	// Save this value back to the INI file.
		}
		break;
	case 'I': // III or I2
		// I20xnnmm
		if (Line[2]=='2') // SAA7113 I2C. value. 0xnnmm where nn=address mm=value to write 
		{
			strcpy_P(str,PSTR("Setting SAA7113 I2C register\n"));
			ptr=&Line[3];
			xatoi(&ptr,&n);
			xprintf(PSTR("Blah=%04X\n"),n);
			i2c_SetRegister((n>>8)&0xff,n&0xff);			
			xprintf(PSTR("Done\n"));
		}		
		break;
	case 'J' : // J<h>,DATA - Send a packet to SRAM address
		// Probably want a whole family of J commands.
		// JA<h> - Set the address pointer to SRAM page <h> where <h> is 0..d
		// JW<data> - Write a complete 45 byte packet to the current address and increment
		// JR<data> - Read back the next block of data and increment the pointer.
		// [JT<h> - Retransmit page <h> immediately. (can't work. You must Tx the parent page) ]
		// JT<mpp> - Transmit page <mpp> immediately. (probably need to set a flag in the magazine stream
		// to insert the page in the next transmission slot
		switch (Line[2])
		{
		case 'A': // eg. JA,0   - Set to the start of 
			//xprintf(PSTR("JA set SRAM address (page level)\n"));
			Line[2]='0';Line[3]='x';
			ptr=&Line[2];
			xatoi(&ptr,&n);
			//xprintf(PSTR("JA page=%X SRAMPAGECOUNT=%X SRAMPAGEBASE=%X\n"),n,SRAMPAGECOUNT,SRAMPAGEBASE);
			if (n>=SRAMPAGECOUNT)	// Make sure the page is in range
				returncode=1;					
			else
			{
				n=SRAMPAGEBASE+n*SRAMPAGESIZE;	// This is the actual address
				//xprintf(PSTR("JA address=%04X\n"),n);
				SRAMAddress=n;
				//row=1;
			}
			// We should now fill the packet with some instructions on how to use it!
			// Set the SRAM page address 0..e. There are 14 pages 
			// Coarse address setting
			// For the lulz, JZ gives random access down to byte level
			break;
		case 'Z': // Jay-Z, geddit?, JZ<hex addr 16 bit>
			Line[2]='0';Line[3]='x';
			ptr=&Line[2];
			xatoi(&ptr,&n);
			//xprintf(PSTR("JZ set SRAM address (byte level)\n"));
			//xprintf(PSTR("JZ page=%04X\n"),n);
			// Set the SRAM page address at byte level. Needs an actual 16 bit address
			// where only 15 bits are used.
			// For finer control than the JA command.
			// For the lulz and ability to plonk stuff using random access.
			SRAMAddress=n;
			break;
		case 'W': // JW,<row>,data - Write a packet to the SRAM page buffer
			//xprintf(PSTR("JW Write SRAM data\n"));
			ptr=&Line[3];
			while (*ptr>=' ' && !isdigit(*ptr)) ptr++;	// Seek the row value
			row=atoi(ptr);
			if (!row) // Row address must be greater than 0 					
			{
				returncode=1;	
				break;
			}
			while (isdigit(*ptr) || *ptr==',') ptr++;	// Seek the comma after row
			// If the fifo is transmitting, we must wait here
			for (i=0;FIFOBusy;i++);	// Can this break if the video source has stopped? We may want to timeout on this!
			// xprintf(PSTR("JW addr=%d\n"),row);
			// Write a single packet
			// Not sure how we are going to map control codes but probably the same as OL 
			// Write the packet that we are going to decode into @SRAMAddress
			// TODO: Check the row number to see we don't have a buffer overrun
			// Load and decode the packet

			// Replace this with a section that reads a line of data from USB
			
			// For the first attempt, I'll just copy the rest of the command line
			// I think it is null terminated? Hmm or \r
			// JW,<rest of command line>
			PORTC.OUT&=~VBIT_SEL; // Set the mux to MPU so that we are in control
			for (i=0;i<45;i++)packet[i]=0;
			WritePrefix(packet, 5, row); // This prefix gets replaced later
			packet[3]=row;	// The row gets encoded just before writing to FIFO
			//row++;
			// MRG line format is bit 8 set if it is a control code < ' '
			for (int i=5;i<45 && *ptr && *ptr!='\r';i++)
			{
				packet[i]=*ptr++ & 0x7f;	
			}
			// ** find the address of the row **
			n=SRAMAddress+(row-1)*PACKETSIZE;
			SetSerialRamAddress(SPIRAM_WRITE, n);
			//xprintf(PSTR("JW write address=%04X\n"),n);

			//SRAMAddress+=PACKETSIZE;
			WriteSerialRam(packet,45);
			DeselectSerialRam();
			break;
		case 'R':
			xprintf(PSTR("JR Read back SRAM data\n"));
			// Read back a single packet (translated back into OL format)
			break;
		case 'T':
			xprintf(PSTR("JT Transmit mpp\n"));
			// Set a flag to transmit the selected page ASAP.
			break;
		default:
			returncode=1;
		}
		break;
	case 'L': // L<nn>,<line data>
		// We don't use L in vbit. Because it would require RAM buffering or more file writing,
		// instead we use the e command which writes the file directly.
		xprintf(PSTR("L command not implemented. Use 'e'\n"));
		str[0]=0;
		returncode=1;
		break;
	case 'M': // MD - Delete all the pages selected by the last P command.
		xprintf(PSTR("Delete...\n"));
		// Iterate down all the pages
		// Traverse down subpages and release nodes
		// Go into the pages index and null out the entries in pages.idx
		break;
	case 'O':	/* O - Opt out. Example: O1c*/
		/* Two digit hex number. Only 6 bits are used so the valid range is 0..3f */
			ptr=&Line[0];
			Line[0]='0';Line[1]='x';
			xatoi(&ptr,&n);
			OptRelays=n & 0x3f;
		break;		
	case 'P': // P<mppss>. An invalid character will set null. P without parameters will return the current value
		ptr=&Line[2];
		if (!*ptr)
		{
			sprintf_P(str,PSTR("%s\n\r"),pageFilter);
			break;
		}
		dest=pageFilter;
		for (i=0;i<5;i++)
		{
			ch=*ptr++;
			if (ch=='*')
				valid=1;
			else
			{
				switch (i)
				{
				case 0 : // M
					valid=(ch>'0' && ch<'9' );break;
				case 1 :; // PP
				case 2 :
					valid=((ch>='0' && ch<='9') || (ch>='A' && ch<='F'));break;
				case 3 :; // SS
				case 4 :
					valid=(ch>='0' && ch<='9');break;
				}
			}
			if (valid)
				*dest++ = ch;
			else
			{
				dest[0]=0;
				break;
			}
		}
		*dest=0;	// terminate the string
		// TODO: Find out how many pages are in this page range
		pagecount=FindPageCount();
		if (pagecount<0)
		{
			pagecount=1;
			returncode=8;
			// TODO: At this point we must create the page, as we are about to receive the contents.
			xprintf(PSTR("Page has been created. Please send some data to fill the page\n\r"));
		}
		sprintf_P(str,PSTR("%04d"),pagecount); // Where nnn is the number of pages in this filter. 099 is a filler ack and checksum 
		// str[0]=0;
		break;
	case 'Q' : // QO, QM
		if (Line[2]=='M') // QMnn
		{
			ptr=&Line[3];
			xatoi(&ptr,&n);
			xprintf(PSTR("QM command, n=%d\n"),n);
			n = ini_putl("service", "serialmode", n, inifile);	
			// And at this point put it into the vbi configuration
			// vbi_mode_serial=0 or CTRL_C11_MAGAZINESERIAL_bm
			/** TBA. This setting needs to be in the VBI section
			if (n) 
				vbi_mode_serial=0;
			else
				vbi_mode_serial=CTRL_C11_MAGAZINESERIAL_bm;
			*/
			break;
		}
		// QO sets both odd and even lines
		// QD only sets the odd.
		if (Line[2]=='O' || Line[2]=='D') // QO[18 characters <P|Q|1..8|F>]. QD is the odd line and has 18 lines
		{
			int i;
			char ch;
			ptr=&Line[3];

			xputc('0');
			// Validate it.
			for (i=0;i<18;i++)
			{
				ch=*ptr++;
				switch (ch)
				{
				case '1':;case'2':;case'3':;case'4':;case'5':;case'6':;case'7':;case'8':;case'I':;
				case'F':;
				case'P':;
				case'Q':;
				case'Z':;
					break;
				default:
					returncode=1;
				}
				g_OutputActions[0][i]=ch;		// odd field
				if (Line[2]=='O')
					g_OutputActions[1][i]=ch;	// even field (QO only)
			}
			*ptr=0;
			if (returncode) break;
			n = ini_puts("service", "outputodd", &Line[3], inifile);	
			if (Line[2]=='O')
				n = ini_puts("service", "outputeven", &Line[3], inifile);	// QO only
			break;
		}
		returncode=1;
		break;
	// We could probably use the S command to encapsulate Newfor. We aren't going to be setting the page status much.
	case 'S' : ; // Newfor. This should be a Newfor command. Hmm, but how to escape SO and SI?
		// Work out how to escape data. The parity and reserved characters will break the CI
		break;
	case 'T': // T <hhmmss> (this syntax was superceded by GUT and GUt)
		// testIni();
		// test3();
		// test2();
		// UTC is the time of day in seconds
		Line[8]=0;
		ptr=&(Line[2]);
		UTC=0; // Maybe save this. We need to revert if it fails.
		for (i=2;i<8;i++)
		{
			// First multiply according to which digit
			switch (i)
			{
			case 3:;
			case 5:;
			case 7:
				UTC*=10;break;
			case 4:;
			case 6:
				UTC*=6;break; // (already *10!)
			}
			ch=*(ptr++)-'0';
			UTC+=ch;
		}
		
		// xprintf(PSTR("UTC=%d\n\r"),UTC); // This upsets the protocol!
		
		/**
		UTC=Line[7]-'0';				// s units
		UTC=UTC+(Line[6]-'0')*10;		// s tens
		UTC=UTC+(Line[5]-'0')*60;		// m units
		UTC=UTC+(Line[4]-'0')*60*10;	// m tens
		UTC=UTC+(Line[3]-'0')*60*60;	// h units
		UTC=UTC+(Line[2]-'0')*60*60*10;	// h tens
		*/
		// strcpy_P(str,PSTR("OK\n"));
		str[0]=0;
		break;
	case 'U': // TEST
		Init830F1();
		break;
	case 'V': // Communication settings. 2 hex chars (bit=(on/off) 7=Viewdata/Text 1=CRLF/CR 0=Echo/Silent
		// VBIT seems a bit fussy. When using TED Scheduler it is best to sat V00
		pagecount=sscanf(&(Line[2]),"%2X",&i);
		// xprintf(PSTR("sscanf returns %d. Parameter is %X0\n\r"),pagecount,i);
		if (pagecount>0)
		{
			echoMode=i;		// Yes, it was OK
			// TODO: Save the result in the INI
		}
		else
			returncode=1;	// No, it failed
		break;
	case 'W': // TEST Ad-tec opt outs
		// W14 - Send a mode 14 opt out
		// We want to be able to test various ATP950 modes.
		// read the parameter
		ptr=&Line[2];	
		xatoi(&ptr,&n);
		OptOutMode=n;
		xprintf(PSTR("W=%04X\n"),OptOutMode);
		// Which command? Set the appropriate opt out mode
		switch (OptOutMode)
		{
		case 14:
			xprintf(PSTR("Mode 14 shenanigans\n"),n);
			// Or just flag that we want an opt-out packet
			OptOutMode=14;
			OptOutType=OPTOUT_START;
			// Assemble a mode 14 packet
			break;
		default:
			OptOutMode=0;
			returncode=1;
		}
		// Assemble the packet and 
		break;
	case 'X':	/* X - Exit */
		return 2;	
	case 'Y': /* Y - Version. Y2 should return a date string */
		strcpy_P(str,PSTR("VBIT620 Version 0.04"));
		break;		
	case '?' :; // Status TODO
		xprintf(PSTR("STATUS %02X\n\r"),statusI2C);
		// Want to know if the chips check out and the file system is OK
		// Video Input:
		xprintf(PSTR("Video input: "));report(statusI2C & 0x01); // chip responds, generating field interrupts
		// Digital Encoder
		xprintf(PSTR("Digital encoder: "));report(statusI2C & 0x02); // chip responds
		// FIFO
		statusFIFO=test2();
		xprintf(PSTR("FIFO R/W verified: "));report(statusFIFO); // we can read and write to it
		// File system
		xprintf(PSTR("File system: "));report(statusDisk); // There is a card, it is formatted, it has onair/pages.all
		break;
	default:
		xputs(PSTR("Unknown command\n"));
		returncode=1;
	}
示例#14
0
文件: SDFatFs.cpp 项目: ADTL/ARMWork
size_t SDFile::write(const uint8_t c) {
  return ( f_putc((TCHAR)c, &file) == 1 ? 1 : 0); 
}
示例#15
0
//需要_USE_STRFUNC>=1
//写一个字符到文件
//c:要写入的字符
//返回值:执行结果
u8 mf_putc(u8 c)
{
	return f_putc((TCHAR)c,file);
}
示例#16
0
int FatFs::File::putc(char c)
{
    return f_putc(c, &file);
}
示例#17
0
int DFILE::fsputc (char c)									
{
    return(f_putc (c, &_file));
}
static msg_t ThreadFatFSWorker(void *arg) {
    (void)arg;

    Thread* p;

    chRegSetThreadName("fatfsWorker");
    while (!chThdShouldTerminate()) {

        /* Wait for msg with work to do. */
        p = chMsgWait();


        struct wrapper_msg_base* msg = (struct wrapper_msg_base*) chMsgGet(p);

        msg->result = FR_INVALID_PARAMETER;

        switch(msg->action) {

        case eTERMINATE: {
            break;
        }

#if HAS_MOUNT
        case eFMOUNT: {
            const struct wrapper_msg_vBYTEpFATFS* exmsg = \
                    (const struct wrapper_msg_vBYTEpFATFS*) msg;
            msg->result = f_mount(exmsg->byte, exmsg->fatfsp);
            break;
        }
#endif /* HAS_MOUNT */

#if HAS_OPEN
        case eFOPEN: {
            const struct wrapper_msg_pFILpTCHARvBYTE* exmsg = \
                    (const struct wrapper_msg_pFILpTCHARvBYTE*) msg;

            msg->result = f_open(exmsg->filep, exmsg->string, exmsg->byte);
            break;
        }
#endif /* HAS_OPEN */

#if HAS_READ
        case eFREAD: {
            const struct wrapper_msg_pFILpVOIDvUINTpUINT* exmsg = \
                    (const struct wrapper_msg_pFILpVOIDvUINTpUINT*) msg;

            msg->result = f_read(exmsg->filep, exmsg->voidp, exmsg->uint,
                                 exmsg->uintp);
            break;
        }
#endif /* HAS_READ */

#if HAS_WRITE
        case eFWRITE: {
            const struct wrapper_msg_pFILpVOIDvUINTpUINT* exmsg = \
                    (const struct wrapper_msg_pFILpVOIDvUINTpUINT*) msg;
            msg->result = f_write(exmsg->filep, exmsg->voidp, exmsg->uint,
                                  exmsg->uintp);
            break;
        }
#endif /* HAD_WRITE */

#if HAS_SYNC
        case eFSYNC: {
            const struct wrapper_msg_pFIL* exmsg = \
                                                   (const struct wrapper_msg_pFIL*) msg;
            msg->result = f_sync(exmsg->filep);
            break;
        }
#endif /* HAS_SYNC */

#if HAS_CHDRIVE
        case eFCHDRIVE: {
            const struct wrapper_msg_vBYTE* exmsg = \
                                                    (const struct wrapper_msg_vBYTE*) msg;
            msg->result = f_chdrive(exmsg->byte);
            break;
        }
#endif

#if HAS_CHDIR
        case eFCHDIR: {
            const struct wrapper_msg_pTCHAR* exmsg = \
                    (const struct wrapper_msg_pTCHAR*) msg;

            msg->result = f_chdir(exmsg->string);
            break;
        }
#endif /* HAS_CHDIR */

#if HAS_GETCWD
        case eFGETCWD: {
            const struct wrapper_msg_pTCHARvUINT* exmsg = \
                    (const struct wrapper_msg_pTCHARvUINT*) msg;
            msg->result = f_getcwd(exmsg->string, exmsg->uint);
            break;
        }
#endif

#if HAS_LSEEK
        case eFLSEEK: {
            const struct wrapper_msg_pFILvDWORD* exmsg = \
                    (const struct wrapper_msg_pFILvDWORD*) msg;
            msg->result = f_lseek(exmsg->filep, exmsg->dword);
            break;
        }
#endif /* HAS_LSEEK */

#if HAS_CLOSE
        case eFCLOSE: {
            const struct wrapper_msg_pFIL* exmsg = \
                                                   (const struct wrapper_msg_pFIL*) msg;
            msg->result = f_close(exmsg->filep);
            break;
        }
#endif /* HAS_CLOSE */

#if HAS_OPENDIR
        case eFOPENDIR: {
            const struct wrapper_msg_pDIRpTCHAR* exmsg = \
                    (const struct wrapper_msg_pDIRpTCHAR*) msg;
            msg->result = f_opendir(exmsg->dirp, exmsg->string);
            break;
        }
#endif /* HAD_OPENDIR */

#if HAS_READDIR
        case eFREADDIR: {
            const struct wrapper_msg_pDIRpFILINFO* exmsg = \
                    (const struct wrapper_msg_pDIRpFILINFO*) msg;
            msg->result = f_readdir(exmsg->dirp, exmsg->filinfop);
            break;
        }
#endif /* HAS_READDIR */

#if HAS_STAT
        case eFSTAT: {
            const struct wrapper_msg_pTCHARpFILINFO* exmsg = \
                    (const struct wrapper_msg_pTCHARpFILINFO*) msg;
            msg->result = f_stat(exmsg->string, exmsg->filinfop);
            break;
        }
#endif /* HAS_STAT */

#if HAS_GETFREE
        case eFGETFREE: {
            const struct wrapper_msg_pTCHARpDWORDppFATFS* exmsg = \
                    (const struct wrapper_msg_pTCHARpDWORDppFATFS*) msg;
            msg->result = f_getfree(exmsg->string, exmsg->dwordp, exmsg->fatfspp);
            break;
        }
#endif /* HAS_GETFREE */

#if HAS_TRUNCATE
        case eFTRUNCATE: {
            const struct wrapper_msg_pFIL* exmsg = \
                                                   (const struct wrapper_msg_pFIL*) msg;
            msg->result = f_truncate(exmsg->filep);
            break;
        }
#endif /* HAS_TRUNCATE */

#if HAS_UNLINK
        case eFUNLINK: {
            const struct wrapper_msg_pTCHAR* exmsg = \
                    (const struct wrapper_msg_pTCHAR*) msg;
            msg->result = f_unlink(exmsg->string);
            break;
        }
#endif /* HAS_UNLINK */

#if HAS_MKDIR
        case eFMKDIR: {
            const struct wrapper_msg_pTCHAR* exmsg = \
                    (const struct wrapper_msg_pTCHAR*) msg;
            msg->result = f_mkdir(exmsg->string);
            break;
        }
#endif /* HAS_MKDIR */

#if HAS_CHMOD
        case eFCHMOD: {
            const struct wrapper_msg_pTCHARvBYTEvBYTE* exmsg = \
                    (const struct wrapper_msg_pTCHARvBYTEvBYTE*) msg;
            msg->result = f_chmod(exmsg->string, exmsg->byte1, exmsg->byte2);
            break;
        }
#endif /* HAS_CHMOD */

#if HAS_UTIME
        case eFUTIME: {
            const struct wrapper_msg_pTCHARpFILINFO* exmsg = \
                    (const struct wrapper_msg_pTCHARpFILINFO*) msg;
            msg->result = f_utime(exmsg->string, exmsg->filinfop);
            break;
        }
#endif /* HAD_UTIME */

#if HAS_RENAME
        case eFRENAME: {
            const struct wrapper_msg_pTCHARpTCHAR* exmsg = \
                    (const struct wrapper_msg_pTCHARpTCHAR*) msg;

            msg->result = f_rename(exmsg->string1, exmsg->string2);
            break;
        }
#endif /* HAS_RENAME */

#if HAS_MKFS
        case eFMKFS: {
            const struct wrapper_msg_vBYTEvBYTEvUINT* exmsg = \
                    (const struct wrapper_msg_vBYTEvBYTEvUINT*) msg;
            msg->result = f_mkfs(exmsg->byte1, exmsg->byte2, exmsg->uint);
            break;
        }
#endif /* HAS_MKFS */

#if HAS_FDISK
        case eFFDISK: {
            const struct wrapper_msg_vBYTEpDWORDpVOID* exmsg = \
                    (const struct wrapper_msg_vBYTEpDWORDpVOID*) msg;
            msg->result = f_fdisk(exmsg->byte, exmsg->dwordp, exmsg->voidp);
            break;
        }
#endif /* HAS_FDISK */

#if HAS_GETS
        case eFGETS: {
            struct wrapper_msg_pTCHARvINTpFILpTCHAR* exmsg = \
                    (struct wrapper_msg_pTCHARvINTpFILpTCHAR*) msg;

            exmsg->string2 = f_gets(exmsg->string, exmsg->n, exmsg->filep);
            break;
        }
#endif /* HAS_GETS */

#if HAS_PUTC
        case eFPUTC: {
            const struct wrapper_msg_vTCHARpFIL* exmsg = \
                    (const struct wrapper_msg_vTCHARpFIL*) msg;

            msg->result = f_putc(exmsg->tchar, exmsg->filep);
            break;
        }
#endif /* HAS_PUTC */

#if HAS_PUTS
        case eFPUTS: {
            const struct wrapper_msg_pTCHARpFIL* exmsg = \
                    (const struct wrapper_msg_pTCHARpFIL*) msg;

            msg->result = f_puts(exmsg->string, exmsg->filep);
            break;
        }
#endif /* HAS_PUTS */

        }

        /* Done, release msg again. */
        chMsgRelease(p, 0);
    }

    return 0;
}