🧑💻 Update GD32 MFL Platform, Arduino Core (#27830)
This commit is contained in:
parent
735cd9a092
commit
c9e7d6f55c
11 changed files with 253 additions and 242 deletions
|
|
@ -105,7 +105,7 @@ extern "C" char* dtostrf(double val, signed char width, unsigned char prec, char
|
||||||
class MarlinHAL {
|
class MarlinHAL {
|
||||||
public:
|
public:
|
||||||
// Before setup()
|
// Before setup()
|
||||||
MarlinHAL() {}
|
MarlinHAL() = default;
|
||||||
|
|
||||||
// Watchdog
|
// Watchdog
|
||||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@
|
||||||
|
|
||||||
using namespace arduino;
|
using namespace arduino;
|
||||||
|
|
||||||
MarlinSerial& MarlinSerial::get_instance(usart::USART_Base Base, pin_size_t rxPin, pin_size_t txPin) {
|
auto MarlinSerial::get_instance(usart::USART_Base Base, pin_size_t rxPin, pin_size_t txPin) -> MarlinSerial& {
|
||||||
UsartSerial& serial = UsartSerial::get_instance(Base, rxPin, txPin);
|
auto& serial = UsartSerial::get_instance(Base, rxPin, txPin);
|
||||||
return *reinterpret_cast<MarlinSerial*>(&serial);
|
return *reinterpret_cast<MarlinSerial*>(&serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ MarlinSerial& MarlinSerial::get_instance(usart::USART_Base Base, pin_size_t rxPi
|
||||||
|
|
||||||
static void emergency_callback() {
|
static void emergency_callback() {
|
||||||
if (!current_serial_instance) return;
|
if (!current_serial_instance) return;
|
||||||
const uint8_t last_data = current_serial_instance->get_last_data();
|
const auto last_data = current_serial_instance->get_last_data();
|
||||||
emergency_parser.update(current_serial_instance->emergency_state, last_data);
|
emergency_parser.update(current_serial_instance->emergency_state, last_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
using namespace arduino;
|
using namespace arduino;
|
||||||
|
|
||||||
struct MarlinSerial : public UsartSerial {
|
struct MarlinSerial : public UsartSerial {
|
||||||
static MarlinSerial& get_instance(usart::USART_Base Base, pin_size_t rxPin = NO_PIN, pin_size_t txPin = NO_PIN);
|
static auto get_instance(usart::USART_Base Base, pin_size_t rxPin = NO_PIN, pin_size_t txPin = NO_PIN) -> MarlinSerial&;
|
||||||
|
|
||||||
void begin(unsigned long baudrate, uint16_t config);
|
void begin(unsigned long baudrate, uint16_t config);
|
||||||
inline void begin(unsigned long baudrate) { begin(baudrate, SERIAL_8N1); }
|
inline void begin(unsigned long baudrate) { begin(baudrate, SERIAL_8N1); }
|
||||||
|
|
@ -57,7 +57,7 @@ struct MarlinSerial : public UsartSerial {
|
||||||
EmergencyParser::State emergency_state;
|
EmergencyParser::State emergency_state;
|
||||||
|
|
||||||
// Accessor method to get the last received byte
|
// Accessor method to get the last received byte
|
||||||
uint8_t get_last_data() { return usart_.get_last_data(); }
|
auto get_last_data() -> uint8_t { return usart_.get_last_data(); }
|
||||||
|
|
||||||
// Register the emergency callback
|
// Register the emergency callback
|
||||||
void register_emergency_callback(void (*callback)());
|
void register_emergency_callback(void (*callback)());
|
||||||
|
|
|
||||||
|
|
@ -21,26 +21,27 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Fast I/O interfaces for GD32F303RE
|
// Fast I/O interfaces for GD32
|
||||||
|
|
||||||
#include <GPIO.hpp>
|
#include <GPIO.hpp>
|
||||||
|
#include <variant.h>
|
||||||
#include <PinOps.hpp>
|
#include <PinOps.hpp>
|
||||||
#include <PinOpsMap.hpp>
|
#include <PinOpsMap.hpp>
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline void fast_write_pin_wrapper(pin_size_t IO, T V) {
|
static inline void fast_write_pin_wrapper(pin_size_t IO, T V) {
|
||||||
auto port = getPortFromPin(IO);
|
const PortPinPair& pp = port_pin_map[IO];
|
||||||
auto pin = getPinInPort(IO);
|
gpio::fast_write_pin(pp.port, pp.pin, static_cast<bool>(V));
|
||||||
if (static_cast<bool>(V)) gpio::fast_set_pin(port, pin);
|
|
||||||
else gpio::fast_clear_pin(port, pin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool fast_read_pin_wrapper(pin_size_t IO) {
|
static inline auto fast_read_pin_wrapper(pin_size_t IO) -> bool {
|
||||||
return gpio::fast_read_pin(getPortFromPin(IO), getPinInPort(IO));
|
const PortPinPair& pp = port_pin_map[IO];
|
||||||
|
return gpio::fast_read_pin(pp.port, pp.pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void fast_toggle_pin_wrapper(pin_size_t IO) {
|
static inline void fast_toggle_pin_wrapper(pin_size_t IO) {
|
||||||
gpio::fast_toggle_pin(getPortFromPin(IO), getPinInPort(IO));
|
const PortPinPair& pp = port_pin_map[IO];
|
||||||
|
gpio::fast_toggle_pin(pp.port, pp.pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,9 @@ bool isAnalogPin(const pin_t pin) {
|
||||||
if (!isValidPin(pin)) return false;
|
if (!isValidPin(pin)) return false;
|
||||||
|
|
||||||
if (getAdcChannel(pin) != adc::ADC_Channel::INVALID) {
|
if (getAdcChannel(pin) != adc::ADC_Channel::INVALID) {
|
||||||
auto& instance = gpio::GPIO::get_instance(getPortFromPin(pin)).value();
|
const PortPinPair& pp = port_pin_map[pin];
|
||||||
return instance.get_pin_mode(getPinInPort(pin)) == gpio::Pin_Mode::ANALOG && !M43_NEVER_TOUCH(pin);
|
auto& instance = gpio::GPIO::get_instance(pp.port).value();
|
||||||
|
return instance.get_pin_mode(pp.pin) == gpio::Pin_Mode::ANALOG && !M43_NEVER_TOUCH(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -80,8 +81,9 @@ bool isAnalogPin(const pin_t pin) {
|
||||||
bool getValidPinMode(const pin_t pin) {
|
bool getValidPinMode(const pin_t pin) {
|
||||||
if (!isValidPin(pin)) return false;
|
if (!isValidPin(pin)) return false;
|
||||||
|
|
||||||
auto& instance = gpio::GPIO::get_instance(getPortFromPin(pin)).value();
|
const PortPinPair& pp = port_pin_map[pin];
|
||||||
gpio::Pin_Mode mode = instance.get_pin_mode(getPinInPort(pin));
|
auto& instance = gpio::GPIO::get_instance(pp.port).value();
|
||||||
|
gpio::Pin_Mode mode = instance.get_pin_mode(pp.pin);
|
||||||
|
|
||||||
return mode != gpio::Pin_Mode::ANALOG && mode != gpio::Pin_Mode::INPUT_FLOATING &&
|
return mode != gpio::Pin_Mode::ANALOG && mode != gpio::Pin_Mode::INPUT_FLOATING &&
|
||||||
mode != gpio::Pin_Mode::INPUT_PULLUP && mode != gpio::Pin_Mode::INPUT_PULLDOWN;
|
mode != gpio::Pin_Mode::INPUT_PULLUP && mode != gpio::Pin_Mode::INPUT_PULLDOWN;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
namespace sdio {
|
namespace sdio {
|
||||||
|
|
||||||
CardDMA& CardDMA::get_instance() {
|
auto CardDMA::get_instance() -> CardDMA& {
|
||||||
static CardDMA instance;
|
static CardDMA instance;
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
@ -38,9 +38,7 @@ CardDMA::CardDMA() :
|
||||||
sdcard_cid_{0U, 0U, 0U, 0U},
|
sdcard_cid_{0U, 0U, 0U, 0U},
|
||||||
sdcard_scr_{0U, 0U},
|
sdcard_scr_{0U, 0U},
|
||||||
desired_clock_(Default_Desired_Clock),
|
desired_clock_(Default_Desired_Clock),
|
||||||
stop_condition_(0U),
|
|
||||||
total_bytes_(0U),
|
total_bytes_(0U),
|
||||||
count_(0U),
|
|
||||||
sdio_(SDIO::get_instance()),
|
sdio_(SDIO::get_instance()),
|
||||||
config_(sdio_.get_config()),
|
config_(sdio_.get_config()),
|
||||||
dmaBase_(dma::DMA_Base::DMA1_BASE),
|
dmaBase_(dma::DMA_Base::DMA1_BASE),
|
||||||
|
|
@ -50,15 +48,15 @@ CardDMA::CardDMA() :
|
||||||
transfer_error_(SDIO_Error_Type::OK),
|
transfer_error_(SDIO_Error_Type::OK),
|
||||||
interface_version_(Interface_Version::UNKNOWN),
|
interface_version_(Interface_Version::UNKNOWN),
|
||||||
card_type_(Card_Type::UNKNOWN),
|
card_type_(Card_Type::UNKNOWN),
|
||||||
|
current_state_(Operational_State::READY),
|
||||||
transfer_end_(false),
|
transfer_end_(false),
|
||||||
is_rx_(false),
|
|
||||||
multiblock_(false),
|
multiblock_(false),
|
||||||
current_state_(Operational_State::READY)
|
is_rx_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize card and put in standby state
|
// Initialize card and put in standby state
|
||||||
SDIO_Error_Type CardDMA::init() {
|
auto CardDMA::init() -> SDIO_Error_Type {
|
||||||
// Reset SDIO peripheral
|
// Reset SDIO peripheral
|
||||||
sdio_.reset();
|
sdio_.reset();
|
||||||
sync_domains();
|
sync_domains();
|
||||||
|
|
@ -79,7 +77,7 @@ SDIO_Error_Type CardDMA::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Startup command procedure according to SDIO specification
|
// Startup command procedure according to SDIO specification
|
||||||
SDIO_Error_Type CardDMA::begin_startup_procedure() {
|
auto CardDMA::begin_startup_procedure() -> SDIO_Error_Type {
|
||||||
sdio_.set_power_mode(Power_Control::POWER_ON);
|
sdio_.set_power_mode(Power_Control::POWER_ON);
|
||||||
sdio_.set_clock_enable(true);
|
sdio_.set_clock_enable(true);
|
||||||
sync_domains();
|
sync_domains();
|
||||||
|
|
@ -124,12 +122,12 @@ SDIO_Error_Type CardDMA::begin_startup_procedure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Voltage validation
|
// Voltage validation
|
||||||
SDIO_Error_Type CardDMA::validate_voltage() {
|
auto CardDMA::validate_voltage() -> SDIO_Error_Type {
|
||||||
uint32_t response = 0U;
|
uint32_t response = 0U;
|
||||||
uint32_t count = 0U;
|
uint32_t count = 0U;
|
||||||
bool valid_voltage = false;
|
bool valid_voltage = false;
|
||||||
|
|
||||||
while ((count < Max_Voltage_Checks) && (valid_voltage == false)) {
|
while (count < Max_Voltage_Checks && valid_voltage == false) {
|
||||||
if (send_command_and_check(Command_Index::CMD55, 0, Command_Response::RSP_SHORT,
|
if (send_command_and_check(Command_Index::CMD55, 0, Command_Response::RSP_SHORT,
|
||||||
Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD55]() {
|
Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD55]() {
|
||||||
return get_r1_result(cmd);
|
return get_r1_result(cmd);
|
||||||
|
|
@ -144,7 +142,7 @@ SDIO_Error_Type CardDMA::validate_voltage() {
|
||||||
return SDIO_Error_Type::ACMD41_FAILED;
|
return SDIO_Error_Type::ACMD41_FAILED;
|
||||||
}
|
}
|
||||||
response = sdio_.get_response(Response_Type::RESPONSE0);
|
response = sdio_.get_response(Response_Type::RESPONSE0);
|
||||||
valid_voltage = (((response >> 31U) == 1U) ? true : false);
|
valid_voltage = ((response >> 31U) == 1U);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,7 +169,7 @@ void CardDMA::begin_shutdown_procedure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize card
|
// Initialize card
|
||||||
SDIO_Error_Type CardDMA::card_init() {
|
auto CardDMA::card_init() -> SDIO_Error_Type {
|
||||||
if (sdio_.get_power_mode() == static_cast<uint32_t>(Power_Control::POWER_OFF)) {
|
if (sdio_.get_power_mode() == static_cast<uint32_t>(Power_Control::POWER_OFF)) {
|
||||||
return SDIO_Error_Type::INVALID_OPERATION;
|
return SDIO_Error_Type::INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
@ -221,7 +219,7 @@ SDIO_Error_Type CardDMA::card_init() {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::store_cid() {
|
auto CardDMA::store_cid() -> SDIO_Error_Type {
|
||||||
// Store the CID register values
|
// Store the CID register values
|
||||||
sdcard_cid_[0] = sdio_.get_response(Response_Type::RESPONSE0);
|
sdcard_cid_[0] = sdio_.get_response(Response_Type::RESPONSE0);
|
||||||
sdcard_cid_[1] = sdio_.get_response(Response_Type::RESPONSE1);
|
sdcard_cid_[1] = sdio_.get_response(Response_Type::RESPONSE1);
|
||||||
|
|
@ -231,7 +229,7 @@ SDIO_Error_Type CardDMA::store_cid() {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::store_csd() {
|
auto CardDMA::store_csd() -> SDIO_Error_Type {
|
||||||
// Store the CSD register values
|
// Store the CSD register values
|
||||||
sdcard_csd_[0] = sdio_.get_response(Response_Type::RESPONSE0);
|
sdcard_csd_[0] = sdio_.get_response(Response_Type::RESPONSE0);
|
||||||
sdcard_csd_[1] = sdio_.get_response(Response_Type::RESPONSE1);
|
sdcard_csd_[1] = sdio_.get_response(Response_Type::RESPONSE1);
|
||||||
|
|
@ -241,7 +239,7 @@ SDIO_Error_Type CardDMA::store_csd() {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::set_hardware_bus_width(Bus_Width width) {
|
auto CardDMA::set_hardware_bus_width(Bus_Width width) -> SDIO_Error_Type {
|
||||||
if (card_type_ == Card_Type::SD_MMC || width == Bus_Width::WIDTH_8BIT) {
|
if (card_type_ == Card_Type::SD_MMC || width == Bus_Width::WIDTH_8BIT) {
|
||||||
return SDIO_Error_Type::UNSUPPORTED_FUNCTION;
|
return SDIO_Error_Type::UNSUPPORTED_FUNCTION;
|
||||||
}
|
}
|
||||||
|
|
@ -283,7 +281,7 @@ SDIO_Error_Type CardDMA::set_hardware_bus_width(Bus_Width width) {
|
||||||
return SDIO_Error_Type::UNSUPPORTED_FUNCTION;
|
return SDIO_Error_Type::UNSUPPORTED_FUNCTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::read(uint8_t* buf, uint32_t address, uint32_t count) {
|
auto CardDMA::read(uint8_t* buf, uint32_t address, uint32_t count) -> SDIO_Error_Type {
|
||||||
if (current_state_ == Operational_State::READY) {
|
if (current_state_ == Operational_State::READY) {
|
||||||
transfer_error_ = SDIO_Error_Type::OK;
|
transfer_error_ = SDIO_Error_Type::OK;
|
||||||
current_state_ = Operational_State::BUSY;
|
current_state_ = Operational_State::BUSY;
|
||||||
|
|
@ -340,7 +338,7 @@ SDIO_Error_Type CardDMA::read(uint8_t* buf, uint32_t address, uint32_t count) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::write(uint8_t* buf, uint32_t address, uint32_t count) {
|
auto CardDMA::write(uint8_t* buf, uint32_t address, uint32_t count) -> SDIO_Error_Type {
|
||||||
// Enable the interrupts
|
// Enable the interrupts
|
||||||
sdio_.set_interrupt_enable(Interrupt_Type::DTCRCERRIE, true);
|
sdio_.set_interrupt_enable(Interrupt_Type::DTCRCERRIE, true);
|
||||||
sdio_.set_interrupt_enable(Interrupt_Type::DTTMOUTIE, true);
|
sdio_.set_interrupt_enable(Interrupt_Type::DTTMOUTIE, true);
|
||||||
|
|
@ -381,14 +379,14 @@ SDIO_Error_Type CardDMA::write(uint8_t* buf, uint32_t address, uint32_t count) {
|
||||||
sdio_.set_data_state_machine_and_send(Data_Timeout, total_bytes_, block_size,
|
sdio_.set_data_state_machine_and_send(Data_Timeout, total_bytes_, block_size,
|
||||||
Transfer_Mode::BLOCK, Transfer_Direction::SDIO_TO_CARD, true);
|
Transfer_Mode::BLOCK, Transfer_Direction::SDIO_TO_CARD, true);
|
||||||
|
|
||||||
while ((dma_.get_flag(dma::Status_Flags::FLAG_FTFIF)) || (dma_.get_flag(dma::Status_Flags::FLAG_ERRIF))) {
|
while (dma_.get_flag(dma::Status_Flags::FLAG_FTFIF) || dma_.get_flag(dma::Status_Flags::FLAG_ERRIF)) {
|
||||||
// Wait for the IRQ handler to clear
|
// Wait for the IRQ handler to clear
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::erase(uint32_t address_start, uint32_t address_end) {
|
auto CardDMA::erase(uint32_t address_start, uint32_t address_end) -> SDIO_Error_Type {
|
||||||
SDIO_Error_Type result = SDIO_Error_Type::OK;
|
SDIO_Error_Type result = SDIO_Error_Type::OK;
|
||||||
|
|
||||||
// Card command classes CSD
|
// Card command classes CSD
|
||||||
|
|
@ -459,9 +457,11 @@ void CardDMA::handle_interrupts() {
|
||||||
disable_all_interrupts();
|
disable_all_interrupts();
|
||||||
sdio_.set_data_state_machine_enable(false);
|
sdio_.set_data_state_machine_enable(false);
|
||||||
|
|
||||||
if ((multiblock_) && (!is_rx_)) {
|
if (multiblock_ && !is_rx_) {
|
||||||
transfer_error_ = stop_transfer();
|
transfer_error_ = stop_transfer();
|
||||||
if (transfer_error_ != SDIO_Error_Type::OK) {}
|
if (transfer_error_ != SDIO_Error_Type::OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_rx_) {
|
if (!is_rx_) {
|
||||||
|
|
@ -497,7 +497,7 @@ void CardDMA::handle_interrupts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::select_deselect() {
|
auto CardDMA::select_deselect() -> SDIO_Error_Type {
|
||||||
// CMD7 (SELECT/DESELECT_CARD)
|
// CMD7 (SELECT/DESELECT_CARD)
|
||||||
if (send_command_and_check(Command_Index::CMD7, static_cast<uint32_t>(sdcard_rca_ << RCA_Shift),
|
if (send_command_and_check(Command_Index::CMD7, static_cast<uint32_t>(sdcard_rca_ << RCA_Shift),
|
||||||
Command_Response::RSP_SHORT, Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD7]() {
|
Command_Response::RSP_SHORT, Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD7]() {
|
||||||
|
|
@ -508,7 +508,7 @@ SDIO_Error_Type CardDMA::select_deselect() {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_card_interface_status(uint32_t* status) {
|
auto CardDMA::get_card_interface_status(uint32_t* status) -> SDIO_Error_Type {
|
||||||
if (status == nullptr) return SDIO_Error_Type::INVALID_PARAMETER;
|
if (status == nullptr) return SDIO_Error_Type::INVALID_PARAMETER;
|
||||||
|
|
||||||
// CMD13 (SEND_STATUS)
|
// CMD13 (SEND_STATUS)
|
||||||
|
|
@ -524,7 +524,7 @@ SDIO_Error_Type CardDMA::get_card_interface_status(uint32_t* status) {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_sdcard_status(uint32_t* status) {
|
auto CardDMA::get_sdcard_status(uint32_t* status) -> SDIO_Error_Type {
|
||||||
uint32_t count = 0U;
|
uint32_t count = 0U;
|
||||||
|
|
||||||
// CMD16 (SET_BLOCKLEN)
|
// CMD16 (SET_BLOCKLEN)
|
||||||
|
|
@ -599,7 +599,7 @@ void CardDMA::check_dma_complete() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::stop_transfer() {
|
auto CardDMA::stop_transfer() -> SDIO_Error_Type {
|
||||||
// CMD12 (STOP_TRANSMISSION)
|
// CMD12 (STOP_TRANSMISSION)
|
||||||
if (send_command_and_check(Command_Index::CMD12, 0, Command_Response::RSP_SHORT, Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD12]() {
|
if (send_command_and_check(Command_Index::CMD12, 0, Command_Response::RSP_SHORT, Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD12]() {
|
||||||
return get_r1_result(cmd);
|
return get_r1_result(cmd);
|
||||||
|
|
@ -609,7 +609,7 @@ SDIO_Error_Type CardDMA::stop_transfer() {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transfer_State CardDMA::get_transfer_state() {
|
auto CardDMA::get_transfer_state() -> Transfer_State {
|
||||||
Transfer_State transfer_state = Transfer_State::IDLE;
|
Transfer_State transfer_state = Transfer_State::IDLE;
|
||||||
if (sdio_.get_flag(Status_Flags::FLAG_TXRUN) | sdio_.get_flag(Status_Flags::FLAG_RXRUN)) {
|
if (sdio_.get_flag(Status_Flags::FLAG_TXRUN) | sdio_.get_flag(Status_Flags::FLAG_RXRUN)) {
|
||||||
transfer_state = Transfer_State::BUSY;
|
transfer_state = Transfer_State::BUSY;
|
||||||
|
|
@ -618,7 +618,7 @@ Transfer_State CardDMA::get_transfer_state() {
|
||||||
return transfer_state;
|
return transfer_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CardDMA::get_card_capacity() const {
|
[[nodiscard]] auto CardDMA::get_card_capacity() const -> uint32_t {
|
||||||
auto extract_bits = [](uint32_t value, uint8_t start_bit, uint8_t length) -> uint32_t {
|
auto extract_bits = [](uint32_t value, uint8_t start_bit, uint8_t length) -> uint32_t {
|
||||||
return (value >> start_bit) & ((1U << length) - 1U);
|
return (value >> start_bit) & ((1U << length) - 1U);
|
||||||
};
|
};
|
||||||
|
|
@ -665,7 +665,7 @@ uint32_t CardDMA::get_card_capacity() const {
|
||||||
return capacity;
|
return capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_card_specific_data(Card_Info* info) {
|
auto CardDMA::get_card_specific_data(Card_Info* info) -> SDIO_Error_Type {
|
||||||
if (info == nullptr) return SDIO_Error_Type::INVALID_PARAMETER;
|
if (info == nullptr) return SDIO_Error_Type::INVALID_PARAMETER;
|
||||||
|
|
||||||
// Store basic card information
|
// Store basic card information
|
||||||
|
|
@ -735,28 +735,20 @@ SDIO_Error_Type CardDMA::get_card_specific_data(Card_Info* info) {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Block_Size CardDMA::get_data_block_size_index(uint16_t size) {
|
constexpr auto CardDMA::get_data_block_size_index(uint16_t size) -> Block_Size {
|
||||||
switch (size) {
|
if (size < 1 || size > 16384) return Block_Size::BYTES_1;
|
||||||
case 1: return Block_Size::BYTES_1;
|
|
||||||
case 2: return Block_Size::BYTES_2;
|
// Check if size is a power of two
|
||||||
case 4: return Block_Size::BYTES_4;
|
if ((size & (size - 1)) != 0) return Block_Size::BYTES_1;
|
||||||
case 8: return Block_Size::BYTES_8;
|
|
||||||
case 16: return Block_Size::BYTES_16;
|
// Count trailing zeros to find the index
|
||||||
case 32: return Block_Size::BYTES_32;
|
uint16_t index = 0;
|
||||||
case 64: return Block_Size::BYTES_64;
|
while ((size >>= 1) != 0) ++index;
|
||||||
case 128: return Block_Size::BYTES_128;
|
|
||||||
case 256: return Block_Size::BYTES_256;
|
return static_cast<Block_Size>(index);
|
||||||
case 512: return Block_Size::BYTES_512;
|
|
||||||
case 1024: return Block_Size::BYTES_1024;
|
|
||||||
case 2048: return Block_Size::BYTES_2048;
|
|
||||||
case 4096: return Block_Size::BYTES_4096;
|
|
||||||
case 8192: return Block_Size::BYTES_8192;
|
|
||||||
case 16384: return Block_Size::BYTES_16384;
|
|
||||||
default: return Block_Size::BYTES_1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_card_state(Card_State* card_state) {
|
auto CardDMA::get_card_state(Card_State* card_state) -> SDIO_Error_Type {
|
||||||
// CMD13 (SEND_STATUS)
|
// CMD13 (SEND_STATUS)
|
||||||
if (send_command_and_check(Command_Index::CMD13, static_cast<uint32_t>(sdcard_rca_ << RCA_Shift),
|
if (send_command_and_check(Command_Index::CMD13, static_cast<uint32_t>(sdcard_rca_ << RCA_Shift),
|
||||||
Command_Response::RSP_SHORT, Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD13]() {
|
Command_Response::RSP_SHORT, Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD13]() {
|
||||||
|
|
@ -773,7 +765,7 @@ SDIO_Error_Type CardDMA::get_card_state(Card_State* card_state) {
|
||||||
|
|
||||||
if (response & All_R1_Error_Bits) {
|
if (response & All_R1_Error_Bits) {
|
||||||
for (const auto& entry : errorTableR1) {
|
for (const auto& entry : errorTableR1) {
|
||||||
if (response & entry.mask) {
|
if (TEST(response, entry.bit_position)) {
|
||||||
return entry.errorType;
|
return entry.errorType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -783,23 +775,28 @@ SDIO_Error_Type CardDMA::get_card_state(Card_State* card_state) {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_command_sent_result() {
|
auto CardDMA::get_command_sent_result() -> SDIO_Error_Type {
|
||||||
volatile uint32_t timeout = 0x00FFFFFFU;
|
constexpr uint32_t MAX_TIMEOUT = 0x00FFFFFFU;
|
||||||
|
uint32_t timeout = MAX_TIMEOUT;
|
||||||
|
|
||||||
while ((sdio_.get_flag(Status_Flags::FLAG_CMDSEND) == false) && (timeout != 0U)) {
|
// Wait for command sent flag or timeout
|
||||||
timeout = timeout - 1U;
|
while (!sdio_.get_flag(Status_Flags::FLAG_CMDSEND) && timeout) {
|
||||||
|
--timeout;
|
||||||
}
|
}
|
||||||
if (timeout == 0U) return SDIO_Error_Type::RESPONSE_TIMEOUT;
|
|
||||||
sdio_.clear_multiple_interrupt_flags(clear_command_flags);
|
|
||||||
|
|
||||||
|
// Check if timeout occurred
|
||||||
|
if (timeout == 0U) {
|
||||||
|
return SDIO_Error_Type::RESPONSE_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear command flags and return success
|
||||||
|
sdio_.clear_multiple_interrupt_flags(clear_command_flags);
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::check_sdio_status(Command_Index index, bool check_index, bool ignore_crc) {
|
auto CardDMA::check_sdio_status(Command_Index index, bool check_index, bool ignore_crc) -> SDIO_Error_Type {
|
||||||
// Wait until one of the relevant flags is set
|
// Wait until one of the relevant flags is set
|
||||||
bool flag_set = sdio_.wait_cmd_flags();
|
if (!sdio_.wait_cmd_flags()) {
|
||||||
|
|
||||||
if (!flag_set) {
|
|
||||||
return SDIO_Error_Type::RESPONSE_TIMEOUT;
|
return SDIO_Error_Type::RESPONSE_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -810,56 +807,55 @@ SDIO_Error_Type CardDMA::check_sdio_status(Command_Index index, bool check_index
|
||||||
// If cmd was received, check the index
|
// If cmd was received, check the index
|
||||||
// Responses that dont do an index check will send an invalid cmd index
|
// Responses that dont do an index check will send an invalid cmd index
|
||||||
if (check_index && (index != Command_Index::INVALID)) {
|
if (check_index && (index != Command_Index::INVALID)) {
|
||||||
uint8_t idx = sdio_.get_command_index();
|
uint8_t received_idx = sdio_.get_command_index();
|
||||||
if (idx != static_cast<uint8_t>(index)) {
|
if (received_idx != static_cast<uint8_t>(index)) {
|
||||||
|
sdio_.clear_multiple_interrupt_flags(clear_command_flags);
|
||||||
return SDIO_Error_Type::ILLEGAL_COMMAND;
|
return SDIO_Error_Type::ILLEGAL_COMMAND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clear all flags before returning
|
|
||||||
|
// Command received successfully
|
||||||
sdio_.clear_multiple_interrupt_flags(clear_command_flags);
|
sdio_.clear_multiple_interrupt_flags(clear_command_flags);
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout check
|
// Check for timeout
|
||||||
if (sdio_.get_flag(Status_Flags::FLAG_CMDTMOUT)) {
|
if (sdio_.get_flag(Status_Flags::FLAG_CMDTMOUT)) {
|
||||||
sdio_.clear_flag(Clear_Flags::FLAG_CMDTMOUTC);
|
sdio_.clear_flag(Clear_Flags::FLAG_CMDTMOUTC);
|
||||||
return SDIO_Error_Type::RESPONSE_TIMEOUT;
|
return SDIO_Error_Type::RESPONSE_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CRC check
|
// Check for CRC error if not ignored
|
||||||
if (!ignore_crc) {
|
if (!ignore_crc && sdio_.get_flag(Status_Flags::FLAG_CCRCERR)) {
|
||||||
if (sdio_.get_flag(Status_Flags::FLAG_CCRCERR)) {
|
|
||||||
sdio_.clear_flag(Clear_Flags::FLAG_CCRCERRC);
|
sdio_.clear_flag(Clear_Flags::FLAG_CCRCERRC);
|
||||||
return SDIO_Error_Type::COMMAND_CRC_ERROR;
|
return SDIO_Error_Type::COMMAND_CRC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Responses that dont do an index check will send an invalid cmd index
|
// Final index check (redundant with the first check, but keeping for safety)
|
||||||
|
// This code path should rarely be taken due to the earlier checks
|
||||||
if (check_index && (index != Command_Index::INVALID)) {
|
if (check_index && (index != Command_Index::INVALID)) {
|
||||||
uint8_t idx = sdio_.get_command_index();
|
uint8_t received_idx = sdio_.get_command_index();
|
||||||
if (idx != static_cast<uint8_t>(index)) {
|
if (received_idx != static_cast<uint8_t>(index)) {
|
||||||
|
sdio_.clear_multiple_interrupt_flags(clear_command_flags);
|
||||||
return SDIO_Error_Type::ILLEGAL_COMMAND;
|
return SDIO_Error_Type::ILLEGAL_COMMAND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all flags before returning
|
// Clear all flags and return success
|
||||||
sdio_.clear_multiple_interrupt_flags(clear_command_flags);
|
sdio_.clear_multiple_interrupt_flags(clear_command_flags);
|
||||||
|
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_r1_result(Command_Index index) {
|
auto CardDMA::get_r1_result(Command_Index index) -> SDIO_Error_Type {
|
||||||
SDIO_Error_Type result = check_sdio_status(index, true, false);
|
SDIO_Error_Type result = check_sdio_status(index, true, false);
|
||||||
if (result != SDIO_Error_Type::OK) {
|
if (result != SDIO_Error_Type::OK) return result;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the R1 response and check for errors
|
// Get the R1 response and check for errors
|
||||||
uint32_t response = sdio_.get_response(Response_Type::RESPONSE0);
|
uint32_t response = sdio_.get_response(Response_Type::RESPONSE0);
|
||||||
|
|
||||||
if (response & All_R1_Error_Bits) {
|
if (response & All_R1_Error_Bits) {
|
||||||
for (const auto& entry : errorTableR1) {
|
for (const auto& entry : errorTableR1) {
|
||||||
if (response & entry.mask) {
|
if (TEST(response, entry.bit_position)) {
|
||||||
return entry.errorType;
|
return entry.errorType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -869,7 +865,7 @@ SDIO_Error_Type CardDMA::get_r1_result(Command_Index index) {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_r6_result(Command_Index index, uint16_t* rca) {
|
auto CardDMA::get_r6_result(Command_Index index, uint16_t* rca) -> SDIO_Error_Type {
|
||||||
SDIO_Error_Type result = check_sdio_status(index, true, false);
|
SDIO_Error_Type result = check_sdio_status(index, true, false);
|
||||||
if (result != SDIO_Error_Type::OK) return result;
|
if (result != SDIO_Error_Type::OK) return result;
|
||||||
|
|
||||||
|
|
@ -877,7 +873,7 @@ SDIO_Error_Type CardDMA::get_r6_result(Command_Index index, uint16_t* rca) {
|
||||||
|
|
||||||
if (response & R6_Error_Bits) {
|
if (response & R6_Error_Bits) {
|
||||||
for (const auto& entry : errorTableR6) {
|
for (const auto& entry : errorTableR6) {
|
||||||
if (response & entry.mask) {
|
if (TEST(response, entry.bit_position)) {
|
||||||
return entry.errorType;
|
return entry.errorType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -888,14 +884,9 @@ SDIO_Error_Type CardDMA::get_r6_result(Command_Index index, uint16_t* rca) {
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_r7_result() {
|
auto CardDMA::get_scr(uint16_t rca, uint32_t* scr) -> SDIO_Error_Type {
|
||||||
return check_sdio_status(Command_Index::INVALID, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::get_scr(uint16_t rca, uint32_t* scr) {
|
|
||||||
uint32_t temp_scr[2] = {0U, 0U};
|
uint32_t temp_scr[2] = {0U, 0U};
|
||||||
uint32_t index_scr = 0U;
|
uint32_t index_scr = 0U;
|
||||||
uint32_t* src_data = scr;
|
|
||||||
|
|
||||||
// CMD16 (SET_BLOCKLEN)
|
// CMD16 (SET_BLOCKLEN)
|
||||||
if (send_command_and_check(Command_Index::CMD16, 8U, Command_Response::RSP_SHORT,
|
if (send_command_and_check(Command_Index::CMD16, 8U, Command_Response::RSP_SHORT,
|
||||||
|
|
@ -928,36 +919,41 @@ SDIO_Error_Type CardDMA::get_scr(uint16_t rca, uint32_t* scr) {
|
||||||
// Store SCR
|
// Store SCR
|
||||||
while (!sdio_.check_scr_flags()) {
|
while (!sdio_.check_scr_flags()) {
|
||||||
if (sdio_.get_flag(Status_Flags::FLAG_RXDTVAL)) {
|
if (sdio_.get_flag(Status_Flags::FLAG_RXDTVAL)) {
|
||||||
*(temp_scr + index_scr) = sdio_.read_fifo_word();
|
temp_scr[index_scr++] = sdio_.read_fifo_word();
|
||||||
++index_scr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for errors
|
||||||
if (sdio_.get_flag(Status_Flags::FLAG_DTTMOUT)) {
|
if (sdio_.get_flag(Status_Flags::FLAG_DTTMOUT)) {
|
||||||
sdio_.clear_flag(Clear_Flags::FLAG_DTTMOUTC);
|
sdio_.clear_flag(Clear_Flags::FLAG_DTTMOUTC);
|
||||||
return SDIO_Error_Type::DATA_TIMEOUT;
|
return SDIO_Error_Type::DATA_TIMEOUT;
|
||||||
} else if (sdio_.get_flag(Status_Flags::FLAG_DTCRCERR)) {
|
}
|
||||||
|
else if (sdio_.get_flag(Status_Flags::FLAG_DTCRCERR)) {
|
||||||
sdio_.clear_flag(Clear_Flags::FLAG_DTCRCERRC);
|
sdio_.clear_flag(Clear_Flags::FLAG_DTCRCERRC);
|
||||||
return SDIO_Error_Type::DATA_CRC_ERROR;
|
return SDIO_Error_Type::DATA_CRC_ERROR;
|
||||||
} else if (sdio_.get_flag(Status_Flags::FLAG_RXORE)) {
|
}
|
||||||
|
else if (sdio_.get_flag(Status_Flags::FLAG_RXORE)) {
|
||||||
sdio_.clear_flag(Clear_Flags::FLAG_RXOREC);
|
sdio_.clear_flag(Clear_Flags::FLAG_RXOREC);
|
||||||
return SDIO_Error_Type::RX_FIFO_OVERRUN;
|
return SDIO_Error_Type::RX_FIFO_OVERRUN;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdio_.clear_multiple_interrupt_flags(clear_data_flags);
|
sdio_.clear_multiple_interrupt_flags(clear_data_flags);
|
||||||
|
|
||||||
constexpr uint32_t Zero_Seven = (0xFFU << 0U);
|
constexpr uint32_t BYTE0_MASK = 0xFFU;
|
||||||
constexpr uint32_t Eight_Fifteen = (0xFFU << 8U);
|
constexpr uint32_t BYTE1_MASK = 0xFF00U;
|
||||||
constexpr uint32_t Sixteen_Twentythree = (0xFFU << 16U);
|
constexpr uint32_t BYTE2_MASK = 0xFF0000U;
|
||||||
constexpr uint32_t TwentyFour_Thirtyone = (0xFFU << 24U);
|
constexpr uint32_t BYTE3_MASK = 0xFF000000U;
|
||||||
|
|
||||||
// adjust SCR value
|
// Byte-swap the SCR values (convert from big-endian to little-endian)
|
||||||
*src_data = ((temp_scr[1] & Zero_Seven) << 24U) | ((temp_scr[1] & Eight_Fifteen) << 8U) |
|
scr[0] = ((temp_scr[1] & BYTE0_MASK) << 24) |
|
||||||
((temp_scr[1] & Sixteen_Twentythree) >> 8U) | ((temp_scr[1] & TwentyFour_Thirtyone) >> 24U);
|
((temp_scr[1] & BYTE1_MASK) << 8) |
|
||||||
|
((temp_scr[1] & BYTE2_MASK) >> 8) |
|
||||||
|
((temp_scr[1] & BYTE3_MASK) >> 24);
|
||||||
|
|
||||||
src_data = src_data + 1U;
|
scr[1] = ((temp_scr[0] & BYTE0_MASK) << 24) |
|
||||||
*src_data = ((temp_scr[0] & Zero_Seven) << 24U) | ((temp_scr[0] & Eight_Fifteen) << 8U) |
|
((temp_scr[0] & BYTE1_MASK) << 8) |
|
||||||
((temp_scr[0] & Sixteen_Twentythree) >> 8U) | ((temp_scr[0] & TwentyFour_Thirtyone) >> 24U);
|
((temp_scr[0] & BYTE2_MASK) >> 8) |
|
||||||
|
((temp_scr[0] & BYTE3_MASK) >> 24);
|
||||||
|
|
||||||
return SDIO_Error_Type::OK;
|
return SDIO_Error_Type::OK;
|
||||||
}
|
}
|
||||||
|
|
@ -965,23 +961,22 @@ SDIO_Error_Type CardDMA::get_scr(uint16_t rca, uint32_t* scr) {
|
||||||
// DMA for rx/tx is always DMA1 channel 3
|
// DMA for rx/tx is always DMA1 channel 3
|
||||||
void CardDMA::set_dma_parameters(uint8_t* buf, uint32_t count, bool is_write) {
|
void CardDMA::set_dma_parameters(uint8_t* buf, uint32_t count, bool is_write) {
|
||||||
constexpr uint32_t flag_bits = (1U << static_cast<uint32_t>(dma::INTF_Bits::GIF3));
|
constexpr uint32_t flag_bits = (1U << static_cast<uint32_t>(dma::INTF_Bits::GIF3));
|
||||||
|
|
||||||
dma_.clear_flags(flag_bits);
|
dma_.clear_flags(flag_bits);
|
||||||
|
|
||||||
// Disable and reset DMA
|
// Disable and reset DMA
|
||||||
dma_.set_channel_enable(false);
|
dma_.set_channel_enable(false);
|
||||||
dma_.clear_channel();
|
dma_.clear_channel();
|
||||||
|
|
||||||
dma_.init({
|
dma_.init(dma::DMA_Config{
|
||||||
count,
|
.count = count,
|
||||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(buf)),
|
.memory_address = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(buf)),
|
||||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(sdio_.reg_address(SDIO_Regs::FIFO))),
|
.peripheral_address = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(sdio_.reg_address(SDIO_Regs::FIFO))),
|
||||||
dma::Bit_Width::WIDTH_32BIT,
|
.peripheral_bit_width = dma::Bit_Width::WIDTH_32BIT,
|
||||||
dma::Bit_Width::WIDTH_32BIT,
|
.memory_bit_width = dma::Bit_Width::WIDTH_32BIT,
|
||||||
dma::Increase_Mode::INCREASE_DISABLE,
|
.peripheral_increase = dma::Increase_Mode::INCREASE_DISABLE,
|
||||||
dma::Increase_Mode::INCREASE_ENABLE,
|
.memory_increase = dma::Increase_Mode::INCREASE_ENABLE,
|
||||||
dma::Channel_Priority::MEDIUM_PRIORITY,
|
.channel_priority = dma::Channel_Priority::MEDIUM_PRIORITY,
|
||||||
is_write ? dma::Transfer_Direction::M2P : dma::Transfer_Direction::P2M
|
.direction = is_write ? dma::Transfer_Direction::M2P : dma::Transfer_Direction::P2M
|
||||||
});
|
});
|
||||||
|
|
||||||
dma_.set_memory_to_memory_enable(false);
|
dma_.set_memory_to_memory_enable(false);
|
||||||
|
|
@ -995,13 +990,15 @@ void CardDMA::set_dma_parameters(uint8_t* buf, uint32_t count, bool is_write) {
|
||||||
dma_.set_channel_enable(true);
|
dma_.set_channel_enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDIO_Error_Type CardDMA::wait_for_card_ready() {
|
auto CardDMA::wait_for_card_ready() -> SDIO_Error_Type {
|
||||||
volatile uint32_t timeout = 0x00FFFFFFU;
|
constexpr uint32_t MAX_TIMEOUT = 0x00FFFFFFU;
|
||||||
|
uint32_t timeout = MAX_TIMEOUT;
|
||||||
uint32_t response = sdio_.get_response(Response_Type::RESPONSE0);
|
uint32_t response = sdio_.get_response(Response_Type::RESPONSE0);
|
||||||
|
|
||||||
while (((response & static_cast<uint32_t>(R1_Status::READY_FOR_DATA)) == 0U) && (timeout != 0U)) {
|
// Poll until card is ready for data or timeout occurs
|
||||||
// Continue to send CMD13 to poll the state of card until buffer empty or timeout
|
while (((response & static_cast<uint32_t>(R1_Status::READY_FOR_DATA)) == 0U) && timeout) {
|
||||||
timeout = timeout - 1U;
|
--timeout;
|
||||||
|
|
||||||
// CMD13 (SEND_STATUS)
|
// CMD13 (SEND_STATUS)
|
||||||
if (send_command_and_check(Command_Index::CMD13, static_cast<uint32_t>(sdcard_rca_ << RCA_Shift),
|
if (send_command_and_check(Command_Index::CMD13, static_cast<uint32_t>(sdcard_rca_ << RCA_Shift),
|
||||||
Command_Response::RSP_SHORT, Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD13]() {
|
Command_Response::RSP_SHORT, Wait_Type::WT_NONE, [this, cmd = Command_Index::CMD13]() {
|
||||||
|
|
@ -1009,10 +1006,13 @@ SDIO_Error_Type CardDMA::wait_for_card_ready() {
|
||||||
}) != SDIO_Error_Type::OK) {
|
}) != SDIO_Error_Type::OK) {
|
||||||
return SDIO_Error_Type::CMD13_FAILED;
|
return SDIO_Error_Type::CMD13_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get updated response
|
||||||
response = sdio_.get_response(Response_Type::RESPONSE0);
|
response = sdio_.get_response(Response_Type::RESPONSE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (timeout == 0U) ? SDIO_Error_Type::ERROR : SDIO_Error_Type::OK;
|
// Return error if timeout occurred, otherwise success
|
||||||
|
return timeout ? SDIO_Error_Type::OK : SDIO_Error_Type::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sdio
|
} // namespace sdio
|
||||||
|
|
|
||||||
|
|
@ -26,76 +26,82 @@ class DMA;
|
||||||
|
|
||||||
class CardDMA {
|
class CardDMA {
|
||||||
public:
|
public:
|
||||||
static CardDMA& get_instance();
|
static auto get_instance() -> CardDMA&;
|
||||||
|
|
||||||
SDIO_Error_Type init();
|
// Initialization
|
||||||
SDIO_Error_Type card_init();
|
auto init() -> SDIO_Error_Type;
|
||||||
SDIO_Error_Type begin_startup_procedure();
|
auto card_init() -> SDIO_Error_Type;
|
||||||
|
|
||||||
|
// Startup and shutdown procedures
|
||||||
|
auto begin_startup_procedure() -> SDIO_Error_Type;
|
||||||
void begin_shutdown_procedure();
|
void begin_shutdown_procedure();
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
SDIO_Error_Type set_hardware_bus_width(Bus_Width width);
|
auto set_hardware_bus_width(Bus_Width width) -> SDIO_Error_Type;
|
||||||
// Main read/write functions for single and multiblock transfers
|
auto send_bus_width_command(uint32_t width_value) -> SDIO_Error_Type;
|
||||||
SDIO_Error_Type read(uint8_t* buf, uint32_t address, uint32_t count);
|
|
||||||
SDIO_Error_Type write(uint8_t* buf, uint32_t address, uint32_t count);
|
// Main read/write/erase functions
|
||||||
// DMA transfers
|
auto read(uint8_t* buf, uint32_t address, uint32_t count) -> SDIO_Error_Type;
|
||||||
// Other card functions
|
auto write(uint8_t* buf, uint32_t address, uint32_t count) -> SDIO_Error_Type;
|
||||||
SDIO_Error_Type erase(uint32_t address_start, uint32_t address_end);
|
auto erase(uint32_t address_start, uint32_t address_end) -> SDIO_Error_Type;
|
||||||
// Interrupt handler
|
|
||||||
void handle_interrupts();
|
|
||||||
// Card select
|
// Card select
|
||||||
SDIO_Error_Type select_deselect();
|
auto select_deselect() -> SDIO_Error_Type;
|
||||||
|
|
||||||
SDIO_Error_Type get_card_interface_status(uint32_t* status);
|
// Status and state
|
||||||
SDIO_Error_Type get_sdcard_status(uint32_t* status);
|
auto get_card_interface_status(uint32_t* status) -> SDIO_Error_Type;
|
||||||
|
auto get_sdcard_status(uint32_t* status) -> SDIO_Error_Type;
|
||||||
|
auto get_transfer_state() -> Transfer_State;
|
||||||
|
auto get_card_state(Card_State* card_state) -> SDIO_Error_Type;
|
||||||
|
auto check_sdio_status(Command_Index index = Command_Index::INVALID, bool check_index = false, bool ignore_crc = false) -> SDIO_Error_Type;
|
||||||
|
|
||||||
void check_dma_complete();
|
// DMA
|
||||||
SDIO_Error_Type stop_transfer();
|
|
||||||
|
|
||||||
Transfer_State get_transfer_state();
|
|
||||||
uint32_t get_card_capacity() const;
|
|
||||||
|
|
||||||
SDIO_Error_Type send_bus_width_command(uint32_t width_value);
|
|
||||||
|
|
||||||
SDIO_Error_Type get_card_specific_data(Card_Info* info);
|
|
||||||
constexpr Block_Size get_data_block_size_index(uint16_t size);
|
|
||||||
|
|
||||||
SDIO_Error_Type get_card_state(Card_State* card_state);
|
|
||||||
SDIO_Error_Type check_sdio_status(Command_Index index = Command_Index::INVALID, bool check_index = false, bool ignore_crc = false);
|
|
||||||
|
|
||||||
// DMA configuration
|
|
||||||
void set_dma_parameters(uint8_t* buf, uint32_t count, bool is_write);
|
void set_dma_parameters(uint8_t* buf, uint32_t count, bool is_write);
|
||||||
|
void check_dma_complete();
|
||||||
|
|
||||||
|
// Stop transfer
|
||||||
|
auto stop_transfer() -> SDIO_Error_Type;
|
||||||
|
|
||||||
|
// Card information
|
||||||
|
auto get_card_specific_data(Card_Info* info) -> SDIO_Error_Type;
|
||||||
|
constexpr auto get_data_block_size_index(uint16_t size) -> Block_Size;
|
||||||
|
[[nodiscard]] auto get_card_capacity() const -> uint32_t;
|
||||||
|
|
||||||
// SDIO configuration
|
// SDIO configuration
|
||||||
void sdio_configure(const SDIO_Config config) { sdio_.init(config); }
|
void sdio_configure(const SDIO_Config config) { sdio_.init(config); }
|
||||||
|
|
||||||
// Varaible stored parameters
|
// Interrupt handler
|
||||||
SDIO_Error_Type get_scr(uint16_t rca, uint32_t* scr);
|
void handle_interrupts();
|
||||||
SDIO_Error_Type store_cid();
|
|
||||||
SDIO_Error_Type store_csd();
|
|
||||||
|
|
||||||
// Accessor methods
|
// Varaible stored parameters
|
||||||
SDIO_Config& get_config() { return config_; }
|
auto get_scr(uint16_t rca, uint32_t* scr) -> SDIO_Error_Type;
|
||||||
dma::DMA& get_dma_instance() { return dma_; }
|
auto store_cid() -> SDIO_Error_Type;
|
||||||
|
auto store_csd() -> SDIO_Error_Type;
|
||||||
|
|
||||||
|
// Inlined accessor methods
|
||||||
|
auto get_config() -> SDIO_Config& { return config_; }
|
||||||
|
auto get_dma_instance() -> dma::DMA& { return dma_; }
|
||||||
void set_data_end_interrupt() { sdio_.set_interrupt_enable(Interrupt_Type::DTENDIE, true); }
|
void set_data_end_interrupt() { sdio_.set_interrupt_enable(Interrupt_Type::DTENDIE, true); }
|
||||||
void set_sdio_dma_enable(bool enable) { sdio_.set_dma_enable(enable); }
|
void set_sdio_dma_enable(bool enable) { sdio_.set_dma_enable(enable); }
|
||||||
bool get_is_sdio_rx() { return is_rx_; }
|
auto get_is_sdio_rx() -> bool { return is_rx_; }
|
||||||
void clear_sdio_data_flags() { sdio_.clear_multiple_interrupt_flags(clear_data_flags); }
|
void clear_sdio_data_flags() { sdio_.clear_multiple_interrupt_flags(clear_data_flags); }
|
||||||
void clear_sdio_cmd_flags() { sdio_.clear_multiple_interrupt_flags(clear_command_flags); }
|
void clear_sdio_cmd_flags() { sdio_.clear_multiple_interrupt_flags(clear_command_flags); }
|
||||||
void clear_sdio_common_flags() { sdio_.clear_multiple_interrupt_flags(clear_common_flags); }
|
void clear_sdio_common_flags() { sdio_.clear_multiple_interrupt_flags(clear_common_flags); }
|
||||||
Operational_State get_state() { return current_state_; }
|
auto get_state() -> Operational_State { return current_state_; }
|
||||||
void set_state(Operational_State state) { current_state_ = state; }
|
void set_state(Operational_State state) { current_state_ = state; }
|
||||||
void set_transfer_end(bool value) { transfer_end_ = value; }
|
|
||||||
void set_transfer_error(SDIO_Error_Type error) { transfer_error_ = error; }
|
void set_transfer_error(SDIO_Error_Type error) { transfer_error_ = error; }
|
||||||
|
void set_transfer_end(bool end) { transfer_end_ = end; };
|
||||||
|
|
||||||
inline SDIO_Error_Type set_desired_clock(uint32_t desired_clock, bool wide_bus, bool low_power) {
|
auto set_desired_clock(uint32_t desired_clock, bool wide_bus, bool low_power) -> SDIO_Error_Type {
|
||||||
sdio_.init({
|
sdio_.init(SDIO_Config{
|
||||||
desired_clock,
|
.desired_clock = desired_clock,
|
||||||
Clock_Edge::RISING_EDGE,
|
.enable_bypass = false,
|
||||||
wide_bus ? Bus_Width::WIDTH_4BIT : Bus_Width::WIDTH_1BIT,
|
.enable_powersave = low_power,
|
||||||
false,
|
.enable_hwclock = false,
|
||||||
low_power,
|
.clock_edge = Clock_Edge::RISING_EDGE,
|
||||||
false
|
.width = wide_bus ? Bus_Width::WIDTH_4BIT : Bus_Width::WIDTH_1BIT
|
||||||
});
|
});
|
||||||
|
|
||||||
sync_domains();
|
sync_domains();
|
||||||
desired_clock_ = desired_clock;
|
desired_clock_ = desired_clock;
|
||||||
|
|
||||||
|
|
@ -107,19 +113,17 @@ private:
|
||||||
|
|
||||||
// Prevent copying or assigning
|
// Prevent copying or assigning
|
||||||
CardDMA(const CardDMA&) = delete;
|
CardDMA(const CardDMA&) = delete;
|
||||||
CardDMA& operator=(const CardDMA&) = delete;
|
auto operator=(const CardDMA&) -> CardDMA& = delete;
|
||||||
|
|
||||||
// Helper function
|
// Helper function
|
||||||
SDIO_Error_Type wait_for_card_ready();
|
auto wait_for_card_ready() -> SDIO_Error_Type;
|
||||||
|
|
||||||
// Member variables
|
// Member variables
|
||||||
alignas(4) uint32_t sdcard_csd_[4];
|
alignas(4) uint32_t sdcard_csd_[4];
|
||||||
alignas(4) uint32_t sdcard_cid_[4];
|
alignas(4) uint32_t sdcard_cid_[4];
|
||||||
alignas(4) uint32_t sdcard_scr_[2];
|
alignas(4) uint32_t sdcard_scr_[2];
|
||||||
uint32_t desired_clock_;
|
uint32_t desired_clock_;
|
||||||
uint32_t stop_condition_;
|
|
||||||
uint32_t total_bytes_;
|
uint32_t total_bytes_;
|
||||||
uint32_t count_;
|
|
||||||
SDIO& sdio_;
|
SDIO& sdio_;
|
||||||
SDIO_Config& config_;
|
SDIO_Config& config_;
|
||||||
const dma::DMA_Base dmaBase_;
|
const dma::DMA_Base dmaBase_;
|
||||||
|
|
@ -129,66 +133,70 @@ private:
|
||||||
SDIO_Error_Type transfer_error_;
|
SDIO_Error_Type transfer_error_;
|
||||||
Interface_Version interface_version_;
|
Interface_Version interface_version_;
|
||||||
Card_Type card_type_;
|
Card_Type card_type_;
|
||||||
volatile bool transfer_end_;
|
Operational_State current_state_;
|
||||||
volatile bool is_rx_;
|
bool transfer_end_;
|
||||||
volatile bool multiblock_;
|
bool multiblock_;
|
||||||
volatile Operational_State current_state_;
|
bool is_rx_;
|
||||||
|
|
||||||
// Private helper methods
|
// Private helper methods
|
||||||
SDIO_Error_Type validate_voltage();
|
auto validate_voltage() -> SDIO_Error_Type;
|
||||||
SDIO_Error_Type get_r1_result(Command_Index index);
|
auto get_command_sent_result() -> SDIO_Error_Type;
|
||||||
//SDIO_Error_Type get_r2_r3_result();
|
auto get_r1_result(Command_Index index) -> SDIO_Error_Type;
|
||||||
SDIO_Error_Type get_r6_result(Command_Index index, uint16_t* rca);
|
auto get_r6_result(Command_Index index, uint16_t* rca) -> SDIO_Error_Type;
|
||||||
SDIO_Error_Type get_r7_result();
|
auto get_r7_result() -> SDIO_Error_Type { return check_sdio_status(Command_Index::INVALID, false, false); };
|
||||||
//SDIO_Error_Type get_r1_error_type(uint32_t response);
|
void sync_domains() { delayMicroseconds(8); }
|
||||||
SDIO_Error_Type get_command_sent_result();
|
|
||||||
|
|
||||||
inline void sync_domains() {
|
auto validate_transfer_params(uint32_t* buf, uint16_t size) -> bool {
|
||||||
delayMicroseconds(8);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool validate_transfer_params(uint32_t* buf, uint16_t size) {
|
|
||||||
if (buf == nullptr) return false;
|
if (buf == nullptr) return false;
|
||||||
// Size must be > 0, <= 2048 and power of 2
|
// Size must be > 0, <= 2048 and power of 2
|
||||||
if ((size == 0U) || (size > 2048U) || (size & (size - 1U))) {
|
return size > 0U && size <= 2048U && !(size & (size - 1U));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_sdsc_specific_csd(Card_Info* info, const uint8_t* csd_bytes) {
|
void process_sdsc_specific_csd(Card_Info* info, const uint8_t* csd_bytes) {
|
||||||
info->csd.device_size = (static_cast<uint32_t>(csd_bytes[6] & 0x03U) << 10U) |
|
const uint32_t device_size = ((csd_bytes[6] & 0x3U) << 10) |
|
||||||
(static_cast<uint32_t>(csd_bytes[7]) << 2U) |
|
(csd_bytes[7] << 2) |
|
||||||
(static_cast<uint32_t>((csd_bytes[8] & 0xC0U) >> 6U));
|
((csd_bytes[8] >> 6) & 0x3U);
|
||||||
info->csd.device_size_multiplier = static_cast<uint8_t>((csd_bytes[9] & 0x03U) << 1U |
|
|
||||||
(csd_bytes[10] & 0x80U) >> 7U);
|
|
||||||
|
|
||||||
info->block_size = static_cast<uint32_t>(1 << info->csd.read_block_length);
|
const uint8_t device_size_multiplier = ((csd_bytes[9] & 0x3U) << 1) |
|
||||||
info->capacity = static_cast<uint32_t>((info->csd.device_size + 1U) *
|
((csd_bytes[10] >> 7) & 0x1U);
|
||||||
(1U << (info->csd.device_size_multiplier + 2U)) *
|
|
||||||
info->block_size);
|
// Store calculated values
|
||||||
|
info->csd.device_size = device_size;
|
||||||
|
info->csd.device_size_multiplier = device_size_multiplier;
|
||||||
|
|
||||||
|
// Calculate block size and capacity
|
||||||
|
info->block_size = 1U << info->csd.read_block_length;
|
||||||
|
info->capacity = (device_size + 1U) *
|
||||||
|
(1U << (device_size_multiplier + 2U)) *
|
||||||
|
info->block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_sdhc_specific_csd(Card_Info* info, const uint8_t* csd_bytes) {
|
void process_sdhc_specific_csd(Card_Info* info, const uint8_t* csd_bytes) {
|
||||||
info->csd.device_size = static_cast<uint32_t>((csd_bytes[7] & 0x3FU) << 16U) |
|
info->csd.device_size = static_cast<uint32_t>((csd_bytes[7] & 0x3FU) << 16) |
|
||||||
static_cast<uint32_t>((csd_bytes[8]) << 8U) |
|
static_cast<uint32_t>((csd_bytes[8]) << 8) |
|
||||||
static_cast<uint32_t>(csd_bytes[9]);
|
static_cast<uint32_t>(csd_bytes[9]);
|
||||||
|
|
||||||
|
// Set block size and calculate capacity
|
||||||
info->block_size = BLOCK_SIZE;
|
info->block_size = BLOCK_SIZE;
|
||||||
info->capacity = static_cast<uint32_t>((info->csd.device_size + 1U) *
|
info->capacity = static_cast<uint32_t>((info->csd.device_size + 1U) *
|
||||||
BLOCK_SIZE * KILOBYTE);
|
BLOCK_SIZE * KILOBYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_common_csd_tail(Card_Info* info, const uint8_t* csd_bytes) {
|
void process_common_csd_tail(Card_Info* info, const uint8_t* csd_bytes) {
|
||||||
info->csd.sector_size = static_cast<uint8_t>(((csd_bytes[9] & 0x3FU) << 1U) |
|
// Calculate sector_size
|
||||||
(csd_bytes[10] & 0x80U) >> 7U);
|
info->csd.sector_size = static_cast<uint8_t>(((csd_bytes[9] & 0x3FU) << 1) |
|
||||||
info->csd.speed_factor = static_cast<uint8_t>((csd_bytes[11] & 0x1CU) >> 2U);
|
(csd_bytes[10] & 0x80U) >> 7);
|
||||||
info->csd.write_block_length = static_cast<uint8_t>(((csd_bytes[11] & 0x03U) << 2U) |
|
|
||||||
((csd_bytes[12] & 0xC0U) >> 6U));
|
// Calculate speed_factor and write_block_length
|
||||||
info->csd.checksum = static_cast<uint8_t>((csd_bytes[15] & 0xFEU) >> 1U);
|
info->csd.speed_factor = static_cast<uint8_t>((csd_bytes[11] & 0x1CU) >> 2);
|
||||||
|
info->csd.write_block_length = static_cast<uint8_t>(((csd_bytes[11] & 0x3U) << 2) |
|
||||||
|
((csd_bytes[12] & 0xC0U) >> 6));
|
||||||
|
|
||||||
|
// Calculate checksum
|
||||||
|
info->csd.checksum = static_cast<uint8_t>((csd_bytes[15] & 0xFEU) >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void disable_all_interrupts() {
|
void disable_all_interrupts() {
|
||||||
sdio_.set_interrupt_enable(Interrupt_Type::DTCRCERRIE, false);
|
sdio_.set_interrupt_enable(Interrupt_Type::DTCRCERRIE, false);
|
||||||
sdio_.set_interrupt_enable(Interrupt_Type::DTTMOUTIE, false);
|
sdio_.set_interrupt_enable(Interrupt_Type::DTTMOUTIE, false);
|
||||||
sdio_.set_interrupt_enable(Interrupt_Type::DTENDIE, false);
|
sdio_.set_interrupt_enable(Interrupt_Type::DTENDIE, false);
|
||||||
|
|
@ -200,8 +208,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CheckFunc>
|
template <typename CheckFunc>
|
||||||
inline SDIO_Error_Type send_command_and_check(Command_Index command, uint32_t argument,
|
auto send_command_and_check(Command_Index command, uint32_t argument,
|
||||||
Command_Response response, Wait_Type type, CheckFunc check_result) {
|
Command_Response response, Wait_Type type, CheckFunc check_result) -> SDIO_Error_Type {
|
||||||
sdio_.set_command_state_machine(command, argument, response, type);
|
sdio_.set_command_state_machine(command, argument, response, type);
|
||||||
sync_domains();
|
sync_domains();
|
||||||
sdio_.set_command_state_machine_enable(true);
|
sdio_.set_command_state_machine_enable(true);
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ inline constexpr uint8_t SDIO_READ_RETRIES = READ_RETRIES;
|
||||||
|
|
||||||
Card_State cardState = Card_State::READY;
|
Card_State cardState = Card_State::READY;
|
||||||
|
|
||||||
bool SDIO_SetBusWidth(Bus_Width width) {
|
auto SDIO_SetBusWidth(Bus_Width width) -> bool {
|
||||||
return (CardDMA_I.set_hardware_bus_width(width) == SDIO_Error_Type::OK);
|
return (CardDMA_I.set_hardware_bus_width(width) == SDIO_Error_Type::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,5 +32,5 @@
|
||||||
#define SDIO_CMD_PIN PD2
|
#define SDIO_CMD_PIN PD2
|
||||||
|
|
||||||
void sdio_mfl_init();
|
void sdio_mfl_init();
|
||||||
bool SDIO_SetBusWidth(sdio::Bus_Width width);
|
auto SDIO_SetBusWidth(sdio::Bus_Width width) -> bool;
|
||||||
void DMA1_IRQHandler(dma::DMA_Channel channel);
|
void DMA1_IRQHandler(dma::DMA_Channel channel);
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ static inline constexpr struct {timer::TIMER_Base base; uint8_t timer_number;} b
|
||||||
};
|
};
|
||||||
|
|
||||||
// Converts a timer base to an integer timer index.
|
// Converts a timer base to an integer timer index.
|
||||||
constexpr int timer_base_to_index(timer::TIMER_Base base) {
|
constexpr auto timer_base_to_index(timer::TIMER_Base base) -> int {
|
||||||
for (const auto& timer : base_to_index) {
|
for (const auto& timer : base_to_index) {
|
||||||
if (timer.base == base) {
|
if (timer.base == base) {
|
||||||
return static_cast<int>(timer.timer_number);
|
return static_cast<int>(timer.timer_number);
|
||||||
|
|
@ -131,7 +131,7 @@ FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_number)
|
||||||
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_number, const hal_timer_t value) {
|
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_number, const hal_timer_t value) {
|
||||||
if (!HAL_timer_initialized(timer_number)) return;
|
if (!HAL_timer_initialized(timer_number)) return;
|
||||||
|
|
||||||
const uint32_t new_value = static_cast<uint32_t>(value + 1U);
|
const auto new_value = static_cast<uint32_t>(value + 1U);
|
||||||
GeneralTimer& timer = (timer_number == MF_TIMER_STEP) ? Step_Timer : Temp_Timer;
|
GeneralTimer& timer = (timer_number == MF_TIMER_STEP) ? Step_Timer : Temp_Timer;
|
||||||
|
|
||||||
if (timer_number == MF_TIMER_STEP || timer_number == MF_TIMER_TEMP) {
|
if (timer_number == MF_TIMER_STEP || timer_number == MF_TIMER_TEMP) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
####################################
|
####################################
|
||||||
|
|
||||||
[gd32_base]
|
[gd32_base]
|
||||||
platform = https://github.com/bmourit/platform-mfl/archive/refs/tags/V1.0.3.zip
|
platform = https://github.com/bmourit/platform-mfl/archive/refs/tags/V1.0.4.zip
|
||||||
board_build.core = gd32
|
board_build.core = gd32
|
||||||
build_src_filter = ${common.default_src_filter} +<src/HAL/GD32_MFL> +<src/HAL/shared/backtrace>
|
build_src_filter = ${common.default_src_filter} +<src/HAL/GD32_MFL> +<src/HAL/shared/backtrace>
|
||||||
build_unflags = -std=gnu++11 -std=gnu++14 -std=gnu++17
|
build_unflags = -std=gnu++11 -std=gnu++14 -std=gnu++17
|
||||||
|
|
@ -28,7 +28,7 @@ extra_scripts = ${common.extra_scripts}
|
||||||
#
|
#
|
||||||
[env:GD32F303RE_creality_mfl]
|
[env:GD32F303RE_creality_mfl]
|
||||||
extends = gd32_base
|
extends = gd32_base
|
||||||
board = mfl_creality_422
|
board = mfl_creality_v4
|
||||||
board_build.offset = 0x7000
|
board_build.offset = 0x7000
|
||||||
board_upload.offset_address = 0x08007000
|
board_upload.offset_address = 0x08007000
|
||||||
board_build.rename = firmware-{time}.bin
|
board_build.rename = firmware-{time}.bin
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue