Subversion Repositories HomeAutomation

Rev

Rev 1115 | Go to most recent revision | 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 rmDumperPrt =1200; // remote port for dumping data
41
static uint16_t rmCan2SerPrt =1100; // remote port for Can2Serial-data
541 arune 42
//static uint16_t locDumperPrt =1200; // listen port 
280 arune 43
static uint16_t locCan2SerPrt =1100; // listen port for Can2Serial-data
379 arune 44
static uint8_t gotdumpserver = 0;
45
static uint8_t gotcan2serserver = 0;
205 arune 46
 
47
 
48
static uint8_t remotemac[6];
49
static uint8_t remoteip[4];
50
 
379 arune 51
static uint8_t prgremotemac[6];
52
static uint8_t prgremoteip[4];
53
 
205 arune 54
#define BUFFER_SIZE 250
55
static uint8_t buf[BUFFER_SIZE+1];
56
 
212 arune 57
#define SEND_BUFFER_SIZE 20
58
static char sendbuf[SEND_BUFFER_SIZE+1];
59
static uint8_t buffpoint;
60
 
281 arune 61
#define C2S_START_BYTE 253
62
#define C2S_END_BYTE 250
1304 arune 63
#define C2S_PING_BYTE 251
281 arune 64
 
1115 arune 65
#if USE_STDCAN == 0
661 arune 66
volatile Can_Message_t rxMsg; // Message storage
67
volatile uint8_t rxMsgFull;   // Synchronization flag
1115 arune 68
#endif
69
 
212 arune 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
 *--------------------------------------------------------------------------*/
661 arune 76
/*int udp_putchar(char c, FILE* stream) {
379 arune 77
    if (gotdumpserver != 0) {
212 arune 78
        sendbuf[buffpoint] = c;
79
        buffpoint++;
80
 
81
        if (c == '\n' || buffpoint > SEND_BUFFER_SIZE) {
280 arune 82
            send_udp(buf, sendbuf, buffpoint, rmDumperPrt, remotemac, remoteip);
212 arune 83
            buffpoint = 0;
205 arune 84
        }
85
    }
86
    return 0;
87
}
88
 
89
static FILE mystdout = FDEV_SETUP_STREAM(udp_putchar, NULL, _FDEV_SETUP_WRITE);
661 arune 90
*/
205 arune 91
 
1115 arune 92
#if USE_STDCAN == 0
661 arune 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
}
1115 arune 101
#endif
661 arune 102
 
205 arune 103
/*-----------------------------------------------------------------------------
104
 * Main Program
105
 *---------------------------------------------------------------------------*/
106
int main(void) {
1003 linlun 107
 
932 arune 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
205 arune 113
 
1003 linlun 114
 
205 arune 115
    //ethernet vars
116
    uint16_t plen = 0;
117
    uint8_t payloadlen=0;
212 arune 118
    buffpoint = 0;
205 arune 119
 
120
    //can vars
661 arune 121
 
212 arune 122
    uint32_t timeStamp = 0;
661 arune 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);
205 arune 131
 
212 arune 132
    Mcu_Init();
205 arune 133
    Timebase_Init();
212 arune 134
 
135
    //alla printf ska skriva till udp
661 arune 136
    //stdout = &mystdout;    //set the output stream 
1115 arune 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
205 arune 149
 
661 arune 150
    sei();
541 arune 151
 
205 arune 152
    /*initialize enc28j60*/
669 arune 153
    if (enc28j60Init(mymac) != 1) {
154
        /* Great place to set an IO for debug */
155
    }
205 arune 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 */
661 arune 171
        //Can_Service();
205 arune 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();
1115 arune 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
541 arune 181
            txMsg.DataLength = 0;
182
            Can_Send(&txMsg);
1115 arune 183
#else
184
            txMsg.Length = 0;
185
            StdCan_Put(&txMsg);
186
#endif
205 arune 187
 
188
        }
541 arune 189
#endif
205 arune 190
 
191
        /* check if any messages have been received */
1115 arune 192
#if USE_STDCAN == 0
193
        if (rxMsgFull) {
194
#else
195
        if (StdCan_Get(&rxMsg) == StdCan_Ret_OK) {
196
#endif
281 arune 197
            uint8_t i;
661 arune 198
 
541 arune 199
            /*if (gotdumpserver != 0) {
379 arune 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");
541 arune 206
            }*/
212 arune 207
 
379 arune 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);
1115 arune 217
#if USE_STDCAN == 0
379 arune 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
                }
1115 arune 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
379 arune 232
                sendbuf2[16] = C2S_END_BYTE;
1115 arune 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
379 arune 243
            }
661 arune 244
 
1115 arune 245
#if USE_STDCAN == 0
246
            rxMsgFull = 0;
247
#endif
205 arune 248
        }
249
 
212 arune 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
 
205 arune 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);
212 arune 284
                            //txMsg.Id = 6;
285
                            //Can_Send(&txMsg);
205 arune 286
 
287
                    }
288
                    if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
289
                        payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
379 arune 290
                        uint8_t i = 0;
291
 
292
                        //om port 1100 (programmeringsporten)
280 arune 293
                        if ((buf[UDP_DST_PORT_H_P]==((locCan2SerPrt>>8) & 0xff)) && (buf[UDP_DST_PORT_L_P] == (locCan2SerPrt & 0xff))) {
379 arune 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
 
1304 arune 305
                            if ((buf[UDP_DATA_P]==C2S_START_BYTE) && (buf[UDP_DATA_P+16]==C2S_END_BYTE) && (payloadlen==17))
306
                            {
1115 arune 307
#if USE_STDCAN == 0
379 arune 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];
1304 arune 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);
379 arune 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);
1115 arune 320
#else
321
                                static StdCan_Msg_t cm;
322
                                //cm.Id = 0;
323
                                cm.Length = buf[UDP_DATA_P+7];
1304 arune 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);
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
541 arune 332
                                /*if (gotdumpserver != 0) {
379 arune 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]);
281 arune 337
                                    }
379 arune 338
                                    printf("}\n");
541 arune 339
                                }*/
1304 arune 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
281 arune 353
                            }
379 arune 354
                        //om port 1200 (dumparporten) 
541 arune 355
                        } /*else if ((buf[UDP_DST_PORT_H_P]==((locDumperPrt>>8) & 0xff)) && (buf[UDP_DST_PORT_L_P] == (locDumperPrt & 0xff))) {
379 arune 356
                            if (gotdumpserver == 0) {
212 arune 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
 
379 arune 368
                                gotdumpserver = 1;
280 arune 369
                                make_udp_reply_from_request(buf,"Got server",10,rmDumperPrt);
212 arune 370
                            } else {
280 arune 371
                                make_udp_reply_from_request(buf,"Already got server",18,rmDumperPrt);
212 arune 372
                            }
541 arune 373
                        }*/
205 arune 374
                    }                      
375
                }
376
            }
377
        }
378
 
379
 
380
 
381
 
382
    }
383
 
384
    return 0;
385
}