#define CAN1_REGS_BASE 0x40044000UL
#define CAN2_REGS_BASE 0x40048000UL
+#define CANAF_REGS_BASE 0x4003C000UL
#define CAN_MOD_o 0x0000
#define CAN_CMR_o 0x0004
#define CAN_TDA3_o 0x0058
#define CAN_TDB3_o 0x005C
+
+#define CANAF_AFMR_o 0x0000
+#define CANAF_SFF_sa_o 0x0004
+#define CANAF_SFF_GRP_sa_o 0x0008
+#define CANAF_EFF_sa_o 0x000C
+#define CANAF_EFF_GRP_sa_o 0x0010
+#define CANAF_ENDofTable_o 0x0014
+#define CANAF_LUTerrAd_o 0x0018
+#define CANAF_LUTerr_o 0x001C
+
//----------------------------------
#define CAN1MOD (*(uint32_t*)(CAN1_REGS_BASE+CAN_MOD_o))
#define CAN1TDB3 (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDB3_o))
+
+#define CANAF_AFMR (*(uint32_t*)(CANAF_REGS_BASE+CANAF_AFMR_o))
+#define CANAF_SFF_sa (*(uint32_t*)(CANAF_REGS_BASE+CANAF_SFF_sa_o))
+#define CANAF_SFF_GRP_sa (*(uint32_t*)(CANAF_REGS_BASE+CANAF_SFF_GRP_sa_o))
+#define CANAF_EFF_sa (*(uint32_t*)(CANAF_REGS_BASE+CANAF_EFF_sa_o))
+#define CANAF_EFF_GRP_sa (*(uint32_t*)(CANAF_REGS_BASE+CANAF_EFF_GRP_sa_o))
+#define CANAF_ENDofTable (*(uint32_t*)(CANAF_REGS_BASE+CANAF_ENDofTable_o))
+#define CANAF_LUTerrAd (*(uint32_t*)(CANAF_REGS_BASE+CANAF_LUTerrAd_o))
+#define CANAF_LUTerr (*(uint32_t*)(CANAF_REGS_BASE+CANAF_LUTerr_o))
+
//----------------------------------
+//CAN Global Status Register
+#define CAN_GSR_BS (1<<7)
+
//CAN Interrupt and Capture Register bits
+#define CAN_ICR_RI (1<<0)
#define CAN_ICR_TI1 (1<<1)
+#define CAN_ICR_DOI (1<<3)
+#define CAN_ICR_IDI (1<<8)
//CAN Status Register bits
+#define CAN_SR_RBS (1<<0)
+#define CAN_SR_DOS (1<<1)
#define CAN_SR_TBS1 (1<<2)
//CAN Command Register bits
#define CAN_TFI1_RTR (1<<30)
#define CAN_TFI1_EXT (1<<31)
+//CAN Receive Frame Status register
+#define CAN_RFS_RTR (1<<30)
+#define CAN_RFS_EXT (1<<31)
+
//CAN Interrupt Enable Register bits
+#define CAN_IER_RIE (1<<0)
#define CAN_IER_TIE1 (1<<1)
+#define CAN_IER_DOIE (1<<3)
+#define CAN_IER_IDIE (1<<8)
+
//----------------------------------
void CAN_init(uint32_t baudrate);
void CAN_send(canmsg_t* msg);
+void CAN_recv(canmsg_t* msg);
void CAN_IRQHandler(void);
//----------------------------------
int lpc17xx_register(struct chipspecops_t *chipspecops);
int lpc17xx_attach_to_chip(struct canchip_t *chip);
int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj);
+void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj);
#ifdef __cplusplus
}
extern struct canhardware_t *hardware_p;
+extern volatile uint32_t cnt;
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
// interrupt handler
-// now only for transmitting - irq when one message was transmitted (for check if another message is pending in can msg queue)
+// for transmitting - irq when one message was transmitted (for check if another message is pending in can msg queue)
+// for receiving - irq when message was received and is available in Receive buffer
void CAN_IRQHandler(){
uint32_t i;
-
+
i = CAN1ICR;
- if(!(i & CAN_ICR_TI1))
- return;
+
+ if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){
+
+ struct canchip_t *chip;
+ chip = hardware_p->candevice[0]->chip[0];
- struct canchip_t *chip;
- chip = hardware_p->candevice[0]->chip[0];
-
- lpc17xx_irq_handler(0, chip);
+ lpc17xx_irq_handler(0, chip);
+ }
+ if(i & CAN_ICR_DOI){
+ printf("Data overrun\n");
+ CAN1CMR = CAN_CMR_CDO;
+ }
+
+
+
}
-
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
struct msgobj_t *obj;
obj = chip->msgobj[0];
-
+
+ if(CAN1SR & CAN_SR_RBS) {
+ lpc17xx_read(chip,obj);
+ obj->ret = 0;
+ }
+
+
if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) {
can_msgobj_set_fl(obj,TX_REQUEST);
}
}
+
return CANCHIP_IRQ_HANDLED;
}
}
+void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) {
+
+
+ CAN_recv(&obj->rx_msg);
+
+ // fill CAN message timestamp
+ can_filltimestamp(&obj->rx_msg.timestamp);
+
+ canque_filter_msg2edges(obj->qends, &obj->rx_msg);
+
+ // release Receive buffer
+ CAN1CMR = CAN_CMR_RRB;
+
+}
+
int lpc17xx_fill_chipspecops(struct canchip_t *chip){
chip->max_objects=1;
}
+void CAN_recv(canmsg_t* msg){
+
+/*
+ msg->id = ++cnt;
+ msg->data[0] = 0xAA;
+ msg->data[1] = 0xBB;
+ msg->length = 2;
+*/
+
+
+ uint32_t data;
+ uint32_t i;
+
+ // only for debug
+ cnt++;
+
+ // read data lenght
+ msg->length = ((CAN1RFS)>>16) & 0xF;
+
+ // read identifier
+ msg->id = CAN1RID;
+
+ // EXT frame
+ if(CAN1RFS & CAN_RFS_EXT)
+ msg->flags |= MSG_EXT;
+ else
+ msg->flags &= ~MSG_EXT;
+
+
+ // RTR frame
+ if(CAN1RFS & CAN_RFS_RTR)
+ msg->flags |= MSG_RTR;
+ else
+ msg->flags &= ~MSG_RTR;
+
+
+ // read data
+ data = CAN1RDA;
+ for(i=0; i<4; i++)
+ msg->data[i] = (data>>(i*8)) & 0xFF;
+
+ data = CAN1RDB;
+ for(i=4; i<8; i++)
+ msg->data[i] = (data>>((i-4)*8)) & 0xFF;
+
+}
+
void CAN_send(canmsg_t* msg){
uint32_t data;
uint32_t tmp;
uint32_t pclksel0;
uint32_t val;
+ uint32_t i;
printf("CAN INIT, baudrate: %d\n", baudrate);
// return to normal operating
CAN1MOD = 0;
+ //--------------------------
+
+ // Acceptance Filter Off Mode
+ CANAF_AFMR = 0x01;
+
+ // clear RAM masks
+ for (i = 0; i < 512; i++) {
+ CANAF_RAM->mask[i] = 0x00;
+ }
+
+ CANAF_SFF_sa = 0x00;
+ CANAF_SFF_GRP_sa = 0x00;
+ CANAF_EFF_sa = 0x00;
+ CANAF_EFF_GRP_sa = 0x00;
+ CANAF_ENDofTable = 0x00;
+
+
+ // Acceptance Filter Bypass Mode - all messages accepted
+ CANAF_AFMR = 0x02;
+
+ //--------------------------
+
// enable interrupt after transmit
CAN1IER |= CAN_IER_TIE1;
+ // enable receive interrupt
+ CAN1IER |= CAN_IER_RIE;
+ // enable data overrun interrupt
+ CAN1IER |= CAN_IER_DOIE;
+
// enable CAN interrupt
NVIC_EnableIRQ(CAN_IRQn);
+
}
/***********************************************************************
* global variables
***********************************************************************/
-
+volatile uint32_t cnt;
usb_device_t usb_device;
int chipnr,bd;
int i,size,m=0;
+ cnt=0;
+
CANMSG("Starting USBCAN module firmware...\n");
-
// volatile int i=0;
bootloader_run=0;
sys_err();
}
-// !!! DEBUG - first version, only transmitting CAN messages with usage of queue system from LinCAN
+// !!! DEBUG - transmitting and receiving CAN messages with usage of queue system from LinCAN - first version!
//***********************************************************************
// if (!(IO0PIN&P0_SJA1000_INT_PIN)) //INT PIN is inverted
// chip->chipspecops->irq_handler(0,chip);
+// if (CAN1SR & CAN_SR_RBS)
+// 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 - 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_udev_write_endpoint(&eps[1],ep1_tx_buff,16);
+ //printf("ID: %d\n", msgid);
+
canque_free_outslot(qends, qedge, slot);
timer_tx_off=50; //rozsviceni diod pri vysilani
CLR_OUT_PIN(LED_PORT,LED1_BIT);
usb_device.ep_events &= ~MASK_EP1TX;
+
}
+
}
- */
+
//if (usb_can_send && )