Subversion Repositories HomeAutomation

Rev

Rev 212 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

/**
 * CAN Test. This program sends a CAN message once every second. The ID of the
 * message is increased each time for testing purposes.
 * 
 * @date    2006-11-21
 * @author  Jimmy Myhrman
 *   
 */

/*-----------------------------------------------------------------------------
 * Includes
 *---------------------------------------------------------------------------*/
/* system files */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <stdio.h>
/* lib files */
#include <can.h>
//#include <serial.h>
#include <timebase.h>
#include <ip_arp_udp_tcp.h>
#include <enc28j60.h>
#include <timeout.h>
#include <avr_compat.h>
#include <net.h>

// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
static uint8_t myip[4] = {193,11,254,22};
static uint16_t remoteport =1200; // listen port for udp
static uint8_t gotserver = 0;

// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX

static uint8_t remotemac[6];
static uint8_t remoteip[4];

#define BUFFER_SIZE 250
static uint8_t buf[BUFFER_SIZE+1];
static uint8_t replybuf[BUFFER_SIZE+1];

int udp_putchar(char c, FILE* stream) {
    if (gotserver != 0) {
        uint8_t i=0;
        while(i<BUFFER_SIZE+1){
            buf[i]=replybuf[i];
            i++;
        }
        //send_udp(replybuf, &c, 1, remoteport, remotemac, remoteip);
        make_udp_reply_from_request(buf, "hello", 5, remoteport);
        //send_udp(buf, &c, 1, remoteport, remotemac, remoteip);
    }
    return 0;
}

static FILE mystdout = FDEV_SETUP_STREAM(udp_putchar, NULL, _FDEV_SETUP_WRITE); 

/*-----------------------------------------------------------------------------
 * Main Program
 *---------------------------------------------------------------------------*/
int main(void) {

    //ethernet vars
    uint16_t plen = 0;
    uint8_t ledi=0;
    uint8_t payloadlen=0;
    
    uint32_t timeStamp = 0;
    
    //can vars
    Can_Message_t txMsg;
    Can_Message_t rxMsg;
    txMsg.Id = 3;
    txMsg.DataLength = 0;
    txMsg.RemoteFlag = 0;
    txMsg.ExtendedFlag = 1; //DataLength and the databytes are just what happens to be in the memory. They are never set.
    
    Timebase_Init();
//  Serial_Init();
    #if defined(__AVR_ATmega88__)
    // set the clock speed to 8MHz
    // set the clock prescaler. First write CLKPCE to enable setting of clock the
    // next four instructions.
    CLKPR=(1<<CLKPCE);
    CLKPR=0; // 8 MHZ
    #endif
    
    //stdout = &mystdout;    //set the output stream 
    
    sei();

//  printf("CanInit...");
    if (Can_Init() != CAN_OK) {
//      printf("FAILED!\n");
    }
    else {
//      printf("OK!\n");
    }

    /* enable PB0, reset as output */
    DDRB|= (1<<DDB0);
    /* set output to gnd, reset the ethernet chip */
    PORTB &= ~(1<<PB0);
    delay_ms(20);
    /* set output to Vcc, reset inactive */
    PORTB|= (1<<PB0);
    delay_ms(100);
    
    // LED
    /* enable PB1, LED as output */
    DDRD|= (1<<DDD6);
    /* set output to Vcc, LED off */
    PORTD|= (1<<PD6);

    /*initialize enc28j60*/
    enc28j60Init(mymac);
    delay_ms(20);
    
    /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
    // LEDB=yellow LEDA=green
    //
    // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
    // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
    enc28j60PhyWrite(PHLCON,0x476);
    delay_ms(20);
    
    /* set output to GND, red LED on */
    PORTD &= ~(1<<PD6);
    ledi=1;
    
    //init the ethernet/ip layer:
    init_ip_arp_udp_tcp(mymac,myip,80);

    /* main loop */
    while (1) {
        /* service the CAN routines */
        Can_Service();
        
//PORTD &= ~(1<<PD6);
        
        /* send CAN message and check for CAN errors once every second */
        if (Timebase_PassedTimeMillis(timeStamp) >= 2000) {
            timeStamp = Timebase_CurrentTime();
            /* send txMsg */
            //txMsg.Id++;
            txMsg.Id = 3;
            Can_Send(&txMsg);
            if (ledi){
                    /* set output to Vcc, LED off */
                    PORTD|= (1<<PD6);
                    ledi=0;
            }else{
                    /* set output to GND, LED on */
                    PORTD &= ~(1<<PD6);
                    ledi=1;
            }
            
        }
        
        /* check if any messages have been received */
        while (Can_Receive(&rxMsg) == CAN_OK) {
            //printf("MSG Received: ID=%lx, DLC=%u, EXT=%u, RTR=%u, ", rxMsg.Id, (uint16_t)(rxMsg.DataLength), (uint16_t)(rxMsg.ExtendedFlag), (uint16_t)(rxMsg.RemoteFlag));
            /*printf("data={ ");
            for (uint8_t i=0; i<rxMsg.DataLength; i++) {
                printf("%x ", rxMsg.Data.bytes[i]);
            }
            printf("}\n");
            */
            if (gotserver != 0) {
                uint8_t i = 0;
                while(i<BUFFER_SIZE+1){
                    buf[i]=replybuf[i];
                    i++;
                }
                send_udp(buf, "hello", 6, remoteport, remotemac, remoteip);
                //make_udp_reply_from_request(buf, "hello", 5, remoteport);
                i = 0;
                while(i<BUFFER_SIZE+1){
                    buf[i]=replybuf[i];
                    i++;
                }
                //make_udp_reply_from_request(buf, "world", 5, remoteport);
                send_udp(buf, "world", 6, remoteport, remotemac, remoteip);
            }
            //printf("Hello world! %i \n", txMsg.Id);        
        }
        
        // get the next new packet:
        plen = enc28j60PacketReceive(BUFFER_SIZE, buf);

        /*plen will ne unequal to zero if there is a valid 
         * packet (without crc error) */
        if(plen!=0){
            // arp is broadcast if unknown but a host may also
            // verify the mac address by sending it to 
            // a unicast address.
            if(eth_type_is_arp_and_my_ip(buf,plen)){
                    make_arp_answer_from_request(buf);
            } else {
                // check if ip packets (icmp or udp) are for us:
                if(eth_type_is_ip_and_my_ip(buf,plen)!=0){
                    //if (ledi){
                            /* set output to Vcc, LED off */
                    //        PORTD|= (1<<PD6);
                    //        ledi=0;
                    //}else{
                            /* set output to GND, LED on */
                    //        PORTD &= ~(1<<PD6);
                    //        ledi=1;
                    //}
                    
                    if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
                            // a ping packet, let's send pong
                            make_echo_reply_from_request(buf,plen);
                            txMsg.Id = 6;
                            Can_Send(&txMsg);
                            
                    }
                    if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
                        payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
                        if (buf[UDP_DATA_P]=='t' && payloadlen==5){
                            uint8_t i=0;
                            
                            while(i<6){
                                remotemac[i]=buf[ETH_SRC_MAC +i];
                                i++;
                            }
                            i=0;
                            while(i<4){
                                remoteip[i]=buf[IP_SRC_P +i];
                                i++;
                            }
                            i=0;
                            while(i<BUFFER_SIZE+1){
                                replybuf[i]=buf[i];
                                i++;
                            }
                            
                            gotserver = 1;
                            make_udp_reply_from_request(buf,"Got server",10,remoteport);
                        }
                    }                       
                }
            }
        }
        

                
        
    }
    
    return 0;
}