Cleanups for STM32F7

This commit is contained in:
Scott Lahteine 2018-01-15 02:28:39 -06:00
parent a0246c5c96
commit 42933c804a
18 changed files with 988 additions and 1293 deletions

View file

@ -49,9 +49,9 @@
#define GET_TIMER(IO) (PIN_MAP[IO].timer_device != NULL)
#define OUT_WRITE(IO, v) { _SET_OUTPUT(IO); WRITE(IO, v); }
/*
/**
* TODO: Write a macro to test if PIN is PWM or not.
*/
#define PWM_PIN(p) true
#endif /* _FASTIO_STM32F1_H */
#endif // _FASTIO_STM32F1_H

View file

@ -78,8 +78,7 @@ static uint16_t EE_VerifyPageFullyErased(uint32_t Address);
* @retval - Flash error code: on write Flash error
* - FLASH_COMPLETE: on success
*/
uint16_t EE_Initialise(void)
{
uint16_t EE_Initialise(void) {
uint16_t PageStatus0 = 6, PageStatus1 = 6;
uint16_t VarIdx = 0;
uint16_t EepromStatus = 0, ReadStatus = 0;
@ -100,209 +99,141 @@ uint16_t EE_Initialise(void)
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Check for invalid header states and repair if necessary */
switch (PageStatus0)
{
switch (PageStatus0) {
case ERASED:
if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
{
if (PageStatus1 == VALID_PAGE) { /* Page0 erased, Page1 valid */
/* Erase Page0 */
if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
{
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)
{
if (FlashStatus != HAL_OK) {
return FlashStatus;
}
}
}
else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
{
else if (PageStatus1 == RECEIVE_DATA) { /* Page0 erased, Page1 receive */
/* Erase Page0 */
if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
{
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;
}
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;
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
{
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;
}
if (FlashStatus != HAL_OK) return FlashStatus;
}
break;
case RECEIVE_DATA:
if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
{
if (PageStatus1 == VALID_PAGE) { /* Page0 receive, Page1 valid */
/* Transfer data from Page1 to Page0 */
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
{
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
{
x = VarIdx;
}
if (VarIdx != x)
{
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)
{
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;
}
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;
}
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))
{
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;
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
}
else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */
{
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))
{
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;
}
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;
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
else /* Invalid state -> format eeprom */
{
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;
}
if (FlashStatus != HAL_OK) return FlashStatus;
}
break;
case VALID_PAGE:
if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
{
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;
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */
{
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))
{
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;
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
}
else /* Page0 valid, Page1 receive */
{
else { /* Page0 valid, Page1 receive */
/* Transfer data from Page0 to Page1 */
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
{
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
{
x = VarIdx;
}
if (VarIdx != x)
{
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)
{
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;
}
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;
}
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))
{
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;
}
if (FlashStatus != HAL_OK) return FlashStatus;
}
}
break;
@ -311,10 +242,7 @@ uint16_t EE_Initialise(void)
/* 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;
}
if (FlashStatus != HAL_OK) return FlashStatus;
break;
}
@ -331,30 +259,22 @@ uint16_t EE_Initialise(void)
* - 0: if Page not erased
* - 1: if Page erased
*/
uint16_t EE_VerifyPageFullyErased(uint32_t Address)
{
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)
{
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)
{
if (AddressValue != ERASED) {
/* In case variable value is read, reset ReadStatus flag */
ReadStatus = 0;
break;
}
/* Next address location */
Address = Address + 4;
Address += 4;
}
/* Return ReadStatus value: (0: Page not erased, 1: Sector erased) */
return ReadStatus;
}
@ -369,8 +289,7 @@ uint16_t EE_VerifyPageFullyErased(uint32_t Address)
* - 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 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;
@ -379,10 +298,7 @@ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
/* Check if there is no valid page */
if (ValidPage == NO_VALID_PAGE)
{
return 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));
@ -391,29 +307,21 @@ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
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))
{
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)
{
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 = Address - 4;
else /* Next address location */
Address -= 4;
}
}
/* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
return ReadStatus;
}
@ -428,19 +336,13 @@ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
* - 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)
{
uint16_t Status = 0;
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) {
/* Write the variable virtual address and value in the EEPROM */
Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
uint16_t Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
/* In case the EEPROM active page is full */
if (Status == PAGE_FULL)
{
/* Perform Page transfer */
if (Status == PAGE_FULL) /* Perform Page transfer */
Status = EE_PageTransfer(VirtAddress, Data);
}
/* Return last operation status */
return Status;
@ -452,8 +354,7 @@ uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
* @retval Status of the last operation (Flash write or erase) done during
* EEPROM formating
*/
static HAL_StatusTypeDef EE_Format(void)
{
static HAL_StatusTypeDef EE_Format(void) {
HAL_StatusTypeDef FlashStatus = HAL_OK;
uint32_t SectorError = 0;
FLASH_EraseInitTypeDef pEraseInit;
@ -463,33 +364,22 @@ static HAL_StatusTypeDef EE_Format(void)
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
/* Erase Page0 */
if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
{
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;
}
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;
}
if (FlashStatus != HAL_OK) return FlashStatus;
pEraseInit.Sector = PAGE1_ID;
/* Erase Page1 */
if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
{
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;
}
if (FlashStatus != HAL_OK) return FlashStatus;
}
return HAL_OK;
@ -504,8 +394,7 @@ static HAL_StatusTypeDef EE_Format(void)
* @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)
{
static uint16_t EE_FindValidPage(uint8_t Operation) {
uint16_t PageStatus0 = 6, PageStatus1 = 6;
/* Get Page0 actual status */
@ -515,51 +404,28 @@ static uint16_t EE_FindValidPage(uint8_t Operation)
PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
/* Write or read operation */
switch (Operation)
{
switch (Operation) {
case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */
if (PageStatus1 == VALID_PAGE)
{
if (PageStatus1 == VALID_PAGE) {
/* Page0 receiving data */
if (PageStatus0 == RECEIVE_DATA)
{
return PAGE0; /* Page0 valid */
if (PageStatus0 == RECEIVE_DATA) return PAGE0; /* Page0 valid */
else return PAGE1; /* Page1 valid */
}
else
{
return PAGE1; /* Page1 valid */
}
}
else if (PageStatus0 == VALID_PAGE)
{
else if (PageStatus0 == VALID_PAGE) {
/* Page1 receiving data */
if (PageStatus1 == RECEIVE_DATA)
{
return PAGE1; /* Page1 valid */
if (PageStatus1 == RECEIVE_DATA) return PAGE1; /* Page1 valid */
else return PAGE0; /* Page0 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 */
@ -576,8 +442,7 @@ static uint16_t EE_FindValidPage(uint8_t Operation)
* - 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)
{
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;
@ -586,10 +451,7 @@ static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Da
ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
/* Check if there is no valid page */
if (ValidPage == NO_VALID_PAGE)
{
return 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));
@ -598,28 +460,20 @@ static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Da
PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((ValidPage + 1) * PAGE_SIZE));
/* Check each active page address starting from begining */
while (Address < PageEndAddress)
{
while (Address < PageEndAddress) {
/* Verify if Address and Address+2 contents are 0xFFFFFFFF */
if ((*(__IO uint32_t*)Address) == 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;
}
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 = Address + 4;
}
else /* Next address location */
Address += 4;
}
/* Return PAGE_FULL in case the valid page is full */
@ -637,8 +491,7 @@ static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Da
* - 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)
{
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;
@ -650,60 +503,42 @@ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
/* Get active Page for read operation */
ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
if (ValidPage == PAGE1) /* Page1 valid */
{
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 */
{
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;
}
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;
}
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 */
{
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)
{
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;
}
if (EepromStatus != HAL_OK) return EepromStatus;
}
}
}
@ -716,18 +551,12 @@ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
/* 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;
}
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;
}
if (FlashStatus != HAL_OK) return FlashStatus;
/* Return last operation flash status */
return FlashStatus;

View file

@ -92,7 +92,6 @@ uint8_t HAL_get_reset_source (void) {
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET)
return RST_POWER_ON;
return 0;
}
@ -102,8 +101,6 @@ extern "C" {
extern unsigned int _ebss; // end of bss section
}
// return free memory between end of heap (or end bss) and whatever is current
/*

View file

@ -85,11 +85,8 @@ void spiBegin(void) {
SET_OUTPUT(SS_PIN);
WRITE(SS_PIN, HIGH);
}
/** Configure SPI for specified SPI speed */
void spiInit(uint8_t spiRate) {
// Use datarates Marlin uses
@ -108,8 +105,6 @@ void spiInit(uint8_t spiRate) {
SPI.begin();
}
/**
* @brief Receives a single byte from the SPI port.
*
@ -133,8 +128,6 @@ uint8_t spiRec(void) {
*
* @details Uses DMA
*/
void spiRead(uint8_t* buf, uint16_t nbyte) {
SPI.beginTransaction(spiConfig);
SPI.dmaTransfer(0, const_cast<uint8_t*>(buf), nbyte);
@ -162,8 +155,6 @@ void spiSend(uint8_t b) {
*
* @details Use DMA
*/
void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPI.beginTransaction(spiConfig);
SPI.transfer(token);
@ -171,8 +162,6 @@ void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPI.endTransaction();
}
#endif // SOFTWARE_SPI
#endif // STM32F7

View file

@ -20,8 +20,8 @@
*
*/
#ifdef STM32F7
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
@ -71,7 +71,7 @@ tTimerConfig timerConfig[NUM_HARDWARE_TIMERS];
bool timers_initialised[NUM_HARDWARE_TIMERS] = {false};
void HAL_timer_start(uint8_t timer_num, uint32_t frequency) {
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
if (!timers_initialised[timer_num]) {
switch (timer_num) {
@ -103,52 +103,48 @@ void HAL_timer_start(uint8_t timer_num, uint32_t frequency) {
timers_initialised[timer_num] = true;
}
timerConfig[timer_num].timerdef.Init.Period = ((HAL_TIMER_RATE / timerConfig[timer_num].timerdef.Init.Prescaler) / (frequency)) - 1;
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 ){
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()
{
extern "C" void TIM5_IRQHandler() {
((void(*)(void))timerConfig[0].callback)();
}
extern "C" void TIM7_IRQHandler()
{
extern "C" void TIM7_IRQHandler() {
((void(*)(void))timerConfig[1].callback)();
}
void HAL_timer_set_count (uint8_t timer_num, uint32_t count) {
void HAL_timer_set_count(const uint8_t timer_num, const uint32_t count) {
__HAL_TIM_SetAutoreload(&timerConfig[timer_num].timerdef, count);
}
void HAL_timer_set_current_count (uint8_t timer_num, uint32_t count) {
void HAL_timer_set_current_count(const uint8_t timer_num, const uint32_t count) {
__HAL_TIM_SetAutoreload(&timerConfig[timer_num].timerdef, count);
}
void HAL_timer_enable_interrupt (uint8_t timer_num) {
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
HAL_NVIC_EnableIRQ(timerConfig[timer_num].IRQ_Id);
}
void HAL_timer_disable_interrupt (uint8_t timer_num) {
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
HAL_NVIC_DisableIRQ(timerConfig[timer_num].IRQ_Id);
}
hal_timer_t HAL_timer_get_count (uint8_t timer_num) {
hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
return __HAL_TIM_GetAutoreload(&timerConfig[timer_num].timerdef);
}
uint32_t HAL_timer_get_current_count(uint8_t timer_num) {
uint32_t HAL_timer_get_current_count(const uint8_t timer_num) {
return __HAL_TIM_GetCounter(&timerConfig[timer_num].timerdef);
}
void HAL_timer_isr_prologue (uint8_t timer_num) {
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);
}
}
#endif
#endif // STM32F7

View file

@ -20,8 +20,6 @@
*
*/
#ifndef _HAL_TIMERS_STM32F7_H
#define _HAL_TIMERS_STM32F7_H
@ -35,10 +33,9 @@
// Defines
// --------------------------------------------------------------------------
#define FORCE_INLINE __attribute__((always_inline)) inline
#define hal_timer_t uint32_t //hal_timer_t uint32_t //TODO: One is 16-bit, one 32-bit - does this need to be checked?
#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
@ -86,27 +83,23 @@ typedef struct {
//extern const tTimerConfig timerConfig[];
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
void HAL_timer_start (uint8_t timer_num, uint32_t frequency);
void HAL_timer_enable_interrupt(uint8_t timer_num);
void HAL_timer_disable_interrupt(uint8_t timer_num);
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);
void HAL_timer_set_count(const uint8_t timer_num, const uint32_t count);
hal_timer_t HAL_timer_get_count(const uint8_t timer_num);
uint32_t HAL_timer_get_current_count(const uint8_t timer_num);
void HAL_timer_set_count (uint8_t timer_num, uint32_t count);
hal_timer_t HAL_timer_get_count (uint8_t timer_num);
uint32_t HAL_timer_get_current_count(uint8_t timer_num);
void HAL_timer_set_current_count (uint8_t timer_num, uint32_t count); //New
void HAL_timer_set_current_count(const uint8_t timer_num, const uint32_t count); // New
/*FORCE_INLINE static void HAL_timer_set_current_count(const uint8_t timer_num, const hal_timer_t count) {
// To do ??
}*/
void HAL_timer_isr_prologue (uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num);
#endif // _HAL_TIMERS_STM32F7_H

View file

@ -1,28 +1,28 @@
/*
TMC26XStepper.cpp - - TMC26X Stepper library for Wiring/Arduino
based on the stepper library by Tom Igoe, et. al.
Copyright (c) 2011, Interactive Matter, Marcus Nowotny
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
/**
* TMC26XStepper.cpp - - TMC26X Stepper library for Wiring/Arduino
*
* based on the stepper library by Tom Igoe, et. al.
*
* Copyright (c) 2011, Interactive Matter, Marcus Nowotny
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
//#include "Arduino.h"
@ -120,56 +120,56 @@ SPIClass SPI_6(SPI6, SPI6_MOSI_PIN, SPI6_MISO_PIN, SPI6_SCK_PIN);
unsigned char current_scaling = 0;
/*
/**
* Constructor
* number_of_steps - the steps per rotation
* cs_pin - the SPI client select pin
* dir_pin - the pin where the direction pin is connected
* step_pin - the pin where the step pin is connected
*/
TMC26XStepper::TMC26XStepper(int number_of_steps, int cs_pin, int dir_pin, int step_pin, unsigned int current, unsigned int resistor)
{
//we are not started yet
TMC26XStepper::TMC26XStepper(int number_of_steps, int cs_pin, int dir_pin, int step_pin, unsigned int current, unsigned int resistor) {
// We are not started yet
started = false;
//by default cool step is not enabled
// By default cool step is not enabled
cool_step_enabled = false;
//save the pins for later use
// Save the pins for later use
this->cs_pin = cs_pin;
this->dir_pin = dir_pin;
this->step_pin = step_pin;
//store the current sense resistor value for later use
// Store the current sense resistor value for later use
this->resistor = resistor;
//initizalize our status values
// Initizalize our status values
this->steps_left = 0;
this->direction = 0;
//initialize register values
// Initialize register values
driver_control_register_value = DRIVER_CONTROL_REGISTER | INITIAL_MICROSTEPPING;
chopper_config_register = CHOPPER_CONFIG_REGISTER;
//setting the default register values
// Setting the default register values
driver_control_register_value = DRIVER_CONTROL_REGISTER|INITIAL_MICROSTEPPING;
microsteps = (1 << INITIAL_MICROSTEPPING);
microsteps = _BV(INITIAL_MICROSTEPPING);
chopper_config_register = CHOPPER_CONFIG_REGISTER;
cool_step_register_value = COOL_STEP_REGISTER;
stall_guard2_current_register_value = STALL_GUARD2_LOAD_MEASURE_REGISTER;
driver_configuration_register_value = DRIVER_CONFIG_REGISTER | READ_STALL_GUARD_READING;
//set the current
// Set the current
setCurrent(current);
//set to a conservative start value
// Set to a conservative start value
setConstantOffTimeChopper(7, 54, 13,12,1);
//set a nice microstepping value
// Set a nice microstepping value
setMicrosteps(DEFAULT_MICROSTEPPING_VALUE);
//save the number of steps
// Save the number of steps
this->number_of_steps = number_of_steps;
}
/*
/**
* start & configure the stepper driver
* just must be called.
*/
@ -184,7 +184,6 @@ void TMC26XStepper::start() {
SERIAL_PRINTF("\n Resistor: %d", resistor);
//SERIAL_PRINTF("\n current: %d", current);
SERIAL_ECHOPAIR("\n Microstepping: ", microsteps);
#endif
//set the pins as output & its initial value
@ -210,54 +209,44 @@ void TMC26XStepper::start() {
started = true;
}
/*
Mark the driver as unstarted to be able to start it again
/**
* Mark the driver as unstarted to be able to start it again
*/
void TMC26XStepper::un_start() {
started=false;
}
void TMC26XStepper::un_start() { started = false; }
/*
Sets the speed in revs per minute
/**
* Sets the speed in revs per minute
*/
void TMC26XStepper::setSpeed(unsigned int whatSpeed)
{
void TMC26XStepper::setSpeed(unsigned int whatSpeed) {
this->speed = whatSpeed;
this->step_delay = (60UL * 1000UL * 1000UL) / ((unsigned long)this->number_of_steps * (unsigned long)whatSpeed * (unsigned long)this->microsteps);
this->step_delay = 60UL * sq(1000UL) / ((unsigned long)this->number_of_steps * (unsigned long)whatSpeed * (unsigned long)this->microsteps);
#ifdef TMC_DEBUG0 // crashes
//SERIAL_PRINTF("Step delay in micros: ");
SERIAL_ECHOPAIR("\nStep delay in micros: ", this->step_delay);
#endif
//update the next step time
// Update the next step time
this->next_step_time = this->last_step_time + this->step_delay;
}
unsigned int TMC26XStepper::getSpeed(void) {
return this->speed;
}
unsigned int TMC26XStepper::getSpeed(void) { return this->speed; }
/*
Moves the motor steps_to_move steps. If the number is negative,
the motor moves in the reverse direction.
/**
* Moves the motor steps_to_move steps.
* Negative indicates the reverse direction.
*/
char TMC26XStepper::step(int steps_to_move)
{
char TMC26XStepper::step(int steps_to_move) {
if (this->steps_left == 0) {
this->steps_left = abs(steps_to_move); // how many steps to take
// determine direction based on whether steps_to_mode is + or -:
if (steps_to_move > 0) {
// determine direction based on whether steps_to_move is + or -:
if (steps_to_move > 0)
this->direction = 1;
} else if (steps_to_move < 0) {
else if (steps_to_move < 0)
this->direction = 0;
}
return 0;
} else {
return -1;
}
return -1;
}
char TMC26XStepper::move(void) {
@ -269,12 +258,11 @@ char TMC26XStepper::move(void) {
// rem if (time >= this->next_step_time) {
if (abs(time - this->last_step_time) > this->step_delay) {
// increment or decrement the step number,
// depending on direction:
if (this->direction == 1) {
if (this->direction == 1)
digitalWrite(step_pin, HIGH);
} else {
else {
digitalWrite(dir_pin, HIGH);
digitalWrite(step_pin, HIGH);
}
@ -292,13 +280,9 @@ char TMC26XStepper::move(void) {
return 0;
}
char TMC26XStepper::isMoving(void) {
return (this->steps_left>0);
}
char TMC26XStepper::isMoving(void) { return this->steps_left > 0; }
unsigned int TMC26XStepper::getStepsLeft(void) {
return this->steps_left;
}
unsigned int TMC26XStepper::getStepsLeft(void) { return this->steps_left; }
char TMC26XStepper::stop(void) {
//note to self if the motor is currently moving
@ -313,23 +297,23 @@ char TMC26XStepper::stop(void) {
void TMC26XStepper::setCurrent(unsigned int current) {
unsigned char current_scaling = 0;
//calculate the current scaling from the max current setting (in mA)
double mASetting = (double)current;
double resistor_value = (double) this->resistor;
// remove vesense flag
double mASetting = (double)current,
resistor_value = (double)this->resistor;
// remove vsense flag
this->driver_configuration_register_value &= ~(VSENSE);
//this is derrived from I=(cs+1)/32*(Vsense/Rsense)
//leading to cs = CS = 32*R*I/V (with V = 0,31V oder 0,165V and I = 1000*current)
// Derived from I = (cs + 1) / 32 * (Vsense / Rsense)
// leading to cs = 32 * R * I / V (with V = 0,31V oder 0,165V and I = 1000 * current)
// with Rsense = 0,15
// for vsense = 0,310V (VSENSE not set)
// or vsense = 0,165V (VSENSE set)
current_scaling = (byte)((resistor_value*mASetting*32.0/(0.31*1000.0*1000.0))-0.5); //theoretically - 1.0 for better rounding it is 0.5
current_scaling = (byte)((resistor_value * mASetting * 32.0 / (0.31 * sq(1000.0))) - 0.5); //theoretically - 1.0 for better rounding it is 0.5
//check if the current scalingis too low
// Check if the current scalingis too low
if (current_scaling < 16) {
//set the csense bit to get a use half the sense voltage (to support lower motor currents)
// Set the csense bit to get a use half the sense voltage (to support lower motor currents)
this->driver_configuration_register_value |= VSENSE;
// and recalculate the current setting
current_scaling = (byte)((resistor_value*mASetting*32.0/(0.165*1000.0*1000.0))-0.5); //theoretically - 1.0 for better rounding it is 0.5
current_scaling = (byte)((resistor_value * mASetting * 32.0 / (0.165 * sq(1000.0))) - 0.5); //theoretically - 1.0 for better rounding it is 0.5
#ifdef TMC_DEBUG0 // crashes
//SERIAL_PRINTF("CS (Vsense=1): ");
SERIAL_ECHOPAIR("\nCS (Vsense=1): ",current_scaling);
@ -340,9 +324,8 @@ void TMC26XStepper::setCurrent(unsigned int current) {
}
// do some sanity checks
if (current_scaling>31) {
current_scaling=31;
}
NOMORE(current_scaling, 31);
// delete the old value
stall_guard2_current_register_value &= ~(CURRENT_SCALING_PATTERN);
// set the new current scaling
@ -355,35 +338,30 @@ void TMC26XStepper::setCurrent(unsigned int current) {
}
unsigned int TMC26XStepper::getCurrent(void) {
//we calculate the current according to the datasheet to be on the safe side
//this is not the fastest but the most accurate and illustrative way
double result = (double)(stall_guard2_current_register_value & CURRENT_SCALING_PATTERN);
double resistor_value = (double)this->resistor;
double voltage = (driver_configuration_register_value & VSENSE)? 0.165:0.31;
result = (result+1.0)/32.0*voltage/resistor_value*1000.0*1000.0;
// Calculate the current according to the datasheet to be on the safe side.
// This is not the fastest but the most accurate and illustrative way.
double result = (double)(stall_guard2_current_register_value & CURRENT_SCALING_PATTERN),
resistor_value = (double)this->resistor,
voltage = (driver_configuration_register_value & VSENSE) ? 0.165 : 0.31;
result = (result + 1.0) / 32.0 * voltage / resistor_value * sq(1000.0);
return (unsigned int)result;
}
void TMC26XStepper::setStallGuardThreshold(char stall_guard_threshold, char stall_guard_filter_enabled) {
if (stall_guard_threshold<-64) {
stall_guard_threshold = -64;
// We just have 5 bits
} else if (stall_guard_threshold > 63) {
stall_guard_threshold = 63;
}
//add trim down to 7 bits
stall_guard_threshold &=0x7f;
//delete old stall guard settings
LIMIT(stall_guard_threshold, -64, 63);
// Add trim down to 7 bits
stall_guard_threshold &= 0x7F;
// Delete old stall guard settings
stall_guard2_current_register_value &= ~(STALL_GUARD_CONFIG_PATTERN);
if (stall_guard_filter_enabled) {
if (stall_guard_filter_enabled)
stall_guard2_current_register_value |= STALL_GUARD_FILTER_ENABLED;
}
// Set the new stall guard threshold
stall_guard2_current_register_value |= (((unsigned long)stall_guard_threshold << 8) & STALL_GUARD_CONFIG_PATTERN);
//if started we directly send it to the motor
if (started) {
send262(stall_guard2_current_register_value);
}
// If started we directly send it to the motor
if (started) send262(stall_guard2_current_register_value);
}
char TMC26XStepper::getStallGuardThreshold(void) {
@ -395,21 +373,17 @@ char TMC26XStepper::getStallGuardThreshold(void) {
//check if it is negative and fill it up with leading 1 for proper negative number representation
//rem if (result & _BV(6)) {
if (result & (1 << (6))) {
result |= 0xC0;
}
if (TEST(result, 6)) result |= 0xC0;
return result;
}
char TMC26XStepper::getStallGuardFilter(void) {
if (stall_guard2_current_register_value & STALL_GUARD_FILTER_ENABLED) {
if (stall_guard2_current_register_value & STALL_GUARD_FILTER_ENABLED)
return -1;
} else {
return 0;
}
}
/*
/**
* Set the number of microsteps per step.
* 0,2,4,8,16,32,64,128,256 is supported
* any value in between will be mapped to the next smaller value
@ -421,29 +395,37 @@ void TMC26XStepper::setMicrosteps(int number_of_steps) {
if (number_of_steps >= 256) {
setting_pattern = 0;
microsteps = 256;
} else if (number_of_steps>=128) {
}
else if (number_of_steps >= 128) {
setting_pattern = 1;
microsteps = 128;
} else if (number_of_steps>=64) {
}
else if (number_of_steps >= 64) {
setting_pattern = 2;
microsteps = 64;
} else if (number_of_steps>=32) {
}
else if (number_of_steps >= 32) {
setting_pattern = 3;
microsteps = 32;
} else if (number_of_steps>=16) {
}
else if (number_of_steps >= 16) {
setting_pattern = 4;
microsteps = 16;
} else if (number_of_steps>=8) {
}
else if (number_of_steps >= 8) {
setting_pattern = 5;
microsteps = 8;
} else if (number_of_steps>=4) {
}
else if (number_of_steps >= 4) {
setting_pattern = 6;
microsteps = 4;
} else if (number_of_steps>=2) {
}
else if (number_of_steps >= 2) {
setting_pattern = 7;
microsteps = 2;
//1 and 0 lead to full step
} else if (number_of_steps<=1) {
}
else if (number_of_steps <= 1) {
setting_pattern = 8;
microsteps = 1;
}
@ -451,27 +433,24 @@ void TMC26XStepper::setMicrosteps(int number_of_steps) {
//SERIAL_PRINTF("Microstepping: ");
SERIAL_ECHOPAIR("\n Microstepping: ", microsteps);
#endif
//delete the old value
this->driver_control_register_value &=0xFFFF0ul;
//set the new value
// Delete the old value
this->driver_control_register_value &= 0xFFFF0UL;
// Set the new value
this->driver_control_register_value |= setting_pattern;
//if started we directly send it to the motor
if (started) {
send262(driver_control_register_value);
}
//recalculate the stepping delay by simply setting the speed again
// If started we directly send it to the motor
if (started) send262(driver_control_register_value);
// Recalculate the stepping delay by simply setting the speed again
this->setSpeed(this->speed);
}
/*
/**
* returns the effective number of microsteps at the moment
*/
int TMC26XStepper::getMicrosteps(void) {
return microsteps;
}
int TMC26XStepper::getMicrosteps(void) { return microsteps }
/*
/**
* constant_off_time: The off time setting controls the minimum chopper frequency.
* For most applications an off time within the range of 5μs to 20μs will fit.
* 2...15: off time setting
@ -495,67 +474,51 @@ int TMC26XStepper::getMicrosteps(void) {
* 0: end by time only
*/
void TMC26XStepper::setConstantOffTimeChopper(char constant_off_time, char blank_time, char fast_decay_time_setting, char sine_wave_offset, unsigned char use_current_comparator) {
//perform some sanity checks
if (constant_off_time<2) {
constant_off_time=2;
} else if (constant_off_time>15) {
constant_off_time=15;
}
//save the constant off time
// Perform some sanity checks
LIMIT(constant_off_time, 2, 15);
// Save the constant off time
this->constant_off_time = constant_off_time;
char blank_value;
//calculate the value acc to the clock cycles
if (blank_time>=54) {
blank_value=3;
} else if (blank_time>=36) {
blank_value=2;
} else if (blank_time>=24) {
blank_value=1;
} else {
blank_value=0;
}
if (fast_decay_time_setting<0) {
fast_decay_time_setting=0;
} else if (fast_decay_time_setting>15) {
fast_decay_time_setting=15;
}
if (sine_wave_offset < -3) {
sine_wave_offset = -3;
} else if (sine_wave_offset>12) {
sine_wave_offset = 12;
}
//shift the sine_wave_offset
// Calculate the value acc to the clock cycles
const char blank_value = blank_time >= 54 ? 3 :
blank_time >= 36 ? 2 :
blank_time >= 24 ? 1 : 0;
LIMIT(fast_decay_time_setting, 0, 15);
LIMIT(sine_wave_offset, -3, 12);
// Shift the sine_wave_offset
sine_wave_offset += 3;
//calculate the register setting
//first of all delete all the values for this
chopper_config_register &= ~((1<<12) | BLANK_TIMING_PATTERN | HYSTERESIS_DECREMENT_PATTERN | HYSTERESIS_LOW_VALUE_PATTERN | HYSTERESIS_START_VALUE_PATTERN | T_OFF_TIMING_PATERN);
//set the constant off pattern
// Calculate the register setting
// First of all delete all the values for this
chopper_config_register &= ~(_BV(12) | BLANK_TIMING_PATTERN | HYSTERESIS_DECREMENT_PATTERN | HYSTERESIS_LOW_VALUE_PATTERN | HYSTERESIS_START_VALUE_PATTERN | T_OFF_TIMING_PATERN);
// Set the constant off pattern
chopper_config_register |= CHOPPER_MODE_T_OFF_FAST_DECAY;
//set the blank timing value
// Set the blank timing value
chopper_config_register |= ((unsigned long)blank_value) << BLANK_TIMING_SHIFT;
//setting the constant off time
// Setting the constant off time
chopper_config_register |= constant_off_time;
//set the fast decay time
//set msb
// Set the fast decay time
// Set msb
chopper_config_register |= (((unsigned long)(fast_decay_time_setting & 0x8)) << HYSTERESIS_DECREMENT_SHIFT);
//other bits
// Other bits
chopper_config_register |= (((unsigned long)(fast_decay_time_setting & 0x7)) << HYSTERESIS_START_VALUE_SHIFT);
//set the sine wave offset
// Set the sine wave offset
chopper_config_register |= (unsigned long)sine_wave_offset << HYSTERESIS_LOW_SHIFT;
//using the current comparator?
if (!use_current_comparator) {
chopper_config_register |= (1<<12);
}
//if started we directly send it to the motor
// Using the current comparator?
if (!use_current_comparator)
chopper_config_register |= _BV(12);
// If started we directly send it to the motor
if (started) {
// rem send262(driver_control_register_value);
send262(chopper_config_register);
}
}
/*
/**
* constant_off_time: The off time setting controls the minimum chopper frequency.
* For most applications an off time within the range of 5μs to 20μs will fit.
* 2...15: off time setting
@ -576,45 +539,26 @@ void TMC26XStepper::setConstantOffTimeChopper(char constant_off_time, char blank
*/
void TMC26XStepper::setSpreadCycleChopper(char constant_off_time, char blank_time, char hysteresis_start, char hysteresis_end, char hysteresis_decrement) {
//perform some sanity checks
if (constant_off_time<2) {
constant_off_time=2;
} else if (constant_off_time>15) {
constant_off_time=15;
}
//save the constant off time
// Perform some sanity checks
LIMIT(constant_off_time, 2, 15);
// Save the constant off time
this->constant_off_time = constant_off_time;
char blank_value;
//calculate the value acc to the clock cycles
if (blank_time>=54) {
blank_value=3;
} else if (blank_time>=36) {
blank_value=2;
} else if (blank_time>=24) {
blank_value=1;
} else {
blank_value=0;
}
if (hysteresis_start<1) {
hysteresis_start=1;
} else if (hysteresis_start>8) {
hysteresis_start=8;
}
// Calculate the value acc to the clock cycles
const char blank_value = blank_time >= 54 ? 3 :
blank_time >= 36 ? 2 :
blank_time >= 24 ? 1 : 0;
LIMIT(hysteresis_start, 1, 8);
hysteresis_start--;
if (hysteresis_end < -3) {
hysteresis_end = -3;
} else if (hysteresis_end>12) {
hysteresis_end = 12;
}
//shift the hysteresis_end
LIMIT(hysteresis_start, -3, 12);
// Shift the hysteresis_end
hysteresis_end += 3;
if (hysteresis_decrement<0) {
hysteresis_decrement=0;
} else if (hysteresis_decrement>3) {
hysteresis_decrement=3;
}
LIMIT(hysteresis_decrement, 0, 3);
//first of all delete all the values for this
chopper_config_register &= ~(CHOPPER_MODE_T_OFF_FAST_DECAY | BLANK_TIMING_PATTERN | HYSTERESIS_DECREMENT_PATTERN | HYSTERESIS_LOW_VALUE_PATTERN | HYSTERESIS_START_VALUE_PATTERN | T_OFF_TIMING_PATERN);
@ -632,12 +576,11 @@ void TMC26XStepper::setSpreadCycleChopper(char constant_off_time, char blank_tim
//if started we directly send it to the motor
if (started) {
//rem send262(driver_control_register_value);
send262(chopper_config_register);
}
}
/*
/**
* In a constant off time chopper scheme both coil choppers run freely, i.e. are not synchronized.
* The frequency of each chopper mainly depends on the coil current and the position dependant motor coil inductivity, thus it depends on the microstep position.
* With some motors a slightly audible beat can occur between the chopper frequencies, especially when they are near to each other. This typically occurs at a
@ -650,80 +593,68 @@ void TMC26XStepper::setSpreadCycleChopper(char constant_off_time, char blank_tim
* reducing electromagnetic emission on single frequencies.
*/
void TMC26XStepper::setRandomOffTime(char value) {
if (value) {
if (value)
chopper_config_register |= RANDOM_TOFF_TIME;
} else {
else
chopper_config_register &= ~(RANDOM_TOFF_TIME);
}
//if started we directly send it to the motor
if (started) {
//rem send262(driver_control_register_value);
send262(chopper_config_register);
}
}
void TMC26XStepper::setCoolStepConfiguration(unsigned int lower_SG_threshold, unsigned int SG_hysteresis, unsigned char current_decrement_step_size,
unsigned char current_increment_step_size, unsigned char lower_current_limit) {
//sanitize the input values
if (lower_SG_threshold>480) {
lower_SG_threshold = 480;
}
//divide by 32
void TMC26XStepper::setCoolStepConfiguration(
unsigned int lower_SG_threshold,
unsigned int SG_hysteresis,
unsigned char current_decrement_step_size,
unsigned char current_increment_step_size,
unsigned char lower_current_limit)
{
// Sanitize the input values
NOMORE(lower_SG_threshold, 480);
// Divide by 32
lower_SG_threshold >>= 5;
if (SG_hysteresis>480) {
SG_hysteresis=480;
}
//divide by 32
NOMORE(SG_hysteresis, 480);
// Divide by 32
SG_hysteresis >>= 5;
if (current_decrement_step_size>3) {
current_decrement_step_size=3;
}
if (current_increment_step_size>3) {
current_increment_step_size=3;
}
if (lower_current_limit>1) {
lower_current_limit=1;
}
//store the lower level in order to enable/disable the cool step
NOMORE(current_decrement_step_size, 3);
NOMORE(current_increment_step_size, 3);
NOMORE(lower_current_limit, 1);
// Store the lower level in order to enable/disable the cool step
this->cool_step_lower_threshold=lower_SG_threshold;
//if cool step is not enabled we delete the lower value to keep it disabled
if (!this->cool_step_enabled) {
lower_SG_threshold=0;
}
//the good news is that we can start with a complete new cool step register value
//and simply set the values in the register
cool_step_register_value = ((unsigned long)lower_SG_threshold) | (((unsigned long)SG_hysteresis)<<8) | (((unsigned long)current_decrement_step_size)<<5)
| (((unsigned long)current_increment_step_size)<<13) | (((unsigned long)lower_current_limit)<<15)
//and of course we have to include the signature of the register
| COOL_STEP_REGISTER;
// If cool step is not enabled we delete the lower value to keep it disabled
if (!this->cool_step_enabled) lower_SG_threshold = 0;
// The good news is that we can start with a complete new cool step register value
// And simply set the values in the register
cool_step_register_value = ((unsigned long)lower_SG_threshold)
| (((unsigned long)SG_hysteresis) << 8)
| (((unsigned long)current_decrement_step_size) << 5)
| (((unsigned long)current_increment_step_size) << 13)
| (((unsigned long)lower_current_limit) << 15)
| COOL_STEP_REGISTER; // Register signature
//SERIAL_PRINTFln(cool_step_register_value,HEX);
if (started) {
send262(cool_step_register_value);
}
if (started) send262(cool_step_register_value);
}
void TMC26XStepper::setCoolStepEnabled(boolean enabled) {
//simply delete the lower limit to disable the cool step
// Simply delete the lower limit to disable the cool step
cool_step_register_value &= ~SE_MIN_PATTERN;
//and set it to the proper value if cool step is to be enabled
if (enabled) {
// And set it to the proper value if cool step is to be enabled
if (enabled)
cool_step_register_value |= this->cool_step_lower_threshold;
}
//and save the enabled status
// And save the enabled status
this->cool_step_enabled = enabled;
//save the register value
if (started) {
send262(cool_step_register_value);
}
// Save the register value
if (started) send262(cool_step_register_value);
}
boolean TMC26XStepper::isCoolStepEnabled(void) {
return this->cool_step_enabled;
}
boolean TMC26XStepper::isCoolStepEnabled(void) { return this->cool_step_enabled; }
unsigned int TMC26XStepper::getCoolStepLowerSgThreshold() {
//we return our internally stored value - in order to provide the correct setting even if cool step is not enabled
// We return our internally stored value - in order to provide the correct setting even if cool step is not enabled
return this->cool_step_lower_threshold<<5;
}
@ -751,20 +682,12 @@ void TMC26XStepper::setEnabled(boolean enabled) {
chopper_config_register |= this->constant_off_time;
}
//if not enabled we don't have to do anything since we already delete t_off from the register
if (started) {
send262(chopper_config_register);
}
if (started) send262(chopper_config_register);
}
boolean TMC26XStepper::isEnabled() {
if (chopper_config_register & T_OFF_PATTERN) {
return true;
} else {
return false;
}
}
boolean TMC26XStepper::isEnabled() { return !!(chopper_config_register & T_OFF_PATTERN); }
/*
/**
* reads a value from the TMC26X status register. The value is not obtained directly but can then
* be read by the various status routines.
*
@ -774,11 +697,11 @@ void TMC26XStepper::readStatus(char read_value) {
//reset the readout configuration
driver_configuration_register_value &= ~(READ_SELECTION_PATTERN);
//this now equals TMC26X_READOUT_POSITION - so we just have to check the other two options
if (read_value == TMC26X_READOUT_STALLGUARD) {
if (read_value == TMC26X_READOUT_STALLGUARD)
driver_configuration_register_value |= READ_STALL_GUARD_READING;
} else if (read_value == TMC26X_READOUT_CURRENT) {
else if (read_value == TMC26X_READOUT_CURRENT)
driver_configuration_register_value |= READ_STALL_GUARD_AND_COOL_STEP;
}
//all other cases are ignored to prevent funny values
//check if the readout is configured for the value we are interested in
if (driver_configuration_register_value != old_driver_configuration_register_value) {
@ -799,9 +722,7 @@ int TMC26XStepper::getMotorPosition(void) {
//returns -1 if stallguard information is not present
int TMC26XStepper::getCurrentStallGuardReading(void) {
//if we don't yet started there cannot be a stall guard value
if (!started) {
return -1;
}
if (!started) return -1;
//not time optimal, but solution optiomal:
//first read out the stall guard value
readStatus(TMC26X_READOUT_STALLGUARD);
@ -810,97 +731,80 @@ int TMC26XStepper::getCurrentStallGuardReading(void) {
unsigned char TMC26XStepper::getCurrentCSReading(void) {
//if we don't yet started there cannot be a stall guard value
if (!started) {
return 0;
}
if (!started) return 0;
//not time optimal, but solution optiomal:
//first read out the stall guard value
readStatus(TMC26X_READOUT_CURRENT);
return (getReadoutValue() & 0x1f);
return (getReadoutValue() & 0x1F);
}
unsigned int TMC26XStepper::getCurrentCurrent(void) {
double result = (double)getCurrentCSReading();
double resistor_value = (double)this->resistor;
double voltage = (driver_configuration_register_value & VSENSE)? 0.165:0.31;
result = (result+1.0)/32.0*voltage/resistor_value*1000.0*1000.0;
double result = (double)getCurrentCSReading(),
resistor_value = (double)this->resistor,
voltage = (driver_configuration_register_value & VSENSE)? 0.165 : 0.31;
result = (result + 1.0) / 32.0 * voltage / resistor_value * sq(1000.0);
return (unsigned int)result;
}
/*
return true if the stallguard threshold has been reached
/**
* Return true if the stallguard threshold has been reached
*/
boolean TMC26XStepper::isStallGuardOverThreshold(void) {
if (!this->started) {
return false;
}
if (!this->started) return false;
return (driver_status_result & STATUS_STALL_GUARD_STATUS);
}
/*
returns if there is any over temperature condition:
OVER_TEMPERATURE_PREWARING if pre warning level has been reached
OVER_TEMPERATURE_SHUTDOWN if the temperature is so hot that the driver is shut down
Any of those levels are not too good.
/**
* returns if there is any over temperature condition:
* OVER_TEMPERATURE_PREWARING if pre warning level has been reached
* OVER_TEMPERATURE_SHUTDOWN if the temperature is so hot that the driver is shut down
* Any of those levels are not too good.
*/
char TMC26XStepper::getOverTemperature(void) {
if (!this->started) {
return 0;
}
if (driver_status_result & STATUS_OVER_TEMPERATURE_SHUTDOWN) {
if (!this->started) return 0;
if (driver_status_result & STATUS_OVER_TEMPERATURE_SHUTDOWN)
return TMC26X_OVERTEMPERATURE_SHUTDOWN;
}
if (driver_status_result & STATUS_OVER_TEMPERATURE_WARNING) {
if (driver_status_result & STATUS_OVER_TEMPERATURE_WARNING)
return TMC26X_OVERTEMPERATURE_PREWARING;
}
return 0;
}
//is motor channel A shorted to ground
// Is motor channel A shorted to ground
boolean TMC26XStepper::isShortToGroundA(void) {
if (!this->started) {
return false;
}
if (!this->started) return false;
return (driver_status_result & STATUS_SHORT_TO_GROUND_A);
}
//is motor channel B shorted to ground
// Is motor channel B shorted to ground
boolean TMC26XStepper::isShortToGroundB(void) {
if (!this->started) {
return false;
}
if (!this->started) return false;
return (driver_status_result & STATUS_SHORT_TO_GROUND_B);
}
//is motor channel A connected
// Is motor channel A connected
boolean TMC26XStepper::isOpenLoadA(void) {
if (!this->started) {
return false;
}
if (!this->started) return false;
return (driver_status_result & STATUS_OPEN_LOAD_A);
}
//is motor channel B connected
// Is motor channel B connected
boolean TMC26XStepper::isOpenLoadB(void) {
if (!this->started) {
return false;
}
if (!this->started) return false;
return (driver_status_result & STATUS_OPEN_LOAD_B);
}
//is chopper inactive since 2^20 clock cycles - defaults to ~0,08s
// Is chopper inactive since 2^20 clock cycles - defaults to ~0,08s
boolean TMC26XStepper::isStandStill(void) {
if (!this->started) {
return false;
}
if (!this->started) return false;
return (driver_status_result & STATUS_STAND_STILL);
}
//is chopper inactive since 2^20 clock cycles - defaults to ~0,08s
boolean TMC26XStepper::isStallGuardReached(void) {
if (!this->started) {
return false;
}
if (!this->started) return false;
return (driver_status_result & STATUS_STALL_GUARD_STATUS);
}
@ -910,62 +814,54 @@ int TMC26XStepper::getReadoutValue(void) {
return (int)(driver_status_result >> 10);
}
int TMC26XStepper::getResistor() {
return this->resistor;
}
int TMC26XStepper::getResistor() { return this->resistor; }
boolean TMC26XStepper::isCurrentScalingHalfed() {
if (this->driver_configuration_register_value & VSENSE) {
return true;
} else {
return false;
return !!(this->driver_configuration_register_value & VSENSE);
}
}
/*
version() returns the version of the library:
/**
* version() returns the version of the library:
*/
int TMC26XStepper::version(void)
{
return 1;
}
int TMC26XStepper::version(void) { return 1; }
void TMC26XStepper::debugLastStatus() {
#ifdef TMC_DEBUG1
if (this->started) {
if (this->getOverTemperature()&TMC26X_OVERTEMPERATURE_PREWARING) {
if (this->getOverTemperature()&TMC26X_OVERTEMPERATURE_PREWARING)
SERIAL_ECHOLNPGM("\n WARNING: Overtemperature Prewarning!");
} else if (this->getOverTemperature()&TMC26X_OVERTEMPERATURE_SHUTDOWN) {
else if (this->getOverTemperature()&TMC26X_OVERTEMPERATURE_SHUTDOWN)
SERIAL_ECHOLNPGM("\n ERROR: Overtemperature Shutdown!");
}
if (this->isShortToGroundA()) {
if (this->isShortToGroundA())
SERIAL_ECHOLNPGM("\n ERROR: SHORT to ground on channel A!");
}
if (this->isShortToGroundB()) {
if (this->isShortToGroundB())
SERIAL_ECHOLNPGM("\n ERROR: SHORT to ground on channel B!");
}
if (this->isOpenLoadA()) {
if (this->isOpenLoadA())
SERIAL_ECHOLNPGM("\n ERROR: Channel A seems to be unconnected!");
}
if (this->isOpenLoadB()) {
if (this->isOpenLoadB())
SERIAL_ECHOLNPGM("\n ERROR: Channel B seems to be unconnected!");
}
if (this->isStallGuardReached()) {
if (this->isStallGuardReached())
SERIAL_ECHOLNPGM("\n INFO: Stall Guard level reached!");
}
if (this->isStandStill()) {
if (this->isStandStill())
SERIAL_ECHOLNPGM("\n INFO: Motor is standing still.");
}
unsigned long readout_config = driver_configuration_register_value & READ_SELECTION_PATTERN;
int value = getReadoutValue();
const int value = getReadoutValue();
if (readout_config == READ_MICROSTEP_POSTION) {
//SERIAL_PRINTF("Microstep postion phase A: ");
SERIAL_ECHOPAIR("\n Microstep postion phase A: ", value);
} else if (readout_config == READ_STALL_GUARD_READING) {
}
else if (readout_config == READ_STALL_GUARD_READING) {
//SERIAL_PRINTF("Stall Guard value:");
SERIAL_ECHOPAIR("\n Stall Guard value:", value);
} else if (readout_config == READ_STALL_GUARD_AND_COOL_STEP) {
int stallGuard = value & 0xf;
int current = value & 0x1F0;
}
else if (readout_config == READ_STALL_GUARD_AND_COOL_STEP) {
int stallGuard = value & 0xF, current = value & 0x1F0;
//SERIAL_PRINTF("Approx Stall Guard: ");
SERIAL_ECHOPAIR("\n Approx Stall Guard: ", stallGuard);
//SERIAL_PRINTF("Current level");
@ -975,7 +871,7 @@ if (this->started) {
#endif
}
/*
/**
* send register settings to the stepper driver via SPI
* returns the current status
*/
@ -1004,11 +900,11 @@ inline void TMC26XStepper::send262(unsigned long datagram) {
#endif
//write/read the values
i_datagram = STEPPER_SPI.transfer((datagram >> 16) & 0xff);
i_datagram = STEPPER_SPI.transfer((datagram >> 16) & 0xFF);
i_datagram <<= 8;
i_datagram |= STEPPER_SPI.transfer((datagram >> 8) & 0xff);
i_datagram |= STEPPER_SPI.transfer((datagram >> 8) & 0xFF);
i_datagram <<= 8;
i_datagram |= STEPPER_SPI.transfer((datagram) & 0xff);
i_datagram |= STEPPER_SPI.transfer((datagram) & 0xFF);
i_datagram >>= 4;
#ifdef TMC_DEBUG1
@ -1018,6 +914,7 @@ inline void TMC26XStepper::send262(unsigned long datagram) {
SERIAL_PRINTF("\n\nReceived %x", i_datagram);
debugLastStatus();
#endif
//deselect the TMC chip
digitalWrite(cs_pin,HIGH);
@ -1027,7 +924,6 @@ inline void TMC26XStepper::send262(unsigned long datagram) {
// SPI.setDataMode(oldMode);
//}
//store the datagram as status result
driver_status_result = i_datagram;
}

View file

@ -1,37 +1,35 @@
/*
TMC26XStepper.cpp - - TMC26X Stepper library for Wiring/Arduino
based on the stepper library by Tom Igoe, et. al.
Copyright (c) 2011, Interactive Matter, Marcus Nowotny
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
/**
* TMC26XStepper.h - - TMC26X Stepper library for Wiring/Arduino
*
* based on the stepper library by Tom Igoe, et. al.
*
* Copyright (c) 2011, Interactive Matter, Marcus Nowotny
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#include "../../inc/MarlinConfig.h"
// ensure this library description is only included once
#ifndef TMC26XStepper_h
#define TMC26XStepper_h
#ifndef _TMC26XSTEPPER_H_
#define _TMC26XSTEPPER_H_
//! return value for TMC26XStepper.getOverTemperature() if there is a overtemperature situation in the TMC chip
/*!
@ -568,43 +566,42 @@ class TMC26XStepper {
int version(void);
private:
unsigned int steps_left; //the steps the motor has to do to complete the movement
unsigned int steps_left; // The steps the motor has to do to complete the movement
int direction; // Direction of rotation
unsigned long step_delay; // delay between steps, in ms, based on speed
int number_of_steps; // total number of steps this motor can take
unsigned int speed; // we need to store the current speed in order to change the speed after changing microstepping
unsigned int resistor; //current sense resitor value in milliohm
unsigned long step_delay; // Delay between steps, in ms, based on speed
int number_of_steps; // Total number of steps this motor can take
unsigned int speed; // Store the current speed in order to change the speed after changing microstepping
unsigned int resistor; // Current sense resitor value in milliohm
unsigned long last_step_time; // time stamp in ms of when the last step was taken
unsigned long next_step_time; // time stamp in ms of when the last step was taken
unsigned long last_step_time; // Time stamp in ms of when the last step was taken
unsigned long next_step_time; // Time stamp in ms of when the last step was taken
//driver control register copies to easily set & modify the registers
// Driver control register copies to easily set & modify the registers
unsigned long driver_control_register_value;
unsigned long chopper_config_register;
unsigned long cool_step_register_value;
unsigned long stall_guard2_current_register_value;
unsigned long driver_configuration_register_value;
//the driver status result
// The driver status result
unsigned long driver_status_result;
//helper routione to get the top 10 bit of the readout
// Helper routione to get the top 10 bit of the readout
inline int getReadoutValue();
//the pins for the stepper driver
// The pins for the stepper driver
unsigned char cs_pin;
unsigned char step_pin;
unsigned char dir_pin;
//status values
boolean started; //if the stepper has been started yet
int microsteps; //the current number of micro steps
char constant_off_time; //we need to remember this value in order to enable and disable the motor
// Status values
boolean started; // If the stepper has been started yet
int microsteps; // The current number of micro steps
char constant_off_time; // We need to remember this value in order to enable and disable the motor
unsigned char cool_step_lower_threshold; // we need to remember the threshold to enable and disable the CoolStep feature
boolean cool_step_enabled; //we need to remember this to configure the coolstep if it si enabled
boolean cool_step_enabled; // We need to remember this to configure the coolstep if it si enabled
// SPI sender
inline void send262(unsigned long datagram);
};
#endif
#endif // _TMC26XSTEPPER_H_

View file

@ -51,4 +51,4 @@
#define OUT_WRITE(IO, v) { _SET_OUTPUT(IO); WRITE(IO, v); }
#endif /* _FASTIO_STM32F7_H */
#endif // _FASTIO_STM32F7_H

View file

@ -34,22 +34,19 @@
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)
{
if (HAL_IWDG_Init(&hiwdg) != HAL_OK) {
//Error_Handler();
}
}
void watchdog_reset() {
/* Refresh IWDG: reload counter */
if (HAL_IWDG_Refresh(&hiwdg) != HAL_OK)
{
if (HAL_IWDG_Refresh(&hiwdg) != HAL_OK) {
/* Refresh Error */
//Error_Handler();
}
}
#endif // USE_WATCHDOG
#endif // STM32F7

View file

@ -120,6 +120,7 @@
// Macros to contrain values
#define NOLESS(v,n) do{ if (v < n) v = n; }while(0)
#define NOMORE(v,n) do{ if (v > n) v = n; }while(0)
#define LIMIT(v,n1,n2) do{ if (v < n1) v = n1; else if (v > n2) v = n2; }while(0)
// Macros to support option testing
#define _CAT(a, ...) a ## __VA_ARGS__

View file

@ -42,7 +42,7 @@
#include <SPI.h>
#if defined(STM32F7)
#ifdef STM32F7
#include "../HAL/HAL_STM32F7/TMC2660.h"
#else
#include <TMC26XStepper.h>

View file

@ -49,7 +49,7 @@
// TMC26X drivers have STEP/DIR on normal pins, but ENABLE via SPI
#if ENABLED(HAVE_TMCDRIVER)
#include <SPI.h>
#if defined(STM32F7)
#ifdef STM32F7
#include "../HAL/HAL_STM32F7/TMC2660.h"
#else
#include <TMC26XStepper.h>