libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
mspm0_spi.hpp
1#pragma once
2
3#include <ti/driverlib/dl_dma.h>
4#include <ti/driverlib/dl_spi.h>
5
6#include "spi.hpp"
7#include "ti_msp_dl_config.h"
8
9namespace LibXR
10{
11
21class MSPM0SPI : public SPI
22{
23 public:
24 struct Resources
25 {
26 SPI_Regs* instance;
27 IRQn_Type irqn;
28 uint32_t clock_freq;
29 uint8_t index;
30 uint8_t dma_rx_channel;
31 uint8_t dma_tx_channel;
32 };
33
34 MSPM0SPI(Resources res, RawData dma_rx_buffer, RawData dma_tx_buffer,
35 uint32_t dma_enable_min_size = 3,
37 SPI::Prescaler::DIV_4, false});
38
39 ErrorCode ReadAndWrite(RawData read_data, ConstRawData write_data, OperationRW& op,
40 bool in_isr = false) override;
41
42 ErrorCode SetConfig(SPI::Configuration config) override;
43
44 ErrorCode MemRead(uint16_t reg, RawData read_data, OperationRW& op,
45 bool in_isr = false) override;
46
47 ErrorCode MemWrite(uint16_t reg, ConstRawData write_data, OperationRW& op,
48 bool in_isr = false) override;
49
50 uint32_t GetMaxBusSpeed() const override;
51
52 Prescaler GetMaxPrescaler() const override;
53
54 ErrorCode Transfer(size_t size, OperationRW& op, bool in_isr = false) override;
55
56 static void OnInterrupt(uint8_t index);
57
58 static constexpr uint8_t ResolveIndex(IRQn_Type irqn)
59 {
60 switch (irqn)
61 {
62#if defined(SPI0_BASE)
63 case SPI0_INT_IRQn:
64 return 0;
65#endif
66#if defined(SPI1_BASE)
67 case SPI1_INT_IRQn:
68 return 1;
69#endif
70#if defined(SPI2_BASE)
71 case SPI2_INT_IRQn:
72 return 2;
73#endif
74 default:
75 return INVALID_INSTANCE_INDEX;
76 }
77 }
78
79 private:
80 enum class DmaMode : uint8_t
81 {
82 DUPLEX,
83 RX_ONLY,
84 TX_ONLY
85 };
86
87#if defined(SPI2_BASE)
88 static constexpr uint8_t MAX_SPI_INSTANCES = 3;
89#elif defined(SPI1_BASE)
90 static constexpr uint8_t MAX_SPI_INSTANCES = 2;
91#else
92 static constexpr uint8_t MAX_SPI_INSTANCES = 1;
93#endif
94 static constexpr uint8_t INVALID_INSTANCE_INDEX = 0xFF;
95 static constexpr uint32_t RX_ONLY_REPEAT_TX_MAX_FRAMES = 256U;
96
97 ErrorCode PollingTransfer(uint8_t* rx, const uint8_t* tx, uint32_t len);
98
99 ErrorCode CompleteDmaOperation(OperationRW& op, bool in_isr);
100
101 void StartDmaDuplex(uint32_t count);
102
103 void StartDmaRxOnly(uint32_t offset, uint32_t count);
104
105 void StartDmaTxOnly(uint32_t count);
106
107 void StopDma();
108
109 void HandleInterrupt();
110
111 bool DmaBusy() const;
112
113 Resources res_;
114 uint32_t dma_enable_min_size_;
115 OperationRW rw_op_;
116 volatile ErrorCode dma_result_ = ErrorCode::OK;
117 RawData read_buff_;
118 bool mem_read_ = false;
119 DmaMode dma_mode_ = DmaMode::DUPLEX;
120 uint32_t masked_interrupts_for_tx_only_ = 0;
121 uint32_t rx_only_offset_ = 0;
122 uint32_t rx_only_remaining_ = 0;
123 volatile bool busy_ = false;
124
125 static MSPM0SPI* instance_map_[MAX_SPI_INSTANCES];
126};
127
136#define MSPM0_SPI_INIT(name, clock_hz, dma_rx_name, dma_tx_name, rx_buffer_addr, \
137 rx_buffer_size, tx_buffer_addr, tx_buffer_size, dma_min_size) \
138 ::LibXR::MSPM0SPI::Resources{name##_INST, \
139 name##_INST_INT_IRQN, \
140 static_cast<uint32_t>(clock_hz), \
141 ::LibXR::MSPM0SPI::ResolveIndex(name##_INST_INT_IRQN), \
142 static_cast<uint8_t>(dma_rx_name##_CHAN_ID), \
143 static_cast<uint8_t>(dma_tx_name##_CHAN_ID)}, \
144 ::LibXR::RawData{(rx_buffer_addr), (rx_buffer_size)}, \
145 ::LibXR::RawData{(tx_buffer_addr), (tx_buffer_size)}, (dma_min_size)
146
147} // namespace LibXR
只读原始数据视图 / Immutable raw data view
MSPM0 SPI 控制器 / MSPM0 SPI controller.
Definition mspm0_spi.hpp:22
uint32_t GetMaxBusSpeed() const override
获取 SPI 设备的最大时钟速度 / Gets the maximum clock speed of the SPI device.
Definition mspm0_spi.cpp:84
ErrorCode Transfer(size_t size, OperationRW &op, bool in_isr=false) override
进行一次SPI传输(使用当前缓冲区数据,零拷贝,支持双缓冲)。 Performs a SPI transfer (zero-copy, supports double buffering).
ErrorCode SetConfig(SPI::Configuration config) override
设置 SPI 配置参数 / Sets SPI configuration parameters.
Definition mspm0_spi.cpp:51
Prescaler GetMaxPrescaler() const override
获取 SPI 设备的最大分频系数 / Gets the maximum prescaler of the SPI device.
Definition mspm0_spi.cpp:86
ErrorCode MemWrite(uint16_t reg, ConstRawData write_data, OperationRW &op, bool in_isr=false) override
向 SPI 设备的寄存器写入数据。 Writes data to a specific register of the SPI device.
ErrorCode ReadAndWrite(RawData read_data, ConstRawData write_data, OperationRW &op, bool in_isr=false) override
进行 SPI 读写操作 / Performs SPI read and write operations.
ErrorCode MemRead(uint16_t reg, RawData read_data, OperationRW &op, bool in_isr=false) override
从 SPI 设备的寄存器读取数据。 Reads data from a specific register of the SPI device.
可写原始数据视图 / Mutable raw data view
串行外设接口(SPI)抽象类。 Abstract class for Serial Peripheral Interface (SPI).
Definition spi.hpp:15
@ EDGE_1
在第一个时钟边沿采样数据 / Data sampled on the first clock edge.
@ DIV_4
分频系数为 4 / Division factor is 4.
WriteOperation OperationRW
定义读写操作类型的别名 / Defines an alias for the read/write operation type.
Definition spi.hpp:63
@ LOW
时钟空闲时为低电平 / Clock idle low.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ OK
操作成功 / Operation successful
存储 SPI 配置参数的结构体。 Structure for storing SPI configuration parameters.
Definition spi.hpp:86