Skip to content

Commit da901d6

Browse files
committed
♻️ Cleanup stm32_generic::spi code
1 parent 395dce3 commit da901d6

File tree

4 files changed

+54
-44
lines changed

4 files changed

+54
-44
lines changed

demos/applications/spi.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ void application(resource_list& p_map)
4545
hal::delay(clock, 1s);
4646

4747
hal::print(console, "Read operation: [ ");
48+
chip_select.level(false);
4849
hal::read(spi, buffer);
50+
chip_select.level(true);
4951

5052
for (auto const& byte : buffer) {
5153
hal::print<32>(console, "0x%02X ", byte);
@@ -55,11 +57,15 @@ void application(resource_list& p_map)
5557
hal::delay(clock, 1s);
5658

5759
hal::print(console, "Full-duplex transfer\n");
60+
chip_select.level(false);
5861
spi.transfer(payload, buffer);
62+
chip_select.level(true);
5963
hal::delay(clock, 1s);
6064

6165
hal::print(console, "Half-duplex transfer\n");
66+
chip_select.level(false);
6267
hal::write_then_read(spi, payload, buffer);
68+
chip_select.level(true);
6369
hal::delay(clock, 1s);
6470

6571
{

demos/platforms/stm32f103c8.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ resource_list initialize_platform()
6565
.scl = &scl_output_pin,
6666
};
6767
static hal::bit_bang_i2c bit_bang_i2c(bit_bang_pins, steady_clock);
68+
6869
static hal::stm32f1::output_pin spi_chip_select('A', 4);
69-
static hal::stm32f1::spi spi1(hal::bus<2>,
70+
static hal::stm32f1::spi spi1(hal::bus<1>,
7071
{
7172
.clock_rate = 250.0_kHz,
7273
.clock_polarity = false,

src/stm32_generic/spi.cpp

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct control_register1
5454
/// Frame Format
5555
/// 0: msb transmitted first
5656
/// 1: lsb tranmitted first
57-
static constexpr auto frame_format = bit_mask::from<7>();
57+
static constexpr auto lsb_first = bit_mask::from<7>();
5858

5959
/// internal slave select
6060
static constexpr auto internal_slave_select = bit_mask::from<8>();
@@ -65,40 +65,37 @@ struct control_register1
6565

6666
/// Recieve only
6767
/// 0: Full Duplex, 1: Output disable
68-
[[maybe_unused]] static constexpr auto rx_only = bit_mask::from<10>();
68+
static constexpr auto rx_only = bit_mask::from<10>();
6969

7070
/// Data frame format
7171
/// 0: 8-bits, 1: 16-bit
72-
[[maybe_unused]] static constexpr auto data_frame_format =
73-
bit_mask::from<11>();
72+
static constexpr auto data_frame_format = bit_mask::from<11>();
7473

7574
/// CRC transfer next
7675
/// 0: No CRC phase, 1: transfer CRC next
77-
[[maybe_unused]] static constexpr auto crc_transfer_next =
78-
bit_mask::from<12>();
76+
static constexpr auto crc_transfer_next = bit_mask::from<12>();
7977

8078
/// CRC enable
8179
/// 0: disable, 1: enable
82-
[[maybe_unused]] static constexpr auto crc_enable = bit_mask::from<13>();
80+
static constexpr auto crc_enable = bit_mask::from<13>();
8381

8482
/// Output enable in bidirectional mode
8583
/// 0: output disabled, 1: output enable
8684
static constexpr auto bidirectional_output_enable = bit_mask::from<14>();
8785

8886
/// Bidirectional data mode enable
8987
/// 0: full-duplex, 1: half-duplex
90-
[[maybe_unused]] static constexpr auto bidirectional_mode_enable =
91-
bit_mask::from<15>();
88+
static constexpr auto bidirectional_mode_enable = bit_mask::from<15>();
9289
};
9390

9491
/// SPI Control Register 2
9592
struct control_register2
9693
{
9794
/// Rx buffer DMA enable
98-
[[maybe_unused]] static constexpr auto rx_dma_enable = bit_mask::from<0>();
95+
static constexpr auto rx_dma_enable = bit_mask::from<0>();
9996

10097
/// Tx buffer DMA enable
101-
[[maybe_unused]] static constexpr auto tx_dma_enable = bit_mask::from<1>();
98+
static constexpr auto tx_dma_enable = bit_mask::from<1>();
10299

103100
/// Slave select output enable
104101
/// 0: use a GPIO, 1: use the NSS pin
@@ -109,16 +106,13 @@ struct control_register2
109106
static constexpr auto frame_format = bit_mask::from<4>();
110107

111108
/// Error interupt enable
112-
[[maybe_unused]] static constexpr auto error_interrupt_enable =
113-
bit_mask::from<5>();
109+
static constexpr auto error_interrupt_enable = bit_mask::from<5>();
114110

115111
/// Rx buffer empty interrupt enable
116-
[[maybe_unused]] static constexpr auto rx_buffer_empty_interrupt_enable =
117-
bit_mask::from<6>();
112+
static constexpr auto rx_buffer_empty_interrupt_enable = bit_mask::from<6>();
118113

119114
/// Tx buffer empty interrupt enable
120-
[[maybe_unused]] static constexpr auto tx_buffer_empty_interrupt_enable =
121-
bit_mask::from<7>();
115+
static constexpr auto tx_buffer_empty_interrupt_enable = bit_mask::from<7>();
122116
};
123117

124118
/// SPI Status Register
@@ -131,8 +125,8 @@ struct status_register
131125
static constexpr auto tx_buffer_empty = bit_mask::from<1>();
132126

133127
/// Channel side (i2s only)
134-
/// 0: left has been transmitted/recieved
135-
/// 1: right has been transmitted/recieved
128+
/// 0: left has been transmitted/received
129+
/// 1: right has been transmitted/received
136130
[[maybe_unused]] static constexpr auto i2s_channel_side = bit_mask::from<2>();
137131

138132
/// Underrun flag
@@ -190,19 +184,20 @@ spi::spi(hal::unsafe, void* p_peripheral_address)
190184

191185
spi::~spi()
192186
{
187+
auto& reg = to_reg(m_peripheral_address);
188+
bit_modify(reg.cr1).clear<control_register1::enable>();
193189
}
194190

195191
void spi::configure(hal::spi::settings const& p_settings,
196192
hal::hertz p_peripheral_clock_speed)
197193
{
198-
auto& reg = to_reg(m_peripheral_address);
194+
using namespace hal::literals;
199195

200-
// Set SPI to master mode by clearing
201-
bit_modify(reg.cr1).set(control_register1::master_selection);
196+
auto& reg = to_reg(m_peripheral_address);
202197

203-
using namespace hal::literals;
204198
auto const clock_divider = p_peripheral_clock_speed / p_settings.clock_rate;
205199
auto prescaler = static_cast<std::uint16_t>(clock_divider);
200+
206201
if (prescaler <= 1) {
207202
prescaler = 2;
208203
} else if (prescaler > 256) {
@@ -213,25 +208,33 @@ void spi::configure(hal::spi::settings const& p_settings,
213208
if (std::has_single_bit(prescaler)) {
214209
baud_control--;
215210
}
216-
bit_modify(reg.cr1)
217-
.insert<control_register1::baud_rate_control>(baud_control)
218-
.insert<control_register1::clock_phase>(
219-
p_settings.data_valid_on_trailing_edge)
220-
.insert<control_register1::clock_polarity>(p_settings.clock_idles_high)
221-
.set<control_register1::bidirectional_output_enable>()
222-
.set<control_register1::software_slave_management>()
223-
.set<control_register1::internal_slave_select>()
224-
.clear<control_register1::frame_format>();
225211

226212
bit_modify(reg.cr2)
213+
.clear<control_register2::rx_dma_enable>()
214+
.clear<control_register2::tx_dma_enable>()
215+
// We set `slave_select_output_enable` because it is required for master
216+
// mode to work.
227217
.set<control_register2::slave_select_output_enable>()
228-
.clear<control_register2::frame_format>();
229-
230-
bit_modify(reg.cr1).set<control_register1::master_selection>();
218+
.clear<control_register2::frame_format>()
219+
.clear<control_register2::error_interrupt_enable>()
220+
.clear<control_register2::rx_buffer_empty_interrupt_enable>()
221+
.clear<control_register2::tx_buffer_empty_interrupt_enable>();
231222

232223
bit_modify(reg.cr1)
233-
.set<control_register1::enable>()
234-
.clear<control_register1::internal_slave_select>();
224+
.clear<control_register1::rx_only>()
225+
.clear<control_register1::crc_transfer_next>()
226+
.clear<control_register1::data_frame_format>()
227+
.clear<control_register1::crc_enable>()
228+
.clear<control_register1::lsb_first>()
229+
.clear<control_register1::bidirectional_mode_enable>()
230+
.clear<control_register1::bidirectional_output_enable>()
231+
.insert<control_register1::baud_rate_control>(baud_control)
232+
.insert<control_register1::clock_phase>(p_settings.clock_phase)
233+
.insert<control_register1::clock_polarity>(p_settings.clock_polarity)
234+
.set<control_register1::internal_slave_select>() // same as disabled
235+
.set<control_register1::software_slave_management>()
236+
.set<control_register1::master_selection>()
237+
.set<control_register1::enable>();
235238
}
236239

237240
void spi::transfer(std::span<hal::byte const> p_data_out,
@@ -250,7 +253,7 @@ void spi::transfer(std::span<hal::byte const> p_data_out,
250253
// The stm's spi driver needs to be internally told that it is selecting a
251254
// device before it will emit anything on the pins. This will control the NSS
252255
// pin if it is selected, otherwise, its just an internal enable signal.
253-
bit_modify(reg.cr1).set<control_register1::internal_slave_select>();
256+
bit_modify(reg.cr1).clear<control_register1::internal_slave_select>();
254257

255258
for (size_t index = 0; index < max_length; index++) {
256259
hal::byte byte = 0;
@@ -277,7 +280,7 @@ void spi::transfer(std::span<hal::byte const> p_data_out,
277280
}
278281
}
279282

280-
bit_modify(reg.cr1).clear<control_register1::internal_slave_select>();
283+
bit_modify(reg.cr1).set<control_register1::internal_slave_select>();
281284

282285
// Wait for bus activity to cease before leaving the function
283286
while (busy(reg)) {

src/stm32f1/spi.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ spi::spi(std::uint8_t p_bus_number, spi::settings const& p_settings)
6464
// Datasheet: Chapter 4: Pin definition Table 9
6565
switch (m_peripheral_id) {
6666
case peripheral::spi1: {
67+
hal::bit_modify(alternative_function_io->mapr)
68+
.clear<pin_remap::spi1_remap>();
6769
// clock
6870
configure_pin({ .port = 'A', .pin = 5 }, push_pull_alternative_output);
6971
// cipo
7072
configure_pin({ .port = 'A', .pin = 6 }, input_float);
7173
// copi
7274
configure_pin({ .port = 'A', .pin = 7 }, push_pull_alternative_output);
73-
hal::bit_modify(alternative_function_io->mapr)
74-
.clear<pin_remap::spi1_remap>();
7575
break;
7676
}
7777
case peripheral::spi2: {
@@ -84,14 +84,14 @@ spi::spi(std::uint8_t p_bus_number, spi::settings const& p_settings)
8484
break;
8585
}
8686
case peripheral::spi3: {
87+
hal::bit_modify(alternative_function_io->mapr2)
88+
.set<pin_remap2::spi3_remap>();
8789
// clock
8890
configure_pin({ .port = 'C', .pin = 10 }, push_pull_alternative_output);
8991
// cipo
9092
configure_pin({ .port = 'C', .pin = 11 }, input_float);
9193
// copi
9294
configure_pin({ .port = 'C', .pin = 12 }, push_pull_alternative_output);
93-
hal::bit_modify(alternative_function_io->mapr2)
94-
.clear<pin_remap2::spi3_remap>();
9595
break;
9696
}
9797
default:

0 commit comments

Comments
 (0)