__u8 data[8];
};
-/* CAN extended mask */
-struct usbcan_mask_t{
- __u32 code;
- __u32 mask;
-};
-
/* Structure to hold all of our device specific stuff */
struct usbcan_usb {
struct usb_device *udev; /* the usb device for this device */
spinlock_t err_lock; /* lock for errors */
struct mutex io_mutex; /* synchronize I/O with disconnect */
struct urb *rcv;
- struct usbcan_canmsg_t rcv_msg;
- struct usbcan_canmsg_t tx_msg;
+/* uchar8_t rcv_msg[16];
+ uchar8_t tx_msg[16];*/
+ __u8 rcv_msg[16];
+ __u8 tx_msg[16];
kthread_t rcvthread; /* usb receive kernel thread */
struct candevice_t *candev;
int retval;
struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
- struct usbcan_mask_t usbmask = {
- .code=code,
- .mask=mask,
- };
+ __u8 usbbuf[16];
+
+ *(uint32_t *)(usbbuf)=cpu_to_le32(mask);
+ *(uint32_t *)(usbbuf+4)=cpu_to_le32(code);
retval=usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, dev->ctl_out_endpointAddr),
USBCAN_VENDOR_EXT_MASK_SET,
USB_TYPE_VENDOR,
0, chip->chip_idx,
- &usbmask, sizeof(struct usbcan_mask_t),
+ &usbbuf, 16,
10000);
if (retval<0)
return -ENODEV;
USBCAN_VENDOR_EXT_MASK_STATUS,
USB_TYPE_VENDOR,
0, chip->chip_idx,
- dev->ctl_in_buffer, dev->ctl_in_size,
+ &usbbuf, 16,
10000);
- if (retval==1){
- if(dev->ctl_in_buffer[0]==1){
+ if (retval==16){
+ if(usbbuf[0]==1){
DEBUGMSG("Setting acceptance code to 0x%lx\n",(unsigned long)code);
DEBUGMSG("Setting acceptance mask to 0x%lx\n",(unsigned long)mask);
return 0;
int retval;
struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
- // Data too big to use single receive control message
- struct can_baudparams_t baud={
- .flags=flags,
- .baudrate=rate,
- .sjw=sjw,
- .sample_pt=sampl_pt,
- };
+ __u8 usbbuf[16];
+ *(int32_t *)(usbbuf)=cpu_to_le32(rate);
+ *(int32_t *)(usbbuf+4)=cpu_to_le32(sjw);
+ *(int32_t *)(usbbuf+8)=cpu_to_le32(sampl_pt);
+ *(int32_t *)(usbbuf+12)=cpu_to_le32(flags);
retval=usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, dev->ctl_out_endpointAddr),
USBCAN_VENDOR_BAUD_RATE_SET,
USB_TYPE_VENDOR,
0, chip->chip_idx,
- &baud, sizeof(struct can_baudparams_t),
+ &usbbuf, 16,
10000);
if (retval<0)
return -ENODEV;
USBCAN_VENDOR_BAUD_RATE_STATUS,
USB_TYPE_VENDOR,
0, chip->chip_idx,
- dev->ctl_in_buffer, dev->ctl_in_size,
+ usbbuf, 16,
10000);
- if (retval==1){
- if(dev->ctl_in_buffer[0]==1)
+ if (retval==16){
+ if(usbbuf[0]==1)
return 0;
}
struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
int i=0;
int len;
+ __u8 *ptr;
/* Wait until Transmit Buffer Status is released */
while ( usbcan_chip_queue_status(chip) &&
return -EIO;
}
- dev->tx_msg.chip_id=(__u8)chip->chip_idx;
+ *(uint8_t *)(dev->tx_msg)=chip->chip_idx & 0xFF;
len = msg->length;
if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
- dev->tx_msg.length=(__u8)len;
- dev->tx_msg.flags=(__u16)msg->flags;
-
- if(msg->flags&MSG_EXT) {
- dev->tx_msg.id[0]=(msg->id) & 0xff;
- dev->tx_msg.id[1]=(msg->id>>8) & 0xff;
- dev->tx_msg.id[2]=(msg->id>>16) & 0xff;
- dev->tx_msg.id[3]=(msg->id>>24) & 0xff;
- } else {
- dev->tx_msg.id[0]=(msg->id) & 0xff;
- dev->tx_msg.id[1]=(msg->id>>8) & 0xff;
- dev->tx_msg.id[2]=0;
- dev->tx_msg.id[3]=0;
- }
- for(i=0; i < len; i++) {
- dev->tx_msg.data[i]=(__u8) msg->data[i];
+
+ *(uint8_t *)(dev->tx_msg+1)=len & 0xFF;
+ *(uint16_t *)(dev->tx_msg+2)=cpu_to_le16(msg->flags);
+ *(uint32_t *)(dev->tx_msg+4)=cpu_to_le32(msg->id);
+
+ for(ptr=dev->tx_msg+8,i=0; i < len; ptr++,i++) {
+ *ptr=msg->data[i] & 0xFF;
}
- for(i; i < 8; i++) {
- dev->tx_msg.data[i]=0;
+ for(; i < 8; ptr++,i++) {
+ *ptr=0;
}
return 0;
}
set_bit(USBCAN_TX_PENDING,&dev->flags);
retval=usb_bulk_msg(dev->udev,
usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
- &dev->tx_msg, sizeof(struct usbcan_canmsg_t),
+ &dev->tx_msg, 16,
&len,10000);
clear_bit(USBCAN_TX_PENDING,&dev->flags);
if (retval){
{
int retval;
struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
+ uint16_t value=(btr1&0xFF)<<8 | (btr0&0xFF);
retval = usb_control_msg(dev->udev,
usb_rcvctrlpipe(dev->udev, dev->ctl_in_endpointAddr),
USBCAN_VENDOR_SET_BTREGS,
USB_TYPE_VENDOR,
- btr1<<8 | btr0, chip->chip_idx,
+ cpu_to_le16(value), chip->chip_idx,
dev->ctl_in_buffer, dev->ctl_in_size,
10000);
if (retval==1){
if(dev->ctl_in_buffer[0]==1)
- return 1;
- if(dev->ctl_in_buffer[0]==0)
return 0;
+ if(dev->ctl_in_buffer[0]==0)
+ return 1;
}
return -ENODEV;
}
dev->rcv->dev = dev->udev;
usb_fill_bulk_urb(dev->rcv, dev->udev,
usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
- &dev->rcv_msg, sizeof(struct usbcan_canmsg_t),
+ &dev->rcv_msg, 16,
usbcan_rcv, dev);
/* an endless loop in which we are doing our work */
int i, len;
clear_bit(USBCAN_DATA_READ,&dev->flags);
- if ((dev->candev->chip[dev->rcv_msg.chip_id])&&
- (dev->candev->chip[dev->rcv_msg.chip_id]->flags & CHIP_CONFIGURED)){
-
- obj=dev->candev->chip[dev->rcv_msg.chip_id]->msgobj[0];
- if (dev->rcv_msg.flags & MSG_EXT) {
- obj->rx_msg.id =
- (dev->rcv_msg.id[0]) +
- (dev->rcv_msg.id[1]<<8) +
- (dev->rcv_msg.id[2]<<16) +
- (dev->rcv_msg.id[3]<<24);
- } else {
- obj->rx_msg.id =
- (dev->rcv_msg.id[0]) +
- (dev->rcv_msg.id[1]<<8);
- }
- obj->rx_msg.flags = dev->rcv_msg.flags;
- len=dev->rcv_msg.length;
+ if ((dev->candev->chip[dev->rcv_msg[0]])&&
+ (dev->candev->chip[dev->rcv_msg[0]]->flags & CHIP_CONFIGURED)
+ ){
+ __u8 *ptr;
+
+ obj=dev->candev->chip[dev->rcv_msg[0]]->msgobj[0];
+
+ len=*(uint8_t *)(dev->rcv_msg+1);
if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
obj->rx_msg.length = len;
- for(i=0; i< len; i++) {
- obj->rx_msg.data[i]=obj->rx_msg.data[i];
+
+ obj->rx_msg.flags=le16_to_cpu(*(uint16_t *)(dev->rcv_msg+2));
+ obj->rx_msg.id=le32_to_cpu((*(uint32_t *)(dev->rcv_msg+4)));
+
+ for(ptr=dev->rcv_msg+8,i=0; i < len; ptr++,i++) {
+ obj->rx_msg.data[i]=*ptr;
}
// fill CAN message timestamp
#include_HEADERS = ul_idstr.h
bin_PROGRAMS = usbcan
-usbcan_SOURCES = main.c usb_srq.c can.c can_queue.c sja1000p.c can_quesysless.c devcommon.c setup.c ul_usb1.c finish.c
+usbcan_SOURCES = main.c usb_srq.c can.c can_queue.c sja1000p.c can_quesysless.c devcommon.c setup.c ul_usb1.c finish.c usb_vend.c
#usbtest_SOURCES += ul_idstr.c
#lib_LOADLIBES = bspbase ul_drv lpciap keyval lpciap_kvpb mach_hal uldy
+#ifndef UL_USB1_H
+#define UL_USB1_H
+
/* ul_usb1.h
* Header file for the Linux CAN-bus driver.
* Written by Arnaud Westenberg email:arnaud@wanadoo.nl
// unsigned ul_usb1_read_register(struct candevice_t *candev,unsigned long address);
// int ul_usb1_program_irq(struct candevice_t *candev);
+struct ul_usb1_chip_data
+{
+ int flags;
+};
+
+#define UL_USB1_CHIP_MASK_SET (1<<0)
+#define UL_USB1_CHIP_BAUD_SET (1<<1)
+
int ul_usb1_init(void);
void ul_usb1_exit(void);
+
+#endif /* UL_USB1_H */
#include <lpciap.h>
#include <lpciap_kvpb.h>
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+ #include <byteswap.h>
+#endif
+
#include "./can/can.h"
#include "./can/sja1000p.h"
#include "./can/main.h"
#include "./can/ul_usb1.h"
//#include "./can/setup.h"
+#include "./usb/usb_vend.h"
+
#define MASK_EP1RX 0x01
#define MASK_EP1TX 0x02
struct canchip_t *chips_p[MAX_TOT_CHIPS];
struct msgobj_t *objects_p[MAX_TOT_MSGOBJS];
+struct canuser_t *canuser;
+
/***********************************************************************
* SOMETHING BAD HAPPENED
struct candevice_t *candev;
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;
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){
+ uint16_t msgflags;
+ uint32_t msgid;
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;i<CAN_MSG_LENGTH;i++){
- canmsg.data[i]=*((unsigned char*)(ep1_rx_buff+8+i));
+ canmsg.length=*(uint8_t *)(ep1_rx_buff+1);
+ if (canmsg.length > CAN_MSG_LENGTH)
+ canmsg.length=CAN_MSG_LENGTH;
+ msgflags=*(uint16_t *)(ep1_rx_buff+2);
+ msgid=*(uint32_t *)(ep1_rx_buff+4);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ msgflags = bswap_16( msgflags);
+ msgid = bswap_32( msgid);
+ #endif
+ canmsg.flags=msgflags;
+ canmsg.id=msgid;
+
+ for (i=0;i<canmsg.length;i++){
+ canmsg.data[i]=*(unsigned char*)(ep1_rx_buff+8+i);
+ }
+ for (;i<CAN_MSG_LENGTH;i++){
+ canmsg.data[i]=0;
}
/* Automatic selection of extended format if ID>2047 */
if (canmsg.id & ~0x7ffl & MSG_ID_MASK ) canmsg.flags |= MSG_EXT;
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;i<CAN_MSG_LENGTH;i++){
- (*((uint32_t*)(ep1_tx_buff+8+i)))=slot->msg.data[i];
+ uint16_t msgflags;
+ uint32_t msgid;
+
+ *(uint8_t *)(ep1_tx_buff)=0;
+ *(uint8_t *)(ep1_tx_buff+1)=slot->msg.length;
+
+ msgflags=slot->msg.flags;
+ msgid=slot->msg.id;
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ msgflags = bswap_16( msgflags);
+ msgid = bswap_32( msgid);
+ #endif
+
+ *(uint16_t *)(ep1_tx_buff+2)=msgflags;
+ *(uint32_t *)(ep1_tx_buff+4)=msgid;
+ for (i=0;i<slot->msg.length;i++){
+ *(uint8_t *)(ep1_tx_buff+8+i)=slot->msg.data[i];
+ }
+ for (;i<CAN_MSG_LENGTH;i++){
+ *(uint8_t *)(ep1_tx_buff+8+i)=0;
}
usb_udev_write_endpoint(&eps[1],ep1_tx_buff,USB_MAX_PACKET);
candev->nr_82527_chips=NR_82527;
candev->nr_sja1000_chips=NR_SJA1000;
candev->nr_all_chips=NR_82527+NR_SJA1000;
- //candev->flags |= CANDEV_PROGRAMMABLE_IRQ;
+ candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
return 0;
}
candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL |
sjaOCR_TX0_LH;
+ candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct ul_usb1_chip_data));
+ if (candev->chip[chipnr]->chip_data==NULL)
+ return -ENOMEM;
return 0;
}
--- /dev/null
+#ifndef USBCAN_VENDOR
+#define USBCAN_VENDOR
+
+#include <usb/usb.h>
+
+#define USBCAN_VENDOR_BAUD_RATE_SET (1)
+#define USBCAN_VENDOR_BAUD_RATE_STATUS (2)
+#define USBCAN_VENDOR_SET_BTREGS (3)
+#define USBCAN_VENDOR_CHECK_TX_STAT (4)
+#define USBCAN_VENDOR_START_CHIP (5)
+#define USBCAN_VENDOR_STOP_CHIP (6)
+#define USBCAN_VENDOR_EXT_MASK_SET (7)
+#define USBCAN_VENDOR_EXT_MASK_STATUS (8)
+
+int usbcan_vendor(usb_device_t *udev);
+
+int set_ext_mask_complete_fnc(struct usb_ep_t *ep, int status);
+
+#endif /* USBCAN_VENDOR */
--- /dev/null
+#include <stdio.h>
+#include <system_def.h>
+#include <hal_intr.h>
+#include "./can/ul_usb1.h"
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/main.h"
+#include "./can/devcommon.h"
+#include "./usb/usb_vend.h"
+//#include "./can/ul_usb1.h"
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+ #include <byteswap.h>
+#endif
+
+extern struct canuser_t *canuser;
+
+int set_ext_mask_complete_fnc(struct usb_ep_t *ep, int status){
+ int dest_chip;
+
+ unsigned long code;
+ unsigned long mask;
+
+ struct ul_usb1_chip_data *chip_data=NULL;
+
+ usb_device_t *udev=ep->udev;
+ unsigned char *data=ep->ptr - ep->actual;
+
+ if (udev->request.bRequest==USBCAN_VENDOR_EXT_MASK_SET){
+ dest_chip=(udev->request.wIndex);
+ if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+ goto error;
+ if (!chips_p[dest_chip])
+ goto error;
+ if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+ goto nodata;
+
+ mask=*(uint32_t *)(data);
+ code=*(uint32_t *)(data+4);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ mask = bswap_32( mask);
+ code = bswap_32( code);
+ #endif
+
+
+ if (chips_p[dest_chip]->chipspecops->extended_mask(chips_p[dest_chip], code, mask)<0)
+ goto error;
+ chip_data->flags |= UL_USB1_CHIP_MASK_SET;
+ }
+ return 0;
+error:
+ chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
+nodata:
+ return -1;
+}
+
+int set_baud_rate_complete_fnc(struct usb_ep_t *ep, int status){
+ int dest_chip;
+
+ int32_t rate,sjw,sampl_pt,flags;
+
+ struct ul_usb1_chip_data *chip_data=NULL;
+
+ usb_device_t *udev=ep->udev;
+ unsigned char *data=ep->ptr - ep->actual;
+
+ if (udev->request.bRequest==USBCAN_VENDOR_BAUD_RATE_SET){
+ dest_chip=(udev->request.wIndex);
+ if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+ goto error;
+ if (!chips_p[dest_chip])
+ goto error;
+ if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+ goto nodata;
+
+ rate=*(int32_t *)(data);
+ sjw=*(int32_t *)(data+4);
+ sampl_pt=*(int32_t *)(data+8);
+ flags=*(int32_t *)(data+12);
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ rate = bswap_32( rate);
+ sjw = bswap_32( sjw);
+ sampl_pt = bswap_32( sampl_pt);
+ flags = bswap_32( flags);
+ #endif
+
+ if (chips_p[dest_chip]->chipspecops->baud_rate(chips_p[dest_chip], rate, chips_p[dest_chip]->clock, sjw, sampl_pt, flags)<0)
+ goto error;
+ chip_data->flags |= UL_USB1_CHIP_BAUD_SET;
+ }
+ return 0;
+error:
+ chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
+nodata:
+ return -1;
+}
+
+int usbcan_vendor(usb_device_t *udev)
+{
+ // wIndex, wValue, bRequest, wLength
+ int dest_chip;
+ struct ul_usb1_chip_data *chip_data;
+ uint8_t ret;
+
+ dest_chip=(udev->request.wIndex);
+ if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+ return 0; // Should look like ok (0) or stall (-1)?
+ if (!chips_p[dest_chip])
+ return 0; // Should look like ok (0) or stall (-1)?
+
+ switch ( udev->request.bRequest) {
+ case USBCAN_VENDOR_EXT_MASK_SET:
+ udev->ep0.complete_fnc=set_ext_mask_complete_fnc;
+ return 1;
+ case USBCAN_VENDOR_EXT_MASK_STATUS:
+ ret=-1;
+ if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+ usb_send_control_data(udev,&ret,1);
+ else{
+ ret=(chip_data->flags & UL_USB1_CHIP_MASK_SET)?1:0;
+ usb_send_control_data(udev,&ret,1);
+ }
+ chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
+ return 1;
+
+ case USBCAN_VENDOR_BAUD_RATE_SET:
+ udev->ep0.complete_fnc=set_baud_rate_complete_fnc;
+ return 1;
+ case USBCAN_VENDOR_BAUD_RATE_STATUS:
+ ret=-1;
+ if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+ usb_send_control_data(udev,&ret,1);
+ else{
+ ret=(chip_data->flags & UL_USB1_CHIP_BAUD_SET)?1:0;
+ usb_send_control_data(udev,&ret,1);
+ }
+ chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
+ return 1;
+
+ case USBCAN_VENDOR_SET_BTREGS:
+ {
+ uint16_t value=udev->request.wValue;
+ ret=1;
+ if (chips_p[dest_chip]->chipspecops->set_btregs(chips_p[dest_chip],value&0xFF,(value>>8)&0xFF)<0)
+ ret=0;
+ usb_send_control_data(udev,&ret,1);
+ return 1;
+ }
+ return 1;
+
+ case USBCAN_VENDOR_CHECK_TX_STAT:
+ {
+ struct canque_edge_t *qedge;
+ struct canque_slot_t *slot;
+ ret=0;
+ if (canque_get_inslot(canuser->qends, &qedge, &slot, 0)>=0){
+ canque_abort_inslot(canuser->qends, qedge, slot);
+ ret=1;
+ }
+ usb_send_control_data(udev,&ret,1);
+ return 1;
+ }
+
+ case USBCAN_VENDOR_START_CHIP:
+ ret=1;
+ if (chips_p[dest_chip]->chipspecops->start_chip(chips_p[dest_chip])<0)
+ ret=0;
+ usb_send_control_data(udev,&ret,1);
+ return 1;
+ case USBCAN_VENDOR_STOP_CHIP:
+ ret=1;
+ if (chips_p[dest_chip]->chipspecops->stop_chip(chips_p[dest_chip])<0)
+ ret=0;
+ usb_send_control_data(udev,&ret,1);
+ return 1;
+ }
+
+ return 0;
+}