From 902c885782d389905d5c34c78a19e2be8d7e6cf5 Mon Sep 17 00:00:00 2001 From: Bob-the-Kuhn Date: Wed, 4 Apr 2018 20:13:27 -0500 Subject: [PATCH] Switch to TMC2130 compatible hardware SPI & misc (#10299) --- Marlin/src/HAL/HAL_DUE/HAL_Due.cpp | 49 ++++++++++++------------ Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp | 46 +++++++++++----------- Marlin/src/HAL/HAL_DUE/SanityCheck_Due.h | 8 ++++ Marlin/src/Marlin.cpp | 11 +++--- Marlin/src/sd/Sd2Card.cpp | 11 +++--- 5 files changed, 67 insertions(+), 58 deletions(-) diff --git a/Marlin/src/HAL/HAL_DUE/HAL_Due.cpp b/Marlin/src/HAL/HAL_DUE/HAL_Due.cpp index 44fd6a019f..f53e7a122e 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/HAL_Due.cpp @@ -1,23 +1,21 @@ -/* ************************************************************************** - - Marlin 3D Printer Firmware - Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.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 . -****************************************************************************/ - +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.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 . + */ /** * Description: HAL for Arduino Due and compatible (SAM3X8E) @@ -77,6 +75,9 @@ uint16_t HAL_adc_result; // HAL initialization task void HAL_init(void) { // Initialize the USB stack + #if ENABLED(SDSUPPORT) + OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up + #endif usb_task_init(); } @@ -86,10 +87,10 @@ void HAL_idletask(void) { usb_task_idle(); } -// disable interrupts +// Disable interrupts void cli(void) { noInterrupts(); } -// enable interrupts +// Enable interrupts void sei(void) { interrupts(); } void HAL_clear_reset_source(void) { } @@ -106,7 +107,7 @@ uint8_t HAL_get_reset_source(void) { } void _delay_ms(const int delay_ms) { - // todo: port for Due? + // Todo: port for Due? delay(delay_ms); } @@ -114,7 +115,7 @@ extern "C" { extern unsigned int _ebss; // end of bss section } -// return free memory between end of heap (or end bss) and whatever is current +// Return free memory between end of heap (or end bss) and whatever is current int freeMemory() { int free_memory, heap_end = (int)_sbrk(0); return (int)&free_memory - (heap_end ? heap_end : (int)&_ebss); diff --git a/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp b/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp index 2de71e3070..36aec94136 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp @@ -486,7 +486,7 @@ static void spiRxBlockX(uint8_t* buf, uint32_t todo) { do { - *buf++ = spiTransferRx(0xff); + *buf++ = spiTransferRx(0xFF); } while (--todo); } @@ -629,7 +629,7 @@ bool spiInitMaded = false; void spiBegin() { - if(spiInitMaded == false) { + if (spiInitMaded == false) { // Configure SPI pins PIO_Configure( g_APinDescription[SCK_PIN].pPort, @@ -681,8 +681,8 @@ } void spiInit(uint8_t spiRate) { - if(spiInitMaded == false) { - if(spiRate > 6) spiRate = 1; + if (spiInitMaded == false) { + if (spiRate > 6) spiRate = 1; #if MB(ALLIGATOR) // Set SPI mode 1, clock, select not active after transfer, with delay between transfers @@ -789,7 +789,7 @@ } // Read from SPI into buffer - void spiRead(uint8_t*buf, uint16_t nbyte) { + void spiRead(uint8_t* buf, uint16_t nbyte) { if (nbyte-- == 0) return; for (int i = 0; i < nbyte; i++) { @@ -830,38 +830,37 @@ #define SPI_MODE_2_DUE_HW 0 #define SPI_MODE_3_DUE_HW 1 - void spiInit(uint8_t spiRate = 6 ) { // default to slowest rate if not specified) + void spiInit(uint8_t spiRate=6) { // Default to slowest rate if not specified) // 8.4 MHz, 4 MHz, 2 MHz, 1 MHz, 0.5 MHz, 0.329 MHz, 0.329 MHz int spiDueDividors[] = { 10, 21, 42, 84, 168, 255, 255 }; - if(spiRate > 6) spiRate = 1; + if (spiRate > 6) spiRate = 1; - /* enable PIOA and SPI0 */ + // Enable PIOA and SPI0 REG_PMC_PCER0 = (1UL << ID_PIOA) | (1UL << ID_SPI0); - /* disable PIO on A26 and A27 */ + // Disable PIO on A26 and A27 REG_PIOA_PDR = 0x0c000000; OUT_WRITE(SDSS, 1); - /* reset SPI0 (from sam lib) */ + // Reset SPI0 (from sam lib) SPI0->SPI_CR = SPI_CR_SPIDIS; SPI0->SPI_CR = SPI_CR_SWRST; SPI0->SPI_CR = SPI_CR_SWRST; SPI0->SPI_CR = SPI_CR_SPIEN; - - /* master mode, no fault detection, chip select 0 */ - SPI0->SPI_MR = SPI_MR_MSTR | SPI_MR_PCSDEC | SPI_MR_MODFDIS; - - /* SPI mode 0, 8 Bit data transfer, baud rate */ - SPI0->SPI_CSR[0] = SPI_CSR_SCBR(spiDueDividors[spiRate]) | SPI_MODE_0_DUE_HW; + // TMC2103 compatible setup + // Master mode, no fault detection, PCS bits in data written to TDR select CSR register + SPI0->SPI_MR = SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS; + // SPI mode 0, 8 Bit data transfer, baud rate + SPI0->SPI_CSR[3] = SPI_CSR_SCBR(spiDueDividors[spiRate]) | SPI_CSR_CSAAT | SPI_MODE_0_DUE_HW; // use same CSR as TMC2130 } static uint8_t spiTransfer(uint8_t data) { - /* wait until tx register is empty */ + // Wait until tx register is empty while( (SPI0->SPI_SR & SPI_SR_TDRE) == 0 ); - /* send data */ - SPI0->SPI_TDR = (uint32_t)data; // | SPI_PCS(0xF); + // Send data + SPI0->SPI_TDR = (uint32_t)data | 0x00070000UL; // Add TMC2130 PCS bits to every byte // wait for transmit register empty while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0); @@ -877,15 +876,14 @@ } uint8_t spiRec() { - uint8_t data = spiTransfer(0xff); + uint8_t data = spiTransfer(0xFF); return data; } - void spiRead(uint8_t*buf, uint16_t nbyte) { + void spiRead(uint8_t* buf, uint16_t nbyte) { if (nbyte == 0) return; - for (int i = 0; i < nbyte; i++) { - buf[i] = spiTransfer(0xff); - } + for (int i = 0; i < nbyte; i++) + buf[i] = spiTransfer(0xFF); } void spiSend(uint8_t data) { diff --git a/Marlin/src/HAL/HAL_DUE/SanityCheck_Due.h b/Marlin/src/HAL/HAL_DUE/SanityCheck_Due.h index f3905d940f..c4edfd49d8 100644 --- a/Marlin/src/HAL/HAL_DUE/SanityCheck_Due.h +++ b/Marlin/src/HAL/HAL_DUE/SanityCheck_Due.h @@ -27,3 +27,11 @@ /** * Require gcc 4.7 or newer (first included with Arduino 1.6.8) for C++11 features. */ + +#if ENABLED(SDSUPPORT) && ENABLED(HAVE_TMC2130) + #if ENABLED(DUE_SOFTWARE_SPI) && !ENABLED(TMC_USE_SW_SPI) + #error "DUE software SPI is incompatible with TMC2130 hardware SPI. Enable TMC_USE_SW_SPI to fix." + #elif !ENABLED(DUE_SOFTWARE_SPI) && ENABLED(TMC_USE_SW_SPI) + #error "DUE hardware SPI is incompatible with TMC2130 software SPI. Disable TMC_USE_SW_SPI to fix." + #endif +#endif diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp index 23b7079057..61479a8aad 100644 --- a/Marlin/src/Marlin.cpp +++ b/Marlin/src/Marlin.cpp @@ -892,14 +892,15 @@ void setup() { * - Call LCD update */ void loop() { - if (commands_in_queue < BUFSIZE) get_available_commands(); #if ENABLED(SDSUPPORT) card.checkautostart(false); #endif - advance_command_queue(); - - endstops.report_state(); - idle(); + for (;;) { + if (commands_in_queue < BUFSIZE) get_available_commands(); + advance_command_queue(); + endstops.report_state(); + idle(); + } } diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index 9216480e20..174a8ffd4a 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -249,15 +249,16 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) { watchdog_reset(); #endif - // set pin modes - pinMode(chipSelectPin_, OUTPUT); // Solution for #8746 by @benlye + // Set pin modes + digitalWrite(chipSelectPin_, HIGH); // For some CPUs pinMode can write the wrong data so init desired data value first + pinMode(chipSelectPin_, OUTPUT); // Solution for #8746 by @benlye spiBegin(); - // set SCK rate for initialization commands + // Set SCK rate for initialization commands spiRate_ = SPI_SD_INIT_RATE; spiInit(spiRate_); - // must supply min of 74 clock cycles with CS high. + // Must supply min of 74 clock cycles with CS high. for (uint8_t i = 0; i < 10; i++) spiSend(0xFF); // Initialization can cause the watchdog to timeout, so reinit it here @@ -265,7 +266,7 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) { watchdog_reset(); #endif - // command to go idle in SPI mode + // Command to go idle in SPI mode while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { error(SD_CARD_ERROR_CMD0);