Subversion Repositories HomeAutomation

Rev

Rev 2291 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /*
  2.  * can_lib.c
  3.  *
  4.  * Created: 10/18/2013 11:37:43 AM
  5.  *  Author: Scott_Schmit
  6.  
  7.     The contents of this file were copy & pasted from the CAN Software Library
  8.     on Atmel.com. The library was written for AT90CANxx devices, but was modified
  9.     as an ATmegaxxM1 library.
  10.  
  11.  */
  12.  
  13. //******************************************************************************
  14. //! @file $RCSfile: can_lib.c,v $
  15. //!
  16. //! Copyright (c) 2007 Atmel.
  17. //!
  18. //! Use of this program is subject to Atmel's End User License Agreement.
  19. //! Please read file license.txt for copyright notice.
  20. //!
  21. //! @brief This file contains the library of functions of:
  22. //!             - CAN (Controller Array Network)
  23. //!             - AT90CAN128/64/32
  24. //!
  25. //! This file can be parsed by Doxygen for automatic documentation generation.
  26. //! This file has been validated with AVRStudio-413528/WinAVR-20070122.
  27. //!
  28. //! @version $Revision: 3.20 $ $Name: jtellier $
  29. //!
  30. //! @todo
  31. //! @bug
  32. //******************************************************************************
  33.  
  34. //_____ I N C L U D E S ________________________________________________________
  35. #include "config.h"
  36. #include "can_lib.h"
  37. #include "can_drv.h"
  38.  
  39. //_____ D E F I N I T I O N S __________________________________________________
  40.  
  41. //_____ F U N C T I O N S ______________________________________________________
  42.  
  43. //------------------------------------------------------------------------------
  44. //  @fn can_init
  45. //!
  46. //! CAN macro initialization. Reset the CAN peripheral, initialize the bit
  47. //! timing, initialize all the registers mapped in SRAM to put MObs in
  48. //! inactive state and enable the CAN macro.
  49. //!
  50. //! @warning The CAN macro will be enable after seen on CAN bus a receceive
  51. //!          level as long as of an inter frame (hardware feature).
  52. //!
  53. //! @param  Mode (for "can_fixed_baudrate" param not used)
  54. //!         ==0: start CAN bit timing evaluation from faster baudrate
  55. //!         ==1: start CAN bit timing evaluation with CANBTx registers
  56. //!              contents
  57. //!
  58. //! @return Baudrate Status
  59. //!         ==0: research of bit timing configuration failed
  60. //!         ==1: baudrate performed
  61. //!
  62. //------------------------------------------------------------------------------
  63. uint8_t can_init(uint8_t mode)
  64. {
  65.     if ((Can_bit_timing(mode))==0) return (0);  // c.f. macro in "can_drv.h"
  66.     can_clear_all_mob();                        // c.f. function in "can_drv.c"
  67.     Can_enable();                               // c.f. macro in "can_drv.h"
  68.     return (1);
  69. }
  70.  
  71. //------------------------------------------------------------------------------
  72. //  @fn can_cmd
  73. //!
  74. //! This function takes a CAN descriptor, analyses the action to do:
  75. //! transmit, receive or abort.
  76. //! This function returns a status (CAN_CMD_ACCEPTED or CAN_CMD_REFUSED) if
  77. //! a MOb for Rx or Tx has been found. If no MOB has been found, the
  78. //! application must be retry at a later date.
  79. //! This function also updates the CAN descriptor status (MOB_PENDING or
  80. //! MOB_NOT_REACHED) if a MOb for Rx or Tx has been found. If aborting
  81. //! is performed, the CAN descriptor status will be set to STATUS_CLEARED.
  82. //!
  83. //! @param  st_cmd_t* - Can_descriptor pointer on CAN descriptor structure
  84. //!         to select the action to do.
  85. //!
  86. //! @return CAN_CMD_ACCEPTED - command is accepted
  87. //!         CAN_CMD_REFUSED  - command is refused
  88. //!
  89. //------------------------------------------------------------------------------
  90. uint8_t can_cmd(st_cmd_t* cmd)
  91. {
  92.   uint8_t mob_handle, cpt;
  93.   uint32_t u32_temp;
  94.  
  95.   if (cmd->cmd == CMD_ABORT)
  96.   {
  97.     if (cmd->status == MOB_PENDING)
  98.     {
  99.       // Rx or Tx not yet performed
  100.       Can_set_mob(cmd->handle);
  101.       Can_mob_abort();
  102.       Can_clear_status_mob();       // To be sure !
  103.       cmd->handle = 0;
  104.     }
  105.     cmd->status = STATUS_CLEARED;
  106.   }
  107.   else
  108.   {
  109.     mob_handle = can_get_mob_free();
  110.     if (mob_handle!= NO_MOB)
  111.     {
  112.       cmd->status = MOB_PENDING;
  113.       cmd->handle = mob_handle;
  114.       Can_set_mob(mob_handle);
  115.       Can_clear_mob();
  116.          
  117.       switch (cmd->cmd)
  118.       {
  119.         //------------      
  120.         case CMD_TX:    
  121.           if (cmd->ctrl.ide){ Can_set_ext_id(cmd->id.ext);}
  122.           else              { Can_set_std_id(cmd->id.std);}
  123.           for (cpt=0;cpt<cmd->dlc;cpt++) CANMSG = *(cmd->pt_data + cpt);
  124.           if (cmd->ctrl.rtr) Can_set_rtr();
  125.             else Can_clear_rtr();    
  126.           Can_set_dlc(cmd->dlc);
  127.           Can_config_tx();
  128.           break;
  129.         //------------      
  130.         case CMD_TX_DATA:    
  131.           if (cmd->ctrl.ide){ Can_set_ext_id(cmd->id.ext);}
  132.           else              { Can_set_std_id(cmd->id.std);}
  133.           for (cpt=0;cpt<cmd->dlc;cpt++) CANMSG = *(cmd->pt_data + cpt);
  134.           cmd->ctrl.rtr=0; Can_clear_rtr();
  135.           Can_set_dlc(cmd->dlc);
  136.           Can_config_tx();
  137.           break;
  138.         //------------      
  139.         case CMD_TX_REMOTE:      
  140.           if (cmd->ctrl.ide){ Can_set_ext_id(cmd->id.ext);}
  141.           else              { Can_set_std_id(cmd->id.std);}
  142.           cmd->ctrl.rtr=1; Can_set_rtr();
  143.           Can_set_dlc(cmd->dlc);
  144.           Can_config_tx();
  145.           break;
  146.         //------------      
  147.         case CMD_RX:
  148.           u32_temp=0; Can_set_ext_msk(u32_temp);
  149.           Can_set_dlc(cmd->dlc);
  150.           Can_clear_rtrmsk();
  151.           Can_clear_idemsk();
  152.           Can_config_rx();      
  153.           break;
  154.         //------------      
  155.         case CMD_RX_DATA:
  156.           u32_temp=0; Can_set_ext_msk(u32_temp);
  157.           Can_set_dlc(cmd->dlc);
  158.           cmd->ctrl.rtr=0; Can_set_rtrmsk(); Can_clear_rtr();
  159.           Can_clear_idemsk();
  160.           Can_config_rx();      
  161.           break;
  162.         //------------      
  163.         case CMD_RX_REMOTE:
  164.           u32_temp=0; Can_set_ext_msk(u32_temp);
  165.           Can_set_dlc(cmd->dlc);
  166.           cmd->ctrl.rtr=1; Can_set_rtrmsk(); Can_set_rtr();
  167.           Can_clear_rplv();
  168.           Can_clear_idemsk();
  169.           Can_config_rx();      
  170.           break;
  171.         //------------      
  172.         case CMD_RX_MASKED:
  173.           if (cmd->ctrl.ide){ Can_set_ext_id(cmd->id.ext);}
  174.           else              { Can_set_std_id(cmd->id.std);}
  175.           u32_temp=~0; Can_set_ext_msk(u32_temp);
  176.           Can_set_dlc(cmd->dlc);
  177.           Can_clear_rtrmsk();
  178.           Can_set_idemsk();
  179.           Can_config_rx();      
  180.           break;
  181.         //------------      
  182.         case CMD_RX_DATA_MASKED:
  183.           if (cmd->ctrl.ide){ Can_set_ext_id(cmd->id.ext);}
  184.           else              { Can_set_std_id(cmd->id.std);}
  185.           u32_temp=~0; Can_set_ext_msk(u32_temp);
  186.           Can_set_dlc(cmd->dlc);
  187.           cmd->ctrl.rtr=0; Can_set_rtrmsk(); Can_clear_rtr();
  188.           Can_set_idemsk();
  189.           Can_config_rx();      
  190.           break;
  191.         //------------      
  192.         case CMD_RX_REMOTE_MASKED:
  193.           if (cmd->ctrl.ide){ Can_set_ext_id(cmd->id.ext);}
  194.           else              { Can_set_std_id(cmd->id.std);}
  195.           u32_temp=~0; Can_set_ext_msk(u32_temp);
  196.           Can_set_dlc(cmd->dlc);
  197.           cmd->ctrl.rtr=1; Can_set_rtrmsk(); Can_set_rtr();
  198.           Can_clear_rplv();
  199.           Can_set_idemsk();
  200.           Can_config_rx();      
  201.           break;
  202.         //------------      
  203.         case CMD_REPLY:
  204.           for (cpt=0;cpt<cmd->dlc;cpt++) CANMSG = *(cmd->pt_data + cpt);
  205.           u32_temp=0; Can_set_ext_msk(u32_temp);
  206.           Can_set_dlc(cmd->dlc);
  207.           cmd->ctrl.rtr=1; Can_set_rtrmsk(); Can_set_rtr();
  208.           Can_set_rplv();
  209.           Can_clear_idemsk();
  210.           Can_config_rx();      
  211.           break;
  212.         //------------      
  213.         case CMD_REPLY_MASKED:
  214.           if (cmd->ctrl.ide){ Can_set_ext_id(cmd->id.ext);}
  215.           else              { Can_set_std_id(cmd->id.std);}
  216.           for (cpt=0;cpt<cmd->dlc;cpt++) CANMSG = *(cmd->pt_data + cpt);
  217.           u32_temp=~0; Can_set_ext_msk(u32_temp);
  218.           Can_set_dlc(cmd->dlc);
  219.           cmd->ctrl.rtr=1; Can_set_rtrmsk(); Can_set_rtr();
  220.           Can_set_rplv();
  221.           Can_set_idemsk();
  222.           Can_config_rx();      
  223.           break;
  224.         //------------      
  225.         default:
  226.           // case CMD_NONE or not implemented command
  227.           cmd->status = STATUS_CLEARED;
  228.           break;
  229.         //------------      
  230.       } // switch (cmd ...
  231.     } // if (mob_handle ...
  232.     else
  233.     {
  234.       cmd->status = MOB_NOT_REACHED;
  235.       return CAN_CMD_REFUSED;
  236.     }
  237.   } // else of no CMD_ABORT
  238.   return CAN_CMD_ACCEPTED;
  239. }
  240.  
  241. //------------------------------------------------------------------------------
  242. //  @fn can_get_status
  243. //!
  244. //! This function allows to return if the command has been performed or not.
  245. //! In an reception case, all the CAN message is stored in the structure.
  246. //! This function also updates the CAN descriptor status (MOB_TX_COMPLETED,    
  247. //!  MOB_RX_COMPLETED, MOB_RX_COMPLETED_DLCW or MOB_???_ERROR).        
  248. //!
  249. //! @param  st_cmd_t* pointer on CAN descriptor structure.
  250. //!
  251. //! @return CAN_STATUS_COMPLETED     - Rx or Tx is completed
  252. //!         CAN_STATUS_NOT_COMPLETED - Rx or Tx is not completed
  253. //!         CAN_STATUS_ERROR         - Error in configuration or in the
  254. //!                                    CAN communication
  255. //!
  256. //------------------------------------------------------------------------------
  257. uint8_t can_get_status (st_cmd_t* cmd)
  258. {
  259.     uint8_t a_status, rtn_val;
  260.      
  261.     a_status = cmd->status;
  262.  
  263.     if ((a_status==STATUS_CLEARED)||(a_status==MOB_NOT_REACHED)||(a_status==MOB_DISABLE))
  264.     {
  265.         return CAN_STATUS_ERROR;
  266.     }
  267.  
  268.     Can_set_mob(cmd->handle);
  269.     a_status = can_get_mob_status();
  270.    
  271.     switch (a_status)
  272.     {
  273.         case MOB_NOT_COMPLETED:
  274.             // cmd->status not updated
  275.             rtn_val = CAN_STATUS_NOT_COMPLETED;
  276.             break;
  277.         //---------------      
  278.         case MOB_RX_COMPLETED:    
  279.         case MOB_RX_COMPLETED_DLCW:
  280.             cmd->dlc = Can_get_dlc();
  281.             can_get_data(cmd->pt_data);
  282.             cmd->ctrl.rtr = Can_get_rtr();
  283.             if (Can_get_ide()) // if extended frame
  284.             {
  285.                 cmd->ctrl.ide = 1; // extended frame
  286.                 Can_get_ext_id(cmd->id.ext);
  287.             }
  288.             else // else standard frame
  289.                 {
  290.                     cmd->ctrl.ide = 0;
  291.                     Can_get_std_id(cmd->id.std);
  292.                 }
  293.             // Status field of descriptor: 0x20 if Rx completed
  294.             // Status field of descriptor: 0xA0 if Rx completed with DLCWarning    
  295.             cmd->status = a_status;
  296.             Can_mob_abort();        // Freed the MOB
  297.             Can_clear_status_mob(); //   and reset MOb status
  298.             rtn_val = CAN_STATUS_COMPLETED;
  299.             break;
  300.         //---------------      
  301.         case MOB_TX_COMPLETED:    
  302.             // Status field of descriptor: 0x40 if Tx completed
  303.             cmd->status = a_status;
  304.             Can_mob_abort();        // Freed the MOB
  305.             Can_clear_status_mob(); //   and reset MOb status
  306.             rtn_val = CAN_STATUS_COMPLETED;
  307.             break;
  308.         //---------------      
  309.         default:
  310.             // Status field of descriptor: (bin)000b.scfa if MOb error
  311.             cmd->status = a_status;
  312.             Can_mob_abort();        // Freed the MOB
  313.             Can_clear_status_mob(); //   and reset MOb status
  314.             rtn_val = CAN_STATUS_ERROR;
  315.             break;
  316.              
  317.     } // switch (a_status...
  318.  
  319.     return (rtn_val);
  320. }
  321.