Fix CAN sending

It now works reliably with multiple mailboxes in a way which agrees with
how the TRM says it should work.

Change-Id: I3522dc9a1a1bb24a7ca57307d8c421968746a5de
diff --git a/motors/peripheral/can.c b/motors/peripheral/can.c
index 0e731e2..9db9f8f 100644
--- a/motors/peripheral/can.c
+++ b/motors/peripheral/can.c
@@ -27,11 +27,7 @@
 
 // TODO(Brian): Do something about CAN errors and warnings (enable interrupts?).
 
-// Flags for the interrupt to process which don't actually come from the
-// hardware. Currently, only used for tx buffers.
-static volatile uint32_t can_manual_flags = 0;
-
-void can_init(void) {
+void can_init() {
   printf("can_init\n");
 
   SIM_SCGC6 |= SIM_SCGC6_FLEXCAN0;
@@ -84,13 +80,8 @@
                /* such a fast peripheral clock, this has lots of margin. */ |
                CAN_CTRL2_EACEN /* Match on IDE and RTR. */;
 
-  // Enable interrupts for the RX mailbox.
-  CAN0_IMASK1 = 1 << 1;
-
   // Now take it out of freeze mode.
   CAN0_MCR &= ~CAN_MCR_HALT;
-
-  //NVIC_ENABLE_IRQ(IRQ_CAN_MESSAGE);
 }
 
 static void can_vesc_process_rx(volatile CanMessageBuffer *buffer,
@@ -138,18 +129,21 @@
   (void)prio_id;
 }
 
-int can_send(uint32_t can_id, const unsigned char *data, unsigned int length) {
-  volatile CanMessageBuffer *const message_buffer = &CAN0_MESSAGES[0];
+int can_send(uint32_t can_id, const unsigned char *data, unsigned int length,
+             unsigned int mailbox) {
+  volatile CanMessageBuffer *const message_buffer = &CAN0_MESSAGES[mailbox];
 
-  if (CAN_MB_CONTROL_EXTRACT_CODE(message_buffer->control_timestamp) ==
-      CAN_MB_CODE_TX_DATA) {
-    return -1;
-  }
+  // Just inactivate the mailbox to start with. Checking if it's done being
+  // transmitted doesn't seem to work like the reference manual describes, so
+  // just take the brute force approach.
+  message_buffer->control_timestamp =
+      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_INACTIVE);
 
   // Yes, it might actually matter that we clear the interrupt flag before
   // doing stuff...
-  CAN0_IFLAG1 = 1 << (message_buffer - CAN0_MESSAGES);
-  message_buffer->prio_id = can_id;
+  CAN0_IFLAG1 = 1 << mailbox;
+
+  message_buffer->prio_id = (can_id << 18);
   // Copy only the bytes from data that we're supposed to onto the stack, and
   // then move it into the message buffer 32 bits at a time (because it might
   // get unhappy about writing individual bytes). Plus, we have to byte-swap
@@ -164,9 +158,10 @@
     message_buffer->data[0] = __builtin_bswap32(data_words[0]);
     message_buffer->data[1] = __builtin_bswap32(data_words[1]);
   }
+  // TODO(Brian): Set IDE and SRR for extended frames.
   message_buffer->control_timestamp =
-      CAN_MB_CONTROL_INSERT_DLC(length) | CAN_MB_CONTROL_SRR |
-      CAN_MB_CONTROL_IDE | CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_DATA);
+      CAN_MB_CONTROL_INSERT_DLC(length) |
+      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_DATA);
   return 0;
 }
 
diff --git a/motors/peripheral/can.h b/motors/peripheral/can.h
index acd6cce..1bdf6e8 100644
--- a/motors/peripheral/can.h
+++ b/motors/peripheral/can.h
@@ -12,7 +12,9 @@
 
 void can_init(void);
 
-int can_send(uint32_t can_id, const unsigned char *data, unsigned int length);
+// Mailbox is 2 or 3 for the two send mailboxes.
+int can_send(uint32_t can_id, const unsigned char *data, unsigned int length,
+             unsigned int mailbox);
 
 // Sets *length to -1 if there isn't a new piece of data to receive.
 void can_receive_command(unsigned char *data, int *length);