Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  *
  3.  *
  4.  *
  5.  * @date    2006-11-21
  6.  * @author  Jimmy Myhrman, Anders Runeson
  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 rmDumperPrt =1200; // remote port for dumping data
  34. static uint16_t rmCan2SerPrt =1100; // remote port for Can2Serial-data
  35. static uint16_t locDumperPrt =1200; // listen port
  36. static uint16_t locCan2SerPrt =1100; // listen port for Can2Serial-data
  37. static uint8_t gotserver = 0;
  38.  
  39. // how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
  40.  
  41. static uint8_t remotemac[6];
  42. static uint8_t remoteip[4];
  43.  
  44. #define BUFFER_SIZE 250
  45. static uint8_t buf[BUFFER_SIZE+1];
  46.  
  47. #define SEND_BUFFER_SIZE 20
  48. static char sendbuf[SEND_BUFFER_SIZE+1];
  49. static uint8_t buffpoint;
  50.  
  51. #define C2S_START_BYTE 253
  52. #define C2S_END_BYTE 250
  53.  
  54. /*----------------------------------------------------------------------------
  55.  * Putchar for udp
  56.  * Implements a small buffer, sends packet over udp if buffer is full or
  57.  * \n-char is sent.
  58.  * Needs a timeout to force send.
  59.  *--------------------------------------------------------------------------*/
  60. int udp_putchar(char c, FILE* stream) {
  61.     if (gotserver != 0) {
  62.         sendbuf[buffpoint] = c;
  63.         buffpoint++;
  64.        
  65.         if (c == '\n' || buffpoint > SEND_BUFFER_SIZE) {
  66.             send_udp(buf, sendbuf, buffpoint, rmDumperPrt, remotemac, remoteip);
  67.             buffpoint = 0;
  68.         }
  69.     }
  70.     return 0;
  71. }
  72.  
  73. static FILE mystdout = FDEV_SETUP_STREAM(udp_putchar, NULL, _FDEV_SETUP_WRITE);
  74.  
  75. /*-----------------------------------------------------------------------------
  76.  * Main Program
  77.  *---------------------------------------------------------------------------*/
  78. int main(void) {
  79.  
  80.     //ethernet vars
  81.     uint16_t plen = 0;
  82.     uint8_t ledi=0;
  83.     uint8_t payloadlen=0;
  84.     buffpoint = 0;
  85.    
  86.     //can vars
  87.     Can_Message_t txMsg;
  88.     Can_Message_t rxMsg;
  89.     txMsg.Id = 3;
  90.     txMsg.DataLength = 0;
  91.     txMsg.RemoteFlag = 0;
  92.     txMsg.ExtendedFlag = 1; //DataLength and the databytes are just what happens to be in the memory. They are never set.
  93.  
  94.  
  95.     uint32_t timeStamp = 0;
  96.    
  97.     Mcu_Init();
  98.     Timebase_Init();
  99.     //Serial_Init();
  100.  
  101.     //alla printf ska skriva till udp
  102.     stdout = &mystdout;    //set the output stream
  103.    
  104.     sei();
  105.  
  106. //  printf("CanInit...");
  107.     if (Can_Init() != CAN_OK) {
  108. //      printf("FAILED!\n");
  109.     }
  110.     else {
  111. //      printf("OK!\n");
  112.     }
  113.  
  114.     /* enable PB0, reset as output */
  115.     DDRB|= (1<<DDB0);
  116.     /* set output to gnd, reset the ethernet chip */
  117.     PORTB &= ~(1<<PB0);
  118.     delay_ms(20);
  119.     /* set output to Vcc, reset inactive */
  120.     PORTB|= (1<<PB0);
  121.     delay_ms(100);
  122.    
  123.     // LED
  124.     /* enable PB1, LED as output */
  125.     DDRD|= (1<<DDD6);
  126.     /* set output to Vcc, LED off */
  127.     PORTD|= (1<<PD6);
  128.  
  129.     //printf("Init enc\n");
  130.     /*initialize enc28j60*/
  131.     enc28j60Init(mymac);
  132.     delay_ms(20);
  133.    
  134.     /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
  135.     // LEDB=yellow LEDA=green
  136.     //
  137.     // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
  138.     enc28j60PhyWrite(PHLCON,0x476);
  139.     delay_ms(20);
  140.    
  141.     /* set output to GND, red LED on */
  142.     PORTD &= ~(1<<PD6);
  143.     ledi=1;
  144.    
  145.     //init the ethernet/ip layer:
  146.     init_ip_arp_udp_tcp(mymac,myip,80);
  147.  
  148.     /* main loop */
  149.     while (1) {
  150.         /* service the CAN routines */
  151.         Can_Service();
  152.        
  153.         /* send CAN message and check for CAN errors once every second */
  154.         if (Timebase_PassedTimeMillis(timeStamp) >= 2000) {
  155.             timeStamp = Timebase_CurrentTime();
  156.             /* send txMsg */
  157.             //txMsg.Id++;
  158.             //txMsg.Id = 3;
  159.             //Can_Send(&txMsg);
  160.            
  161.         }
  162.        
  163.         /* check if any messages have been received */
  164.         while (Can_Receive(&rxMsg) == CAN_OK) {
  165.             uint8_t i;
  166.             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));
  167.             printf("data={ ");
  168.             for (i=0; i<rxMsg.DataLength; i++) {
  169.                 printf("%x ", rxMsg.Data.bytes[i]);
  170.             }
  171.             printf("}\n");
  172.            
  173.             //skicka ocksĂ„ som udppaket till rmCan2SerPrt
  174.             char sendbuf2[17];
  175.             sendbuf2[0] = C2S_START_BYTE;
  176.             sendbuf2[1] = (uint8_t)rxMsg.Id;
  177.             sendbuf2[2] = (uint8_t)(rxMsg.Id>>8);
  178.             sendbuf2[3] = (uint8_t)(rxMsg.Id>>16);
  179.             sendbuf2[4] = (uint8_t)(rxMsg.Id>>24);
  180.             sendbuf2[5] = rxMsg.ExtendedFlag;
  181.             sendbuf2[6] = rxMsg.RemoteFlag;
  182.             sendbuf2[7] = rxMsg.DataLength;
  183.             for (uint8_t i=0; i<8; i++) {
  184.                 sendbuf2[8+i] = rxMsg.Data.bytes[i];
  185.             }
  186.             sendbuf2[16] = C2S_END_BYTE;
  187.             send_udp(buf, sendbuf2, 17, rmCan2SerPrt, remotemac, remoteip);
  188.         }
  189.        
  190.         //test-debug-kod
  191.         if ((enc28j60Read(EIR) & EIR_TXERIF)) {
  192.             //printf("EIR_TXERIF set!\n");
  193.             if ((enc28j60Read(ECON1) & ECON1_TXRTS)) {
  194.                 //printf("ECON1_TXRTS set!\n");
  195.             }
  196.         }
  197.         if ((enc28j60Read(EIR) & EIR_TXIF)) {
  198.             //printf("EIR_TXIF set! ");
  199.         }
  200.         if ((enc28j60Read(ESTAT) & ESTAT_TXABRT)) {
  201.             //printf("ESTAT_TXABRT set!\n");
  202.             //printf("MACLCON1: %i\n", enc28j60Read(MACLCON1));
  203.             enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ESTAT, ESTAT_TXABRT);
  204.         }
  205.        
  206.         // get the next new packet:
  207.         plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
  208.  
  209.         /*plen will ne unequal to zero if there is a valid
  210.          * packet (without crc error) */
  211.         if(plen!=0){
  212.             // arp is broadcast if unknown but a host may also
  213.             // verify the mac address by sending it to
  214.             // a unicast address.
  215.             if(eth_type_is_arp_and_my_ip(buf,plen)){
  216.                     make_arp_answer_from_request(buf);
  217.             } else {
  218.                 // check if ip packets (icmp or udp) are for us:
  219.                 if(eth_type_is_ip_and_my_ip(buf,plen)!=0){
  220.                    
  221.                     if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
  222.                             // a ping packet, let's send pong
  223.                             make_echo_reply_from_request(buf,plen);
  224.                             //txMsg.Id = 6;
  225.                             //Can_Send(&txMsg);
  226.                            
  227.                     }
  228.                     if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
  229.                         payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
  230.                         //printf("hej %x %x\n", buf[UDP_DST_PORT_H_P], buf[UDP_DST_PORT_L_P]);
  231.                         if ((buf[UDP_DST_PORT_H_P]==((locCan2SerPrt>>8) & 0xff)) && (buf[UDP_DST_PORT_L_P] == (locCan2SerPrt & 0xff))) {
  232.                             if (payloadlen==17) {   //ifsats ska in i ovan eller nedan ifsats kanske? nedan
  233.                                 if (buf[UDP_DATA_P]==C2S_START_BYTE && buf[UDP_DATA_P+16]==C2S_END_BYTE) {
  234.                                     Can_Message_t cm;
  235.                                     //cm.Id = 0;
  236.                                     cm.DataLength = buf[UDP_DATA_P+7];
  237.                                     cm.RemoteFlag = buf[UDP_DATA_P+6];
  238.                                     cm.ExtendedFlag = buf[UDP_DATA_P+5];
  239.                                     cm.Id = (uint32_t)buf[UDP_DATA_P+1] + ((uint32_t)buf[UDP_DATA_P+2] << 8) + ((uint32_t)buf[UDP_DATA_P+3] << 16) + ((uint32_t)buf[UDP_DATA_P+4] << 24);
  240.                                     uint8_t i;
  241.                                     for (i = 0; i < cm.DataLength; i++) {
  242.                                         cm.Data.bytes[i] = buf[UDP_DATA_P+8+i];
  243.                                     }
  244.                                     Can_Send(&cm);
  245.                                 }
  246.                                 printf("hoj\n");
  247.                             }
  248.                         } else if (buf[UDP_DATA_P]=='t' && payloadlen==5){
  249.                             uint8_t i=0;
  250.                             if (gotserver == 0) {
  251.                                 while(i<6){
  252.                                     remotemac[i]=buf[ETH_SRC_MAC +i];
  253.                                     i++;
  254.                                 }
  255.                                 i=0;
  256.                                 while(i<4){
  257.                                     remoteip[i]=buf[IP_SRC_P +i];
  258.                                     i++;
  259.                                 }
  260.                                 i=0;
  261.                                
  262.                                 gotserver = 1;
  263.                                 make_udp_reply_from_request(buf,"Got server",10,rmDumperPrt);
  264.                             } else {
  265.                                 make_udp_reply_from_request(buf,"Already got server",18,rmDumperPrt);
  266.                             }
  267.                         }
  268.                     }                      
  269.                 }
  270.             }
  271.         }
  272.        
  273.  
  274.                
  275.        
  276.     }
  277.    
  278.     return 0;
  279. }
  280.