STM32F1 USB cdc/msc composite device (#15180)
Co-Authored-By: bigtreetech <38851044+bigtreetech@users.noreply.github.com>
This commit is contained in:
		| @@ -82,7 +82,7 @@ | ||||
| // Public Variables | ||||
| // ------------------------ | ||||
|  | ||||
| #ifdef SERIAL_USB | ||||
| #if (!defined(SERIAL_USB) && !defined(USE_USB_COMPOSITE)) | ||||
|   USBSerial SerialUSB; | ||||
| #endif | ||||
|  | ||||
| @@ -215,6 +215,9 @@ void HAL_init(void) { | ||||
|   #if PIN_EXISTS(LED) | ||||
|     OUT_WRITE(LED_PIN, LOW); | ||||
|   #endif | ||||
|   #ifdef USE_USB_COMPOSITE | ||||
|     MSC_SD_init(); | ||||
|   #endif | ||||
|   #if PIN_EXISTS(USB_CONNECT) | ||||
|     OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING);  // USB clear connection | ||||
|     delay(1000);                                         // Give OS time to notice | ||||
| @@ -222,6 +225,24 @@ void HAL_init(void) { | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| // HAL idle task | ||||
| void HAL_idletask(void) { | ||||
|   #ifdef USE_USB_COMPOSITE | ||||
|     #if ENABLED(SHARED_SD_CARD) | ||||
|       // If Marlin is using the SD card we need to lock it to prevent access from | ||||
|       // a PC via USB. | ||||
|       // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but | ||||
|       // this will not reliably detect delete operations. To be safe we will lock | ||||
|       // the disk if Marlin has it mounted. Unfortuately there is currently no way | ||||
|       // to unmount the disk from the LCD menu. | ||||
|       // if (IS_SD_PRINTING() || IS_SD_FILE_OPEN()) | ||||
|       /* copy from lpc1768 framework, should be fixed later for process SHARED_SD_CARD*/ | ||||
|     #endif | ||||
|     // process USB mass storage device class loop | ||||
|     MarlinMSC.loop(); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| /* VGPV Done with defines | ||||
| // disable interrupts | ||||
| void cli(void) { noInterrupts(); } | ||||
|   | ||||
| @@ -42,21 +42,30 @@ | ||||
| #include <util/atomic.h> | ||||
|  | ||||
| #include "../../inc/MarlinConfigPre.h" | ||||
| #include "msc_sd.h" | ||||
|  | ||||
| // ------------------------ | ||||
| // Defines | ||||
| // ------------------------ | ||||
|  | ||||
| #ifdef SERIAL_USB | ||||
|   #ifndef USE_USB_COMPOSITE | ||||
|     #define UsbSerial Serial | ||||
|   #else | ||||
|     #define UsbSerial MarlinCompositeSerial | ||||
|   #endif | ||||
|   #define MSerial1  Serial1 | ||||
|   #define MSerial2  Serial2 | ||||
|   #define MSerial3  Serial3 | ||||
|   #define MSerial4  Serial4 | ||||
|   #define MSerial5  Serial5 | ||||
| #else | ||||
|   #ifndef USE_USB_COMPOSITE | ||||
|     extern USBSerial SerialUSB; | ||||
|     #define UsbSerial SerialUSB | ||||
|   #else | ||||
|     #define UsbSerial MarlinCompositeSerial | ||||
|   #endif | ||||
|   #define MSerial1  Serial | ||||
|   #define MSerial2  Serial1 | ||||
|   #define MSerial3  Serial2 | ||||
| @@ -111,6 +120,8 @@ | ||||
|  | ||||
| // Set interrupt grouping for this MCU | ||||
| void HAL_init(void); | ||||
| #define HAL_IDLETASK 1 | ||||
| void HAL_idletask(void); | ||||
|  | ||||
| /** | ||||
|  * TODO: review this to return 1 for pins that are not analog input | ||||
|   | ||||
| @@ -0,0 +1,56 @@ | ||||
| ; | ||||
| ; STMicroelectronics Communication Device Class driver installation file | ||||
| ; (C)2006 Copyright STMicroelectronics | ||||
| ; | ||||
|  | ||||
| [Version] | ||||
| Signature="$Windows NT$" | ||||
| Class=Ports | ||||
| ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} | ||||
| Provider=%STM% | ||||
| LayoutFile=layout.inf | ||||
|  | ||||
| [Manufacturer] | ||||
| %MFGNAME%=VirComDevice,NT,NTamd64 | ||||
|  | ||||
| [DestinationDirs] | ||||
| DefaultDestDir = 12 | ||||
|  | ||||
| [VirComDevice.NT] | ||||
| %DESCRIPTION%=DriverInstall,USB\VID_1EAF&PID_0029&MI_01 | ||||
| %DESCRIPTION%=DriverInstall,USB\VID_1EAF&PID_0029&MI_01 | ||||
|  | ||||
| [VirComDevice.NTamd64] | ||||
| %DESCRIPTION%=DriverInstall,USB\VID_1EAF&PID_0029&MI_01 | ||||
| %DESCRIPTION%=DriverInstall,USB\VID_1EAF&PID_0029&MI_01 | ||||
|  | ||||
| [DriverInstall.NT] | ||||
| Include=mdmcpq.inf | ||||
| CopyFiles=FakeModemCopyFileSection | ||||
| AddReg=DriverInstall.NT.AddReg | ||||
|  | ||||
| [DriverInstall.NT.AddReg] | ||||
| HKR,,DevLoader,,*ntkern | ||||
| HKR,,NTMPDriver,,usbser.sys | ||||
| HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" | ||||
|  | ||||
| [DriverInstall.NT.Services] | ||||
| AddService=usbser, 0x00000002, DriverServiceInst | ||||
|  | ||||
| [DriverServiceInst] | ||||
| DisplayName=%SERVICE% | ||||
| ServiceType=1 | ||||
| StartType=3 | ||||
| ErrorControl=1 | ||||
| ServiceBinary=%12%\usbser.sys | ||||
|  | ||||
| ;------------------------------------------------------------------------------ | ||||
| ;  String Definitions | ||||
| ;------------------------------------------------------------------------------ | ||||
|  | ||||
|  | ||||
| [Strings] | ||||
| STM         = "LeafLabs" | ||||
| MFGNAME     = "LeafLabs" | ||||
| DESCRIPTION = "Maple R3" | ||||
| SERVICE     = "USB Virtual COM port" | ||||
							
								
								
									
										64
									
								
								Marlin/src/HAL/HAL_STM32F1/msc_sd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Marlin/src/HAL/HAL_STM32F1/msc_sd.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * | ||||
|  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * 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 USE_USB_COMPOSITE | ||||
|  | ||||
| #include "msc_sd.h" | ||||
| #include "SPI.h" | ||||
|  | ||||
| #define PRODUCT_ID 0x29 | ||||
|  | ||||
| USBMassStorage MarlinMSC; | ||||
| USBCompositeSerial MarlinCompositeSerial; | ||||
|  | ||||
| #include "../../inc/MarlinConfig.h" | ||||
|  | ||||
| #ifdef HAS_ONBOARD_SD | ||||
|  | ||||
|   #include "onboard_sd.h" | ||||
|  | ||||
|   static bool MSC_Write(const uint8_t *writebuff, uint32_t startSector, uint16_t numSectors) { | ||||
|     return (disk_write(0, writebuff, startSector, numSectors) == RES_OK); | ||||
|   } | ||||
|   static bool MSC_Read(uint8_t *readbuff, uint32_t startSector, uint16_t numSectors) { | ||||
|     return (disk_read(0, readbuff, startSector, numSectors) == RES_OK); | ||||
|   } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| void MSC_SD_init() { | ||||
|   USBComposite.setProductId(PRODUCT_ID); | ||||
|   // Just set MarlinCompositeSerial enabled to true | ||||
|   // because when MarlinCompositeSerial.begin() is used in setup() | ||||
|   // it clears all USBComposite devices. | ||||
|   MarlinCompositeSerial.begin(); | ||||
|   USBComposite.end(); | ||||
|   USBComposite.clear(); | ||||
|   // Set api and register mass storage | ||||
|   #ifdef HAS_ONBOARD_SD | ||||
|     uint32_t cardSize; | ||||
|     if (disk_initialize(0) == RES_OK) { | ||||
|       if (disk_ioctl(0, GET_SECTOR_COUNT, (void *)(&cardSize)) == RES_OK) { | ||||
|         MarlinMSC.setDriveData(0, cardSize, MSC_Read, MSC_Write); | ||||
|         MarlinMSC.registerComponent(); | ||||
|       } | ||||
|     } | ||||
|   #endif | ||||
|   // Register composite Serial | ||||
|   MarlinCompositeSerial.registerComponent(); | ||||
|   USBComposite.begin(); | ||||
| } | ||||
|  | ||||
| #endif // USE_USB_COMPOSITE | ||||
							
								
								
									
										24
									
								
								Marlin/src/HAL/HAL_STM32F1/msc_sd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Marlin/src/HAL/HAL_STM32F1/msc_sd.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * | ||||
|  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <USBComposite.h> | ||||
|  | ||||
| extern USBMassStorage MarlinMSC; | ||||
| extern USBCompositeSerial MarlinCompositeSerial; | ||||
|  | ||||
| void MSC_SD_init(); | ||||
							
								
								
									
										558
									
								
								Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										558
									
								
								Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,558 @@ | ||||
| /*------------------------------------------------------------------------*/ | ||||
| /* STM32F1: MMCv3/SDv1/SDv2 (SPI mode) control module                     */ | ||||
| /*------------------------------------------------------------------------*/ | ||||
| /* | ||||
| / * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
| / * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] | ||||
| / * Copyright (C) 2015, ChaN, all right reserved. | ||||
| / | ||||
| / * This software is a free software and there is NO WARRANTY. | ||||
| / * No restriction on use. You can use, modify and redistribute it for | ||||
| /   personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. | ||||
| / * Redistributions of source code must retain the above copyright notice. | ||||
| / | ||||
| /-------------------------------------------------------------------------*/ | ||||
| #include "../../inc/MarlinConfig.h" | ||||
|  | ||||
| #ifdef HAS_ONBOARD_SD | ||||
|  | ||||
| #include "onboard_sd.h" | ||||
| #include "spi.h" | ||||
| #include "fastio.h" | ||||
|  | ||||
| #ifdef SHARED_SD_CARD | ||||
|   #ifndef ON_BOARD_SPI_DEVICE | ||||
|     #define ON_BOARD_SPI_DEVICE SPI_DEVICE | ||||
|   #endif | ||||
|   #define ONBOARD_SD_SPI SPI | ||||
| #else | ||||
|   SPIClass OnBoardSPI(ON_BOARD_SPI_DEVICE) | ||||
|   #define ONBOARD_SD_SPI OnBoardSPI | ||||
| #endif | ||||
|  | ||||
| #if ON_BOARD_SPI_DEVICE == 1 | ||||
|   #define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_4 | ||||
| #else | ||||
|   #define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2 | ||||
| #endif | ||||
|  | ||||
| #define CS_LOW()  {WRITE(ONBOARD_SD_CS_PIN, LOW);}  /* Set OnBoardSPI cs low */ | ||||
| #define CS_HIGH() {WRITE(ONBOARD_SD_CS_PIN, HIGH);} /* Set OnBoardSPI cs high */ | ||||
|  | ||||
| #define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX) | ||||
| #define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256) | ||||
|  | ||||
| /*-------------------------------------------------------------------------- | ||||
|    Module Private Functions | ||||
| ---------------------------------------------------------------------------*/ | ||||
|  | ||||
| #include "onboard_sd.h" | ||||
|  | ||||
| /* MMC/SD command */ | ||||
| #define CMD0  (0)     /* GO_IDLE_STATE */ | ||||
| #define CMD1  (1)     /* SEND_OP_COND (MMC) */ | ||||
| #define ACMD41  (0x80+41) /* SEND_OP_COND (SDC) */ | ||||
| #define CMD8  (8)     /* SEND_IF_COND */ | ||||
| #define CMD9  (9)     /* SEND_CSD */ | ||||
| #define CMD10 (10)    /* SEND_CID */ | ||||
| #define CMD12 (12)    /* STOP_TRANSMISSION */ | ||||
| #define ACMD13  (0x80+13) /* SD_STATUS (SDC) */ | ||||
| #define CMD16 (16)    /* SET_BLOCKLEN */ | ||||
| #define CMD17 (17)    /* READ_SINGLE_BLOCK */ | ||||
| #define CMD18 (18)    /* READ_MULTIPLE_BLOCK */ | ||||
| #define CMD23 (23)    /* SET_BLOCK_COUNT (MMC) */ | ||||
| #define ACMD23  (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */ | ||||
| #define CMD24 (24)    /* WRITE_BLOCK */ | ||||
| #define CMD25 (25)    /* WRITE_MULTIPLE_BLOCK */ | ||||
| #define CMD32 (32)    /* ERASE_ER_BLK_START */ | ||||
| #define CMD33 (33)    /* ERASE_ER_BLK_END */ | ||||
| #define CMD38 (38)    /* ERASE */ | ||||
| #define CMD48 (48)    /* READ_EXTR_SINGLE */ | ||||
| #define CMD49 (49)    /* WRITE_EXTR_SINGLE */ | ||||
| #define CMD55 (55)    /* APP_CMD */ | ||||
| #define CMD58 (58)    /* READ_OCR */ | ||||
|  | ||||
| static volatile DSTATUS Stat = STA_NOINIT;  /* Physical drive status */ | ||||
| static volatile UINT timeout; | ||||
| static BYTE CardType;      /* Card type flags */ | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Send/Receive data to the MMC  (Platform dependent)                    */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| /* Exchange a byte */ | ||||
| static BYTE xchg_spi ( | ||||
|   BYTE dat  /* Data to send */ | ||||
| ) { | ||||
|   BYTE returnByte = ONBOARD_SD_SPI.transfer(dat); | ||||
|   return returnByte; | ||||
| } | ||||
|  | ||||
| /* Receive multiple byte */ | ||||
| static void rcvr_spi_multi ( | ||||
|   BYTE *buff,   /* Pointer to data buffer */ | ||||
|   UINT btr    /* Number of bytes to receive (16, 64 or 512) */ | ||||
| ) { | ||||
|   ONBOARD_SD_SPI.dmaTransfer(0, const_cast<uint8_t*>(buff), btr); | ||||
| } | ||||
|  | ||||
| #if _DISKIO_WRITE | ||||
|  | ||||
|   /* Send multiple bytes */ | ||||
|   static void xmit_spi_multi ( | ||||
|     const BYTE *buff, /* Pointer to the data */ | ||||
|     UINT btx      /* Number of bytes to send (multiple of 16) */ | ||||
|   ) { | ||||
|     ONBOARD_SD_SPI.dmaSend(const_cast<uint8_t*>(buff), btx); | ||||
|   } | ||||
|  | ||||
| #endif // _DISKIO_WRITE | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Wait for card ready                                                   */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| static int wait_ready (  /* 1:Ready, 0:Timeout */ | ||||
|   UINT wt     /* Timeout [ms] */ | ||||
| ) { | ||||
|   BYTE d; | ||||
|  | ||||
|   timeout = millis() + wt; | ||||
|   do { | ||||
|     d = xchg_spi(0xFF); | ||||
|     /* This loop takes a while. Insert rot_rdq() here for multitask environment. */ | ||||
|   } while (d != 0xFF && (timeout > millis()));  /* Wait for card goes ready or timeout */ | ||||
|  | ||||
|   return (d == 0xFF) ? 1 : 0; | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Deselect card and release SPI                                         */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| static void deselect(void) { | ||||
|   CS_HIGH();    /* CS = H */ | ||||
|   xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */ | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Select card and wait for ready                                        */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| static int select(void) { /* 1:OK, 0:Timeout */ | ||||
|   CS_LOW();   /* CS = L */ | ||||
|   xchg_spi(0xFF); /* Dummy clock (force DO enabled) */ | ||||
|  | ||||
|   if (wait_ready(500)) return 1;  /* Leading busy check: Wait for card ready */ | ||||
|  | ||||
|   deselect();   /* Timeout */ | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Control SPI module (Platform dependent)                               */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| static void power_on(void) {  /* Enable SSP module and attach it to I/O pads */ | ||||
|   ONBOARD_SD_SPI.setModule(ON_BOARD_SPI_DEVICE); | ||||
|   ONBOARD_SD_SPI.begin(); | ||||
|   ONBOARD_SD_SPI.setBitOrder(MSBFIRST); | ||||
|   ONBOARD_SD_SPI.setDataMode(SPI_MODE0); | ||||
|   OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH); /* Set CS# high */ | ||||
| } | ||||
|  | ||||
| static void power_off(void) {   /* Disable SPI function */ | ||||
|   select();       /* Wait for card ready */ | ||||
|   deselect(); | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Receive a data packet from the MMC                                    */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| static int rcvr_datablock (  /* 1:OK, 0:Error */ | ||||
|   BYTE *buff,     /* Data buffer */ | ||||
|   UINT btr      /* Data block length (byte) */ | ||||
| ) { | ||||
|   BYTE token; | ||||
|  | ||||
|   timeout = millis() + 200; | ||||
|   do {              /* Wait for DataStart token in timeout of 200ms */ | ||||
|     token = xchg_spi(0xFF); | ||||
|     /* This loop will take a while. Insert rot_rdq() here for multitask environment. */ | ||||
|   } while ((token == 0xFF) && (timeout > millis())); | ||||
|   if (token != 0xFE) return 0;   /* Function fails if invalid DataStart token or timeout */ | ||||
|  | ||||
|   rcvr_spi_multi(buff, btr);    /* Store trailing data to the buffer */ | ||||
|   xchg_spi(0xFF); xchg_spi(0xFF); /* Discard CRC */ | ||||
|  | ||||
|   return 1;           /* Function succeeded */ | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Send a data packet to the MMC                                         */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| #if _DISKIO_WRITE | ||||
|  | ||||
|   static int xmit_datablock (  /* 1:OK, 0:Failed */ | ||||
|     const BYTE *buff, /* Ponter to 512 byte data to be sent */ | ||||
|     BYTE token      /* Token */ | ||||
|   ) { | ||||
|     BYTE resp; | ||||
|  | ||||
|     if (!wait_ready(500)) return 0;   /* Leading busy check: Wait for card ready to accept data block */ | ||||
|  | ||||
|     xchg_spi(token);          /* Send token */ | ||||
|     if (token == 0xFD) return 1;    /* Do not send data if token is StopTran */ | ||||
|  | ||||
|     xmit_spi_multi(buff, 512);      /* Data */ | ||||
|     xchg_spi(0xFF); xchg_spi(0xFF);   /* Dummy CRC */ | ||||
|  | ||||
|     resp = xchg_spi(0xFF);        /* Receive data resp */ | ||||
|  | ||||
|     return (resp & 0x1F) == 0x05 ? 1 : 0; /* Data was accepted or not */ | ||||
|  | ||||
|     /* Busy check is done at next transmission */ | ||||
|   } | ||||
|  | ||||
| #endif // _DISKIO_WRITE | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Send a command packet to the MMC                                      */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| static BYTE send_cmd (   /* Return value: R1 resp (bit7==1:Failed to send) */ | ||||
|   BYTE cmd,   /* Command index */ | ||||
|   DWORD arg   /* Argument */ | ||||
| ) { | ||||
|   BYTE n, res; | ||||
|  | ||||
|   if (cmd & 0x80) { /* Send a CMD55 prior to ACMD<n> */ | ||||
|     cmd &= 0x7F; | ||||
|     res = send_cmd(CMD55, 0); | ||||
|     if (res > 1) return res; | ||||
|   } | ||||
|  | ||||
|   /* Select the card and wait for ready except to stop multiple block read */ | ||||
|   if (cmd != CMD12) { | ||||
|     deselect(); | ||||
|     if (!select()) return 0xFF; | ||||
|   } | ||||
|  | ||||
|   /* Send command packet */ | ||||
|   xchg_spi(0x40 | cmd);       /* Start + command index */ | ||||
|   xchg_spi((BYTE)(arg >> 24));    /* Argument[31..24] */ | ||||
|   xchg_spi((BYTE)(arg >> 16));    /* Argument[23..16] */ | ||||
|   xchg_spi((BYTE)(arg >> 8));     /* Argument[15..8] */ | ||||
|   xchg_spi((BYTE)arg);        /* Argument[7..0] */ | ||||
|   n = 0x01;             /* Dummy CRC + Stop */ | ||||
|   if (cmd == CMD0) n = 0x95;      /* Valid CRC for CMD0(0) */ | ||||
|   if (cmd == CMD8) n = 0x87;      /* Valid CRC for CMD8(0x1AA) */ | ||||
|   xchg_spi(n); | ||||
|  | ||||
|   /* Receive command resp */ | ||||
|   if (cmd == CMD12) xchg_spi(0xFF); /* Diacard following one byte when CMD12 */ | ||||
|   n = 10;               /* Wait for response (10 bytes max) */ | ||||
|   do | ||||
|     res = xchg_spi(0xFF); | ||||
|   while ((res & 0x80) && --n); | ||||
|  | ||||
|   return res;             /* Return received response */ | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------- | ||||
|    Public Functions | ||||
| ---------------------------------------------------------------------------*/ | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Initialize disk drive                                                 */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| DSTATUS disk_initialize ( | ||||
|   BYTE drv    /* Physical drive number (0) */ | ||||
| ) { | ||||
|   BYTE n, cmd, ty, ocr[4]; | ||||
|  | ||||
|   if (drv) return STA_NOINIT;     /* Supports only drive 0 */ | ||||
|   power_on();             /* Initialize SPI */ | ||||
|  | ||||
|   if (Stat & STA_NODISK) return Stat; /* Is a card existing in the soket? */ | ||||
|  | ||||
|   FCLK_SLOW(); | ||||
|   for (n = 10; n; n--) xchg_spi(0xFF);  /* Send 80 dummy clocks */ | ||||
|  | ||||
|   ty = 0; | ||||
|   if (send_cmd(CMD0, 0) == 1) {     /* Put the card SPI state */ | ||||
|     timeout = millis() + 1000;            /* Initialization timeout = 1 sec */ | ||||
|     if (send_cmd(CMD8, 0x1AA) == 1) { /* Is the catd SDv2? */ | ||||
|       for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);  /* Get 32 bit return value of R7 resp */ | ||||
|       if (ocr[2] == 0x01 && ocr[3] == 0xAA) {       /* Does the card support 2.7-3.6V? */ | ||||
|         while ((timeout > millis()) && send_cmd(ACMD41, 1UL << 30)) ; /* Wait for end of initialization with ACMD41(HCS) */ | ||||
|         if ((timeout > millis()) && send_cmd(CMD58, 0) == 0) {    /* Check CCS bit in the OCR */ | ||||
|           for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); | ||||
|           ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;  /* Check if the card is SDv2 */ | ||||
|         } | ||||
|       } | ||||
|     } else {  /* Not an SDv2 card */ | ||||
|       if (send_cmd(ACMD41, 0) <= 1)   { /* SDv1 or MMCv3? */ | ||||
|         ty = CT_SD1; cmd = ACMD41;  /* SDv1 (ACMD41(0)) */ | ||||
|       } else { | ||||
|         ty = CT_MMC; cmd = CMD1;  /* MMCv3 (CMD1(0)) */ | ||||
|       } | ||||
|       while ((timeout > millis()) && send_cmd(cmd, 0)) ;    /* Wait for the card leaves idle state */ | ||||
|       if (!(timeout > millis()) || send_cmd(CMD16, 512) != 0) /* Set block length: 512 */ | ||||
|         ty = 0; | ||||
|     } | ||||
|   } | ||||
|   CardType = ty;  /* Card type */ | ||||
|   deselect(); | ||||
|  | ||||
|   if (ty) {   /* OK */ | ||||
|     FCLK_FAST();      /* Set fast clock */ | ||||
|     Stat &= ~STA_NOINIT;  /* Clear STA_NOINIT flag */ | ||||
|   } else {    /* Failed */ | ||||
|     power_off(); | ||||
|     Stat = STA_NOINIT; | ||||
|   } | ||||
|  | ||||
|   return Stat; | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Get disk status                                                       */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| DSTATUS disk_status ( | ||||
|   BYTE drv    /* Physical drive number (0) */ | ||||
| ) { | ||||
|   if (drv) return STA_NOINIT;   /* Supports only drive 0 */ | ||||
|   return Stat;  /* Return disk status */ | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Read sector(s)                                                        */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| DRESULT disk_read ( | ||||
|   BYTE drv,   /* Physical drive number (0) */ | ||||
|   BYTE *buff,   /* Pointer to the data buffer to store read data */ | ||||
|   DWORD sector, /* Start sector number (LBA) */ | ||||
|   UINT count    /* Number of sectors to read (1..128) */ | ||||
| ) { | ||||
|   BYTE cmd; | ||||
|  | ||||
|   if (drv || !count) return RES_PARERR;   /* Check parameter */ | ||||
|   if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */ | ||||
|   if (!(CardType & CT_BLOCK)) sector *= 512;  /* LBA ot BA conversion (byte addressing cards) */ | ||||
|   FCLK_FAST(); | ||||
|   cmd = count > 1 ? CMD18 : CMD17;      /*  READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */ | ||||
|   if (send_cmd(cmd, sector) == 0) { | ||||
|     do { | ||||
|       if (!rcvr_datablock(buff, 512)) break; | ||||
|       buff += 512; | ||||
|     } while (--count); | ||||
|     if (cmd == CMD18) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ | ||||
|   } | ||||
|   deselect(); | ||||
|  | ||||
|   return count ? RES_ERROR : RES_OK;  /* Return result */ | ||||
| } | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Write sector(s)                                                       */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| #if _DISKIO_WRITE | ||||
|  | ||||
|   DRESULT disk_write( | ||||
|     BYTE drv,     /* Physical drive number (0) */ | ||||
|     const BYTE *buff, /* Ponter to the data to write */ | ||||
|     DWORD sector,   /* Start sector number (LBA) */ | ||||
|     UINT count      /* Number of sectors to write (1..128) */ | ||||
|   ) { | ||||
|     if (drv || !count) return RES_PARERR;   /* Check parameter */ | ||||
|     if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */ | ||||
|     if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protect */ | ||||
|     FCLK_FAST(); | ||||
|     if (!(CardType & CT_BLOCK)) sector *= 512;  /* LBA ==> BA conversion (byte addressing cards) */ | ||||
|  | ||||
|     if (count == 1) { /* Single sector write */ | ||||
|       if ((send_cmd(CMD24, sector) == 0)  /* WRITE_BLOCK */ | ||||
|         && xmit_datablock(buff, 0xFE)) { | ||||
|         count = 0; | ||||
|       } | ||||
|     } | ||||
|     else {        /* Multiple sector write */ | ||||
|       if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */ | ||||
|       if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ | ||||
|         do { | ||||
|           if (!xmit_datablock(buff, 0xFC)) break; | ||||
|           buff += 512; | ||||
|         } while (--count); | ||||
|         if (!xmit_datablock(0, 0xFD)) count = 1;  /* STOP_TRAN token */ | ||||
|       } | ||||
|     } | ||||
|     deselect(); | ||||
|  | ||||
|     return count ? RES_ERROR : RES_OK;  /* Return result */ | ||||
|   } | ||||
|  | ||||
| #endif // _DISKIO_WRITE | ||||
|  | ||||
| /*-----------------------------------------------------------------------*/ | ||||
| /* Miscellaneous drive controls other than data read/write               */ | ||||
| /*-----------------------------------------------------------------------*/ | ||||
|  | ||||
| #if _DISKIO_IOCTL | ||||
|  | ||||
|   DRESULT disk_ioctl ( | ||||
|     BYTE drv,   /* Physical drive number (0) */ | ||||
|     BYTE cmd,   /* Control command code */ | ||||
|     void *buff    /* Pointer to the conrtol data */ | ||||
|   ) { | ||||
|     DRESULT res; | ||||
|     BYTE n, csd[16], *ptr = (BYTE *)buff; | ||||
|     DWORD *dp, st, ed, csize; | ||||
|     #if _DISKIO_ISDIO | ||||
|       SDIO_CMD *sdio = buff; | ||||
|       BYTE rc, *buf; | ||||
|       UINT dc; | ||||
|     #endif | ||||
|  | ||||
|     if (drv) return RES_PARERR;         /* Check parameter */ | ||||
|     if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */ | ||||
|  | ||||
|     res = RES_ERROR; | ||||
|     FCLK_FAST(); | ||||
|     switch (cmd) { | ||||
|       case CTRL_SYNC:     /* Wait for end of internal write process of the drive */ | ||||
|         if (select()) res = RES_OK; | ||||
|         break; | ||||
|  | ||||
|       case GET_SECTOR_COUNT:  /* Get drive capacity in unit of sector (DWORD) */ | ||||
|         if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { | ||||
|           if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */ | ||||
|             csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1; | ||||
|             *(DWORD*)buff = csize << 10; | ||||
|           } else {          /* SDC ver 1.XX or MMC ver 3 */ | ||||
|             n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; | ||||
|             csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; | ||||
|             *(DWORD*)buff = csize << (n - 9); | ||||
|           } | ||||
|           res = RES_OK; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       case GET_BLOCK_SIZE:  /* Get erase block size in unit of sector (DWORD) */ | ||||
|         if (CardType & CT_SD2) {  /* SDC ver 2.00 */ | ||||
|           if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ | ||||
|             xchg_spi(0xFF); | ||||
|             if (rcvr_datablock(csd, 16)) {        /* Read partial block */ | ||||
|               for (n = 64 - 16; n; n--) xchg_spi(0xFF); /* Purge trailing data */ | ||||
|               *(DWORD*)buff = 16UL << (csd[10] >> 4); | ||||
|               res = RES_OK; | ||||
|             } | ||||
|           } | ||||
|         } else {          /* SDC ver 1.XX or MMC */ | ||||
|           if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {  /* Read CSD */ | ||||
|             if (CardType & CT_SD1) {  /* SDC ver 1.XX */ | ||||
|               *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); | ||||
|             } else {          /* MMC */ | ||||
|               *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); | ||||
|             } | ||||
|             res = RES_OK; | ||||
|           } | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       case CTRL_TRIM:   /* Erase a block of sectors (used when _USE_TRIM in ffconf.h is 1) */ | ||||
|         if (!(CardType & CT_SDC)) break;        /* Check if the card is SDC */ | ||||
|         if (disk_ioctl(drv, MMC_GET_CSD, csd)) break; /* Get CSD */ | ||||
|         if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; /* Check if sector erase can be applied to the card */ | ||||
|         dp = (DWORD *)buff; st = dp[0]; ed = dp[1];       /* Load sector block */ | ||||
|         if (!(CardType & CT_BLOCK)) { | ||||
|           st *= 512; ed *= 512; | ||||
|         } | ||||
|         if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { /* Erase sector block */ | ||||
|           res = RES_OK; /* FatFs does not check result of this command */ | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       /* Following commands are never used by FatFs module */ | ||||
|  | ||||
|       case MMC_GET_TYPE:    /* Get MMC/SDC type (BYTE) */ | ||||
|         *ptr = CardType; | ||||
|         res = RES_OK; | ||||
|         break; | ||||
|  | ||||
|       case MMC_GET_CSD:   /* Read CSD (16 bytes) */ | ||||
|         if (send_cmd(CMD9, 0) == 0 && rcvr_datablock(ptr, 16)) {  /* READ_CSD */ | ||||
|           res = RES_OK; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       case MMC_GET_CID:   /* Read CID (16 bytes) */ | ||||
|         if (send_cmd(CMD10, 0) == 0 && rcvr_datablock(ptr, 16)) { /* READ_CID */ | ||||
|           res = RES_OK; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       case MMC_GET_OCR:   /* Read OCR (4 bytes) */ | ||||
|         if (send_cmd(CMD58, 0) == 0) {  /* READ_OCR */ | ||||
|           for (n = 4; n; n--) *ptr++ = xchg_spi(0xFF); | ||||
|           res = RES_OK; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       case MMC_GET_SDSTAT:  /* Read SD status (64 bytes) */ | ||||
|         if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ | ||||
|           xchg_spi(0xFF); | ||||
|           if (rcvr_datablock(ptr, 64)) res = RES_OK; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|       #if _DISKIO_ISDIO | ||||
|  | ||||
|         case ISDIO_READ: | ||||
|           sdio = buff; | ||||
|           if (send_cmd(CMD48, 0x80000000 | sdio->func << 28 | sdio->addr << 9 | ((sdio->ndata - 1) & 0x1FF)) == 0) { | ||||
|             for (Timer1 = 1000; (rc = xchg_spi(0xFF)) == 0xFF && Timer1; ) ; | ||||
|             if (rc == 0xFE) { | ||||
|               for (buf = sdio->data, dc = sdio->ndata; dc; dc--) *buf++ = xchg_spi(0xFF); | ||||
|               for (dc = 514 - sdio->ndata; dc; dc--) xchg_spi(0xFF); | ||||
|               res = RES_OK; | ||||
|             } | ||||
|           } | ||||
|           break; | ||||
|         case ISDIO_WRITE: | ||||
|           sdio = buff; | ||||
|           if (send_cmd(CMD49, 0x80000000 | sdio->func << 28 | sdio->addr << 9 | ((sdio->ndata - 1) & 0x1FF)) == 0) { | ||||
|             xchg_spi(0xFF); xchg_spi(0xFE); | ||||
|             for (buf = sdio->data, dc = sdio->ndata; dc; dc--) xchg_spi(*buf++); | ||||
|             for (dc = 514 - sdio->ndata; dc; dc--) xchg_spi(0xFF); | ||||
|             if ((xchg_spi(0xFF) & 0x1F) == 0x05) res = RES_OK; | ||||
|           } | ||||
|           break; | ||||
|         case ISDIO_MRITE: | ||||
|           sdio = buff; | ||||
|           if (send_cmd(CMD49, 0x84000000 | sdio->func << 28 | sdio->addr << 9 | sdio->ndata >> 8) == 0) { | ||||
|             xchg_spi(0xFF); xchg_spi(0xFE); | ||||
|             xchg_spi(sdio->ndata); | ||||
|             for (dc = 513; dc; dc--) xchg_spi(0xFF); | ||||
|             if ((xchg_spi(0xFF) & 0x1F) == 0x05) res = RES_OK; | ||||
|           } | ||||
|           break; | ||||
|  | ||||
|       #endif // _DISKIO_ISDIO | ||||
|  | ||||
|       default: res = RES_PARERR; | ||||
|     } | ||||
|  | ||||
|     deselect(); | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
| #endif // _DISKIO_IOCTL | ||||
|  | ||||
| #endif // HAS_ONBOARD_SD | ||||
							
								
								
									
										96
									
								
								Marlin/src/HAL/HAL_STM32F1/onboard_sd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								Marlin/src/HAL/HAL_STM32F1/onboard_sd.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /*----------------------------------------------------------------------- | ||||
| / * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
| / * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] | ||||
| / * Low level disk interface module include file   (C)ChaN, 2015 | ||||
| /-----------------------------------------------------------------------*/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #define _DISKIO_WRITE   1   /* 1: Enable disk_write function */ | ||||
| #define _DISKIO_IOCTL   1   /* 1: Enable disk_ioctl fucntion */ | ||||
| #define _DISKIO_ISDIO   0   /* 1: Enable iSDIO control fucntion */ | ||||
|  | ||||
| typedef unsigned char BYTE; | ||||
| typedef unsigned short WORD; | ||||
| typedef unsigned long DWORD; | ||||
| typedef unsigned int UINT; | ||||
|  | ||||
| /* Status of Disk Functions */ | ||||
| typedef BYTE    DSTATUS; | ||||
|  | ||||
| /* Results of Disk Functions */ | ||||
| typedef enum { | ||||
|   RES_OK = 0,     /* 0: Successful */ | ||||
|   RES_ERROR,      /* 1: R/W Error */ | ||||
|   RES_WRPRT,      /* 2: Write Protected */ | ||||
|   RES_NOTRDY,     /* 3: Not Ready */ | ||||
|   RES_PARERR      /* 4: Invalid Parameter */ | ||||
| } DRESULT; | ||||
|  | ||||
|  | ||||
| #if _DISKIO_ISDIO | ||||
| /* Command structure for iSDIO ioctl command */ | ||||
| typedef struct { | ||||
|  BYTE    func;   /* Function number: 0..7 */ | ||||
|  WORD    ndata;  /* Number of bytes to transfer: 1..512, or mask + data */ | ||||
|  DWORD   addr;   /* Register address: 0..0x1FFFF */ | ||||
|  void*   data;   /* Pointer to the data (to be written | read buffer) */ | ||||
| } SDIO_CMD; | ||||
| #endif | ||||
|  | ||||
| /*---------------------------------------*/ | ||||
| /* Prototypes for disk control functions */ | ||||
|  | ||||
| DSTATUS disk_initialize(BYTE pdrv); | ||||
| DSTATUS disk_status(BYTE pdrv); | ||||
| DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count); | ||||
| #if _DISKIO_WRITE | ||||
|   DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); | ||||
| #endif | ||||
| #if _DISKIO_IOCTL | ||||
|   DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff); | ||||
| #endif | ||||
|  | ||||
| /* Disk Status Bits (DSTATUS) */ | ||||
| #define STA_NOINIT      0x01    /* Drive not initialized */ | ||||
| #define STA_NODISK      0x02    /* No medium in the drive */ | ||||
| #define STA_PROTECT     0x04    /* Write protected */ | ||||
|  | ||||
| /* Command code for disk_ioctrl fucntion */ | ||||
|  | ||||
| /* Generic command (Used by FatFs) */ | ||||
| #define CTRL_SYNC        0  /* Complete pending write process (needed at _FS_READONLY == 0) */ | ||||
| #define GET_SECTOR_COUNT 1  /* Get media size (needed at _USE_MKFS == 1) */ | ||||
| #define GET_SECTOR_SIZE  2  /* Get sector size (needed at _MAX_SS != _MIN_SS) */ | ||||
| #define GET_BLOCK_SIZE   3  /* Get erase block size (needed at _USE_MKFS == 1) */ | ||||
| #define CTRL_TRIM        4  /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ | ||||
|  | ||||
| /* Generic command (Not used by FatFs) */ | ||||
| #define CTRL_FORMAT      5  /* Create physical format on the media */ | ||||
| #define CTRL_POWER_IDLE  6  /* Put the device idle state */ | ||||
| #define CTRL_POWER_OFF   7  /* Put the device off state */ | ||||
| #define CTRL_LOCK        8  /* Lock media removal */ | ||||
| #define CTRL_UNLOCK      9  /* Unlock media removal */ | ||||
| #define CTRL_EJECT      10  /* Eject media */ | ||||
|  | ||||
| /* MMC/SDC specific ioctl command (Not used by FatFs) */ | ||||
| #define MMC_GET_TYPE    50  /* Get card type */ | ||||
| #define MMC_GET_CSD     51  /* Get CSD */ | ||||
| #define MMC_GET_CID     52  /* Get CID */ | ||||
| #define MMC_GET_OCR     53  /* Get OCR */ | ||||
| #define MMC_GET_SDSTAT  54  /* Get SD status */ | ||||
| #define ISDIO_READ      55  /* Read data form SD iSDIO register */ | ||||
| #define ISDIO_WRITE     56  /* Write data to SD iSDIO register */ | ||||
| #define ISDIO_MRITE     57  /* Masked write data to SD iSDIO register */ | ||||
|  | ||||
| /* ATA/CF specific ioctl command (Not used by FatFs) */ | ||||
| #define ATA_GET_REV     60  /* Get F/W revision */ | ||||
| #define ATA_GET_MODEL   61  /* Get model name */ | ||||
| #define ATA_GET_SN      62  /* Get serial number */ | ||||
|  | ||||
| /* MMC card type flags (MMC_GET_TYPE) */ | ||||
| #define CT_MMC      0x01        /* MMC ver 3 */ | ||||
| #define CT_SD1      0x02        /* SD ver 1 */ | ||||
| #define CT_SD2      0x04        /* SD ver 2 */ | ||||
| #define CT_SDC      (CT_SD1|CT_SD2) /* SD */ | ||||
| #define CT_BLOCK    0x08        /* Block addressing */ | ||||
| @@ -187,3 +187,15 @@ | ||||
|   #endif | ||||
|  | ||||
| #endif // HAS_SPI_LCD | ||||
|  | ||||
| // | ||||
| // SD Support | ||||
| // | ||||
| #define HAS_ONBOARD_SD | ||||
|  | ||||
| #ifndef SDCARD_CONNECTION | ||||
|   #define SDCARD_CONNECTION ONBOARD | ||||
| #endif | ||||
|  | ||||
| #define ON_BOARD_SPI_DEVICE 1    //SPI1 | ||||
| #define ONBOARD_SD_CS_PIN  PA4   // Chip select for "System" SD card | ||||
|   | ||||
| @@ -142,3 +142,15 @@ | ||||
|   #endif | ||||
|  | ||||
| #endif // HAS_SPI_LCD | ||||
|  | ||||
| // | ||||
| // SD Support | ||||
| // | ||||
| #define HAS_ONBOARD_SD | ||||
|  | ||||
| #ifndef SDCARD_CONNECTION | ||||
|   #define SDCARD_CONNECTION ONBOARD | ||||
| #endif | ||||
|  | ||||
| #define ON_BOARD_SPI_DEVICE 1    //SPI1 | ||||
| #define ONBOARD_SD_CS_PIN  PA4   // Chip select for "System" SD card | ||||
|   | ||||
| @@ -160,20 +160,20 @@ | ||||
| // | ||||
|  | ||||
| // By default the onboard SD is enabled. | ||||
| // To disable it and use an external SD (connected to LCD) | ||||
| // enable STM32_SD_LCD. | ||||
| // set SDCARD_CONNECTION form 'ONBOARD' to 'LCD' and use an external SD (connected to LCD) | ||||
| #define HAS_ONBOARD_SD | ||||
| #ifndef SDCARD_CONNECTION | ||||
|   #define SDCARD_CONNECTION ONBOARD | ||||
| #endif | ||||
|  | ||||
| //#define STM32_SD_LCD | ||||
|  | ||||
| #if ENABLED(STM32_SD_LCD) | ||||
| #if SD_CONNECTION_IS(LCD) | ||||
|   #define ENABLE_SPI3 | ||||
|   #define SD_DETECT_PIN    PB9 | ||||
|   #define SCK_PIN          PB3 | ||||
|   #define MISO_PIN         PB4 | ||||
|   #define MOSI_PIN         PB5 | ||||
|   #define SS_PIN           PA15 | ||||
| #else | ||||
|   #define SDCARD_CONNECTION ONBOARD | ||||
| #if SD_CONNECTION_IS(ONBOARD) | ||||
|   #define ENABLE_SPI1 | ||||
|   #define SD_DETECT_PIN    PA3 | ||||
|   #define SCK_PIN          PA5 | ||||
| @@ -181,6 +181,8 @@ | ||||
|   #define MOSI_PIN         PA7 | ||||
|   #define SS_PIN           PA4 | ||||
| #endif | ||||
| #define ON_BOARD_SPI_DEVICE 1    //SPI1 | ||||
| #define ONBOARD_SD_CS_PIN  PA4   // Chip select for "System" SD card | ||||
|  | ||||
| #ifndef ST7920_DELAY_1 | ||||
|   #define ST7920_DELAY_1 DELAY_NS(125) | ||||
|   | ||||
| @@ -77,7 +77,7 @@ | ||||
| #define UHS_VID_OPTI 0x03fbU // OPTi, Inc. | ||||
| #define UHS_VID_ELITEGROUP_COMPUTER_SYSTEMS 0x03fcU // Elitegroup Computer Systems | ||||
| #define UHS_VID_XILINX 0x03fdU // Xilinx, Inc. | ||||
| #define UHS_VID_FARALLON_COMUNICATIONS 0x03feU // Farallon Comunications | ||||
| #define UHS_VID_FARALLON_COMUNICATIONS 0x03feU // Farallon Communications | ||||
| #define UHS_VID_NATIONAL_SEMICONDUCTOR 0x0400U // National Semiconductor Corp. | ||||
| #define UHS_VID_NATIONAL_REGISTRY 0x0401U // National Registry, Inc. | ||||
| #define UHS_VID_ALI 0x0402U // ALi Corp. | ||||
|   | ||||
| @@ -304,7 +304,7 @@ platform_packages = tool-stm32duino | ||||
| extra_scripts     = buildroot/share/PlatformIO/scripts/STM32F1_SKR_MINI.py | ||||
| build_flags       = !python Marlin/src/HAL/HAL_STM32F1/build_flags.py | ||||
|   ${common.build_flags} -std=gnu++14 | ||||
|   -DDEBUG_LEVEL=0 | ||||
|   -DDEBUG_LEVEL=0 -DUSE_USB_COMPOSITE | ||||
| build_unflags     = -std=gnu++11 | ||||
| lib_deps          = ${common.lib_deps} | ||||
| lib_ignore        = Adafruit NeoPixel, SPI | ||||
|   | ||||
		Reference in New Issue
	
	Block a user