Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
MCAN.cxx
1
34#ifndef _DEFAULT_SOURCE
35#define _DEFAULT_SOURCE
36#endif
37
38#include "TCAN4550Can.hxx"
39
40#include <fcntl.h>
41#include <unistd.h>
42
43#include <atomic>
44
46{
47 /* 20 MHz clock source
48 * TQ = BRP / freq = 10 / 20 MHz = 500 nsec
49 * Baud = 125 kHz
50 * bit time = 1 / 125 kHz = 8 usec = 16 TQ
51 * SyncSeg = 1 TQ
52 * PropSeg = 7 TQ
53 * Seg1 = 4 TQ
54 * Seg2 = 4 TQ
55 * sample time = (1 TQ + 7 TQ + 4 TQ) / 16 TQ = 75%
56 * SJW = Seg - 1 = 4 - 1 = 3
57 * SJW = 3 * 500 nsec = 1.5 usec
58 *
59 * Oscillator Tolerance:
60 * 4 / (2 * ((13 * 16) - 4)) = 0.980%
61 * 3 / (20 * 16) = 0.938%
62 * = 0.938%
63 */
64 {20000000, 125000, {(3 - 1), (4 - 1), (11 - 1), (10 - 1)}},
65 /* 40 MHz clock source
66 * TQ = BRP / freq = 10 / 40 MHz = 500 nsec
67 * Baud = 125 kHz
68 * bit time = 1 / 125 kHz = 8 usec = 16 TQ
69 * SyncSeg = 1 TQ
70 * PropSeg = 7 TQ
71 * Seg1 = 4 TQ
72 * Seg2 = 4 TQ
73 * sample time = (1 TQ + 7 TQ + 4 TQ) / 16 TQ = 75%
74 * SJW = Seg - 1 = 4 - 1 = 3
75 * SJW = 3 * 500 nsec = 1.5 usec
76 *
77 * Oscillator Tolerance:
78 * 4 / (2 * ((13 * 16) - 4)) = 0.980%
79 * 3 / (20 * 16) = 0.938%
80 * = 0.938%
81 */
82 {40000000, 125000, {(3 - 1), (4 - 1), (11 - 1), (20 - 1)}},
83};
84
85
86//
87// init()
88//
89void TCAN4550Can::init(const char *spi_name, uint32_t freq, uint32_t baud,
90 uint16_t rx_timeout_bits)
91{
92 spiFd_ = ::open(spi_name, O_RDWR);
93 HASSERT(spiFd_ >= 0);
94
95 ::ioctl(spiFd_, SPI_IOC_GET_OBJECT_REFERENCE, &spi_);
97
98 // configure SPI bus settings
99 uint8_t spi_mode = SPI_MODE_0;
100 uint8_t spi_bpw = 32;
101 uint32_t spi_max_speed_hz = freq / 2;
102 if (spi_max_speed_hz > SPI_MAX_SPEED_HZ)
103 {
104 spi_max_speed_hz = SPI_MAX_SPEED_HZ;
105 }
106 ::ioctl(spiFd_, SPI_IOC_WR_MODE, &spi_mode);
107 ::ioctl(spiFd_, SPI_IOC_WR_BITS_PER_WORD, &spi_bpw);
108 ::ioctl(spiFd_, SPI_IOC_WR_MAX_SPEED_HZ, &spi_max_speed_hz);
109
110 // lock SPI bus access
111 OSMutexLock locker(&lock_);
112
113 {
114 // read/clear TCAN status flags
115 uint32_t status = register_read(INTERRUPT_STATUS);
117 }
118 {
119 // transition to "Normal" mode with sleep and watchdog disabled
120 Mode mode;
121 mode.sweDis = 1; // disable sleep
122 mode.wdEnable = 0; // disable watchdog
123 mode.modeSel = 2; // normal mode
124 mode.clkRef = (freq == 40000000);
125
126 register_write(MODE, mode.data);
127 }
128 {
129 // enter configuration mode
130 Cccr cccr; // default is initialization mode
131 register_write(CCCR, cccr.data);
132 do
133 {
134 cccr.data = register_read(CCCR);
135 } while (cccr.init == 0);
136
137 cccr.cce = 1; // configuration change enable
138 register_write(CCCR, cccr.data);
139 do
140 {
141 cccr.data = register_read(CCCR);
142 } while (cccr.cce == 0);
143 }
144
145 // diasable all TCAN interrupts
147
148 // clear MRAM, a bit brute force, but gets the job done
149 for (uint16_t offset = 0x0000; offset < MRAM_SIZE_WORDS; ++offset)
150 {
151 register_write((Registers)(MRAM + offset), 0);
152 }
153
154 {
155 // setup RX FIFO 0
156 Rxfxc rxf0c;
157 rxf0c.fsa = RX_FIFO_0_MRAM_ADDR; // FIFO start address
158 rxf0c.fs = RX_FIFO_SIZE; // FIFO size
159 register_write(RXF0C, rxf0c.data);
160 }
161 {
162 // setup TX configuration
163 Txbc txbc;
164 txbc.tbsa = TX_BUFFERS_MRAM_ADDR; // buffers start address
165 txbc.ndtb = TX_DEDICATED_BUFFER_COUNT; // dedicated transmit buffers
166 txbc.tfqs = TX_FIFO_SIZE; // FIFO/queue size
167 register_write(TXBC, txbc.data);
168 }
169 {
170 // setup TX buffer element size
171 Txesc txesc;
172 txesc.tbds = 0; // 8 byte data field size
173 register_write(TXESC, txesc.data);
174 }
175 {
176 // setup TX event FIFO
177 Txefc txefc;
178 txefc.efsa = TX_EVENT_FIFO_MRAM_ADDR; // event FIFO start address
179 txefc.efs = TX_EVENT_FIFO_SIZE; // event FIFO size
180 txefc.efwm = TX_EVENT_FIFO_SIZE / 2; // event FIFO watermark
181 register_write(TXEFC, txefc.data);
182 }
183 {
184 // setup timestamp counter
185 // make sure that the timeout is reasonable
186 HASSERT(rx_timeout_bits >= 10);
187
188 Tscc tscc; // default TCP = (1 - 1) = 0
189 tscc.tss = 1; // value incremented according to TCP
190 register_write(TSCC, tscc.data);
191
192 Tocc tocc;
193 tocc.etoc = 1; // enable timeout counter
194 tocc.tos = 2; // timeout controlled by RX FIFO 0
195 tocc.top = (rx_timeout_bits - 1); // timeout counts in bit periods
196 register_write(TOCC, tocc.data);
197 }
198
199 // Setup timing
200 for ( size_t i = 0; i < ARRAYSIZE(BAUD_TABLE); ++i)
201 {
202 if (BAUD_TABLE[i].freq == freq && BAUD_TABLE[i].baud == baud)
203 {
204 register_write(NBTP, BAUD_TABLE[i].nbtp.data);
205
206 Cccr cccr;
207 do
208 {
209 cccr.data = 0;
210 register_write(CCCR, cccr.data);
211 cccr.data = register_read(CCCR);
212 } while (cccr.init == 1);
213
214 return;
215 }
216 }
217
218 // unsupported frequency
219 HASSERT(0);
220}
221
222//
223// enable()
224//
226{
227 // There is a mutex lock of lock_ above us, so the following sequence is
228 // thread safe.
229 if (!is_created())
230 {
231 // start the thread at the highest priority in the system
232 start(name, get_priority_max(), 512);
233
240 }
241
242 txCompleteMask_ = 0;
243 txPending_ = false;
244 rxPending_ = true; // waiting on an RX message
245 {
246 // clear MCAN interrupts
247 MCANInterrupt mcan_interrupt;
248 mcan_interrupt.data = 0x3FFFFFFF;
249 register_write(IR, mcan_interrupt.data);
250 }
251 {
252 // enable MCAN interrupts
253 mcanInterruptEnable_.data = 0; // start with all interrupts disabled
254 mcanInterruptEnable_.rf0l = 1; // RX FIFO 0 message lost
255 mcanInterruptEnable_.tc = 1; // transmission complete
256 mcanInterruptEnable_.too = 1; // timeout occured (RX timeout)
257 mcanInterruptEnable_.ep = 1; // error passive
258 mcanInterruptEnable_.bo = 1; // bus-off status
260 }
261 {
262 // enable interrupt line 0
263 Ile ile;
264 ile.eint0 = 1;
265 register_write(ILE, ile.data);
266 }
267 {
268 // enable normal operation mode
269 Cccr cccr;
270 cccr.init = 0; // normal operation mode, enables CAN bus access
271 register_write(CCCR, cccr.data);
272 }
273
275
277}
278
279//
280// disable()
281//
283{
284 // There is a mutex lock of lock_ above us, so the following sequence is
285 // thread safe.
287
289
290 {
291 // enable initalization mode
292 Cccr cccr;
293 cccr.init = 1; // initialization mode, disables CAN bus access
294 register_write(CCCR, cccr.data);
295 }
296 {
297 // disable interrupt line 0
298 Ile ile;
299 register_write(ILE, ile.data);
300 }
301 {
302 // disable MCAN interrupts
305 }
306
308}
309
310//
311// TCAN4550Can::flush_buffers()
312//
314{
315 // lock SPI bus access
316 OSMutexLock locker(&lock_);
317
318 // cancel TX FIFO buffers
320
321 // get the rx status (FIFO fill level)
322 Rxfxs rxf0s;
323 rxf0s.data = register_read(RXF0S);
324
326 while (rxf0s.ffl)
327 {
328 // acknowledge the next FIFO index
329 Rxfxa rxf0a;
330 rxf0a.fai = rxf0s.fgi;
331 register_write(RXF0A, rxf0a.data);
332
333 // increment index and count
334 if (++rxf0s.fgi >= RX_FIFO_SIZE)
335 {
336 rxf0s.fgi = 0;
337 }
338 --rxf0s.ffl;
339 }
340}
341
342//
343// TCAN4550Can::read()
344//
345ssize_t TCAN4550Can::read(File *file, void *buf, size_t count)
346{
347 HASSERT((count % sizeof(struct can_frame)) == 0);
348
349 struct can_frame *data = (struct can_frame*)buf;
350 ssize_t result = 0;
351
352 count /= sizeof(struct can_frame);
353
354 while (count)
355 {
356 size_t frames_read = 0;
357 MRAMRXBuffer *mram_rx_buffer = reinterpret_cast<MRAMRXBuffer*>(data);
358
359 {
360 // lock SPI bus access
361 OSMutexLock locker(&lock_);
362 Rxfxs rxf0s;
363 rxf0s.data = register_read(RXF0S);
364 if (rxf0s.ffl)
365 {
366 static_assert(sizeof(struct can_frame) == sizeof(MRAMRXBuffer), "RX buffer size does not match assumptions.");
367
368 // clip to the continous buffer memory available
369 frames_read = std::min(RX_FIFO_SIZE - rxf0s.fgi, rxf0s.ffl);
370
371 // clip to the number of asked for frames
372 frames_read = std::min(frames_read, count);
373
374 // read from MRAM
376 RX_FIFO_0_MRAM_ADDR + (rxf0s.fgi * sizeof(MRAMRXBuffer)),
377 mram_rx_buffer, frames_read);
378
379 // acknowledge the last FIFO index read
380 Rxfxa rxf0a;
381 rxf0a.fai = rxf0s.fgi + (frames_read - 1);
382 register_write(RXF0A, rxf0a.data);
383 }
384 if (frames_read == rxf0s.ffl)
385 {
386 // all of the data was pulled out, need to re-enable RX
387 // timeout interrupt
388
389 // set pending flag
390 rxPending_ = true;
391
392 // enable receive timeout interrupt
395 }
396 }
397 // shuffle data for structure translation
398 for (size_t i = 0; i < frames_read; ++i)
399 {
400 struct can_frame tmp;
401
402 tmp.can_id = mram_rx_buffer[i].id;
403 if (!mram_rx_buffer[i].xtd)
404 {
405 // standard frame
406 tmp.can_id >>= 18;
407 }
408 tmp.can_dlc = mram_rx_buffer[i].dlc;
409 tmp.can_rtr = mram_rx_buffer[i].rtr;
410 tmp.can_eff = mram_rx_buffer[i].xtd;
411 tmp.can_err = mram_rx_buffer[i].esi;
412
413 std::atomic_thread_fence(std::memory_order_seq_cst);
414
415 data[i].raw[0] = tmp.raw[0];
416 data[i].raw[1] = tmp.raw[1];
417 }
418
419 if (frames_read == 0)
420 {
421 // no more data to receive
422 if ((file->flags & O_NONBLOCK) || result > 0)
423 {
424 break;
425 }
426 else
427 {
428 // wait for data to come in
429 rxBuf->block_until_condition(file, true);
430 }
431 }
432
433 count -= frames_read;
434 result += frames_read;
435 data += frames_read;
436 }
437
438 if (!result && (file->flags & O_NONBLOCK))
439 {
440 return -EAGAIN;
441 }
442
443 return result * sizeof(struct can_frame);
444}
445
446//
447// TCAN4550Can::write()
448//
449ssize_t TCAN4550Can::write(File *file, const void *buf, size_t count)
450{
451 HASSERT((count % sizeof(struct can_frame)) == 0);
452
453 const struct can_frame *data = (const struct can_frame*)buf;
454 ssize_t result = 0;
455
456 count /= sizeof(struct can_frame);
457
458 while (count)
459 {
460 size_t frames_written = 0;
461
462 {
463 // lock SPI bus access
464 OSMutexLock locker(&lock_);
465
467 {
468 // cancel pending TX FIFO buffers to make room
470
481 }
482
483 Txfqs txfqs;
484 txfqs.data = register_read(TXFQS);
485 if (txfqs.tffl)
486 {
487 // clip to the continous buffer memory available
488 frames_written = std::min(
490 txfqs.tffl);
491
492 // clip to the number of provided frames
493 frames_written = std::min(frames_written, count);
494
495 uint32_t txbar = 0;
496 uint32_t put_index = txfqs.tfqpi;
498 // shuffle data for structure translation
499 for (size_t i = 0; i < frames_written; ++i, ++put_index)
500 {
501 if (data[i].can_eff)
502 {
503 // extended frame
504 tx_buffers[i].id = data[i].can_id;
505 }
506 else
507 {
508 // standard frame
509 tx_buffers[i].id = data[i].can_id << 18;
510 }
511 tx_buffers[i].rtr = data[i].can_rtr;
512 tx_buffers[i].xtd = data[i].can_eff;
513 tx_buffers[i].esi = data[i].can_err;
514 tx_buffers[i].dlc = data[i].can_dlc;
515 tx_buffers[i].brs = 0;
516 tx_buffers[i].fdf = 0;
517 tx_buffers[i].efc = 0;
518 tx_buffers[i].mm = 0;
519 tx_buffers[i].data64 = data[i].data64;
520 txbar |= 0x1 << put_index;
521 }
522
523 // write to MRAM
525 TX_BUFFERS_MRAM_ADDR + (txfqs.tfqpi * sizeof(MRAMTXBuffer)),
526 &txBufferMultiWrite_, frames_written);
527
528 // add transmission requests
529 register_write(TXBAR, txbar);
530 }
531 if (frames_written == txfqs.tffl)
532 {
533 // No space left in the TX FIFO. Setup a software emulation for
534 // a transmit watermark half way through the FIFO
535
536 // set pending flag
537 txPending_ = true;
538
539 uint32_t watermark_index = txfqs.tfgi + (TX_FIFO_SIZE / 2);
540 if (watermark_index >=
542 {
543 watermark_index -= TX_FIFO_SIZE;
544 }
545 txCompleteMask_ |= 0x1 << watermark_index;
546
547 // enable TX FIFO buffer interrupt
549 }
550 }
551
552 if (frames_written == 0)
553 {
554 // no more data to transmit
555 if ((file->flags & O_NONBLOCK) || result > 0)
556 {
557 break;
558 }
559 else
560 {
561 // wait for space to be available
562 txBuf->block_until_condition(file, false);
563 }
564 }
565 else
566 {
567 result += frames_written;
568 count -= frames_written;
569 data += frames_written;
570 }
571 }
572
573 if (!result && (file->flags & O_NONBLOCK))
574 {
575 return -EAGAIN;
576 }
577
578 return result * sizeof(struct can_frame);
579}
580
581//
582// TCQN4550Can::select()
583//
584bool TCAN4550Can::select(File* file, int mode)
585{
586 bool retval = false;
587 switch (mode)
588 {
589 case FREAD:
590 {
591 AtomicHolder h(this);
592 if (rxPending_)
593 {
595 }
596 else
597 {
598 retval = true;
599 }
600 break;
601 }
602 case FWRITE:
603 {
604 AtomicHolder h (this);
605 if (txPending_)
606 {
608 }
609 else
610 {
611 retval = true;
612 }
613 break;
614 }
615 default:
616 return Can::select(file, mode);
617 }
618
619 return retval;
620}
621
622//
623// TCAN4550Can::ioctl()
624//
625int TCAN4550Can::ioctl(File *file, unsigned long int key, unsigned long data)
626{
627 if (key == SIOCGCANSTATE)
628 {
629 *((can_state_t*)data) = state_;
630 return 0;
631 }
632 return -EINVAL;
633}
634
635//
636// entry()
637//
638__attribute__((optimize("-O3")))
639void *TCAN4550Can::entry()
640{
641 for ( ; /* forever */ ; )
642 {
643#if TCAN4550_DEBUG
644 int result = sem_.timedwait(SEC_TO_NSEC(1));
645
646 if (result != 0)
647 {
648 OSMutexLock locker(&lock_);
649 enable_ = register_read(INTERRUPT_ENABLE);
650 spiStatus_ = register_read(STATUS);
651 status_ = register_read(INTERRUPT_STATUS);
652
653 MRAMSPIMessage msg;
654 msg.cmd = READ;
655 msg.addrH = 0x10;
656 msg.addrL = 0x00;
657 msg.length = 64;
658
659 spi_ioc_transfer xfer[2];
660 xfer[0].tx_buf = (unsigned long)&msg;
661 xfer[0].rx_buf = 0;
662 xfer[0].len = sizeof(MRAMSPIMessage);
663 xfer[1].tx_buf = 0;
664 xfer[1].rx_buf = (unsigned long)regs_;
665 xfer[1].len = sizeof(regs_);
666
667 spi_->transfer_with_cs_assert_polled(xfer, 2);
668 continue;
669 }
670#else
671 sem_.wait();
672#endif
673
674 // lock SPI bus access
675 OSMutexLock locker(&lock_);
676
680
681 // read status flags
682 MCANInterrupt mcan_interrupt;
683 mcan_interrupt.data = register_read(IR);
684
685 // clear status flags for enabled interrupts
686 register_write(IR, mcan_interrupt.data & mcanInterruptEnable_.data);
687
688 // read TCAN status flags
689 uint32_t status = register_read(INTERRUPT_STATUS);
690
691 // clear TCAN status flags
692 register_write(INTERRUPT_STATUS, status);
693#if TCAN4550_DEBUG
694 status_ = status;
695#endif
696 // error handling
697 if (mcan_interrupt.bo || mcan_interrupt.ep || mcan_interrupt.rf0l)
698 {
699 // read protocol status
700 Psr psr;
701 psr.data = register_read(PSR);
702
703 if (mcan_interrupt.rf0l)
704 {
705 // receive overrun
706 ++overrunCount;
707 }
708 if (mcan_interrupt.ep)
709 {
710 if (psr.ep)
711 {
712 // error passive state
713#if TCAN4550_DEBUG
714 testPin_->clr();
715#endif
716 ++softErrorCount;
717 state_ = CAN_STATE_BUS_PASSIVE;
718 }
719 else
720 {
721#if TCAN4550_DEBUG
722 testPin_->set();
723#endif
724 state_ = CAN_STATE_ACTIVE;
725 }
726 }
727 if (mcan_interrupt.bo)
728 {
729 if (psr.bo)
730 {
731 // bus off
732#if TCAN4550_DEBUG
733 testPin_->write(!testPin_->read());
734#endif
735 ++busOffCount;
736 state_ = CAN_STATE_BUS_OFF;
737 // attempt recovery
738 Cccr cccr;
739 do
740 {
741 cccr.data = 0;
742 register_write(CCCR, cccr.data);
743 cccr.data = register_read(CCCR);
744 } while (cccr.init == 1);
745
746 // cancel TX FIFO buffers
747 register_write(TXBCR, TX_FIFO_BUFFERS_MASK);
748
749 txBuf->signal_condition();
750#if TCAN4550_DEBUG
751 testPin_->write(!testPin_->read());
752#endif
753 }
754 else
755 {
756#if TCAN4550_DEBUG
757 testPin_->set();
758#endif
759 state_ = CAN_STATE_ACTIVE;
760 }
761 }
762 }
763
764 // transmission complete
765 if (mcan_interrupt.tc && txCompleteMask_)
766 {
767 {
768 AtomicHolder h(this);
769 // clear pending flag
770 txPending_ = false;
771
772 // signal anyone waiting
773 txBuf->signal_condition();
774 }
775
776 // disable TX buffer tranmission complete interrupt
777 txCompleteMask_ = 0;
778 register_write(TXBTIE, txCompleteMask_);
779 }
780
781 // received timeout
782 if (mcan_interrupt.too && mcanInterruptEnable_.too)
783 {
784 {
785 AtomicHolder h(this);
786 // clear pending flag
787 rxPending_ = false;
788
789 // signal anyone waiting
790 rxBuf->signal_condition();
791 }
792
793 // disable timeout interrupt
794 mcanInterruptEnable_.too = 0;
795 register_write(IE, mcanInterruptEnable_.data);
796 }
797
798 interruptEnable_();
799 }
800
801 return NULL;
802}
See OSMutexLock in os/OS.hxx.
Definition Atomic.hxx:153
DeviceBuffer< struct can_frame > * txBuf
transmit buffer
DeviceBuffer< struct can_frame > * rxBuf
receive buffer
bool select(File *file, int mode) OVERRIDE
Device select method.
void select_insert()
Add client to list of clients needing woken.
const char * name
device name
Definition Devtab.hxx:266
int open(File *, const char *, int, int) OVERRIDE
Open method.
OSMutex lock_
protects internal structures.
Definition Devtab.hxx:588
Class to allow convenient locking and unlocking of mutexes in a C context.
Definition OS.hxx:494
bool is_created()
Definition OS.hxx:90
static int get_priority_max()
Get the maximum thread priority.
Definition OS.hxx:132
void start(const char *name, int priority, size_t stack_size)
Starts the thread.
Definition OS.hxx:78
Specification of CAN driver for the TCAN4550.
Definition MCAN.hxx:54
static constexpr uint32_t TX_FIFO_SIZE
size in elements for the TX FIFO
Definition MCAN.hxx:161
static constexpr uint16_t TX_BUFFERS_MRAM_ADDR
start address of TX BUFFERS in MRAM
Definition MCAN.hxx:173
void disable() override
function to disable device
Definition MCAN.cxx:282
MCANInterrupt mcanInterruptEnable_
shadow for the interrupt enable
Definition MCAN.hxx:1142
bool select(File *file, int mode) override
Device select method.
Definition MCAN.cxx:584
static constexpr uint32_t TX_DEDICATED_BUFFER_COUNT
size in elements for the dedicated TX buffers
Definition MCAN.hxx:158
static constexpr uint16_t RX_FIFO_0_MRAM_ADDR
start address of RX FIFO 0 in MRAM
Definition MCAN.hxx:167
uint32_t register_read(Registers address)
Read from a SPI register.
Definition MCAN.hxx:1036
void init(const char *spi_name, uint32_t freq, uint32_t baud, uint16_t rx_timeout_bits)
Initialize CAN device settings.
Definition MCAN.cxx:89
int spiFd_
SPI bus that accesses TCAN4550.
Definition MCAN.hxx:1139
int ioctl(File *file, unsigned long int key, unsigned long data) override
Request an ioctl transaction.
Definition MCAN.cxx:625
Registers
SPI Registers, word addressing, not byte addressing.
Definition MCAN.hxx:185
@ TXFQS
0xC4 0xC4 TX FIFO/queue status
Definition MCAN.hxx:253
@ RXF0C
0xA0 -— RX FIFO 0 configuration
Definition MCAN.hxx:244
@ NBTP
nominal bit timing and prescaler
Definition MCAN.hxx:208
@ INTERRUPT_STATUS
interrupt and diagnostic flags
Definition MCAN.hxx:196
@ TXBAR
0xD0 0xCC TX buffer add request
Definition MCAN.hxx:256
@ RXF0S
0xA4 0x90 RX FIFO 0 status
Definition MCAN.hxx:245
@ TXESC
0xC8 -— TX buffer element size configuration
Definition MCAN.hxx:254
@ TXEFC
0xF0 -— TX event FIFO configuration
Definition MCAN.hxx:264
@ RXF0A
0xA8 0x94 RX FIFO 0 Acknowledge
Definition MCAN.hxx:246
@ ILE
interrupt line enable
Definition MCAN.hxx:224
@ IE
interrupt enable
Definition MCAN.hxx:222
@ IR
interrupt status
Definition MCAN.hxx:221
@ TXBC
0xC0 0xC0 TX buffer configuration
Definition MCAN.hxx:252
@ INTERRUPT_ENABLE
interrupt and diagnostic flags
Definition MCAN.hxx:199
@ MODE
modes of operation and pin configurations
Definition MCAN.hxx:191
@ CCCR
CC control.
Definition MCAN.hxx:207
@ TXBTIE
0xE0 0xDC TX buffer transmission interrupt enable
Definition MCAN.hxx:260
@ TXBCR
0xD4 0xD0 TX buffer cancellation request
Definition MCAN.hxx:257
@ TSCC
timestamp counter configuration
Definition MCAN.hxx:209
@ MRAM
MRAM offset.
Definition MCAN.hxx:269
@ TOCC
timeout counter configuration
Definition MCAN.hxx:211
static constexpr uint32_t RX_FIFO_SIZE
size in elements for the RX FIFO
Definition MCAN.hxx:152
void txbuf_write(uint16_t offset, MRAMTXBufferMultiWrite *buf, size_t count)
Write one or more TX buffers.
Definition MCAN.hxx:1115
ssize_t write(File *file, const void *buf, size_t count) override
Write to a file or device.
Definition MCAN.cxx:449
static constexpr size_t MRAM_SIZE_WORDS
size in words of the MRAM memory
Definition MCAN.hxx:127
void(* interruptEnable_)()
enable interrupt callback
Definition MCAN.hxx:1137
static constexpr uint16_t TX_EVENT_FIFO_MRAM_ADDR
start address of TX Event FIFO in MRAM
Definition MCAN.hxx:170
void register_write(Registers address, uint32_t data)
Write to a SPI register.
Definition MCAN.hxx:1062
SPI * spi_
pointer to a SPI object instance
Definition MCAN.hxx:1140
ssize_t read(File *file, void *buf, size_t count) override
Read from a file or device.
Definition MCAN.cxx:345
static constexpr uint32_t TX_FIFO_BUFFERS_MASK
mask of all the TX buffers used in the TX FIFO
Definition MCAN.hxx:164
void enable() override
function to enable device
Definition MCAN.cxx:225
uint8_t txPending_
waiting on a TX active event
Definition MCAN.hxx:1149
void rxbuf_read(uint16_t offset, MRAMRXBuffer *buf, size_t count)
Read one or more RX buffers.
Definition MCAN.hxx:1087
static constexpr uint32_t SPI_MAX_SPEED_HZ
maximum SPI clock speed in Hz
Definition MCAN.hxx:124
void flush_buffers() override
Called after disable.
Definition MCAN.cxx:313
MRAMTXBufferMultiWrite txBufferMultiWrite_
Allocating this buffer here avoids having to put it on the TCAN4550Can::write() caller's stack.
Definition MCAN.hxx:1154
uint8_t state_
present bus state
Definition MCAN.hxx:1144
uint8_t rxPending_
waiting on a RX active event
Definition MCAN.hxx:1150
uint32_t txCompleteMask_
shadow for the transmit complete buffer mask
Definition MCAN.hxx:1143
static const TCAN4550Baud BAUD_TABLE[]
baud rate settings table
Definition MCAN.hxx:45
void(* interruptDisable_)()
disable interrupt callback
Definition MCAN.hxx:1138
static constexpr uint32_t TX_EVENT_FIFO_SIZE
size in elements for the TX event FIFO
Definition MCAN.hxx:155
#define CAN_STATE_BUS_OFF
CAN bus off.
#define CAN_STATE_ACTIVE
CAN bus active.
#define SIOCGCANSTATE
Read the CAN state.
uint32_t can_state_t
CAN state type.
#define CAN_STATE_STOPPED
CAN bus stopped.
#define CAN_STATE_BUS_PASSIVE
CAN bus error passive.
#define FWRITE
Workaround for missing header defines on some newlib versions.
Definition fcntl.h:58
#define FREAD
Workaround for missing header defines on some newlib versions.
Definition fcntl.h:53
#define ARRAYSIZE(a)
Returns the number of elements in a statically defined array (of static size)
Definition macros.h:185
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
#define SEC_TO_NSEC(_sec)
Convert a second value to a nanosecond value.
Definition os.h:286
File information.
Definition Devtab.hxx:52
int flags
open flags
Definition Devtab.hxx:63
CC control register definition.
Definition MCAN.hxx:362
uint32_t data
raw word value
Definition MCAN.hxx:371
uint32_t cce
configuration change enable
Definition MCAN.hxx:375
uint32_t init
initialzation
Definition MCAN.hxx:374
MCAN interrupt line enable register definition.
Definition MCAN.hxx:839
uint32_t eint0
enable interrupt line 0
Definition MCAN.hxx:851
uint32_t data
raw word value
Definition MCAN.hxx:848
MCAN interrupt registers (IR, IE, and ILS) definition.
Definition MCAN.hxx:787
uint32_t tc
transmission completed
Definition MCAN.hxx:809
uint32_t too
timeout occurred
Definition MCAN.hxx:819
uint32_t rf0l
RX FIFO 0 message lost.
Definition MCAN.hxx:802
uint32_t ep
error passive
Definition MCAN.hxx:824
uint32_t data
raw word value
Definition MCAN.hxx:796
uint32_t bo
bus-off status
Definition MCAN.hxx:827
RX Buffer structure.
Definition MCAN.hxx:912
uint32_t xtd
extended identifier
Definition MCAN.hxx:915
uint32_t id
CAN identifier.
Definition MCAN.hxx:913
uint32_t esi
error state indicator
Definition MCAN.hxx:916
uint32_t dlc
data length code
Definition MCAN.hxx:919
uint32_t rtr
remote transmission request
Definition MCAN.hxx:914
MRAM SPI message for read/write commands.
Definition MCAN.hxx:891
uint8_t addrL
register address LSB
Definition MCAN.hxx:899
uint8_t length
length in words
Definition MCAN.hxx:898
uint8_t addrH
register address MSB
Definition MCAN.hxx:900
MRAMTXBuffer txBuffers[TX_FIFO_SIZE]
buffer payload
Definition MCAN.hxx:983
TX Buffer structure.
Definition MCAN.hxx:937
uint32_t mm
message marker
Definition MCAN.hxx:949
uint64_t data64
data payload 64-bit
Definition MCAN.hxx:953
uint32_t efc
event FIFO control
Definition MCAN.hxx:948
uint32_t brs
bit rate switch
Definition MCAN.hxx:945
uint32_t id
CAN identifier.
Definition MCAN.hxx:938
uint32_t fdf
FD format.
Definition MCAN.hxx:946
uint32_t dlc
data length code
Definition MCAN.hxx:944
uint32_t esi
error state indicator
Definition MCAN.hxx:941
uint32_t xtd
extended identifier
Definition MCAN.hxx:940
uint32_t rtr
remote transmission request
Definition MCAN.hxx:939
Mode register definition.
Definition MCAN.hxx:286
uint32_t wdEnable
watchdog enable
Definition MCAN.hxx:301
uint32_t sweDis
sleep wake error disable
Definition MCAN.hxx:299
uint32_t data
raw word value
Definition MCAN.hxx:295
uint32_t modeSel
mode of operation select
Definition MCAN.hxx:303
uint32_t clkRef
CLKIN/crystal freq reference.
Definition MCAN.hxx:317
Protocol status register definition.
Definition MCAN.hxx:505
uint32_t data
raw word value
Definition MCAN.hxx:508
uint32_t ep
error passive
Definition MCAN.hxx:513
uint32_t bo
bus-off status
Definition MCAN.hxx:515
RX FIFO x acknowledge register definition.
Definition MCAN.hxx:583
uint32_t fai
RX FIFO acknowledge index.
Definition MCAN.hxx:595
uint32_t data
raw word value
Definition MCAN.hxx:592
RX FIFO x configuraation register definition.
Definition MCAN.hxx:534
uint32_t fsa
RX FIFO start address.
Definition MCAN.hxx:546
uint32_t fs
RX FIFO size.
Definition MCAN.hxx:548
uint32_t data
raw word value
Definition MCAN.hxx:543
RX FIFO x status register definition.
Definition MCAN.hxx:559
uint32_t data
raw word value
Definition MCAN.hxx:562
uint32_t fgi
RX FIFO get index.
Definition MCAN.hxx:568
uint32_t ffl
RX FIFO fill level.
Definition MCAN.hxx:565
Buad rate table entry.
Definition MCAN.hxx:860
Timeout counter configuration register definition.
Definition MCAN.hxx:466
uint32_t etoc
enable timeout counter
Definition MCAN.hxx:478
uint32_t top
timeout period
Definition MCAN.hxx:484
uint32_t data
raw word value
Definition MCAN.hxx:475
uint32_t tos
timeout select
Definition MCAN.hxx:479
Timestamp counter configuration register definition.
Definition MCAN.hxx:429
uint32_t data
raw word value
Definition MCAN.hxx:438
uint32_t tss
timestamp select
Definition MCAN.hxx:441
TX Buffer configuraation register definition.
Definition MCAN.hxx:603
uint32_t tfqs
TX FIFO/queue size.
Definition MCAN.hxx:620
uint32_t data
raw word value
Definition MCAN.hxx:612
uint32_t ndtb
number of dediated transmit buffers
Definition MCAN.hxx:617
uint32_t tbsa
TX buffers start address.
Definition MCAN.hxx:615
TX event FIFO configuration register definition.
Definition MCAN.hxx:672
uint32_t efsa
event FIFO start address
Definition MCAN.hxx:684
uint32_t efwm
event FIFO watermark
Definition MCAN.hxx:689
uint32_t efs
event FIFO size
Definition MCAN.hxx:686
uint32_t data
raw word value
Definition MCAN.hxx:681
TX buffer element size configurataion register definition.
Definition MCAN.hxx:652
uint32_t tbds
TX buffer data field size.
Definition MCAN.hxx:664
uint32_t data
raw word value
Definition MCAN.hxx:661
TX FIFO/queue status register definition.
Definition MCAN.hxx:629
uint32_t tfgi
TX FIFO/queue get index.
Definition MCAN.hxx:638
uint32_t tfqpi
TX FIFO/queue put index.
Definition MCAN.hxx:641
uint32_t data
raw word value
Definition MCAN.hxx:632
uint32_t tffl
TX FIFO free level.
Definition MCAN.hxx:635