Peripheral Accessor class

I found a wonderful way to make peripheral accessor classes in HEW C++.

Given a simple peripheral like the CMT, one can construct a class.  Notice that I just cut and paste the peipheral structure found in iodefine.h in the .hpp file

the peripheral registers are aligned and padded in iodefine.h so that "C" code can use these registers as if they were mapped into memory via a bunch of clumsy macros.

One could use "placement new" to create a CMT object at the base address of a CMT register set.

But with HEW C++ it is quite easy.

These accessors are global since the hardware is global.  Each CMT is created at the base addres of the register set.

since the structure is volatile, all structure members are volatile.

Notice at the end of the incude file, a C function UnitTest_CMT().  This does work.

It works well for peripherals that have common register definitions, SCI, RSPI, CMT, DAC, DTC, PORTS.  Does not work well with MTU2 since these timers have a whacky register layout.

Note that these are accessor classes and cannot have any additional member data other than the peripheral register structure, but the member functions can provide significant functionality to operate upon these registers and hide all the messy impl details.  Using inline may inprove efficiency.

in .CPP file

#pragma  address CMT0 = 0x00088002

CMT CMT0; // the global instance

#pragma  address CMT1 = 0x00088008

CMT CMT1; // the global instance

#pragma  address CMT2 = 0x00088012

CMT CMT2; // the global instance

#pragma  address CMT3 = 0x00088018

CMT CMT3; // the global instance

access of registers is almost identical to the "C" version

void CMT::SetDivisor(CMTDivisor const divisor)

{

Stop();

cmt.CMCR.BIT.CKS = (uint16_t)(divisor & (BIT(0) | BIT(1)));  //or in only important bits}

.hpp file

/*!
* @file CMT.hpp
* @class CMT
* @brief CMT object
* create four CMT global objects.
* each object will control a channel
* users can then configure these units
* Copyright rocketdawg systems 2011
* This is a public include file and the object instances are extern
*/

#ifndef _CMT_OBJECT_
#define _CMT_OBJECT_

#include <stdint.h>
#include "stdreg.h"

#pragma bit_order left
#pragma unpack
typedef struct rx_cmt {
union {
  unsigned short WORD;
  struct {
   unsigned short :9;
   unsigned short CMIE:1;
   unsigned short :4;
   unsigned short CKS:2;
  } BIT;
} CMCR;
unsigned short CMCNT;
unsigned short CMCOR;
}rx_cmt_t;

class CMT
{
public:
enum CMTDivisor { CMT_PCLK_8 = 0, CMT_PCLK_32 = 1, CMT_PCLK_128 = 2, CMT_PCLK_512 = 3 };
CMT();

void ModuleEnable();  //call power manager to enable peripheral
void ModuleDisable();
void SetDivisor(CMTDivisor const divisor);
void SetCount(uint16_t const count);
void SetMatch(uint16_t const count);
void Start();
void Stop();
void EnableInterrupt();
void DisableInterrupt();
void ISR(void);

private:
volatile rx_cmt_t cmt;

/// no copy constructor.  Forces compiler to omit code
CMT(const CMT &);
/// no assignment constructor. Forces compiler to omit code
CMT & operator= (const CMT &);
};

//extern global instance
extern CMT CMT0;
extern CMT CMT1;
extern CMT CMT2;
extern CMT CMT3;


#ifdef __cplusplus
extern "C" {
void UnitTest_CMT(void);
}
#endif


#endif

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

  • Hey,

    I've been trying to do stuff like this, and I'm happy to see that you have a working copy. I used a static pointer from within the object created to point to the structure, but this might be a better way. I will check it out soon. :)

  • In reply to oraut:

    Any suggestions for registering the ISR routine with the ICU and vector table?

    One way I can think of is to create an class/object for the vector table and have it in RAM.