From: Jiri Vanek Date: Mon, 19 Dec 2011 12:41:08 +0000 (+0100) Subject: first version, only transmitting CAN messages without usage of queue system from... X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/ad1d46af5c8562e90a3f8564cf511213ff1f1745 first version, only transmitting CAN messages without usage of queue system from LinCAN --- diff --git a/embedded/app/usbcan/Makefile.omk b/embedded/app/usbcan/Makefile.omk index 5b17aa8..588f007 100644 --- a/embedded/app/usbcan/Makefile.omk +++ b/embedded/app/usbcan/Makefile.omk @@ -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 index 0000000..1b66997 --- /dev/null +++ b/embedded/app/usbcan/can/lpc17xx_can.h @@ -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 index 0000000..eee3718 --- /dev/null +++ b/embedded/app/usbcan/lpc17xx_can.c @@ -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; + + +} + diff --git a/embedded/app/usbcan/main.c b/embedded/app/usbcan/main.c index 86d98ab..4b91631 100644 --- a/embedded/app/usbcan/main.c +++ b/embedded/app/usbcan/main.c @@ -60,12 +60,17 @@ #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(chipnrflags |= 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 && ) diff --git a/embedded/app/usbcan/usb_vend.c b/embedded/app/usbcan/usb_vend.c index 7ab1b95..29cea43 100644 --- a/embedded/app/usbcan/usb_vend.c +++ b/embedded/app/usbcan/usb_vend.c @@ -2,7 +2,7 @@ #include #include -#include +//#include #include "./can/can.h" #include "./can/can_sysdep.h" #include "./can/main.h"