Subversion Repositories HomeAutomation

Rev

Rev 687 | Rev 693 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 687 Rev 690
Line 1... Line -...
1
/**
-
 
2
 * High level functions for bus communication and standard node behaviour.
-
 
3
 *
-
 
4
 * @author  Andreas Fritiofson
-
 
5
 *
-
 
6
 * @date    2007-10-24
-
 
7
 */
-
 
8
 
1
 
9
#include <config.h>
-
 
10
#include "stdcan.h"
2
#include "stdcan.h"
11
#if defined(_AVRLIB_BIOS_)
3
#if defined(_AVRLIB_BIOS_)
12
#include <bios.h>
4
#include <bios.h>
13
#define Can_Send BIOS_CanSend
5
#define Can_Send BIOS_CanSend
14
#else
6
#else
Line 33... Line 25...
33
 */
25
 */
34
StdCan_Msg_t TxQ[STDCAN_TX_QUEUE_SIZE];
26
StdCan_Msg_t TxQ[STDCAN_TX_QUEUE_SIZE];
35
unsigned char TxQ_Rd_idx; /**< Transmit queue read index. */
27
unsigned char TxQ_Rd_idx; /**< Transmit queue read index. */
36
unsigned char TxQ_Wr_idx; /**< Transmit queue write index. */
28
unsigned char TxQ_Wr_idx; /**< Transmit queue write index. */
37
unsigned char TxQ_Len; /**< Number of messages in transmit queue. */
29
unsigned char TxQ_Len; /**< Number of messages in transmit queue. */
-
 
30
#endif
-
 
31
 
-
 
32
#if (STDCAN_FILTER)
-
 
33
/**
-
 
34
 * The message acceptance filters.
-
 
35
 */
-
 
36
typedef struct {
-
 
37
    char Active; /**< True if this filter should be used. */
-
 
38
    unsigned long Id; /**< Match if id matches the message id in all bit locations that are not masked. */
-
 
39
    unsigned long Mask; /**< Each bit specifies if the corresponding id bit must match (mask[n] = 1) or is Don't Care (mask[n] = 0). */
-
 
40
} StdCan_Filter_t;
-
 
41
 
-
 
42
StdCan_Filter_t RxFilters[STDCAN_NUM_FILTERS];
38
#endif
43
#endif
39
 
44
 
40
/**
45
/**
41
 * CAN message callback.
46
 * CAN message callback.
42
 * Callback for when a message is received from the lower
47
 * Callback for when a message is received from the lower
43
 * layer (BIOS or CAN driver).
48
 * layer (BIOS or CAN driver).
44
 */
49
 */
45
void Can_Process(Can_Message_t* msg)
50
void Can_Process(Can_Message_t* msg)
46
{
51
{
47
    unsigned char n;
52
    unsigned char n;
48
    /* Check if there is room on the queue. */
53
    /* Check if there is room on the queue. */
49
    if (RxQ_Len < STDCAN_RX_QUEUE_SIZE) {
54
    if (RxQ_Len < STDCAN_RX_QUEUE_SIZE) {
-
 
55
       
-
 
56
#if (STDCAN_FILTER)
-
 
57
        /* Try to match each filter in turn. */
-
 
58
        for (n = 0; n < STDCAN_NUM_FILTERS; n++) {
-
 
59
            if (RxFilters[n].Active && !((msg->Id ^ RxFilters[n].Id) & RxFilters[n].Mask)) {
-
 
60
                RxQ[RxQ_Wr_idx].Match = n;
-
 
61
                break;
-
 
62
            }
-
 
63
        }
-
 
64
       
-
 
65
        if (n == STDCAN_NUM_FILTERS) return; // No match found, discard message.
-
 
66
#endif
50
        /* Copy the message from lower layer into the queue. */
67
        /* Copy the message from lower layer into the queue. */
51
        RxQ[RxQ_Wr_idx].Id     = msg->Id;
68
        RxQ[RxQ_Wr_idx].Id     = msg->Id;
52
        RxQ[RxQ_Wr_idx].Length = msg->DataLength;
69
        RxQ[RxQ_Wr_idx].Length = msg->DataLength;
53
        //TODO: This should be guarded against invalid DataLength.
70
        //TODO: This should be guarded against invalid DataLength.
54
        for (n = 0; n < RxQ[RxQ_Wr_idx].Length; n++) {
71
        for (n = 0; n < RxQ[RxQ_Wr_idx].Length; n++) {
Line 59... Line 76...
59
        RxQ_Len++;
76
        RxQ_Len++;
60
    } else {
77
    } else {
61
        /* Overflow, just drop the new message. In the future, some
78
        /* Overflow, just drop the new message. In the future, some
62
         * form of priority scheme could be used to drop another
79
         * form of priority scheme could be used to drop another
63
         * message in the queue.
80
         * message in the queue.
64
         */
81
         */
65
    }
82
    }
66
}
83
}
67
 
84
 
68
StdCan_Ret_t StdCan_Init(Node_Desc_t* node_desc)
85
StdCan_Ret_t StdCan_Init(Node_Desc_t* node_desc)
69
{
86
{
70
    StdCan_Ret_t retval;
87
    StdCan_Ret_t retval;
71
   
88
   
72
    /* Reset all queue variables. */
89
    /* Reset all queue variables. */
73
    RxQ_Rd_idx = 0;
90
    RxQ_Rd_idx = 0;
74
    RxQ_Wr_idx = 0;
91
    RxQ_Wr_idx = 0;
75
    RxQ_Len    = 0;
92
    RxQ_Len    = 0;
-
 
93
#if (STDCAN_TX_QUEUE_SIZE > 1)
76
    TxQ_Rd_idx = 0;
94
    TxQ_Rd_idx = 0;
77
    TxQ_Wr_idx = 0;
95
    TxQ_Wr_idx = 0;
78
    TxQ_Len    = 0;
96
    TxQ_Len    = 0;
-
 
97
#endif
79
   
98
   
80
#if defined(_AVRLIB_BIOS_)
99
#if defined(_AVRLIB_BIOS_)
81
    /* Initialize BIOS' interface for CAN. */
100
    /* Initialize BIOS' interface for CAN. */
82
    BIOS_CanCallback = Can_Process;
101
    BIOS_CanCallback = Can_Process;
83
    retval = StdCan_Ret_OK;
102
    retval = StdCan_Ret_OK;
Line 122... Line 141...
122
 
141
 
123
StdCan_Ret_t StdCan_Put(StdCan_Msg_t* msg)
142
StdCan_Ret_t StdCan_Put(StdCan_Msg_t* msg)
124
{
143
{
125
    Can_Message_t Can_Msg;
144
    Can_Message_t Can_Msg;
126
    unsigned char n;
145
    unsigned char n;
127
   
146
   
128
    /* Validate message. */
147
    /* Validate message. */
129
    if ((unsigned)msg->Length > 8) return StdCan_Ret_DataErr;
148
    if ((unsigned)msg->Length > 8) return StdCan_Ret_DataErr;
130
   
149
   
131
    /* Copy message directly to lower layer until a proper
150
    /* Copy message directly to lower layer until a proper
132
     * queue has been implemented.
151
     * queue has been implemented.
Line 163... Line 182...
163
                 | (NODE_ID << CAN_SHIFT_NMT_SID);
182
                 | (NODE_ID << CAN_SHIFT_NMT_SID);
164
   
183
   
165
    /* Try to send it. */
184
    /* Try to send it. */
166
    Can_Send(&Heartbeat);
185
    Can_Send(&Heartbeat);
167
}
186
}
-
 
187
 
-
 
188
#if (STDCAN_FILTER)
-
 
189
StdCan_Ret_t StdCan_EnableFilter(unsigned char filter, unsigned long id, unsigned long mask)
-
 
190
{
-
 
191
    if (filter < STDCAN_NUM_FILTERS) {
-
 
192
        RxFilters[filter].Id = id;
-
 
193
        RxFilters[filter].Mask = mask;
-
 
194
        RxFilters[filter].Active = 1;
-
 
195
        return StdCan_Ret_OK;
-
 
196
    } else {
-
 
197
        return StdCan_Ret_DataErr;
-
 
198
    }
-
 
199
}
-
 
200
 
-
 
201
StdCan_Ret_t StdCan_DisableFilter(unsigned char filter)
-
 
202
{
-
 
203
    if (filter < STDCAN_NUM_FILTERS) {
-
 
204
        RxFilters[filter].Active = 0;
-
 
205
        return StdCan_Ret_OK;
-
 
206
    } else {
-
 
207
        return StdCan_Ret_DataErr;
-
 
208
    }
-
 
209
}
-
 
210
#endif