11
Dependents: yezhong_main_controller_copy_3_
mcp2515.cpp@10:c0b402665e50, 2022-03-01 (annotated)
- Committer:
- yezhong
- Date:
- Tue Mar 01 08:49:53 2022 +0000
- Revision:
- 10:c0b402665e50
- Parent:
- 9:4129ee73824c
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tecnosys | 0:d8f50b1e384f | 1 | /****************************************************************************** |
tecnosys | 1:dbc44582f2f8 | 2 | * |
tecnosys | 0:d8f50b1e384f | 3 | * Controller Area Network (CAN) Demo-Application |
tecnosys | 1:dbc44582f2f8 | 4 | * Atmel AVR with Microchip MCP2515 |
tecnosys | 1:dbc44582f2f8 | 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 | 1:dbc44582f2f8 | 14 | * |
tecnosys | 0:d8f50b1e384f | 15 | * Summary : MCP2515 "low-level" driver |
tecnosys | 0:d8f50b1e384f | 16 | * |
tecnosys | 1:dbc44582f2f8 | 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 | 1:dbc44582f2f8 | 29 | * All credits to the nerds above, this source has been adapted for the |
yezhong | 9:4129ee73824c | 30 | * LPC1768 platform by J.Engelman. And doesn't 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 | 1:dbc44582f2f8 | 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 | 1:dbc44582f2f8 | 46 | #define PHSEG11 4 |
tecnosys | 1:dbc44582f2f8 | 47 | #define PHSEG21 1 |
tecnosys | 1:dbc44582f2f8 | 48 | #define BTLMODE2 7 |
tecnosys | 1:dbc44582f2f8 | 49 | //BTLMODE 0x80 (128) |
tecnosys | 1:dbc44582f2f8 | 50 | #define BRP2 2 |
tecnosys | 1:dbc44582f2f8 | 51 | #define BRP1 1 |
tecnosys | 1:dbc44582f2f8 | 52 | #define BRP0 0 |
tecnosys | 0:d8f50b1e384f | 53 | |
tecnosys | 1:dbc44582f2f8 | 54 | #define CNF2_BTLMODE 0x80 |
tecnosys | 1:dbc44582f2f8 | 55 | #define CNF3 0x28 |
tecnosys | 1:dbc44582f2f8 | 56 | #define CNF3_SOF 0x08 |
tecnosys | 1:dbc44582f2f8 | 57 | #define CNF3_WAKFIL 0x04 |
tecnosys | 1:dbc44582f2f8 | 58 | #define CNF3_PHSEG2_MASK 0x07 |
tecnosys | 0:d8f50b1e384f | 59 | |
tecnosys | 1:dbc44582f2f8 | 60 | mcp2515::mcp2515(SPI& _spi, PinName ncs) |
tecnosys | 1:dbc44582f2f8 | 61 | : spi(_spi), _ncs(ncs) { |
tecnosys | 1:dbc44582f2f8 | 62 | printf("\n\rmcp2515 = %d",this); |
tecnosys | 1:dbc44582f2f8 | 63 | printf("\n\rpin = %d",ncs); |
tecnosys | 0:d8f50b1e384f | 64 | |
tecnosys | 0:d8f50b1e384f | 65 | } |
tecnosys | 0:d8f50b1e384f | 66 | |
tecnosys | 0:d8f50b1e384f | 67 | |
tecnosys | 1:dbc44582f2f8 | 68 | |
tecnosys | 0:d8f50b1e384f | 69 | void mcp2515::_reset() { |
tecnosys | 0:d8f50b1e384f | 70 | |
tecnosys | 0:d8f50b1e384f | 71 | _select(); |
tecnosys | 0:d8f50b1e384f | 72 | _spi_readwrite(MCP_RESET); |
tecnosys | 0:d8f50b1e384f | 73 | _deselect(); |
tecnosys | 0:d8f50b1e384f | 74 | wait(0.001); |
tecnosys | 0:d8f50b1e384f | 75 | } |
tecnosys | 0:d8f50b1e384f | 76 | |
tecnosys | 1:dbc44582f2f8 | 77 | void mcp2515::setRegister( uint8_t address, uint8_t value) { |
tecnosys | 0:d8f50b1e384f | 78 | _select(); |
tecnosys | 0:d8f50b1e384f | 79 | _spi_readwrite(MCP_WRITE); |
tecnosys | 0:d8f50b1e384f | 80 | _spi_readwrite(address); |
tecnosys | 0:d8f50b1e384f | 81 | _spi_readwrite(value); |
tecnosys | 0:d8f50b1e384f | 82 | _deselect(); |
tecnosys | 0:d8f50b1e384f | 83 | } |
tecnosys | 0:d8f50b1e384f | 84 | |
tecnosys | 1:dbc44582f2f8 | 85 | uint8_t mcp2515::configRate( uint8_t canSpeed) { |
tecnosys | 0:d8f50b1e384f | 86 | uint8_t set, cfg1, cfg2, cfg3; |
tecnosys | 1:dbc44582f2f8 | 87 | |
tecnosys | 0:d8f50b1e384f | 88 | set = 0; |
tecnosys | 1:dbc44582f2f8 | 89 | |
tecnosys | 0:d8f50b1e384f | 90 | switch (canSpeed) { |
tecnosys | 1:dbc44582f2f8 | 91 | case (CAN_500KBPS_8MHZ) : |
yezhong | 9:4129ee73824c | 92 | cfg1 = 0x04; |
tecnosys | 1:dbc44582f2f8 | 93 | cfg2 = 0xA0; |
tecnosys | 1:dbc44582f2f8 | 94 | cfg3 = 0x02; |
tecnosys | 1:dbc44582f2f8 | 95 | case (CAN_50KBPS_8MHZ) : |
yezhong | 9:4129ee73824c | 96 | cfg1 = 0x04; //0x09; |
tecnosys | 1:dbc44582f2f8 | 97 | cfg2 = 0xB8; //0x90; |
tecnosys | 1:dbc44582f2f8 | 98 | cfg3 = 0x05; //0x02; |
tecnosys | 0:d8f50b1e384f | 99 | case (CAN_125KBPS) : |
yezhong | 9:4129ee73824c | 100 | cfg1 = MCP_4MHz_125kBPS_CFG1 ; |
tecnosys | 0:d8f50b1e384f | 101 | cfg2 = MCP_4MHz_125kBPS_CFG2 ; |
tecnosys | 0:d8f50b1e384f | 102 | cfg3 = MCP_4MHz_125kBPS_CFG3 ; |
tecnosys | 0:d8f50b1e384f | 103 | set = 1; |
tecnosys | 0:d8f50b1e384f | 104 | break; |
tecnosys | 0:d8f50b1e384f | 105 | case (CAN_20KBPS) : |
yezhong | 9:4129ee73824c | 106 | cfg1 = MCP_4MHz_20kBPS_CFG1 ; |
tecnosys | 0:d8f50b1e384f | 107 | cfg2 = MCP_4MHz_20kBPS_CFG2 ; |
tecnosys | 0:d8f50b1e384f | 108 | cfg3 = MCP_4MHz_20kBPS_CFG3 ; |
tecnosys | 0:d8f50b1e384f | 109 | set = 1; |
tecnosys | 0:d8f50b1e384f | 110 | break; |
yezhong | 9:4129ee73824c | 111 | case (CAN_500KBPS_10MHz) : |
yezhong | 9:4129ee73824c | 112 | cfg1 = 0x00; |
yezhong | 9:4129ee73824c | 113 | cfg2 = 0x92; |
yezhong | 9:4129ee73824c | 114 | cfg3 = 0x02; |
yezhong | 9:4129ee73824c | 115 | set = 1; |
yezhong | 9:4129ee73824c | 116 | break; |
tecnosys | 0:d8f50b1e384f | 117 | default: |
tecnosys | 0:d8f50b1e384f | 118 | set = 0; |
tecnosys | 0:d8f50b1e384f | 119 | break; |
tecnosys | 0:d8f50b1e384f | 120 | } |
tecnosys | 1:dbc44582f2f8 | 121 | |
tecnosys | 0:d8f50b1e384f | 122 | if (set) { |
tecnosys | 0:d8f50b1e384f | 123 | setRegister(MCP_CNF1, cfg1); |
tecnosys | 0:d8f50b1e384f | 124 | setRegister(MCP_CNF2, cfg2); |
tecnosys | 0:d8f50b1e384f | 125 | setRegister(MCP_CNF3, cfg3); |
tecnosys | 0:d8f50b1e384f | 126 | return MCP2515_OK; |
tecnosys | 1:dbc44582f2f8 | 127 | } else { |
tecnosys | 0:d8f50b1e384f | 128 | return MCP2515_FAIL; |
tecnosys | 0:d8f50b1e384f | 129 | } |
tecnosys | 1:dbc44582f2f8 | 130 | } |
tecnosys | 1:dbc44582f2f8 | 131 | |
tecnosys | 1:dbc44582f2f8 | 132 | int mcp2515::configRate2(int bit_rate) |
tecnosys | 1:dbc44582f2f8 | 133 | { |
tecnosys | 1:dbc44582f2f8 | 134 | //struct spi_device *spi = to_spi_device(can->cdev.dev); |
tecnosys | 1:dbc44582f2f8 | 135 | //struct mcp251x *chip = dev_get_drvdata(&spi->dev); |
tecnosys | 1:dbc44582f2f8 | 136 | //struct mcp251x_platform_data *pdata = spi->dev.platform_data; |
yezhong | 10:c0b402665e50 | 137 | // printf("\n\rcanspeed=%d",bit_rate); |
yezhong | 9:4129ee73824c | 138 | int f_osc = 8000000; |
tecnosys | 1:dbc44582f2f8 | 139 | int tqs; /* tbit/TQ */ |
tecnosys | 1:dbc44582f2f8 | 140 | int brp; |
tecnosys | 1:dbc44582f2f8 | 141 | int ps1, ps2, propseg, sjw; |
tecnosys | 1:dbc44582f2f8 | 142 | |
tecnosys | 1:dbc44582f2f8 | 143 | /* Determine the BRP value that gives the requested bit rate. */ |
tecnosys | 1:dbc44582f2f8 | 144 | for(brp = 0; brp < 8; brp++) { |
tecnosys | 1:dbc44582f2f8 | 145 | tqs = f_osc / (2 * (brp + 1)) / bit_rate; |
tecnosys | 1:dbc44582f2f8 | 146 | if (tqs >= 5 && tqs <= 25 |
tecnosys | 1:dbc44582f2f8 | 147 | && (f_osc / (2 * (brp + 1)) / tqs) == bit_rate) |
tecnosys | 1:dbc44582f2f8 | 148 | break; |
tecnosys | 1:dbc44582f2f8 | 149 | } |
tecnosys | 1:dbc44582f2f8 | 150 | if (brp >= 8) printf("Spaztic BRP"); |
tecnosys | 1:dbc44582f2f8 | 151 | // return -1; |
tecnosys | 0:d8f50b1e384f | 152 | |
tecnosys | 1:dbc44582f2f8 | 153 | /* The CAN bus bit time (tbit) is determined by: |
tecnosys | 1:dbc44582f2f8 | 154 | * tbit = (SyncSeg + PropSeg + PS1 + PS2) * TQ |
tecnosys | 1:dbc44582f2f8 | 155 | * with: |
tecnosys | 1:dbc44582f2f8 | 156 | * SyncSeg = 1 |
tecnosys | 1:dbc44582f2f8 | 157 | * sample point (between PS1 and PS2) must be at 60%-70% of the bit time |
tecnosys | 1:dbc44582f2f8 | 158 | * PropSeg + PS1 >= PS2 |
tecnosys | 1:dbc44582f2f8 | 159 | * PropSeg + PS1 >= Tdelay |
tecnosys | 1:dbc44582f2f8 | 160 | * PS2 > SJW |
tecnosys | 1:dbc44582f2f8 | 161 | * 1 <= PropSeg <= 8, 1 <= PS1 <=8, 2 <= PS2 <= 8 |
tecnosys | 1:dbc44582f2f8 | 162 | * SJW = 1 is sufficient in most cases. |
tecnosys | 1:dbc44582f2f8 | 163 | * Tdelay is usually 1 or 2 TQ. |
tecnosys | 1:dbc44582f2f8 | 164 | */ |
tecnosys | 1:dbc44582f2f8 | 165 | |
tecnosys | 1:dbc44582f2f8 | 166 | propseg = ps1 = ps2 = (tqs - 1) / 3; |
tecnosys | 1:dbc44582f2f8 | 167 | if (tqs - (1 + propseg + ps1 + ps2) == 2) |
tecnosys | 1:dbc44582f2f8 | 168 | ps1++; |
tecnosys | 1:dbc44582f2f8 | 169 | if (tqs - (1 + propseg + ps1 + ps2) == 1) |
tecnosys | 1:dbc44582f2f8 | 170 | ps2++; |
tecnosys | 1:dbc44582f2f8 | 171 | sjw = 1; |
tecnosys | 1:dbc44582f2f8 | 172 | |
yezhong | 10:c0b402665e50 | 173 | // printf("\n\rbit rate: BRP = %d, Tbit = %d TQ, PropSeg = %d, PS1 = %d, PS2 = %d, SJW = %d\n", |
yezhong | 10:c0b402665e50 | 174 | // brp, tqs, propseg, ps1, ps2, sjw); |
tecnosys | 1:dbc44582f2f8 | 175 | |
tecnosys | 1:dbc44582f2f8 | 176 | /* Since we can only change the bit rate when the network device is |
tecnosys | 1:dbc44582f2f8 | 177 | * down the chip must be in sleep mode. Wake it up and put it into |
tecnosys | 1:dbc44582f2f8 | 178 | * config mode. */ |
tecnosys | 1:dbc44582f2f8 | 179 | //mcp251x_hw_wakeup(spi); |
tecnosys | 1:dbc44582f2f8 | 180 | //mcp251x_write_bits(spi, CANCTRL, CANCTRL_REQOP_MASK, CANCTRL_REQOP_CONF); |
tecnosys | 1:dbc44582f2f8 | 181 | |
tecnosys | 1:dbc44582f2f8 | 182 | //mcp251x_write_reg(spi, CNF1, ((sjw-1) << 6) | brp); |
tecnosys | 1:dbc44582f2f8 | 183 | //mcp251x_write_reg(spi, CNF2, CNF2_BTLMODE | ((ps1-1) << 3) | (propseg-1)); |
tecnosys | 1:dbc44582f2f8 | 184 | //mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK, (ps2-1)); |
tecnosys | 1:dbc44582f2f8 | 185 | setRegister(MCP_CNF1, ((sjw-1) << 6) | brp ); |
tecnosys | 1:dbc44582f2f8 | 186 | setRegister(MCP_CNF2, CNF2_BTLMODE | ((ps1-1) << 3) | (propseg-1) ); |
tecnosys | 1:dbc44582f2f8 | 187 | modifyRegister(MCP_CNF3, CNF3_PHSEG2_MASK, (ps2-1) ); |
tecnosys | 1:dbc44582f2f8 | 188 | //mcp251x_hw_sleep(spi); |
tecnosys | 1:dbc44582f2f8 | 189 | |
tecnosys | 1:dbc44582f2f8 | 190 | /* Calculate actual bit rate. */ |
tecnosys | 1:dbc44582f2f8 | 191 | //chip->bit_rate = pdata->f_osc / (2 * (brp + 1)) / tqs; |
tecnosys | 1:dbc44582f2f8 | 192 | |
tecnosys | 1:dbc44582f2f8 | 193 | return 0; |
tecnosys | 1:dbc44582f2f8 | 194 | } |
tecnosys | 1:dbc44582f2f8 | 195 | |
tecnosys | 1:dbc44582f2f8 | 196 | uint8_t mcp2515::readRegister( uint8_t address) { |
tecnosys | 0:d8f50b1e384f | 197 | uint8_t ret; |
tecnosys | 1:dbc44582f2f8 | 198 | |
tecnosys | 0:d8f50b1e384f | 199 | _select(); |
tecnosys | 0:d8f50b1e384f | 200 | _spi_readwrite(MCP_READ); |
tecnosys | 0:d8f50b1e384f | 201 | _spi_readwrite(address); |
tecnosys | 0:d8f50b1e384f | 202 | ret = _spi_read(); |
tecnosys | 0:d8f50b1e384f | 203 | _deselect(); |
tecnosys | 1:dbc44582f2f8 | 204 | |
tecnosys | 0:d8f50b1e384f | 205 | return ret; |
tecnosys | 0:d8f50b1e384f | 206 | } |
tecnosys | 0:d8f50b1e384f | 207 | |
tecnosys | 1:dbc44582f2f8 | 208 | void mcp2515::readRegisterS( uint8_t address, |
tecnosys | 1:dbc44582f2f8 | 209 | uint8_t values[], uint8_t n) { |
tecnosys | 0:d8f50b1e384f | 210 | uint8_t i; |
tecnosys | 1:dbc44582f2f8 | 211 | |
tecnosys | 0:d8f50b1e384f | 212 | _select(); |
tecnosys | 0:d8f50b1e384f | 213 | _spi_readwrite(MCP_READ); |
tecnosys | 0:d8f50b1e384f | 214 | _spi_readwrite(address); |
tecnosys | 0:d8f50b1e384f | 215 | // mcp2515 has auto-increment of address-pointer |
tecnosys | 0:d8f50b1e384f | 216 | for (i=0; i<n; i++) { |
tecnosys | 0:d8f50b1e384f | 217 | values[i] = _spi_read(); |
tecnosys | 0:d8f50b1e384f | 218 | } |
tecnosys | 0:d8f50b1e384f | 219 | _deselect(); |
tecnosys | 0:d8f50b1e384f | 220 | } |
tecnosys | 0:d8f50b1e384f | 221 | |
tecnosys | 1:dbc44582f2f8 | 222 | void mcp2515::modifyRegister( uint8_t address, |
tecnosys | 1:dbc44582f2f8 | 223 | uint8_t mask, uint8_t data) { |
tecnosys | 0:d8f50b1e384f | 224 | _select(); |
tecnosys | 0:d8f50b1e384f | 225 | _spi_readwrite(MCP_BITMOD); |
tecnosys | 0:d8f50b1e384f | 226 | _spi_readwrite(address); |
tecnosys | 0:d8f50b1e384f | 227 | _spi_readwrite(mask); |
tecnosys | 0:d8f50b1e384f | 228 | _spi_readwrite(data); |
tecnosys | 0:d8f50b1e384f | 229 | _deselect(); |
tecnosys | 0:d8f50b1e384f | 230 | } |
tecnosys | 0:d8f50b1e384f | 231 | |
tecnosys | 0:d8f50b1e384f | 232 | |
tecnosys | 1:dbc44582f2f8 | 233 | uint8_t mcp2515::readXXStatus_helper( uint8_t cmd) { |
tecnosys | 0:d8f50b1e384f | 234 | uint8_t i; |
tecnosys | 1:dbc44582f2f8 | 235 | |
tecnosys | 0:d8f50b1e384f | 236 | _select(); |
tecnosys | 0:d8f50b1e384f | 237 | _spi_readwrite(cmd); |
tecnosys | 0:d8f50b1e384f | 238 | i = _spi_read(); |
tecnosys | 0:d8f50b1e384f | 239 | _deselect(); |
tecnosys | 1:dbc44582f2f8 | 240 | |
tecnosys | 0:d8f50b1e384f | 241 | return i; |
tecnosys | 0:d8f50b1e384f | 242 | } |
tecnosys | 1:dbc44582f2f8 | 243 | |
tecnosys | 1:dbc44582f2f8 | 244 | uint8_t mcp2515::readStatus(void) { |
tecnosys | 0:d8f50b1e384f | 245 | return readXXStatus_helper(MCP_READ_STATUS); |
tecnosys | 0:d8f50b1e384f | 246 | } |
tecnosys | 0:d8f50b1e384f | 247 | |
tecnosys | 1:dbc44582f2f8 | 248 | uint8_t mcp2515::RXStatus(void) { |
tecnosys | 0:d8f50b1e384f | 249 | return readXXStatus_helper(MCP_RX_STATUS); |
tecnosys | 0:d8f50b1e384f | 250 | } |
tecnosys | 0:d8f50b1e384f | 251 | |
tecnosys | 0:d8f50b1e384f | 252 | // read-modify-write - better: Bit Modify Instruction |
tecnosys | 1:dbc44582f2f8 | 253 | uint8_t mcp2515::setCANCTRL_Mode(uint8_t newmode) { |
tecnosys | 1:dbc44582f2f8 | 254 | |
tecnosys | 0:d8f50b1e384f | 255 | uint8_t i; |
tecnosys | 1:dbc44582f2f8 | 256 | |
tecnosys | 0:d8f50b1e384f | 257 | i = readRegister(MCP_CANCTRL); |
tecnosys | 0:d8f50b1e384f | 258 | i &= ~(MODE_MASK); |
tecnosys | 0:d8f50b1e384f | 259 | i |= newmode; |
tecnosys | 0:d8f50b1e384f | 260 | setRegister(MCP_CANCTRL, i); |
tecnosys | 1:dbc44582f2f8 | 261 | |
tecnosys | 0:d8f50b1e384f | 262 | // verify as advised in datasheet |
tecnosys | 0:d8f50b1e384f | 263 | i = readRegister(MCP_CANCTRL); |
tecnosys | 0:d8f50b1e384f | 264 | i &= MODE_MASK; |
tecnosys | 0:d8f50b1e384f | 265 | if ( i == newmode ) { |
tecnosys | 1:dbc44582f2f8 | 266 | return MCP2515_OK; |
tecnosys | 1:dbc44582f2f8 | 267 | } else { |
tecnosys | 0:d8f50b1e384f | 268 | return MCP2515_FAIL; |
tecnosys | 0:d8f50b1e384f | 269 | } |
tecnosys | 1:dbc44582f2f8 | 270 | |
tecnosys | 0:d8f50b1e384f | 271 | } |
tecnosys | 0:d8f50b1e384f | 272 | |
tecnosys | 0:d8f50b1e384f | 273 | |
tecnosys | 1:dbc44582f2f8 | 274 | void mcp2515::setRegisterS( uint8_t address, |
tecnosys | 1:dbc44582f2f8 | 275 | uint8_t values[], uint8_t n) { |
tecnosys | 0:d8f50b1e384f | 276 | uint8_t i; |
tecnosys | 1:dbc44582f2f8 | 277 | |
tecnosys | 0:d8f50b1e384f | 278 | _select(); |
tecnosys | 0:d8f50b1e384f | 279 | _spi_readwrite(MCP_WRITE); |
tecnosys | 0:d8f50b1e384f | 280 | _spi_readwrite(address); |
tecnosys | 0:d8f50b1e384f | 281 | // mcp2515 has auto-increment of address-pointer |
tecnosys | 0:d8f50b1e384f | 282 | for (i=0; i<n; i++) { |
tecnosys | 0:d8f50b1e384f | 283 | _spi_readwrite(values[i]); |
tecnosys | 0:d8f50b1e384f | 284 | } |
tecnosys | 0:d8f50b1e384f | 285 | _deselect(); |
tecnosys | 0:d8f50b1e384f | 286 | } |
tecnosys | 0:d8f50b1e384f | 287 | |
tecnosys | 1:dbc44582f2f8 | 288 | void mcp2515::read_can_id( uint8_t mcp_addr, |
tecnosys | 1:dbc44582f2f8 | 289 | uint8_t* ext, uint32_t* can_id ) { |
tecnosys | 0:d8f50b1e384f | 290 | uint8_t tbufdata[4]; |
tecnosys | 1:dbc44582f2f8 | 291 | |
tecnosys | 0:d8f50b1e384f | 292 | *ext = 0; |
tecnosys | 0:d8f50b1e384f | 293 | *can_id = 0; |
tecnosys | 1:dbc44582f2f8 | 294 | |
tecnosys | 0:d8f50b1e384f | 295 | readRegisterS( mcp_addr, tbufdata, 4 ); |
tecnosys | 1:dbc44582f2f8 | 296 | |
tecnosys | 0:d8f50b1e384f | 297 | *can_id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5); |
tecnosys | 1:dbc44582f2f8 | 298 | |
tecnosys | 0:d8f50b1e384f | 299 | if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M ) { |
tecnosys | 0:d8f50b1e384f | 300 | // extended id |
tecnosys | 0:d8f50b1e384f | 301 | *can_id = (*can_id<<2) + (tbufdata[MCP_SIDL] & 0x03); |
tecnosys | 0:d8f50b1e384f | 302 | *can_id <<= 16; |
tecnosys | 0:d8f50b1e384f | 303 | *can_id = *can_id +(tbufdata[MCP_EID8]<<8) + tbufdata[MCP_EID0]; |
tecnosys | 0:d8f50b1e384f | 304 | *ext = 1; |
tecnosys | 0:d8f50b1e384f | 305 | } |
tecnosys | 0:d8f50b1e384f | 306 | } |
tecnosys | 0:d8f50b1e384f | 307 | |
tecnosys | 0:d8f50b1e384f | 308 | |
tecnosys | 1:dbc44582f2f8 | 309 | void mcp2515::read_can_idN( uint8_t mcp_addr, |
tecnosys | 1:dbc44582f2f8 | 310 | CANFormat* ext, unsigned int* can_id ) { |
tecnosys | 1:dbc44582f2f8 | 311 | uint8_t tbufdata[4]; |
tecnosys | 1:dbc44582f2f8 | 312 | |
tecnosys | 1:dbc44582f2f8 | 313 | *ext = CANStandard; |
tecnosys | 1:dbc44582f2f8 | 314 | *can_id = 0; |
tecnosys | 1:dbc44582f2f8 | 315 | |
tecnosys | 1:dbc44582f2f8 | 316 | readRegisterS( mcp_addr, tbufdata, 4 ); |
tecnosys | 1:dbc44582f2f8 | 317 | |
tecnosys | 1:dbc44582f2f8 | 318 | *can_id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5); |
tecnosys | 1:dbc44582f2f8 | 319 | |
tecnosys | 1:dbc44582f2f8 | 320 | if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M ) { |
tecnosys | 1:dbc44582f2f8 | 321 | // extended id |
tecnosys | 1:dbc44582f2f8 | 322 | *can_id = (*can_id<<2) + (tbufdata[MCP_SIDL] & 0x03); |
tecnosys | 1:dbc44582f2f8 | 323 | *can_id <<= 16; |
tecnosys | 1:dbc44582f2f8 | 324 | *can_id = *can_id +(tbufdata[MCP_EID8]<<8) + tbufdata[MCP_EID0]; |
tecnosys | 1:dbc44582f2f8 | 325 | *ext = CANExtended;//1; |
tecnosys | 1:dbc44582f2f8 | 326 | } |
tecnosys | 1:dbc44582f2f8 | 327 | } |
tecnosys | 1:dbc44582f2f8 | 328 | |
tecnosys | 0:d8f50b1e384f | 329 | // Buffer can be MCP_RXBUF_0 or MCP_RXBUF_1 |
tecnosys | 1:dbc44582f2f8 | 330 | void mcp2515::read_canMsg( uint8_t buffer_sidh_addr, CANMessage* msg) |
tecnosys | 1:dbc44582f2f8 | 331 | //CANMessage mcp2515::read_canMsg( uint8_t buffer_sidh_addr) |
tecnosys | 0:d8f50b1e384f | 332 | { |
tecnosys | 1:dbc44582f2f8 | 333 | uint8_t mcp_addr, ctrl,dlc; |
tecnosys | 1:dbc44582f2f8 | 334 | |
tecnosys | 1:dbc44582f2f8 | 335 | |
tecnosys | 0:d8f50b1e384f | 336 | |
tecnosys | 0:d8f50b1e384f | 337 | mcp_addr = buffer_sidh_addr; |
tecnosys | 1:dbc44582f2f8 | 338 | |
tecnosys | 1:dbc44582f2f8 | 339 | read_can_idN( mcp_addr, &msg->format, &msg->id ); |
tecnosys | 1:dbc44582f2f8 | 340 | |
tecnosys | 0:d8f50b1e384f | 341 | ctrl = readRegister( mcp_addr-1 ); |
tecnosys | 1:dbc44582f2f8 | 342 | dlc = readRegister( mcp_addr+4 ); |
tecnosys | 1:dbc44582f2f8 | 343 | |
tecnosys | 0:d8f50b1e384f | 344 | //if ((*dlc & RTR_MASK) || (ctrl & 0x08)) { |
tecnosys | 0:d8f50b1e384f | 345 | if ((ctrl & 0x08)) { |
tecnosys | 1:dbc44582f2f8 | 346 | msg->type = CANRemote; //1 CANRemote |
tecnosys | 0:d8f50b1e384f | 347 | } else { |
tecnosys | 1:dbc44582f2f8 | 348 | msg->type = CANData; //0 CANData |
tecnosys | 0:d8f50b1e384f | 349 | } |
tecnosys | 1:dbc44582f2f8 | 350 | |
tecnosys | 1:dbc44582f2f8 | 351 | dlc &= MCP_DLC_MASK; |
tecnosys | 1:dbc44582f2f8 | 352 | readRegisterS( mcp_addr+5, &(msg->data[0]), dlc ); |
tecnosys | 1:dbc44582f2f8 | 353 | msg->len =dlc; |
tecnosys | 1:dbc44582f2f8 | 354 | |
tecnosys | 0:d8f50b1e384f | 355 | } |
tecnosys | 0:d8f50b1e384f | 356 | |
tecnosys | 1:dbc44582f2f8 | 357 | void mcp2515::setDebugConsole(Serial c){ |
tecnosys | 1:dbc44582f2f8 | 358 | //console=c; |
tecnosys | 1:dbc44582f2f8 | 359 | debug=true; |
tecnosys | 1:dbc44582f2f8 | 360 | } |
tecnosys | 0:d8f50b1e384f | 361 | |
tecnosys | 1:dbc44582f2f8 | 362 | void mcp2515::write_can_id( uint8_t mcp_addr, |
tecnosys | 1:dbc44582f2f8 | 363 | uint8_t ext, uint32_t can_id ) { |
tecnosys | 0:d8f50b1e384f | 364 | uint16_t canid; |
tecnosys | 0:d8f50b1e384f | 365 | uint8_t tbufdata[4]; |
tecnosys | 1:dbc44582f2f8 | 366 | |
tecnosys | 0:d8f50b1e384f | 367 | canid = (uint16_t)(can_id & 0x0FFFF); |
tecnosys | 1:dbc44582f2f8 | 368 | |
tecnosys | 0:d8f50b1e384f | 369 | if ( ext == 1) { |
tecnosys | 0:d8f50b1e384f | 370 | tbufdata[MCP_EID0] = (uint8_t) (canid & 0xFF); |
tecnosys | 0:d8f50b1e384f | 371 | tbufdata[MCP_EID8] = (uint8_t) (canid / 256); |
tecnosys | 0:d8f50b1e384f | 372 | canid = (uint16_t)( can_id / 0x10000L ); |
tecnosys | 0:d8f50b1e384f | 373 | tbufdata[MCP_SIDL] = (uint8_t) (canid & 0x03); |
tecnosys | 0:d8f50b1e384f | 374 | tbufdata[MCP_SIDL] += (uint8_t) ((canid & 0x1C )*8); |
tecnosys | 0:d8f50b1e384f | 375 | tbufdata[MCP_SIDL] |= MCP_TXB_EXIDE_M; |
tecnosys | 0:d8f50b1e384f | 376 | tbufdata[MCP_SIDH] = (uint8_t) (canid / 32 ); |
tecnosys | 1:dbc44582f2f8 | 377 | } else { |
tecnosys | 0:d8f50b1e384f | 378 | tbufdata[MCP_SIDH] = (uint8_t) (canid / 8 ); |
tecnosys | 0:d8f50b1e384f | 379 | tbufdata[MCP_SIDL] = (uint8_t) ((canid & 0x07 )*32); |
tecnosys | 0:d8f50b1e384f | 380 | tbufdata[MCP_EID0] = 0; |
tecnosys | 0:d8f50b1e384f | 381 | tbufdata[MCP_EID8] = 0; |
tecnosys | 0:d8f50b1e384f | 382 | } |
tecnosys | 0:d8f50b1e384f | 383 | setRegisterS( mcp_addr, tbufdata, 4 ); |
tecnosys | 0:d8f50b1e384f | 384 | } |
tecnosys | 0:d8f50b1e384f | 385 | |
tecnosys | 0:d8f50b1e384f | 386 | // Buffer can be MCP_TXBUF_0 MCP_TXBUF_1 or MCP_TXBUF_2 |
tecnosys | 1:dbc44582f2f8 | 387 | void mcp2515::write_canMsg( uint8_t buffer_sidh_addr, |
tecnosys | 1:dbc44582f2f8 | 388 | CANMessage* msg) { |
tecnosys | 0:d8f50b1e384f | 389 | uint8_t mcp_addr, dlc; |
tecnosys | 0:d8f50b1e384f | 390 | |
tecnosys | 0:d8f50b1e384f | 391 | mcp_addr = buffer_sidh_addr; |
tecnosys | 0:d8f50b1e384f | 392 | dlc = msg->len; |
tecnosys | 1:dbc44582f2f8 | 393 | |
tecnosys | 0:d8f50b1e384f | 394 | setRegisterS(mcp_addr+5, &(msg->data[0]), dlc ); // write data bytes |
tecnosys | 0:d8f50b1e384f | 395 | write_can_id( mcp_addr, msg->format, |
tecnosys | 1:dbc44582f2f8 | 396 | msg->id ); // write CAN id |
tecnosys | 0:d8f50b1e384f | 397 | if ( msg->type == 1) dlc |= MCP_RTR_MASK; // if RTR set bit in byte |
tecnosys | 0:d8f50b1e384f | 398 | setRegister( (mcp_addr+4), dlc ); // write the RTR and DLC |
tecnosys | 0:d8f50b1e384f | 399 | } |
tecnosys | 0:d8f50b1e384f | 400 | |
tecnosys | 1:dbc44582f2f8 | 401 | void mcp2515::start_transmit( uint8_t buffer_sidh_addr) { |
tecnosys | 1:dbc44582f2f8 | 402 | // TXBnCTRL_addr = TXBnSIDH_addr - 1 |
tecnosys | 1:dbc44582f2f8 | 403 | modifyRegister( buffer_sidh_addr-1 , MCP_TXB_TXREQ_M, |
tecnosys | 1:dbc44582f2f8 | 404 | MCP_TXB_TXREQ_M ); |
tecnosys | 0:d8f50b1e384f | 405 | } |
tecnosys | 0:d8f50b1e384f | 406 | |
tecnosys | 1:dbc44582f2f8 | 407 | uint8_t mcp2515::getNextFreeTXBuf(uint8_t *txbuf_n) { |
tecnosys | 1:dbc44582f2f8 | 408 | uint8_t res, i, ctrlval; |
tecnosys | 1:dbc44582f2f8 | 409 | uint8_t ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL }; |
tecnosys | 1:dbc44582f2f8 | 410 | |
tecnosys | 1:dbc44582f2f8 | 411 | res = MCP_ALLTXBUSY; |
tecnosys | 1:dbc44582f2f8 | 412 | *txbuf_n = 0x00; |
tecnosys | 0:d8f50b1e384f | 413 | |
tecnosys | 1:dbc44582f2f8 | 414 | // check all 3 TX-Buffers |
tecnosys | 1:dbc44582f2f8 | 415 | for (i=0; i<MCP_N_TXBUFFERS; i++) { |
tecnosys | 1:dbc44582f2f8 | 416 | ctrlval = readRegister( ctrlregs[i] ); |
tecnosys | 1:dbc44582f2f8 | 417 | if ( (ctrlval & MCP_TXB_TXREQ_M) == 0 ) { |
tecnosys | 1:dbc44582f2f8 | 418 | |
tecnosys | 1:dbc44582f2f8 | 419 | *txbuf_n = ctrlregs[i]+1; // return SIDH-address of Buffer |
tecnosys | 1:dbc44582f2f8 | 420 | res = MCP2515_OK; |
tecnosys | 1:dbc44582f2f8 | 421 | return res; /* ! function exit */ |
tecnosys | 1:dbc44582f2f8 | 422 | } |
tecnosys | 1:dbc44582f2f8 | 423 | } |
tecnosys | 1:dbc44582f2f8 | 424 | |
tecnosys | 1:dbc44582f2f8 | 425 | return res; |
tecnosys | 0:d8f50b1e384f | 426 | } |
tecnosys | 0:d8f50b1e384f | 427 | |
tecnosys | 1:dbc44582f2f8 | 428 | void mcp2515::initCANBuffers(void) { |
tecnosys | 1:dbc44582f2f8 | 429 | // uint8_t i, a1, a2, a3; |
tecnosys | 1:dbc44582f2f8 | 430 | |
tecnosys | 1:dbc44582f2f8 | 431 | // TODO: check why this is needed to receive extended |
tecnosys | 0:d8f50b1e384f | 432 | // and standard frames |
tecnosys | 0:d8f50b1e384f | 433 | // Mark all filter bits as don't care: |
tecnosys | 0:d8f50b1e384f | 434 | write_can_id(MCP_RXM0SIDH, 0, 0); |
tecnosys | 0:d8f50b1e384f | 435 | write_can_id(MCP_RXM1SIDH, 0, 0); |
tecnosys | 0:d8f50b1e384f | 436 | // Anyway, set all filters to 0: |
tecnosys | 1:dbc44582f2f8 | 437 | write_can_id(MCP_RXF0SIDH, 1, 0); // RXB0: extended |
tecnosys | 0:d8f50b1e384f | 438 | write_can_id(MCP_RXF1SIDH, 0, 0); // AND standard |
tecnosys | 1:dbc44582f2f8 | 439 | write_can_id(MCP_RXF2SIDH, 1, 0); // RXB1: extended |
tecnosys | 0:d8f50b1e384f | 440 | write_can_id(MCP_RXF3SIDH, 0, 0); // AND standard |
tecnosys | 0:d8f50b1e384f | 441 | write_can_id(MCP_RXF4SIDH, 0, 0); |
tecnosys | 0:d8f50b1e384f | 442 | write_can_id(MCP_RXF5SIDH, 0, 0); |
tecnosys | 1:dbc44582f2f8 | 443 | /* |
tecnosys | 0:d8f50b1e384f | 444 | // Clear, deactivate the three transmit buffers |
tecnosys | 0:d8f50b1e384f | 445 | // TXBnCTRL -> TXBnD7 |
tecnosys | 0:d8f50b1e384f | 446 | a1 = MCP_TXB0CTRL; |
tecnosys | 0:d8f50b1e384f | 447 | a2 = MCP_TXB1CTRL; |
tecnosys | 0:d8f50b1e384f | 448 | a3 = MCP_TXB2CTRL; |
tecnosys | 0:d8f50b1e384f | 449 | for (i = 0; i < 14; i++) { // in-buffer loop |
tecnosys | 0:d8f50b1e384f | 450 | setRegister(a1, 0); |
tecnosys | 0:d8f50b1e384f | 451 | setRegister(a2, 0); |
tecnosys | 0:d8f50b1e384f | 452 | setRegister(a3, 0); |
tecnosys | 0:d8f50b1e384f | 453 | a1++; |
tecnosys | 0:d8f50b1e384f | 454 | a2++; |
tecnosys | 0:d8f50b1e384f | 455 | a3++; |
tecnosys | 0:d8f50b1e384f | 456 | } |
tecnosys | 1:dbc44582f2f8 | 457 | */ |
tecnosys | 0:d8f50b1e384f | 458 | // and clear, deactivate the two receive buffers. |
tecnosys | 1:dbc44582f2f8 | 459 | // setRegister(MCP_RXB0CTRL, 0); |
tecnosys | 1:dbc44582f2f8 | 460 | //setRegister(MCP_RXB1CTRL, 0); |
tecnosys | 0:d8f50b1e384f | 461 | } |
tecnosys | 0:d8f50b1e384f | 462 | |
yezhong | 9:4129ee73824c | 463 | uint8_t mcp2515::init(int canSpeed) { |
tecnosys | 0:d8f50b1e384f | 464 | uint8_t res; |
tecnosys | 1:dbc44582f2f8 | 465 | |
tecnosys | 0:d8f50b1e384f | 466 | _deselect(); |
tecnosys | 0:d8f50b1e384f | 467 | //MCP_CS_DDR |= ( 1 << MCP_CS_BIT ); |
tecnosys | 1:dbc44582f2f8 | 468 | |
tecnosys | 0:d8f50b1e384f | 469 | _reset(); |
tecnosys | 1:dbc44582f2f8 | 470 | |
tecnosys | 0:d8f50b1e384f | 471 | |
tecnosys | 0:d8f50b1e384f | 472 | res = setCANCTRL_Mode(MODE_CONFIG); |
tecnosys | 1:dbc44582f2f8 | 473 | |
tecnosys | 1:dbc44582f2f8 | 474 | if ( res == MCP2515_FAIL ) { |
tecnosys | 1:dbc44582f2f8 | 475 | printf("\r\nCAN init failed %d\n\r",&_ncs); |
tecnosys | 1:dbc44582f2f8 | 476 | return res; /* function exit on error */ |
tecnosys | 0:d8f50b1e384f | 477 | } |
tecnosys | 1:dbc44582f2f8 | 478 | res = configRate2(canSpeed); |
yezhong | 9:4129ee73824c | 479 | //res = configRate(CAN_500KBPS_10MHz); |
tecnosys | 1:dbc44582f2f8 | 480 | |
tecnosys | 0:d8f50b1e384f | 481 | if ( res == MCP2515_OK ) { |
tecnosys | 0:d8f50b1e384f | 482 | initCANBuffers(); |
tecnosys | 1:dbc44582f2f8 | 483 | |
tecnosys | 0:d8f50b1e384f | 484 | // enable both receive-buffers to receive messages |
tecnosys | 0:d8f50b1e384f | 485 | // with std. and ext. identifiers |
tecnosys | 0:d8f50b1e384f | 486 | // and enable rollover |
tecnosys | 1:dbc44582f2f8 | 487 | modifyRegister(MCP_RXB0CTRL, |
tecnosys | 1:dbc44582f2f8 | 488 | MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK, |
tecnosys | 1:dbc44582f2f8 | 489 | MCP_RXB_RX_STDEXT | MCP_RXB_BUKT_MASK ); |
tecnosys | 1:dbc44582f2f8 | 490 | modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK, |
tecnosys | 1:dbc44582f2f8 | 491 | MCP_RXB_RX_STDEXT); |
tecnosys | 0:d8f50b1e384f | 492 | |
tecnosys | 1:dbc44582f2f8 | 493 | // Prescaler setting of the CLKOUT pin to zero |
tecnosys | 1:dbc44582f2f8 | 494 | // => Spending clock frequency of the CLKOUT pin MCP2515 |
tecnosys | 1:dbc44582f2f8 | 495 | modifyRegister (MCP_CANCTRL, 0x07, CLKOUT_ENABLE); |
tecnosys | 0:d8f50b1e384f | 496 | } |
tecnosys | 1:dbc44582f2f8 | 497 | |
tecnosys | 0:d8f50b1e384f | 498 | return res; |
tecnosys | 0:d8f50b1e384f | 499 | } |
tecnosys | 0:d8f50b1e384f | 500 | |
tecnosys | 0:d8f50b1e384f | 501 | /* |
tecnosys | 0:d8f50b1e384f | 502 | * Select function |
tecnosys | 0:d8f50b1e384f | 503 | */ |
tecnosys | 1:dbc44582f2f8 | 504 | |
tecnosys | 0:d8f50b1e384f | 505 | void mcp2515::_select() { |
tecnosys | 0:d8f50b1e384f | 506 | //printf("{"); |
tecnosys | 0:d8f50b1e384f | 507 | _ncs = 0; |
tecnosys | 0:d8f50b1e384f | 508 | } |
tecnosys | 0:d8f50b1e384f | 509 | |
tecnosys | 0:d8f50b1e384f | 510 | |
tecnosys | 0:d8f50b1e384f | 511 | /* |
tecnosys | 0:d8f50b1e384f | 512 | * Deselect function |
tecnosys | 0:d8f50b1e384f | 513 | */ |
tecnosys | 0:d8f50b1e384f | 514 | |
tecnosys | 0:d8f50b1e384f | 515 | void mcp2515::_deselect() { |
tecnosys | 0:d8f50b1e384f | 516 | _ncs = 1; |
tecnosys | 0:d8f50b1e384f | 517 | //printf("}"); |
tecnosys | 0:d8f50b1e384f | 518 | } |
tecnosys | 0:d8f50b1e384f | 519 | |
tecnosys | 0:d8f50b1e384f | 520 | int mcp2515::status() { |
tecnosys | 0:d8f50b1e384f | 521 | int status = 0; |
tecnosys | 0:d8f50b1e384f | 522 | _select(); |
tecnosys | 1:dbc44582f2f8 | 523 | spi.write(0xd7); |
tecnosys | 1:dbc44582f2f8 | 524 | status = (spi.write(0x00) << 8 ); |
tecnosys | 1:dbc44582f2f8 | 525 | status |= spi.write(0x00); |
tecnosys | 0:d8f50b1e384f | 526 | _deselect(); |
tecnosys | 0:d8f50b1e384f | 527 | return status; |
tecnosys | 0:d8f50b1e384f | 528 | } |
tecnosys | 0:d8f50b1e384f | 529 | |
tecnosys | 0:d8f50b1e384f | 530 | void mcp2515::_pollbusy() { |
tecnosys | 0:d8f50b1e384f | 531 | volatile int busy = 1; |
tecnosys | 0:d8f50b1e384f | 532 | while (busy) { |
tecnosys | 0:d8f50b1e384f | 533 | // if bit 7 is set, we can proceed |
tecnosys | 0:d8f50b1e384f | 534 | if ( status() & 0x80 ) { |
tecnosys | 0:d8f50b1e384f | 535 | busy = 0; |
tecnosys | 0:d8f50b1e384f | 536 | } |
tecnosys | 0:d8f50b1e384f | 537 | } |
tecnosys | 0:d8f50b1e384f | 538 | } |
tecnosys | 0:d8f50b1e384f | 539 | |
tecnosys | 0:d8f50b1e384f | 540 | |
tecnosys | 1:dbc44582f2f8 | 541 | uint8_t mcp2515::_spi_readwrite(uint8_t data) { |
tecnosys | 1:dbc44582f2f8 | 542 | //printf("W0x%x ", data); |
tecnosys | 1:dbc44582f2f8 | 543 | uint8_t ret = spi.write(data); |
tecnosys | 1:dbc44582f2f8 | 544 | // printf("R0x%x,", ret); |
tecnosys | 0:d8f50b1e384f | 545 | return ret; |
tecnosys | 0:d8f50b1e384f | 546 | } |
tecnosys | 0:d8f50b1e384f | 547 | |
tecnosys | 1:dbc44582f2f8 | 548 | uint8_t mcp2515::_spi_read(void) { |
tecnosys | 0:d8f50b1e384f | 549 | return _spi_readwrite(SPI_NULL); |
tecnosys | 0:d8f50b1e384f | 550 | } |
tecnosys | 1:dbc44582f2f8 | 551 | |
tecnosys | 1:dbc44582f2f8 | 552 | void mcp2515::dumpExtendedStatus(void) { |
tecnosys | 1:dbc44582f2f8 | 553 | uint8_t tec, rec, eflg; |
tecnosys | 1:dbc44582f2f8 | 554 | |
tecnosys | 1:dbc44582f2f8 | 555 | tec = readRegister(MCP_TEC); |
tecnosys | 1:dbc44582f2f8 | 556 | rec = readRegister(MCP_REC); |
tecnosys | 1:dbc44582f2f8 | 557 | eflg = readRegister(MCP_EFLG); |
tecnosys | 1:dbc44582f2f8 | 558 | |
yezhong | 10:c0b402665e50 | 559 | // printf("MCP2515 Extended Status:\n\r"); |
yezhong | 10:c0b402665e50 | 560 | // printf("MCP Transmit Error Count %d \r\n", tec); |
yezhong | 10:c0b402665e50 | 561 | // printf("MCP Receiver Error Count %d \n\r", rec); |
yezhong | 10:c0b402665e50 | 562 | // printf("MCP Error Flag %d\n\r", eflg); |
tecnosys | 1:dbc44582f2f8 | 563 | |
tecnosys | 1:dbc44582f2f8 | 564 | if ( (rec>127) || (tec>127) ) { |
tecnosys | 1:dbc44582f2f8 | 565 | printf("Error-Passive or Bus-Off\n\r"); |
tecnosys | 1:dbc44582f2f8 | 566 | } |
tecnosys | 1:dbc44582f2f8 | 567 | |
tecnosys | 1:dbc44582f2f8 | 568 | if (eflg & MCP_EFLG_RX1OVR) |
tecnosys | 1:dbc44582f2f8 | 569 | printf("Receive Buffer 1 Overflow\r\n"); |
tecnosys | 1:dbc44582f2f8 | 570 | if (eflg & MCP_EFLG_RX0OVR) |
tecnosys | 1:dbc44582f2f8 | 571 | printf("Receive Buffer 0 Overflow\n\r"); |
tecnosys | 1:dbc44582f2f8 | 572 | if (eflg & MCP_EFLG_TXBO) |
tecnosys | 1:dbc44582f2f8 | 573 | printf("Bus-Off\n\r"); |
tecnosys | 1:dbc44582f2f8 | 574 | if (eflg & MCP_EFLG_TXEP) |
tecnosys | 1:dbc44582f2f8 | 575 | printf("Receive Error Passive\n\r"); |
tecnosys | 1:dbc44582f2f8 | 576 | if (eflg & MCP_EFLG_TXWAR) |
tecnosys | 1:dbc44582f2f8 | 577 | printf("Transmit Error Warning\n\r"); |
tecnosys | 1:dbc44582f2f8 | 578 | if (eflg & MCP_EFLG_RXWAR) |
tecnosys | 1:dbc44582f2f8 | 579 | printf("Receive Error Warning\r\n"); |
tecnosys | 1:dbc44582f2f8 | 580 | if (eflg & MCP_EFLG_EWARN ) |
tecnosys | 1:dbc44582f2f8 | 581 | printf("Receive Error Warning\n\r"); |
tecnosys | 1:dbc44582f2f8 | 582 | } |