Hi fat16lib,
your new code is great, especially the truncate function is awesome. Using multiple buffers is an improvement as well (although i don't see the point in using 12 - if your logger doesn't manage to write fast enough when using 3 buffers, it's propably too slow and won't catch up after going through 12 ... or does the writing latency vary in such an extreme way?)
nonetheless, I encounter the same problem that I did with my previous code, because the CAN-Controller and the SD-Card controller share the mosi and miso line.
Im using this shield
http://www.skpang.co.uk/catalog/arduino-canbus-shield-with-usd-card-holder-p-706.html
And i have to set ChipSelectLow(SS_PIN) when I want to write to the sd and put it back to high (not selected) afterwards, because otherwise receiving the CAN-Messages also writes nonsense to the SD card
...
If i do not allow interrupts while writing, everything works fine, but i "lose" one or 2 messages during the write process, because the CAN controller can only buffer 2 messages.
Thus, calling cli() right before writing to the sd card works fine
cli(); //clear interrupts
digitalWrite(SS_PIN, LOW); // SD on[/i]
// write block to SD
if (!sd.card()->writeData(block)) {
error("writeData");
}
digitalWrite(SS_PIN, HIGH); // SD off
sei(); // enable interrupts[/i]
...
I then tried to enable interrupts at various positions in the writeData() function, and after encountering many write errors I found a position that produced no errors and a "valid" log file (formatwise):
/** SPI send block - only one call so force inline */
static inline __attribute__((always_inline))
void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPDR = token;
for (uint16_t i = 0; i < 512; i += 2) {
// turn writing off and on again to allow interrupts
chipSelectHigh();
sei();
cli();
chipSelectLow();
// custom code end
while (!(SPSR & (1 << SPIF)));
SPDR = buf[i];
while (!(SPSR & (1 << SPIF)));
SPDR = buf[i + 1];
}
while (!(SPSR & (1 << SPIF)));
}
...
But if I do so, I get an incomplete Log file! somehow a lot of data is lost and I have milliseconds of no data. Maybe because of a buffer not actually being written?! ... i don't receive any errors and the program moves on without a hint..
I'm giving up hope, after testing it with your impressive logger. Do you have any hint, as to what I could try?
I'm sorry if this seems like I'm asking you to debug my code ... but I've already invested 15+ hours into solving this interference problem and I'm considering giving up my goal of achieving a Real-Time Capable CAN logger...
edit:
do you know, whether calling chipSelectLow/High during the write process does stuff other than just turning the connection on/off ? does it flush a buffer or something like that? .... is this something to consider debugging?