Mercurial > ~darius > hgwebdir.cgi > stm32temp
view main.c @ 57:adc9b1555f9d
Add the ability to log temperatures to SD card.
Fix a few warnings while I am here.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Mon, 08 Apr 2013 22:20:40 +0930 |
parents | b21db2b47a27 |
children | f1c9a51e368a |
line wrap: on
line source
#include <ctype.h> #include <malloc.h> #include <math.h> #include <stdio.h> #include <stdint.h> #include <time.h> #include <string.h> #include <sys/time.h> #include <stdlib.h> #include <assert.h> #include "stm32f10x.h" #include "1wire.h" #include "comm.h" #include "delay.h" #include "flash.h" #include "hw.h" #include "lcd.h" #include "main.h" #include "rtc.h" #include "sd.h" #include "sprink.h" #include "tempctrl.h" #include "touch.h" #define MAXARGS 10 #define LINEBUF 40 typedef struct { char *buf; volatile uint8_t state; uint8_t len; } consbuf_t; void NVIC_Configuration(void); /* Called every 1 / TICK_FREQ */ #define TICK_FREQ 10000 RAMFUNC void SysTick_Handler(void) { static uint32_t tick = 0; static int led = 0; tick++; if (tick % 10000 == 0) { led = !led; if (led) GPIO_SetBits(GPIOB, GPIO_Pin_5); else GPIO_ResetBits(GPIOB, GPIO_Pin_5); } } consbuf_t cmd; RAMFUNC void USART1_IRQHandler(void) { char c; int i; /* Recieved data */ while (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { c = USART_ReceiveData(USART1); /* End of line? */ if (c == '\n' || c == '\r') { cmd.buf[cmd.state] = '\0'; fputs("\n", stdout); cmd.len = cmd.state; cmd.state = 255; continue; } /* Ctrl-w / Ctrl-u */ if (c == 0x17 || c == 0x15) { for (i = 0; i < cmd.state; i++) fputs("\010\040\010", stdout); cmd.state = 0; continue; } /* Backspace/delete */ if (c == 0x08 || c == 0x7f) { if (cmd.state > 0) { cmd.state--; fputs("\010\040\010", stdout); } continue; } /* Anything unprintable just ignore it */ if (!isprint(c)) continue; cmd.buf[cmd.state] = c; /* Echo back to the user */ comm_put(cmd.buf[cmd.state]); cmd.state++; /* Over flow? */ if (cmd.state == LINEBUF - 1) { fputs("\nLine too long", stdout); cmd.state = 0; continue; } } } int main(void) { char buf[40], *argv[MAXARGS], **ap, *tmp; int argc; struct tm nowtm; time_t now; uint16_t x, y, x1, y1, z1, z2, r, c, rx, ry; float t, t2; cmd.state = cmd.len = 0; cmd.buf = malloc(LINEBUF); /* Init hardware - configure IO ports and external peripherals */ hw_init(); /* NVIC configuration */ NVIC_Configuration(); /* Setup SysTick Timer rate, also enables Systick and Systick-Interrupt */ if (SysTick_Config(SystemCoreClock / TICK_FREQ)) { /* Capture error */ comm_puts("Can't setup SysTick\n"); while (1) ; } /* Set stdout to unbuffered */ setvbuf(stdout, NULL, _IONBF, 0); /* Say hello */ fputs("\n\n\nHello world\n", stdout); lcd_stripes(); lcd_circle(20, 20, 20, 1, LCD_RED); /* Bottom left */ lcd_circle(300, 220, 20, 1, LCD_WHITE); /* Top right */ lcd_circle(20, 220, 20, 1, LCD_BLUE); /* Top left */ lcd_circle(300, 20, 20, 1, LCD_GREEN); /* Bottom right */ lcd_line(20, 20, 20, 220, LCD_BLACK); lcd_line(20, 220, 300, 220, LCD_BLACK); lcd_line(300, 220, 300, 20, LCD_BLACK); lcd_line(300, 20, 20, 20, LCD_BLACK); lcd_ellipse(160, 120, 50, 30, 1, LCD_WHITE); lcd_ellipse(160, 120, 30, 50, 1, LCD_WHITE); /* Setup temperature control stuff */ tempctrl_init(); /* Setup sprinkler stuff */ sprink_init(); /* Setup SD card */ sd_init(); while (1) { fputs("> ", stdout); while (cmd.state != 255) { tempctrl_update(); sprink_update(); } if (cmd.len < 1) goto out; /* Split command string on space/tab boundaries into argv/argc */ argc = 0; tmp = cmd.buf; for (ap = argv; (*ap = strsep(&cmd.buf, " \t")) != NULL;) { if (**ap != '\0') { argc++; if (++ap >= &argv[MAXARGS]) break; } } /* Reset the buffer pointer after strsep() has mangled it */ cmd.buf = tmp; if (!strcmp("gc", argv[0])) { now = time(NULL); gmtime_r(&now, &nowtm); strftime(buf, sizeof(buf) - 1, "%Y/%m/%d %H:%M:%S UTC", &nowtm); printf("Time is %s (%d)\n", buf, (int)now); } else if (!strcmp("sc", argv[0])) { struct timeval tv; if (argc != 2) { fputs("Incorrect number of arguments\n", stdout); goto out; } tv.tv_sec = atoi(argv[1]); tv.tv_usec = 0; settimeofday(&tv, NULL); } else if (!strcmp("read", argv[0])) { printf("PB5 = %d\n", GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15)); } else if (!strcmp("touch", argv[0])) { for (int i = 0; i < 10; i++) { tp_getcoords(&x, &y, &z1, &z2, &t, &t2); printf("X = %5d Y = %5d Z1 = %5d Z2 = %5d T = %7.2f T2 = %7.2f\n", x, y, z1, z2, t, t2); } } else if (!strcmp("fl", argv[0])) { flashcmd(argc - 1, argv + 1); } else if (!strcmp("tc", argv[0])) { tempctrl_cmd(argc - 1, argv + 1); } else if (!strcmp("pwm", argv[0])) { lcd_setpwm(atoi(argv[1])); } else if (!strcmp("circ", argv[0])) { if (argc != 5) { fputs("Unable to parse circ args\n", stdout); goto out; } x = atoi(argv[1]); y = atoi(argv[2]); r = atoi(argv[3]); c = lcd_parsecol(argv[4][0]); lcd_circle(x, y, r, 0, c); } else if (!strncmp("ellip", cmd.buf, 6)) { if (argc != 5) { fputs("Unable to parse ellip args\n", stdout); goto out; } x = atoi(argv[1]); y = atoi(argv[2]); rx = atoi(argv[3]); ry = atoi(argv[4]); c = lcd_parsecol(argv[5][0]); lcd_ellipse(x, y, rx, ry, 0, c); } else if (!strncmp("line", cmd.buf, 5)) { if (argc != 5) { fputs("Unable to parse line args\n", stdout); goto out; } x = atoi(argv[1]); y = atoi(argv[2]); x1 = atoi(argv[3]); y1 = atoi(argv[4]); c = lcd_parsecol(argv[5][0]); lcd_line(x, y, x1, y1, c); } else if (!strcmp("delay", argv[0])) { for (x = 0; x < 100; x++) { GPIO_SetBits(GPIOE, GPIO_Pin_2); delay(30); GPIO_ResetBits(GPIOE, GPIO_Pin_2); delay(60); } } else if (!strcmp("cyc", argv[0])) { if (argc != 2) { fputs("Incorrect number of arguments\n", stdout); goto out; } GPIO_SetBits(GPIOE, GPIO_Pin_2); delay(atoi(argv[1])); GPIO_ResetBits(GPIOE, GPIO_Pin_2); fputs("Done\n", stdout); } else if (!strcmp("rs", argv[0])) { printf("Reset got %d\n", OWTouchReset()); } else if (!strcmp("sr", argv[0])) { uint8_t ROM[8]; int8_t i; memset(ROM, 0, 8); i = OWFirst(ROM, 1, 0); do { switch (i) { case OW_NOMODULES: case OW_FOUND: break; case OW_BADWIRE: case OW_NOPRESENCE: case OW_BADCRC: default: printf("Err %d\n", i); break; } if (i != OW_FOUND) break; for (i = 0; i < 8; i++) printf("%02x%s", ROM[i], i == 7 ? "\n" : ":"); i = OWNext(ROM, 1, 0); } while (1); } else if (!strcmp("rb", argv[0])) { printf("Read bit returned %d\n", OWReadBit()); } else if (!strcmp("wb", argv[0])) { if (argc != 2) { fputs("Incorrect number of arguments\n", stdout); goto out; } x = atoi(argv[1]); OWWriteBit(x); printf("Wrote %d\n", x); } else if (!strcmp("te", argv[0])) { uint8_t ROM[8]; int16_t res; if (sscanf(argv[1], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &ROM[0], &ROM[1], &ROM[2], &ROM[3], &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { fputs("Unable to parse ROM ID\n", stdout); goto out; } res = OWGetTemp(ROM); switch (res) { case OW_TEMP_WRONG_FAM: printf("ROM specified isn't a temperature sensor\n"); break; case OW_TEMP_CRC_ERR: printf("CRC mismatch\n"); break; case OW_TEMP_NO_ROM: printf("No ROM found\n"); break; default: printf("%hd.%02hd\n", GETWHOLE(res), GETFRAC(res)); break; } } else if (!strcmp("rtc", argv[0])) { float f, err, maxerr; uint32_t d, i; maxerr = 0; for (i = 0; i < 32768; i++) { d = RTC_PS2USEC(32768 - i); f = ((float)i * 1e6) / (float)RTC_PRESCALE; err = fabs(d - f); //rtcprintf("i = %d, d = %d, f = %.3f, err = %.3f\n", i, d, f, err); if (err > maxerr) maxerr = err; } printf("Max err = %.3f\n", maxerr); } else if (!strcmp("assert", argv[0])) { assert(0 == 1); } else if (!strcmp("sd", argv[0])) { sd_cmd(argc - 1, argv + 1); } else if (!strcmp("zz", argv[0])) { NVIC_SystemReset(); } else { printf("Unknown command\n"); } out: cmd.state = 0; } } /* Configure interrupt controller */ #ifdef VECT_TAB_RAM /* vector-offset (TBLOFF) from bottom of SRAM. defined in linker script */ extern uint32_t _isr_vectorsram_offs; #else extern uint32_t _isr_vectorsflash_offs; #endif void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000+_isr_vectorsram_offs */ NVIC_SetVectorTable(NVIC_VectTab_RAM, (uint32_t)&_isr_vectorsram_offs); #else /* Set the Vector Table base location at 0x08000000+_isr_vectorsflash_offs */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, (uint32_t)&_isr_vectorsflash_offs); #endif /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable the SDIO Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }