Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. /**
  2.  * CAN Test. This program sends a CAN message once every second. The ID of the
  3.  * message is increased each time for testing purposes.
  4.  *
  5.  * @date    2006-11-21
  6.  * @author  Jimmy Myhrman
  7.  *  
  8.  */
  9.  
  10. /*-----------------------------------------------------------------------------
  11.  * Includes
  12.  *---------------------------------------------------------------------------*/
  13. /* system files */
  14. #include <avr/io.h>
  15. #include <avr/interrupt.h>
  16. #include <avr/wdt.h>
  17. #include <stdio.h>
  18. /* lib files */
  19. #include <can.h>
  20. //#include <serial.h>
  21. #include <timebase.h>
  22. #include <ip_arp_udp_tcp.h>
  23. #include <enc28j60.h>
  24. #include <timeout.h>
  25. #include <avr_compat.h>
  26. #include <net.h>
  27.  
  28. // please modify the following two lines. mac and ip have to be unique
  29. // in your local area network. You can not have the same numbers in
  30. // two devices:
  31. static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
  32. static uint8_t myip[4] = {193,11,254,22};
  33. static uint16_t remoteport =1200; // listen port for udp
  34. static uint8_t gotserver = 0;
  35.  
  36. // how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
  37.  
  38. static uint8_t remotemac[6];
  39. static uint8_t remoteip[4];
  40.  
  41. #define BUFFER_SIZE 250
  42. static uint8_t buf[BUFFER_SIZE+1];
  43. static uint8_t replybuf[BUFFER_SIZE+1];
  44.  
  45. int udp_putchar(char c, FILE* stream) {
  46.     if (gotserver != 0) {
  47.         uint8_t i=0;
  48.         while(i<BUFFER_SIZE+1){
  49.             buf[i]=replybuf[i];
  50.             i++;
  51.         }
  52.         //send_udp(replybuf, &c, 1, remoteport, remotemac, remoteip);
  53.         make_udp_reply_from_request(buf, "hello", 5, remoteport);
  54.         //send_udp(buf, &c, 1, remoteport, remotemac, remoteip);
  55.     }
  56.     return 0;
  57. }
  58.  
  59. static FILE mystdout = FDEV_SETUP_STREAM(udp_putchar, NULL, _FDEV_SETUP_WRITE);
  60.  
  61. /*-----------------------------------------------------------------------------
  62.  * Main Program
  63.  *---------------------------------------------------------------------------*/
  64. int main(void) {
  65.  
  66.     //ethernet vars
  67.     uint16_t plen = 0;
  68.     uint8_t ledi=0;
  69.     uint8_t payloadlen=0;
  70.    
  71.     uint32_t timeStamp = 0;
  72.    
  73.     //can vars
  74.     Can_Message_t txMsg;
  75.     Can_Message_t rxMsg;
  76.     txMsg.Id = 3;
  77.     txMsg.DataLength = 0;
  78.     txMsg.RemoteFlag = 0;
  79.     txMsg.ExtendedFlag = 1; //DataLength and the databytes are just what happens to be in the memory. They are never set.
  80.    
  81.     Timebase_Init();
  82. //  Serial_Init();
  83.     #if defined(__AVR_ATmega88__)
  84.     // set the clock speed to 8MHz
  85.     // set the clock prescaler. First write CLKPCE to enable setting of clock the
  86.     // next four instructions.
  87.     CLKPR=(1<<CLKPCE);
  88.     CLKPR=0; // 8 MHZ
  89.     #endif
  90.    
  91.     //stdout = &mystdout;    //set the output stream
  92.    
  93.     sei();
  94.  
  95. //  printf("CanInit...");
  96.     if (Can_Init() != CAN_OK) {
  97. //      printf("FAILED!\n");
  98.     }
  99.     else {
  100. //      printf("OK!\n");
  101.     }
  102.  
  103.     /* enable PB0, reset as output */
  104.     DDRB|= (1<<DDB0);
  105.     /* set output to gnd, reset the ethernet chip */
  106.     PORTB &= ~(1<<PB0);
  107.     delay_ms(20);
  108.     /* set output to Vcc, reset inactive */
  109.     PORTB|= (1<<PB0);
  110.     delay_ms(100);
  111.    
  112.     // LED
  113.     /* enable PB1, LED as output */
  114.     DDRD|= (1<<DDD6);
  115.     /* set output to Vcc, LED off */
  116.     PORTD|= (1<<PD6);
  117.  
  118.     /*initialize enc28j60*/
  119.     enc28j60Init(mymac);
  120.     delay_ms(20);
  121.    
  122.     /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
  123.     // LEDB=yellow LEDA=green
  124.     //
  125.     // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
  126.     // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
  127.     enc28j60PhyWrite(PHLCON,0x476);
  128.     delay_ms(20);
  129.    
  130.     /* set output to GND, red LED on */
  131.     PORTD &= ~(1<<PD6);
  132.     ledi=1;
  133.    
  134.     //init the ethernet/ip layer:
  135.     init_ip_arp_udp_tcp(mymac,myip,80);
  136.  
  137.     /* main loop */
  138.     while (1) {
  139.         /* service the CAN routines */
  140.         Can_Service();
  141.        
  142. //PORTD &= ~(1<<PD6);
  143.        
  144.         /* send CAN message and check for CAN errors once every second */
  145.         if (Timebase_PassedTimeMillis(timeStamp) >= 2000) {
  146.             timeStamp = Timebase_CurrentTime();
  147.             /* send txMsg */
  148.             //txMsg.Id++;
  149.             txMsg.Id = 3;
  150.             Can_Send(&txMsg);
  151.             if (ledi){
  152.                     /* set output to Vcc, LED off */
  153.                     PORTD|= (1<<PD6);
  154.                     ledi=0;
  155.             }else{
  156.                     /* set output to GND, LED on */
  157.                     PORTD &= ~(1<<PD6);
  158.                     ledi=1;
  159.             }
  160.            
  161.         }
  162.        
  163.         /* check if any messages have been received */
  164.         while (Can_Receive(&rxMsg) == CAN_OK) {
  165.             //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));
  166.             /*printf("data={ ");
  167.             for (uint8_t i=0; i<rxMsg.DataLength; i++) {
  168.                 printf("%x ", rxMsg.Data.bytes[i]);
  169.             }
  170.             printf("}\n");
  171.             */
  172.             if (gotserver != 0) {
  173.                 uint8_t i = 0;
  174.                 while(i<BUFFER_SIZE+1){
  175.                     buf[i]=replybuf[i];
  176.                     i++;
  177.                 }
  178.                 send_udp(buf, "hello", 6, remoteport, remotemac, remoteip);
  179.                 //make_udp_reply_from_request(buf, "hello", 5, remoteport);
  180.                 i = 0;
  181.                 while(i<BUFFER_SIZE+1){
  182.                     buf[i]=replybuf[i];
  183.                     i++;
  184.                 }
  185.                 //make_udp_reply_from_request(buf, "world", 5, remoteport);
  186.                 send_udp(buf, "world", 6, remoteport, remotemac, remoteip);
  187.             }
  188.             //printf("Hello world! %i \n", txMsg.Id);        
  189.         }
  190.        
  191.         // get the next new packet:
  192.         plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
  193.  
  194.         /*plen will ne unequal to zero if there is a valid
  195.          * packet (without crc error) */
  196.         if(plen!=0){
  197.             // arp is broadcast if unknown but a host may also
  198.             // verify the mac address by sending it to
  199.             // a unicast address.
  200.             if(eth_type_is_arp_and_my_ip(buf,plen)){
  201.                     make_arp_answer_from_request(buf);
  202.             } else {
  203.                 // check if ip packets (icmp or udp) are for us:
  204.                 if(eth_type_is_ip_and_my_ip(buf,plen)!=0){
  205.                     //if (ledi){
  206.                             /* set output to Vcc, LED off */
  207.                     //        PORTD|= (1<<PD6);
  208.                     //        ledi=0;
  209.                     //}else{
  210.                             /* set output to GND, LED on */
  211.                     //        PORTD &= ~(1<<PD6);
  212.                     //        ledi=1;
  213.                     //}
  214.                    
  215.                     if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
  216.                             // a ping packet, let's send pong
  217.                             make_echo_reply_from_request(buf,plen);
  218.                             txMsg.Id = 6;
  219.                             Can_Send(&txMsg);
  220.                            
  221.                     }
  222.                     if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
  223.                         payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
  224.                         if (buf[UDP_DATA_P]=='t' && payloadlen==5){
  225.                             uint8_t i=0;
  226.                            
  227.                             while(i<6){
  228.                                 remotemac[i]=buf[ETH_SRC_MAC +i];
  229.                                 i++;
  230.                             }
  231.                             i=0;
  232.                             while(i<4){
  233.                                 remoteip[i]=buf[IP_SRC_P +i];
  234.                                 i++;
  235.                             }
  236.                             i=0;
  237.                             while(i<BUFFER_SIZE+1){
  238.                                 replybuf[i]=buf[i];
  239.                                 i++;
  240.                             }
  241.                            
  242.                             gotserver = 1;
  243.                             make_udp_reply_from_request(buf,"Got server",10,remoteport);
  244.                         }
  245.                     }                      
  246.                 }
  247.             }
  248.         }
  249.        
  250.  
  251.                
  252.        
  253.     }
  254.    
  255.     return 0;
  256. }
  257.