Standardize Marlin SPI (part 1) (#19989)
This commit is contained in:
parent
97d7af7a23
commit
85d094bbb4
1
.github/workflows/test-builds.yml
vendored
1
.github/workflows/test-builds.yml
vendored
|
@ -83,6 +83,7 @@ jobs:
|
|||
- STM32F103RET6_creality
|
||||
- LERDGEX
|
||||
- mks_robin_nano35
|
||||
- mks_robin_nano35_stm32
|
||||
- NUCLEO_F767ZI
|
||||
|
||||
# Put lengthy tests last
|
||||
|
|
|
@ -127,11 +127,9 @@
|
|||
for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]);
|
||||
}
|
||||
|
||||
void spiSend(uint32_t chan, byte b) {
|
||||
}
|
||||
void spiSend(uint32_t chan, byte b) {}
|
||||
|
||||
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
|
||||
}
|
||||
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {}
|
||||
|
||||
// Read single byte from SPI
|
||||
uint8_t spiRec() { return doio(0xFF); }
|
||||
|
@ -143,9 +141,7 @@
|
|||
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
|
||||
}
|
||||
|
||||
uint8_t spiTransfer(uint8_t b) {
|
||||
return doio(b);
|
||||
}
|
||||
uint8_t spiTransfer(uint8_t b) { return doio(b); }
|
||||
|
||||
// Write from buffer to SPI
|
||||
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||
|
@ -201,6 +197,15 @@ SPIClass::SPIClass(uint8_t device) {
|
|||
GPDMA_Init();
|
||||
}
|
||||
|
||||
SPIClass::SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel) {
|
||||
#if BOARD_NR_SPI >= 1
|
||||
if (mosi == BOARD_SPI1_MOSI_PIN) SPIClass(1);
|
||||
#endif
|
||||
#if BOARD_NR_SPI >= 2
|
||||
if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SPIClass::begin() {
|
||||
// Init the SPI pins in the first begin call
|
||||
if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) ||
|
||||
|
@ -331,25 +336,15 @@ void SPIClass::read(uint8_t *buf, uint32_t len) {
|
|||
for (uint16_t i = 0; i < len; i++) buf[i] = transfer(0xFF);
|
||||
}
|
||||
|
||||
void SPIClass::setClock(uint32_t clock) {
|
||||
_currentSetting->clock = clock;
|
||||
}
|
||||
void SPIClass::setClock(uint32_t clock) { _currentSetting->clock = clock; }
|
||||
|
||||
void SPIClass::setModule(uint8_t device) {
|
||||
_currentSetting = &_settings[device - 1];// SPI channels are called 1 2 and 3 but the array is zero indexed
|
||||
}
|
||||
void SPIClass::setModule(uint8_t device) { _currentSetting = &_settings[device - 1]; } // SPI channels are called 1, 2, and 3 but the array is zero-indexed
|
||||
|
||||
void SPIClass::setBitOrder(uint8_t bitOrder) {
|
||||
_currentSetting->bitOrder = bitOrder;
|
||||
}
|
||||
void SPIClass::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; }
|
||||
|
||||
void SPIClass::setDataMode(uint8_t dataMode) {
|
||||
_currentSetting->dataMode = dataMode;
|
||||
}
|
||||
void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; }
|
||||
|
||||
void SPIClass::setDataSize(uint32_t ds) {
|
||||
_currentSetting->dataSize = ds;
|
||||
}
|
||||
void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; }
|
||||
|
||||
/**
|
||||
* Set up/tear down
|
||||
|
|
45
Marlin/src/HAL/LPC1768/MarlinSPI.h
Normal file
45
Marlin/src/HAL/LPC1768/MarlinSPI.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
/**
|
||||
* Marlin currently requires 3 SPI classes:
|
||||
*
|
||||
* SPIClass:
|
||||
* This class is normally provided by frameworks and has a semi-default interface.
|
||||
* This is needed because some libraries reference it globally.
|
||||
*
|
||||
* SPISettings:
|
||||
* Container for SPI configs for SPIClass. As above, libraries may reference it globally.
|
||||
*
|
||||
* These two classes are often provided by frameworks so we cannot extend them to add
|
||||
* useful methods for Marlin.
|
||||
*
|
||||
* MarlinSPI:
|
||||
* Provides the default SPIClass interface plus some Marlin goodies such as a simplified
|
||||
* interface for SPI DMA transfer.
|
||||
*
|
||||
*/
|
||||
|
||||
using MarlinSPI = SPIClass;
|
|
@ -126,6 +126,11 @@ public:
|
|||
*/
|
||||
SPIClass(uint8_t spiPortNumber);
|
||||
|
||||
/**
|
||||
* Init using pins
|
||||
*/
|
||||
SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)-1);
|
||||
|
||||
/**
|
||||
* Select and configure the current selected SPI device to use
|
||||
*/
|
||||
|
|
161
Marlin/src/HAL/STM32/MarlinSPI.cpp
Normal file
161
Marlin/src/HAL/STM32/MarlinSPI.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MarlinSPI.h"
|
||||
|
||||
static void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb, uint32_t dataSize) {
|
||||
spi_init(obj, speed, mode, msb);
|
||||
// spi_init set 8bit always
|
||||
// TODO: copy the code from spi_init and handle data size, to avoid double init always!!
|
||||
if (dataSize != SPI_DATASIZE_8BIT) {
|
||||
obj->handle.Init.DataSize = dataSize;
|
||||
HAL_SPI_Init(&obj->handle);
|
||||
__HAL_SPI_ENABLE(&obj->handle);
|
||||
}
|
||||
}
|
||||
|
||||
void MarlinSPI::setClockDivider(uint8_t _div) {
|
||||
_speed = spi_getClkFreq(&_spi);// / _div;
|
||||
_clockDivider = _div;
|
||||
}
|
||||
|
||||
void MarlinSPI::begin(void) {
|
||||
//TODO: only call spi_init if any parameter changed!!
|
||||
spi_init(&_spi, _speed, _dataMode, _bitOrder, _dataSize);
|
||||
}
|
||||
|
||||
void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc) {
|
||||
_dmaHandle.Init.Direction = direction;
|
||||
_dmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
_dmaHandle.Init.Mode = DMA_NORMAL;
|
||||
_dmaHandle.Init.Priority = DMA_PRIORITY_LOW;
|
||||
_dmaHandle.Init.MemInc = minc ? DMA_MINC_ENABLE : DMA_MINC_DISABLE;
|
||||
|
||||
if (_dataSize == DATA_SIZE_8BIT) {
|
||||
_dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
_dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
}
|
||||
else {
|
||||
_dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
_dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
}
|
||||
#ifdef STM32F4xx
|
||||
_dmaHandle.Init.Channel = DMA_CHANNEL_3;
|
||||
_dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
#endif
|
||||
|
||||
// start DMA hardware
|
||||
// TODO: check if hardware is already enabled
|
||||
#ifdef SPI1_BASE
|
||||
if (_spiHandle.Instance == SPI1) {
|
||||
#ifdef STM32F1xx
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel3 : DMA1_Channel2;
|
||||
#elif defined(STM32F4xx)
|
||||
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||
_dmaHandle.Instance = DMA2_Stream3;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI2_BASE
|
||||
if (_spiHandle.Instance == SPI2) {
|
||||
#ifdef STM32F1xx
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel5 : DMA1_Channel4;
|
||||
#elif defined(STM32F4xx)
|
||||
//TODO: f4 dma config
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI3_BASE
|
||||
if (_spiHandle.Instance == SPI3) {
|
||||
#ifdef STM32F1xx
|
||||
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Channel2 : DMA2_Channel1;
|
||||
#elif defined(STM32F4xx)
|
||||
//TODO: f4 dma config
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
HAL_DMA_Init(&_dmaHandle);
|
||||
}
|
||||
|
||||
byte MarlinSPI::transfer(uint8_t _data) {
|
||||
uint8_t rxData = 0xFF;
|
||||
HAL_SPI_TransmitReceive(&_spi.handle, &_data, &rxData, 1, HAL_MAX_DELAY);
|
||||
return rxData;
|
||||
}
|
||||
|
||||
uint8_t MarlinSPI::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length) {
|
||||
const uint8_t ff = 0xFF;
|
||||
|
||||
//if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) //only enable if disabled
|
||||
__HAL_SPI_ENABLE(&_spi.handle);
|
||||
|
||||
if (receiveBuf) {
|
||||
setupDma(_spi.handle, _dmaRx, DMA_PERIPH_TO_MEMORY, true);
|
||||
HAL_DMA_Start(&_dmaRx, (uint32_t)&(_spi.handle.Instance->DR), (uint32_t)receiveBuf, length);
|
||||
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_RXDMAEN); /* Enable Rx DMA Request */
|
||||
}
|
||||
|
||||
// check for 2 lines transfer
|
||||
bool mincTransmit = true;
|
||||
if (transmitBuf == nullptr && _spi.handle.Init.Direction == SPI_DIRECTION_2LINES && _spi.handle.Init.Mode == SPI_MODE_MASTER) {
|
||||
transmitBuf = &ff;
|
||||
mincTransmit = false;
|
||||
}
|
||||
|
||||
if (transmitBuf) {
|
||||
setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, mincTransmit);
|
||||
HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
|
||||
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
|
||||
}
|
||||
|
||||
if (transmitBuf) {
|
||||
HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
|
||||
HAL_DMA_Abort(&_dmaTx);
|
||||
HAL_DMA_DeInit(&_dmaTx);
|
||||
}
|
||||
|
||||
// while ((_spi.handle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
|
||||
|
||||
if (receiveBuf) {
|
||||
HAL_DMA_PollForTransfer(&_dmaRx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
|
||||
HAL_DMA_Abort(&_dmaRx);
|
||||
HAL_DMA_DeInit(&_dmaRx);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t MarlinSPI::dmaSend(const void * transmitBuf, uint16_t length, bool minc) {
|
||||
setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, minc);
|
||||
HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
|
||||
__HAL_SPI_ENABLE(&_spi.handle);
|
||||
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
|
||||
HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
|
||||
HAL_DMA_Abort(&_dmaTx);
|
||||
// DeInit objects
|
||||
HAL_DMA_DeInit(&_dmaTx);
|
||||
return 1;
|
||||
}
|
107
Marlin/src/HAL/STM32/MarlinSPI.h
Normal file
107
Marlin/src/HAL/STM32/MarlinSPI.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "HAL.h"
|
||||
#include <SPI.h>
|
||||
|
||||
extern "C" {
|
||||
#include <utility/spi_com.h>
|
||||
}
|
||||
|
||||
/**
|
||||
* Marlin currently requires 3 SPI classes:
|
||||
*
|
||||
* SPIClass:
|
||||
* This class is normally provided by frameworks and has a semi-default interface.
|
||||
* This is needed because some libraries reference it globally.
|
||||
*
|
||||
* SPISettings:
|
||||
* Container for SPI configs for SPIClass. As above, libraries may reference it globally.
|
||||
*
|
||||
* These two classes are often provided by frameworks so we cannot extend them to add
|
||||
* useful methods for Marlin.
|
||||
*
|
||||
* MarlinSPI:
|
||||
* Provides the default SPIClass interface plus some Marlin goodies such as a simplified
|
||||
* interface for SPI DMA transfer.
|
||||
*
|
||||
*/
|
||||
|
||||
#define DATA_SIZE_8BIT SPI_DATASIZE_8BIT
|
||||
#define DATA_SIZE_16BIT SPI_DATASIZE_16BIT
|
||||
|
||||
class MarlinSPI {
|
||||
public:
|
||||
MarlinSPI() : MarlinSPI(NC, NC, NC, NC) {}
|
||||
|
||||
MarlinSPI(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)NC) : _mosiPin(mosi), _misoPin(miso), _sckPin(sclk), _ssPin(ssel) {
|
||||
_spi.pin_miso = digitalPinToPinName(_misoPin);
|
||||
_spi.pin_mosi = digitalPinToPinName(_mosiPin);
|
||||
_spi.pin_sclk = digitalPinToPinName(_sckPin);
|
||||
_spi.pin_ssel = digitalPinToPinName(_ssPin);
|
||||
_dataSize = DATA_SIZE_8BIT;
|
||||
_bitOrder = MSBFIRST;
|
||||
_dataMode = SPI_MODE_0;
|
||||
_spi.handle.State = HAL_SPI_STATE_RESET;
|
||||
setClockDivider(SPI_SPEED_CLOCK_DIV2_MHZ);
|
||||
}
|
||||
|
||||
void begin(void);
|
||||
void end(void) {}
|
||||
|
||||
byte transfer(uint8_t _data);
|
||||
uint8_t dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length);
|
||||
uint8_t dmaSend(const void * transmitBuf, uint16_t length, bool minc = true);
|
||||
|
||||
/* These methods are deprecated and kept for compatibility.
|
||||
* Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
|
||||
*/
|
||||
void setBitOrder(BitOrder _order) { _bitOrder = _order; }
|
||||
|
||||
void setDataMode(uint8_t _mode) {
|
||||
switch (_mode) {
|
||||
case SPI_MODE0: _dataMode = SPI_MODE_0; break;
|
||||
case SPI_MODE1: _dataMode = SPI_MODE_1; break;
|
||||
case SPI_MODE2: _dataMode = SPI_MODE_2; break;
|
||||
case SPI_MODE3: _dataMode = SPI_MODE_3; break;
|
||||
}
|
||||
}
|
||||
|
||||
void setClockDivider(uint8_t _div);
|
||||
|
||||
private:
|
||||
void setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc = false);
|
||||
|
||||
spi_t _spi;
|
||||
DMA_HandleTypeDef _dmaTx;
|
||||
DMA_HandleTypeDef _dmaRx;
|
||||
BitOrder _bitOrder;
|
||||
spi_mode_e _dataMode;
|
||||
uint8_t _clockDivider;
|
||||
uint32_t _speed;
|
||||
uint32_t _dataSize;
|
||||
pin_t _mosiPin;
|
||||
pin_t _misoPin;
|
||||
pin_t _sckPin;
|
||||
pin_t _ssPin;
|
||||
};
|
|
@ -105,7 +105,7 @@ void SetTimerInterruptPriorities();
|
|||
|
||||
// FORCE_INLINE because these are used in performance-critical situations
|
||||
FORCE_INLINE bool HAL_timer_initialized(const uint8_t timer_num) {
|
||||
return timer_instance[timer_num] != NULL;
|
||||
return timer_instance[timer_num] != nullptr;
|
||||
}
|
||||
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
|
||||
return HAL_timer_initialized(timer_num) ? timer_instance[timer_num]->getCount() : 0;
|
||||
|
|
45
Marlin/src/HAL/STM32F1/MarlinSPI.h
Normal file
45
Marlin/src/HAL/STM32F1/MarlinSPI.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
/**
|
||||
* Marlin currently requires 3 SPI classes:
|
||||
*
|
||||
* SPIClass:
|
||||
* This class is normally provided by frameworks and has a semi-default interface.
|
||||
* This is needed because some libraries reference it globally.
|
||||
*
|
||||
* SPISettings:
|
||||
* Container for SPI configs for SPIClass. As above, libraries may reference it globally.
|
||||
*
|
||||
* These two classes are often provided by frameworks so we cannot extend them to add
|
||||
* useful methods for Marlin.
|
||||
*
|
||||
* MarlinSPI:
|
||||
* Provides the default SPIClass interface plus some Marlin goodies such as a simplified
|
||||
* interface for SPI DMA transfer.
|
||||
*
|
||||
*/
|
||||
|
||||
using MarlinSPI = SPIClass;
|
|
@ -147,6 +147,18 @@ SPIClass::SPIClass(uint32_t spi_num) {
|
|||
_currentSetting->state = SPI_STATE_IDLE;
|
||||
}
|
||||
|
||||
SPIClass::SPIClass(int8_t mosi, int8_t miso, int8_t sclk, int8_t ssel) {
|
||||
#if BOARD_NR_SPI >= 1
|
||||
if (mosi == BOARD_SPI1_MOSI_PIN) SPIClass(1);
|
||||
#endif
|
||||
#if BOARD_NR_SPI >= 2
|
||||
if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2);
|
||||
#endif
|
||||
#if BOARD_NR_SPI >= 3
|
||||
if (mosi == BOARD_SPI3_MOSI_PIN) SPIClass(3);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up/tear down
|
||||
*/
|
||||
|
|
|
@ -163,6 +163,11 @@ public:
|
|||
*/
|
||||
SPIClass(uint32_t spiPortNumber);
|
||||
|
||||
/**
|
||||
* Init using pins
|
||||
*/
|
||||
SPIClass(int8_t mosi, int8_t miso, int8_t sclk, int8_t ssel=-1);
|
||||
|
||||
/**
|
||||
* @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).
|
||||
*/
|
||||
|
|
|
@ -32,7 +32,12 @@
|
|||
|
||||
/**
|
||||
* lcd_put_u8str_ind_P
|
||||
* Print a string with an index substituted within it
|
||||
*
|
||||
* Print a string with an index substituted within it:
|
||||
*
|
||||
* = displays '0'....'10' for indexes 0 - 10
|
||||
* ~ displays '1'....'11' for indexes 0 - 10
|
||||
* * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
|
||||
*/
|
||||
lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) {
|
||||
uint8_t *p = (uint8_t*)pstr;
|
||||
|
|
|
@ -44,21 +44,21 @@ void TFT_String::set_font(const uint8_t *font) {
|
|||
|
||||
for (glyph = 0; glyph < 256; glyph++) glyphs[glyph] = nullptr;
|
||||
|
||||
DEBUG_ECHOLNPAIR("Format: ", font_header->Format);
|
||||
DEBUG_ECHOLNPAIR("BBXWidth: ", font_header->BBXWidth);
|
||||
DEBUG_ECHOLNPAIR("BBXHeight: ", font_header->BBXHeight);
|
||||
DEBUG_ECHOLNPAIR("BBXOffsetX: ", font_header->BBXOffsetX);
|
||||
DEBUG_ECHOLNPAIR("BBXOffsetY: ", font_header->BBXOffsetY);
|
||||
DEBUG_ECHOLNPAIR("CapitalAHeight: ", font_header->CapitalAHeight);
|
||||
DEBUG_ECHOLNPAIR("Encoding65Pos: ", font_header->Encoding65Pos);
|
||||
DEBUG_ECHOLNPAIR("Encoding97Pos: ", font_header->Encoding97Pos);
|
||||
DEBUG_ECHOLNPAIR("Format: ", font_header->Format);
|
||||
DEBUG_ECHOLNPAIR("BBXWidth: ", font_header->BBXWidth);
|
||||
DEBUG_ECHOLNPAIR("BBXHeight: ", font_header->BBXHeight);
|
||||
DEBUG_ECHOLNPAIR("BBXOffsetX: ", font_header->BBXOffsetX);
|
||||
DEBUG_ECHOLNPAIR("BBXOffsetY: ", font_header->BBXOffsetY);
|
||||
DEBUG_ECHOLNPAIR("CapitalAHeight: ", font_header->CapitalAHeight);
|
||||
DEBUG_ECHOLNPAIR("Encoding65Pos: ", font_header->Encoding65Pos);
|
||||
DEBUG_ECHOLNPAIR("Encoding97Pos: ", font_header->Encoding97Pos);
|
||||
DEBUG_ECHOLNPAIR("FontStartEncoding: ", font_header->FontStartEncoding);
|
||||
DEBUG_ECHOLNPAIR("FontEndEncoding: ", font_header->FontEndEncoding);
|
||||
DEBUG_ECHOLNPAIR("LowerGDescent: ", font_header->LowerGDescent);
|
||||
DEBUG_ECHOLNPAIR("FontAscent: ", font_header->FontAscent);
|
||||
DEBUG_ECHOLNPAIR("FontDescent: ", font_header->FontDescent);
|
||||
DEBUG_ECHOLNPAIR("FontXAscent: ", font_header->FontXAscent);
|
||||
DEBUG_ECHOLNPAIR("FontXDescent: ", font_header->FontXDescent);
|
||||
DEBUG_ECHOLNPAIR("FontEndEncoding: ", font_header->FontEndEncoding);
|
||||
DEBUG_ECHOLNPAIR("LowerGDescent: ", font_header->LowerGDescent);
|
||||
DEBUG_ECHOLNPAIR("FontAscent: ", font_header->FontAscent);
|
||||
DEBUG_ECHOLNPAIR("FontDescent: ", font_header->FontDescent);
|
||||
DEBUG_ECHOLNPAIR("FontXAscent: ", font_header->FontXAscent);
|
||||
DEBUG_ECHOLNPAIR("FontXDescent: ", font_header->FontXDescent);
|
||||
|
||||
add_glyphs(font);
|
||||
}
|
||||
|
@ -72,9 +72,8 @@ void TFT_String::add_glyphs(const uint8_t *font) {
|
|||
glyphs[glyph] = (glyph_t *)pointer;
|
||||
pointer += sizeof(glyph_t) + ((glyph_t *)pointer)->DataSize;
|
||||
}
|
||||
else {
|
||||
else
|
||||
pointer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,6 +85,13 @@ void TFT_String::set() {
|
|||
|
||||
uint8_t read_byte(uint8_t *byte) { return *byte; }
|
||||
|
||||
/**
|
||||
* Add a string, applying substitutions for the following characters:
|
||||
*
|
||||
* = displays '0'....'10' for indexes 0 - 10
|
||||
* ~ displays '1'....'11' for indexes 0 - 10
|
||||
* * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
|
||||
*/
|
||||
void TFT_String::add(uint8_t *string, int8_t index, uint8_t *itemString) {
|
||||
wchar_t wchar;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#if HAS_SPI_FLASH
|
||||
|
||||
#include "W25Qxx.h"
|
||||
#include <SPI.h>
|
||||
|
||||
W25QXXFlash W25QXX;
|
||||
|
||||
|
@ -41,6 +40,11 @@ W25QXXFlash W25QXX;
|
|||
#ifndef SPI_FLASH_CS_PIN
|
||||
#define SPI_FLASH_CS_PIN W25QXX_CS_PIN
|
||||
#endif
|
||||
#ifndef NC
|
||||
#define NC -1
|
||||
#endif
|
||||
|
||||
MarlinSPI W25QXXFlash::mySPI(SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN, SPI_FLASH_SCK_PIN, NC);
|
||||
|
||||
#define W25QXX_CS_H OUT_WRITE(SPI_FLASH_CS_PIN, HIGH)
|
||||
#define W25QXX_CS_L OUT_WRITE(SPI_FLASH_CS_PIN, LOW)
|
||||
|
@ -69,11 +73,11 @@ void W25QXXFlash::init(uint8_t spiRate) {
|
|||
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
|
||||
default: clock = SPI_CLOCK_DIV2;// Default from the SPI library
|
||||
}
|
||||
SPI.setModule(SPI_DEVICE);
|
||||
SPI.begin();
|
||||
SPI.setClockDivider(clock);
|
||||
SPI.setBitOrder(MSBFIRST);
|
||||
SPI.setDataMode(SPI_MODE0);
|
||||
|
||||
mySPI.setClockDivider(clock);
|
||||
mySPI.setBitOrder(MSBFIRST);
|
||||
mySPI.setDataMode(SPI_MODE0);
|
||||
mySPI.begin();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,12 +86,12 @@ void W25QXXFlash::init(uint8_t spiRate) {
|
|||
* @return Byte received
|
||||
*/
|
||||
uint8_t W25QXXFlash::spi_flash_Rec() {
|
||||
const uint8_t returnByte = SPI.transfer(0xFF);
|
||||
const uint8_t returnByte = mySPI.transfer(0xFF);
|
||||
return returnByte;
|
||||
}
|
||||
|
||||
uint8_t W25QXXFlash::spi_flash_read_write_byte(uint8_t data) {
|
||||
const uint8_t returnByte = SPI.transfer(data);
|
||||
const uint8_t returnByte = mySPI.transfer(data);
|
||||
return returnByte;
|
||||
}
|
||||
|
||||
|
@ -100,7 +104,9 @@ uint8_t W25QXXFlash::spi_flash_read_write_byte(uint8_t data) {
|
|||
*
|
||||
* @details Uses DMA
|
||||
*/
|
||||
void W25QXXFlash::spi_flash_Read(uint8_t* buf, uint16_t nbyte) { SPI.dmaTransfer(0, const_cast<uint8_t*>(buf), nbyte); }
|
||||
void W25QXXFlash::spi_flash_Read(uint8_t* buf, uint16_t nbyte) {
|
||||
mySPI.dmaTransfer(0, const_cast<uint8_t*>(buf), nbyte);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send a single byte on SPI port
|
||||
|
@ -109,7 +115,7 @@ void W25QXXFlash::spi_flash_Read(uint8_t* buf, uint16_t nbyte) { SPI.dmaTransfer
|
|||
*
|
||||
* @details
|
||||
*/
|
||||
void W25QXXFlash::spi_flash_Send(uint8_t b) { SPI.send(b); }
|
||||
void W25QXXFlash::spi_flash_Send(uint8_t b) { mySPI.transfer(b); }
|
||||
|
||||
/**
|
||||
* @brief Write token and then write from 512 byte buffer to SPI (for SD card)
|
||||
|
@ -120,8 +126,8 @@ void W25QXXFlash::spi_flash_Send(uint8_t b) { SPI.send(b); }
|
|||
* @details Use DMA
|
||||
*/
|
||||
void W25QXXFlash::spi_flash_SendBlock(uint8_t token, const uint8_t* buf) {
|
||||
SPI.send(token);
|
||||
SPI.dmaSend(const_cast<uint8_t*>(buf), 512);
|
||||
mySPI.transfer(token);
|
||||
mySPI.dmaSend(const_cast<uint8_t*>(buf), 512);
|
||||
}
|
||||
|
||||
uint16_t W25QXXFlash::W25QXX_ReadID(void) {
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include HAL_PATH(../HAL, MarlinSPI.h)
|
||||
|
||||
#define W25X_WriteEnable 0x06
|
||||
#define W25X_WriteDisable 0x04
|
||||
#define W25X_ReadStatusReg 0x05
|
||||
|
@ -49,6 +51,8 @@
|
|||
#define SPI_FLASH_PerWritePageSize 256
|
||||
|
||||
class W25QXXFlash {
|
||||
private:
|
||||
static MarlinSPI mySPI;
|
||||
public:
|
||||
void init(uint8_t spiRate);
|
||||
static uint8_t spi_flash_Rec();
|
||||
|
|
|
@ -191,6 +191,9 @@
|
|||
#define FSMC_DMA_DEV DMA2
|
||||
#define FSMC_DMA_CHANNEL DMA_CH5
|
||||
|
||||
#define TFT_CS_PIN FSMC_CS_PIN
|
||||
#define TFT_RS_PIN FSMC_RS_PIN
|
||||
|
||||
#define TOUCH_BUTTONS_HW_SPI
|
||||
#define TOUCH_BUTTONS_HW_SPI_DEVICE 2
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO
|
|||
exec_test $1 $2 "MKS Robin nano v1.2 Emulated DOGM FSMC"
|
||||
|
||||
#
|
||||
# MKS Robin v2 nano LVGL SPI
|
||||
# MKS Robin v2 nano Emulated DOGM SPI
|
||||
# (Robin v2 nano has no FSMC interface)
|
||||
#
|
||||
use_example_configs Mks/Robin
|
||||
|
|
69
buildroot/tests/mks_robin_nano35_stm32-tests
Normal file
69
buildroot/tests/mks_robin_nano35_stm32-tests
Normal file
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build tests for MKS Robin nano
|
||||
# (STM32F1 genericSTM32F103VE)
|
||||
#
|
||||
|
||||
# exit on first failure
|
||||
set -e
|
||||
|
||||
#
|
||||
# MKS Robin nano v1.2 Emulated DOGM FSMC
|
||||
#
|
||||
use_example_configs Mks/Robin
|
||||
opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO
|
||||
exec_test $1 $2 "MKS Robin nano v1.2 Emulated DOGM FSMC"
|
||||
|
||||
#
|
||||
# MKS Robin v2 nano Emulated DOGM SPI
|
||||
# (Robin v2 nano has no FSMC interface)
|
||||
#
|
||||
use_example_configs Mks/Robin
|
||||
opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO_V2
|
||||
opt_disable TFT_INTERFACE_FSMC
|
||||
opt_enable TFT_INTERFACE_SPI
|
||||
exec_test $1 $2 "MKS Robin v2 nano Emulated DOGM SPI"
|
||||
|
||||
#
|
||||
# MKS Robin nano v1.2 LVGL FSMC
|
||||
#
|
||||
# use_example_configs Mks/Robin
|
||||
# opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO
|
||||
# opt_disable TFT_CLASSIC_UI TFT_COLOR_UI TOUCH_SCREEN TFT_RES_320x240
|
||||
# opt_enable TFT_LVGL_UI TFT_RES_480x320
|
||||
# exec_test $1 $2 "MKS Robin nano v1.2 LVGL FSMC"
|
||||
|
||||
#
|
||||
# MKS Robin v2 nano LVGL SPI
|
||||
# (Robin v2 nano has no FSMC interface)
|
||||
#
|
||||
# use_example_configs Mks/Robin
|
||||
# opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO_V2
|
||||
# opt_disable TFT_INTERFACE_FSMC TFT_COLOR_UI TOUCH_SCREEN TFT_RES_320x240
|
||||
# opt_enable TFT_INTERFACE_SPI TFT_LVGL_UI TFT_RES_480x320
|
||||
# exec_test $1 $2 "MKS Robin v2 nano LVGL SPI"
|
||||
|
||||
#
|
||||
# MKS Robin v2 nano New Color UI 480x320 SPI
|
||||
# (Robin v2 nano has no FSMC interface)
|
||||
#
|
||||
use_example_configs Mks/Robin
|
||||
opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO_V2
|
||||
opt_disable TFT_INTERFACE_FSMC TFT_RES_320x240
|
||||
opt_enable TFT_INTERFACE_SPI TFT_RES_480x320
|
||||
exec_test $1 $2 "MKS Robin v2 nano New Color UI 480x320 SPI"
|
||||
|
||||
#
|
||||
# MKS Robin v2 nano LVGL SPI + TMC
|
||||
# (Robin v2 nano has no FSMC interface)
|
||||
#
|
||||
# use_example_configs Mks/Robin
|
||||
# opt_set MOTHERBOARD BOARD_MKS_ROBIN_NANO_V2
|
||||
# opt_disable TFT_INTERFACE_FSMC TFT_COLOR_UI TOUCH_SCREEN TFT_RES_320x240
|
||||
# opt_enable TFT_INTERFACE_SPI TFT_LVGL_UI TFT_RES_480x320
|
||||
# opt_set X_DRIVER_TYPE TMC2209
|
||||
# opt_set Y_DRIVER_TYPE TMC2209
|
||||
# exec_test $1 $2 "MKS Robin v2 nano LVGL SPI + TMC"
|
||||
|
||||
# cleanup
|
||||
restore_configs
|
Loading…
Reference in a new issue