Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

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