c

Committer:
tecnosys
Date:
Sat Jan 30 08:46:04 2010 +0000
Revision:
0:d8f50b1e384f
Child:
1:dbc44582f2f8

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tecnosys 0:d8f50b1e384f 1 /******************************************************************************
tecnosys 0:d8f50b1e384f 2 *
tecnosys 0:d8f50b1e384f 3 * Controller Area Network (CAN) Demo-Application
tecnosys 0:d8f50b1e384f 4 * Atmel AVR with Microchip MCP2515
tecnosys 0:d8f50b1e384f 5 *
tecnosys 0:d8f50b1e384f 6 * Copyright (C) 2005 Martin THOMAS, Kaiserslautern, Germany
tecnosys 0:d8f50b1e384f 7 * <eversmith@heizung-thomas.de>
tecnosys 0:d8f50b1e384f 8 * http://www.siwawi.arubi.uni-kl.de/avr_projects
tecnosys 0:d8f50b1e384f 9 *
tecnosys 0:d8f50b1e384f 10 *****************************************************************************
tecnosys 0:d8f50b1e384f 11 *
tecnosys 0:d8f50b1e384f 12 * File : mcp2515.c
tecnosys 0:d8f50b1e384f 13 * Version : 0.9
tecnosys 0:d8f50b1e384f 14 *
tecnosys 0:d8f50b1e384f 15 * Summary : MCP2515 "low-level" driver
tecnosys 0:d8f50b1e384f 16 *
tecnosys 0:d8f50b1e384f 17 * Parts of this code are adapted from a MCP2510 sample-application
tecnosys 0:d8f50b1e384f 18 * by KVASER AB, http://www.kvaser.com (KVASER-code is marked as free)
tecnosys 0:d8f50b1e384f 19 *
tecnosys 0:d8f50b1e384f 20 * This code-module is free to use but you have to keep the copyright
tecnosys 0:d8f50b1e384f 21 * notice.
tecnosys 0:d8f50b1e384f 22 *
tecnosys 0:d8f50b1e384f 23 *
tecnosys 0:d8f50b1e384f 24 *****************************************************************************
tecnosys 0:d8f50b1e384f 25 *
tecnosys 0:d8f50b1e384f 26 * File : mcp2515.cpp (mbed LPC1768 version)
tecnosys 0:d8f50b1e384f 27 * Version : 0.1
tecnosys 0:d8f50b1e384f 28 *
tecnosys 0:d8f50b1e384f 29 * All credits to the nerds above, this source has been adapted for the
tecnosys 0:d8f50b1e384f 30 * LPC1768 platform by J.Engelman. And does'nt require and of the copyrighted
tecnosys 0:d8f50b1e384f 31 * SPI or AVR controller code that Martin or co have excluded copyright.
tecnosys 0:d8f50b1e384f 32 * This module remains free.
tecnosys 0:d8f50b1e384f 33 *
tecnosys 0:d8f50b1e384f 34 *
tecnosys 0:d8f50b1e384f 35 *****************************************************************************/
tecnosys 0:d8f50b1e384f 36
tecnosys 0:d8f50b1e384f 37 #include "mcp2515.h"
tecnosys 0:d8f50b1e384f 38
tecnosys 0:d8f50b1e384f 39 #include <mbed.h>
tecnosys 0:d8f50b1e384f 40 #include "mcp2515_can.h"
tecnosys 0:d8f50b1e384f 41 #include "mcp2515_defs.h"
tecnosys 0:d8f50b1e384f 42 #include "mcp2515_bittime.h"
tecnosys 0:d8f50b1e384f 43
tecnosys 0:d8f50b1e384f 44 #define SPI_NULL (0x00)
tecnosys 0:d8f50b1e384f 45
tecnosys 0:d8f50b1e384f 46
tecnosys 0:d8f50b1e384f 47
tecnosys 0:d8f50b1e384f 48 mcp2515::mcp2515(PinName mosi, PinName miso, PinName clk, PinName ncs)
tecnosys 0:d8f50b1e384f 49 : _spi(mosi, miso, clk), _ncs(ncs) {
tecnosys 0:d8f50b1e384f 50
tecnosys 0:d8f50b1e384f 51 // _spi.format(8,0);
tecnosys 0:d8f50b1e384f 52 // _spi.frequency(10000000);
tecnosys 0:d8f50b1e384f 53 //_spi.frequency(5000000);
tecnosys 0:d8f50b1e384f 54
tecnosys 0:d8f50b1e384f 55 }
tecnosys 0:d8f50b1e384f 56
tecnosys 0:d8f50b1e384f 57
tecnosys 0:d8f50b1e384f 58 void mcp2515::_reset() {
tecnosys 0:d8f50b1e384f 59
tecnosys 0:d8f50b1e384f 60 _select();
tecnosys 0:d8f50b1e384f 61 _spi_readwrite(MCP_RESET);
tecnosys 0:d8f50b1e384f 62 _deselect();
tecnosys 0:d8f50b1e384f 63 wait(0.001);
tecnosys 0:d8f50b1e384f 64 }
tecnosys 0:d8f50b1e384f 65
tecnosys 0:d8f50b1e384f 66 void mcp2515::setRegister(const uint8_t address, const uint8_t value)
tecnosys 0:d8f50b1e384f 67 {
tecnosys 0:d8f50b1e384f 68 _select();
tecnosys 0:d8f50b1e384f 69 _spi_readwrite(MCP_WRITE);
tecnosys 0:d8f50b1e384f 70 _spi_readwrite(address);
tecnosys 0:d8f50b1e384f 71 _spi_readwrite(value);
tecnosys 0:d8f50b1e384f 72 _deselect();
tecnosys 0:d8f50b1e384f 73 }
tecnosys 0:d8f50b1e384f 74
tecnosys 0:d8f50b1e384f 75 uint8_t mcp2515::configRate(const uint8_t canSpeed)
tecnosys 0:d8f50b1e384f 76 {
tecnosys 0:d8f50b1e384f 77 uint8_t set, cfg1, cfg2, cfg3;
tecnosys 0:d8f50b1e384f 78
tecnosys 0:d8f50b1e384f 79 set = 0;
tecnosys 0:d8f50b1e384f 80
tecnosys 0:d8f50b1e384f 81 switch (canSpeed) {
tecnosys 0:d8f50b1e384f 82 case (CAN_125KBPS) :
tecnosys 0:d8f50b1e384f 83 cfg1 = MCP_4MHz_125kBPS_CFG1 ;
tecnosys 0:d8f50b1e384f 84 cfg2 = MCP_4MHz_125kBPS_CFG2 ;
tecnosys 0:d8f50b1e384f 85 cfg3 = MCP_4MHz_125kBPS_CFG3 ;
tecnosys 0:d8f50b1e384f 86 set = 1;
tecnosys 0:d8f50b1e384f 87 break;
tecnosys 0:d8f50b1e384f 88 case (CAN_20KBPS) :
tecnosys 0:d8f50b1e384f 89 cfg1 = MCP_4MHz_20kBPS_CFG1 ;
tecnosys 0:d8f50b1e384f 90 cfg2 = MCP_4MHz_20kBPS_CFG2 ;
tecnosys 0:d8f50b1e384f 91 cfg3 = MCP_4MHz_20kBPS_CFG3 ;
tecnosys 0:d8f50b1e384f 92 set = 1;
tecnosys 0:d8f50b1e384f 93 break;
tecnosys 0:d8f50b1e384f 94 default:
tecnosys 0:d8f50b1e384f 95 set = 0;
tecnosys 0:d8f50b1e384f 96 break;
tecnosys 0:d8f50b1e384f 97 }
tecnosys 0:d8f50b1e384f 98
tecnosys 0:d8f50b1e384f 99 if (set) {
tecnosys 0:d8f50b1e384f 100 setRegister(MCP_CNF1, cfg1);
tecnosys 0:d8f50b1e384f 101 setRegister(MCP_CNF2, cfg2);
tecnosys 0:d8f50b1e384f 102 setRegister(MCP_CNF3, cfg3);
tecnosys 0:d8f50b1e384f 103 return MCP2515_OK;
tecnosys 0:d8f50b1e384f 104 }
tecnosys 0:d8f50b1e384f 105 else {
tecnosys 0:d8f50b1e384f 106 return MCP2515_FAIL;
tecnosys 0:d8f50b1e384f 107 }
tecnosys 0:d8f50b1e384f 108 }
tecnosys 0:d8f50b1e384f 109
tecnosys 0:d8f50b1e384f 110 uint8_t mcp2515::readRegister(const uint8_t address)
tecnosys 0:d8f50b1e384f 111 {
tecnosys 0:d8f50b1e384f 112 uint8_t ret;
tecnosys 0:d8f50b1e384f 113
tecnosys 0:d8f50b1e384f 114 _select();
tecnosys 0:d8f50b1e384f 115 _spi_readwrite(MCP_READ);
tecnosys 0:d8f50b1e384f 116 _spi_readwrite(address);
tecnosys 0:d8f50b1e384f 117 ret = _spi_read();
tecnosys 0:d8f50b1e384f 118 _deselect();
tecnosys 0:d8f50b1e384f 119
tecnosys 0:d8f50b1e384f 120 return ret;
tecnosys 0:d8f50b1e384f 121 }
tecnosys 0:d8f50b1e384f 122
tecnosys 0:d8f50b1e384f 123 void mcp2515::readRegisterS(const uint8_t address,
tecnosys 0:d8f50b1e384f 124 uint8_t values[], const uint8_t n)
tecnosys 0:d8f50b1e384f 125 {
tecnosys 0:d8f50b1e384f 126 uint8_t i;
tecnosys 0:d8f50b1e384f 127
tecnosys 0:d8f50b1e384f 128 _select();
tecnosys 0:d8f50b1e384f 129 _spi_readwrite(MCP_READ);
tecnosys 0:d8f50b1e384f 130 _spi_readwrite(address);
tecnosys 0:d8f50b1e384f 131 // mcp2515 has auto-increment of address-pointer
tecnosys 0:d8f50b1e384f 132 for (i=0; i<n; i++) {
tecnosys 0:d8f50b1e384f 133 values[i] = _spi_read();
tecnosys 0:d8f50b1e384f 134 }
tecnosys 0:d8f50b1e384f 135 _deselect();
tecnosys 0:d8f50b1e384f 136 }
tecnosys 0:d8f50b1e384f 137
tecnosys 0:d8f50b1e384f 138 void mcp2515::modifyRegister(const uint8_t address,
tecnosys 0:d8f50b1e384f 139 const uint8_t mask, const uint8_t data)
tecnosys 0:d8f50b1e384f 140 {
tecnosys 0:d8f50b1e384f 141 _select();
tecnosys 0:d8f50b1e384f 142 _spi_readwrite(MCP_BITMOD);
tecnosys 0:d8f50b1e384f 143 _spi_readwrite(address);
tecnosys 0:d8f50b1e384f 144 _spi_readwrite(mask);
tecnosys 0:d8f50b1e384f 145 _spi_readwrite(data);
tecnosys 0:d8f50b1e384f 146 _deselect();
tecnosys 0:d8f50b1e384f 147 }
tecnosys 0:d8f50b1e384f 148
tecnosys 0:d8f50b1e384f 149
tecnosys 0:d8f50b1e384f 150 uint8_t mcp2515::readXXStatus_helper(const uint8_t cmd)
tecnosys 0:d8f50b1e384f 151 {
tecnosys 0:d8f50b1e384f 152 uint8_t i;
tecnosys 0:d8f50b1e384f 153
tecnosys 0:d8f50b1e384f 154 _select();
tecnosys 0:d8f50b1e384f 155 _spi_readwrite(cmd);
tecnosys 0:d8f50b1e384f 156 i = _spi_read();
tecnosys 0:d8f50b1e384f 157 _deselect();
tecnosys 0:d8f50b1e384f 158
tecnosys 0:d8f50b1e384f 159 return i;
tecnosys 0:d8f50b1e384f 160 }
tecnosys 0:d8f50b1e384f 161
tecnosys 0:d8f50b1e384f 162 uint8_t mcp2515::readStatus(void)
tecnosys 0:d8f50b1e384f 163 {
tecnosys 0:d8f50b1e384f 164 return readXXStatus_helper(MCP_READ_STATUS);
tecnosys 0:d8f50b1e384f 165 }
tecnosys 0:d8f50b1e384f 166
tecnosys 0:d8f50b1e384f 167 uint8_t mcp2515::RXStatus(void)
tecnosys 0:d8f50b1e384f 168 {
tecnosys 0:d8f50b1e384f 169 return readXXStatus_helper(MCP_RX_STATUS);
tecnosys 0:d8f50b1e384f 170 }
tecnosys 0:d8f50b1e384f 171
tecnosys 0:d8f50b1e384f 172 // read-modify-write - better: Bit Modify Instruction
tecnosys 0:d8f50b1e384f 173 uint8_t mcp2515::setCANCTRL_Mode(uint8_t newmode)
tecnosys 0:d8f50b1e384f 174 {
tecnosys 0:d8f50b1e384f 175 uint8_t i;
tecnosys 0:d8f50b1e384f 176
tecnosys 0:d8f50b1e384f 177 i = readRegister(MCP_CANCTRL);
tecnosys 0:d8f50b1e384f 178 i &= ~(MODE_MASK);
tecnosys 0:d8f50b1e384f 179 i |= newmode;
tecnosys 0:d8f50b1e384f 180 setRegister(MCP_CANCTRL, i);
tecnosys 0:d8f50b1e384f 181
tecnosys 0:d8f50b1e384f 182 // verify as advised in datasheet
tecnosys 0:d8f50b1e384f 183 i = readRegister(MCP_CANCTRL);
tecnosys 0:d8f50b1e384f 184 i &= MODE_MASK;
tecnosys 0:d8f50b1e384f 185 if ( i == newmode ) {
tecnosys 0:d8f50b1e384f 186 return MCP2515_OK;
tecnosys 0:d8f50b1e384f 187 }
tecnosys 0:d8f50b1e384f 188 else {
tecnosys 0:d8f50b1e384f 189 return MCP2515_FAIL;
tecnosys 0:d8f50b1e384f 190 }
tecnosys 0:d8f50b1e384f 191 }
tecnosys 0:d8f50b1e384f 192
tecnosys 0:d8f50b1e384f 193
tecnosys 0:d8f50b1e384f 194 void mcp2515::setRegisterS(const uint8_t address,
tecnosys 0:d8f50b1e384f 195 const uint8_t values[], const uint8_t n)
tecnosys 0:d8f50b1e384f 196 {
tecnosys 0:d8f50b1e384f 197 uint8_t i;
tecnosys 0:d8f50b1e384f 198
tecnosys 0:d8f50b1e384f 199 _select();
tecnosys 0:d8f50b1e384f 200 _spi_readwrite(MCP_WRITE);
tecnosys 0:d8f50b1e384f 201 _spi_readwrite(address);
tecnosys 0:d8f50b1e384f 202 // mcp2515 has auto-increment of address-pointer
tecnosys 0:d8f50b1e384f 203 for (i=0; i<n; i++) {
tecnosys 0:d8f50b1e384f 204 _spi_readwrite(values[i]);
tecnosys 0:d8f50b1e384f 205 }
tecnosys 0:d8f50b1e384f 206 _deselect();
tecnosys 0:d8f50b1e384f 207 }
tecnosys 0:d8f50b1e384f 208
tecnosys 0:d8f50b1e384f 209 void mcp2515::read_can_id( const uint8_t mcp_addr,
tecnosys 0:d8f50b1e384f 210 uint8_t* ext, uint32_t* can_id )
tecnosys 0:d8f50b1e384f 211 {
tecnosys 0:d8f50b1e384f 212 uint8_t tbufdata[4];
tecnosys 0:d8f50b1e384f 213
tecnosys 0:d8f50b1e384f 214 *ext = 0;
tecnosys 0:d8f50b1e384f 215 *can_id = 0;
tecnosys 0:d8f50b1e384f 216
tecnosys 0:d8f50b1e384f 217 readRegisterS( mcp_addr, tbufdata, 4 );
tecnosys 0:d8f50b1e384f 218
tecnosys 0:d8f50b1e384f 219 *can_id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
tecnosys 0:d8f50b1e384f 220
tecnosys 0:d8f50b1e384f 221 if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M ) {
tecnosys 0:d8f50b1e384f 222 // extended id
tecnosys 0:d8f50b1e384f 223 *can_id = (*can_id<<2) + (tbufdata[MCP_SIDL] & 0x03);
tecnosys 0:d8f50b1e384f 224 *can_id <<= 16;
tecnosys 0:d8f50b1e384f 225 *can_id = *can_id +(tbufdata[MCP_EID8]<<8) + tbufdata[MCP_EID0];
tecnosys 0:d8f50b1e384f 226 *ext = 1;
tecnosys 0:d8f50b1e384f 227 }
tecnosys 0:d8f50b1e384f 228 }
tecnosys 0:d8f50b1e384f 229
tecnosys 0:d8f50b1e384f 230
tecnosys 0:d8f50b1e384f 231 // Buffer can be MCP_RXBUF_0 or MCP_RXBUF_1
tecnosys 0:d8f50b1e384f 232 void mcp2515::read_canMsg( const uint8_t buffer_sidh_addr,
tecnosys 0:d8f50b1e384f 233 CANMessage* msg)
tecnosys 0:d8f50b1e384f 234 {
tecnosys 0:d8f50b1e384f 235 /*
tecnosys 0:d8f50b1e384f 236 uint8_t mcp_addr, ctrl;
tecnosys 0:d8f50b1e384f 237
tecnosys 0:d8f50b1e384f 238 mcp_addr = buffer_sidh_addr;
tecnosys 0:d8f50b1e384f 239
tecnosys 0:d8f50b1e384f 240 read_can_id( mcp_addr, &(msg->extended_identifier),
tecnosys 0:d8f50b1e384f 241 &(msg->identifier) );
tecnosys 0:d8f50b1e384f 242
tecnosys 0:d8f50b1e384f 243 ctrl = readRegister( mcp_addr-1 );
tecnosys 0:d8f50b1e384f 244 msg->dlc = readRegister( mcp_addr+4 );
tecnosys 0:d8f50b1e384f 245
tecnosys 0:d8f50b1e384f 246 //if ((*dlc & RTR_MASK) || (ctrl & 0x08)) {
tecnosys 0:d8f50b1e384f 247 if ((ctrl & 0x08)) {
tecnosys 0:d8f50b1e384f 248 msg->rtr = 1;
tecnosys 0:d8f50b1e384f 249 } else {
tecnosys 0:d8f50b1e384f 250 msg->rtr = 0;
tecnosys 0:d8f50b1e384f 251 }
tecnosys 0:d8f50b1e384f 252
tecnosys 0:d8f50b1e384f 253 msg->dlc &= MCP_DLC_MASK;
tecnosys 0:d8f50b1e384f 254 readRegisterS( mcp_addr+5, &(msg->dta[0]), msg->dlc );
tecnosys 0:d8f50b1e384f 255 */
tecnosys 0:d8f50b1e384f 256 }
tecnosys 0:d8f50b1e384f 257
tecnosys 0:d8f50b1e384f 258
tecnosys 0:d8f50b1e384f 259 void mcp2515::write_can_id( const uint8_t mcp_addr,
tecnosys 0:d8f50b1e384f 260 const uint8_t ext, const uint32_t can_id )
tecnosys 0:d8f50b1e384f 261 {
tecnosys 0:d8f50b1e384f 262 uint16_t canid;
tecnosys 0:d8f50b1e384f 263 uint8_t tbufdata[4];
tecnosys 0:d8f50b1e384f 264
tecnosys 0:d8f50b1e384f 265 canid = (uint16_t)(can_id & 0x0FFFF);
tecnosys 0:d8f50b1e384f 266
tecnosys 0:d8f50b1e384f 267 if ( ext == 1) {
tecnosys 0:d8f50b1e384f 268 tbufdata[MCP_EID0] = (uint8_t) (canid & 0xFF);
tecnosys 0:d8f50b1e384f 269 tbufdata[MCP_EID8] = (uint8_t) (canid / 256);
tecnosys 0:d8f50b1e384f 270 canid = (uint16_t)( can_id / 0x10000L );
tecnosys 0:d8f50b1e384f 271 tbufdata[MCP_SIDL] = (uint8_t) (canid & 0x03);
tecnosys 0:d8f50b1e384f 272 tbufdata[MCP_SIDL] += (uint8_t) ((canid & 0x1C )*8);
tecnosys 0:d8f50b1e384f 273 tbufdata[MCP_SIDL] |= MCP_TXB_EXIDE_M;
tecnosys 0:d8f50b1e384f 274 tbufdata[MCP_SIDH] = (uint8_t) (canid / 32 );
tecnosys 0:d8f50b1e384f 275 }
tecnosys 0:d8f50b1e384f 276 else {
tecnosys 0:d8f50b1e384f 277 tbufdata[MCP_SIDH] = (uint8_t) (canid / 8 );
tecnosys 0:d8f50b1e384f 278 tbufdata[MCP_SIDL] = (uint8_t) ((canid & 0x07 )*32);
tecnosys 0:d8f50b1e384f 279 tbufdata[MCP_EID0] = 0;
tecnosys 0:d8f50b1e384f 280 tbufdata[MCP_EID8] = 0;
tecnosys 0:d8f50b1e384f 281 }
tecnosys 0:d8f50b1e384f 282 setRegisterS( mcp_addr, tbufdata, 4 );
tecnosys 0:d8f50b1e384f 283 }
tecnosys 0:d8f50b1e384f 284
tecnosys 0:d8f50b1e384f 285 // Buffer can be MCP_TXBUF_0 MCP_TXBUF_1 or MCP_TXBUF_2
tecnosys 0:d8f50b1e384f 286 void mcp2515::write_canMsg( const uint8_t buffer_sidh_addr,
tecnosys 0:d8f50b1e384f 287 CANMessage* msg)
tecnosys 0:d8f50b1e384f 288 {
tecnosys 0:d8f50b1e384f 289 uint8_t mcp_addr, dlc;
tecnosys 0:d8f50b1e384f 290
tecnosys 0:d8f50b1e384f 291 mcp_addr = buffer_sidh_addr;
tecnosys 0:d8f50b1e384f 292 dlc = msg->len;
tecnosys 0:d8f50b1e384f 293
tecnosys 0:d8f50b1e384f 294 setRegisterS(mcp_addr+5, &(msg->data[0]), dlc ); // write data bytes
tecnosys 0:d8f50b1e384f 295 write_can_id( mcp_addr, msg->format,
tecnosys 0:d8f50b1e384f 296 msg->id ); // write CAN id
tecnosys 0:d8f50b1e384f 297 if ( msg->type == 1) dlc |= MCP_RTR_MASK; // if RTR set bit in byte
tecnosys 0:d8f50b1e384f 298 setRegister( (mcp_addr+4), dlc ); // write the RTR and DLC
tecnosys 0:d8f50b1e384f 299 }
tecnosys 0:d8f50b1e384f 300
tecnosys 0:d8f50b1e384f 301 void mcp2515::start_transmit(const uint8_t buffer_sidh_addr)
tecnosys 0:d8f50b1e384f 302 {
tecnosys 0:d8f50b1e384f 303 // TXBnCTRL_addr = TXBnSIDH_addr - 1
tecnosys 0:d8f50b1e384f 304 modifyRegister( buffer_sidh_addr-1 , MCP_TXB_TXREQ_M,
tecnosys 0:d8f50b1e384f 305 MCP_TXB_TXREQ_M );
tecnosys 0:d8f50b1e384f 306 }
tecnosys 0:d8f50b1e384f 307
tecnosys 0:d8f50b1e384f 308 uint8_t mcp2515::getNextFreeTXBuf(uint8_t *txbuf_n)
tecnosys 0:d8f50b1e384f 309 {
tecnosys 0:d8f50b1e384f 310 uint8_t res, i, ctrlval;
tecnosys 0:d8f50b1e384f 311 uint8_t ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
tecnosys 0:d8f50b1e384f 312
tecnosys 0:d8f50b1e384f 313 res = MCP_ALLTXBUSY;
tecnosys 0:d8f50b1e384f 314 *txbuf_n = 0x00;
tecnosys 0:d8f50b1e384f 315
tecnosys 0:d8f50b1e384f 316 // check all 3 TX-Buffers
tecnosys 0:d8f50b1e384f 317 for (i=0; i<MCP_N_TXBUFFERS; i++) {
tecnosys 0:d8f50b1e384f 318 ctrlval = readRegister( ctrlregs[i] );
tecnosys 0:d8f50b1e384f 319 if ( (ctrlval & MCP_TXB_TXREQ_M) == 0 ) {
tecnosys 0:d8f50b1e384f 320
tecnosys 0:d8f50b1e384f 321 *txbuf_n = ctrlregs[i]+1; // return SIDH-address of Buffer
tecnosys 0:d8f50b1e384f 322 res = MCP2515_OK;
tecnosys 0:d8f50b1e384f 323 return res; /* ! function exit */
tecnosys 0:d8f50b1e384f 324 }
tecnosys 0:d8f50b1e384f 325 }
tecnosys 0:d8f50b1e384f 326
tecnosys 0:d8f50b1e384f 327 return res;
tecnosys 0:d8f50b1e384f 328 }
tecnosys 0:d8f50b1e384f 329
tecnosys 0:d8f50b1e384f 330 void mcp2515::initCANBuffers(void)
tecnosys 0:d8f50b1e384f 331 {
tecnosys 0:d8f50b1e384f 332 uint8_t i, a1, a2, a3;
tecnosys 0:d8f50b1e384f 333
tecnosys 0:d8f50b1e384f 334 // TODO: check why this is needed to receive extended
tecnosys 0:d8f50b1e384f 335 // and standard frames
tecnosys 0:d8f50b1e384f 336 // Mark all filter bits as don't care:
tecnosys 0:d8f50b1e384f 337 write_can_id(MCP_RXM0SIDH, 0, 0);
tecnosys 0:d8f50b1e384f 338 write_can_id(MCP_RXM1SIDH, 0, 0);
tecnosys 0:d8f50b1e384f 339 // Anyway, set all filters to 0:
tecnosys 0:d8f50b1e384f 340 write_can_id(MCP_RXF0SIDH, 1, 0); // RXB0: extended
tecnosys 0:d8f50b1e384f 341 write_can_id(MCP_RXF1SIDH, 0, 0); // AND standard
tecnosys 0:d8f50b1e384f 342 write_can_id(MCP_RXF2SIDH, 1, 0); // RXB1: extended
tecnosys 0:d8f50b1e384f 343 write_can_id(MCP_RXF3SIDH, 0, 0); // AND standard
tecnosys 0:d8f50b1e384f 344 write_can_id(MCP_RXF4SIDH, 0, 0);
tecnosys 0:d8f50b1e384f 345 write_can_id(MCP_RXF5SIDH, 0, 0);
tecnosys 0:d8f50b1e384f 346
tecnosys 0:d8f50b1e384f 347 // Clear, deactivate the three transmit buffers
tecnosys 0:d8f50b1e384f 348 // TXBnCTRL -> TXBnD7
tecnosys 0:d8f50b1e384f 349 a1 = MCP_TXB0CTRL;
tecnosys 0:d8f50b1e384f 350 a2 = MCP_TXB1CTRL;
tecnosys 0:d8f50b1e384f 351 a3 = MCP_TXB2CTRL;
tecnosys 0:d8f50b1e384f 352 for (i = 0; i < 14; i++) { // in-buffer loop
tecnosys 0:d8f50b1e384f 353 setRegister(a1, 0);
tecnosys 0:d8f50b1e384f 354 setRegister(a2, 0);
tecnosys 0:d8f50b1e384f 355 setRegister(a3, 0);
tecnosys 0:d8f50b1e384f 356 a1++;
tecnosys 0:d8f50b1e384f 357 a2++;
tecnosys 0:d8f50b1e384f 358 a3++;
tecnosys 0:d8f50b1e384f 359 }
tecnosys 0:d8f50b1e384f 360
tecnosys 0:d8f50b1e384f 361 // and clear, deactivate the two receive buffers.
tecnosys 0:d8f50b1e384f 362 setRegister(MCP_RXB0CTRL, 0);
tecnosys 0:d8f50b1e384f 363 setRegister(MCP_RXB1CTRL, 0);
tecnosys 0:d8f50b1e384f 364 }
tecnosys 0:d8f50b1e384f 365
tecnosys 0:d8f50b1e384f 366 uint8_t mcp2515::init(const uint8_t canSpeed)
tecnosys 0:d8f50b1e384f 367 {
tecnosys 0:d8f50b1e384f 368 uint8_t res;
tecnosys 0:d8f50b1e384f 369
tecnosys 0:d8f50b1e384f 370 _deselect();
tecnosys 0:d8f50b1e384f 371 //MCP_CS_DDR |= ( 1 << MCP_CS_BIT );
tecnosys 0:d8f50b1e384f 372
tecnosys 0:d8f50b1e384f 373 _reset();
tecnosys 0:d8f50b1e384f 374
tecnosys 0:d8f50b1e384f 375 res = setCANCTRL_Mode(MODE_CONFIG);
tecnosys 0:d8f50b1e384f 376
tecnosys 0:d8f50b1e384f 377 if ( res == MCP2515_FAIL ){
tecnosys 0:d8f50b1e384f 378 printf("FAIL here");
tecnosys 0:d8f50b1e384f 379 return res; /* function exit on error */
tecnosys 0:d8f50b1e384f 380 }
tecnosys 0:d8f50b1e384f 381 res = configRate(canSpeed);
tecnosys 0:d8f50b1e384f 382
tecnosys 0:d8f50b1e384f 383 if ( res == MCP2515_OK ) {
tecnosys 0:d8f50b1e384f 384 initCANBuffers();
tecnosys 0:d8f50b1e384f 385
tecnosys 0:d8f50b1e384f 386
tecnosys 0:d8f50b1e384f 387 // enable both receive-buffers to receive messages
tecnosys 0:d8f50b1e384f 388 // with std. and ext. identifiers
tecnosys 0:d8f50b1e384f 389 // and enable rollover
tecnosys 0:d8f50b1e384f 390 modifyRegister(MCP_RXB0CTRL,
tecnosys 0:d8f50b1e384f 391 MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
tecnosys 0:d8f50b1e384f 392 MCP_RXB_RX_STDEXT | MCP_RXB_BUKT_MASK );
tecnosys 0:d8f50b1e384f 393 modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
tecnosys 0:d8f50b1e384f 394 MCP_RXB_RX_STDEXT);
tecnosys 0:d8f50b1e384f 395
tecnosys 0:d8f50b1e384f 396 }
tecnosys 0:d8f50b1e384f 397
tecnosys 0:d8f50b1e384f 398 return res;
tecnosys 0:d8f50b1e384f 399 }
tecnosys 0:d8f50b1e384f 400
tecnosys 0:d8f50b1e384f 401 /*
tecnosys 0:d8f50b1e384f 402 * Select function
tecnosys 0:d8f50b1e384f 403 */
tecnosys 0:d8f50b1e384f 404
tecnosys 0:d8f50b1e384f 405 void mcp2515::_select() {
tecnosys 0:d8f50b1e384f 406 //printf("{");
tecnosys 0:d8f50b1e384f 407 _ncs = 0;
tecnosys 0:d8f50b1e384f 408 }
tecnosys 0:d8f50b1e384f 409
tecnosys 0:d8f50b1e384f 410
tecnosys 0:d8f50b1e384f 411 /*
tecnosys 0:d8f50b1e384f 412 * Deselect function
tecnosys 0:d8f50b1e384f 413 */
tecnosys 0:d8f50b1e384f 414
tecnosys 0:d8f50b1e384f 415 void mcp2515::_deselect() {
tecnosys 0:d8f50b1e384f 416 _ncs = 1;
tecnosys 0:d8f50b1e384f 417 //printf("}");
tecnosys 0:d8f50b1e384f 418 }
tecnosys 0:d8f50b1e384f 419
tecnosys 0:d8f50b1e384f 420 int mcp2515::status() {
tecnosys 0:d8f50b1e384f 421 int status = 0;
tecnosys 0:d8f50b1e384f 422 _select();
tecnosys 0:d8f50b1e384f 423 _spi.write(0xd7);
tecnosys 0:d8f50b1e384f 424 status = (_spi.write(0x00) << 8 );
tecnosys 0:d8f50b1e384f 425 status |= _spi.write(0x00);
tecnosys 0:d8f50b1e384f 426 _deselect();
tecnosys 0:d8f50b1e384f 427 return status;
tecnosys 0:d8f50b1e384f 428 }
tecnosys 0:d8f50b1e384f 429
tecnosys 0:d8f50b1e384f 430 void mcp2515::_pollbusy() {
tecnosys 0:d8f50b1e384f 431 volatile int busy = 1;
tecnosys 0:d8f50b1e384f 432 while (busy) {
tecnosys 0:d8f50b1e384f 433 // if bit 7 is set, we can proceed
tecnosys 0:d8f50b1e384f 434 if ( status() & 0x80 ) {
tecnosys 0:d8f50b1e384f 435 busy = 0;
tecnosys 0:d8f50b1e384f 436 }
tecnosys 0:d8f50b1e384f 437 }
tecnosys 0:d8f50b1e384f 438 }
tecnosys 0:d8f50b1e384f 439
tecnosys 0:d8f50b1e384f 440
tecnosys 0:d8f50b1e384f 441 uint8_t mcp2515::_spi_readwrite(uint8_t data)
tecnosys 0:d8f50b1e384f 442 {
tecnosys 0:d8f50b1e384f 443 //printf("W0x%x ", data);
tecnosys 0:d8f50b1e384f 444 uint8_t ret = _spi.write(data);
tecnosys 0:d8f50b1e384f 445 // printf("R0x%x,", ret);
tecnosys 0:d8f50b1e384f 446 return ret;
tecnosys 0:d8f50b1e384f 447 }
tecnosys 0:d8f50b1e384f 448
tecnosys 0:d8f50b1e384f 449 uint8_t mcp2515::_spi_read(void)
tecnosys 0:d8f50b1e384f 450 {
tecnosys 0:d8f50b1e384f 451 return _spi_readwrite(SPI_NULL);
tecnosys 0:d8f50b1e384f 452 }