Skip to content

Instantly share code, notes, and snippets.

Created June 5, 2012 19:19
Show Gist options
  • Select an option

  • Save anonymous/2877114 to your computer and use it in GitHub Desktop.

Select an option

Save anonymous/2877114 to your computer and use it in GitHub Desktop.
main.c
#include <string.h>
#include <stdio.h>
#include "ch.h"
#include "hal.h"
#include "test.h"
#include "shell.h"
#include "evtimer.h"
#include "chprintf.h"
#include "ff.h"
#include "glcd.h"
#include "graph.h"
#include "touchpad.h"
#define BKGRD Black
#define RESOLUTION 100
FATFS MMC_FS;
MMCDriver MMCD1;
volatile uint16_t x, y;
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];
unsigned char cmd[][6] = {
{"r123\n"},
{"r999\n"},
{"r520\n"},
{"l092\n"},
{"l340\n"},
{"l420\n"},
{"r000\n"}};
int16_t coord[][2] = {{0,0}, {50,50}, {75,50}, {150,120}, {185,120},
{195,40},{220,40},{260, 0}};
static FRESULT scan_files(BaseSequentialStream *chp, char *path) {
FRESULT res;
FILINFO fno;
FIL fi;
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(10240)
#define TEST_WA_SIZE THD_WA_SIZE(256)
static void cmd_write(BaseSequentialStream *chp, int argc, char *argv[]) {
FRESULT ferr;
FIL fdst;
UINT written;
BYTE buffer[64];
char path[64];
uint8_t i;
if(argv[0] != NULL)
strcpy(path, argv[0]);
else
strcpy(path, "vitfit.txt");
ferr = f_open(&fdst, path, FA_CREATE_ALWAYS | FA_WRITE);
if(ferr != FR_OK) {
chprintf(chp, "f_open() failed!\r\n");
return;
}
for(i=0; i<(sizeof(cmd)/sizeof(cmd[0])); i++) {
strcpy(buffer, "This is some foo text\n");
f_write(&fdst, buffer, sizeof(buffer), &written);
}
f_close(&fdst);
return;
}
static void cmd_read(BaseSequentialStream *chp, int argc, char *argv[]) {
FRESULT ferr;
FIL fdst;
UINT br;
BYTE buffer[2048];
char path[64];
if(argv[0] != NULL)
strcpy(path, argv[0]);
else
strcpy(path, "vitfit.txt");
ferr = f_open(&fdst, path, FA_READ);
if(ferr != FR_OK) {
chprintf(chp, "f_open() failed!\r\n");
return;
}
ferr = f_read(&fdst, buffer, sizeof(buffer), &br);
if(ferr != FR_OK) {
chprintf(chp, "f_read() failed!");
return;
}
f_close(&fdst);
removeChar(buffer, '\r');
removeChar(buffer, '\n');
chprintf(chp, "%s\r\n", buffer);
}
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_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 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 const ShellCommand commands[] = {
{"mem", cmd_mem},
{"threads", cmd_threads},
{"test", cmd_test},
{"tree", cmd_tree},
{"write", cmd_write},
{"read", cmd_read},
{NULL, NULL}
};
static const ShellConfig shell_cfg1 = {
(BaseSequentialStream *)&SD2,
commands
};
void removeChar(char *str, char ch) {
char *src, *dst;
for(src = dst = str; *src != '\0'; src++) {
*dst = *src;
if(*dst != ch) dst++;
}
*dst = '\0';
}
uint16_t checksum(unsigned char *buffer) {
uint8_t i;
uint16_t ret = 0;
for (i = 0; i < strlen(buffer); i++)
ret += buffer[i];
return (ret & 0xff);
}
static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {
(void)arg;
chRegSetThreadName("blinker");
while (TRUE) {
palTogglePad(GPIOD, GPIOD_LED1);
if (fs_ready)
chThdSleepMilliseconds(200);
else
chThdSleepMilliseconds(500);
}
return 0;
}
static WORKING_AREA(waThread2, 1024);
static msg_t Thread2(SerialDriver *chp) {
chRegSetThreadName("USART1");
char buffer[20];
uint16_t i;
while(TRUE) {
chprintf(chp, "----------------------------------------------\r\n");
chprintf(chp, "\r\n");
for(i=0; i<(sizeof(cmd)/sizeof(cmd[0])); i++) {
*strchr(cmd[i], '\n') = '\0';
sprintf(buffer, "#0201%s", cmd[i]);
sprintf(buffer, "%s%02X%c", buffer, checksum(buffer), '\r');
chprintf(chp, "%s\n", buffer);
chThdSleepSeconds(5);
}
sprintf(buffer, "#0201s%02X%c", checksum("#0201s"), '\r');
chprintf(chp, "%s\n", buffer);
}
}
static WORKING_AREA(waThread3, 512);
static msg_t Thread3(void *arg) {
chRegSetThreadName("touchpad");
(void)arg;
while(TRUE) {
if(tpIRQ()) {
}
}
}
static void InsertHandler(eventid_t id) {
FRESULT err;
(void)id;
if (mmcConnect(&MMCD1)) {
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;
fs_ready = FALSE;
}
void readSD(unsigned char *buffer) {
FRESULT ferr;
FIL fdst;
UINT br;
char path[64];
ferr = f_open(&fdst, "vitfit.txt", FA_READ);
if(ferr != FR_OK)
return;
ferr = f_read(&fdst, buffer, sizeof(buffer), &br);
if(ferr != FR_OK)
return;
f_close(&fdst);
chprintf(&SD2, buffer);
removeChar(buffer, '\r');
removeChar(buffer, '\n');
}
static void touchIRQ(EXTDriver *extp, expchannel_t channel) {
(void)extp;
(void)channel;
chSysLockFromIsr();
palTogglePad(GPIOD, GPIOD_LED2);
chSysUnlockFromIsr()
}
static void buttonIRQ(EXTDriver *extp, expchannel_t channel) {
(void)extp;
(void)channel;
chSysLockFromIsr();
palTogglePad(GPIOD, GPIOD_LED3);
chSysUnlockFromIsr();
}
int main(void) {
static const evhandler_t evhndl[] = {
InsertHandler,
RemoveHandler
};
Thread *shelltp = NULL;
struct EventListener el0, el1;
static const SerialConfig sd1cfg = {
2400,
USART_CR1_M | USART_CR1_PCE,
USART_CR2_STOP1_BITS | USART_CR2_LINEN,
0,
};
static const EXTConfig extcfg = {
{
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOC, touchIRQ},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, buttonIRQ},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL}
}
};
halInit();
chSysInit();
sdStart(&SD1, &sd1cfg);
sdStart(&SD2, NULL);
shellInit();
lcdInit();
tpInit();
tpCalibrate();
lcdClear(BKGRD);
lcdSetOrientation(landscape);
graphDrawSystem(20, lcdGetWidth()-20, lcdGetHeight()-20, 20, Yellow);
graphDrawNet(coord, sizeof(coord)/sizeof(coord[0]), 2, Red, Green);
palSetPadMode(GPIOC, GPIOC_SDPWR, PAL_MODE_OUTPUT_PUSHPULL);
palClearPad(GPIOC, GPIOC_SDPWR);
palSetPadMode(IOPORT2, GPIOB_SPI2NSS, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(GPIOB, GPIOB_SPI2NSS);
mmcObjectInit(&MMCD1);
mmcStart(&MMCD1, &mmccfg);
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
//chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, &SD1);
chThdCreateStatic(waThread3, sizeof(waThread3), NORMALPRIO, Thread3, NULL);
chEvtRegister(&MMCD1.inserted_event, &el0, 0);
chEvtRegister(&MMCD1.removed_event, &el1, 1);
extStart(&EXTD1, &extcfg);
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment