Subversion Repositories HomeAutomation

Rev

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