#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)
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;
struct msgobj_t *objects_p[MAX_TOT_MSGOBJS];
-/**
- SOMETHING BAD HAPPENED
-*/
+/***********************************************************************
+ * SOMETHING BAD HAPPENED
+ ***********************************************************************/
+
int sys_err(){
unsigned char i=0;
}
}
-/**
- 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;
}*/
}
-/***********************************/
+/***********************************************************************
+ * 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;
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;
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;
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;i<CAN_MSG_LENGTH;i++){
+ canmsg.data[i]=*((unsigned char*)(ep1_rx_buff+8+i));
+ }
+ /* 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);
+ }
+ 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;
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;i<CAN_MSG_LENGTH;i++){
+ (*((uint32_t*)(ep1_tx_buff+8+i)))=slot->msg.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 */
* 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;slowdown<SJA1000_SCLK;slowdown++);
+ //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Start command
+
+ // Set memory address
+ IO1SET=__val2mfld(0x00FF0000,address&0xFF); // Shift data to SJA pins and output them
+ for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
+ //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Makes address active
+ CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
+
+ // Setting data
+ CLR_OUT_PIN(IO0,P0_SJA1000_WR_PIN);
+
+ IO1CLR=0x00FF0000;
+ IO1SET=__val2mfld(0x00FF0000,data&0xFF);
+ for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
+ SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Data should be accepted by now
+ SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
- dev = (struct usb_ul_usb1 *)candev->sysdevptr.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 */
* 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;slowdown<SJA1000_SCLK;slowdown++);
+ //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
+
+ // Request memory address
+ IO1SET=__val2mfld(0x00FF0000,address&0xFF);
+ for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
+ //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
+ CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+
+ // Get data
+
+ IO1DIR&=~0x00FF0000; // Sets port as input
+ CLR_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
+ for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
+ data=__mfld2val(0x00FF0000,IO1PIN);
+ SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
+ SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
+ for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
+ return data;
+
+// 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;
// mutex_lock(&dev->io_mutex);
// if (!dev) { /* disconnect() was called */