
#ifndef __STDIO_H
#define __STDIO_H 1


#ifdef __cplusplus
extern "C" {
#endif

#include "stdarg.h"



#ifndef EOF
# define EOF (-1)
#endif

#ifndef NULL
  #define NULL (void *)0
#endif
//#################################################################

//#################################################################

typedef void *STREAM;

/* USART   module stream descriptors */

#define USART0_STREAM                     ((STREAM *)0x40000980UL)
#define USART1_STREAM                     ((STREAM *)0x40000A00UL)
#define USART2_STREAM                     ((STREAM *)0x40000A80UL)
#define USART3_STREAM                     ((STREAM *)0x40000B00UL)
#define USART4_STREAM                     ((STREAM *)0x40000B80UL)

#define USART5_STREAM                     ((STREAM *)0x40001E80UL)
#define USART6_STREAM                     ((STREAM *)0x40001F00UL)
#define USART7_STREAM                     ((STREAM *)0x40001F80UL)
/*SOME HAVE */
#define USART8_STREAM                      ((STREAM *)0x40004700UL)
#define USART9_STREAM                      ((STREAM *)0x40004780UL)
#define USART10_STREAM                     ((STREAM *)0x40004800UL)
#define USART11_STREAM                     ((STREAM *)0x40004880UL)
#define USART12_STREAM                     ((STREAM *)0x40004900UL)
#define USART13_STREAM                     ((STREAM *)0x40004980UL)
#define USART14_STREAM                     ((STREAM *)0x40005680UL)
#define USART15_STREAM                     ((STREAM *)0x40005700UL)

/*defalt */
#define	stdin	USART0_STREAM
#define	stdout	USART0_STREAM
#define	stderr	USART0_STREAM


//#################################################################for lib
#define  __IO_getchar			getchar
#define  __stream_getchar		fgetchar

#define  __IO_puts 				puts
#define  __stream_puts			fputs

#define  __IO_putchar 			putchar
#define  __stream_putchar		fputchar
//####################################################
 // Basic USART INPUT OUTPUT , weak can be rewrite
 //####################################################

extern char getchar	 (void);					// USART0_STREAM
extern char fgetchar (STREAM *stream);			// USART0_STREAM ~ USART7_STREAM   USART8_STREAM~USART15_STREAM

extern int putchar  (int c);					// USART0_STREAM
extern int fputchar (int c,STREAM *stream);		// USART0_STREAM ~ USART7_STREAM   USART8_STREAM~USART15_STREAM

/*
under lib,these four function is designed by weak    ,you can rewrite this for yourself code,like

__attribute__((optimize("-O2"))) __attribute__((noinline)) 
int  putchar (int c)
{
  unsigned int timeout=20000;  // like this ,need > byte send time.
  (void)c;
  //###############################
  //USART        USARTx_TBUFR 
  volatile unsigned int* deref=( unsigned int*)USART0_STREAM;
  deref[3] =c;
  #if 0
	  __asm("DSI");
	  while( 	(deref[2]&(1<<13))  !=0	);
	  while( 	(deref[2]&(1<<13)) 	==0	);
	  __asm("ENI");
	  // or delay a byte send time;
  #else
  __asm__("NOP");
	  while( 	(deref[2]&(1<<27)) 	==0	){
		  	if(timeout-- ==0 )
		  		return -1;
	  }// or delay a byte send time;
  #endif
 return 0;
}
__attribute__((optimize("-O2"))) __attribute__((noinline)) 
int  fputchar   (int c,STREAM *stream)
{
  unsigned int timeout=20000; // like this ,need > byte send time.
  volatile unsigned int* deref=( unsigned int*)stream;
  deref[3] =c;
  #if 0
	  __asm("DSI");
	  while( 	(deref[2]&(1<<13))  !=0	);
	  while( 	(deref[2]&(1<<13)) 	==0	);
	  __asm("ENI");
	  // or delay a byte send time;
  #else
  __asm__("NOP");
	  while( 	(deref[2]&(1<<27)) 	==0	){
		  	if(timeout-- ==0 )
		  		return -1;
	  }// or delay a byte send time;
  #endif
 return 0;
}
//#########################################################################################
char   getchar(void)
{
	volatile unsigned int* deref=( unsigned int*)USART0_STREAM;

	 while( 	(deref[2]&(1<<11)) 	==0	);
	 return deref[4];
}
char   fgetchar (STREAM *stream)
{
   volatile unsigned int* deref=( unsigned int*)stream;

   while( 	(deref[2]&(1<<11)) 	==0	);
   return deref[4];
}
*/
//#########################################################################################
extern int puts (const char *);					 // USART0_STREAM
extern int fputs(const char *str,STREAM *stream);// USART0_STREAM ~ USART7_STREAM  USART8_STREAM~USART15_STREAM
extern int fwrite(const char *str,unsigned int Size,unsigned int N, STREAM *stream);

//####################################################
 // Format USART INPUT
 //####################################################
extern char	_scanf_buf_[256];

extern char getche(void);   // not lib ,if use scanf or vscanf,you need implementation it
//{
//	return getchar();
//	return fgetchar(USART0_STREAM);
//  return Buffer[x++];
//}
extern char * gets(char * s);  // Invoking cgets
extern char * cgets(char * s);

extern int scanf  (const char * fmt, ...);							//format input
extern int vscanf (const char * fmt, va_list ap);					//format input

extern int fscanf (const char * str,const char * fmt, ...);			//format input
extern int sscanf (const char * str,const char * fmt, ...);			//format input

extern int vsscanf(const char * str,const char * fmt, va_list ap);	//format input
//####################################################
// USART0_STREAM  Format Output// Format Output With USARTx_STREAM// Format Output With Character String
//####################################################
// USART0_STREAM
extern int printf (const char *fmt, ...);
// USART0_STREAM ~ USART7_STREAM   USART8_STREAM~USART15_STREAM
extern int fprintf (STREAM *stream, const char *fmt, ...);
// format string buffer
extern int sprintf (char *str, const char *fmt, ...);
extern int snprintf (char *str, unsigned int n, const char *format, ...);

//####################################################
// Real Output|Format Function
//####################################################
extern int vprintf (const char *fmt, va_list ap);
extern int vfprintf (STREAM *stream, const char *fmt, va_list ap);
extern int vsprintf (char *str, const char *fmt, va_list ap);
extern int vsnprintf (char *s, unsigned int n, const char *format, va_list ap);	// weak can be rewrite
/*
int  
vsnprintf (char *str, unsigned int n, const char *format, va_list ap)
{
  char buf[512];  // no malloc to use ,limit max length string to x bytes,with stack enough
  int result=0;
  //##################################################################
  result = vsprintf (buf, format, ap);
  if (n > 0)   {
      if ((long) n > result)
    	  memcpy (str, buf, result+1);
      else   {
    	  memcpy (str, buf, n-1);  	  str[n - 1] = 0;
      }
  }
  //##################################################################
  return result;
}
*/
//####################################################
//similar printf ,small and independence
//####################################################
// use    USART0_STREAM
extern void printf_small (const char *fmt, ...);/* printf_small() supports float print */
extern void printf_tiny (const char *fmt, ...);/* printf_tiny() does not support float print */
//####################################################
#ifdef __cplusplus
}
#endif

#endif /* __STDIO_H */

