汎用的なビットフィールドを扱う(1ビット)

組み込み用途でプログラムをしていると、

IO.PDR1.BIT.B0 = 1;

みたいな感じで、ビットフィールドの操作をよくする。
(char 型の IO.PDR1 の 0 ビット目に 1 をセットする)


ビットフィールドはポインタのように付け替えることが出来ないので、

0系の出力 … IO.PDR1.BIT.B0
1系の出力 … IO.PDR1.BIT.B1

みたいに、複数の系統を同じロジック内で制御する場合に、


以下のような工夫が必要となる。

    if (sys == 0)
        IO.PDR1.BIT.B0 = 1;
    else
        IO.PDR1.BIT.B1 = 1;


それだと管理が煩わしいので、
汎用的に扱える関数群を書いてみた。
とりあえず、最も用途の多い1ビット切り替え用になっている。


以下のように使う。

  BitSw8 sys_out[3];
  
  initBitSw(sys_out[0], &IO.PDR1, 0);    // IO.PDR1.BIT.B0
  initBitSw(sys_out[1], &IO.PDR1, 1);    // IO.PDR1.BIT.B1
  initBitSw(sys_out[2], &IO.PDR1, 2);    // IO.PDR1.BIT.B2
  
  setBitSw(sys_out[0], ON);              // IO.PDR1.BIT.B0 = 1;
  setBitSw(sys_out[1], OFF);             // IO.PDR1.BIT.B1 = 0;
  setBitSw(sys_out[2], ON);              // IO.PDR1.BIT.B2 = 1;
  
  getBitSw(sys_out[0]);                  // 1
  getBitSw(sys_out[1]);                  // 0
  getBitSw(sys_out[2]);                  // 1
  
  printf("0x%x", IO.PDR1);                // 0x05 => 0000 0101


関数呼出しのオーバーヘッドを防ぐためにマクロ関数で定義してある。

/*
 * Bit Switch: 汎用的なビットフィールドを扱う関数群
 *               ただし、1ビットの on / off のみを扱う
 */
#define ON  1
#define OFF 0

// Bit Switch (8bits)
typedef struct bitsw8 {
  unsigned char *adr;
  unsigned char  msk;
} BitSw8;

// Bit Switch (16bits)
typedef struct bitsw16 {
  unsigned short *adr;
  unsigned short  msk;
} BitSw16;

// Bit Switch (32bits)
typedef struct bitsw32 {
  unsigned int *adr;
  unsigned int  msk;
} BitSw32;

// Bit Switch の初期設定
#define initBitSw(bitsw, address, location)   \
  do {                                          \
    (bitsw).adr = (address);                   \
    (bitsw).msk = 0x01 << (location);          \
  } while(0)

// Bit Switch へのデータ設定
#define setBitSw(bitsw, on_off)               \
  do {                                          \
    if (on_off)                                 \
      *(bitsw).adr |= (bitsw).msk;            \
    else                                        \
      *(bitsw).adr &= ~((bitsw).msk);         \
  } while(0)

// Bit Switch のデータ参照
#define getBitSw(bitsw)                       \
  ((*(bitsw).adr & (bitsw).msk) ? ON : OFF)