Browse Source

[2.0.x] HAL for STM32F4 (#10434)

pull/1/head
Karl Andersson 6 years ago
committed by Scott Lahteine
parent
commit
428c54f2ad
  1. 571
      Marlin/src/HAL/HAL_STM32F4/EEPROM_Emul/eeprom_emul.cpp
  2. 117
      Marlin/src/HAL/HAL_STM32F4/EEPROM_Emul/eeprom_emul.h
  3. 143
      Marlin/src/HAL/HAL_STM32F4/EmulatedEeprom.cpp
  4. 140
      Marlin/src/HAL/HAL_STM32F4/HAL.cpp
  5. 249
      Marlin/src/HAL/HAL_STM32F4/HAL.h
  6. 53
      Marlin/src/HAL/HAL_STM32F4/HAL_Servo_STM32F4.cpp
  7. 41
      Marlin/src/HAL/HAL_STM32F4/HAL_Servo_STM32F4.h
  8. 165
      Marlin/src/HAL/HAL_STM32F4/HAL_spi_STM32F4.cpp
  9. 156
      Marlin/src/HAL/HAL_STM32F4/HAL_timers_STM32F4.cpp
  10. 105
      Marlin/src/HAL/HAL_STM32F4/HAL_timers_STM32F4.h
  11. 12
      Marlin/src/HAL/HAL_STM32F4/README.md
  12. 66
      Marlin/src/HAL/HAL_STM32F4/SanityCheck.h
  13. 77
      Marlin/src/HAL/HAL_STM32F4/endstop_interrupts.h
  14. 54
      Marlin/src/HAL/HAL_STM32F4/fastio_STM32F4.h
  15. 75
      Marlin/src/HAL/HAL_STM32F4/persistent_store_impl.cpp
  16. 1
      Marlin/src/HAL/HAL_STM32F4/pinsDebug.h
  17. 41
      Marlin/src/HAL/HAL_STM32F4/spi_pins.h
  18. 57
      Marlin/src/HAL/HAL_STM32F4/watchdog_STM32F4.cpp
  19. 33
      Marlin/src/HAL/HAL_STM32F4/watchdog_STM32F4.h
  20. 2
      Marlin/src/HAL/platforms.h
  21. 2
      Marlin/src/HAL/servo.cpp
  22. 3
      Marlin/src/HAL/servo.h
  23. 11
      Marlin/src/backtrace/unwmemaccess.cpp
  24. 1868
      Marlin/src/config/examples/STM32F4/Configuration.h
  25. 1
      Marlin/src/core/boards.h
  26. 2
      Marlin/src/pins/pins.h
  27. 204
      Marlin/src/pins/pins_STM32F4.h
  28. 10
      platformio.ini

571
Marlin/src/HAL/HAL_STM32F4/EEPROM_Emul/eeprom_emul.cpp

@ -0,0 +1,571 @@
/**
******************************************************************************
* @file EEPROM/EEPROM_Emulation/src/eeprom.c
* @author MCD Application Team
* @version V1.2.6
* @date 04-November-2016
* @brief This file provides all the EEPROM emulation firmware functions.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright © 2016 STMicroelectronics International N.V.
* All rights reserved.</center></h2>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted, provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific written permission.
* 4. This software, including modifications and/or derivative works of this
* software, must execute solely and exclusively on microcontroller or
* microprocessor devices manufactured by or for STMicroelectronics.
* 5. Redistribution and use of this software other than as permitted under
* this license is void and will automatically terminate your rights under
* this license.
*
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/** @addtogroup EEPROM_Emulation
* @{
*/
#ifdef STM32F4
/* Includes ------------------------------------------------------------------*/
#include "eeprom_emul.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Global variable used to store variable value in read sequence */
uint16_t DataVar = 0;
/* Virtual address defined by the user: 0xFFFF value is prohibited */
uint16_t VirtAddVarTab[NB_OF_VAR];
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static HAL_StatusTypeDef EE_Format(void);
static uint16_t EE_FindValidPage(uint8_t Operation);
static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
static uint16_t EE_VerifyPageFullyErased(uint32_t Address);
/**
* @brief Restore the pages to a known good state in case of page's status
* corruption after a power loss.
* @param None.
* @retval - Flash error code: on write Flash error
* - FLASH_COMPLETE: on success
*/
uint16_t EE_Initialise(void) {
uint16_t PageStatus0 = 6, PageStatus1 = 6;
uint16_t VarIdx = 0;
uint16_t EepromStatus = 0, ReadStatus = 0;
int16_t x = -1;
HAL_StatusTypeDef FlashStatus;
uint32_t SectorError = 0;
FLASH_EraseInitTypeDef pEraseInit;
/* Get Page0 status */
PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
/* Get Page1 status */
PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
pEraseInit.TypeErase = TYPEERASE_SECTORS;
pEraseInit.Sector = PAGE0_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Check for invalid header states and repair if necessary */
switch (PageStatus0) {
case ERASED:
if (PageStatus1 == VALID_PAGE) { /* Page0 erased, Page1 valid */
/* Erase Page0 */
if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) {
return FlashStatus;
}
}
}
else if (PageStatus1 == RECEIVE_DATA) { /* Page0 erased, Page1 receive */
/* Erase Page0 */
if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
/* Mark Page1 as valid */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
else { /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
/* Erase both Page0 and Page1 and set Page0 as valid page */
FlashStatus = EE_Format();
/* If erase/program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
break;
case RECEIVE_DATA:
if (PageStatus1 == VALID_PAGE) { /* Page0 receive, Page1 valid */
/* Transfer data from Page1 to Page0 */
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
x = VarIdx;
if (VarIdx != x) {
/* Read the last variables' updates */
ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
/* In case variable corresponding to the virtual address was found */
if (ReadStatus != 0x1) {
/* Transfer the variable to the Page0 */
EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
/* If program operation was failed, a Flash error code is returned */
if (EepromStatus != HAL_OK) return EepromStatus;
}
}
}
/* Mark Page0 as valid */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
pEraseInit.Sector = PAGE1_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Erase Page1 */
if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
else if (PageStatus1 == ERASED) { /* Page0 receive, Page1 erased */
pEraseInit.Sector = PAGE1_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Erase Page1 */
if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
/* Mark Page0 as valid */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
else { /* Invalid state -> format eeprom */
/* Erase both Page0 and Page1 and set Page0 as valid page */
FlashStatus = EE_Format();
/* If erase/program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
break;
case VALID_PAGE:
if (PageStatus1 == VALID_PAGE) { /* Invalid state -> format eeprom */
/* Erase both Page0 and Page1 and set Page0 as valid page */
FlashStatus = EE_Format();
/* If erase/program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
else if (PageStatus1 == ERASED) { /* Page0 valid, Page1 erased */
pEraseInit.Sector = PAGE1_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Erase Page1 */
if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
else { /* Page0 valid, Page1 receive */
/* Transfer data from Page0 to Page1 */
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
x = VarIdx;
if (VarIdx != x) {
/* Read the last variables' updates */
ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
/* In case variable corresponding to the virtual address was found */
if (ReadStatus != 0x1) {
/* Transfer the variable to the Page1 */
EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
/* If program operation was failed, a Flash error code is returned */
if (EepromStatus != HAL_OK) return EepromStatus;
}
}
}
/* Mark Page1 as valid */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
pEraseInit.Sector = PAGE0_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Erase Page0 */
if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
break;
default: /* Any other state -> format eeprom */
/* Erase both Page0 and Page1 and set Page0 as valid page */
FlashStatus = EE_Format();
/* If erase/program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
break;
}
return HAL_OK;
}
/**
* @brief Verify if specified page is fully erased.
* @param Address: page address
* This parameter can be one of the following values:
* @arg PAGE0_BASE_ADDRESS: Page0 base address
* @arg PAGE1_BASE_ADDRESS: Page1 base address
* @retval page fully erased status:
* - 0: if Page not erased
* - 1: if Page erased
*/
uint16_t EE_VerifyPageFullyErased(uint32_t Address) {
uint32_t ReadStatus = 1;
uint16_t AddressValue = 0x5555;
/* Check each active page address starting from end */
while (Address <= PAGE0_END_ADDRESS) {
/* Get the current location content to be compared with virtual address */
AddressValue = (*(__IO uint16_t*)Address);
/* Compare the read address with the virtual address */
if (AddressValue != ERASED) {
/* In case variable value is read, reset ReadStatus flag */
ReadStatus = 0;
break;
}
/* Next address location */
Address += 4;
}
/* Return ReadStatus value: (0: Page not erased, 1: Sector erased) */
return ReadStatus;
}
/**
* @brief Returns the last stored variable data, if found, which correspond to
* the passed virtual address
* @param VirtAddress: Variable virtual address
* @param Data: Global variable contains the read variable value
* @retval Success or error status:
* - 0: if variable was found
* - 1: if the variable was not found
* - NO_VALID_PAGE: if no valid page was found.
*/
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) {
uint16_t ValidPage = PAGE0;
uint16_t AddressValue = 0x5555, ReadStatus = 1;
uint32_t Address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS;
/* Get active Page for read operation */
ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
/* Check if there is no valid page */
if (ValidPage == NO_VALID_PAGE) return NO_VALID_PAGE;
/* Get the valid Page start Address */
PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
/* Get the valid Page end Address */
Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
/* Check each active page address starting from end */
while (Address > (PageStartAddress + 2)) {
/* Get the current location content to be compared with virtual address */
AddressValue = (*(__IO uint16_t*)Address);
/* Compare the read address with the virtual address */
if (AddressValue == VirtAddress) {
/* Get content of Address-2 which is variable value */
*Data = (*(__IO uint16_t*)(Address - 2));
/* In case variable value is read, reset ReadStatus flag */
ReadStatus = 0;
break;
}
else /* Next address location */
Address -= 4;
}
/* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
return ReadStatus;
}
/**
* @brief Writes/upadtes variable data in EEPROM.
* @param VirtAddress: Variable virtual address
* @param Data: 16 bit data to be written
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - PAGE_FULL: if valid page is full
* - NO_VALID_PAGE: if no valid page was found
* - Flash error code: on write Flash error
*/
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) {
/* Write the variable virtual address and value in the EEPROM */
uint16_t Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
/* In case the EEPROM active page is full */
if (Status == PAGE_FULL) /* Perform Page transfer */
Status = EE_PageTransfer(VirtAddress, Data);
/* Return last operation status */
return Status;
}
/**
* @brief Erases PAGE and PAGE1 and writes VALID_PAGE header to PAGE
* @param None
* @retval Status of the last operation (Flash write or erase) done during
* EEPROM formating
*/
static HAL_StatusTypeDef EE_Format(void) {
HAL_StatusTypeDef FlashStatus = HAL_OK;
uint32_t SectorError = 0;
FLASH_EraseInitTypeDef pEraseInit;
pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
pEraseInit.Sector = PAGE0_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Erase Page0 */
if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
/* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
pEraseInit.Sector = PAGE1_ID;
/* Erase Page1 */
if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
}
return HAL_OK;
}
/**
* @brief Find valid Page for write or read operation
* @param Operation: operation to achieve on the valid page.
* This parameter can be one of the following values:
* @arg READ_FROM_VALID_PAGE: read operation from valid page
* @arg WRITE_IN_VALID_PAGE: write operation from valid page
* @retval Valid page number (PAGE or PAGE1) or NO_VALID_PAGE in case
* of no valid page was found
*/
static uint16_t EE_FindValidPage(uint8_t Operation) {
uint16_t PageStatus0 = 6, PageStatus1 = 6;
/* Get Page0 actual status */
PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
/* Get Page1 actual status */
PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
/* Write or read operation */
switch (Operation) {
case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */
if (PageStatus1 == VALID_PAGE) {
/* Page0 receiving data */
if (PageStatus0 == RECEIVE_DATA) return PAGE0; /* Page0 valid */
else return PAGE1; /* Page1 valid */
}
else if (PageStatus0 == VALID_PAGE) {
/* Page1 receiving data */
if (PageStatus1 == RECEIVE_DATA) return PAGE1; /* Page1 valid */
else return PAGE0; /* Page0 valid */
}
else
return NO_VALID_PAGE; /* No valid Page */
case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */
if (PageStatus0 == VALID_PAGE)
return PAGE0; /* Page0 valid */
else if (PageStatus1 == VALID_PAGE)
return PAGE1; /* Page1 valid */
else
return NO_VALID_PAGE; /* No valid Page */
default:
return PAGE0; /* Page0 valid */
}
}
/**
* @brief Verify if active page is full and Writes variable in EEPROM.
* @param VirtAddress: 16 bit virtual address of the variable
* @param Data: 16 bit data to be written as variable value
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - PAGE_FULL: if valid page is full
* - NO_VALID_PAGE: if no valid page was found
* - Flash error code: on write Flash error
*/
static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) {
HAL_StatusTypeDef FlashStatus = HAL_OK;
uint16_t ValidPage = PAGE0;
uint32_t Address = EEPROM_START_ADDRESS, PageEndAddress = EEPROM_START_ADDRESS+PAGE_SIZE;
/* Get valid Page for write operation */
ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
/* Check if there is no valid page */
if (ValidPage == NO_VALID_PAGE) return NO_VALID_PAGE;
/* Get the valid Page start Address */
Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
/* Get the valid Page end Address */
PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((ValidPage + 1) * PAGE_SIZE));
/* Check each active page address starting from begining */
while (Address < PageEndAddress) {
/* Verify if Address and Address+2 contents are 0xFFFFFFFF */
if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF) {
/* Set variable data */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address, Data);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
/* Set variable virtual address */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address + 2, VirtAddress);
/* Return program operation status */
return FlashStatus;
}
else /* Next address location */
Address += 4;
}
/* Return PAGE_FULL in case the valid page is full */
return PAGE_FULL;
}
/**
* @brief Transfers last updated variables data from the full Page to
* an empty one.
* @param VirtAddress: 16 bit virtual address of the variable
* @param Data: 16 bit data to be written as variable value
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - PAGE_FULL: if valid page is full
* - NO_VALID_PAGE: if no valid page was found
* - Flash error code: on write Flash error
*/
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) {
HAL_StatusTypeDef FlashStatus = HAL_OK;
uint32_t NewPageAddress = EEPROM_START_ADDRESS;
uint16_t OldPageId=0;
uint16_t ValidPage = PAGE0, VarIdx = 0;
uint16_t EepromStatus = 0, ReadStatus = 0;
uint32_t SectorError = 0;
FLASH_EraseInitTypeDef pEraseInit;
/* Get active Page for read operation */
ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
if (ValidPage == PAGE1) { /* Page1 valid */
/* New page address where variable will be moved to */
NewPageAddress = PAGE0_BASE_ADDRESS;
/* Old page ID where variable will be taken from */
OldPageId = PAGE1_ID;
}
else if (ValidPage == PAGE0) { /* Page0 valid */
/* New page address where variable will be moved to */
NewPageAddress = PAGE1_BASE_ADDRESS;
/* Old page ID where variable will be taken from */
OldPageId = PAGE0_ID;
}
else
return NO_VALID_PAGE; /* No valid Page */
/* Set the new Page status to RECEIVE_DATA status */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
/* Write the variable passed as parameter in the new active page */
EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
/* If program operation was failed, a Flash error code is returned */
if (EepromStatus != HAL_OK) return EepromStatus;
/* Transfer process: transfer variables from old to the new active page */
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
if (VirtAddVarTab[VarIdx] != VirtAddress) { /* Check each variable except the one passed as parameter */
/* Read the other last variable updates */
ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
/* In case variable corresponding to the virtual address was found */
if (ReadStatus != 0x1) {
/* Transfer the variable to the new active page */
EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
/* If program operation was failed, a Flash error code is returned */
if (EepromStatus != HAL_OK) return EepromStatus;
}
}
}
pEraseInit.TypeErase = TYPEERASE_SECTORS;
pEraseInit.Sector = OldPageId;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Erase the old Page: Set old Page status to ERASED status */
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
/* If erase operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
/* Set new Page status to VALID_PAGE status */
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != HAL_OK) return FlashStatus;
/* Return last operation flash status */
return FlashStatus;
}
#endif // STM32F4
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

117
Marlin/src/HAL/HAL_STM32F4/EEPROM_Emul/eeprom_emul.h

@ -0,0 +1,117 @@
/**
******************************************************************************
* @file EEPROM/EEPROM_Emulation/inc/eeprom.h
* @author MCD Application Team
* @version V1.2.6
* @date 04-November-2016
* @brief This file contains all the functions prototypes for the EEPROM
* emulation firmware library.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright 2016 STMicroelectronics International N.V.
* All rights reserved.</center></h2>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted, provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific written permission.
* 4. This software, including modifications and/or derivative works of this
* software, must execute solely and exclusively on microcontroller or
* microprocessor devices manufactured by or for STMicroelectronics.
* 5. Redistribution and use of this software other than as permitted under
* this license is void and will automatically terminate your rights under
* this license.
*
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __EEEPROM_EMUL_H
#define __EEEPROM_EMUL_H
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "../../../inc/MarlinConfig.h"
#include "../HAL.h"
/* Exported constants --------------------------------------------------------*/
/* EEPROM emulation firmware error codes */
#define EE_OK (uint32_t)HAL_OK
#define EE_ERROR (uint32_t)HAL_ERROR
#define EE_BUSY (uint32_t)HAL_BUSY
#define EE_TIMEOUT (uint32_t)HAL_TIMEOUT
/* Define the size of the sectors to be used */
#define PAGE_SIZE (uint32_t)0x4000 /* Page size = 16KByte */
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
#define VOLTAGE_RANGE (uint8_t)VOLTAGE_RANGE_3
/* EEPROM start address in Flash */
#define EEPROM_START_ADDRESS ((uint32_t)0x08078000) /* EEPROM emulation start address:
after 480KByte of used Flash memory */
/* Pages 0 and 1 base and end addresses */
#define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
#define PAGE0_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))
#define PAGE0_ID FLASH_SECTOR_1
#define PAGE1_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x4000))
#define PAGE1_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (2 * PAGE_SIZE - 1)))
#define PAGE1_ID FLASH_SECTOR_2
/* Used Flash pages for EEPROM emulation */
#define PAGE0 ((uint16_t)0x0000)
#define PAGE1 ((uint16_t)0x0001) /* Page nb between PAGE0_BASE_ADDRESS & PAGE1_BASE_ADDRESS*/
/* No valid page define */
#define NO_VALID_PAGE ((uint16_t)0x00AB)
/* Page status definitions */
#define ERASED ((uint16_t)0xFFFF) /* Page is empty */
#define RECEIVE_DATA ((uint16_t)0xEEEE) /* Page is marked to receive data */
#define VALID_PAGE ((uint16_t)0x0000) /* Page containing valid data */
/* Valid pages in read and write defines */
#define READ_FROM_VALID_PAGE ((uint8_t)0x00)
#define WRITE_IN_VALID_PAGE ((uint8_t)0x01)
/* Page full define */
#define PAGE_FULL ((uint8_t)0x80)
/* Variables' number */
#define NB_OF_VAR ((uint16_t)4096)
/* Exported types ------------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint16_t EE_Initialise(void);
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);
#endif /* __EEEPROM_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

143
Marlin/src/HAL/HAL_STM32F4/EmulatedEeprom.cpp

@ -0,0 +1,143 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef STM32F4
/**
* Description: functions for I2C connected external EEPROM.
* Not platform dependent.
*/
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS) && DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "HAL.h"
#include "EEPROM_Emul/eeprom_emul.h"
// --------------------------------------------------------------------------
// Externals
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Local defines
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Private Variables
// --------------------------------------------------------------------------
static bool eeprom_initialised = false;
// --------------------------------------------------------------------------
// Function prototypes
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Private functions
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
// FLASH_FLAG_PGSERR (Programming Sequence Error) was renamed to
// FLASH_FLAG_ERSERR (Erasing Sequence Error) in STM32F4
// #define FLASH_FLAG_PGSERR FLASH_FLAG_ERSERR
// --------------------------------------------------------------------------
// EEPROM
// --------------------------------------------------------------------------
void eeprom_init() {
if (!eeprom_initialised) {
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
/* EEPROM Init */
if (EE_Initialise() != EE_OK)
for (;;) HAL_Delay(1); // Spin forever until watchdog reset
HAL_FLASH_Lock();
eeprom_initialised = true;
}
}
void eeprom_write_byte(unsigned char *pos, unsigned char value) {
uint16_t eeprom_address = (unsigned) pos;
eeprom_init();
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
if (EE_WriteVariable(eeprom_address, (uint16_t) value) != EE_OK)
for (;;) HAL_Delay(1); // Spin forever until watchdog reset
HAL_FLASH_Lock();
}
unsigned char eeprom_read_byte(unsigned char *pos) {
uint16_t data = 0xFF;
uint16_t eeprom_address = (unsigned)pos;
eeprom_init();
if (EE_ReadVariable(eeprom_address, &data) != EE_OK) {
return (unsigned char)data;
}
return (unsigned char)data;
}
void eeprom_read_block(void *__dst, const void *__src, size_t __n) {
uint16_t data = 0xFF;
uint16_t eeprom_address = (unsigned) __src;
eeprom_init();
for (uint8_t c = 0; c < __n; c++) {
EE_ReadVariable(eeprom_address+c, &data);
*((uint8_t*)__dst + c) = data;
}
}
void eeprom_update_block(const void *__src, void *__dst, size_t __n) {
}
#endif // ENABLED(EEPROM_SETTINGS) && DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
#endif // STM32F4

140
Marlin/src/HAL/HAL_STM32F4/HAL.cpp

@ -0,0 +1,140 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
* Copyright (c) 2017 Victor Perez
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef STM32F4
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "HAL.h"
//#include <Wire.h>
// --------------------------------------------------------------------------
// Externals
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Local defines
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
uint16_t HAL_adc_result;
// --------------------------------------------------------------------------
// Private Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Function prototypes
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Private functions
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
/* VGPV Done with defines
// disable interrupts
void cli(void) { noInterrupts(); }
// enable interrupts
void sei(void) { interrupts(); }
*/
void HAL_clear_reset_source(void) { __HAL_RCC_CLEAR_RESET_FLAGS(); }
uint8_t HAL_get_reset_source (void) {
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET)
return RST_WATCHDOG;
if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) != RESET)
return RST_SOFTWARE;
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET)
return RST_EXTERNAL;
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET)
return RST_POWER_ON;
return 0;
}
void _delay_ms(const int delay_ms) { delay(delay_ms); }
extern "C" {
extern unsigned int _ebss; // end of bss section
}
// return free memory between end of heap (or end bss) and whatever is current
/*
#include "wirish/syscalls.c"
//extern caddr_t _sbrk(int incr);
#ifndef CONFIG_HEAP_END
extern char _lm_heap_end;
#define CONFIG_HEAP_END ((caddr_t)&_lm_heap_end)
#endif
extern "C" {
static int freeMemory() {
char top = 't';
return &top - reinterpret_cast<char*>(sbrk(0));
}
int freeMemory() {
int free_memory;
int heap_end = (int)_sbrk(0);
free_memory = ((int)&free_memory) - ((int)heap_end);
return free_memory;
}
}
*/
// --------------------------------------------------------------------------
// ADC
// --------------------------------------------------------------------------
void HAL_adc_start_conversion(const uint8_t adc_pin) {
HAL_adc_result = analogRead(adc_pin);
}
uint16_t HAL_adc_get_result(void) {
return HAL_adc_result;
}
#endif // STM32F4

249
Marlin/src/HAL/HAL_STM32F4/HAL.h

@ -0,0 +1,249 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
* Copyright (c) 2017 Victor Perez
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef _HAL_STM32F4_H
#define _HAL_STM32F4_H
#define CPU_32_BIT
#undef DEBUG_NONE
#ifndef vsnprintf_P
#define vsnprintf_P vsnprintf
#endif
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include <stdint.h>
#include "Arduino.h"
#include "../math_32bit.h"
#include "../HAL_SPI.h"
#include "fastio_STM32F4.h"
#include "watchdog_STM32F4.h"
#include "HAL_timers_STM32F4.h"
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
//Serial override
//extern HalSerial usb_serial;
#if SERIAL_PORT == 0
#error "Serial port 0 does not exist"
#endif
#if !WITHIN(SERIAL_PORT, -1, 6)
#error "SERIAL_PORT must be from -1 to 6"
#endif
#if SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
#elif SERIAL_PORT == 1
#define MYSERIAL0 SerialUART1
#elif SERIAL_PORT == 2
#define MYSERIAL0 SerialUART2
#elif SERIAL_PORT == 3
#define MYSERIAL0 SerialUART3
#elif SERIAL_PORT == 4
#define MYSERIAL0 SerialUART4
#elif SERIAL_PORT == 5
#define MYSERIAL0 SerialUART5
#elif SERIAL_PORT == 6
#define MYSERIAL0 SerialUART6
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == 0
#error "Serial port 0 does not exist"
#endif
#if !WITHIN(SERIAL_PORT_2, -1, 6)
#error "SERIAL_PORT_2 must be from -1 to 6"
#elif SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT"
#endif
#define NUM_SERIAL 2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 SerialUSB
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 SerialUART1
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 SerialUART2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 SerialUART3
#elif SERIAL_PORT_2 == 4
#define MYSERIAL1 SerialUART4
#elif SERIAL_PORT_2 == 5
#define MYSERIAL1 SerialUART5
#elif SERIAL_PORT_2 == 6
#define MYSERIAL1 SerialUART6
#endif
#else
#define NUM_SERIAL 1
#endif
#define _BV(b) (1 << (b))
/**
* TODO: review this to return 1 for pins that are not analog input
*/
#ifndef analogInputToDigitalPin
#define analogInputToDigitalPin(p) (p)
#endif
#define CRITICAL_SECTION_START noInterrupts();
#define CRITICAL_SECTION_END interrupts();
// On AVR this is in math.h?
#define square(x) ((x)*(x))
#ifndef strncpy_P
#define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
#endif
// Fix bug in pgm_read_ptr
#undef pgm_read_ptr
#define pgm_read_ptr(addr) (*(addr))
#define RST_POWER_ON 1
#define RST_EXTERNAL 2
#define RST_BROWN_OUT 4
#define RST_WATCHDOG 8
#define RST_JTAG 16
#define RST_SOFTWARE 32
#define RST_BACKUP 64
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
typedef int8_t pin_t;
#define HAL_SERVO_LIB libServo
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
/** result of last ADC conversion */
extern uint16_t HAL_adc_result;
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
// Disable interrupts
#define cli() do { DISABLE_TEMPERATURE_INTERRUPT(); DISABLE_STEPPER_DRIVER_INTERRUPT(); } while(0)
// Enable interrupts
#define sei() do { ENABLE_TEMPERATURE_INTERRUPT(); ENABLE_STEPPER_DRIVER_INTERRUPT(); } while(0)
// Memory related
#define __bss_end __bss_end__
/** clear reset reason */
void HAL_clear_reset_source (void);
/** reset reason */
uint8_t HAL_get_reset_source (void);
void _delay_ms(const int delay);
/*
extern "C" {
int freeMemory(void);
}
*/
extern "C" char* _sbrk(int incr);
/*
static int freeMemory() {
volatile int top;
top = (int)((char*)&top - reinterpret_cast<char*>(_sbrk(0)));
return top;
}
*/
static int freeMemory() {
volatile char top;
return &top - reinterpret_cast<char*>(_sbrk(0));
}
// SPI: Extended functions which take a channel number (hardware SPI only)
/** Write single byte to specified SPI channel */
void spiSend(uint32_t chan, byte b);
/** Write buffer to specified SPI channel */
void spiSend(uint32_t chan, const uint8_t* buf, size_t n);
/** Read single byte from specified SPI channel */
uint8_t spiRec(uint32_t chan);
// EEPROM
/**
* TODO: Write all this eeprom stuff. Can emulate eeprom in flash as last resort.
* Wire library should work for i2c eeproms.
*/
void eeprom_write_byte(unsigned char *pos, unsigned char value);
unsigned char eeprom_read_byte(unsigned char *pos);
void eeprom_read_block (void *__dst, const void *__src, size_t __n);
void eeprom_update_block (const void *__src, void *__dst, size_t __n);
// ADC
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
inline void HAL_adc_init(void) {}
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC HAL_adc_result
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result(void);
/* Todo: Confirm none of this is needed.
uint16_t HAL_getAdcReading(uint8_t chan);
void HAL_startAdcConversion(uint8_t chan);
uint8_t HAL_pinToAdcChannel(int pin);
uint16_t HAL_getAdcFreerun(uint8_t chan, bool wait_for_conversion = false);
//uint16_t HAL_getAdcSuperSample(uint8_t chan);
void HAL_enable_AdcFreerun(void);
//void HAL_disable_AdcFreerun(uint8_t chan);
*/
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
#endif // _HAL_STM32F4_H

53
Marlin/src/HAL/HAL_STM32F4/HAL_Servo_STM32F4.cpp

@ -0,0 +1,53 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2017 Victor Perez
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef STM32F4
#include "../../inc/MarlinConfig.h"
#if HAS_SERVOS
#include "HAL_Servo_STM32F4.h"
int8_t libServo::attach(const int pin) {
return Servo::attach(pin);
}
int8_t libServo::attach(const int pin, const int min, const int max) {
return Servo::attach(pin, min, max);
}
void libServo::move(const int value) {
constexpr uint16_t servo_delay[] = SERVO_DELAY;
static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
if (this->attach(0) >= 0) {
this->write(value);
safe_delay(servo_delay[this->servoIndex]);
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE)
this->detach();
#endif
}
}
#endif // HAS_SERVOS
#endif // STM32F4

41
Marlin/src/HAL/HAL_STM32F4/HAL_Servo_STM32F4.h

@ -0,0 +1,41 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2017 Victor Perez
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAL_SERVO_STM32F4_H
#define HAL_SERVO_STM32F4_H
#include <Servo.h>
// Inherit and expand on the official library
class libServo : public Servo {
public:
int8_t attach(const int pin);
int8_t attach(const int pin, const int min, const int max);
void move(const int value);
private:
uint16_t min_ticks;
uint16_t max_ticks;
uint8_t servoIndex; // index into the channel data for this servo
};
#endif // HAL_SERVO_STM32F4_H

165
Marlin/src/HAL/HAL_STM32F4/HAL_spi_STM32F4.cpp

@ -0,0 +1,165 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2017 Victor Perez
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Software SPI functions originally from Arduino Sd2Card Library
* Copyright (C) 2009 by William Greiman
*/
/**
* Adapted to the STM32F4 HAL
*/
#ifdef STM32F4
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "HAL.h"
#include "../HAL_SPI.h"
#include "pins_arduino.h"
#include "spi_pins.h"
#include "../../core/macros.h"
#include <SPI.h>
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
static SPISettings spiConfig;
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
#if ENABLED(SOFTWARE_SPI)
// --------------------------------------------------------------------------
// Software SPI
// --------------------------------------------------------------------------
#error "Software SPI not supported for STM32F4. Use hardware SPI."
#else
// --------------------------------------------------------------------------
// Hardware SPI
// --------------------------------------------------------------------------
/**
* VGPV SPI speed start and F_CPU/2, by default 72/2 = 36Mhz
*/
/**
* @brief Begin SPI port setup
*
* @return Nothing
*
* @details Only configures SS pin since libmaple creates and initialize the SPI object
*/
void spiBegin(void) {
#if !PIN_EXISTS(SS)
#error SS_PIN not defined!
#endif
SET_OUTPUT(SS_PIN);
WRITE(SS_PIN, HIGH);
}
/** Configure SPI for specified SPI speed */
void spiInit(uint8_t spiRate) {
// Use datarates Marlin uses
uint32_t clock;
switch (spiRate) {
case SPI_FULL_SPEED: clock = 20000000; break; // 13.9mhz=20000000 6.75mhz=10000000 3.38mhz=5000000 .833mhz=1000000
case SPI_HALF_SPEED: clock = 5000000; break;
case SPI_QUARTER_SPEED: clock = 2500000; break;
case SPI_EIGHTH_SPEED: clock = 1250000; break;
case SPI_SPEED_5: clock = 625000; break;
case SPI_SPEED_6: clock = 300000; break;
default:
clock = 4000000; // Default from the SPI libarary
}
spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
SPI.begin();
}
/**
* @brief Receives a single byte from the SPI port.
*
* @return Byte received
*
* @details
*/
uint8_t spiRec(void) {
SPI.beginTransaction(spiConfig);
uint8_t returnByte = SPI.transfer(0xFF);
SPI.endTransaction();
return returnByte;
}
/**
* @brief Receives a number of bytes from the SPI port to a buffer
*
* @param buf Pointer to starting address of buffer to write to.
* @param nbyte Number of bytes to receive.
* @return Nothing
*
* @details Uses DMA
*/
void spiRead(uint8_t* buf, uint16_t nbyte) {
SPI.beginTransaction(spiConfig);
SPI.dmaTransfer(0, const_cast<uint8_t*>(buf), nbyte);
SPI.endTransaction();
}
/**
* @brief Sends a single byte on SPI port
*
* @param b Byte to send
*
* @details
*/
void spiSend(uint8_t b) {
SPI.beginTransaction(spiConfig);
SPI.transfer(b);
SPI.endTransaction();
}
/**
* @brief Write token and then write from 512 byte buffer to SPI (for SD card)
*
* @param buf Pointer with buffer start address
* @return Nothing
*
* @details Use DMA
*/
void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPI.beginTransaction(spiConfig);
SPI.transfer(token);
SPI.dmaSend(const_cast<uint8_t*>(buf), 512);
SPI.endTransaction();
}
#endif // SOFTWARE_SPI
#endif // STM32F4

156
Marlin/src/HAL/HAL_STM32F4/HAL_timers_STM32F4.cpp

@ -0,0 +1,156 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef STM32F4
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "HAL.h"
#include "HAL_timers_STM32F4.h"
// --------------------------------------------------------------------------
// Externals
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Local defines
// --------------------------------------------------------------------------
#define NUM_HARDWARE_TIMERS 2
//#define PRESCALER 1
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Private Variables
// --------------------------------------------------------------------------
tTimerConfig timerConfig[NUM_HARDWARE_TIMERS];
// --------------------------------------------------------------------------
// Function prototypes
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Private functions
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
bool timers_initialised[NUM_HARDWARE_TIMERS] = {false};
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
if (!timers_initialised[timer_num]) {
switch (timer_num) {
case STEP_TIMER_NUM:
//STEPPER TIMER TIM5 //use a 32bit timer
__HAL_RCC_TIM5_CLK_ENABLE();
timerConfig[0].timerdef.Instance = TIM5;
timerConfig[0].timerdef.Init.Prescaler = (STEPPER_TIMER_PRESCALE);
timerConfig[0].timerdef.Init.CounterMode = TIM_COUNTERMODE_UP;
timerConfig[0].timerdef.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timerConfig[0].IRQ_Id = TIM5_IRQn;
timerConfig[0].callback = (uint32_t)TC5_Handler;
HAL_NVIC_SetPriority(timerConfig[0].IRQ_Id, 1, 0);
break;
case TEMP_TIMER_NUM:
//TEMP TIMER TIM7 // any available 16bit Timer (1 already used for PWM)
__HAL_RCC_TIM7_CLK_ENABLE();
timerConfig[1].timerdef.Instance = TIM7;
timerConfig[1].timerdef.Init.Prescaler = (TEMP_TIMER_PRESCALE);
timerConfig[1].timerdef.Init.CounterMode = TIM_COUNTERMODE_UP;
timerConfig[1].timerdef.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timerConfig[1].IRQ_Id = TIM7_IRQn;
timerConfig[1].callback = (uint32_t)TC7_Handler;
HAL_NVIC_SetPriority(timerConfig[1].IRQ_Id, 2, 0);
break;
}
timers_initialised[timer_num] = true;
}
timerConfig[timer_num].timerdef.Init.Period = (((HAL_TIMER_RATE) / timerConfig[timer_num].timerdef.Init.Prescaler) / frequency) - 1;
if (HAL_TIM_Base_Init(&timerConfig[timer_num].timerdef) == HAL_OK)
HAL_TIM_Base_Start_IT(&timerConfig[timer_num].timerdef);
}
//forward the interrupt
extern "C" void TIM5_IRQHandler() {
((void(*)(void))timerConfig[0].callback)();
}
extern "C" void TIM7_IRQHandler() {
((void(*)(void))timerConfig[1].callback)();
}
void HAL_timer_set_compare(const uint8_t timer_num, const uint32_t compare) {
__HAL_TIM_SetAutoreload(&timerConfig[timer_num].timerdef, compare);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
HAL_NVIC_EnableIRQ(timerConfig[timer_num].IRQ_Id);
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
HAL_NVIC_DisableIRQ(timerConfig[timer_num].IRQ_Id);
}
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
return __HAL_TIM_GetAutoreload(&timerConfig[timer_num].timerdef);
}
uint32_t HAL_timer_get_count(const uint8_t timer_num) {
return __HAL_TIM_GetCounter(&timerConfig[timer_num].timerdef);
}
void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_ticks) {
const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_ticks;
if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp);
}
void HAL_timer_isr_prologue(const uint8_t timer_num) {
if (__HAL_TIM_GET_FLAG(&timerConfig[timer_num].timerdef, TIM_FLAG_UPDATE) == SET) {
__HAL_TIM_CLEAR_FLAG(&timerConfig[timer_num].timerdef, TIM_FLAG_UPDATE);
}
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
if (NVIC->ISER[(uint32_t)((int32_t)timerConfig[timer_num].IRQ_Id) >> 5] & (uint32_t)(1 << ((uint32_t)((int32_t)timerConfig[timer_num].IRQ_Id) & (uint32_t)0x1F))) {
return true;
}
else {
return false;
}
}
#endif // STM32F4

105
Marlin/src/HAL/HAL_STM32F4/HAL_timers_STM32F4.h

@ -0,0 +1,105 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2017 Victor Perez
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef _HAL_TIMERS_STM32F4_H
#define _HAL_TIMERS_STM32F4_H
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include <stdint.h>
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
#define FORCE_INLINE __attribute__((always_inline)) inline
#define hal_timer_t uint32_t // TODO: One is 16-bit, one 32-bit - does this need to be checked?
#define HAL_TIMER_TYPE_MAX 0xFFFF
#define STEP_TIMER_NUM 0 // index of timer to use for stepper
#define TEMP_TIMER_NUM 1 // index of timer to use for temperature
#define HAL_TIMER_RATE (HAL_RCC_GetSysClockFreq() / 2) // frequency of timer peripherals
#define STEPPER_TIMER_PRESCALE 54 // was 40,prescaler for setting stepper timer, 2Mhz
#define HAL_STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define HAL_ENABLE_ISRs() do { if (thermalManager.in_temp_isr)DISABLE_TEMPERATURE_INTERRUPT(); else ENABLE_TEMPERATURE_INTERRUPT(); ENABLE_STEPPER_DRIVER_INTERRUPT(); } while(0)
// TODO change this
extern void TC5_Handler();
extern void TC7_Handler();
#define HAL_STEP_TIMER_ISR void TC5_Handler()
#define HAL_TEMP_TIMER_ISR void TC7_Handler()
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
typedef struct {
TIM_HandleTypeDef timerdef;
IRQn_Type IRQ_Id;
uint32_t callback;
} tTimerConfig;
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
//extern const tTimerConfig timerConfig[];
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_set_compare(const uint8_t timer_num, const uint32_t compare);
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
uint32_t HAL_timer_get_count(const uint8_t timer_num);
void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_ticks);
void HAL_timer_isr_prologue(const uint8_t timer_num);
#endif // _HAL_TIMERS_STM32F4_H

12
Marlin/src/HAL/HAL_STM32F4/README.md

@ -0,0 +1,12 @@
# This HAL is for the STM32F407 MCU used with STM32Generic Arduino core by danieleff.
# Arduino core is located at:
https://github.com/danieleff/STM32GENERIC
Unzip it into [Arduino]/hardware folder
# This HAL is in development.
This HAL is a modified version of Chris Barr's Picoprint STM32F4 HAL.

66
Marlin/src/HAL/HAL_STM32F4/SanityCheck.h

@ -0,0 +1,66 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016, 2017 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Test Re-ARM specific configuration values for errors at compile-time.
*/
#if ENABLED(SPINDLE_LASER_ENABLE)
#if !PIN_EXISTS(SPINDLE_LASER_ENABLE)
#error "SPINDLE_LASER_ENABLE requires SPINDLE_LASER_ENABLE_PIN."
#elif SPINDLE_DIR_CHANGE && !PIN_EXISTS(SPINDLE_DIR)
#error "SPINDLE_DIR_PIN not defined."
#elif ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM)
#if !PWM_PIN(SPINDLE_LASER_PWM_PIN)
#error "SPINDLE_LASER_PWM_PIN not assigned to a PWM pin."
#elif !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
#error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#elif SPINDLE_LASER_POWERUP_DELAY < 1
#error "SPINDLE_LASER_POWERUP_DELAY must be greater than 0."
#elif SPINDLE_LASER_POWERDOWN_DELAY < 1
#error "SPINDLE_LASER_POWERDOWN_DELAY must be greater than 0."
#elif !defined(SPINDLE_LASER_PWM_INVERT)
#error "SPINDLE_LASER_PWM_INVERT missing."
#elif !defined(SPEED_POWER_SLOPE) || !defined(SPEED_POWER_INTERCEPT) || !defined(SPEED_POWER_MIN) || !defined(SPEED_POWER_MAX)
#error "SPINDLE_LASER_PWM equation constant(s) missing."
#elif PIN_EXISTS(CASE_LIGHT) && SPINDLE_LASER_PWM_PIN == CASE_LIGHT_PIN
#error "SPINDLE_LASER_PWM_PIN is used by CASE_LIGHT_PIN."
#elif PIN_EXISTS(E0_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E0_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E0_AUTO_FAN_PIN."
#elif PIN_EXISTS(E1_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E1_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E1_AUTO_FAN_PIN."
#elif PIN_EXISTS(E2_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E2_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E2_AUTO_FAN_PIN."
#elif PIN_EXISTS(E3_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E3_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E3_AUTO_FAN_PIN."
#elif PIN_EXISTS(E4_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E4_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E4_AUTO_FAN_PIN."
#elif PIN_EXISTS(FAN) && SPINDLE_LASER_PWM_PIN == FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used FAN_PIN."
#elif PIN_EXISTS(FAN1) && SPINDLE_LASER_PWM_PIN == FAN1_PIN
#error "SPINDLE_LASER_PWM_PIN is used FAN1_PIN."
#elif PIN_EXISTS(FAN2) && SPINDLE_LASER_PWM_PIN == FAN2_PIN
#error "SPINDLE_LASER_PWM_PIN is used FAN2_PIN."
#elif PIN_EXISTS(CONTROLLERFAN) && SPINDLE_LASER_PWM_PIN == CONTROLLERFAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by CONTROLLERFAN_PIN."
#endif
#endif
#endif // SPINDLE_LASER_ENABLE

77
Marlin/src/HAL/HAL_STM32F4/endstop_interrupts.h

@ -0,0 +1,77 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2017 Victor Perez
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef _ENDSTOP_INTERRUPTS_H_
#define _ENDSTOP_INTERRUPTS_H_
volatile uint8_t e_hit = 0; // Different from 0 when the endstops should be tested in detail.
// Must be reset to 0 by the test function when finished.
// This is what is really done inside the interrupts.
FORCE_INLINE void endstop_ISR_worker( void ) {
e_hit = 2; // Because the detection of a e-stop hit has a 1 step debouncer it has to be called at least twice.
}
// One ISR for all EXT-Interrupts
void endstop_ISR(void) { endstop_ISR_worker(); }
void setup_endstop_interrupts(void) {
#if HAS_X_MAX
pinMode(X_MAX_PIN, INPUT);
attachInterrupt(X_MAX_PIN, endstop_ISR, CHANGE); // assign it
#endif
#if HAS_X_MIN
pinMode(X_MIN_PIN, INPUT);
attachInterrupt(X_MIN_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_Y_MAX
pinMode(Y_MAX_PIN, INPUT);
attachInterrupt(Y_MAX_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_Y_MIN
pinMode(Y_MIN_PIN, INPUT);
attachInterrupt(Y_MIN_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_Z_MAX
pinMode(Z_MAX_PIN, INPUT);
attachInterrupt(Z_MAX_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_Z_MIN
pinMode(Z_MIN_PIN, INPUT);
attachInterrupt(Z_MIN_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_Z2_MAX
pinMode(Z2_MAX_PIN, INPUT);
attachInterrupt(Z2_MAX_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_Z2_MIN
pinMode(Z2_MIN_PIN, INPUT);
attachInterrupt(Z2_MIN_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_Z_MIN_PROBE_PIN
pinMode(Z_MIN_PROBE_PIN, INPUT);
attachInterrupt(Z_MIN_PROBE_PIN, endstop_ISR, CHANGE);
#endif
}
#endif //_ENDSTOP_INTERRUPTS_H_

54
Marlin/src/HAL/HAL_STM32F4/fastio_STM32F4.h

@ -0,0 +1,54 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2017 Victor Perez
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Fast I/O interfaces for STM32F4
* These use GPIO functions instead of Direct Port Manipulation, as on AVR.
*/
#ifndef _FASTIO_STM32F4_H
#define _FASTIO_STM32F4_H
#define _BV(b) (1 << (b))
#define READ(IO) digitalRead(IO)
#define WRITE(IO, v) digitalWrite(IO,v)
#define TOGGLE(IO) do{ _SET_OUTPUT(IO); digitalWrite(IO,!digitalRead(IO)); }while(0)
#define WRITE_VAR(IO, v) digitalWrite(IO,v)
#define _GET_MODE(IO)
#define _SET_MODE(IO,M) pinMode(IO, M)
#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) /*!< Output Push Pull Mode & GPIO_NOPULL */
#define SET_INPUT(IO) _SET_MODE(IO, INPUT) /*!< Input Floating Mode */
#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) /*!< Input with Pull-up activation */
#define SET_INPUT_PULLDOW(IO) _SET_MODE(IO, INPUT_PULLDOWN) /*!< Input with Pull-down activation */
#define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); WRITE(IO, LOW); }while(0)
#define GET_INPUT(IO)
#define GET_OUTPUT(IO)
#define GET_TIMER(IO)
#define OUT_WRITE(IO, v) { _SET_OUTPUT(IO); WRITE(IO, v); }
#endif // _FASTIO_STM32F4_H

75
Marlin/src/HAL/HAL_STM32F4/persistent_store_impl.cpp

@ -0,0 +1,75 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
* Copyright (c) 2016 Victor Perez victor_pv@hotmail.com
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef STM32F4
#include "../persistent_store_api.h"
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS)
namespace HAL {
namespace PersistentStore {
bool access_start() { return true; }
bool access_finish() { return true; }
bool write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc) {
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t v = *value;
// EEPROM has only ~100,000 write cycles,
// so only write bytes that have changed!
if (v != eeprom_read_byte(p)) {
eeprom_write_byte(p, v);
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_START();
SERIAL_ECHOLNPGM(MSG_ERR_EEPROM_WRITE);
return true;
}
}
crc16(crc, &v, 1);
pos++;
value++;
};
return false;
}
bool read_data(int &pos, uint8_t* value, uint16_t size, uint16_t *crc, const bool writing) {
do {
uint8_t c = eeprom_read_byte((unsigned char*)pos);
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;
value++;
} while (--size);
return false;
}
} // PersistentStore
} // HAL
#endif // EEPROM_SETTINGS
#endif // STM32F4

1
Marlin/src/HAL/HAL_STM32F4/pinsDebug.h

@ -0,0 +1 @@
#error Debug pins is not supported on this Platform!

41
Marlin/src/HAL/HAL_STM32F4/spi_pins.h

@ -0,0 +1,41 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef SPI_PINS_H_
#define SPI_PINS_H_
/**
* Define SPI Pins: SCK, MISO, MOSI, SS
*
*/
#ifndef SCK_PIN
#define SCK_PIN PA5
#endif
#ifndef MISO_PIN
#define MISO_PIN PA6
#endif
#ifndef MOSI_PIN
#define MOSI_PIN PA7
#endif
#ifndef SS_PIN
#define SS_PIN PA8
#endif
#endif // SPI_PINS_H_

57
Marlin/src/HAL/HAL_STM32F4/watchdog_STM32F4.cpp

@ -0,0 +1,57 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef STM32F4
#include "../../inc/MarlinConfig.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog_STM32F4.h"
IWDG_HandleTypeDef hiwdg;
void watchdog_init() {
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_32; //32kHz LSI clock and 32x prescalar = 1024Hz IWDG clock
hiwdg.Init.Reload = 4095; //4095 counts = 4 seconds at 1024Hz
if (HAL_IWDG_Init(&hiwdg) != HAL_OK) {
//Error_Handler();
}
}
void watchdog_reset() {
/* Refresh IWDG: reload counter */
if (HAL_IWDG_Refresh(&hiwdg) != HAL_OK) {
/* Refresh Error */
//Error_Handler();
}
else {
#if PIN_EXISTS(LED)
TOGGLE(LED_PIN); // heart beat indicator
#endif
}
}
#endif // USE_WATCHDOG
#endif // STM32F4

33
Marlin/src/HAL/HAL_STM32F4/watchdog_STM32F4.h

@ -0,0 +1,33 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHDOG_STM32F4_H
#define WATCHDOG_STM32F4_H
#include "../../inc/MarlinConfig.h"
extern IWDG_HandleTypeDef hiwdg;
void watchdog_init();
void watchdog_reset();
#endif // WATCHDOG_STM32F1_H

2
Marlin/src/HAL/platforms.h

@ -13,6 +13,8 @@
#define HAL_PLATFORM HAL_LPC1768
#elif defined(__STM32F1__) || defined(TARGET_STM32F1)
#define HAL_PLATFORM HAL_STM32F1
#elif defined(STM32F4)
#define HAL_PLATFORM HAL_STM32F4
#elif defined(STM32F7)
#define HAL_PLATFORM HAL_STM32F7
#else

2
Marlin/src/HAL/servo.cpp

@ -54,7 +54,7 @@
#include "../inc/MarlinConfig.h"
#if HAS_SERVOS && !(IS_32BIT_TEENSY || defined(TARGET_LPC1768))
#if HAS_SERVOS && !(IS_32BIT_TEENSY || defined(TARGET_LPC1768) || defined(STM32F4))
//#include <Arduino.h>
#include "servo.h"

3
Marlin/src/HAL/servo.h

@ -74,7 +74,8 @@
#elif defined(TARGET_LPC1768)
#include "HAL_LPC1768/LPC1768_Servo.h"
#elif defined(STM32F4)
#include "HAL_STM32F4/HAL_Servo_STM32F4.h"
#else
#include <stdint.h>

11
Marlin/src/backtrace/unwmemaccess.cpp

@ -62,6 +62,17 @@
#define END_FLASH_ADDR 0x00080000
#endif
#ifdef STM32F4
// For STM32F407VET
// SRAM (0x20000000 - 0x20030000) (192kb)
// FLASH (0x08000000 - 0x08080000) (512kb)
//
#define START_SRAM_ADDR 0x20000000
#define END_SRAM_ADDR 0x20030000
#define START_FLASH_ADDR 0x08000000
#define END_FLASH_ADDR 0x08080000
#endif
#ifdef STM32F7
// For STM32F765 in BORG
// SRAM (0x20000000 - 0x20080000) (512kb)

1868
Marlin/src/config/examples/STM32F4/Configuration.h

File diff suppressed because it is too large

1
Marlin/src/core/boards.h

@ -207,6 +207,7 @@
#define BOARD_MALYAN_M200 1801 // STM32C8T6 Libmaple based stm32f1 controller
#define BOARD_BEAST 1802 // STM32FxxxVxT6 Libmaple based stm32f4 controller
#define BOARD_STM3R_MINI 1803 // STM32 Libmaple based stm32f1 controller
#define BOARD_STM32F4 1804 // STM32 STM32GENERIC based STM32F4 controller
//
// ARM Cortex M7

2
Marlin/src/pins/pins.h

@ -359,6 +359,8 @@
#include "pins_COHESION3D_REMIX.h"
#elif MB(COHESION3D_MINI)
#include "pins_COHESION3D_MINI.h"
#elif MB(STM32F4)
#include "pins_STM32F4.h"
#else
#error "Unknown MOTHERBOARD value set in Configuration.h"
#endif

204
Marlin/src/pins/pins_STM32F4.h

@ -0,0 +1,204 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
#if !defined(STM32F4)
#error "Oops! Make sure you have an STM32F4 board selected from the 'Tools -> Boards' menu."
#endif
#define DEFAULT_MACHINE_NAME "STM32F407VET6"
#define BOARD_NAME "Marlin for STM32"
// #define I2C_EEPROM
// #define LARGE_FLASH true
#define E2END 0xFFF // EEPROM end address (4kB)
// Ignore temp readings during develpment.
// #define BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
#if E_STEPPERS > 2 || HOTENDS > 2
#error "STM32F4 supports up to 2 hotends / E-steppers."
#endif
#define PORTA 0
#define PORTB 1
#define PORTC 2
#define PORTD 3
#define PORTE 4
#define _STM32_PIN(_PORT,_PIN) ((_PORT * 16) + _PIN)
//
// Limit Switches
//
#define X_MIN_PIN _STM32_PIN(PORTE, 0)
#define X_MAX_PIN -1
#define Y_MIN_PIN _STM32_PIN(PORTE, 1)
#define Y_MAX_PIN -1
#define Z_MIN_PIN _STM32_PIN(PORTE, 14)
#define Z_MAX_PIN -1
//
// Z Probe (when not Z_MIN_PIN)
//
// #ifndef Z_MIN_PROBE_PIN
// #define Z_MIN_PROBE_PIN _STM32_PIN(PORTA, 4)
// #endif
//
// Steppers
//
#define X_STEP_PIN _STM32_PIN(PORTD, 3)
#define X_DIR_PIN _STM32_PIN(PORTD, 2)
#define X_ENABLE_PIN _STM32_PIN(PORTD, 0)
// #ifndef X_CS_PIN
// #define X_CS_PIN _STM32_PIN(PORTD, 1)
// #endif
#define Y_STEP_PIN _STM32_PIN(PORTE, 11)
#define Y_DIR_PIN _STM32_PIN(PORTE, 10)
#define Y_ENABLE_PIN _STM32_PIN(PORTE, 13)
// #ifndef Y_CS_PIN
// #define Y_CS_PIN _STM32_PIN(PORTE, 12)
// #endif
#define Z_STEP_PIN _STM32_PIN(PORTD, 6)
#define Z_DIR_PIN _STM32_PIN(PORTD, 7)
#define Z_ENABLE_PIN _STM32_PIN(PORTD, 4)
// #ifndef Z_CS_PIN
// #define Z_CS_PIN _STM32_PIN(PORTD, 5)
// #endif
#define E0_STEP_PIN _STM32_PIN(PORTB, 5)
#define E0_DIR_PIN _STM32_PIN(PORTB, 6)
#define E0_ENABLE_PIN _STM32_PIN(PORTB, 3)
// #ifndef E0_CS_PIN
// #define E0_CS_PIN _STM32_PIN(PORTB, 4)
// #endif
#define E1_STEP_PIN _STM32_PIN(PORTE, 4)
#define E1_DIR_PIN _STM32_PIN(PORTE, 2)
#define E1_ENABLE_PIN _STM32_PIN(PORTE, 3)
// #ifndef E1_CS_PIN
// #define E1_CS_PIN _STM32_PIN(PORTE, 5)
// #endif
#define SCK_PIN _STM32_PIN(PORTA, 5)
#define MISO_PIN _STM32_PIN(PORTA, 6)
#define MOSI_PIN _STM32_PIN(PORTA, 7)
//
// Temperature Sensors
//
#define TEMP_0_PIN _STM32_PIN(PORTC, 0) // Analog Input
#define TEMP_1_PIN _STM32_PIN(PORTC, 1) // Analog Input
#define TEMP_BED_PIN _STM32_PIN(PORTC, 2) // Analog Input
//
// Heaters / Fans
//
#define HEATER_0_PIN _STM32_PIN(PORTA, 1)
#define HEATER_1_PIN _STM32_PIN(PORTA, 2)
#define HEATER_BED_PIN _STM32_PIN(PORTA, 0)
#define FAN_PIN _STM32_PIN(PORTC, 6)
#define FAN1_PIN _STM32_PIN(PORTC, 7)
#define FAN2_PIN _STM32_PIN(PORTC, 8)
#define ORIG_E0_AUTO_FAN_PIN FAN1_PIN // Use this by NOT overriding E0_AUTO_FAN_PIN
//
// Misc. Functions
//
//#define CASE_LIGHT_PIN_CI _STM32_PIN(PORTF, 13)
//#define CASE_LIGHT_PIN_DO _STM32_PIN(PORTF, 14)
//#define NEOPIXEL_PIN _STM32_PIN(PORTF, 13)
//
// Prusa i3 MK2 Multi Material Multiplexer Support
//
// #define E_MUX0_PIN _STM32_PIN(PORTG, 3)
// #define E_MUX1_PIN _STM32_PIN(PORTG, 4)
//
// Servos
//
// #define SERVO0_PIN _STM32_PIN(PORTE, 13)
// #define SERVO1_PIN _STM32_PIN(PORTE, 14)
#define SDSS _STM32_PIN(PORTE, 7)
#define SS_PIN _STM32_PIN(PORTE, 7)
#define LED_PIN _STM32_PIN(PORTB, 7) //Alive
#define PS_ON_PIN _STM32_PIN(PORTA, 10)
#define KILL_PIN _STM32_PIN(PORTA, 8)
#define PWR_LOSS _STM32_PIN(PORTA, 4) //Power loss / nAC_FAULT
//
// LCD / Controller
//
#define SD_DETECT_PIN _STM32_PIN(PORTA, 15)
#define BEEPER_PIN _STM32_PIN(PORTC, 9)
#define LCD_PINS_RS _STM32_PIN(PORTE, 9)
#define LCD_PINS_ENABLE _STM32_PIN(PORTE, 8)
#define LCD_PINS_D4 _STM32_PIN(PORTB, 12)
#define LCD_PINS_D5 _STM32_PIN(PORTB, 13)
#define LCD_PINS_D6 _STM32_PIN(PORTB, 14)
#define LCD_PINS_D7 _STM32_PIN(PORTB, 15)
#define BTN_EN1 _STM32_PIN(PORTC, 4)
#define BTN_EN2 _STM32_PIN(PORTC, 5)
#define BTN_ENC _STM32_PIN(PORTC, 3)
//
// Filament runout
//
#define FIL_RUNOUT_PIN _STM32_PIN(PORTA, 3)
//
// ST7920 Delays
//
#define STM_NOP __asm__("nop\n\t")
#define STM_DELAY_SHORT { STM_NOP; STM_NOP; STM_NOP; STM_NOP; }
#define STM_DELAY_LONG { STM_DELAY_SHORT; STM_DELAY_SHORT; STM_NOP; STM_NOP; }
#ifndef ST7920_DELAY_1
#define ST7920_DELAY_1 { STM_DELAY_SHORT; STM_DELAY_SHORT; }
#endif
#ifndef ST7920_DELAY_2
#define ST7920_DELAY_2 { STM_DELAY_SHORT; }
#endif
#ifndef ST7920_DELAY_3
#define ST7920_DELAY_3 { STM_DELAY_LONG; STM_DELAY_LONG; STM_DELAY_LONG; STM_DELAY_LONG; STM_DELAY_LONG; STM_DELAY_LONG; }
#endif

10
platformio.ini

@ -242,6 +242,16 @@ lib_ldf_mode = 1
src_filter = ${common.default_src_filter}
monitor_baud = 250000
[env:STM32F4]
platform = ststm32
framework = arduino
board = disco_f407vg
build_flags = ${common.build_flags} -DUSE_STM32GENERIC -DMENU_USB_SERIAL -DMENU_SERIAL=SerialUSB
lib_deps = ${common.lib_deps}
lib_ignore = Adafruit NeoPixel, c1921b4, TMC2130Stepper
src_filter = ${common.default_src_filter}
monitor_baud = 250000
#
# Teensy++ 2.0
#

Loading…
Cancel
Save