OpenMPTL - STM32 (common)
C++ Microprocessor Template Library
spi.hpp
Go to the documentation of this file.
1 /*
2  * OpenMPTL - C++ Microprocessor Template Library
3  *
4  * Copyright (C) 2012-2017 Axel Burri <axel@tty0.ch>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 /*
22  * This program contains derivative representations of CMSIS System
23  * View Description (SVD) files, and is subject to the "End User
24  * License Agreement for STMicroelectronics" (see "STM_License.html"
25  * in the containing directory).
26  */
27 
28 #ifndef ARM_CORTEX_STM32_COMMON_REG_SPI_HPP_INCLUDED
29 #define ARM_CORTEX_STM32_COMMON_REG_SPI_HPP_INCLUDED
30 
31 #include <register.hpp>
32 
33 namespace mptl {
34 
35 /**
36  * Serial peripheral interface (SPI)
37  *
38  * NOTE: We use std::uint_fast16_t to access the registers. This way we
39  * leave it up to the compiler to use either 16-bit or 32-bit
40  * integers for the access_type. More precicely: "use fastest
41  * unsigned integer type with width of at least 16 bits". In most
42  * situations the compiler (gcc-4.8) will use 32bit integers.
43  */
44 template<reg_addr_t _base_addr>
45 struct SPI_Common
46 {
47  static constexpr reg_addr_t base_addr = _base_addr;
48 
49  /**
50  * Control register 1
51  */
52  struct CR1
53  : public reg< std::uint_fast16_t, base_addr + 0x00, rw, 0x0000 >
54  {
56 
57  /** Baud Rate Control */
58  template<typename Rb>
59  struct __BR
60  : public Rb
61  {
62  template<unsigned prescaler>
63  struct Prescaler
64  : public regval< Rb,
65  prescaler == 2 ? 0x0 : /**< f_PCLK / 2 */
66  prescaler == 4 ? 0x1 : /**< f_PCLK / 4 */
67  prescaler == 8 ? 0x2 : /**< f_PCLK / 8 */
68  prescaler == 16 ? 0x3 : /**< f_PCLK / 16 */
69  prescaler == 32 ? 0x4 : /**< f_PCLK / 32 */
70  prescaler == 64 ? 0x5 : /**< f_PCLK / 64 */
71  prescaler == 128 ? 0x6 : /**< f_PCLK / 128 */
72  prescaler == 256 ? 0x7 : /**< f_PCLK / 256 */
73  0
74  >
75  {
76  static_assert(prescaler == 2 || prescaler == 4 || prescaler == 8 || prescaler == 16 ||
77  prescaler == 32 || prescaler == 64 || prescaler == 128 || prescaler == 256
78  , "invalid baud rate prescaler");
79  };
80  };
81 
82  using BIDIMODE = regbits< type, 15, 1 >; /**< Bidirectional data mode enable */
83  using BIDIOE = regbits< type, 14, 1 >; /**< Output enable in bidirectional mode */
84  using CRCEN = regbits< type, 13, 1 >; /**< Hardware CRC calculation enable */
85  using CRCNEXT = regbits< type, 12, 1 >; /**< CRC transfer next */
86  using DFF = regbits< type, 11, 1 >; /**< Data frame format */
87  using RXONLY = regbits< type, 10, 1 >; /**< Receive only */
88  using SSM = regbits< type, 9, 1 >; /**< Software slave management */
89  using SSI = regbits< type, 8, 1 >; /**< Internal slave select */
90  using LSBFIRST = regbits< type, 7, 1 >; /**< Frame format */
91  using SPE = regbits< type, 6, 1 >; /**< SPI enable */
92  using BR = __BR < regbits< type, 3, 3 > >; /**< Baud rate control */
93  using MSTR = regbits< type, 2, 1 >; /**< Master selection */
94  using CPOL = regbits< type, 1, 1 >; /**< Clock polarity */
95  using CPHA = regbits< type, 0, 1 >; /**< Clock phase */
96  };
97 
98  /**
99  * Control register 2
100  */
101  struct CR2
102  : public reg< std::uint_fast16_t, base_addr + 0x04, rw, 0x0000 >
103  {
105 
106  using TXEIE = regbits< type, 7, 1 >; /**< Tx buffer empty interrupt enable */
107  using RXNEIE = regbits< type, 6, 1 >; /**< Rx buffer not empty interrupt enable */
108  using ERRIE = regbits< type, 5, 1 >; /**< Error interrupt enable */
109  using SSOE = regbits< type, 2, 1 >; /**< SS output enable */
110  using TXDMAEN = regbits< type, 1, 1 >; /**< Tx buffer DMA enable */
111  using RXDMAEN = regbits< type, 0, 1 >; /**< Rx buffer DMA enable */
112  };
113 
114  /**
115  * Status register
116  */
117  struct SR
118  : public reg< std::uint_fast16_t, base_addr + 0x08, rw, 0x0002 >
119  {
121 
122  using BSY = regbits< type, 7, 1 >; /**< Busy flag */
123  using OVR = regbits< type, 6, 1 >; /**< Overrun flag */
124  using MODF = regbits< type, 5, 1 >; /**< Mode fault */
125  using CRCERR = regbits< type, 4, 1 >; /**< CRC error flag */
126  using UDR = regbits< type, 3, 1 >; /**< Underrun flag */
127  using CHSIDE = regbits< type, 2, 1 >; /**< Channel side */
128  using TXE = regbits< type, 1, 1 >; /**< Transmit buffer empty */
129  using RXNE = regbits< type, 0, 1 >; /**< Receive buffer not empty */
130  };
131 
132  /**
133  * Data register
134  */
136 
137  /**
138  * CRC polynomial register
139  */
141 
142  /**
143  * Rx CRC register
144  */
146 
147  /**
148  * Tx CRC register
149  */
151 
152  /**
153  * I2S configuration register
154  */
155  struct I2SCFGR
156  : public reg< std::uint_fast16_t, base_addr + 0x1c, rw, 0x0000 >
157  {
159 
160  using I2SMOD = regbits< type, 11, 1 >; /**< I2S mode selection */
161  using I2SE = regbits< type, 10, 1 >; /**< I2S Enable */
162  using I2SCFG = regbits< type, 8, 2 >; /**< I2S configuration mode */
163  using PCMSYNC = regbits< type, 7, 1 >; /**< PCM frame synchronization */
164  using I2SSTD = regbits< type, 4, 2 >; /**< I2S standard selection */
165  using CKPOL = regbits< type, 3, 1 >; /**< Steady state clock polarity */
166  using DATLEN = regbits< type, 1, 2 >; /**< Data length to be transferred */
167  using CHLEN = regbits< type, 0, 1 >; /**< Channel length (number of bits per audio channel) */
168  };
169 
170  /**
171  * I2S prescaler register
172  */
173  struct I2SPR
174  : public reg< std::uint_fast16_t, base_addr + 0x20, rw, 00000010 >
175  {
177 
178  using MCKOE = regbits< type, 9, 1 >; /**< Master clock output enable */
179  using ODD = regbits< type, 8, 1 >; /**< Odd factor for the prescaler */
180  using I2SDIV = regbits< type, 0, 8 >; /**< I2S Linear prescaler */
181  };
182 };
183 
184 
185 /**
186  * Some architectures (e.g. stm32f4xx) support multiple frame formats
187  */
188 template<reg_addr_t base_addr>
189 class SPI_Common_Ext : public SPI_Common<base_addr>
190 {
192 
193 public:
194 
195  struct CR2 : public base_type::CR2 {
197  };
198  struct SR : public base_type::SR {
199  using RFE = regbits< typename base_type::SR::type, 8, 1 >; /**< Frame format error */
200  };
201 };
202 
203 } // namespace mptl
204 
205 #endif // ARM_CORTEX_STM32_COMMON_REG_SPI_HPP_INCLUDED
Some architectures (e.g.
Definition: spi.hpp:189
Baud Rate Control.
Definition: spi.hpp:59
Definition: spi.hpp:198
I2S configuration register.
Definition: spi.hpp:155
uintptr_t reg_addr_t
Control register 1.
Definition: spi.hpp:52
Status register.
Definition: spi.hpp:117
I2S prescaler register.
Definition: spi.hpp:173
static constexpr reg_addr_t base_addr
Definition: spi.hpp:47
Definition: spi.hpp:195
Serial peripheral interface (SPI)
Definition: spi.hpp:45
Control register 2.
Definition: spi.hpp:101