Pages: [1]   Go Down
Author Topic: Assign I/0 Stream to UART  (Read 960 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello
I am implementing a webserver using Arduino Ethernet ,Arduino USB2 Serial as Programmer and Arduino Nightly IDE. I have writen  a programm in C. This programm should diplay IP, MAC and SUB Mask Adress on  Hyperterminal Screen(Putty,Teraterm etc) when i enter "ping".
For enabling I/O Steam throuhg UART  i used this following function :
FILE uart_str=FDEV_SETUP_STREAM(uart_putch,uart_getch, _FDEV_SETUP_RW);
When i build the sketch in Arduino IDE i get following error:
expected primary expression before '.'tocken"  
But when i build the same code in AVR Studio 4 i dont get any error.
As far as i know that Arduiono uses AVR GCC libraries  accoring to this reason i should not get this error.
It would be very kind of you  and great help for me,if you could give me some advices.
Regards

You can see my code bellow,

Code:
[/c#include<stdio.h>
//#include<avr\signal.h> diese Header Datei ist veraltet bei Auskommentierung bekommt man warning "this... is obsolete" statt der #include<avr\interrupt.h> benutzen

#define F_CPU 125000UL  //Diese Zeile muss vor #include<util\delay.h> stehen sonst bekommt man Warnung
#define BAUD_RATE 19200
#include<avr\interrupt.h>
#include<avr\io.h>
#include<util\delay.h>
#include<string.h>



//SPI I/O
#define SPI_PORT   PORTB
#define SPI_DDR    DDRB
#define SPI_CS     PORTB2

//Wiznet W5100 OP Code
#define WIZNET_WRITE_OPCODE  0xF0
#define WIZNET_READ_OPCODE   0x0F

//Wiznet W5100 Registe Adress
#define MR        0x0000       //Mode Register
#define GAR       0x0001       //Getwway Adress: 0x0001 to 0x0004
#define SUBR      0x0005       //Subnet mask address: 0x0005 to 0x0008
#define SAR       0x0009       //Source Hardware Address(MAC): 0x0009 to 0x000E
#define SIPR      0x000F       //Source IP Adress: 0x000F to 0x0012
#define RMSR      0x001A       //RX Memory Size Register
#define TMSR      0x001B       //TX Memory Size Register

//Methode to initialize uart
void uart_init(void)
{
  UBRR0H=((((F_CPU)/(BAUD_RATE))/16)-1)>>8;              //set Baud rate
  UBRR0L=((((F_CPU)/(BAUD_RATE))/16)-1);            
  UCSR0B=(1<<RXEN0)|(1<<TXEN0);                          //enable RX & TX
  UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);                        //Config Uart
}

void uart_flush(void)
{
  
  unsigned char dump;
  while(UCSR0A &(1<<RXC0))
  dump=UDR0;
  
}

int uart_putch(char ch, FILE *stream)
{
  if(ch=='\n')
  uart_putch(ch,stream);
  while(!(UCSR0A&(1<<RXC0)))
  UDR0=ch;
  return 0;
}

int uart_getch(FILE *stream)
{
  unsigned char ch=0;
  while(!(UCSR0A&(1<<RXC0)))
  ch=UDR0;
  /*Echo the output back to the terminal*/
  uart_putch(ch,stream);
  return ch;
}

void ansi_cl(void)
{
  //Ansi clear screen: cl=\E[H\E[J    Ansi Code zum Bereinigen des Bildschirmes
  putchar(27);
  putchar('[');
  putchar('H');
  putchar(27);
  putchar('[');
  putchar('J');
}


void ansi_me(void)
{
  //ANSI turn off all attribute: me=\E[0m
  
  putchar(27);
  putchar('[');
  putchar('0');
  putchar('m');
}
  


void SPI_Write(unsigned int addr,unsigned char data)
{
  //Active the CS pin
  SPI_PORT&=~(1<<SPI_CS);
  
  //Sending Wiznet Write Opcode to indicate that its goona be written
  SPDR=WIZNET_WRITE_OPCODE; //SPDR is SPI Data Register for transmission
  
  //Wait for transmission complete.When its complete the SPIF bit of SPI Status Register turns 0
  while(!SPSR &(1<<SPIF))
  //Start Wiznet Address High Byte transmission
  SPDR=((0xFF00)&addr)>>8 ;//Nach der Undverkünpfung wir 8 bit nach recths verlegt
  //Wait for Transmission complete
  while(!(SPSR&(1<<SPIF)))
  //Sending low byte of address
  SPDR=addr&0x00FF;
  //wait for Transmission complete
  while(!(SPSR&(1<<SPIF)))
  //Start data transmission
  SPDR=data;
  //Wait for Transmission complete
  while(!(SPSR&(1<<SPIF)))
  //Deactivate CS pin
  SPI_PORT|=(1<<SPI_CS);
  
}


unsigned char SPI_Read(unsigned int addr)
{
  
  //Activate CS pin of Wiznet
  SPI_PORT&=~(1<<SPI_CS);
  //Preparing Wiznet for reading
  SPDR=WIZNET_READ_OPCODE;
  //wait for Tranmission complete
  while(!(SPSR&(1<<SPIF)))
  //Send high byte of Address
  SPDR=(0xFF00&addr)>>8;
  //wait for Transmission complet
  while(!(SPSR&(1<<SPIF)))
  //Sending low byte of Adress
  SPDR=(0x00FF&addr);
  //wait for Tranmission complete
  while(!(SPSR&(1<<SPIF)))
  //Sending dummy for reading data
  SPDR=0x00;
  //Wait for Transmission complete
  while(!(SPSR&(1<<SPIF)))
  
  //Deactivation of CS pin
  SPI_PORT|=(1<<SPI_CS);
  
  return SPDR;
  
  
}


//Initializing Wiznet Ethernet Controller
void W5100_Init(void)
{
  unsigned char mac_addr[]={0x00,0x16,0x36,0xDE,0x58,0xF6};
  unsigned char ip_addr[]={192,168,0,10};
  unsigned char sub_mask[]={255,255,255,0};
  unsigned char gtw_addr[]={192,168,0,1};
  
 //Setting the Wiznet Mode Register
 SPI_Write(MR,0x80);
 _delay_ms(10);
 
 printf("Reading MR: %d\n\n", SPI_Read(MR));
 
 //Setting Getway Register
 printf("Setting Getway Address:%d.%d.%d.%d\n\n",gtw_addr[0],gtw_addr[1],gtw_addr[2],gtw_addr[3]);
 SPI_Write(GAR+0,gtw_addr[0]);
 SPI_Write(GAR+1,gtw_addr[1]);
 SPI_Write(GAR+2,gtw_addr[2]);
 SPI_Write(GAR+3,gtw_addr[3]);
 _delay_ms(10);//Wait to set properly
 
 printf("Reading GAR: %d.%d.%d.%d\n\n",SPI_Read(GAR+0),SPI_Read(GAR+1),SPI_Read(GAR+2),\
        SPI_Read(GAR+3));
 
 //Setting MAC Address
 printf("Setting Source Address Register:%d.%d.%d.%d\n\n",mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
 SPI_Write((SAR+0),mac_addr[0]);
 SPI_Write(SAR+1,mac_addr[1]);
 SPI_Write(SAR+2,mac_addr[2]);
 SPI_Write(SAR+3,mac_addr[3]);
 SPI_Write(SAR+4,mac_addr[4]);
 SPI_Write(SAR+5,mac_addr[5]);
 _delay_ms(10);//Wait to set properly
 
 printf("Reading SAR:%.2x:%.2x:%.2x:%.2x:%.2x:%2x\n\n",SPI_Read(SAR+0),SPI_Read(SAR+1),SPI_Read(SAR+2),\
         SPI_Read(SAR+3),SPI_Read(SAR+4),SPI_Read(SAR+5));
        
 
 //Setting Submask Register
 printf("Setting Submask Register:%d.%d.%d.%d\n\n",sub_mask[0],sub_mask[1],sub_mask[2],sub_mask[3]);
 SPI_Write(SUBR+0,sub_mask[0]);
 SPI_Write(SUBR+1,sub_mask[1]);
 SPI_Write(SUBR+2,sub_mask[2]);
 SPI_Write(SUBR+3,sub_mask[3]);
 _delay_ms(10);//Wait to set properly

 printf("Reading Submask Register:%d.%d.%d.%d\n\n",SPI_Read(SUBR+0),SPI_Read(SUBR+1),SPI_Read(SUBR+2),\
         SPI_Read(SUBR+3));
 
 
 
 //Setting IP Adress Register
 printf("Setting SIPR:%d.%d.%d.%d\n\n",ip_addr[0],ip_addr[1],ip_addr[2],ip_addr[3]);
 SPI_Write(SIPR+0,ip_addr[0]);
 SPI_Write(SIPR+1,ip_addr[1]);
 SPI_Write(SIPR+2,ip_addr[2]);
 SPI_Write(SIPR+3,ip_addr[3]);
 _delay_ms(10);//Wait to set properly
 
 printf("Reading SIPR:%d.%d.%d.%d\n\n",SPI_Read(SIPR+0),SPI_Read(SIPR+1),SPI_Read(SIPR+2),SPI_Read(SIPR+3));
 
 
 //Setting Wiznet RX and TX memory size (2KB for RX and TX )
 printf("Setting Wiznet RMSR and TMSR\n\n");
 SPI_Write(RMSR,0x55);
 SPI_Write(TMSR,0x55);
 printf("Wiznet is initialized\n");
 
}  


 //Assign I/O stream to UART   :-( :-(
 FILE uart_str=FDEV_SETUP_STREAM(uart_putch,uart_getch, _FDEV_SETUP_RW);  
  
 int main(void)
 {
   //Set PORTD as Output
   DDRD=0xff;
   PORTD=0x00;
  
   //Define In/Output Stream
   stdout=stdin=&uart_str;
  
   //Initialize UART Peripheral
   uart_init();
  
   //Clear Screen
   ansi_me();
   ansi_cl();
   ansi_me();
   ansi_cl();
   uart_flush();
  
   //Iniritialize AVR Mega328 Peripheral
   // Set MOSI(PORTB3),SCK(PORTB5), SS(PORTB2) as output, other as input
   SPI_DDR=(1<<PORTB3)|(1<<PORTB5)|(1<<PORTB2) ;
  
   //CS deactivate CS pin it is high incative
   SPI_PORT|=(1<<SPI_CS);
  
   //Enable SPI, Master Mose 0, set the clock rate fck/2
   SPCR=(1<<SPE)|(1<<MSTR);
   SPSR|=(1<<SPI2X);
  
   //Initialize the Wiznet W5100
   printf("Wiznet W5100 Init\n\n");
   W5100_Init();

   //Loop forever
   for(;;)
   {
   }
   return 0;  
  
 }
ode]
« Last Edit: April 08, 2013, 06:37:41 pm by slewrate » Logged

Rome, Italy
Offline Offline
Sr. Member
****
Karma: 20
Posts: 442
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, the line:

Code:
FILE uart_str=FDEV_SETUP_STREAM(uart_putch,uart_getch, _FDEV_SETUP_RW);   

standing by its own, doesn't make much sense (at least not to me), since it is not part of a function (you can see that immediately after the main() function is defined). Perhaps it's a macro that expands to a function definition, I don't know.

Anyway, the different behavior between Arduino IDE and AVR Studio is probably due to the fact that the Arduino IDE uses a preprocessor to insert lines of code (#include statements, the main() function) that are not present in Arduino sketches). The preprocessor is not as smart as the gcc compiler and (like myself) doesn't understand what that line is for, in that position, while the gcc compiler that is directly invoked by AVR Studio doesn't see a syntax error and proceeds.
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 152
Posts: 6191
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The Serial is already a stream. I used this and worked well. If you do not enter ping within a second, the findUntil function times out and returns false (displays "no ping" on serial monitor).

edit: New code. If nothing is in the serial buffer, it doesn't even check. It only prints "no ping" if you send something that doesn't contain "ping", which would be \r and \n.
Code:
void setup() {
  Serial.begin(9600);
}

void loop() {
  if(Serial.available()) {
    if(Serial.findUntil("ping","\n")) Serial.println("ping!");
    else Serial.println("no ping");
  }
}
http://arduino.cc/en/Reference/Stream
« Last Edit: April 09, 2013, 08:07:07 am by SurferTim » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a lot for your advices
Logged

Pages: [1]   Go Up
Jump to: