]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/c_can.c
Added attach_to_chip() and release_chip() functions for each chip.
[lincan.git] / lincan / src / c_can.c
index d179b18d6d318b507f7fafbbdddd9e9bdb6b258e..4c052c312603d2b0bef68cb518564fe444cde143 100644 (file)
@@ -28,7 +28,7 @@ can_spinlock_t c_can_if2lock=SPIN_LOCK_UNLOCKED; // spin lcok for the if2 regist
  * c_can_enable_configuration - enable chip configuration mode
  * @pchip: pointer to chip state structure
  */
-int c_can_enable_configuration(struct chip_t *pchip)
+int c_can_enable_configuration(struct canchip_t *pchip)
 {
    int i=0;
    u16 flags;
@@ -60,7 +60,7 @@ int c_can_enable_configuration(struct chip_t *pchip)
 }
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_disable_configuration(struct chip_t *pchip)
+int c_can_disable_configuration(struct canchip_t *pchip)
 {
    int i=0;
    u16 flags;
@@ -90,7 +90,7 @@ int c_can_disable_configuration(struct chip_t *pchip)
 }
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_chip_config(struct chip_t *pchip)
+int c_can_chip_config(struct canchip_t *pchip)
 {
 
    DEBUGMSG("(c%d)calling c_can_chip_config(...)\n", pchip->chip_idx);
@@ -140,7 +140,7 @@ int c_can_chip_config(struct chip_t *pchip)
 /*
  * Checks if the Busy-Bit in the IF1-Command-Request Register is set
  */
-int c_can_if1_busycheck(struct chip_t *pchip)
+int c_can_if1_busycheck(struct canchip_t *pchip)
 {
 
    int i=0;
@@ -166,7 +166,7 @@ int c_can_if1_busycheck(struct chip_t *pchip)
 /*
  * Checks if the Busy-Bit in the IF2-Command-Request Register is set
  */
-int c_can_if2_busycheck(struct chip_t *pchip)
+int c_can_if2_busycheck(struct canchip_t *pchip)
 {
 
    int i=0;
@@ -201,7 +201,7 @@ int c_can_if2_busycheck(struct chip_t *pchip)
  * param sampl_pt sample point in % (0-100) sets (TSEG1+2)/(TSEG1+TSEG2+3) ratio
  * param flags fields BTR1_SAM, OCMODE, OCPOL, OCTP, OCTN, CLK_OFF, CBP
  */
-int c_can_baud_rate(struct chip_t *pchip, int rate, int clock,
+int c_can_baud_rate(struct canchip_t *pchip, int rate, int clock,
                        int sjw, int sampl_pt, int flags)
 {
    int best_error = 1000000000, error;
@@ -215,8 +215,6 @@ int c_can_baud_rate(struct chip_t *pchip, int rate, int clock,
    if (c_can_enable_configuration(pchip))
      return -ENODEV;
 
-   clock /=2;
-
        /* tseg even = round down, odd = round up */
    for (tseg=(0+0+2)*2; tseg<=(MAX_TSEG2+MAX_TSEG1+2)*2+1; tseg++)
      {
@@ -237,7 +235,7 @@ int c_can_baud_rate(struct chip_t *pchip, int rate, int clock,
    if (best_error && (rate/best_error < 10))
      {
        CANMSG("baud rate %d is not possible with %d Hz clock\n",
-              rate, 2*clock);
+              rate, clock);
        CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
               best_rate, best_brp, best_tseg, tseg1, tseg2);
        return -EINVAL;
@@ -406,7 +404,7 @@ int c_can_use_mask(struct msgobj_t *pmsgobj,
 }
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_clear_objects(struct chip_t *pchip)
+int c_can_clear_objects(struct canchip_t *pchip)
 {
    unsigned short i = 0;
    unsigned short tempreg = 0;
@@ -460,18 +458,13 @@ int c_can_clear_objects(struct chip_t *pchip)
 }
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_config_irqs(struct chip_t *pchip,
+int c_can_config_irqs(struct canchip_t *pchip,
                       u16 irqs)
 {
    u16 tempreg;
 
    DEBUGMSG("(c%d)calling c_can_config_irqs(...)\n", pchip->chip_idx);
 
-   /*
-    CANMSG("c_can_config_irqs not implemented\n");
-    return -ENOSYS;
-    */
-
    tempreg = c_can_read_reg_w(pchip, CCCR);
    //DEBUGMSG("-> CAN Control Register: 0x%.4lx\n",(long)tempreg);
    c_can_write_reg_w(pchip, tempreg | (irqs & 0xe), CCCR);
@@ -480,7 +473,7 @@ int c_can_config_irqs(struct chip_t *pchip,
 }
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_pre_read_config(struct chip_t *pchip, struct msgobj_t *pmsgobj)
+int c_can_pre_read_config(struct canchip_t *pchip, struct msgobj_t *pmsgobj)
 {
    unsigned short readMaskCM = IFXCM_CNTRL | IFXCM_ARB;
    unsigned short writeMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_WRRD;
@@ -491,18 +484,26 @@ int c_can_pre_read_config(struct chip_t *pchip, struct msgobj_t *pmsgobj)
 
    spin_lock( &c_can_if1lock );
 
-
    //loading Message Object in IF1
-   if (c_can_if1_busycheck(pmsgobj->hostchip)) return -ENODEV;
+   if (c_can_if1_busycheck(pmsgobj->hostchip))
+       goto error_enodev;
+   
    c_can_write_reg_w(pmsgobj->hostchip, readMaskCM, CCIF1CM);
    c_can_write_reg_w(pmsgobj->hostchip, pmsgobj->object, CCIF1CR);
+
    //setting Message Valid Bit to zero
-   if (c_can_if1_busycheck(pmsgobj->hostchip)) return -ENODEV;
+   if (c_can_if1_busycheck(pmsgobj->hostchip))
+       goto error_enodev;
+
    c_can_write_reg_w(pmsgobj->hostchip, 0, CCIF1A2);
    c_can_write_reg_w(pmsgobj->hostchip, writeMaskCM, CCIF1CM);
    c_can_write_reg_w(pmsgobj->hostchip, pmsgobj->object, CCIF1CR);
+
    //Configuring Message-Object
-   if (c_can_if1_busycheck(pmsgobj->hostchip)) return -ENODEV;
+   /* Only access when the C_CAN controller is idle */
+   if (c_can_if1_busycheck(pmsgobj->hostchip))
+       goto error_enodev;
+
    mcreg = c_can_read_reg_w(pmsgobj->hostchip, CCIF1CM);
    c_can_write_reg_w(pmsgobj->hostchip, 
                      ((mcreg & IFXMC_UMASK) | IFXMC_EOB | IFXMC_RXIE), CCIF1DMC);
@@ -531,10 +532,16 @@ int c_can_pre_read_config(struct chip_t *pchip, struct msgobj_t *pmsgobj)
 #endif
 
    return 0;
+
+error_enodev:
+   CANMSG("Timeout in c_can_if1_busycheck\n");
+   spin_unlock(&c_can_if1lock);
+   return -ENODEV;
+
 }
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, 
+int c_can_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, 
                                struct canmsg_t *msg)
 {
        return 0; 
@@ -546,7 +553,7 @@ int c_can_pre_write_config(struct chip_t *chip, struct msgobj_t *obj,
  *In this version the method also sends the message.
  */
 
-int c_can_send_msg(struct chip_t *pchip, struct msgobj_t *pmsgobj,
+int c_can_send_msg(struct canchip_t *pchip, struct msgobj_t *pmsgobj,
                        struct canmsg_t *pmsg)
 {   
    unsigned short readMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_DA | IFXCM_DB;
@@ -622,7 +629,7 @@ int c_can_send_msg(struct chip_t *pchip, struct msgobj_t *pmsgobj,
 }
 
 //////////////////////////////////////////////////////////////////////
-int c_can_remote_request(struct chip_t *pchip, struct msgobj_t *pmsgobj )
+int c_can_remote_request(struct canchip_t *pchip, struct msgobj_t *pmsgobj )
 {
    unsigned short readMaskCM = IFXCM_CNTRL;// | IFXCM_ARB;
    //unsigned short writeMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_WRRD;
@@ -660,7 +667,7 @@ int c_can_remote_request(struct chip_t *pchip, struct msgobj_t *pmsgobj )
 }
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_set_btregs(struct chip_t *pchip,
+int c_can_set_btregs(struct canchip_t *pchip,
                      u16 btr0,
                     u16 btr1)
 {
@@ -691,7 +698,7 @@ int c_can_set_btregs(struct chip_t *pchip,
 /*
  * Starts the Chip, by setting the CAN Enable Bit
  */
-int c_can_start_chip(struct chip_t *pchip)
+int c_can_start_chip(struct canchip_t *pchip)
 {
    u16 flags = 0;
 
@@ -704,11 +711,10 @@ int c_can_start_chip(struct chip_t *pchip)
        return -1;
      }
 
-   //   flags = c_can_read_reg_w(pchip, CCCE) | CE_EN;
-   //   c_can_write_reg_w(pchip, flags, CCCE);
-   //
+#ifdef C_CAN_WITH_CCCE
    flags = c_can_read_reg_w(pchip, CCCE) | CE_EN;
    c_can_write_reg_w(pchip, flags, CCCE);
+#endif
 
    DEBUGMSG("-> ok\n");
 #ifdef REGDUMP
@@ -722,7 +728,7 @@ int c_can_start_chip(struct chip_t *pchip)
 /*
  * Stops the Chip, by deleting the CAN Enable Bit
  */
-int c_can_stop_chip(struct chip_t *pchip)
+int c_can_stop_chip(struct canchip_t *pchip)
 {
    u16 flags = 0;
 
@@ -735,18 +741,43 @@ int c_can_stop_chip(struct chip_t *pchip)
        return -1;
      }
 
+#ifdef C_CAN_WITH_CCCE
    flags = c_can_read_reg_w(pchip, CCCE) & ~CE_EN;
    c_can_write_reg_w(pchip, flags, CCCE);
+#endif
 
    DEBUGMSG("-> ok\n");
    return 0;
 }
 
+int c_can_attach_to_chip(struct canchip_t *chip)
+{
+       return 0;
+}
+
+int c_can_release_chip(struct canchip_t *chip)
+{
+       int temp;
+
+       temp = c_can_read_reg_w(chip, CCCR);
+
+       /* Disable IRQ generation */
+       c_can_config_irqs(chip, 0);
+
+       temp = c_can_read_reg_w(chip, CCCR);
+
+       /* Power-down C_CAN, except this does nothing in the version 1.2 */
+       c_can_stop_chip(chip);
+
+
+       return 0;
+}
+
 ///////////////////////////////////////////////////////////////////////
 /*
  *Check the TxOK bit of the Status Register and resets it afterwards.
  */
-int c_can_check_tx_stat(struct chip_t *pchip)
+int c_can_check_tx_stat(struct canchip_t *pchip)
 {
    unsigned long tempstat = 0;
 
@@ -770,7 +801,7 @@ int c_can_check_tx_stat(struct chip_t *pchip)
 
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
+int c_can_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
 {
        can_preempt_disable();
        
@@ -785,7 +816,7 @@ int c_can_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
 }
 
 ///////////////////////////////////////////////////////////////////////
-int c_can_filtch_rq(struct chip_t *chip, struct msgobj_t *obj)
+int c_can_filtch_rq(struct canchip_t *chip, struct msgobj_t *obj)
 {
        can_preempt_disable();
        
@@ -800,7 +831,7 @@ int c_can_filtch_rq(struct chip_t *chip, struct msgobj_t *obj)
 
 
 ///////////////////////////////////////////////////////////////////////
-void c_can_registerdump(struct chip_t *pchip)
+void c_can_registerdump(struct canchip_t *pchip)
 {
    CANMSG("------------------------------------\n");
    CANMSG("---------C-CAN Register Dump--------\n");
@@ -820,8 +851,10 @@ void c_can_registerdump(struct chip_t *pchip)
          (long)(c_can_read_reg_w( pchip, CCTR)));
    CANMSG("Baud Rate Presc. Register:    0x%.4lx\n",
          (long)(c_can_read_reg_w( pchip, CCBRPE)));
+#ifdef C_CAN_WITH_CCCE
    CANMSG("CAN Enable Register:          0x%.4lx\n",
          (long)(c_can_read_reg_w( pchip, CCCE)));
+#endif
    CANMSG("Transm. Req. 1 Register:      0x%.4lx\n",
          (long)(c_can_read_reg_w( pchip, CCTREQ1)));
    CANMSG("Transm. Req. 2 Register:      0x%.4lx\n",
@@ -884,6 +917,37 @@ void c_can_registerdump(struct chip_t *pchip)
    CANMSG("------------------------------------\n");
 }
 
+
+void c_can_if1_registerdump(struct canchip_t *pchip)
+{
+   CANMSG("----------------------------------------\n");
+   CANMSG("Error Counting Register:      0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCEC)));
+   CANMSG("---------C-CAN IF1 Register Dump--------\n");
+   CANMSG("IF1 Command Req. Register:    0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1CR)));
+   CANMSG("IF1 Command Mask Register:    0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1CM)));
+   CANMSG("IF1 Mask 1 Register:          0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1M1)));
+   CANMSG("IF1 Mask 2 Register:          0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1M2)));
+   CANMSG("IF1 Arbitration 1 Register:   0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1A1)));
+   CANMSG("IF1 Arbitration 2 Register:   0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1A2)));
+   CANMSG("IF1 Message Control Register: 0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1DMC)));
+   CANMSG("IF1 Data A1 Register:         0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1DA1)));
+   CANMSG("IF1 Data A2 Register:         0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1DA2)));
+   CANMSG("IF1 Data B1 Register:         0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1DB1)));
+   CANMSG("IF1 Data B2 Register:         0x%.4lx\n",
+         (long)(c_can_read_reg_w( pchip, CCIF1DB2)));
+}
+
 ///////////////////////////////////////////////////////////////////////
 
 int c_can_register(struct chipspecops_t *chipspecops)
@@ -905,40 +969,26 @@ int c_can_register(struct chipspecops_t *chipspecops)
        chipspecops->remote_request=c_can_remote_request;
        chipspecops->enable_configuration=c_can_enable_configuration;
        chipspecops->disable_configuration=c_can_disable_configuration;
+       chipspecops->attach_to_chip=c_can_attach_to_chip;
+       chipspecops->release_chip=c_can_release_chip;
        chipspecops->set_btregs=c_can_set_btregs;
        chipspecops->start_chip=c_can_start_chip;
        chipspecops->stop_chip=c_can_stop_chip;
        chipspecops->irq_handler=c_can_irq_handler;
+       chipspecops->irq_accept = NULL;
        return 0;
 }
 
-/*int c_can_register(struct chip_t *pchip)
+int c_can_fill_chipspecops(struct canchip_t *chip)
 {
-   DEBUGMSG("(c%d)call c_can_register\n", pchip->chip_idx);
-
-   // Validate pointer
-   if ( NULL == pchip ) return -1;
-
-   pchip->chip_config = c_can_chip_config;
-   pchip->set_baud_rate = c_can_baud_rate;
-   pchip->set_mask = c_can_mask;
-   pchip->set_use_mask = c_can_use_mask;
-   //pchip->set_message15_mask = c_can_extended_mask;
-   pchip->clear_objects = c_can_clear_objects;
-   pchip->config_irqs = c_can_config_irqs;
-   pchip->pre_read_config = c_can_pre_read_config;
-   //pchip->pre_write_config = c_can_pre_write_config;
-   pchip->send_msg = c_can_send_msg;
-   pchip->check_tx_stat = c_can_check_tx_stat;
-   pchip->remote_request = c_can_remote_request;
-   pchip->enable_configuration = c_can_enable_configuration;
-   pchip->disable_configuration = c_can_disable_configuration;
-   pchip->set_btregs = c_can_set_btregs;
-   pchip->start_chip = c_can_start_chip;
-   pchip->stop_chip = c_can_stop_chip;
-   pchip->register_dump = c_can_registerdump;
-
-   DEBUGMSG("-> ok\n");
-   return 0;
+       chip->chip_type="c_can";
+       if(MAX_MSGOBJS >= 32) {
+               chip->max_objects = 32;
+       } else {
+               CANMSG("C_CAN requires 32 message objects per chip,"
+                      " but only %d is compiled maximum\n",MAX_MSGOBJS);
+               chip->max_objects = MAX_MSGOBJS;
+       }
+       c_can_register(chip->chipspecops);
+       return 0;
 }
-*/