Subversion Repositories HomeAutomation

Rev

Rev 1304 | 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. #include <canid.h>
  21. #include <config.h>
  22. /* lib files */
  23. #if USE_STDCAN == 1
  24. #include <stdcan.h>
  25. #else
  26. #include <mcp2515.h>
  27. #endif
  28. //#include <serial.h>
  29. #include <timebase.h>
  30. #include <mcu.h>
  31. #include <ip_arp_udp_tcp.h>
  32. #include <enc28j60.h>
  33. #include <timeout.h>
  34. #include <avr_compat.h>
  35. #include <net.h>
  36.  
  37. static uint8_t mymac[6] = {ENC28J60_MAC1,ENC28J60_MAC2,ENC28J60_MAC3,ENC28J60_MAC4,ENC28J60_MAC5,ENC28J60_MAC6};
  38. //static uint8_t myip[4] = {192,168,0,50};
  39. static uint8_t myip[4] = {ENC28J60_IP1,ENC28J60_IP2,ENC28J60_IP3,ENC28J60_IP4};
  40. static uint16_t rmDumperPrt =1200; // remote port for dumping data
  41. static uint16_t rmCan2SerPrt =1100; // remote port for Can2Serial-data
  42. //static uint16_t locDumperPrt =1200; // listen port
  43. static uint16_t locCan2SerPrt =1100; // listen port for Can2Serial-data
  44. static uint8_t gotdumpserver = 0;
  45. static uint8_t gotcan2serserver = 0;
  46.  
  47.  
  48. static uint8_t remotemac[6];
  49. static uint8_t remoteip[4];
  50.  
  51. static uint8_t prgremotemac[6];
  52. static uint8_t prgremoteip[4];
  53.  
  54. #define BUFFER_SIZE 250
  55. static uint8_t buf[BUFFER_SIZE+1];
  56.  
  57. #define SEND_BUFFER_SIZE 20
  58. static char sendbuf[SEND_BUFFER_SIZE+1];
  59. static uint8_t buffpoint;
  60.  
  61. #define C2S_START_BYTE 253
  62. #define C2S_END_BYTE 250
  63. #define C2S_PING_BYTE 251
  64.  
  65. #if USE_STDCAN == 0
  66. volatile Can_Message_t rxMsg; // Message storage
  67. volatile uint8_t rxMsgFull;   // Synchronization flag
  68. #endif
  69.  
  70. /*----------------------------------------------------------------------------
  71.  * Putchar for udp
  72.  * Implements a small buffer, sends packet over udp if buffer is full or
  73.  * \n-char is sent.
  74.  * Needs a timeout to force send.
  75.  *--------------------------------------------------------------------------*/
  76. /*int udp_putchar(char c, FILE* stream) {
  77.     if (gotdumpserver != 0) {
  78.         sendbuf[buffpoint] = c;
  79.         buffpoint++;
  80.        
  81.         if (c == '\n' || buffpoint > SEND_BUFFER_SIZE) {
  82.             send_udp(buf, sendbuf, buffpoint, rmDumperPrt, remotemac, remoteip);
  83.             buffpoint = 0;
  84.         }
  85.     }
  86.     return 0;
  87. }
  88.  
  89. static FILE mystdout = FDEV_SETUP_STREAM(udp_putchar, NULL, _FDEV_SETUP_WRITE);
  90. */
  91.  
  92. #if USE_STDCAN == 0
  93. void Can_Process(Can_Message_t* msg) {
  94.     if (!(msg->ExtendedFlag)) return; // We don't care about standard CAN frames.
  95.  
  96.     if (!rxMsgFull) {
  97.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  98.         rxMsgFull = 1;
  99.     }
  100. }
  101. #endif
  102.  
  103. /*-----------------------------------------------------------------------------
  104.  * Main Program
  105.  *---------------------------------------------------------------------------*/
  106. int main(void) {
  107.  
  108. #if MCP_CS_BIT != PB2
  109.     /* If slave select is not set as output it might change SPI hw to slave
  110.      * See ch 18.3.2 (18.3 SS Pin Functionality) in ATmega48/88/168-datasheet */
  111.     DDRB |= (1<<PB2);
  112. #endif
  113.  
  114.  
  115.     //ethernet vars
  116.     uint16_t plen = 0;
  117.     uint8_t payloadlen=0;
  118.     buffpoint = 0;
  119.    
  120.     //can vars
  121.    
  122.     uint32_t timeStamp = 0;
  123.  
  124.     //uint8_t sw=0;
  125.     // LED
  126.     /* enable PB1, LED as output */
  127.     //DDRB|= (1<<DDB0);
  128.    
  129.     /* set output to Vcc, LED off */
  130.     //PORTB|= (1<<PB0);
  131.    
  132.     Mcu_Init();
  133.     Timebase_Init();
  134.  
  135.     //alla printf ska skriva till udp
  136.     //stdout = &mystdout;    //set the output stream
  137.  
  138. #if USE_STDCAN == 0
  139.     Can_Init();
  140.     Can_Message_t txMsg;
  141.     txMsg.RemoteFlag = 0;
  142.     txMsg.ExtendedFlag = 1;
  143.     rxMsgFull = 0;
  144. #else
  145.     StdCan_Init(0);
  146.     StdCan_Msg_t txMsg;
  147.     StdCan_Msg_t rxMsg;
  148. #endif
  149.  
  150.     sei();
  151.  
  152.     /*initialize enc28j60*/
  153.     if (enc28j60Init(mymac) != 1) {
  154.         /* Great place to set an IO for debug */
  155.     }
  156.     delay_ms(20);
  157.    
  158.     /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
  159.     // LEDB=yellow LEDA=green
  160.     //
  161.     // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
  162.     enc28j60PhyWrite(PHLCON,0x476);
  163.     delay_ms(20);
  164.    
  165.     //init the ethernet/ip layer:
  166.     init_ip_arp_udp_tcp(mymac,myip,80);
  167.  
  168.     /* main loop */
  169.     while (1) {
  170.         /* service the CAN routines */
  171.         //Can_Service();
  172.        
  173. #if SENDTIMESTAMP == 1
  174.         /* send CAN message and check for CAN errors once every second */
  175.         if (Timebase_PassedTimeMillis(timeStamp) >= 1000) {
  176.             timeStamp = Timebase_CurrentTime();
  177.  
  178.             /* send timestamp, to keep network alive */
  179.             txMsg.Id = (CAN_NMT << CAN_SHIFT_CLASS) | (CAN_NMT_TIME << CAN_SHIFT_NMT_TYPE);
  180. #if USE_STDCAN == 0
  181.             txMsg.DataLength = 0;
  182.             Can_Send(&txMsg);
  183. #else
  184.             txMsg.Length = 0;
  185.             StdCan_Put(&txMsg);
  186. #endif
  187.            
  188.         }
  189. #endif
  190.        
  191.         /* check if any messages have been received */
  192. #if USE_STDCAN == 0
  193.         if (rxMsgFull) {
  194. #else
  195.         if (StdCan_Get(&rxMsg) == StdCan_Ret_OK) {
  196. #endif
  197.             uint8_t i;
  198.            
  199.             /*if (gotdumpserver != 0) {
  200.                 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));
  201.                 printf("data={ ");
  202.                 for (i=0; i<rxMsg.DataLength; i++) {
  203.                     printf("%x ", rxMsg.Data.bytes[i]);
  204.                 }
  205.                 printf("}\n");
  206.             }*/
  207.            
  208.             if (gotcan2serserver != 0) {
  209.                 //skicka ocks� som udppaket till rmCan2SerPrt
  210.                 char sendbuf2[17];
  211.                
  212.                 sendbuf2[0] = C2S_START_BYTE;
  213.                 sendbuf2[1] = (uint8_t)rxMsg.Id;
  214.                 sendbuf2[2] = (uint8_t)(rxMsg.Id>>8);
  215.                 sendbuf2[3] = (uint8_t)(rxMsg.Id>>16);
  216.                 sendbuf2[4] = (uint8_t)(rxMsg.Id>>24);
  217. #if USE_STDCAN == 0
  218.                 sendbuf2[5] = rxMsg.ExtendedFlag;
  219.                 sendbuf2[6] = rxMsg.RemoteFlag;
  220.                 sendbuf2[7] = rxMsg.DataLength;
  221.                 for (i=0; i<8; i++) {
  222.                     sendbuf2[8+i] = rxMsg.Data.bytes[i];
  223.                 }
  224. #else
  225.                 sendbuf2[5] = 1;
  226.                 sendbuf2[6] = 0;
  227.                 sendbuf2[7] = rxMsg.Length;
  228.                 for (i=0; i<8; i++) {
  229.                     sendbuf2[8+i] = rxMsg.Data[i];
  230.                 }
  231. #endif
  232.                 sendbuf2[16] = C2S_END_BYTE;
  233.                
  234. #ifndef ENC28J60_USART_SPI_MODE
  235.                 //MCP_INT_DISABLE();
  236.                 cli();
  237. #endif
  238.                 send_udp(buf, sendbuf2, 18, rmCan2SerPrt, prgremotemac, prgremoteip);
  239. #ifndef ENC28J60_USART_SPI_MODE
  240.                 sei();
  241.                 //MCP_INT_ENABLE();
  242. #endif
  243.             }
  244.            
  245. #if USE_STDCAN == 0
  246.             rxMsgFull = 0;
  247. #endif
  248.         }
  249.        
  250.         //test-debug-kod
  251.         if ((enc28j60Read(EIR) & EIR_TXERIF)) {
  252.             //printf("EIR_TXERIF set!\n");
  253.             if ((enc28j60Read(ECON1) & ECON1_TXRTS)) {
  254.                 //printf("ECON1_TXRTS set!\n");
  255.             }
  256.         }
  257.         if ((enc28j60Read(EIR) & EIR_TXIF)) {
  258.             //printf("EIR_TXIF set! ");
  259.         }
  260.         if ((enc28j60Read(ESTAT) & ESTAT_TXABRT)) {
  261.             //printf("ESTAT_TXABRT set!\n");
  262.             //printf("MACLCON1: %i\n", enc28j60Read(MACLCON1));
  263.             enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ESTAT, ESTAT_TXABRT);
  264.         }
  265.        
  266.         // get the next new packet:
  267.         plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
  268.  
  269.         /*plen will ne unequal to zero if there is a valid
  270.          * packet (without crc error) */
  271.         if(plen!=0){
  272.             // arp is broadcast if unknown but a host may also
  273.             // verify the mac address by sending it to
  274.             // a unicast address.
  275.             if(eth_type_is_arp_and_my_ip(buf,plen)){
  276.                     make_arp_answer_from_request(buf);
  277.             } else {
  278.                 // check if ip packets (icmp or udp) are for us:
  279.                 if(eth_type_is_ip_and_my_ip(buf,plen)!=0){
  280.                    
  281.                     if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
  282.                             // a ping packet, let's send pong
  283.                             make_echo_reply_from_request(buf,plen);
  284.                             //txMsg.Id = 6;
  285.                             //Can_Send(&txMsg);
  286.                            
  287.                     }
  288.                     if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
  289.                         payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
  290.                         uint8_t i = 0;
  291.                        
  292.                         //om port 1100 (programmeringsporten)
  293.                         if ((buf[UDP_DST_PORT_H_P]==((locCan2SerPrt>>8) & 0xff)) && (buf[UDP_DST_PORT_L_P] == (locCan2SerPrt & 0xff))) {
  294.                             while(i<6){
  295.                                 prgremotemac[i]=buf[ETH_SRC_MAC +i];
  296.                                 i++;
  297.                             }
  298.                             i=0;
  299.                             while(i<4){
  300.                                 prgremoteip[i]=buf[IP_SRC_P +i];
  301.                                 i++;
  302.                             }
  303.                             gotcan2serserver = 1;
  304.  
  305.                             if ((buf[UDP_DATA_P]==C2S_START_BYTE) && (buf[UDP_DATA_P+16]==C2S_END_BYTE) && (payloadlen==17))
  306.                             {
  307. #if USE_STDCAN == 0
  308.                                 Can_Message_t cm;
  309.                                 //cm.Id = 0;
  310.                                 cm.DataLength = buf[UDP_DATA_P+7];
  311.                                 cm.RemoteFlag = buf[UDP_DATA_P+6];
  312.                                 cm.ExtendedFlag = buf[UDP_DATA_P+5];
  313.                                 cm.Id = (uint32_t)buf[UDP_DATA_P+1] + ((uint32_t)buf[UDP_DATA_P+2] << 8) +
  314.                                         ((uint32_t)buf[UDP_DATA_P+3] << 16) + ((uint32_t)buf[UDP_DATA_P+4] << 24);
  315.                                 uint8_t i;
  316.                                 for (i = 0; i < cm.DataLength; i++) {
  317.                                     cm.Data.bytes[i] = buf[UDP_DATA_P+8+i];
  318.                                 }
  319.                                 Can_Send(&cm);
  320. #else
  321.                                 static StdCan_Msg_t cm;
  322.                                 //cm.Id = 0;
  323.                                 cm.Length = buf[UDP_DATA_P+7];
  324.                                 cm.Id = (uint32_t)buf[UDP_DATA_P+1] + ((uint32_t)buf[UDP_DATA_P+2] << 8) +
  325.                                         ((uint32_t)buf[UDP_DATA_P+3] << 16) + ((uint32_t)buf[UDP_DATA_P+4] << 24);
  326.                                 uint8_t i;
  327.                                 for (i = 0; i < cm.Length; i++) {
  328.                                     cm.Data[i] = buf[UDP_DATA_P+8+i];
  329.                                 }
  330.                                 StdCan_Put(&cm);
  331. #endif
  332.                                 /*if (gotdumpserver != 0) {
  333.                                     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));
  334.                                     printf("data={ ");
  335.                                     for (i=0; i<cm.DataLength; i++) {
  336.                                         printf("%x ", cm.Data.bytes[i]);
  337.                                     }
  338.                                     printf("}\n");
  339.                                 }*/
  340.                             }
  341.                             else if ((buf[UDP_DATA_P]==C2S_PING_BYTE) && (payloadlen==1))
  342.                             {
  343.                                 char sendbuf3[1];
  344.                                 sendbuf3[0] = C2S_PING_BYTE;
  345.                
  346. #ifndef ENC28J60_USART_SPI_MODE
  347.                                 cli();
  348. #endif
  349.                                 send_udp(buf, sendbuf3, 1, rmCan2SerPrt, prgremotemac, prgremoteip);
  350. #ifndef ENC28J60_USART_SPI_MODE
  351.                                 sei();
  352. #endif
  353.                             }
  354.                         //om port 1200 (dumparporten)
  355.                         } /*else if ((buf[UDP_DST_PORT_H_P]==((locDumperPrt>>8) & 0xff)) && (buf[UDP_DST_PORT_L_P] == (locDumperPrt & 0xff))) {
  356.                             if (gotdumpserver == 0) {
  357.                                 while(i<6){
  358.                                     remotemac[i]=buf[ETH_SRC_MAC +i];
  359.                                     i++;
  360.                                 }
  361.                                 i=0;
  362.                                 while(i<4){
  363.                                     remoteip[i]=buf[IP_SRC_P +i];
  364.                                     i++;
  365.                                 }
  366.                                 i=0;
  367.                                
  368.                                 gotdumpserver = 1;
  369.                                 make_udp_reply_from_request(buf,"Got server",10,rmDumperPrt);
  370.                             } else {
  371.                                 make_udp_reply_from_request(buf,"Already got server",18,rmDumperPrt);
  372.                             }
  373.                         }*/
  374.                     }                      
  375.                 }
  376.             }
  377.         }
  378.        
  379.  
  380.                
  381.        
  382.     }
  383.    
  384.     return 0;
  385. }
  386.