#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
--- /dev/null
+#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_
--- /dev/null
+#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;
+
+
+}
+
#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
typedef void (*FNC)(); //function ptr
+
/***********************************************************************
* global variables
***********************************************************************/
***********************************************************************/
int sys_err(){
+
unsigned char i=0;
while(1) {
/***********************************************************************
* Microsecond delay routine
***********************************************************************/
-
+/*
void udelay(long time)
{
volatile long ticks=(time * CCLK) / 2000000;
ticks--;
} while(ticks>0);
}
-
+*/
/***********************************************************************
* Routine for visible LED blinking (on USB transmission)
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;
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;
}
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();
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)
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];
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();
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);
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
***********************************************************************/
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;
/* 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){
}*/
}
+ // 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");
usb_device.ep_events &= ~MASK_EP1TX;
}
}
+ */
//if (usb_can_send && )
#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"