PSoC で C++ を使う その2

前回の続きです。
PSoC5LP では C++ がわかったので、ラッパクラスが作れないか見てみました。

方針としては
1. PSoC Creator が自動生成する関数を struct でまとめる
2. ラッパクラスに (1) を登録して宣言する
3. read(), write() など、よく使うと思われる関数のみ対応
といったところです。
(割り込みは今のところ使う予定が無いので後回しです)

struct の宣言が面倒なのでマクロもあわせて作ってます。

#include <stdint.h>

/* --------------------------------------------------------------------------
 * PSoC SPIM Wrapper Class
 * --------------------------------------------------------------------------
 *
 *  Usage
 *
 *  pdev_spi_t dev = CREATE_PDEV_SPI_T(INSTANCE_NAME);
 *  PSoC_SPIM  spi(&dev);
 *
 *  spi.write(0xXX);
 *  while(!(spi.dev->ReadTxStatus() & spi.STS_BYTE_COMPLETE));
 *  spi.read();
 */

typedef struct {
  void    (*Start)(void);
  uint8_t (*ReadTxStatus)(void);
  uint8_t (*ReadRxStatus)(void);
  void    (*WriteTxData)(uint8_t);
  uint8_t (*ReadRxData)(void);
} pdev_spi_t;

#define CREATE_PDEV_SPI_T(instance_name) { \
  .Start        = instance_name ## _Start, \
  .ReadTxStatus = instance_name ## _ReadTxStatus, \
  .ReadRxStatus = instance_name ## _ReadRxStatus, \
  .WriteTxData  = instance_name ## _WriteTxData, \
  .ReadRxData   = instance_name ## _ReadRxData \
}

class PSoC_SPIM {
  public:
    const pdev_spi_t * const dev;
    static const uint8_t STS_SPI_DONE           = 0x01;
    static const uint8_t STS_TX_FIFO_EMPTY      = 0x02;
    static const uint8_t STS_TX_FIFO_NOT_FULL   = 0x04;
    static const uint8_t STS_BYTE_COMPLETE      = 0x08;
    static const uint8_t STS_SPI_IDLE           = 0x10;
    static const uint8_t STS_RX_FIFO_FULL       = 0x10;
    static const uint8_t STS_RX_FIFO_NOT_EMPTY  = 0x20;
    static const uint8_t STS_RX_FIFO_OVERRUN    = 0x40;

    PSoC_SPIM(pdev_spi_t * _dev) : dev(_dev)
    {
      if(dev->Start) dev->Start();
    }

    inline void    write(uint8_t data) { dev->WriteTxData(data);   }
    inline uint8_t read(void)          { return dev->ReadRxData(); }
};