first version, only transmitting CAN messages without usage of queue system from...
authorJiri Vanek <vanekjir@fel.cvut.cz>
Mon, 19 Dec 2011 12:41:08 +0000 (13:41 +0100)
committerJiri Vanek <vanekjir@fel.cvut.cz>
Mon, 19 Dec 2011 12:41:08 +0000 (13:41 +0100)
embedded/app/usbcan/Makefile.omk
embedded/app/usbcan/can/lpc17xx_can.h [new file with mode: 0644]
embedded/app/usbcan/lpc17xx_can.c [new file with mode: 0644]
embedded/app/usbcan/main.c
embedded/app/usbcan/usb_vend.c

index 5b17aa8..588f007 100644 (file)
@@ -19,13 +19,14 @@ INCLUDES += -I.
 #include_HEADERS  = ul_idstr.h
 
 bin_PROGRAMS = usbcan
-usbcan_SOURCES = main.c can_queue.c sja1000p.c can_quesysless.c devcommon.c setup.c finish.c usb_vend.c
-usbcan_SOURCES += can_lpcbusemu.c ul_usb1.c
+usbcan_SOURCES = main.c can_queue.c sja1000p.c  devcommon.c setup.c finish.c usb_vend.c can_quesysless.c lpc17xx_can.c
+#usbcan_SOURCES += can_lpcbusemu.c ul_usb1.c
 
 #usbtest_SOURCES +=  ul_idstr.c
 #lib_LOADLIBES =  bspbase ul_drv lpciap keyval lpciap_kvpb mach_hal uldy
 lib_LOADLIBES =  bspbase usbbase usbmore lpcusb mach_hal
-usbcan_MOREOBJS = $(USER_LIB_DIR)/system_stub.o $(USER_LIB_DIR)/ivt.o
+usbcan_MOREOBJS = $(USER_LIB_DIR)/system_stub.o
+# $(USER_LIB_DIR)/ivt.o
 nobase_include_HEADERS = usb/usb_defs.h
 
 link_VARIANTS = app boot
diff --git a/embedded/app/usbcan/can/lpc17xx_can.h b/embedded/app/usbcan/can/lpc17xx_can.h
new file mode 100644 (file)
index 0000000..1b66997
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef LPC17XX_CAN_H_
+#define LPC17XX_CAN_H_
+
+#include "LPC17xx.h"
+#include "hal_machperiph.h"
+#include "cpu_def.h"
+#include "system_def.h"
+#include "can/canmsg.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#define CAN1_REGS_BASE 0x40044000UL
+#define CAN2_REGS_BASE 0x40048000UL
+
+#define CAN_MOD_o              0x0000
+#define CAN_CMR_o              0x0004
+#define CAN_GSR_o              0x0008
+#define CAN_ICR_o              0x000C
+#define CAN_IER_o              0x0010
+#define CAN_BTR_o              0x0014
+#define CAN_EWL_o              0x0018
+#define CAN_SR_o               0x001C
+#define CAN_RFS_o              0x0020
+#define CAN_RID_o              0x0024
+#define CAN_RDA_o              0x0028
+#define CAN_RDB_o              0x002C
+#define CAN_TFI1_o             0x0030
+#define CAN_TID1_o             0x0034
+#define CAN_TDA1_o             0x0038
+#define CAN_TDB1_o             0x003C
+#define CAN_TFI2_o             0x0040
+#define CAN_TID2_o             0x0044
+#define CAN_TDA2_o             0x0048
+#define CAN_TDB2_o             0x004C
+#define CAN_TFI3_o             0x0050
+#define CAN_TID3_o             0x0054
+#define CAN_TDA3_o             0x0058
+#define CAN_TDB3_o             0x005C
+
+//----------------------------------
+
+#define CAN1MOD                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_MOD_o))
+#define CAN1CMR                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_CMR_o))
+#define CAN1GSR                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_GSR_o))
+#define CAN1ICR                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_ICR_o))
+#define CAN1IER                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_IER_o))
+#define CAN1BTR                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_BTR_o))
+#define CAN1EWL                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_EWL_o))
+#define CAN1SR                 (*(uint32_t*)(CAN1_REGS_BASE+CAN_SR_o))
+#define CAN1RFS                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_RFS_o))
+#define CAN1RID                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_RID_o))
+#define CAN1RDA                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_RDA_o))
+#define CAN1RDB                        (*(uint32_t*)(CAN1_REGS_BASE+CAN_RDB_o))
+#define CAN1TFI1               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TFI1_o))
+#define CAN1TID1               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TID1_o))
+#define CAN1TDA1               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDA1_o))
+#define CAN1TDB1               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDB1_o))
+#define CAN1TFI2               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TFI2_o))
+#define CAN1TID2               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TID2_o))
+#define CAN1TDA2               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDA2_o))
+#define CAN1TDB2               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDB2_o))
+#define CAN1TFI3               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TFI3_o))
+#define CAN1TID3               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TID3_o))
+#define CAN1TDA3               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDA3_o))
+#define CAN1TDB3               (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDB3_o))
+
+
+//----------------------------------
+
+#define PCONP SC->PCONP
+#define PCLKSEL0 SC->PCLKSEL0 
+
+#define PINSEL0 PINCON->PINSEL0
+#define PINMODE0 PINCON->PINMODE0
+#define PINMODE_OD0 PINCON->PINMODE_OD0
+
+#define PCCAN1 (1<<13) // CAN Controller 1 power/clock control bit. 
+#define PCCAN2 (1<<14) // CAN Controller 2 power/clock control bit. 
+
+#define PCLK_CAN1_MASK ((1<<27)|(1<<26)) 
+#define PCLK_CAN2_MASK ((1<<29)|(1<<28)) 
+#define PCLK_ACF_MASK  ((1<<31)|(1<<30))
+
+#define CAN1_RX_MASK   ((1<<1)|(1<<0))
+#define CAN1_TX_MASK   ((1<<3)|(1<<2))
+
+// CAN1_RX_BIT a CAN1_TX_BIT jiz definovany v system_def.h
+
+
+void CAN_init(uint32_t baudrate);
+void CAN_send(canmsg_t* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LPC17XX_CAN_H_ 
diff --git a/embedded/app/usbcan/lpc17xx_can.c b/embedded/app/usbcan/lpc17xx_can.c
new file mode 100644 (file)
index 0000000..eee3718
--- /dev/null
@@ -0,0 +1,211 @@
+#include "can/lpc17xx_can.h"
+
+static void CAN_configPin();
+static void CAN_setBusTiming(uint32_t baudrate);
+
+//------------------------------------------
+
+static void CAN_configPin(){
+
+//     CAN1 - select P0.0 as RD1. P0.1 as TD1
+
+       uint32_t pinsel0;
+       uint32_t pinmode0;
+       uint32_t pinmode_od0;
+       uint8_t pinsel0_val = 1;
+       uint8_t pinmode0_val = 0;
+       uint8_t pinmode_od0_val = 0;
+
+
+       pinsel0 = PINSEL0;
+       pinsel0 &= ~CAN1_RX_MASK;
+       pinsel0 &= ~CAN1_TX_MASK;
+       pinsel0 |= __val2mfld(CAN1_RX_MASK, pinsel0_val);
+       pinsel0 |= __val2mfld(CAN1_TX_MASK, pinsel0_val);
+       PINSEL0 = pinsel0;
+
+       pinmode0 = PINMODE0;
+       pinmode0 &= ~CAN1_RX_MASK;
+       pinmode0 &= ~CAN1_TX_MASK;
+       pinmode0 |= __val2mfld(CAN1_RX_MASK, pinmode0_val);
+       pinmode0 |= __val2mfld(CAN1_TX_MASK, pinmode0_val);
+       PINMODE0 = pinmode0;
+
+       pinmode_od0 = PINMODE_OD0;
+       if (pinmode_od0_val){
+               pinmode_od0 |= CAN1_RX_BIT;
+               pinmode_od0 |= CAN1_TX_BIT;
+       }
+       else{
+               pinmode_od0 &= ~CAN1_RX_BIT;
+               pinmode_od0 &= ~CAN1_TX_BIT;
+       }
+       PINMODE_OD0 = pinmode_od0;
+       
+
+}
+
+void CAN_send(canmsg_t* msg){
+
+       uint32_t data;
+       uint32_t i;
+
+       // check status of TB1
+       while (!(CAN1SR & (1<<2))){}
+       
+       CAN1TFI1 &= ~0x000F0000;
+       CAN1TFI1 |= (msg->length)<<16;
+
+       // EXT frame
+       if(msg->flags & MSG_EXT)
+               CAN1TFI1 |= (1<<31);
+       else
+               CAN1TFI1 &= ~(1<<31);
+               
+       // RTR frame
+       if(msg->flags & MSG_RTR)
+               CAN1TFI1 |= (1<<30);
+       else
+               CAN1TFI1 &= ~(1<<30);
+
+       // write CAN ID
+       CAN1TID1 = msg->id;
+
+       // write first 4 data bytes
+
+       data=0;
+       for(i=0; i<4; i++)
+               data |= (msg->data[i])<<(i*8);
+
+       CAN1TDA1 = data;
+
+       // write second 4 data bytes
+
+       data=0;
+       for(i=4; i<8; i++)
+               data |= (msg->data[i])<<((i-4)*8);
+               CAN1TDB1 = data;
+
+       // write transmission request
+       CAN1CMR = 0x21;
+
+}
+
+void CAN_setBusTiming(uint32_t baudrate){
+
+       uint32_t PCLK_CAN;
+       uint32_t res;
+
+       uint8_t tq_numb; // number of time quantum
+       uint8_t TSEG1, TSEG2;
+       uint8_t BRP;
+       uint8_t SJW;
+       uint8_t SAM;
+       uint8_t div;
+
+       // 0 = the bus is sampled once
+       SAM = 0;
+
+       // the Synchronization Jump Width (this value plus one) 
+       SJW = 3;
+
+       // get clock divide for CAN1    
+       div = __mfld2val(PCLK_CAN1_MASK, PCLKSEL0);
+       switch(div){
+               case 0:
+                       div = 4;
+                       break;
+               case 1:
+                       div = 1;
+                       break;
+               case 2:
+                       div = 2;
+                       break;
+               case 3:
+                       // only for CAN, for other peripherials '11' value means div=8
+                       div = 6;
+                       break;
+       }
+
+
+       PCLK_CAN = system_frequency / div;
+
+       res = PCLK_CAN / baudrate;
+
+
+       // calculation of tq_numb - number of time quantum (must be in <8,25>)
+       // tq_numb = TSEG1 + TSEG2 + 3
+
+       for(tq_numb=25; tq_numb>=8; tq_numb--){
+               
+               if ((res%tq_numb)==0){
+               
+                       // Baud Rate Prescaler. The PCLK clock is divided by (this value plus one) to produce the CAN clock.
+                       BRP = (res / tq_numb) - 1;
+
+                       // sync. segment allways 1 tq
+                       tq_numb--;
+
+                       // number of tq from the sample point to the next nominal Sync. point (this value plus one)                     
+                       TSEG2 = (tq_numb/3) - 1;
+
+                       // number of tq from Sync. point to the sample point (this value plus one)                      
+                       TSEG1 = tq_numb - (tq_numb/3) - 1;
+
+                       break;
+               }
+       }
+
+       CAN1BTR = ((SAM<<23)|(TSEG2<<20)|(TSEG1<<16)|(SJW<<14)|(BRP<<0));
+
+}
+
+void CAN_init(uint32_t baudrate)
+{
+       uint32_t tmp;
+       uint32_t pclksel0;
+       uint32_t val;
+       
+
+       // configure CAN1 pins 
+       CAN_configPin();
+
+       // turn on power and clock for CAN1 
+       PCONP |= PCCAN1;
+       
+       // set clock divide for CAN1 
+
+       val = 0x00; // 00       PCLK_peripheral = CCLK/4 
+       pclksel0 = PCLKSEL0;
+       pclksel0 &= ~PCLK_CAN1_MASK;
+       pclksel0 &= ~PCLK_CAN2_MASK;
+       pclksel0 &= ~PCLK_ACF_MASK;
+       pclksel0 |= __val2mfld(PCLK_CAN1_MASK, val);
+       pclksel0 |= __val2mfld(PCLK_CAN2_MASK, val);
+       pclksel0 |= __val2mfld(PCLK_ACF_MASK, val);
+       PCLKSEL0 = pclksel0;
+       
+       // enter reset mode
+       CAN1MOD = 1;
+
+       // disable all CAN interrupts
+       CAN1IER = 0;
+
+       // reset value of Global Status Register (global controller status and error counters) 
+       CAN1GSR = 0x3C;
+
+       // request command to release Rx, Tx buffer and clear data overrun 
+       CAN1CMR = (1<<1)|(1<<2)|(1<<3);
+
+       // read to clear interrupt pending in Interrupt Capture Register 
+       tmp = CAN1ICR;
+
+       // set bus timing 
+       CAN_setBusTiming(baudrate);
+
+       // return to normal operating 
+       CAN1MOD = 0;
+
+       
+}
+
index 86d98ab..4b91631 100644 (file)
 #include "./can/modparms.h"
 #include "./can/devcommon.h"
 
-#include "./can/ul_usb1.h"
+//#include "./can/ul_usb1.h"
+
 //#include "./can/setup.h"
 
 #include "./usb/usb_defs.h"
 #include "./usb/usb_vend.h"
 
+// DEBUG CAN
+#include "can/lpc17xx_can.h"
+// DEBUG CAN - end
+
 #define MASK_EP1RX  0x01
 #define MASK_EP1TX  0x02
 
@@ -101,6 +106,7 @@ LT_TIMER_IMP(lt_2sec)
 
 typedef void (*FNC)(); //function ptr
 
+
 /***********************************************************************
  * global variables
  ***********************************************************************/
@@ -135,6 +141,7 @@ extern int register_obj_struct(struct msgobj_t *obj, int minorbase);
  ***********************************************************************/
 
 int sys_err(){
+  
   unsigned char i=0;
 
   while(1) {
@@ -155,7 +162,7 @@ int sys_err(){
 /***********************************************************************
  * Microsecond delay routine
  ***********************************************************************/
-
+/*
 void udelay(long time)
 {
   volatile long ticks=(time * CCLK) / 2000000;
@@ -163,7 +170,7 @@ void udelay(long time)
     ticks--;
   } while(ticks>0);
 }
-
+*/
 
 /***********************************************************************
  * Routine for visible LED blinking (on USB transmission)
@@ -175,6 +182,7 @@ void timer_10ms(void)
   else SET_OUT_PIN(LED_PORT,LED1_BIT);
   if (timer_rx_off!=0) timer_rx_off--;
   else SET_OUT_PIN(LED_PORT,LED2_BIT);
+
 /*  if (timer_configured!=0) timer_configured--;
   else {
     timer_configured=20;
@@ -203,27 +211,42 @@ int main(void)
        int i,size,m=0;
 
        CANMSG("Starting USBCAN module firmware...\n");
+       
 
 //     volatile int i=0;
        bootloader_run=0;
        /***********************************/
+
        lt_10msec_init();
        lt_100msec_init();
        lt_2sec_init();
 
-       SET_OUT_PIN(LED_PORT,LED_ERR);
-       CLR_OUT_PIN(LED_PORT,LED_GP);
+       // DEBUG
+       //SET_OUT_PIN(LED_PORT,LED_ERR);
+       //CLR_OUT_PIN(LED_PORT,LED_GP);
 
        if (USB_MAX_PACKET<16){
                CANMSG("Maximum packet size less than 16B (is %dB)\n",USB_MAX_PACKET);
                sys_err();
        }
 
-       /***********************************************************************
-        * CAN device initialization - device side (adapted from LinCAN setup.c)
-        ***********************************************************************/
+// !!! DEBUG - first version, only transmitting CAN messages withnout usage of queue system from LinCAN
+
+       // CAN
+       CAN_init(1000000);
+       // CAN end
+
+/*
+
+       //***********************************************************************
+       // * CAN device initialization - device side (adapted from LinCAN setup.c)
+       // ***********************************************************************
+
+       // DEBUG
+       //can_init(); // only for successful compiling (defined in can_lpcbusemu.c)
+       
+
 
-       can_init();
 
        DEBUGMSG("Initiating CAN device initialization\n");
        baudrate[0]=1000;
@@ -251,17 +274,19 @@ int main(void)
        }
        memset(candev->hwspecops, 0, sizeof(struct hwspecops_t));
 
-       ul_usb1_register(candev->hwspecops);
+       // DEBUG
+       //ul_usb1_register(candev->hwspecops);  // only for successful compiling (defined in ul_usb1.c)
+       
 
        bd=baudrate[0];
        if (candev->hwspecops->init_hw_data(candev)){
                CANMSG("HW data could not be initialized\n");
                sys_err();
        }
-       /* Alocate and initialize the chip structures */
+       // Alocate and initialize the chip structures
        for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) {
-/*             if(chipnr<irqnum)
-                       irqsig=irq[*irq_param_idx_p+chipnr];*/
+//             if(chipnr<irqnum)
+//                     irqsig=irq[*irq_param_idx_p+chipnr];
                if (init_chip_struct(candev, chipnr, 0, bd*1000)){
                        CANMSG("Chip structure could not be initialized\n");
                        sys_err();
@@ -295,10 +320,10 @@ int main(void)
                chip->flags |= CHIP_ATTACHED;
 
 // Interrupts from chip are served in main cycle
-/*             if(can_chip_setup_irq(chip)<0) {
+//             if(can_chip_setup_irq(chip)<0) {
 //                     CANMSG("Error to setup chip IRQ\n");
-                       sys_err();
-               }*/
+//                     sys_err();
+//             }
        }
 
        if (candev->flags & CANDEV_PROGRAMMABLE_IRQ)
@@ -307,9 +332,9 @@ int main(void)
                        sys_err();
                }
 
-       /***********************************************************************
-        * CAN device initialization - client side (adapted from LinCAN open.c)
-        ***********************************************************************/
+       //***********************************************************************
+       // * CAN device initialization - client side (adapted from LinCAN open.c)
+       // ***********************************************************************
 
        chip=candev->chip[0];
        obj=chip->msgobj[0];
@@ -327,7 +352,7 @@ int main(void)
                if (chip->chipspecops->pre_read_config(chip,obj)<0)
                        CANMSG("Error initializing chip for receiving\n");
 
-       } /* End of chip configuration */
+       } // End of chip configuration
 
        canuser = (struct canuser_t *)malloc(sizeof(struct canuser_t));
        if(canuser == NULL) sys_err();
@@ -342,7 +367,7 @@ int main(void)
        canqueue_ends_init_kern(qends);
        canuser->qends = qends;
 
-       /*required to synchronize with RT-Linux context*/
+       //required to synchronize with RT-Linux context
        can_spin_lock_irqsave(&canuser_manipulation_lock, iflags);
        list_add(&canuser->peers, &obj->obj_users);
        can_spin_unlock_irqrestore(&canuser_manipulation_lock, iflags);
@@ -352,10 +377,11 @@ int main(void)
 
        if(canqueue_connect_edge(canuser->rx_edge0=canque_new_edge_kern(MAX_BUF_LENGTH),
                obj->qends, canuser->qends)<0) sys_err();
-       /*FIXME: more generic model should be used there*/
+       //FIXME: more generic model should be used there
        canque_edge_decref(canuser->rx_edge0);
        canque_edge_decref(edge);
 
+*/
 
        /***********************************************************************
         * USB Init
@@ -389,16 +415,24 @@ int main(void)
         ***********************************************************************/
 
        timer_rx_off=timer_tx_off=timer_str=timer_configured=0;
+
+
+       printf("Main loop\n");
+
        while (1) {
 
                usb_check_events(&usb_device);
                usb_control_response(&usb_device);
 
-               if (!(IO0PIN&P0_SJA1000_INT_PIN)) //INT PIN is inverted
-                       chip->chipspecops->irq_handler(0,chip);
+// DEBUG
+//             if (!(IO0PIN&P0_SJA1000_INT_PIN)) //INT PIN is inverted
+//                     chip->chipspecops->irq_handler(0,chip);
 
                if (usb_device.ep_events & MASK_EP1RX) {  //EP1RX - data waiting to receive
-                       if (canque_get_inslot(qends, &qedge, &slot, 0)>=0){ //Free slot obtained
+                       
+                       // DEBUG - unused queue system (yet)
+                       //if (canque_get_inslot(qends, &qedge, &slot, 0)>=0){ //Free slot obtained
+
                                size=usb_udev_read_endpoint(&eps[0],ep1_rx_buff,16);
                                if (size==16){
                                        uint16_t msgflags;
@@ -425,15 +459,23 @@ int main(void)
                                        /* Automatic selection of extended format if ID>2047 */
                                        if (canmsg.id & ~0x7ffl & MSG_ID_MASK ) canmsg.flags |= MSG_EXT;
                                        /* has been dependent on "extended" option */
-                                       slot->msg=canmsg;
-                                       canque_put_inslot(qends, qedge, slot);
+
+                                       // DEBUG - unused queue system (yet)                            
+                                       //slot->msg=canmsg;
+                                       //canque_put_inslot(qends, qedge, slot);
+                                       CAN_send(&canmsg);
                                }
-                               else
-                                       canque_abort_inslot(qends,qedge,slot);
+
+                               // DEBUG - unused queue system (yet)
+                               //else
+                               //      canque_abort_inslot(qends,qedge,slot);
+
                                timer_rx_off=50;        //rosviceni diody pri prijmu
                                CLR_OUT_PIN(LED_PORT,LED2_BIT);
                                usb_device.ep_events &= ~MASK_EP1RX;
-                       }
+                       
+                       // DEBUG                        
+                       //}
 
 
 /*                     if (size==2){
@@ -454,6 +496,8 @@ int main(void)
                        }*/
                }
 
+               // DEBUG - only transmitting CAN messages, no reading (yet)
+               /*
                if(usb_device.ep_events & MASK_EP1TX){ //EP1TX - data transmitted
                        if(canque_test_outslot(qends, &qedge, &slot)>=0){
                                DEBUGMSG("CAN message ready to send over usb\n");
@@ -486,6 +530,7 @@ int main(void)
                                usb_device.ep_events &= ~MASK_EP1TX;
                        }
                }
+               */
 
                //if (usb_can_send && )
 
index 7ab1b95..29cea43 100644 (file)
@@ -2,7 +2,7 @@
 
 #include <stdio.h>
 #include <system_def.h>
-#include <hal_intr.h>
+//#include <hal_intr.h>
 #include "./can/can.h"
 #include "./can/can_sysdep.h"
 #include "./can/main.h"