Subversion Repositories HomeAutomation

Rev

Rev 1686 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

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