MCP2515 CAN BUS controller seems to conflict with writing to SD card?

I have a CAN BUS Shield from SparkFun and am talking to it from a Propeller project board, trying to make something that will log diagnostic messages to an SD card so I look at them offline. I'm interfacing with the MCP2515 using SPI and have code written using PropWare and although I haven't actually plugged it into a car yet the library does seem to be talking to the chip and I can send messages in loopback mode and get them back - everything seems golden up to this point.

But, when I add logging to the SD card to the setup, all interactions with the MCP2515 start returning errors after the first call to fopen() to open the file to start logging.

For the SD card I'm using one of these OSEPP shield things.

The voltages are a bit interesting, as the CAN BUS Shield and the OSEPP SD shield both require 5v power and I have a separate regulator and capacitor for each to give the stable power. (At first I thought that maybe using the SD card was causing a power dip and browning out the MCP2515, which I guess it still possible but I don't see how.)

The basic connections are: Prop pins 0-3 are SPI for SD, connected directly; Prop pins 13-16 are SPI for MCP2515 with a 2k resistor in series on the MISO pin (and this has worked and I confirmed I get messages back from the chip with this setup).

And the offending snippet of code (C++) looks like:
    // THIS ALWAYS WORKS
    int sdret = sd_mount(
        SDCARD_DO,
        SDCARD_CLK,
        SDCARD_DI,
        SDCARD_CS);

    // PropWare setup for MCP2515 SPI
    const SPI spi(MOSI, MISO, SCLK);
    MCP2515   can(spi, CS);

    // IF I COMMENT THIS LINE OUT THINGS WORK FINE, OTHERWISE THE can.start() BELOW ERRORS
    FILE* fp = fopen("proplog.txt", "a");

    can.start(MCP2515::BaudRate::BAUD_1000KBPS)


I haven't looked at the raw bits/signal that the MCP2515 returns after it starts freaking out, which I will do as soon as I can, but I'm guessing it's either gibberish or all the same bit - i.e. the chip is not in a valid state.

Does anyone know what I might be missing here? Kinda stumped.

Comments

  • 12 Comments sorted by Date Added Votes
  • Nvm - I switched this over to use PropWare's FatFileSystem class instead of using simpletools and everything is working fine now (with the exact same hardware setup). So it must have been a purely software issue. Possibly it was something strange like the stack overflowing or something due to the image being almost exactly 32k... no idea, but no matter at this point.
  • Interesting to hear that switching to PropWare's FAT classes fixed it. I don't see anything wrong with the code you've posted above.

    FYI: none of the code you're using so far (SPI, SD, Fat*, MCP2515) use their own cog. That means you can either simplify your board by combining the SPI buses, or increase your performance by running the SD+FAT code in a separate cog from the MCP2515 code.
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • Thanks for the feedback and that makes sense.

    After trying a few things the only (somewhat) educated guess I can make is that I was overflowing the stack and things are going haywire because it. I've noticed that somewhere around 31500 (maybe a bit less) as a built image size will cause all kinds of strange things to happen. And then I'll comment out some separate unrelated functionality and it's library and it will drop down to 30000 or so - and the same code that was just failing now works fine. I've tried this 3 or 4 times and it's fairly reproducible.

    Do you happen to have any tips on reducing the output size? On this project when I include code for CAN bus interaction via MCP2515, logging via SD, and LCD display (HD44780), the image size is somewhere around 34k and it of course doesn't load.

    (Or I guess switching to a memory model that supports external storage, assuming that is feasible, is a possibility as well, although it seems overkill for what I'm doing.)
  • Sorry - don't want to bug you with things I've already figured out. - I just tried playing around with the different memory models and compiling as CMM makes a huge difference - almost half the size. Most likely that solves my issue right there: back down to 19k with everything included!

    (Only catch I can see is if the runtime speed somehow makes a difference - apparently CMM is slower. But I don't think so, the only possible caveat I see is if I lose messages off the CAN bus by not retrieving them fast enough because the code now runs slower and the MCP2515 will only buffer I think 3 or something before it throws them away - but I doubt that will be a significant issue, if an issue at all.)
  • Glad you found the switch for CMM. The downside to CMM is, of course, speed. It is much slower than LMM. The communication loops in PropWare are all in fcache, so you will get the same max frequency for your comms, but the delay between words (or in the case of the SD card, between blocks) will be significantly higher.

    I'm thrilled to hear you're getting so much use out of PropWare's classes. Care to share exactly what you're building?
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • Understood on the down sides of CMM, I think it will be fine in my case.

    A client of mine sells devices that plug into the OBD port of your car along with a related service and online platform. They want to be able to do a test on each device and make sure it does it's thing properly before they ship each one out the door. I believe all that is needed is for the device to "detect that a car is present" and it will initialize itself and the person doing that can see that all is well and it's done. Right now they literally walk out to the parking lot and plug the thing into a car to test it, or they recently bought one of these simulators and that works as well. The problem is that it's not very cost effective as you scale up - the simulators are easily $150 a pop. So I'm essentially trying to build just enough of one of these simulators in software (recording the bus chatter from a car and playing it back is probably fine - I'm hoping it's that simple).

    I'm doing a prototype for now with an LCD and SD logging, but the final will just be a big board with a dozen or two OBD ports on it and I'll probably drive 4-5 of them with one propeller project board. And yes, it's all using PropWare - which is awesome! :)

    --

    As another interesting note: Even with the smaller code size I still ran into odd stack issues; and the fix was to move variables (specifically the larger classes/structures) out of the main function and make them global - thus removing them from the stack. This is a workable fix but it was not easy to figure out. I also couldn't find out how to change the stack size associated with the main function (I know that when you start new cogs you give it a specific stack space to use, but I'm not sure how the stack size for cog 0 is chosen; I assume it's a compiler/linker flag of some sort but I haven't found it yet.)
  • bgpbgp Posts: 33
    edited March 21 Vote Up0Vote Down
    Hey David,

    I ran into something _very_ strange in the course of this. I stripped it down to a simple demo program and made a video (it's only 2 min). When you have a sec can you please take a look and see if you have any idea what might be happening here: (link: youtu.be/opC-Iec6OAE ): (TL;DR: a small program compiled with CMM exhibits buggy behavior but works in LMM.)



    I've been running into this phenomenon quite a bit. The behavior seems deterministic for each build, i.e. the same exact source, compiled and run over and over will produce the same output each time. But when I do some small innocuous change like adding or removing a log line, the program will then exhibit some additional piece of strange behavior - everything from randomly freezing to garbled console output, etc.

    (FYI: Just tried the same experiment - same source code line for line - building through SimpleIDE and the result was exactly the same. Also, PropWare version: 3.0.0.132)

    -Brad
  • Well now THAT is weird. It *could* be the PropGCC binary incompatibility that we've been running into elsewhere recently. Someone compiled a new(er) version of PropGCC which I have hosted here. Would you mind trying that out and seeing if it works more reliably?

    Also, just FYI, you never have to manually re-invoke CMake after the first time. The first dependency that CMake writes in the Makefiles is on the CMake files, so if they ever change, then the Makefiles get auto-regenerated :)
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • Gotcha and thanks. I don't mind trying but that link looks dead (I'm getting a 404).

    P.S. http://david.zemon.name/downloads/ looks browsable; if not what you intended, adding:
    Options -Indexes
    to a .htaccess file in that folder should fix it.
  • Well now I feel dumb... didn't even check for myself. I'm afraid you'll need to compile it for yourself then. Once compiled, I'll upload it to my site for everyone else. Or you can just mail me a Mac so that I can set up continuous builds on it :D
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • Okay, now i have time for a more detailed explanation on compiling PropGCC from source:

    Here's what I run from TeamCity. If you could replicate that, I'd be greatly appreciative:
    git clone --recursive https://github.com/dbetz/propeller-gcc
    cd propeller-gcc
    
    # These steps come from the README, specific to Mac. I haven't tried them
    alias wget="curl -O"
    source fix-xcode-warnings.sh
    
    # Prep
    cd gcc
    ./contrib/download_prerequisites
    cd ..
    
    # Compile
    make GCCDIR=gcc4
    
    # Install
    mkdir ./parallax
    make INSTALL=./parallax
    
    # Package
    BASE_NAME=`cat release/VERSION.txt | grep -v "^#"`
    tar -czf ${BASE_NAME}-osx.tar.gz parallax
    

    Once you have the package, either you can upload it somewhere that allows me access, or I can create a temporary, restricted user for you to SCP the file directly onto my server.
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • Thanks David,

    I built this on my Mac (since it's not going to work for me to mail it to you :)

    Here's the final output: https://www.dropbox.com/s/dayb8nfhvqque7c/propellergcc-alpha_v1_9_0-osx.tar.gz?dl=0

    I did just a quick test and it does not appear to have different behavior than the existing compiler I'm using from the stock SimpleIDE download.

    For now, since I at least understand more about the problem, I was able to work around things by going back to LMM and not using the FAT FS code but instead just logging directly to the SD (the FAT code is ~10k, which makes a very big difference). Not the greatest solution in the world, but it'll work for now.
Sign In or Register to comment.