Created
June 5, 2012 19:19
-
-
Save anonymous/2877114 to your computer and use it in GitHub Desktop.
main.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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