Subversion Repositories HomeAutomation

Rev

Rev 1208 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1208 Rev 1210
1
#include <inttypes.h>
1
#include <inttypes.h>
2
#include <avr/interrupt.h>
2
#include <avr/interrupt.h>
3
#include <stdio.h>
3
#include <stdio.h>
4
#include <string.h>
4
#include <string.h>
5
#include <config.h> // All configuration parameters
5
#include <config.h> // All configuration parameters
6
#include <bios.h>   // BIOS interface declarations, including CAN structure and ID defines.
6
#include <bios.h>   // BIOS interface declarations, including CAN structure and ID defines.
7
#include <drivers/uart/serial.h>
7
#include <drivers/uart/serial.h>
8
#include <drivers/uart/uart.h>
8
#include <drivers/uart/uart.h>
9
#include <drivers/timer/timer.h>
9
#include <drivers/timer/timer.h>
10
#include <drivers/timer/timebase.h>
10
#include <drivers/timer/timebase.h>
11
#include <drivers/can/can.h>
11
#include <drivers/can/can.h>
-
 
12
#include <drivers/can/mcp2515/mcp2515.h>
12
 
13
 
13
#define APP_TYPE    CAN_APPTYPES_SERIALTRANSCEIVER
14
#define APP_TYPE    CAN_APPTYPES_SERIALTRANSCEIVER
14
#define APP_VERSION 0x0001
15
#define APP_VERSION 0x0001
15
 
16
 
16
//Note: Erik Calissendorff, 2009-03-29
17
//Note: Erik Calissendorff, 2009-03-29
17
//Not sure how this is supposed to be used in the CAN message but it's part of the SNS id
18
//Not sure how this is supposed to be used in the CAN message but it's part of the SNS id
18
#define SERIAL_ID_DATA  0
19
#define SERIAL_ID_DATA  0
19
 
20
 
20
//What is the maximum time  that we will wait for addition data from the serial port
21
//What is the maximum time  that we will wait for addition data from the serial port
21
//before we send it in a package, the minimum time if data is available is max-1
22
//before we send it in a package, the minimum time if data is available is max-1
22
#define RECEIVE_WAIT_TIME_MS 5
23
#define RECEIVE_WAIT_TIME_MS 5
23
 
24
 
24
// A simple message "queue", with space for one message only.
25
// A simple message "queue", with space for one message only.
25
// These are declared volatile to tell the compiler not to optimize away accesses.
26
// These are declared volatile to tell the compiler not to optimize away accesses.
26
volatile Can_Message_t rxMsg; // Message storage
27
volatile Can_Message_t rxMsg; // Message storage
27
volatile uint8_t rxMsgFull;   // Synchronization flag
28
volatile uint8_t rxMsgFull;   // Synchronization flag
28
 
29
 
29
// CAN message reception callback.
30
// CAN message reception callback.
30
// This function runs with interrupts disabled, keep it as short as possible.
31
// This function runs with interrupts disabled, keep it as short as possible.
31
void can_receive(Can_Message_t *msg) {
32
void can_receive(Can_Message_t *msg) {
32
    if (!rxMsgFull) {
33
    if (!rxMsgFull) {
33
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
34
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
34
        rxMsgFull = 1;
35
        rxMsgFull = 1;
35
    }
36
    }
36
}
37
}
37
 
38
 
38
int main(void)
39
int main(void)
39
{
40
{
40
    // Enable interrupts as early as possible
41
    // Enable interrupts as early as possible
41
    sei();
42
    sei();
42
 
43
 
43
    Timebase_Init();
44
    Timebase_Init();
44
    Serial_Init();
45
    Serial_Init();
45
 
46
 
46
    Can_Message_t txMsg; // Message storage
47
    Can_Message_t txMsg; // Message storage
47
 
48
 
48
    txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) |
49
    txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) |
49
        (NODE_ID << CAN_SHIFT_NMT_SID);
50
        (NODE_ID << CAN_SHIFT_NMT_SID);
50
    txMsg.DataLength = 4;
51
    txMsg.DataLength = 4;
51
    txMsg.RemoteFlag = 0;
52
    txMsg.RemoteFlag = 0;
52
    txMsg.ExtendedFlag = 1;
53
    txMsg.ExtendedFlag = 1;
53
    txMsg.Data.words[0] = APP_TYPE;
54
    txMsg.Data.words[0] = APP_TYPE;
54
    txMsg.Data.words[1] = APP_VERSION;
55
    txMsg.Data.words[1] = APP_VERSION;
55
 
56
 
56
    // Set up callback for CAN reception, this is optional if only sending is required.
57
    // Set up callback for CAN reception, this is optional if only sending is required.
57
    BIOS_CanCallback = &can_receive;
58
    BIOS_CanCallback = &can_receive;
58
 
59
 
59
    // Send CAN_NMT_APP_START for the transceiver
60
    // Send CAN_NMT_APP_START for the transceiver
60
    BIOS_CanSend(&txMsg);
61
    BIOS_CanSend(&txMsg);
61
 
62
 
62
    //Buffer for incoming serial data
63
    //Buffer for incoming serial data
63
    uint8_t rxBuffer[SERIAL_RX_BUFFER_SIZE];
64
    uint8_t rxBuffer[SERIAL_RX_BUFFER_SIZE];
64
 
65
 
65
    //Ensure that we don't try to buffer more than the buffer size
66
    //Ensure that we don't try to buffer more than the buffer size
66
    uint8_t maxReceiveData=8>SERIAL_RX_BUFFER_SIZE?SERIAL_RX_BUFFER_SIZE:8;
67
    uint8_t maxReceiveData=8>SERIAL_RX_BUFFER_SIZE?SERIAL_RX_BUFFER_SIZE:8;
67
 
68
 
68
    //For loop variable
69
    //For loop variable
69
    uint8_t i;
70
    uint8_t i;
70
 
71
 
71
    //How many bytes have been received from the serial port
72
    //How many bytes have been received from the serial port
72
    uint8_t received_size=0;
73
    uint8_t received_size=0;
73
 
74
 
74
    //The last received data from the serial port
75
    //The last received data from the serial port
75
    unsigned int received_data;
76
    unsigned int received_data;
76
 
77
 
77
    //Used to allow multiple bytes to be send in the same package
78
    //Used to allow multiple bytes to be send in the same package
78
    uint32_t time = Timebase_CurrentTime();
79
    uint32_t time = Timebase_CurrentTime();
79
 
80
 
80
    //Check if we got some data from the serial port
81
    //Check if we got some data from the serial port
81
    uint8_t got_received_data=0;
82
    uint8_t got_received_data=0;
82
   
83
 
83
    while (1) {
84
    while (1) {
84
 
85
 
85
        if (rxMsgFull) {
86
        if (rxMsgFull) {
86
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT && ((uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE) == ACT_TYPE_SERIAL)) {
87
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT && ((uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE) == ACT_TYPE_SERIAL)) {
87
                //Unused uint8_t actid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
88
                //Unused uint8_t actid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
88
 
89
 
89
                for(i=0;i<rxMsg.DataLength;i++)
90
                for(i=0;i<rxMsg.DataLength;i++)
90
                {
91
                {
91
                    uart_putc(rxMsg.Data.bytes[i]);
92
                    uart_putc(rxMsg.Data.bytes[i]);
92
                }
93
                }
93
            }
94
            }
94
 
95
 
95
            // Flush the received message
96
            // Flush the received message
96
            rxMsgFull = 0; //
97
            rxMsgFull = 0; //
97
        }
98
        }
98
 
99
 
99
        //Receiver
100
        //Receiver
100
       
101
 
101
        //Timer for how long we will wait for for more data before sending our packages
102
        //Timer for how long we will wait for for more data before sending our packages
102
        time = Timebase_CurrentTime();
103
        time = Timebase_CurrentTime();
103
 
104
 
104
        //We don't like to wait for the time out unless we get some data.
105
        //We don't like to wait for the time out unless we get some data.
105
        got_received_data=0;
106
        got_received_data=0;
106
        do
107
        do
107
        {
108
        {
108
            received_data=uart_getc();
109
            received_data=uart_getc();
109
            if(received_data != UART_NO_DATA)
110
            if(received_data != UART_NO_DATA)
110
            {
111
            {
111
                got_received_data=1;
112
                got_received_data=1;
112
                //TODO: Erik Calissendorff, 2009-03-29
113
                //TODO: Erik Calissendorff, 2009-03-29
113
                //Error handling should be added to inform us of problems with the serial link
114
                //Error handling should be added to inform us of problems with the serial link
114
 
115
 
115
                rxBuffer[received_size++]=(uint8_t)(received_data & 0x00ff);
116
                rxBuffer[received_size++]=(uint8_t)(received_data & 0x00ff);
116
            }
117
            }
117
        } while(received_size<maxReceiveData && got_received_data==1 && Timebase_CurrentTime()-time < RECEIVE_WAIT_TIME_MS);
118
        } while(received_size<maxReceiveData && got_received_data==1 && Timebase_CurrentTime()-time < RECEIVE_WAIT_TIME_MS);
118
 
119
 
119
        if(received_size > 0)
120
        if(received_size > 0)
120
        {
121
        {
121
            //TODO: Erik Calissendorff, 2009-03-29
122
            //TODO: Erik Calissendorff, 2009-03-29
122
            //We like to be able to accept more then one CAN package of data at a time
123
            //We like to be able to accept more then one CAN package of data at a time
123
 
124
 
124
            txMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_SERIAL << CAN_SHIFT_SNS_TYPE) | (SERIAL_ID_DATA<<CAN_SHIFT_SNS_ID) | (NODE_ID << CAN_SHIFT_SNS_SID));
125
            txMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_SERIAL << CAN_SHIFT_SNS_TYPE) | (SERIAL_ID_DATA<<CAN_SHIFT_SNS_ID) | (NODE_ID << CAN_SHIFT_SNS_SID));
125
            for(i=0;i<received_size;i++)
126
            for(i=0;i<received_size;i++)
126
            {
127
            {
127
                txMsg.Data.bytes[i]=rxBuffer[i];
128
                txMsg.Data.bytes[i]=rxBuffer[i];
128
            }
129
            }
129
            txMsg.DataLength = received_size;
130
            txMsg.DataLength = received_size;
130
           
131
 
131
            BIOS_CanSend(&txMsg);
132
            BIOS_CanSend(&txMsg);
132
        }
133
        }
133
        //Ensure we are reseting the counter
134
        //Ensure we are reseting the counter
134
        received_size=0;
135
        received_size=0;
135
    }
136
    }
136
    return 0;
137
    return 0;
137
}
138
}
138
 
139
 
139
 
140