From: Jan Kriz Date: Wed, 9 Jul 2008 10:51:33 +0000 (+0200) Subject: hw side seems complete, X-Git-Tag: CLT_COMM_CAN_usb_can1_kriz_bp~16 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/26fbfa454cdb986c0e18b41bda3a0e8ec54128ba hw side seems complete, remains LinCAN side --- diff --git a/embedded/app/usbcan/main.c b/embedded/app/usbcan/main.c index 205ae35..97d9785 100644 --- a/embedded/app/usbcan/main.c +++ b/embedded/app/usbcan/main.c @@ -31,13 +31,27 @@ #ifdef USB_MAX_PACKET #undef USB_MAX_PACKET - #define USB_MAX_PACKET 8 + #define USB_MAX_PACKET 16 #endif #define CAN_OP_MASK 0x80 #define CAN_OP_READ 0x80 #define CAN_OP_WRITE 0x00 +/*********************************************************************** + * Note: + * Comparing to LinCAN, there is no need to sleep for processes + * because the degree of filling of fifo from the client side + * is solved in main cycle (no new messages are accepted when full) + * and on the server side by speed of USB interface. FIFO in edge + * from SJA chip to USB interface should never be filled. + ***********************************************************************/ + +/*********************************************************************** + * Note: + * Code is wittingly complex in order to ease future changes in hardware + * configuration and to make it as much similar as the code of LinCAN + ***********************************************************************/ LT_TIMER_DEC(lt_10msec) LT_TIMER_IMP(lt_10msec) @@ -48,15 +62,17 @@ LT_TIMER_IMP(lt_2sec) typedef void (*FNC)(); //function ptr -/***********************************/ -// global variables +/*********************************************************************** + * global variables + ***********************************************************************/ + usb_device_t usb_device; usb_ep_t eps[2]; unsigned char ep1_rx_buff[USB_MAX_PACKET]; unsigned char ep1_tx_buff[USB_MAX_PACKET]; -uint8_t timer_str,timer_rx_off,timer_tx_off,timer_configured,usb_can_send; +uint8_t timer_str,timer_rx_off,timer_tx_off,timer_configured; volatile uint8_t bootloader_run; int processlocal; @@ -68,9 +84,10 @@ struct canchip_t *chips_p[MAX_TOT_CHIPS]; struct msgobj_t *objects_p[MAX_TOT_MSGOBJS]; -/** - SOMETHING BAD HAPPENED -*/ +/*********************************************************************** + * SOMETHING BAD HAPPENED + ***********************************************************************/ + int sys_err(){ unsigned char i=0; @@ -89,16 +106,16 @@ int sys_err(){ } } -/** - Routine for visible LED blinking -*/ +/*********************************************************************** + * Routine for visible LED blinking (on USB transmission) + ***********************************************************************/ + void timer_10ms(void) { if (timer_tx_off!=0) timer_tx_off--; 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; @@ -108,12 +125,24 @@ void timer_10ms(void) }*/ } -/***********************************/ +/*********************************************************************** + * Main routine + ***********************************************************************/ + int main(void) { struct candevice_t *candev; - struct canchip_t *chip; + struct canchip_t *chip=NULL; + struct msgobj_t *obj; + struct canuser_t *canuser; + struct canque_ends_t *qends; + struct canque_edge_t *edge,*qedge; + struct canque_slot_t *slot; + struct canmsg_t canmsg; + can_spin_irqflags_t iflags; + int chipnr,bd; + int i,size; // volatile int i=0; bootloader_run=0; @@ -125,8 +154,10 @@ int main(void) SET_OUT_PIN(LED_PORT,LED_ERR); CLR_OUT_PIN(LED_PORT,LED_GP); - /// ************************* - /// CAN device initialization + /*********************************************************************** + * CAN device initialization - device side (adapted from LinCAN setup.c) + ***********************************************************************/ + baudrate[0]=1000; @@ -186,13 +217,59 @@ int main(void) sys_err(); } + /*********************************************************************** + * CAN device initialization - client side (adapted from LinCAN open.c) + ***********************************************************************/ + + chip=candev->chip[0]; + obj=chip->msgobj[0]; + atomic_inc(&obj->obj_used); + can_msgobj_set_fl(obj,OPENED); + + if (chip->flags & CHIP_CONFIGURED) + DEBUGMSG("Device is already configured.\n"); + else { + if (chip->chipspecops->chip_config(chip)) + CANMSG("Error configuring chip.\n"); + else + chip->flags |= CHIP_CONFIGURED; + + if (chip->chipspecops->pre_read_config(chip,obj)<0) + CANMSG("Error initializing chip for receiving\n"); + + } /* End of chip configuration */ + + canuser = (struct canuser_t *)malloc(sizeof(struct canuser_t)); + if(canuser == NULL) sys_err(); + canuser->flags=0; +// canuser->userinfo.fileinfo.file = file; + canuser->msgobj = obj; +// canuser->magic = CAN_USER_MAGIC; +// file->private_data = canuser; + + qends = (struct canque_ends_t *)malloc(sizeof(struct canque_ends_t)); + if(qends == NULL) sys_err(); + canqueue_ends_init_kern(qends); + canuser->qends = qends; + /*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); - /// *************************************** - /// CAN device initialization - client side + if(canqueue_connect_edge(edge=canque_new_edge_kern(MAX_BUF_LENGTH), + canuser->qends, obj->qends)<0) sys_err(); - ///********* - /// USB init + 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*/ + canque_edge_decref(canuser->rx_edge0); + canque_edge_decref(edge); + + + /*********************************************************************** + * USB Init + ***********************************************************************/ memset( &usb_device, 0, sizeof( usb_device)); usb_device.id = 1; @@ -216,23 +293,47 @@ int main(void) usb_connect(&usb_device); can_init(); - usb_can_send=1; - /********************/ - // start + /*********************************************************************** + * Start + ***********************************************************************/ + timer_rx_off=timer_tx_off=timer_str=timer_configured=0; while (1) { usb_check_events(&usb_device); usb_control_response(&usb_device); - if ((usb_device.ep_events & MASK_EP1RX)&&(usb_can_send)) { //EP1RX - int size; - uint8_t *data; + if (!(IO0PIN&P0_SJA1000_INT_PIN)) + chip->chipspecops->irq_handler(0,chip); + + if (usb_device.ep_events & MASK_EP1RX) { //EP1RX - data waiting to receive uint8_t val; - size=usb_udev_read_endpoint(&eps[0],ep1_rx_buff,USB_MAX_PACKET); - data=(uint8_t *)ep1_rx_buff; - if (size==2){ + if (canque_get_inslot(qends, &qedge, &slot, 0)>=0){ //Free slot obtained + size=usb_udev_read_endpoint(&eps[0],ep1_rx_buff,USB_MAX_PACKET); + if (size==16){ + canmsg.cob=0; + canmsg.id=*((uint32_t*)ep1_rx_buff); + canmsg.flags=(*((uint32_t*)(ep1_rx_buff+4)))>>8; + canmsg.length=(*((uint16_t*)(ep1_rx_buff+6)))&0x00FF; + for (i=0;i2047 */ + 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); + } + 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; + } + + +/* if (size==2){ if (((*data)&CAN_OP_MASK)==CAN_OP_READ){ // Get data from CAN device and return to caller can_read((*data) & 0x7F,&val); *(data+1)=val; @@ -246,15 +347,27 @@ int main(void) timer_tx_off=50; //rozsviceni diod pri vysilani CLR_OUT_PIN(LED_PORT,LED1_BIT); } - } - usb_device.ep_events &= ~MASK_EP1RX; + }*/ } - if(usb_device.ep_events & MASK_EP1TX){ - usb_can_send=1; - usb_device.ep_events &= ~MASK_EP1TX; + if(usb_device.ep_events & MASK_EP1TX){ //EP1TX - data transmitted + if(canque_test_outslot(qends, &qedge, &slot)>=0){ + (*((uint32_t*)ep1_tx_buff))=slot->msg.id; + (*((uint32_t*)(ep1_tx_buff+4)))=slot->msg.flags<<8 | (slot->msg.length&0xFF); + for (i=0;imsg.data[i]; + } + usb_udev_write_endpoint(&eps[1],ep1_tx_buff,USB_MAX_PACKET); + + 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 && ) + #ifdef WATCHDOG_ENABLED watchdog_feed(); #endif /* WATCHDOG_ENABLED */ diff --git a/embedded/app/usbcan/ul_usb1.c b/embedded/app/usbcan/ul_usb1.c index 0b3e388..e100f90 100644 --- a/embedded/app/usbcan/ul_usb1.c +++ b/embedded/app/usbcan/ul_usb1.c @@ -295,16 +295,42 @@ int ul_usb1_program_irq(struct candevice_t *candev) * Return Value: The function does not return a value * File: src/ul_usb1.c */ -void ul_usb1_write_register(struct candevice_t *candev,unsigned data, unsigned long address) +void ul_usb1_write_register(unsigned data, unsigned long address) { - struct usb_ul_usb1 *dev; - int retval; - int bytes_transferred; - unsigned char buffer[2]; - buffer[0]=((unsigned char)address & ~CAN_OP_MASK)+CAN_OP_WRITE; - buffer[1]=(unsigned char)data; + IO1DIR|=0x00FF0000; // Port as output to send data + IO1CLR=0x00FF0000; // Clear all data on port + // Init + SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN); // Stays high on write + SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on address write + SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN); // Sets output buffers to third state + for (slowdown=0;slowdownsysdevptr.anydev; +// struct usb_ul_usb1 *dev; +// int retval; +// int bytes_transferred; +// unsigned char buffer[2]; +// buffer[0]=((unsigned char)address & ~CAN_OP_MASK)+CAN_OP_WRITE; +// buffer[1]=(unsigned char)data; +// +// dev = (struct usb_ul_usb1 *)candev->sysdevptr.anydev; // mutex_lock(&dev->io_mutex); // if (!dev) { /* disconnect() was called */ @@ -340,16 +366,43 @@ exit: * Return Value: The function returns the value stored in @address * File: src/ul_usb1.c */ -unsigned ul_usb1_read_register(struct candevice_t *candev,unsigned long address) +unsigned ul_usb1_read_register(unsigned long address) { - struct usb_ul_usb1 *dev; - int retval; - int bytes_transferred; - unsigned char buffer[2]; - buffer[0]=((unsigned char)address & ~CAN_OP_MASK)+CAN_OP_READ; - buffer[1]=0x00; - - dev = (struct usb_ul_usb1 *)candev->sysdevptr.anydev; + unsigned data; + IO1DIR|=0x00FF0000; // Port as output to set address + IO1CLR=0x00FF0000; // Clear all data + // Init + SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on read + SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN); // Stays high while entering address + SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN); + for (slowdown=0;slowdownsysdevptr.anydev; // mutex_lock(&dev->io_mutex); // if (!dev) { /* disconnect() was called */