123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- /**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2019 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/>.
- *
- */
-
- /**
- * Software L6470 SPI functions originally from Arduino Sd2Card Library
- * Copyright (c) 2009 by William Greiman
- */
-
- #include "../../inc/MarlinConfig.h"
-
- #if HAS_L64XX
-
- #include "Delay.h"
-
- #include "../../core/serial.h"
- #include "../../libs/L64XX/L64XX_Marlin.h"
-
- // Make sure GCC optimizes this file.
- // Note that this line triggers a bug in GCC which is fixed by casting.
- // See the note below.
- #pragma GCC optimize (3)
-
- // run at ~4Mhz
- inline uint8_t L6470_SpiTransfer_Mode_0(uint8_t b) { // using Mode 0
- for (uint8_t bits = 8; bits--;) {
- WRITE(L6470_CHAIN_MOSI_PIN, b & 0x80);
- b <<= 1; // little setup time
-
- WRITE(L6470_CHAIN_SCK_PIN, HIGH);
- DELAY_NS(125); // 10 cycles @ 84mhz
-
- b |= (READ(L6470_CHAIN_MISO_PIN) != 0);
-
- WRITE(L6470_CHAIN_SCK_PIN, LOW);
- DELAY_NS(125); // 10 cycles @ 84mhz
- }
- return b;
- }
-
- inline uint8_t L6470_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3
- for (uint8_t bits = 8; bits--;) {
- WRITE(L6470_CHAIN_SCK_PIN, LOW);
- WRITE(L6470_CHAIN_MOSI_PIN, b & 0x80);
-
- DELAY_NS(125); // 10 cycles @ 84mhz
- WRITE(L6470_CHAIN_SCK_PIN, HIGH);
- DELAY_NS(125); // Need more delay for fast CPUs
-
- b <<= 1; // little setup time
- b |= (READ(L6470_CHAIN_MISO_PIN) != 0);
- }
- DELAY_NS(125); // 10 cycles @ 84mhz
- return b;
- }
-
- /**
- * L64XX methods for SPI init and transfer
- */
- void L64XX_Marlin::spi_init() {
- OUT_WRITE(L6470_CHAIN_SS_PIN, HIGH);
- OUT_WRITE(L6470_CHAIN_SCK_PIN, HIGH);
- OUT_WRITE(L6470_CHAIN_MOSI_PIN, HIGH);
- SET_INPUT(L6470_CHAIN_MISO_PIN);
-
- #if PIN_EXISTS(L6470_BUSY)
- SET_INPUT(L6470_BUSY_PIN);
- #endif
-
- OUT_WRITE(L6470_CHAIN_MOSI_PIN, HIGH);
- }
-
- uint8_t L64XX_Marlin::transfer_single(uint8_t data, int16_t ss_pin) {
- // First device in chain has data sent last
- extDigitalWrite(ss_pin, LOW);
-
- DISABLE_ISRS(); // Disable interrupts during SPI transfer (can't allow partial command to chips)
- const uint8_t data_out = L6470_SpiTransfer_Mode_3(data);
- ENABLE_ISRS(); // Enable interrupts
-
- extDigitalWrite(ss_pin, HIGH);
- return data_out;
- }
-
- uint8_t L64XX_Marlin::transfer_chain(uint8_t data, int16_t ss_pin, uint8_t chain_position) {
- uint8_t data_out = 0;
-
- // first device in chain has data sent last
- extDigitalWrite(ss_pin, LOW);
-
- for (uint8_t i = L64XX::chain[0]; !L64xxManager.spi_abort && i >= 1; i--) { // Send data unless aborted
- DISABLE_ISRS(); // Disable interrupts during SPI transfer (can't allow partial command to chips)
- const uint8_t temp = L6470_SpiTransfer_Mode_3(uint8_t(i == chain_position ? data : dSPIN_NOP));
- ENABLE_ISRS(); // Enable interrupts
- if (i == chain_position) data_out = temp;
- }
-
- extDigitalWrite(ss_pin, HIGH);
- return data_out;
- }
-
- /**
- * Platform-supplied L6470 buffer transfer method
- */
- void L64XX_Marlin::transfer(uint8_t L6470_buf[], const uint8_t length) {
- // First device in chain has its data sent last
-
- if (spi_active) { // Interrupted SPI transfer so need to
- WRITE(L6470_CHAIN_SS_PIN, HIGH); // guarantee min high of 650ns
- DELAY_US(1);
- }
-
- WRITE(L6470_CHAIN_SS_PIN, LOW);
- for (uint8_t i = length; i >= 1; i--)
- L6470_SpiTransfer_Mode_3(uint8_t(L6470_buf[i]));
- WRITE(L6470_CHAIN_SS_PIN, HIGH);
- }
-
- #pragma GCC reset_options
-
- #endif // HAS_L64XX
|