0

I am trying to understand the code, my worry is why in below code "CAN_TypeDef" is being used, can I simply use pointer of type integer,what will be the adverse consequences of integer pointer ?

The below code belongs to CAN(controller area network) library code of stm32f discovery board

in Filename can.c

void CAN_setup (uint32_t ctrl)  {
  CAN_TypeDef *pCAN = (ctrl == 1) ? CAN1 : CAN2;
  uint32_t brp;

When I went to definition of CAN_Typedef it throws me here.

typedef struct
{
  __IO uint32_t              MCR;                 /*!< CAN master control register,         Address offset: 0x00          */
  __IO uint32_t              MSR;                 /*!< CAN master status register,          Address offset: 0x04          */
  __IO uint32_t              TSR;                 /*!< CAN transmit status register,        Address offset: 0x08          */
  __IO uint32_t              RF0R;                /*!< CAN receive FIFO 0 register,         Address offset: 0x0C          */
  __IO uint32_t              RF1R;                /*!< CAN receive FIFO 1 register,         Address offset: 0x10          */
  __IO uint32_t              IER;                 /*!< CAN interrupt enable register,       Address offset: 0x14          */
  __IO uint32_t              ESR;                 /*!< CAN error status register,           Address offset: 0x18          */
  __IO uint32_t              BTR;                 /*!< CAN bit timing register,             Address offset: 0x1C          */
  uint32_t                   RESERVED0[88];       /*!< Reserved, 0x020 - 0x17F                                            */
  CAN_TxMailBox_TypeDef      sTxMailBox[3];       /*!< CAN Tx MailBox,                      Address offset: 0x180 - 0x1AC */
  CAN_FIFOMailBox_TypeDef    sFIFOMailBox[2];     /*!< CAN FIFO MailBox,                    Address offset: 0x1B0 - 0x1CC */
  uint32_t                   RESERVED1[12];       /*!< Reserved, 0x1D0 - 0x1FF                                            */
  __IO uint32_t              FMR;                 /*!< CAN filter master register,          Address offset: 0x200         */
  __IO uint32_t              FM1R;                /*!< CAN filter mode register,            Address offset: 0x204         */
  uint32_t                   RESERVED2;           /*!< Reserved, 0x208                                                    */
  __IO uint32_t              FS1R;                /*!< CAN filter scale register,           Address offset: 0x20C         */
  uint32_t                   RESERVED3;           /*!< Reserved, 0x210                                                    */
  __IO uint32_t              FFA1R;               /*!< CAN filter FIFO assignment register, Address offset: 0x214         */
  uint32_t                   RESERVED4;           /*!< Reserved, 0x218                                                    */
  __IO uint32_t              FA1R;                /*!< CAN filter activation register,      Address offset: 0x21C         */
  uint32_t                   RESERVED5[8];        /*!< Reserved, 0x220-0x23F                                              */ 
  CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register,                 Address offset: 0x240-0x31C   */
} CAN_TypeDef;

I don't understand why typedef .. I have base address of CAN and offset of Different registers, I didn't find any relevance of above code for my purpose.

I am trying to apply this way

/*=========================CAN BASE ADDRESS=============== */

#define CAN1_BASE 0x40006800
#define CAN2_BASE  0x40006400

/==========================================================/

#define CAN1_MCR (CAN1_BASE+ 0x00)
#define CAN2_MCR (CAN2_BASE+ 0x00)  // 0x00 is offset for MCR

#define DEMO(X) (*(unsigned int*)(X)) // will use this to type cast and deference ,accessing the register.

DEMO(CAN1_MCR) =  (CAN_MCR_INRQ   |   CAN_MCR_NART    ); // CAN_MCR_INRQ and CAN_MCR_NART has hexadecimal vale pointing to specific bit in MCR register
naumaan
  • 55
  • 11
  • The struct type provides a mapping for the layout of an addressible multiport hardware interface. A pointer to this type thus represents a pointer to a particular overall interface, and you can easily and clearly access any specific port of that interface through such a pointer, by name. There is no particular reason why you *have* to do it that way, but I'd recommend it to you as a good idea to do so, especially if you're relying on a library that itself does so. – John Bollinger Jul 12 '16 at 15:42
  • @JohnBollinger sir , i am try to make my own implementation inspired by generic library , can I simply use pointer of type integer,what will be the adverse consequences of integer pointer ? – naumaan Jul 12 '16 at 15:46
  • Using a separate pointer directly to each port is messier and less clear. It is likely to be more difficult to build and maintain your code that way, but I see no inherent reason why you could not do so. – John Bollinger Jul 12 '16 at 15:55

2 Answers2

0

The key word is reuse. Saying

#define CAN1_MCR (CAN1_BASE+ 0x00)
#define CAN2_MCR (CAN2_BASE+ 0x00) 

means that you'd have to define the layout twice (with all the double maintenance problems). The structure approach allows to define it once, and use the same definition for each bus.

user58697
  • 7,808
  • 1
  • 14
  • 28
0

Yes... You can use an integer pointer and go ahead with the method you use. But you will miss on "Code Readability" and "Structured Code".

With the typedef struct, it is pretty easy to access the registers and code is easy to read/understand.
Nothing else!!

Swanand
  • 4,027
  • 10
  • 41
  • 69