Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
59 jimmy 1
/**
2
 * CAN Interface. This is a general high-level interface for CAN communication.
3
 * Underlying CAN controllers are abstracted by this interface, so the
4
 * application needs not work directly against the CAN controllers.
5
 *
127 jimmy 6
 * @date    2006-11-19
59 jimmy 7
 *
8
 * @author  Jimmy Myhrman
9
 * @author  Martin Thomas
10
 *  
11
 */
12
 
13
/*-----------------------------------------------------------------------------
14
 * Includes
15
 *---------------------------------------------------------------------------*/
16
#include <string.h>
17
#include <can.h>
18
#include "timebase.h"
19
 
20
 
21
#ifdef CAN_CONTROLLER_MCP2515
22
    #include "mcp2515.h"
23
#else
24
    #error No CAN controller specified! Edit can_cfg.h !
25
#endif
26
 
27
 
28
/*-----------------------------------------------------------------------------
29
 * Functions
30
 *---------------------------------------------------------------------------*/
31
 
32
/**
127 jimmy 33
 * Initializes the CAN interface. Edit can_cfg.h to choose bitrate.
59 jimmy 34
 *
35
 * @return
36
 *      CAN_OK if initialization was successful.
37
 *      CAN_FAILINIT otherwise.
38
 */
127 jimmy 39
Can_Return_t Can_Init() {
40
    Can_Bitrate_t bitrate = CAN_BITRATE;
59 jimmy 41
#ifdef CAN_CONTROLLER_MCP2515
127 jimmy 42
    if (MCP2515_Init(bitrate) != MCP2515_OK) {
59 jimmy 43
        return CAN_FAILINIT;
44
    }
127 jimmy 45
    if (MCP2515_SetCanCtrlMode(MODE_NORMAL) != MCP2515_OK) {
59 jimmy 46
        return CAN_FAILINIT;
47
    }
48
    return CAN_OK;
49
#endif
50
 
51
    return CAN_FAILINIT;
52
 
53
}
54
 
55
 
56
/**
57
 * Sends a CAN message. If the CAN controller is busy, the message will be
58
 * copied to an internal transmission queue and transmitted later.
59
 *
60
 * @param msg
61
 *      Pointer to the CAN message storage buffer.
62
 * @return
63
 *      CAN_OK if the message was successfully sent (or put in queue).
64
 *      CAN_FAILTX if the controller is busy AND the transmission queue is full.
65
 */
127 jimmy 66
Can_Return_t Can_Send(Can_Message_t* msg) {
59 jimmy 67
 
68
#ifdef CAN_CONTROLLER_MCP2515
69
    uint8_t res, txbuf_n;
127 jimmy 70
    res = MCP2515_GetNextFreeTXBuf(&txbuf_n); // info = addr.
59 jimmy 71
    if (res == MCP_ALLTXBUSY) {
72
        return CAN_FAILTX;
73
    }
127 jimmy 74
    MCP2515_WriteCanMsg(txbuf_n, msg);
75
    MCP2515_StartTransmit(txbuf_n);
59 jimmy 76
    return CAN_OK;
77
#endif
78
 
79
}
80
 
81
 
82
/**
83
 * Pulls a message from the internal CAN interface reception queue. Unless this queue
84
 * is empty, a CAN message is moved from the queue into the message storage provided
85
 * by the calling function.
86
 *
87
 * @param msg
88
 *      Pointer to the message storage buffer.
89
 * @return
90
 *      CAN_OK if a received message was successfully copied into the buffer.
91
 *      CAN_NOMSG if there are no received messages available.
92
 */
127 jimmy 93
Can_Return_t Can_Receive(Can_Message_t *msg) {
59 jimmy 94
 
95
#ifdef CAN_CONTROLLER_MCP2515
96
    uint8_t stat, res;
127 jimmy 97
    stat = MCP2515_ReadStatus();
59 jimmy 98
    if (stat & MCP_STAT_RX0IF) {
99
        // Msg in Buffer 0
127 jimmy 100
        MCP2515_ReadCanMsg( MCP_RXBUF_0, msg);
101
        MCP2515_ModifyRegister(MCP_CANINTF, MCP_RX0IF, 0);
59 jimmy 102
        res = CAN_OK;
103
    }
104
    else if (stat & MCP_STAT_RX1IF) {
105
        // Msg in Buffer 1
127 jimmy 106
        MCP2515_ReadCanMsg( MCP_RXBUF_1, msg);
107
        MCP2515_ModifyRegister(MCP_CANINTF, MCP_RX1IF, 0);
59 jimmy 108
        res = CAN_OK;
109
    }
110
    else {
111
        res = CAN_NOMSG;
112
    }  
113
    return res;
114
#endif
115
 
116
}
117
 
118
 
119
/**
120
 * Checks if there are any received CAN messages waiting in the reception queue.
121
 *
122
 * @return
123
 *      CAN_MSGAVAIL if there are messages available.
124
 *      CAN_NOMSG if the queue is empty.
125
 */
127 jimmy 126
Can_Return_t Can_ReceiveAvailable(void) {
59 jimmy 127
 
128
#ifdef CAN_CONTROLLER_MCP2515
129
    uint8_t res;
127 jimmy 130
    res = MCP2515_ReadStatus(); // RXnIF in Bit 1 and 0
59 jimmy 131
    if ( res & MCP_STAT_RXIF_MASK ) {
132
        return CAN_MSGAVAIL;
133
    }
134
    else {
135
        return CAN_NOMSG;
136
    }
137
#endif
138
 
139
}
140
 
141
 
142
/*
143
 * Checks Controller-Error-State.
144
 *
145
 * @return
146
 *      CAN_OK if the controller is OK.
147
 *      CAN_CTRLERROR if errors have occured.
148
 * @todo
149
 *      Styr upp denna funktion lite bättre.
150
 */
127 jimmy 151
Can_Return_t Can_CheckError(void) {
59 jimmy 152
 
153
#ifdef CAN_CONTROLLER_MCP2515
127 jimmy 154
    uint8_t eflg = MCP2515_ReadRegister(MCP_EFLG);
59 jimmy 155
    if (eflg & MCP_EFLG_ERRORMASK) {
156
        return CAN_CTRLERROR;
157
    }
158
    else {
159
        return CAN_OK;
160
    }
161
#endif
162
 
163
}