]> rtime.felk.cvut.cz Git - sysless.git/commitdiff
CAN service program added
authorMarek Peca <mp@duch.cz>
Tue, 6 Sep 2005 18:50:00 +0000 (18:50 +0000)
committerMarek Peca <mp@duch.cz>
Tue, 6 Sep 2005 18:50:00 +0000 (18:50 +0000)
Simple transmission and interrupt called reception works, no error handling

darcs-hash:20050906185015-b965f-e047e567c6b98217528d5ec42acbf746b39dc15e.gz

app/arm/can/can.c [new file with mode: 0644]

diff --git a/app/arm/can/can.c b/app/arm/can/can.c
new file mode 100644 (file)
index 0000000..c798837
--- /dev/null
@@ -0,0 +1,153 @@
+#include <stdlib.h>
+#include <types.h>
+#include <lpc21xx.h>
+
+typedef struct _can_msg_t {
+#define CAN_MSG_RTR    0x40000000
+#define CAN_MSG_EXTID  0x80000000
+  uint32_t flags;
+  unsigned short dlc;
+  uint32_t id;
+  unsigned char data[8];
+} can_msg_t;
+
+typedef void (*can_rx_callback)(can_msg_t *msg);
+
+/* public global variables */
+volatile static int can_msg_received = 0;
+volatile static can_msg_t can_rx_msg;
+
+/* private global variables */
+uint32_t *can_rx_msg_data = (uint32_t*)can_rx_msg.data;
+can_rx_callback can_rx_cb;
+
+/* * */
+
+void can_rx_isr(void) __attribute__ ((interrupt));
+
+void can_init(uint32_t btr, unsigned rx_isr_vect, can_rx_callback rx_cb) {
+  /* enable CAN1 Rx pin */
+  PINSEL1 |= 0x00040000;
+  PINSEL1 &= 0xfff7ffff;
+  /* receive all messages, no filtering */
+  AFMR = 0x2;
+  /* reset mode */
+  C1MOD = 0x1;
+  /* -- addition from lpc2000 maillist msg #3052: */
+  C1CMR = 0x0e; //Clear receive buffer, data overrun, abort tx
+  /* -- end of addition */
+  C1IER = 0x0;
+  C1GSR = 0x0;
+  /* set baudrate & timing */
+  C1BTR = btr;
+  /* register Rx handler */
+  //can_rx_cb = rx_cb;
+  /* set interrupt vector */
+  //((uint32_t*)&VICVectAddr0)[rx_isr_vect] = (uint32_t)can_rx_isr;
+  //((uint32_t*)&VICVectCntl0)[rx_isr_vect] = 0x20 | 26;
+  //VICVectAddr0 = (uint32_t)can_rx_isr;
+  VICVectAddr0 = (unsigned)can_rx_isr;
+  VICVectCntl0 = 0x20 | 26;
+  /* enable Rx int */
+  VICIntEnable = 0x04000000;
+  C1IER = 0x1;
+  /* normal (operating) mode */
+  C1MOD = 0x0;
+#if 0
+  /* LPC2119 CAN.5 erratum workaround */
+  C1TFI1 = 0x00000000;
+  C1TID1 = 0x0;
+  C1CMR = 0x23;
+#endif
+}
+
+int can_tx_msg(can_msg_t *tx_msg);
+
+void can_rx_isr(void) {
+  IOCLR0 |= 0x00000080;
+  can_rx_msg.flags = C1RFS;
+  can_rx_msg.dlc = (can_rx_msg.flags>>16) & 0x7;
+  can_rx_msg.id = C1RID;
+  can_rx_msg_data[0] = C1RDA;
+  can_rx_msg_data[1] = C1RDB;
+  can_msg_received = 1;
+  if (can_rx_cb != NULL)
+    can_rx_cb(&can_rx_msg);
+
+  /*DBG*/can_tx_msg(&can_rx_msg);
+
+  /* release Rx buffer */
+  C1CMR = 0x4;
+  /* int acknowledge */
+  VICVectAddr = 0;
+}
+
+int can_tx_msg(can_msg_t *tx_msg) {
+  uint32_t *data = (uint32_t*)tx_msg->data;
+
+  /* check, if buffer is ready (previous Tx completed) */
+  if ((C1SR & 0x4) == 0)
+    return -1; /* busy */
+  C1TFI1 = (tx_msg->flags & 0xc0000000) |
+    ((tx_msg->dlc<<16) & 0x000f0000);
+  C1TID1 = tx_msg->id;
+  C1TDA1 = data[0];
+  C1TDB1 = data[1];
+  /* start transmission */
+  C1CMR = 0x21; //0x21; //0x30; //0x20;
+  return 0; /* OK */
+}
+
+/* * * * */
+
+void DefaultISR (void) __attribute__ ((interrupt)); 
+
+void DefaultISR(void) {
+  IOCLR0 |= 0x00000080;
+  while (1)
+    { // We should never get here, if we do it is an error
+    }
+}
+
+int main() {
+  can_msg_t msg;
+
+  /*DBG*/IODIR0 |= 0x00000080;
+  IOSET0 |= 0x00000080;
+  //IOCLR0 |= 0x00000080;
+
+  /* peripheral clock = CPU clock (10MHz) */
+  VPBDIV = 1;
+
+  MEMMAP = 0x2;
+
+  // --- cizi moudra
+  // Init Vector Interrupt Controller
+  VICIntEnClr = 0xFFFFFFFFL; // Disable all Ints
+  VICIntSelect = 0x00000000L;
+
+  // Install Default IRQVec
+  VICDefVectAddr = (uint32_t)DefaultISR; // set interrupt vector
+  // ---------------
+  
+  msg.flags = 0;
+  msg.dlc = 4;
+  msg.id = 0x123;
+  msg.data[0] = 'A';
+  msg.data[1] = 'h';
+  msg.data[2] = 'o';
+  msg.data[3] = 'j';
+
+  can_init(0x25c013, 0, NULL);
+
+  while (can_tx_msg(&msg));
+
+  for (;;)
+    if (can_msg_received) {
+      if (can_rx_msg.id == 3)
+       while(can_tx_msg(&msg));
+      can_msg_received = 0;
+    }
+
+  return(0);
+}