Standardize Marlin SPI (part 1) (#19989)
This commit is contained in:
		@@ -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).
 | 
			
		||||
   */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user