Skip to content

Commit e77c422

Browse files
committed
improved Spi for STM and AVR
1 parent c3f17a2 commit e77c422

20 files changed

+1247
-327
lines changed

src/modm/architecture/interface/spi.hpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,24 @@
1212
*/
1313
// ----------------------------------------------------------------------------
1414

15-
#ifndef MODM_INTERFACE_SPI_HPP
16-
#define MODM_INTERFACE_SPI_HPP
15+
#pragma once
1716

1817
#include <modm/architecture/interface/peripheral.hpp>
1918

2019
namespace modm
2120
{
21+
namespace spi
22+
{
23+
24+
template<class Spi>
25+
concept Support_DataSize_Bit16 = requires
26+
{ Spi::DataSize::Bit16; };
27+
28+
template<class Spi>
29+
concept Support_DataSize_Bit32 = requires
30+
{ Spi::DataSize::Bit32; };
31+
32+
} // namespace spi
2233

2334
/// @ingroup modm_architecture_spi
2435
struct Spi
@@ -43,8 +54,7 @@ struct Spi
4354
MsbFirst = 0b0,
4455
LsbFirst = 0b1,
4556
};
57+
4658
};
4759

4860
} // namespace modm
49-
50-
#endif // MODM_INTERFACE_SPI_HPP

src/modm/architecture/interface/spi_master.hpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
*/
1313
// ----------------------------------------------------------------------------
1414

15-
#ifndef MODM_INTERFACE_SPI_MASTER_HPP
16-
#define MODM_INTERFACE_SPI_MASTER_HPP
15+
#pragma once
1716

1817
#include <modm/processing/resumable.hpp>
1918
#include "spi.hpp"
@@ -156,8 +155,22 @@ class SpiMaster : public ::modm::PeripheralDriver, public Spi
156155
static modm::ResumableResult<void>
157156
transfer(const uint8_t *tx, uint8_t *rx, std::size_t length);
158157
#endif
158+
159+
public:
160+
enum State : uint8_t {
161+
Idle = Bit6, // Transaction is running
162+
Repeat = Bit7, // Send same tx multiple times
163+
};
164+
MODM_FLAGS8(State);
165+
166+
enum DataType : uint8_t {
167+
Byte = 0, // 1 byte
168+
HalfWord = 1, // 2 bytes
169+
Word = 2, // 4 bytes
170+
// WordWord = 3 // 8 bytes
171+
};
172+
typedef Value<State_t, 2> DataType_t;
173+
159174
};
160175

161176
} // namespace modm
162-
163-
#endif // MODM_INTERFACE_SPI_MASTER_HPP

src/modm/math/utils/binary.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2021, Thomas Sommer
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
11+
#pragma once
12+
13+
#include <limits>
14+
#include <concepts>
15+
16+
// TODO I'm not sure about this :/
17+
18+
namespace modm {
19+
template<typename T>
20+
concept unsigned_integral_max8 = std::unsigned_integral<T> and std::numeric_limits<T>::digits <= 8;
21+
22+
template<typename T>
23+
concept unsigned_integral_max16 = std::unsigned_integral<T> and std::numeric_limits<T>::digits <= 16;
24+
25+
template<typename T>
26+
concept unsigned_integral_max32 = std::unsigned_integral<T> and std::numeric_limits<T>::digits <= 32;
27+
28+
template<typename T>
29+
concept unsigned_integral_max64 = std::unsigned_integral<T> and std::numeric_limits<T>::digits <= 64;
30+
}

src/modm/platform/dma/stm32/dma.hpp.in

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ public:
190190
ChannelHal::setPeripheralAddress(address);
191191
}
192192

193+
static void
194+
setMemoryDataSize(MemoryDataSize memoryDataSize)
195+
{
196+
ChannelHal::setMemoryDataSize(memoryDataSize);
197+
}
198+
199+
static void
200+
setPeripheralDataSize(PeripheralDataSize peripheralDataSize)
201+
{
202+
ChannelHal::setPeripheralDataSize(peripheralDataSize);
203+
}
204+
193205
/**
194206
* Enable/disable memory increment
195207
*

src/modm/platform/dma/stm32/dma_base.hpp.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public:
155155
Bit16 = HalfWord,
156156
Word = {{ reg_prefix }}_MSIZE_1,
157157
Bit32 = Word,
158+
All = DMA_CCR_MSIZE_0 | DMA_CCR_MSIZE_1
158159
};
159160

160161
enum class
@@ -166,6 +167,7 @@ public:
166167
Bit16 = HalfWord,
167168
Word = {{ reg_prefix }}_PSIZE_1,
168169
Bit32 = Word,
170+
All = DMA_CCR_PSIZE_0 | DMA_CCR_PSIZE_1
169171
};
170172

171173
enum class

src/modm/platform/dma/stm32/dma_hal.hpp.in

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,22 @@ public:
250250
%% endif
251251
}
252252

253+
static void
254+
setMemoryDataSize(MemoryDataSize memoryDataSize)
255+
{
256+
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
257+
Base->CCR &= ~uint32_t(MemoryDataSize::All);
258+
Base->CCR |= uint32_t(memoryDataSize);
259+
}
260+
261+
static void
262+
setPeripheralDataSize(PeripheralDataSize peripheralDataSize)
263+
{
264+
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
265+
Base->CCR &= ~uint32_t(PeripheralDataSize::All);
266+
Base->CCR |= uint32_t(peripheralDataSize);
267+
}
268+
253269
/**
254270
* Enable/disable memory increment
255271
*
@@ -290,9 +306,11 @@ public:
290306

291307
/**
292308
* Set length of data to transfer
309+
*
310+
* @param lenght range: 0-65535
293311
*/
294312
static void
295-
setDataLength(std::size_t length)
313+
setDataLength(uint16_t length)
296314
{
297315
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
298316
%% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]

src/modm/platform/spi/at90_tiny_mega/module.lb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ class Instance(Module):
4848
env.substitutions = properties
4949
env.outbasepath = "modm/src/modm/platform/spi"
5050

51-
env.template("spi.hpp.in", "spi{}.hpp".format(self.instance))
51+
env.template("spi_base.hpp.in", "spi{}.hpp".format(self.instance))
5252
env.template("spi_master.hpp.in", "spi_master{}.hpp".format(self.instance))
53+
env.template("spi_master_impl.hpp.in", "spi_master{}_impl.hpp".format(self.instance))
5354
env.template("spi_master.cpp.in", "spi_master{}.cpp".format(self.instance))
5455

5556
def init(module):
@@ -87,6 +88,7 @@ def build(env):
8788
env.outbasepath = "modm/src/modm/platform/spi"
8889

8990
if "instance" not in driver:
91+
env.template("spi_base.hpp.in")
9092
env.template("spi_master.hpp.in")
93+
env.template("spi_master_impl.hpp.in")
9194
env.template("spi_master.cpp.in")
92-
env.template("spi.hpp.in")

src/modm/platform/spi/at90_tiny_mega/spi.hpp.in

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,14 @@
99
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
1010
*/
1111
// ----------------------------------------------------------------------------
12-
13-
#ifndef MODM_AVR_SPI_HPP
14-
#define MODM_AVR_SPI_HPP
12+
#pragma once
1513

1614
#include <avr/io.h>
1715

1816
/// @cond
1917
%% if partname in ["attiny40"]
2018
// The avr-libc Header files for the ATtiny40 is missing the following
21-
// defines although they are meantioned in the datasheet.
19+
// defines although they are mentioned in the datasheet.
2220
#define SPR0 0
2321
#define SPR1 1
2422
#define CPHA 2
@@ -51,10 +49,7 @@
5149
%% endif
5250
/// @endcond
5351

54-
namespace modm
55-
{
56-
57-
namespace platform
52+
namespace modm::platform
5853
{
5954

6055
/// @ingroup modm_platform_spi
@@ -71,10 +66,29 @@ struct Spi
7166
Div64 = (1 << SPR1{{ id }}),
7267
Div128 = (1 << SPR1{{ id }}) | (1 << SPR0{{ id }}),
7368
};
74-
};
7569

76-
} // namespace platform
70+
enum State : uint8_t {
71+
Idle = Bit6, // Transaction is running
72+
Repeat = Bit7, // Send same tx multiple times
73+
};
74+
MODM_FLAGS8(State);
75+
76+
enum DataType : uint8_t {
77+
Byte = 0, // 1 byte
78+
HalfWord = 1, // 2 bytes
79+
Word = 2, // 4 bytes
80+
// WordWord = 3 // 8 bytes
81+
};
82+
typedef Value<State_t, 2> DataType_t;
83+
};
7784

78-
} // namespace modm
85+
enum Type : uint8_t {
86+
Byte = 0, // 1 byte
87+
HalfWord = 1, // 2 bytes
88+
Word = 2, // 4 bytes
89+
// WordWord = 3 // 8 bytes
90+
};
91+
typedef Value<State_t, 2> Type_t;
92+
};
7993

80-
#endif // MODM_AVR_SPI_HPP
94+
} // namespace modm::platform
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2013-2015, 2017, Niklas Hauser
3+
* Copyright (c) 2017, Fabian Greif
4+
*
5+
* This file is part of the modm project.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
10+
*/
11+
// ----------------------------------------------------------------------------
12+
#pragma once
13+
14+
#include <avr/io.h>
15+
16+
/// @cond
17+
%% if partname in ["attiny40"]
18+
// The avr-libc Header files for the ATtiny40 is missing the following
19+
// defines although they are mentioned in the datasheet.
20+
#define SPR0 0
21+
#define SPR1 1
22+
#define CPHA 2
23+
#define CPOL 3
24+
#define MSTR 4
25+
#define DORD 5
26+
#define SPE 6
27+
#define SPIE 7
28+
29+
#define SPI2X 0
30+
#define WCOL 6
31+
#define SPIF 7
32+
%% elif partname in ["atmega164pa", "atmega324pa"]
33+
// The avr-libc Header files for the ATmega{16,32}4pa are declaring the
34+
// following registers with a trailing zero. Why, Atmel, whyyyy?
35+
#define SPCR SPCR0
36+
#define SPR0 SPR00
37+
#define SPR1 SPR10
38+
#define CPHA CPHA0
39+
#define CPOL CPOL0
40+
#define MSTR MSTR0
41+
#define DORD DORD0
42+
#define SPE SPE0
43+
#define SPIE SPIE0
44+
#define SPSR SPSR0
45+
#define SPI2X SPI2X0
46+
#define WCOL WCOL0
47+
#define SPIF SPIF0
48+
#define SPDR SPDR0
49+
%% endif
50+
/// @endcond
51+
52+
namespace modm::platform
53+
{
54+
55+
/// @ingroup modm_platform_spi
56+
struct SpiBase
57+
{
58+
enum class
59+
Prescaler : uint8_t
60+
{
61+
Div2 = 0x80 | 0,
62+
Div4 = 0,
63+
Div8 = 0x80 | (1 << SPR0{{ id }}),
64+
Div16 = (1 << SPR0{{ id }}),
65+
Div32 = 0x80 | (1 << SPR1{{ id }}),
66+
Div64 = (1 << SPR1{{ id }}),
67+
Div128 = (1 << SPR1{{ id }}) | (1 << SPR0{{ id }}),
68+
};
69+
};
70+
71+
} // namespace modm::platform

0 commit comments

Comments
 (0)