Go Down

Topic: Assign I/0 Stream to UART (Read 978 times) previous topic - next topic

slewrate

Apr 09, 2013, 01:10 am Last Edit: Apr 09, 2013, 01:37 am by slewrate Reason: 1
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: [Select]
[/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]

spatula

Hi, the line:

Code: [Select]

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.

SurferTim

#2
Apr 09, 2013, 02:41 pm Last Edit: Apr 09, 2013, 03:07 pm by SurferTim Reason: 1
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: [Select]
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

slewrate

Thanks a lot for your advices

Go Up