/* * spi.h * * Created on: 29.07.2018 * Author: eyck */ #ifndef SPI_H_ #define SPI_H_ #include #include "util/bit_field.h" #include #include template class spi_regs { public: // storage declarations BEGIN_BF_DECL(sckdiv_t, uint32_t); BF_FIELD(div, 0, 12); END_BF_DECL(); BEGIN_BF_DECL(sckmode_t, uint32_t); BF_FIELD(pha, 0, 1); BF_FIELD(pol, 1, 1); END_BF_DECL(); uint32_t r_csid; uint32_t r_csdef; BEGIN_BF_DECL(csmode_t, uint32_t); BF_FIELD(mode, 0, 2); END_BF_DECL(); BEGIN_BF_DECL(delay0_t, uint32_t); BF_FIELD(cssck, 0, 8); BF_FIELD(sckcs, 16, 8); END_BF_DECL(); BEGIN_BF_DECL(delay1_t, uint32_t); BF_FIELD(intercs, 0, 16); BF_FIELD(interxfr, 16, 8); END_BF_DECL(); BEGIN_BF_DECL(fmt_t, uint32_t); BF_FIELD(proto, 0, 2); BF_FIELD(endian, 2, 1); BF_FIELD(dir, 3, 1); BF_FIELD(len, 16, 4); END_BF_DECL(); BEGIN_BF_DECL(txdata_t, uint32_t); BF_FIELD(data, 0, 8); BF_FIELD(full, 31, 1); END_BF_DECL() r_txdata; BEGIN_BF_DECL(rxdata_t, uint32_t); BF_FIELD(data, 0, 8); BF_FIELD(empty, 31, 1); END_BF_DECL(); BEGIN_BF_DECL(txmark_t, uint32_t); BF_FIELD(txmark, 0, 3); END_BF_DECL(); BEGIN_BF_DECL(rxmark_t, uint32_t); BF_FIELD(rxmark, 0, 3); END_BF_DECL(); BEGIN_BF_DECL(fctrl_t, uint32_t); BF_FIELD(en, 0, 1); END_BF_DECL(); BEGIN_BF_DECL(ffmt_t, uint32_t); BF_FIELD(cmd_en, 0, 1); BF_FIELD(addr_len, 1, 2); BF_FIELD(pad_cnt, 3, 4); BF_FIELD(cmd_proto, 7, 2); BF_FIELD(addr_proto, 9, 2); BF_FIELD(data_proto, 11, 2); BF_FIELD(cmd_code, 16, 8); BF_FIELD(pad_code, 24, 8); END_BF_DECL(); BEGIN_BF_DECL(ie_t, uint32_t); BF_FIELD(txwm, 0, 1); BF_FIELD(rxwm, 1, 1); END_BF_DECL(); BEGIN_BF_DECL(ip_t, uint32_t); BF_FIELD(txwm, 0, 1); BF_FIELD(rxwm, 1, 1); END_BF_DECL(); static inline sckdiv_t& sckdiv_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_SCKDIV); } static inline sckmode_t& sckmode_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_SCKMODE); } static inline uint32_t& csid_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_CSID); } static inline uint32_t& csdef_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_CSDEF); } static inline csmode_t& csmode_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_CSMODE); } static inline delay0_t& dcssck_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_DCSSCK); } static inline uint32_t& dsckcs_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_DSCKCS); } static inline delay1_t& dintercs_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_DINTERCS); } static inline uint32_t& dinterxfr_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_DINTERXFR); } static inline fmt_t& fmt_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_FMT); } static inline txdata_t& txfifo_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_TXFIFO); } static inline rxdata_t& rxfifo_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_RXFIFO); } static inline txmark_t& txctrl_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_TXCTRL); } static inline rxmark_t& rxctrl_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_RXCTRL); } static inline fctrl_t& fctrl_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_FCTRL); } static inline ffmt_t& ffmt_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_FFMT); } static inline ie_t& ie_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_IE); } static inline ip_t& ip_reg(){ return *reinterpret_cast(BASE_ADDR+SPI_REG_IP); } template static bool transfer(std::array& bytes){ csmode_reg().mode=2; // HOLD mode rxctrl_reg().rxmark=bytes.size()-1; // trigger irq if more than 2 bytes are received; ie_reg().rxwm=1; // write data bytes for(size_t i=0; i