It's me, I could need a little help here:
I ported the ARMCM3-STM32F103-FATFS example from the OLIMEX_STM32_P103 to my own board. After compiling and flashing, I can access the shell without any problems. Also the "test" runs successfully.
But when I put in an SD card, nothing happens. I am not sure where the problem is. I put a a line into the InsertHandler() which lights up an LED, when the SD card got plugged in, to be sure that it comes to that point and there's no issue with MMCCP. As suggested, the LED lights up, so I guess, the problem needs to be at mmcConnect(), since the other LED (LED3) dosen't light up (yeah, I like LEDs for debuggin
Can someone tell me, where the problem is?
The only 'big thing' I changed is in my board.c file. My board dosen't support the readout of the write protection, therefore, the function just returns 1 (also tried it with return 0, to be sure, that there is no issue - didn't work too).
here my main.c:
Code: Select all
#include <string.h>
#include "ch.h"
#include "hal.h"
#include "test.h"
#include "shell.h"
#include "evtimer.h"
#include "chprintf.h"
#include "ff.h"
FATFS MMC_FS;
MMCDriver MMCD1;
static bool_t fs_ready = FALSE;
static SPIConfig hs_spicfg = {NULL, IOPORT2, GPIOB_SPI2NSS, 0};
static SPIConfig ls_spicfg = {NULL, IOPORT2, GPIOB_SPI2NSS, SPI_CR1_BR_2 | SPI_CR1_BR_1};
static MMCConfig mmccfg = {&SPID2, &ls_spicfg, &hs_spicfg};
uint8_t fbuff[1024];
static FRESULT scan_files(BaseSequentialStream *chp, char *path) {
FRESULT res;
FILINFO fno;
DIR dir;
int i;
char *fn;
res = f_opendir(&dir, path);
if (res == FR_OK) {
i = strlen(path);
for (;;) {
res = f_readdir(&dir, &fno);
if (res != FR_OK || fno.fname[0] == 0)
break;
if (fno.fname[0] == '.')
continue;
fn = fno.fname;
if (fno.fattrib & AM_DIR) {
path[i++] = '/';
strcpy(&path[i], fn);
res = scan_files(chp, path);
if (res != FR_OK)
break;
path[i] = 0;
} else {
chprintf(chp, "%s/%s\r\n", path, fn);
}
}
}
return res;
}
#define SHELL_WA_SIZE THD_WA_SIZE(2048)
#define TEST_WA_SIZE THD_WA_SIZE(256)
static void cmd_mem(BaseSequentialStream *chp, int argc, char *argv[]) {
size_t n, size;
(void)argv;
if (argc > 0) {
chprintf(chp, "Usage: mem\r\n");
return;
}
n = chHeapStatus(NULL, &size);
chprintf(chp, "core free memory : %u bytes\r\n", chCoreStatus());
chprintf(chp, "heap fragments : %u\r\n", n);
chprintf(chp, "heap free total : %u bytes\r\n", size);
}
static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) {
static const char *states[] = {THD_STATE_NAMES};
Thread *tp;
(void)argv;
if (argc > 0) {
chprintf(chp, "Usage: threads\r\n");
return;
}
chprintf(chp, " addr stack prio refs state time\r\n");
tp = chRegFirstThread();
do {
chprintf(chp, "%.8lx %.8lx %4lu %4lu %9s %lu\r\n",
(uint32_t)tp, (uint32_t)tp->p_ctx.r13,
(uint32_t)tp->p_prio, (uint32_t)(tp->p_refs - 1),
states[tp->p_state], (uint32_t)tp->p_time);
tp = chRegNextThread(tp);
} while (tp != NULL);
}
static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) {
Thread *tp;
(void)argv;
if (argc > 0) {
chprintf(chp, "Usage: test\r\n");
return;
}
tp = chThdCreateFromHeap(NULL, TEST_WA_SIZE, chThdGetPriority(), TestThread, chp);
if (tp == NULL) {
chprintf(chp, "out of memory\r\n");
return;
}
chThdWait(tp);
}
static void cmd_tree(BaseSequentialStream *chp, int argc, char *argv[]) {
FRESULT err;
uint32_t clusters;
FATFS *fsp;
(void)argv;
if (argc > 0) {
chprintf(chp, "Usage: tree\r\n");
return;
}
if (!fs_ready) {
chprintf(chp, "File System not mounted\r\n");
return;
}
err = f_getfree("/", &clusters, &fsp);
if (err != FR_OK) {
chprintf(chp, "FS: f_getfree() failed\r\n");
return;
}
chprintf(chp, "FS: %lu free clusters, %lu sectors per cluster, %lu bytes free\r\n",
clusters, (uint32_t)MMC_FS.csize,
clusters * (uint32_t)MMC_FS.csize * (uint32_t)MMC_SECTOR_SIZE);
fbuff[0] = 0;
scan_files(chp, (char *)fbuff);
}
static const ShellCommand commands[] = {
{"mem", cmd_mem},
{"threads", cmd_threads},
{"test", cmd_test},
{"tree", cmd_tree},
{NULL, NULL}
};
static const ShellConfig shell_cfg1 = {
(BaseSequentialStream *)&SD2, commands
};
static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {
(void)arg;
chRegSetThreadName("blinker");
while(TRUE) {
palTogglePad(IOPORT4, GPIOD_LED1);
if(fs_ready)
chThdSleepMilliseconds(100);
else
chThdSleepMilliseconds(500);
}
return 0;
}
static void InsertHandler(eventid_t id) {
FRESULT err;
(void)id;
palSetPad(GPIOD, GPIOD_LED2);
if (mmcConnect(&MMCD1)) {
palSetPad(GPIOD, GPIOD_LED3);
return;
}
err = f_mount(0, &MMC_FS);
if (err != FR_OK) {
mmcDisconnect(&MMCD1);
return;
}
fs_ready = TRUE;
}
static void RemoveHandler(eventid_t id) {
(void)id;
palClearPad(GPIOD, GPIOD_LED2);
fs_ready = FALSE;
}
int main(void) {
static const evhandler_t evhndl[] = {
InsertHandler,
RemoveHandler
};
Thread *shelltp = NULL;
struct EventListener el0, el1;
halInit();
chSysInit();
sdStart(&SD2, NULL);
shellInit();
palSetPadMode(GPIOB, GPIOB_SPI2NSS, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(GPIOB, GPIOB_SPI2NSS);
mmcObjectInit(&MMCD1);
mmcStart(&MMCD1, &mmccfg);
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
chEvtRegister(&MMCD1.inserted_event, &el0, 0);
chEvtRegister(&MMCD1.removed_event, &el1, 1);
while(TRUE) {
if(!shelltp)
shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO);
else if (chThdTerminated(shelltp)) {
chThdRelease(shelltp); /* Recovers memory of the previous shell. */
shelltp = NULL; /* Triggers spawning of a new shell. */
}
chEvtDispatch(evhndl, chEvtWaitOne(ALL_EVENTS));
}
return 0;
}my board.h:
Code: Select all
#ifndef _BOARD_H_
#define _BOARD_H_
// Board identifier.
#define BOARD_MY_BOARD
#define BOARD_NAME "my board"
// Board frequencies.
#define STM32_LSECLK 32768
#define STM32_HSECLK 8000000
// MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h.
#define STM32F10X_HD
// IO pins assignments.
#define GPIOA_BUTTON 8
#define GPIOD_LED1 8
#define GPIOD_LED2 9
#define GPIOD_LED3 10
#define GPIOD_LED4 11
#define GPIOB_SPI2NSS 12
#define GPIOA_MMCCP 4
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.
*
* The digits have the following meaning:
* 0 - Analog input.
* 1 - Push Pull output 10MHz.
* 2 - Push Pull output 2MHz.
* 3 - Push Pull output 50MHz.
* 4 - Digital input.
* 5 - Open Drain output 10MHz.
* 6 - Open Drain output 2MHz.
* 7 - Open Drain output 50MHz.
* 8 - Digital input with PullUp or PullDown resistor depending on ODR.
* 9 - Alternate Push Pull output 10MHz.
* A - Alternate Push Pull output 2MHz.
* B - Alternate Push Pull output 50MHz.
* C - Reserved.
* D - Alternate Open Drain output 10MHz.
* E - Alternate Open Drain output 2MHz.
* F - Alternate Open Drain output 50MHz.
* Please refer to the STM32 Reference Manual for details.
*/
#define VAL_GPIOACRL 0x34344B34 /* PA7...PA0 */
#define VAL_GPIOACRH 0x444334B4 /* PA15...PA8 */
#define VAL_GPIOAODR 0xFFFFFFFF
#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIOBCRH 0xB4B88888 /* PB15...PB8 */
#define VAL_GPIOBODR 0xFFFFFFFF
#define VAL_GPIOCCRL 0x44848888 /* PC7...PC0 */
#define VAL_GPIOCCRH 0x88833388 /* PC15...PC8 */
#define VAL_GPIOCODR 0xFFFFFFFF
#define VAL_GPIODCRL 0x33388888 /* PD7...PD0 */
#define VAL_GPIODCRH 0x33333333 /* PD15...PD8 */
#define VAL_GPIODODR 0xFFFFFFFF
#define VAL_GPIOECRL 0x33333333 /* PE7...PE0 */
#define VAL_GPIOECRH 0x33333333 /* PE15...PE8 */
#define VAL_GPIOEODR 0xFFFFFFFF
#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {
#endif
void boardInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _FROM_ASM_ */
#endif /* _BOARD_H_ */and my board.c:
Code: Select all
#include "ch.h"
#include "hal.h"
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
* This variable is used by the HAL when initializing the PAL driver.
*/
#if HAL_USE_PAL || defined(__DOXYGEN__)
const PALConfig pal_default_config =
{
{VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH},
{VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH},
{VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH},
{VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH},
{VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH},
};
#endif
#if HAL_USE_MMC_SPI
/* Board-related functions related to the MMC_SPI driver.*/
bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp) {
(void)mmcp;
return !palReadPad(GPIOA, GPIOA_MMCCP);
}
bool_t mmc_lld_is_write_protected(MMCDriver *mmcp) {
(void)mmcp;
return 0;
}
#endif
/*
* Early initialization code.
* This initialization must be performed just after stack setup and before
* any other initialization.
*/
void __early_init(void) {
stm32_clock_init();
}
void boardInit(void) {
palClearPad(GPIOD, GPIOD_LED1);
palClearPad(GPIOD, GPIOD_LED2);
palClearPad(GPIOD, GPIOD_LED3);
palClearPad(GPIOD, GPIOD_LED4);
}I am sure that SPI2NSS is GPIOB Pin 12 on my board.
In the Makefile from the STM32F103-FATFS example, I just changed my board, the linkerscript (STM32F103xE.ld) and the path of the chibios.
I use a SandDisk SD Card Class 2 with 2GB (no sdhc).
~ Tectu
