From 4cdb84a6225ecad39d3d448b4446a49bab68cafa Mon Sep 17 00:00:00 2001 From: Frank Voorburg Date: Mon, 6 Mar 2017 10:35:37 +0000 Subject: [PATCH] Refs #285. Removed FatFS from STM32F103 Nucleo demo bootloader. git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@210 5dc33758-31d5-4daf-9ae8-b24bf3d40d73 --- .../openblt_demoprog_nucleo_stm32f103rb.elf | Bin 97970 -> 98170 bytes .../openblt_demoprog_nucleo_stm32f103rb.map | 140 ++-- .../openblt_demoprog_nucleo_stm32f103rb.srec | 479 ++++++------ .../Boot/blt_conf.h | 36 - .../Boot/lib/fatfs/ffconf.h | 192 ----- .../Boot/lib/fatfs/mmc.c | 683 ------------------ .../Boot/makefile | 7 - 7 files changed, 310 insertions(+), 1227 deletions(-) delete mode 100644 Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/lib/fatfs/ffconf.h delete mode 100644 Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/lib/fatfs/mmc.c diff --git a/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/bin/openblt_demoprog_nucleo_stm32f103rb.elf b/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/bin/openblt_demoprog_nucleo_stm32f103rb.elf index 0cf1791983d12905376ab67ee4501a3cdbe49607..ca5ccd4f83ca4465082f553114b7c6b8531773d9 100644 GIT binary patch literal 98170 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 literal 97970 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:Enable */ -/* To enable file lock control feature, set _FS_LOCK to 1 or greater. - The value defines how many files can be opened simultaneously. */ - - -#endif /* _FFCONFIG */ diff --git a/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/lib/fatfs/mmc.c b/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/lib/fatfs/mmc.c deleted file mode 100644 index 5fe89a9b..00000000 --- a/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/lib/fatfs/mmc.c +++ /dev/null @@ -1,683 +0,0 @@ -/*------------------------------------------------------------------------/ -/ MMCv3/SDv1/SDv2 (in SPI mode) control module -/-------------------------------------------------------------------------/ -/ -/ Copyright (C) 2013, 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. -/ -/-------------------------------------------------------------------------*/ - - -/* - * This file was modified from a sample available from the FatFs - * web site. It was modified to work with a Olimex STM32-P103 - * evaluation board. - * - */ -#include "diskio.h" -#include "stm32f10x.h" /* STM32 registers */ -#include "stm32f10x_conf.h" /* STM32 peripheral drivers */ -#include "boot.h" - - - -/*-------------------------------------------------------------------------- - - Module Private Functions - ----------------------------------------------------------------------------*/ - -/* Definitions for MMC/SDC command */ -#define CMD0 (0) /* GO_IDLE_STATE */ -#define CMD1 (1) /* SEND_OP_COND */ -#define ACMD41 (41|0x80) /* 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 (13|0x80) /* 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 */ -#define ACMD23 (23|0x80) /* SET_WR_BLK_ERASE_COUNT (SDC) */ -#define CMD24 (24) /* WRITE_BLOCK */ -#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */ -#define CMD41 (41) /* SEND_OP_COND (ACMD) */ -#define CMD55 (55) /* APP_CMD */ -#define CMD58 (58) /* READ_OCR */ - - -/* Control signals (Platform dependent) */ -#define CS_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_12) /* MMC CS = L */ -#define CS_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_12) /* MMC CS = H */ - - - -#define FCLK_SLOW() /* Set slow clock (100k-400k) */ -#define FCLK_FAST() set_max_speed() /* Set fast clock (depends on the CSD) */ - -static volatile -DSTATUS Stat = STA_NOINIT; /* Disk status */ - -static -UINT CardType; - - -/*-----------------------------------------------------------------------*/ -/* Send 80 or so clock transitions with CS and DI held high. This is */ -/* required after card power up to get it into SPI mode */ -/*-----------------------------------------------------------------------*/ -static -void send_initial_clock_train(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - unsigned int i; - - /* Ensure CS is held high. */ - CS_HIGH(); - - /* Switch the SSI TX line to a GPIO and drive it high too. */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOB, &GPIO_InitStructure); - GPIO_SetBits(GPIOB, GPIO_Pin_15); - - /* Send 10 bytes over the SSI. This causes the clock to wiggle the */ - /* required number of times. */ - for(i = 0 ; i < 10 ; i++) - { - /* Loop while DR register in not empty */ - while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) { ; } - - /* Send byte through the SPI peripheral */ - SPI_I2S_SendData(SPI2, 0xff); - - /* Wait to receive a byte */ - while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) { ; } - } - - /* Revert to hardware control of the SSI TX line. */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOB, &GPIO_InitStructure); -} - - -/*-----------------------------------------------------------------------*/ -/* Power Control (Platform dependent) */ -/*-----------------------------------------------------------------------*/ -/* When the target system does not support socket power control, there */ -/* is nothing to do in these functions. */ - -static -void power_on (void) -{ - SPI_InitTypeDef SPI_InitStructure; - GPIO_InitTypeDef GPIO_InitStructure; - - /* - * This doesn't really turn the power on, but initializes the - * SSI port and pins needed to talk to the card. - */ - - /* Enable GPIO clock for CS */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); - /* Enable SPI clock, SPI2: APB1 */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); - /* Configure I/O for Flash Chip select (PB12) */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - /* De-select the Card: Chip Select high */ - GPIO_SetBits(GPIOB, GPIO_Pin_12); - - /* Configure SPI pins: SCK (PB13) and MOSI (PB15) with default alternate function (not re-mapped) push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOB, &GPIO_InitStructure); - /* Configure MISO (PB14) as Input with internal pull-up */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - /* SPI configuration */ - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - SPI_InitStructure.SPI_Mode = SPI_Mode_Master; - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; - SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // 72000kHz/256=281kHz < 400kHz - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; - SPI_InitStructure.SPI_CRCPolynomial = 7; - - SPI_Init(SPI2, &SPI_InitStructure); - SPI_CalculateCRC(SPI2, DISABLE); - SPI_Cmd(SPI2, ENABLE); - - /* Set DI and CS high and apply more than 74 pulses to SCLK for the card */ - /* to be able to accept a native command. */ - send_initial_clock_train(); - -} -// set the SSI speed to the max setting -static -void set_max_speed(void) -{ - SPI_InitTypeDef SPI_InitStructure; - - /* Disable the SPI system */ - SPI_Cmd(SPI2, DISABLE); - - /* MMC/SDC can work at the clock frequency up to 20/25MHz so pick a speed close to - * this but not higher - */ - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - SPI_InitStructure.SPI_Mode = SPI_Mode_Master; - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; - SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // 72MHz/4=18MHz < 20MHz - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; - SPI_InitStructure.SPI_CRCPolynomial = 7; - SPI_Init(SPI2, &SPI_InitStructure); - SPI_CalculateCRC(SPI2, DISABLE); - - /* Enable the SPI system */ - SPI_Cmd(SPI2, ENABLE); -} - -static -void power_off (void) -{ - Stat |= STA_NOINIT; /* Force uninitialized */ -} - - -/*-----------------------------------------------------------------------*/ -/* Transmit/Receive data to/from MMC via SPI (Platform dependent) */ -/*-----------------------------------------------------------------------*/ - -static -BYTE xchg_spi (BYTE dat) -{ - /* Send byte through the SPI peripheral */ - SPI_I2S_SendData(SPI2, dat); - - /* Wait to receive a byte */ - while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) { ; } - - /* Return the byte read from the SPI bus */ - return (BYTE)SPI_I2S_ReceiveData(SPI2); -} - -static -void rcvr_spi_m (BYTE *dst) -{ - *dst = xchg_spi(0xFF); -} - - -/*-----------------------------------------------------------------------*/ -/* Wait for card ready */ -/*-----------------------------------------------------------------------*/ - -static -int wait_ready (void) -{ - BYTE d; - ULONG timeOutTime; - - /* set timeout for 500 ms from now */ - timeOutTime = TimerGet() + 500; - - do { - d = xchg_spi(0xFF); - } while ((d != 0xFF) && (TimerGet() < timeOutTime)); - - return (d == 0xFF) ? 1 : 0; -} - - -/*-----------------------------------------------------------------------*/ -/* Deselect the card and release SPI bus */ -/*-----------------------------------------------------------------------*/ - -static -void deselect (void) -{ - CS_HIGH(); - xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */ -} - - - -/*-----------------------------------------------------------------------*/ -/* Select the card and wait ready */ -/*-----------------------------------------------------------------------*/ - -static -int select (void) /* 1:Successful, 0:Timeout */ -{ - CS_LOW(); - xchg_spi(0xFF); /* Dummy clock (force DO enabled) */ - - if (wait_ready()) return 1; /* OK */ - deselect(); - return 0; /* Timeout */ -} - - - -/*-----------------------------------------------------------------------*/ -/* Receive a data packet from MMC */ -/*-----------------------------------------------------------------------*/ - -static -int rcvr_datablock ( /* 1:OK, 0:Failed */ - BYTE *buff, /* Data buffer to store received data */ - UINT btr /* Byte count (must be multiple of 4) */ -) -{ - BYTE token; - ULONG timeOutTime; - - /* set timeout for 100 ms from now */ - timeOutTime = TimerGet() + 100; - - do { /* Wait for data packet in timeout of 100ms */ - token = xchg_spi(0xFF); - } while ((token == 0xFF) && (TimerGet() < timeOutTime)); - - if(token != 0xFE) return 0; /* If not valid data token, retutn with error */ - - do { /* Receive the data block into buffer */ - rcvr_spi_m(buff++); - rcvr_spi_m(buff++); - } while (btr -= 2); - xchg_spi(0xFF); /* Discard CRC */ - xchg_spi(0xFF); - - return 1; /* Return with success */ -} - - - -/*-----------------------------------------------------------------------*/ -/* Send a data packet to MMC */ -/*-----------------------------------------------------------------------*/ - -#if _USE_WRITE -static -int xmit_datablock ( /* 1:OK, 0:Failed */ - const BYTE *buff, /* 512 byte data block to be transmitted */ - BYTE token /* Data token */ -) -{ - BYTE resp; - UINT wc; - - - if (!wait_ready()) return 0; - - xchg_spi(token); /* Xmit a token */ - if (token != 0xFD) { /* Not StopTran token */ - wc = 512; - do { /* Xmit the 512 byte data block to MMC */ - xchg_spi(*buff++); - xchg_spi(*buff++); - } while (wc -= 2); - xchg_spi(0xFF); /* CRC (Dummy) */ - xchg_spi(0xFF); - resp = xchg_spi(0xFF); /* Receive a data response */ - if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */ - return 0; - } - - return 1; -} -#endif - - - -/*-----------------------------------------------------------------------*/ -/* Send a command packet to MMC */ -/*-----------------------------------------------------------------------*/ - -static -BYTE send_cmd ( - BYTE cmd, /* Command byte */ - DWORD arg /* Argument */ -) -{ - BYTE n, res; - - - if (cmd & 0x80) { /* ACMD is the command sequense of CMD55-CMD */ - cmd &= 0x7F; - res = send_cmd(CMD55, 0); - if (res > 1) return res; - } - - /* Select the card and wait for ready */ - 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) + Stop */ - if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) + Stop */ - xchg_spi(n); - - /* Receive command response */ - if (cmd == CMD12) xchg_spi(0xFF); /* Skip a stuff byte on stop to read */ - n = 10; /* Wait for a valid response in timeout of 10 attempts */ - do - res = xchg_spi(0xFF); - while ((res & 0x80) && --n); - - return res; /* Return with the response value */ -} - - - -/*-------------------------------------------------------------------------- - - Public Functions - ----------------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------*/ -/* Initialize Disk Drive */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_initialize ( - BYTE pdrv /* Physical drive nmuber (0) */ -) -{ - BYTE n, cmd, ty, ocr[4]; - ULONG timeOutTime; - - - if (pdrv) return STA_NOINIT; /* Supports only single drive */ - if (Stat & STA_NODISK) return Stat; /* No card in the socket */ - - power_on(); /* Force socket power on */ - - CS_LOW(); /* CS = L */ - - ty = 0; - if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ - timeOutTime = TimerGet() + 1000; /* Initialization timeout of 1000 msec */ - - if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */ - for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); /* Get trailing return value of R7 resp */ - if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ - while ((TimerGet() < timeOutTime) && send_cmd(ACMD41, 0x40000000)); /* Wait for leaving idle state (ACMD41 with HCS bit) */ - if ((TimerGet() < timeOutTime) && 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; /* SDv2 */ - } - } - } else { /* SDv1 or MMCv3 */ - if (send_cmd(ACMD41, 0) <= 1) { - ty = CT_SD1; cmd = ACMD41; /* SDv1 */ - } else { - ty = CT_MMC; cmd = CMD1; /* MMCv3 */ - } - while ((TimerGet() < timeOutTime) && send_cmd(cmd, 0)); /* Wait for leaving idle state */ - if (!(TimerGet() < timeOutTime) || send_cmd(CMD16, 512) != 0) /* Set read/write block length to 512 */ - ty = 0; - } - } - CardType = ty; - deselect(); - - if (ty) { /* Initialization succeded */ - Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ - FCLK_FAST(); - } else { /* Initialization failed */ - power_off(); - } - - return Stat; -} - - - -/*-----------------------------------------------------------------------*/ -/* Get Disk Status */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_status ( - BYTE pdrv /* Physical drive nmuber (0) */ -) -{ - if (pdrv) return STA_NOINIT; /* Supports only single drive */ - return Stat; -} - - - -/*-----------------------------------------------------------------------*/ -/* Read Sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_read ( - BYTE pdrv, /* Physical drive number (0) */ - BYTE *buff, /* Pointer to the data buffer to store read data */ - DWORD sector, /* Start sector number (LBA) */ - BYTE count /* Sector count (1..255) */ -) -{ - if (pdrv || !count) return RES_PARERR; - if (Stat & STA_NOINIT) return RES_NOTRDY; - - if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ - - if (count == 1) { /* Single block read */ - if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */ - && rcvr_datablock(buff, 512)) - count = 0; - } - else { /* Multiple block read */ - if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */ - do { - if (!rcvr_datablock(buff, 512)) break; - buff += 512; - } while (--count); - send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ - } - } - deselect(); - - return count ? RES_ERROR : RES_OK; -} - - - -/*-----------------------------------------------------------------------*/ -/* Write Sector(s) */ -/*-----------------------------------------------------------------------*/ - -#if _USE_WRITE -DRESULT disk_write ( - BYTE pdrv, /* Physical drive nmuber (0) */ - const BYTE *buff, /* Pointer to the data to be written */ - DWORD sector, /* Start sector number (LBA) */ - BYTE count /* Sector count (1..255) */ -) -{ - if (pdrv || !count) return RES_PARERR; - if (Stat & STA_NOINIT) return RES_NOTRDY; - if (Stat & STA_PROTECT) return RES_WRPRT; - - if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ - - if (count == 1) { /* Single block write */ - if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ - && xmit_datablock(buff, 0xFE)) - count = 0; - } - else { /* Multiple block write */ - if (CardType & CT_SDC) send_cmd(ACMD23, count); - 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)) /* STOP_TRAN token */ - count = 1; - } - } - deselect(); - - return count ? RES_ERROR : RES_OK; -} -#endif - - - -/*-----------------------------------------------------------------------*/ -/* Miscellaneous Functions */ -/*-----------------------------------------------------------------------*/ - -#if _USE_IOCTL -DRESULT disk_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive data block */ -) -{ - DRESULT res; - BYTE n, csd[16], *ptr = buff; - DWORD csz; - - - if (pdrv) return RES_PARERR; - if (Stat & STA_NOINIT) return RES_NOTRDY; - - res = RES_ERROR; - switch (cmd) { - case CTRL_SYNC : /* Flush write-back cache, Wait for end of internal process */ - if (select()) res = RES_OK; - break; - - case GET_SECTOR_COUNT : /* Get number of sectors on the disk (WORD) */ - if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { - if ((csd[0] >> 6) == 1) { /* SDv2? */ - csz = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1; - *(DWORD*)buff = csz << 10; - } else { /* SDv1 or MMCv3 */ - n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; - csz = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; - *(DWORD*)buff = csz << (n - 9); - } - res = RES_OK; - } - break; - - case GET_BLOCK_SIZE : /* Get erase block size in unit of sectors (DWORD) */ - if (CardType & CT_SD2) { /* SDv2? */ - 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 { /* SDv1 or MMCv3 */ - if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */ - if (CardType & CT_SD1) { /* SDv1 */ - *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); - } else { /* MMCv3 */ - *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); - } - res = RES_OK; - } - } - break; - - case MMC_GET_TYPE : /* Get card type flags (1 byte) */ - *ptr = CardType; - res = RES_OK; - break; - - case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ - if ((send_cmd(CMD9, 0) == 0) /* READ_CSD */ - && rcvr_datablock(buff, 16)) - res = RES_OK; - break; - - case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ - if ((send_cmd(CMD10, 0) == 0) /* READ_CID */ - && rcvr_datablock(buff, 16)) - res = RES_OK; - break; - - case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ - if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ - for (n = 0; n < 4; n++) - *((BYTE*)buff+n) = xchg_spi(0xFF); - res = RES_OK; - } - break; - - case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */ - if ((CardType & CT_SD2) && send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ - xchg_spi(0xFF); - if (rcvr_datablock(buff, 64)) - res = RES_OK; - } - break; - - default: - res = RES_PARERR; - } - - deselect(); - - return res; -} -#endif - - -/*---------------------------------------------------------*/ -/* User Provided Timer Function for FatFs module */ -/*---------------------------------------------------------*/ -/* This is a real time clock service to be called from */ -/* FatFs module. Any valid time must be returned even if */ -/* the system does not support a real time clock. */ -/* This is not required in read-only configuration. */ - -DWORD get_fattime (void) -{ - /* No RTC supprt. Return a fixed value 2013/5/10 0:00:00 */ - return ((DWORD)(2013 - 1980) << 25) /* Y */ - | ((DWORD)5 << 21) /* M */ - | ((DWORD)10 << 16) /* D */ - | ((DWORD)0 << 11) /* H */ - | ((DWORD)0 << 5) /* M */ - | ((DWORD)0 >> 1); /* S */ -} - - - diff --git a/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/makefile b/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/makefile index f97a5e76..1c1390c4 100644 --- a/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/makefile +++ b/Target/Demo/ARMCM3_STM32F1_Nucleo_F103RB_GCC/Boot/makefile @@ -38,8 +38,6 @@ PROJ_FILES= \ blt_conf.h \ hooks.c \ main.c \ -./lib/fatfs/ffconf.h \ -./lib/fatfs/mmc.c \ ./lib/CMSIS/CM3/CoreSupport/core_cm3.c \ ./lib/CMSIS/CM3/CoreSupport/core_cm3.h \ ./lib/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h \ @@ -54,11 +52,6 @@ main.c \ ./lib/STM32F10x_StdPeriph_Driver/src/stm32f10x_spi.c \ ./lib/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c \ ./lib/STM32F10x_StdPeriph_Driver/stm32f10x_conf.h \ -../../../Source/third_party/fatfs/src/diskio.h \ -../../../Source/third_party/fatfs/src/ff.c \ -../../../Source/third_party/fatfs/src/ff.h \ -../../../Source/third_party/fatfs/src/integer.h \ -../../../Source/third_party/fatfs/src/option/unicode.c \ ../../../Source/boot.c \ ../../../Source/boot.h \ ../../../Source/com.c \