Commit 9bb9c305 authored by Xavier Piroux's avatar Xavier Piroux Committed by Matthieu Cattin

Creating project simple_spi_sd to test only the SD card.

Functions of SD are implemented in ../common/drivers/sd.c and ../common/drivers/sd.h to be OS-independent
parent 380335f4
/*
* Copyright (C) 2014 Julian Lewis
* @author Xavier Piroux <xavierpiroux@gmail.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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @brief implementation of micro SD access
*/
#include "sd.h"
#include "em_cmu.h"
#include "em_usart.h"
/* definitions of MMC/SD commands (in SPI) */
#define SD_CMD0 (0x40 | 0) /* GO_IDLE_STATE */
#define SD_CMD1 (0x40 | 1) /* SEND_OP_COND (MMC) */
#define SD_ACMD41 (0xC0 | 41) /* SEND_OP_COND (SDC) */
#define SD_CMD8 (0x40 | 8) /* SEND_IF_COND */
#define SD_CMD9 (0x40 | 9) /* SEND_CSD */
#define SD_CMD10 (0x40 | 10) /* SEND_CID */
#define SD_CMD12 (0x40 | 12) /* STOP_TRANSMISSION */
#define SD_ACMD13 (0xC0 | 13) /* SD_STATUS (SDC) */
#define SD_CMD16 (0x40 | 16) /* SET_BLOCKLEN */
#define SD_CMD17 (0x40 | 17) /* READ_SINGLE_BLOCK */
#define SD_CMD18 (0x40 | 18) /* READ_MULTIPLE_BLOCK */
#define SD_CMD23 (0x40 | 23) /* SET_BLOCK_COUNT (MMC) */
#define SD_ACMD23 (0xC0 | 23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
#define SD_CMD24 (0x40 | 24) /* WRITE_BLOCK */
#define SD_CMD25 (0x40 | 25) /* WRITE_MULTIPLE_BLOCK */
#define SD_CMD55 (0x40 | 55) /* APP_CMD */
#define SD_CMD58 (0x40 | 58) /* READ_OCR */
/**
* @brief has to be called when doing basic sd init or when powering on/off.
* Calling it more than once is not a problem
*/
static void sd_power_init(void) {
static char first_time = 1;
if (first_time) {
GPIO_Mode_TypeDef gpioModeSD_EN = gpioModePushPull;
GPIO_PinModeSet(SD_PORT_POWER, SD_PIN_POWER, gpioModeSD_EN, 0); /* init pin SD_EN to set power on/off */
first_time = 0;
}
}
static void sd_spi_init(void) {
USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT;
GPIO_Mode_TypeDef gpioModeMosi = gpioModePushPull;
GPIO_Mode_TypeDef gpioModeMiso = gpioModeInput;
GPIO_Mode_TypeDef gpioModeCs = gpioModePushPull;
GPIO_Mode_TypeDef gpioModeClk = gpioModePushPull;
CMU_ClockEnable(SD_SPI_CLOCK, true);
usartInit.baudrate = SD_SPI_BAUDRATE;
USART_InitSync(SD_SPI_UNIT, &usartInit);
SD_SPI_UNIT->ROUTE = (USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CSPEN | (SD_SPI_LOCATION << 8));
GPIO_PinModeSet(SD_PORT_MOSI, SD_PIN_MOSI, gpioModeMosi, 0); /* MOSI */
GPIO_PinModeSet(SD_PORT_MISO, SD_PIN_MISO, gpioModeMiso, 0); /* MISO */
GPIO_PinModeSet(SD_PORT_CS_N, SD_PIN_CS_N, gpioModeCs, 0); /* CS */
GPIO_PinModeSet(SD_PORT_CLOCK, SD_PIN_CLOCK, gpioModeClk, 0); /* Clock */
sd_power_init();
}
//this function writes and reads
static uint8_t sd_spi_transfer_byte(uint8_t txData) {
return USART_SpiTransfer(SD_SPI_UNIT, txData);
}
//this function writes and reads (buffers must have the same length)
static void sd_spi_transfer(uint8_t* txData, uint8_t* rxData, int length) {
int i;
for (i = 0 ; i < length ; i++) {
rxData[i] = sd_spi_transfer_byte(txData[i]);
}
}
//this function writes only
static void sd_spi_transmit(uint8_t *txBuffer, int length) {
while (length > 0) {
// Send only one byte if len==1 or data pointer is not aligned at a 16 bit
// word location in memory.
if((length == 1) || ((unsigned int)txBuffer & 0x1))
{
USART_Tx(SD_SPI_UNIT, *(uint8_t*)txBuffer);
length--;
txBuffer++;
} else {
USART_TxDouble(SD_SPI_UNIT, *(uint16_t*)txBuffer);
length -= 2;
txBuffer += 2;
}
}
// Be sure that all transfer have finished
while(!(SD_SPI_UNIT->STATUS & USART_STATUS_TXC));
}
void sd_power(uint8_t enable) {
uint8_t pins_mask = 1 << SD_PIN_POWER;//pin = PC3
uint8_t values_mask = enable ? pins_mask : 0;
sd_power_init();
GPIO_PortOutSetVal(SD_PORT_POWER, pins_mask, values_mask);//power on/power off
}
#define SD_INIT_TRY_MAX 10
static uint8_t sd_send_command_r1(uint8_t cmd, uint32_t arg);
uint32_t sd_init(void) {
uint32_t res;
int i = 0;
sd_spi_init();
sd_power(1);
/* initializes the micro SD card */
sd_send_command_r1(SD_CMD0, 0);
do {
sd_send_command_r1(SD_CMD55, 0);
res = sd_send_command_r1(SD_ACMD41, 0);
i++;
} while (res == 0 || i > SD_INIT_TRY_MAX);
if (res != 0) {
return 0;
}
sd_send_block_length(SD_SECTOR_SIZE);
return 1;
//TODO: is the init finished?
}
#if 0
/**
* @brief transform a 32 bit value into a 4 bytes array
*/
static void sd_packarg(uint8_t *dest, unsigned long src) {
dest[3] = (uint8_t)(src >> 24);
dest[2] = (uint8_t)(src >> 16);
dest[1] = (uint8_t)(src >> 8);
dest[0] = (uint8_t)(src);
}
#endif
static uint8_t sd_send_command_r1(uint8_t cmd, uint32_t arg) {
uint8_t n, res;
/* Send command packet */
sd_spi_transfer_byte(0x40 | cmd); /* Start + Command index */
sd_spi_transfer_byte((uint8_t)(arg >> 24)); /* Argument[31..24] */
sd_spi_transfer_byte((uint8_t)(arg >> 16)); /* Argument[23..16] */
sd_spi_transfer_byte((uint8_t)(arg >> 8)); /* Argument[15..8] */
sd_spi_transfer_byte((uint8_t) arg); /* Argument[7..0] */
n = 0x01; /* Dummy CRC + Stop */
sd_spi_transfer_byte(n);
/* Receive command response */
if (cmd == SD_CMD12) {
sd_spi_transfer_byte(0xff); /* Skip a stuff byte when stop reading */
}
res = sd_spi_transfer_byte(0xff); /* Send dummy data and check the reply */
return res; /* Return with the response value */
}
uint8_t sd_send_block_length(uint32_t bytes_per_sector) {
return sd_send_command_r1(SD_CMD16, bytes_per_sector);
}
/*
* Copyright (C) 2014 Julian Lewis
* @author Xavier Piroux <xavierpiroux@gmail.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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @brief headers of micro SD access
*/
#ifndef SD_H
#define SD_H
#include "em_gpio.h"
/* Defines */
#define HFRCO_FREQUENCY 14000000
#define SD_SPI_PERCLK_FREQUENCY HFRCO_FREQUENCY
/* Peripherals */
#define SD_SPI_CLOCK cmuClock_USART1
#define SD_SPI_BAUDRATE 1000000
#define SD_SPI_UNIT USART1
#define SD_SPI_LOCATION 1
// Pinout
#define SD_PORT_MOSI gpioPortD
#define SD_PIN_MOSI 0
#define SD_PORT_MISO gpioPortD
#define SD_PIN_MISO 1
#define SD_PORT_CS_N gpioPortD
#define SD_PIN_CS_N 3
#define SD_PORT_CLOCK gpioPortD
#define SD_PIN_CLOCK 2
#define SD_PORT_POWER gpioPortC
#define SD_PIN_POWER 3
//sizes of the SD card
#define SD_SECTOR_SIZE 512 /* Sector size */
#define SD_VOLUME_SIZE (2 * 1024 * 1024) /* definition for size of sddrive0 : we assume working with a 2GB micro SD card */
/**
* @brief micro SD initialization routine.
* @return > 0 means a success
*/
uint32_t sd_init(void);
/**
* @brief Controls power for the micro SD.
* @param uint8_t enable turns on the power if greater than 0.
*/
void sd_power(uint8_t enable);
/**
* @brief Set the number of bytes in a sector of the micro SD
* @param uint8_t bytes_per_sector number of bytes per sector
* @return the reply from the card (0 = success)
*/
uint8_t sd_send_block_length(uint32_t bytes_per_sector);
/**
* @brief enumeration for the possible type of replies coming from the micro SD
*/
typedef enum {
SD_RESPONSE_R1 = 1,
SD_RESPONSE_R2 = 2,
SD_RESPONSE_R3 = 3
} sd_response_type;
#endif /* SD_H */
......@@ -83,8 +83,14 @@ typedef enum {
} sd_response_type;
static int sd_vol0_card_present(void) {
return (GPIO_PortInGet(gpioPortC) & 0x8);//pin = PC3
static void sd_vol0_set_electrical_power(int power) {
uint8_t pins_mask = 0x8;//pin = PC3
uint8_t values_mask = power ? 0x8 : 0;
GPIO_Mode_TypeDef gpioModeSD_EN = gpioModePushPull;
GPIO_PinModeSet(gpioPortC, 3, gpioModeSD_EN, 0); /* init pin SD_EN to set power on/off */
GPIO_PortOutSetVal(gpioPortC, pins_mask, values_mask);//power on/power off
}
/*
* transform a 32 bit value into a 4 bytes array
......@@ -103,7 +109,8 @@ typedef struct {
struct {
uint8_t spiNumber;
uint8_t location;
int (*is_sd_card_present) (void);
CMU_Clock_TypeDef clock;
void (*set_electrical_power) (int power);
void (*spi_setupRXInt) (char* receiveBuffer, int bytesToReceive);
void (*spi_setupTXInt) (char* transmitBuffer, int transmitBufferSize);
void (*usart_wait_TX_finished) (void);
......@@ -117,11 +124,10 @@ static F_DRIVER t_drivers[1];
static t_SdDrv SdDrv[1] =
{
{ ( MDRIVER_SD_VOLUME0_SIZE / MDRIVER_SD_SECTOR_SIZE ), 0,
{1, 1, sd_vol0_card_present, SPI1_setupRXInt, SPI1_setupTXInt, USART1_Wait_TX_finished, USART1_Wait_RX_finished},
&t_drivers[0] }
{1, 1, cmuClock_USART1,
sd_vol0_set_electrical_power, SPI1_setupRXInt, SPI1_setupTXInt, USART1_Wait_TX_finished, USART1_Wait_RX_finished}, &t_drivers[0] }
};
static int sd_card_send_command(F_DRIVER * driver, unsigned char command, unsigned char response_type, unsigned char* argument, unsigned char* response) {
t_SdDrv* pSdDrv = (t_SdDrv*) driver->user_ptr;
static int sd_card_send_command(t_SdDrv* pSdDrv, unsigned char command, unsigned char response_type, unsigned char* argument, unsigned char* response) {
char txBuffer[5];
char rxBuffer[5];
int txSize;
......@@ -159,14 +165,14 @@ static int sd_card_send_command(F_DRIVER * driver, unsigned char command, unsign
static int sd_readsector ( F_DRIVER * driver, void * data, unsigned long sector ) {
char arg_sector_adress[4];
sd_packarg((unsigned char*) arg_sector_adress, sector);
return sd_card_send_command(driver, SD_CMD17, SD_RESPONSE_R3, (unsigned char*) arg_sector_adress, (unsigned char*) data);
return sd_card_send_command((t_SdDrv*) driver->user_ptr, SD_CMD17, SD_RESPONSE_R3, (unsigned char*) arg_sector_adress, (unsigned char*) data);
}
static int sd_writesector ( F_DRIVER * driver, void * data, unsigned long sector ) {
t_SdDrv* pSdDrv = (t_SdDrv*) driver->user_ptr;
char arg_sector_adress[4];
//first, transmit the adress where to write
sd_packarg((unsigned char*) arg_sector_adress, sector);
if (sd_card_send_command(driver, SD_CMD17, SD_RESPONSE_R3, (unsigned char*) arg_sector_adress, NULL) != 0) {
if (sd_card_send_command(pSdDrv, SD_CMD17, SD_RESPONSE_R3, (unsigned char*) arg_sector_adress, NULL) != 0) {
return -1;
}
//now, transmit the data to write
......@@ -177,10 +183,6 @@ static int sd_writesector ( F_DRIVER * driver, void * data, unsigned long sector
static int sd_getphy ( F_DRIVER * driver, F_PHY * phy ) {
t_SdDrv * p = (t_SdDrv *)( driver->user_ptr );
if (p->usart_data.is_sd_card_present() != 0) {
return MDRIVER_SD_ERR_NOTAVAILABLE;
}
phy->number_of_sectors = p->maxsector;
phy->bytes_per_sector = MDRIVER_SD_SECTOR_SIZE;
......@@ -193,6 +195,7 @@ static void sd_release ( F_DRIVER * driver ) {
//TODO: check if SD protocol and disconnect properly the SD through SPI + SD protocol
p->use = 0;
}
p->usart_data.set_electrical_power(0);/* power-off the card */
}
F_DRIVER * sd_initfunc ( unsigned long driver_param ) {
......@@ -207,20 +210,20 @@ F_DRIVER * sd_initfunc ( unsigned long driver_param ) {
}
{
char commandCRC = 0x95;
char arg_block_length[4];
unsigned char arg_block_length[4];
GPIO_Mode_TypeDef gpioModeSD_EN = gpioModeInput;
GPIO_PinModeSet(gpioPortC, 3, gpioModeSD_EN, 0); /* init pin SD_EN to check if SD is plugged */
p->usart_data.set_electrical_power(1);/* power-on the card */
//TODO: check specif of SPI protocol and init SD through SPI protocol
/* Enabling clock to USART 1*/
CMU_ClockEnable(cmuClock_USART1, true);
SPI_setup(1, 1, 1);//init SD SPI
CMU_ClockEnable(p->usart_data.clock, true);
SPI_setup(p->usart_data.spiNumber, p->usart_data.location, 1);//init SD SPI
//TODO: check specif of SD protocol and init SD through SD protocol
//TODO: goto to IDLE state?
SPI1_setupTXInt(&commandCRC, 1);//no reply to answer from the CRC command
USART1_Wait_TX_finished();
sd_packarg((unsigned char*) arg_block_length, MDRIVER_SD_SECTOR_SIZE);//set sector size
//set sector size
sd_packarg(arg_block_length, MDRIVER_SD_SECTOR_SIZE);
sd_card_send_command(p, SD_CMD16, SD_RESPONSE_R1, arg_block_length, NULL);
(void)psp_memset( p->driver, 0, sizeof( F_DRIVER ) );
......
####################################################################
# Makefile #
####################################################################
.SUFFIXES: # ignore builtin rules
.PHONY: all debug release clean flash
####################################################################
# Definitions #
####################################################################
DEVICE = EFM32GG330F1024
PROJECTNAME = simple_spi_sd
# Name of interface configuration file used by OpenOCD
OOCD_IFACE ?= stlink-v2-1
OBJ_DIR = build
EXE_DIR = exe
LST_DIR = lst
####################################################################
# Definitions of toolchain. #
# You might need to do changes to match your system setup #
####################################################################
# Change path to the tools according to your system configuration
# DO NOT add trailing whitespace chars, they do matter !
WINDOWSCS ?= GNU Tools ARM Embedded\4.7 2012q4
LINUXCS ?= /usr
RMDIRS := rm -rf
RMFILES := rm -rf
ALLFILES := /*.*
NULLDEVICE := /dev/null
SHELLNAMES := $(ComSpec)$(COMSPEC)
# Try autodetecting the environment
ifeq ($(SHELLNAMES),)
# Assume we are making on a Linux platform
TOOLDIR := $(LINUXCS)
else
QUOTE :="
ifneq ($(COMSPEC),)
# Assume we are making on a mingw/msys/cygwin platform running on Windows
# This is a convenient place to override TOOLDIR, DO NOT add trailing
# whitespace chars, they do matter !
TOOLDIR := $(PROGRAMFILES)/$(WINDOWSCS)
ifeq ($(findstring cygdrive,$(shell set)),)
# We were not on a cygwin platform
NULLDEVICE := NUL
endif
else
# Assume we are making on a Windows platform
# This is a convenient place to override TOOLDIR, DO NOT add trailing
# whitespace chars, they do matter !
SHELL := $(SHELLNAMES)
TOOLDIR := $(ProgramFiles)/$(WINDOWSCS)
RMDIRS := rd /s /q
RMFILES := del /s /q
ALLFILES := \*.*
NULLDEVICE := NUL
endif
endif
# Create directories and do a clean which is compatible with parallell make
$(shell mkdir $(OBJ_DIR)>$(NULLDEVICE) 2>&1)
$(shell mkdir $(EXE_DIR)>$(NULLDEVICE) 2>&1)
$(shell mkdir $(LST_DIR)>$(NULLDEVICE) 2>&1)
ifeq (clean,$(findstring clean, $(MAKECMDGOALS)))
ifneq ($(filter $(MAKECMDGOALS),all debug release),)
$(shell $(RMFILES) $(OBJ_DIR)$(ALLFILES)>$(NULLDEVICE) 2>&1)
$(shell $(RMFILES) $(EXE_DIR)$(ALLFILES)>$(NULLDEVICE) 2>&1)
$(shell $(RMFILES) $(LST_DIR)$(ALLFILES)>$(NULLDEVICE) 2>&1)
endif
endif
CC = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-gcc$(QUOTE)
LD = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-ld$(QUOTE)
AR = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-ar$(QUOTE)
OBJCOPY = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-objcopy$(QUOTE)
DUMP = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-objdump$(QUOTE)
####################################################################
# Flags #
####################################################################
# -MMD : Don't generate dependencies on system header files.
# -MP : Add phony targets, useful when a h-file is removed from a project.
# -MF : Specify a file to write the dependencies to.
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
#
# Add -Wa,-ahld=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
#
override CFLAGS += -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb \
-mfix-cortex-m3-ldrd -ffunction-sections \
-fdata-sections -fomit-frame-pointer -DDEBUG_EFM \
$(DEPFLAGS)
override ASMFLAGS += -x assembler-with-cpp -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb
#
# NOTE: The -Wl,--gc-sections flag may interfere with debugging using gdb.
#
override LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 \
-mthumb -T../../common/Device/EnergyMicro/EFM32GG/Source/GCC/efm32gg.ld \
-Wl,--gc-sections
LIBS = -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
INCLUDEPATHS += \
-Isrc \
-I../../common/CMSIS/Include \
-I../../common/Device/EnergyMicro/EFM32GG/Include \
-I../../common/emlib/inc \
-I../../common/drivers \
####################################################################
# Files #
####################################################################
C_SRC += \
../../common/Device/EnergyMicro/EFM32GG/Source/system_efm32gg.c \
../../common/emlib/src/em_system.c \
../../common/emlib/src/em_cmu.c \
../../common/emlib/src/em_usart.c \
../../common/emlib/src/em_assert.c \
../../common/emlib/src/em_gpio.c \
../../common/drivers/sd.c \
src/simple_spi_sd.c
s_SRC +=
S_SRC += \
../../common/Device/EnergyMicro/EFM32GG/Source/GCC/startup_efm32gg.S
####################################################################
# Rules #
####################################################################
C_FILES = $(notdir $(C_SRC) )
S_FILES = $(notdir $(S_SRC) $(s_SRC) )
#make list of source paths, sort also removes duplicates
C_PATHS = $(sort $(dir $(C_SRC) ) )
S_PATHS = $(sort $(dir $(S_SRC) $(s_SRC) ) )
C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
S_OBJS = $(if $(S_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.S=.o)))
s_OBJS = $(if $(s_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o)))
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))
OBJS = $(C_OBJS) $(S_OBJS) $(s_OBJS)
vpath %.c $(C_PATHS)
vpath %.s $(S_PATHS)
vpath %.S $(S_PATHS)
# Default build is debug build
all: debug
debug: CFLAGS += -DDEBUG -O0 -g
debug: $(EXE_DIR)/$(PROJECTNAME).bin
release: CFLAGS += -DNDEBUG -O0 -g
release: $(EXE_DIR)/$(PROJECTNAME).bin
# Create objects from C SRC files
$(OBJ_DIR)/%.o: %.c
@echo "Building file: $<"
$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<
# Assemble .s/.S files
$(OBJ_DIR)/%.o: %.s
@echo "Assembling $<"
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
$(OBJ_DIR)/%.o: %.S
@echo "Assembling $<"
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
# Link
$(EXE_DIR)/$(PROJECTNAME).out: $(OBJS)
@echo "Linking target: $@"
$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out
# Create binary file
$(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out
@echo "Creating binary file"
$(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin
# Uncomment next line to produce assembly listing of entire program
# $(DUMP) -h -S -C $(EXE_DIR)/$(PROJECTNAME).out>$(LST_DIR)/$(PROJECTNAME)out.lst
clean:
ifeq ($(filter $(MAKECMDGOALS),all debug release),)
$(RMDIRS) $(OBJ_DIR) $(LST_DIR) $(EXE_DIR)
endif
flash: $(EXE_DIR)/$(PROJECTNAME).bin
openocd -s ./openocd -f interface/$(OOCD_IFACE).cfg -f init.cfg -c "program $(EXE_DIR)/$(PROJECTNAME).bin 0 verify reset"
# include auto-generated dependency files (explicit rules)
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
-include $(C_DEPS)
endif
#
# efm32 stlink pseudo target
#
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME efm32
}
# Work-area is a space in RAM used for flash programming
# By default use 2kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x800
}
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x2ba01477
}
# EFM32 MCUs only support SWD interface
set _TRANSPORT hla_swd
transport select $_TRANSPORT
hla newtap $_CHIPNAME cpu -expected-id $_CPUTAPID
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME hla_target -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
# cortex_m reset_config sysresetreq
source [find efm32_stlink2.cfg]
init
flash probe 0
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment