spirilis 1,265 Posted August 2, 2013 Share Posted August 2, 2013 (edited) 43oh Store: Buy the CAN BoosterPack for $14.99. This is a universal BoosterPack for enabling CAN I/O for all the LaunchPad-capable products. It sports an NXP TJA1051T/3 CAN transceiver which includes a "V_IO" rail for doing native 3.3V CMOS I/O with the CAN controller. Included is the footprint for the Microchip MCP2515, SPI CAN Controller. This is used to enable CAN connectivity for devices that do not have it natively supported. This is optional though. If you do not need the MCP2515, the CAN_RX and CAN_TX pads can be soldered to breakout pads inside the boosterpack arrangement that correspond to the requisite pins on the LaunchPad which have CAN capability. Stellaris/Tiva and Hercules LaunchPads should be able to take advantage of this. In that arrangement, the boosterpack simply supplies the CAN transceiver (physical-layer interface) as well as connectivity ports and the ability to supply or tap into a 5V rail going along the RJ45/CAT5 bus. I decided to choose RJ45 (non-magjack) for the physical connection, primarily due to its versatility as a way to chain multiple LaunchPads together into a long-distance CAN bus arrangement and due to its general-purpose nature. Most people use CAN to connect to their automobile; for this I will be producing a daughterboard that converts DE9 (DB9) OBD-II standard pinout into the Industrial CAN RJ45 standard, including the adaption of 12V automotive power down to 5V for powering the LaunchPad. An OBD-II to DE9 cable will need to be supplied separately to connect this arrangement but they are easy to come by; see here for an example: https://www.sparkfun.com/products/10087 Support for terminating the CAN bus is included, and this board supports the Split-Bus configuration with two 60R resistors and a single 4.7nF capacitor to provide a noise sink. This should be done at either end of the CAN bus, but nodes in the middle shouldn't need it. If any nodes are connected to the bus with a stub (not in-line but branched off using some sort of 3-port concentrator), it is recommended they use termination with two 1.3K-ohm resistors. This is not likely necessary thanks to the two RJ45 ports provided on the board which facilitate connecting nodes "in-line" to the bus. The 5V rail (CAN_V+) in the RJ45 connection can be attached directly to the LaunchPad's 5V rail in order to let the LaunchPad supply power to the whole bus, or it can be connected through a Current-Limiting IC to supply the LaunchPad's 5V rail along with bulk capacitance (SMD 1206 and/or PTH aluminum electrolytic capacitors; supply bulk capacitance to the board to survive long-distance cabling). To support using the 5V supply from the MSP430 LaunchPad, a "5VTAP" pad in the upper left is supplied which you can connect to TP1 (right behind the USB connector). If you are powering the MSP430 LaunchPad from the CAN bus itself this is not needed (the MCP1725 voltage regulator will supply the 3.3V Vcc rail). OSHpark mockup pics: !!! NOTE : this design has major bugs, update forthcoming !!! Schematic (PDF): DipTrace Schematic - SPI_CAN_BPak_draft1.pdf OSHpark gerbers: OSH_SPICAN_v10.zip Elecrow/Seeed/ITead gerbers: Elecrow_SPICANv10_5x10.zip !!! NOTE : this design has major bugs, update forthcoming !!! This board is intended to use the 5x10cm PCB service from the Chinese fabs. Edited February 13, 2014 by bluehash [ADMIN] - Add store link. xxx1, dubnet, reaper7 and 2 others 5 Quote Link to post Share on other sites
spirilis 1,265 Posted August 2, 2013 Author Share Posted August 2, 2013 FYI- The current design uses the TSSOP-20 version of the MCP2515, however I only did that b/c my MCP2515 samples were in that package. I am going to do a short run of 5 boards with that and switch the design to the SOIC-18 version which should be much easier to solder. Quote Link to post Share on other sites
spirilis 1,265 Posted August 3, 2013 Author Share Posted August 3, 2013 I will be making some changes before sending this out for fabbing, notably I'd like to enable the use of a polyfuse gating the 5V-direct connection so any shorts in the CAT5 won't overstress the supply node's 5V rail. Sent from my Galaxy Note II with Tapatalk Quote Link to post Share on other sites
spirilis 1,265 Posted August 30, 2013 Author Share Posted August 30, 2013 It's gettin' there... need to get a mouser order going soon for some 0805 components, including the 60R resistors and 4.7nF capacitors. But it's awfully close to finished & ready to roll, plus my CAN-RJ45-DE9 adapter board from OSHpark should be here tomorrow. After that I'll have a solution for hooking the LaunchPads to my car. Oh, need to snag an OBD-II-to-DE9 cable too. bluehash 1 Quote Link to post Share on other sites
bluehash 1,581 Posted August 30, 2013 Share Posted August 30, 2013 It's gettin' there... need to get a mouser order going soon for some 0805 components, including the 60R resistors and 4.7nF capacitors. But it's awfully close to finished & ready to roll, plus my CAN-RJ45-DE9 adapter board from OSHpark should be here tomorrow. After that I'll have a solution for hooking the LaunchPads to my car. Oh, need to snag an OBD-II-to-DE9 cable too. I bought my cable from here - http://www.obd2cables.com/products/obd-cables/obd-ii-cables/ Quote Link to post Share on other sites
spirilis 1,265 Posted September 12, 2013 Author Share Posted September 12, 2013 Working on an MCP2515 library for the MSP430 now. Pic of the boosterpacks sitting on the Hercules LP and the new F5529 LP: bluehash 1 Quote Link to post Share on other sites
spirilis 1,265 Posted September 17, 2013 Author Share Posted September 17, 2013 Got a decent library written, IMO, just not tested at ALL... LOL I decided to take the opportunity to write proper documentation for it before I go crunching at the code: https://github.com/spirilis/mcp2515/blob/master/API.md Now, time to play... with my logic analyzer hooked up to see what's going on. Quote Link to post Share on other sites
spirilis 1,265 Posted September 18, 2013 Author Share Posted September 18, 2013 Well that's embarrassing, I had the pinout for the right-side of the NXP TJA1051T/3 transceiver backwards. pins 5-8 go top-to-bottom instead of vice versa. Redid the footprint, rerouted that portion of the board... guess round 2 will be coming up. Quote Link to post Share on other sites
spirilis 1,265 Posted December 24, 2013 Author Share Posted December 24, 2013 New boards have been in for a little while, I got one built out with the MCP2515 - this time SOIC-18 instead of TSSOP. Loopback mode at least works, successfully transmits & receives that way, but to do a proper test of the transceiver hardware I need to get a 2nd one built with MCP2515 since I wrote the library & know how to use it (not so much with Tiva and Hercules just yet, although Hercules should be E-A-S-Y with HALCoGen...). Currently have one mostly built with pins on CAN_RX/CAN_TX for Tiva or Hercules, but none built out with the MCP2515. Also running out of RJ45 jacks... oops. Gonna spend my last 2 RJ45 jacks on an MCP2515-based board so I can test my library live over the wire. Then early next month, mouser order time. Quote Link to post Share on other sites
bluehash 1,581 Posted December 24, 2013 Share Posted December 24, 2013 @@spirilis Don't you need two Hercules'? I can loan you mine for testing. Quote Link to post Share on other sites
spirilis 1,265 Posted December 24, 2013 Author Share Posted December 24, 2013 @@spirilis Don't you need two Hercules'? I can loan you mine for testing.Naw I should be able to have heterogeneous CPUs talking... MSP430+MCP2515 talking to Tiva, Hercules, etc (even BBB if I make a cape for this RJ45 pinout) For now I'll build out another MCP2515-populated bpak and have 2 MSP430's talking. Sent from my Galaxy Note II with Tapatalk 4 bluehash 1 Quote Link to post Share on other sites
spirilis 1,265 Posted December 24, 2013 Author Share Posted December 24, 2013 Soldered up my 3rd bpak and used the last 2 RJ45 jacks I got- Will have to test it out later. I wrote a "call.c" and "response.c" based around my library that should properly vet the workability of this boosterpack with a pair of MSP430's. Next month's mouser order... wishlist: Bunch of RJ45 jacks Bunch of NXP TJA1051T/3's Maybe 10 MCP2515's Shitton of TI TPS27081A (the inrush-current limiter chip for nodes feeding off the 5V VBUS in the RJ45 pinout) Then if the BPak does indeed work properly, I'll look into options for selling (probably through the 43oh store, as I know @@bluehash has mentioned interest in CAN work!) It'll be a little different since there will be 2 options for these bpak's... Populate MCP2515, or not. Depends on whether the user will want to use it with an MSP430/C2000 LP (which also doesn't have CAN builtin) or one of the CAN-native MCUs like Tiva and Hercules. bluehash 1 Quote Link to post Share on other sites
spirilis 1,265 Posted December 25, 2013 Author Share Posted December 25, 2013 Welp, got my two MCP2515 BoosterPacks built out, fixed some bad solder joints, can't get the two to talk... slapped my Saleae Logic16 on there and I'm giving it the fine analysis. I'm basically in bitrate/time quanta hell right now, trying to figure out where my can_speed() function and params are going wrong here since I'm getting errors every time I TX - the MCP2515 detects them too and kicks back a message error, Saleae shows it as well. Finally got a CAN frame going out that looks halfway complete except it errors at the very end (ACK)... not to mention the Extended CAN Identifier that my Saleae reports isn't anywhere close to what I was sending. More debugging to go... Quote Link to post Share on other sites
spirilis 1,265 Posted December 26, 2013 Author Share Posted December 26, 2013 Well how 'bout that, the GND pad on the NXP CAN transceiver on my target/receiver boosterpack wasn't connected properly. Many of those chips were reclaimed from my first attempt using a heat gun, so the pads aren't necessarily 100% straight & true. Bolstered them up with a lot more solder+flux and now I have a successful transmission! ... according to the Saleae anyhow. Plus my values I was writing to the speed control registers were off by 1 (many needed a -1 before writing, since value 0 implies whatever the lowest possible value can be). The ID is way off, so my bit shifting math must be wrong somewhere. Gotta sit down with pen & paper and map those out properly. Alas, making good progress! Quote Link to post Share on other sites
spirilis 1,265 Posted December 26, 2013 Author Share Posted December 26, 2013 Huh ok, revelation- Extended CAN IDs have the Standard ID at the high 11 bits, ext ID at the lower 18 bits, not the other way around as I had assumed! So my call.c test is transmitting correctly over the CAN bus now. Receiver isn't sending a reply which is puzzling, so I'll have to try troubleshooting that differently (going to try sending debug info back over the CAN bus now...) Woot! Got my example working properly now. Yay! Lots of small bugs in the handling of the SIDH, SIDL registers... What a mess! At least it's working now. For a sneak peek before I document the library & post it, here's my call & response programs: call.c /* call.c * Very basic I/O test of the MCP2515 on MSP430 * Sends a message every second, responds if it finds the right response * Intended for MSP430 Value Line (G2xxx) chips */ #include <msp430.h> #include "mcp2515.h" uint32_t rid; uint8_t mext; uint8_t irq, buf[8], buf2[16]; volatile int i; volatile uint16_t sleep_counter; #define SLEEP_COUNTER 20 int main() { WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; BCSCTL3 = LFXT1S_2; while (BCSCTL3 & LFXT1OF) ; P1DIR |= BIT0; P1OUT &= ~BIT0; sleep_counter = SLEEP_COUNTER; can_init(); if (can_speed(500000, 1, 3) < 0) { P1OUT |= BIT0; LPM4; } can_rx_setmask(0, 0x000000FF, 1); can_rx_setfilter(0, 0, 0x000000F0); can_rx_mode(0, MCP2515_RXB0CTRL_MODE_RECV_STD_OR_EXT); can_ioctl(MCP2515_OPTION_LOOPBACK, 0); can_ioctl(MCP2515_OPTION_ONESHOT, 0); can_ioctl(MCP2515_OPTION_MULTISAMPLE, 0); // dump registers over SPI for debugging (logic analyzer can view this) for (i=0; i < 16; i++) can_r_reg(i * 16, buf2, 16); WDTCTL = WDT_ADLY_16; IFG1 &= ~WDTIFG; IE1 |= WDTIE; while(1) { if (mcp2515_irq & MCP2515_IRQ_FLAGGED) { irq = can_irq_handler(); if (irq & MCP2515_IRQ_RX && !(irq & MCP2515_IRQ_ERROR)) { i = can_recv(&rid, &mext, buf); if (i > 0) { if (buf[0] == '1' && mext && rid == 0x00000040) { P1OUT |= BIT0; __delay_cycles(800000); P1OUT &= ~BIT0; __delay_cycles(800000); P1OUT |= BIT0; __delay_cycles(800000); P1OUT &= ~BIT0; __delay_cycles(800000); } } } else if (irq & MCP2515_IRQ_ERROR) { if (irq & MCP2515_IRQ_TX && !(irq & MCP2515_IRQ_HANDLED)) can_tx_cancel(); can_r_reg(MCP2515_CANINTF, &mext, 1); can_r_reg(MCP2515_EFLG, &mext, 1); while(1) { P1OUT |= BIT0; __delay_cycles(400000); P1OUT &= ~BIT0; __delay_cycles(400000); } } } if (!sleep_counter) { buf[0] = '1'; buf[1]++; can_send(0x00000080, 1, buf, 2, 3); sleep_counter = SLEEP_COUNTER; } if ( !(mcp2515_irq & MCP2515_IRQ_FLAGGED) ) { //P1OUT ^= BIT0; LPM3; } } return 0; } // WDT overflow/timer #pragma vector=WDT_VECTOR __interrupt void WDT_ISR(void) { IFG1 &= ~WDTIFG; if (sleep_counter) sleep_counter--; else __bic_SR_register_on_exit(LPM3_bits); } // ISR for PORT1 #pragma vector=PORT1_VECTOR __interrupt void P1_ISR(void) { if (P1IFG & CAN_IRQ_PORTBIT) { P1IFG &= ~CAN_IRQ_PORTBIT; mcp2515_irq |= MCP2515_IRQ_FLAGGED; __bic_SR_register_on_exit(LPM4_bits); } } response.c /* response.c * Very basic I/O test of the MCP2515 on MSP430 * Waits to receive a message at 0x80, sends a reply to 0x40 * Intended for MSP430 Value Line (G2xxx) chips */ #include <msp430.h> #include "mcp2515.h" uint32_t rid; uint8_t mext; uint8_t irq, buf[8], buf2[16]; volatile int i; #define SLEEP_COUNTER 20 int main() { WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; BCSCTL3 = LFXT1S_2; while (BCSCTL3 & LFXT1OF) ; P1DIR |= BIT0; P1OUT &= ~BIT0; can_init(); if (can_speed(500000, 1, 1) < 0) { P1OUT |= BIT0; LPM4; } can_rx_setmask(0, 0x000000FF, 1); can_rx_setfilter(0, 0, 0x000000F0); can_rx_mode(0, MCP2515_RXB0CTRL_MODE_RECV_STD_OR_EXT); can_ioctl(MCP2515_OPTION_LOOPBACK, 0); can_ioctl(MCP2515_OPTION_ONESHOT, 1); for (i=0; i < 16; i++) can_r_reg(i * 16, buf2, 16); while(1) { if (mcp2515_irq & MCP2515_IRQ_FLAGGED) { irq = can_irq_handler(); if (irq & MCP2515_IRQ_RX && !(irq & MCP2515_IRQ_ERROR)) { i = can_recv(&rid, &mext, buf); if (i > 0) { if (mext && rid == 0x00000080) { can_send(0x00000040, 1, buf, 2, 3); } } } else if (irq & MCP2515_IRQ_ERROR) { can_r_reg(MCP2515_CANINTF, &mext, 1); can_r_reg(MCP2515_EFLG, &mext, 1); while(1) { P1OUT |= BIT0; __delay_cycles(1600000); P1OUT &= ~BIT0; __delay_cycles(1600000); } } } if ( !(mcp2515_irq & MCP2515_IRQ_FLAGGED) ) { //P1OUT ^= BIT0; LPM3; } } return 0; } // ISR for PORT1 #pragma vector=PORT1_VECTOR __interrupt void P1_ISR(void) { if (P1IFG & CAN_IRQ_PORTBIT) { P1IFG &= ~CAN_IRQ_PORTBIT; mcp2515_irq |= MCP2515_IRQ_FLAGGED; __bic_SR_register_on_exit(LPM3_bits); } } Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.