Subversion Repositories HomeAutomation

Rev

Rev 541 | Rev 670 | Go to most recent revision | Blame | Compare with Previous | 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. #include <string.h>
  19.  
  20. /* lib files */
  21. #include <mcp2515.h>
  22. //#include <serial.h>
  23. #include <timebase.h>
  24. #include <mcu.h>
  25. #include <ip_arp_udp_tcp.h>
  26. #include <enc28j60.h>
  27. #include <timeout.h>
  28. #include <avr_compat.h>
  29. #include <net.h>
  30.  
  31. // please modify the following two lines. mac and ip have to be unique
  32. // in your local area network. You can not have the same numbers in
  33. // two devices:
  34. static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x27};
  35. //static uint8_t myip[4] = {192,168,0,50};
  36. static uint8_t myip[4] = {193,11,254,26};
  37. static uint16_t rmDumperPrt =1200; // remote port for dumping data
  38. static uint16_t rmCan2SerPrt =1100; // remote port for Can2Serial-data
  39. //static uint16_t locDumperPrt =1200; // listen port
  40. static uint16_t locCan2SerPrt =1100; // listen port for Can2Serial-data
  41. static uint8_t gotdumpserver = 0;
  42. static uint8_t gotcan2serserver = 0;
  43.  
  44. // how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
  45.  
  46. static uint8_t remotemac[6];
  47. static uint8_t remoteip[4];
  48.  
  49. static uint8_t prgremotemac[6];
  50. static uint8_t prgremoteip[4];
  51.  
  52. #define BUFFER_SIZE 250
  53. static uint8_t buf[BUFFER_SIZE+1];
  54.  
  55. #define SEND_BUFFER_SIZE 20
  56. static char sendbuf[SEND_BUFFER_SIZE+1];
  57. static uint8_t buffpoint;
  58.  
  59. #define C2S_START_BYTE 253
  60. #define C2S_END_BYTE 250
  61.  
  62. /* set to 0 for not sending timestamps on bus */
  63. #define SENDTIMESTAMP   0
  64.  
  65. volatile Can_Message_t rxMsg; // Message storage
  66. volatile uint8_t rxMsgFull;   // Synchronization flag
  67.  
  68. /*----------------------------------------------------------------------------
  69.  * Putchar for udp
  70.  * Implements a small buffer, sends packet over udp if buffer is full or
  71.  * \n-char is sent.
  72.  * Needs a timeout to force send.
  73.  *--------------------------------------------------------------------------*/
  74. /*int udp_putchar(char c, FILE* stream) {
  75.     if (gotdumpserver != 0) {
  76.         sendbuf[buffpoint] = c;
  77.         buffpoint++;
  78.        
  79.         if (c == '\n' || buffpoint > SEND_BUFFER_SIZE) {
  80.             send_udp(buf, sendbuf, buffpoint, rmDumperPrt, remotemac, remoteip);
  81.             buffpoint = 0;
  82.         }
  83.     }
  84.     return 0;
  85. }
  86.  
  87. static FILE mystdout = FDEV_SETUP_STREAM(udp_putchar, NULL, _FDEV_SETUP_WRITE);
  88. */
  89.  
  90. void Can_Process(Can_Message_t* msg) {
  91.     if (!(msg->ExtendedFlag)) return; // We don't care about standard CAN frames.
  92.  
  93.     if (!rxMsgFull) {
  94.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  95.         rxMsgFull = 1;
  96.     }
  97. }
  98.  
  99. ISR(MCP_INT_VECTOR) {
  100.     // Get first available message from controller and pass it to
  101.     // application handler. If both RX buffers contain messages
  102.     // we will get another interrupt as soon as this one returns.
  103.     if (Can_Receive(&rxMsg) == CAN_OK) {
  104.         // Callbacks are run with global interrupts disabled but
  105.         // with controller flag cleared so another msg can be
  106.         // received while this one is processed.
  107.         Can_Process(&rxMsg);
  108.     }
  109. }
  110.  
  111.  
  112. /*-----------------------------------------------------------------------------
  113.  * Main Program
  114.  *---------------------------------------------------------------------------*/
  115. int main(void) {
  116.  
  117.     //ethernet vars
  118.     uint16_t plen = 0;
  119.     uint8_t payloadlen=0;
  120.     buffpoint = 0;
  121.    
  122.     //can vars
  123.     Can_Message_t txMsg;
  124.     txMsg.Id = 3;
  125.     txMsg.DataLength = 0;
  126.     txMsg.RemoteFlag = 0;
  127.     txMsg.ExtendedFlag = 1;
  128.  
  129.     rxMsgFull = 0;
  130.    
  131.     uint32_t timeStamp = 0;
  132.  
  133.     //uint8_t sw=0;
  134.     // LED
  135.     /* enable PB1, LED as output */
  136.     //DDRB|= (1<<DDB0);
  137.    
  138.     /* set output to Vcc, LED off */
  139.     //PORTB|= (1<<PB0);
  140.    
  141.     Mcu_Init();
  142.     Timebase_Init();
  143.  
  144.     //alla printf ska skriva till udp
  145.     //stdout = &mystdout;    //set the output stream
  146.  
  147.     if (Can_Init() != CAN_OK) {
  148.     }
  149.  
  150.     sei();
  151.  
  152.     /*initialize enc28j60*/
  153.     enc28j60Init(mymac);
  154.     delay_ms(20);
  155.    
  156.     /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
  157.     // LEDB=yellow LEDA=green
  158.     //
  159.     // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
  160.     enc28j60PhyWrite(PHLCON,0x476);
  161.     delay_ms(20);
  162.    
  163.     //init the ethernet/ip layer:
  164.     init_ip_arp_udp_tcp(mymac,myip,80);
  165.  
  166.     /* main loop */
  167.     while (1) {
  168.         /* service the CAN routines */
  169.         //Can_Service();
  170.        
  171. #if SENDTIMESTAMP == 1
  172.         /* send CAN message and check for CAN errors once every second */
  173.         if (Timebase_PassedTimeMillis(timeStamp) >= 1000) {
  174.             timeStamp = Timebase_CurrentTime();
  175.             /* send timestamp, to keep network alive */
  176.             txMsg.Id = 0;
  177.             txMsg.DataLength = 0;
  178.             Can_Send(&txMsg);
  179.            
  180.         }
  181. #endif
  182.        
  183.         /* check if any messages have been received */
  184.         if (rxMsgFull) { //(Can_Receive(&rxMsg) == CAN_OK) {
  185.             uint8_t i;
  186.            
  187.             /*if (gotdumpserver != 0) {
  188.                 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));
  189.                 printf("data={ ");
  190.                 for (i=0; i<rxMsg.DataLength; i++) {
  191.                     printf("%x ", rxMsg.Data.bytes[i]);
  192.                 }
  193.                 printf("}\n");
  194.             }*/
  195.            
  196.             if (gotcan2serserver != 0) {
  197.                 //skicka ocks� som udppaket till rmCan2SerPrt
  198.                 char sendbuf2[17];
  199.                
  200.                 sendbuf2[0] = C2S_START_BYTE;
  201.                 sendbuf2[1] = (uint8_t)rxMsg.Id;
  202.                 sendbuf2[2] = (uint8_t)(rxMsg.Id>>8);
  203.                 sendbuf2[3] = (uint8_t)(rxMsg.Id>>16);
  204.                 sendbuf2[4] = (uint8_t)(rxMsg.Id>>24);
  205.                 sendbuf2[5] = rxMsg.ExtendedFlag;
  206.                 sendbuf2[6] = rxMsg.RemoteFlag;
  207.                 sendbuf2[7] = rxMsg.DataLength;
  208.                 for (i=0; i<8; i++) {
  209.                     sendbuf2[8+i] = rxMsg.Data.bytes[i];
  210.                 }
  211.                 sendbuf2[16] = C2S_END_BYTE;
  212.                
  213.                 MCP_INT_DISABLE();
  214.                 send_udp(buf, sendbuf2, 18, rmCan2SerPrt, prgremotemac, prgremoteip);
  215.                 MCP_INT_ENABLE();
  216.             }
  217.            
  218.             rxMsgFull = 0;
  219.         }
  220.        
  221.         //test-debug-kod
  222.         if ((enc28j60Read(EIR) & EIR_TXERIF)) {
  223.             //printf("EIR_TXERIF set!\n");
  224.             if ((enc28j60Read(ECON1) & ECON1_TXRTS)) {
  225.                 //printf("ECON1_TXRTS set!\n");
  226.             }
  227.         }
  228.         if ((enc28j60Read(EIR) & EIR_TXIF)) {
  229.             //printf("EIR_TXIF set! ");
  230.         }
  231.         if ((enc28j60Read(ESTAT) & ESTAT_TXABRT)) {
  232.             //printf("ESTAT_TXABRT set!\n");
  233.             //printf("MACLCON1: %i\n", enc28j60Read(MACLCON1));
  234.             enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ESTAT, ESTAT_TXABRT);
  235.         }
  236.        
  237.         // get the next new packet:
  238.         plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
  239.  
  240.         /*plen will ne unequal to zero if there is a valid
  241.          * packet (without crc error) */
  242.         if(plen!=0){
  243.             // arp is broadcast if unknown but a host may also
  244.             // verify the mac address by sending it to
  245.             // a unicast address.
  246.             if(eth_type_is_arp_and_my_ip(buf,plen)){
  247.                     make_arp_answer_from_request(buf);
  248.             } else {
  249.                 // check if ip packets (icmp or udp) are for us:
  250.                 if(eth_type_is_ip_and_my_ip(buf,plen)!=0){
  251.                    
  252.                     if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
  253.                             // a ping packet, let's send pong
  254.                             make_echo_reply_from_request(buf,plen);
  255.                             //txMsg.Id = 6;
  256.                             //Can_Send(&txMsg);
  257.                            
  258.                     }
  259.                     if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
  260.                         payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
  261.                         uint8_t i = 0;
  262.                        
  263.                         //om port 1100 (programmeringsporten)
  264.                         if ((buf[UDP_DST_PORT_H_P]==((locCan2SerPrt>>8) & 0xff)) && (buf[UDP_DST_PORT_L_P] == (locCan2SerPrt & 0xff))) {
  265.                             while(i<6){
  266.                                 prgremotemac[i]=buf[ETH_SRC_MAC +i];
  267.                                 i++;
  268.                             }
  269.                             i=0;
  270.                             while(i<4){
  271.                                 prgremoteip[i]=buf[IP_SRC_P +i];
  272.                                 i++;
  273.                             }
  274.                             gotcan2serserver = 1;
  275.  
  276.                             if ((buf[UDP_DATA_P]==C2S_START_BYTE) && (buf[UDP_DATA_P+16]==C2S_END_BYTE) && (payloadlen==17)) {
  277.                                 Can_Message_t cm;
  278.                                 //cm.Id = 0;
  279.                                 cm.DataLength = buf[UDP_DATA_P+7];
  280.                                 cm.RemoteFlag = buf[UDP_DATA_P+6];
  281.                                 cm.ExtendedFlag = buf[UDP_DATA_P+5];
  282.                                 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);
  283.                                 uint8_t i;
  284.                                 for (i = 0; i < cm.DataLength; i++) {
  285.                                     cm.Data.bytes[i] = buf[UDP_DATA_P+8+i];
  286.                                 }
  287.                                 Can_Send(&cm);
  288.                                
  289.                                 /*if (gotdumpserver != 0) {
  290.                                     printf("MSG Received: ID=%lx, DLC=%u, EXT=%u, RTR=%u, ", cm.Id, (uint16_t)(cm.DataLength), (uint16_t)(cm.ExtendedFlag), (uint16_t)(cm.RemoteFlag));
  291.                                     printf("data={ ");
  292.                                     for (i=0; i<cm.DataLength; i++) {
  293.                                         printf("%x ", cm.Data.bytes[i]);
  294.                                     }
  295.                                     printf("}\n");
  296.                                 }*/
  297.                             }
  298.                         //om port 1200 (dumparporten)
  299.                         } /*else if ((buf[UDP_DST_PORT_H_P]==((locDumperPrt>>8) & 0xff)) && (buf[UDP_DST_PORT_L_P] == (locDumperPrt & 0xff))) {
  300.                             if (gotdumpserver == 0) {
  301.                                 while(i<6){
  302.                                     remotemac[i]=buf[ETH_SRC_MAC +i];
  303.                                     i++;
  304.                                 }
  305.                                 i=0;
  306.                                 while(i<4){
  307.                                     remoteip[i]=buf[IP_SRC_P +i];
  308.                                     i++;
  309.                                 }
  310.                                 i=0;
  311.                                
  312.                                 gotdumpserver = 1;
  313.                                 make_udp_reply_from_request(buf,"Got server",10,rmDumperPrt);
  314.                             } else {
  315.                                 make_udp_reply_from_request(buf,"Already got server",18,rmDumperPrt);
  316.                             }
  317.                         }*/
  318.                     }                      
  319.                 }
  320.             }
  321.         }
  322.        
  323.  
  324.                
  325.        
  326.     }
  327.    
  328.     return 0;
  329. }
  330.