Compare commits

...

31 Commits

Author SHA1 Message Date
S.J.R. van Schaik 3484a7b3f6 shell: jtag: add command to enable/disable JTAG 6 years ago
S.J.R. van Schaik efb5a23859 shell: prevent overflow of IDs 6 years ago
S.J.R. van Schaik e05afe9cc9 stm32f1: gpio: prepare GPIOs 7 years ago
S.J.R. van Schaik 1c0a6907df clean up and size optimisations 7 years ago
S.J.R. van Schaik b5cdc92ba8 reset: remove old code 7 years ago
S.J.R. van Schaik 89605d6da0 main: add commands 7 years ago
S.J.R. van Schaik 914b168727 shell: led: add command to enable/disable LEDs 7 years ago
S.J.R. van Schaik 6394c5f006 shell: alarm: add command to enable/disable the alarm 7 years ago
S.J.R. van Schaik 0542810d22 stm32f0: stm32f1: alarm: implement functionality to enable and disable the alarm with a time-out for resetting the host 7 years ago
S.J.R. van Schaik 40ba5323f3 stm32f0: stm32f1: gpio: enable GPIO for LED 7 years ago
S.J.R. van Schaik a5dc77550d stm32f0: stm32f1: led: initial implementation 7 years ago
S.J.R. van Schaik ce71976939 make: add missing header files and update build system 7 years ago
S.J.R. van Schaik 8c8e7fc67c macros: implement count_of() 7 years ago
S.J.R. van Schaik 928487b58e main: initialize buzzers and add shell commands 7 years ago
S.J.R. van Schaik 56f2870fa4 shell: implement set-time command that accepts seconds since the UNIX epoch 7 years ago
S.J.R. van Schaik b369e3a1c0 shell: implement buzzer command 7 years ago
S.J.R. van Schaik 5730538c5f stm32f0: stm32f1: buzzer: initial implementation 7 years ago
S.J.R. van Schaik 0fb4d67cce stm32f0: stm32f1: gpio: rcc: set up timers for PWM 7 years ago
S.J.R. van Schaik 43e3476a6d stm32f1: rtc: use external crystal 7 years ago
S.J.R. van Schaik 6fb626d601 shell: use amount of bytes returned from mufs_read() 7 years ago
S.J.R. van Schaik d1457e8be6 usart: stm32f0: stm32f1: do not null-terminate the buffer in console_read() 7 years ago
S.J.R. van Schaik 4739b8f995 mufs: return actual amount of bytes read in mufs_read() 7 years ago
S.J.R. van Schaik 676c9bdbb0 alarm: stm32f0: stm32f1: initial implementation 7 years ago
S.J.R. van Schaik d66c6da847 gpio: stm32f1: remove old code 7 years ago
S.J.R. van Schaik 3937042b19 gpio: stm32f0: stm32f1: set up reset pin 7 years ago
S.J.R. van Schaik 45d51197b1 stm32f0: stm32f1: usart: have console_read() only react to Ctrl+D and not echo the user input 7 years ago
S.J.R. van Schaik b006de37ad shell: generalise interface of mufs write/mufs append by reading stdin 7 years ago
S.J.R. van Schaik 3df8a7afdf main: check if the flash chip can be probed properly 7 years ago
S.J.R. van Schaik ece960b3c9 stm32f0: stm32f1: usart: send \r\n instead of \r 7 years ago
S.J.R. van Schaik 1e9a5b3fe4 shell: return exit code for admin shell 7 years ago
S.J.R. van Schaik 1503c6f0ed usart: set baud rate to 115200 7 years ago
  1. 2
      Makefile
  2. 13
      include/buzzer.h
  3. 10
      include/led.h
  4. 2
      include/macros.h
  5. 5
      include/rtc.h
  6. 12
      include/shell.h
  7. 3
      include/shell/alarm.h
  8. 3
      include/shell/buzzer.h
  9. 3
      include/shell/led.h
  10. 1
      include/shell/mufs.h
  11. 1
      include/shell/rtc.h
  12. 44
      source/drivers/reset.c
  13. 82
      source/main.c
  14. 1
      source/mufs/file.c
  15. 3
      source/platform/stm32f0/Makefile
  16. 143
      source/platform/stm32f0/alarm.c
  17. 51
      source/platform/stm32f0/buzzer.c
  18. 20
      source/platform/stm32f0/gpio.c
  19. 31
      source/platform/stm32f0/led.c
  20. 7
      source/platform/stm32f0/rcc.c
  21. 3
      source/platform/stm32f1/Makefile
  22. 56
      source/platform/stm32f1/alarm.c
  23. 49
      source/platform/stm32f1/buzzer.c
  24. 24
      source/platform/stm32f1/gpio.c
  25. 32
      source/platform/stm32f1/led.c
  26. 2
      source/platform/stm32f1/rcc.c
  27. 2
      source/platform/stm32f1/rtc.c
  28. 54
      source/platform/usart.c
  29. 7
      source/shell/Makefile
  30. 30
      source/shell/alarm.c
  31. 15
      source/shell/boot.c
  32. 47
      source/shell/buzzer.c
  33. 4
      source/shell/echo.c
  34. 32
      source/shell/flash.c
  35. 17
      source/shell/ftl.c
  36. 36
      source/shell/led.c
  37. 54
      source/shell/mufs.c
  38. 22
      source/shell/rtc.c
  39. 2
      source/shell/version.c

@ -12,7 +12,7 @@ all: $(BUILD)/tbm
-include scripts/Makefile.${TARGET}
CFLAGS += -DTBM_VERSION=\"2017-07-27-dev\"
CFLAGS += -DTBM_VERSION=\"2017-10-31\"
CFLAGS += -Iinclude
CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration
CFLAGS += -Wredundant-decls -pedantic

@ -0,0 +1,13 @@
#pragma once
#include <libopencm3/stm32/timer.h>
struct buzzer {
uint32_t timer;
enum tim_oc_id channel;
};
void buzzer_init(struct buzzer *buzzer);
void buzzer_enable(struct buzzer *buzzer);
void buzzer_disable(struct buzzer *buzzer);
void buzzer_set_freq(struct buzzer *buzzer, uint32_t freq);

@ -0,0 +1,10 @@
#pragma once
struct led {
uint32_t port;
uint32_t pin;
int invert;
};
void led_enable(struct led *led);
void led_disable(struct led *led);

@ -17,6 +17,8 @@
#define MIB (1024 * KIB)
#define GIB (1024 * MIB)
#define count_of(x) (sizeof(x) / sizeof(*(x)))
#define container_of(ptr, type, member) \
(type *)((char *)ptr - offsetof(type, member))

@ -2,6 +2,11 @@
#include <time.h>
#define SECS_PER_DAY (24 * 60 * 60)
int rtc_init(struct tm *time);
int rtc_get_time(struct tm *time);
time_t rtc_time(void);
int alarm_enable(uint32_t timeout);
int alarm_disable(void);

@ -6,7 +6,6 @@ struct console;
struct cmd {
const char *cmd;
const char *desc;
int (* exec)(struct console *con, size_t argc, const char **argv);
};
@ -31,6 +30,11 @@ int shell_init(struct shell *shell, struct cmd *cmds,
struct console *con, const char *prompt, unsigned flags);
int shell_parse(struct shell *shell);
int do_flash_cmd(struct console *con, size_t argc, const char **argv);
int do_ftl_cmd(struct console *con, size_t argc, const char **argv);
int do_mufs_cmd(struct console *con, size_t argc, const char **argv);
int shell_flash_probe(struct console *con, size_t argc, const char **argv);
int shell_flash_release(struct console *con, size_t argc, const char **argv);
int shell_flash_info(struct console *con, size_t argc, const char **argv);
int shell_flash_read(struct console *con, size_t argc, const char **argv);
int shell_flash_write(struct console *con, size_t argc, const char **argv);
int shell_flash_erase(struct console *con, size_t argc, const char **argv);
int shell_ftl_probe(struct console *con, size_t argc, const char **argv);

@ -0,0 +1,3 @@
#pragma once
int shell_alarm(struct console *con, size_t argc, const char **argv);

@ -0,0 +1,3 @@
#pragma once
int shell_buzzer(struct console *con, size_t argc, const char **argv);

@ -0,0 +1,3 @@
#pragma once
int shell_led(struct console *con, size_t argc, const char **argv);

@ -10,5 +10,6 @@ int shell_cat(struct console *con, size_t argc, const char **argv);
int shell_write(struct console *con, size_t argc, const char **argv);
int shell_append(struct console *con, size_t argc, const char **argv);
int shell_mv(struct console *con, size_t argc, const char **argv);
int shell_cp(struct console *con, size_t argc, const char **argv);
int shell_rm(struct console *con, size_t argc, const char **argv);
int shell_ls(struct console *con, size_t argc, const char **argv);

@ -5,3 +5,4 @@ struct console;
int shell_date(struct console *con, size_t argc, const char **argv);
int shell_time(struct console *con, size_t argc, const char **argv);
int shell_set_date(struct console *con, size_t argc, const char **argv);
int shell_set_time(struct console *con, size_t argc, const char **argv);

@ -1,44 +0,0 @@
/* This is our reset code (tested).
*
* TODO: integrate fully within code base.
*/
#include <stdio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
static void delay(unsigned ms)
{
unsigned i;
for (i = 0; i < 1000 * ms; ++i) {
__asm__("nop");
}
}
int main(void)
{
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOC);
gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO11);
gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, GPIO11);
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8);
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO9);
while (1) {
gpio_set(GPIOB, GPIO11);
gpio_clear(GPIOC, GPIO8);
gpio_set(GPIOC, GPIO9);
delay(5 * 5000);
gpio_clear(GPIOB, GPIO11);
gpio_set(GPIOC, GPIO8);
gpio_clear(GPIOC, GPIO9);
delay(5 * 5000);
}
return 0;
}

@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <buzzer.h>
#include <console.h>
#include <gpio.h>
#include <flash.h>
@ -12,8 +13,12 @@
#include <rtc.h>
#include <shell.h>
#include <shell/alarm.h>
#include <shell/boot.h>
#include <shell/buzzer.h>
#include <shell/echo.h>
#include <shell/jtag.h>
#include <shell/led.h>
#include <shell/mufs.h>
#include <shell/rtc.h>
#include <shell/version.h>
@ -23,47 +28,86 @@ struct shell user_shell, admin_shell;
extern struct flash_dev *flash;
extern struct mufs *mufs;
extern struct buzzer buzzers[];
extern size_t nbuzzers;
struct cmd user_cmds[] = {
{ "hi", "", shell_version },
{ "cat", "", shell_cat },
{ "ls", "", shell_ls },
{ "date", "", shell_date },
{ "time", "", shell_time },
{ "booting", "", shell_prepare },
{ NULL, NULL, NULL },
{ "hi", shell_version },
{ "buzzer", shell_buzzer },
{ "led", shell_led },
{ "reset", shell_alarm },
{ "cat", shell_cat },
{ "ls", shell_ls },
{ "date", shell_date },
{ "time", shell_time },
{ "booting", shell_prepare },
{ NULL, NULL },
};
struct cmd admin_cmds[] = {
{ "echo", "", shell_echo },
{ "flash", "", do_flash_cmd },
{ "ftl", "", do_ftl_cmd },
{ "mufs", "", do_mufs_cmd },
{ "date", "", shell_date },
{ "time", "", shell_time },
{ "set-date", "", shell_set_date },
{ NULL, NULL, NULL },
{ "echo", shell_echo },
#ifdef STM32F1
{ "jtag", shell_jtag },
#endif
{ "buzzer", shell_buzzer },
{ "led", shell_led },
{ "reset", shell_alarm },
{ "flash_probe", shell_flash_probe },
{ "flash_release", shell_flash_release },
{ "flash_info", shell_flash_info },
{ "flash_read", shell_flash_read },
{ "flash_write", shell_flash_write },
{ "flash_erase", shell_flash_erase },
{ "ftl_probe", shell_ftl_probe },
{ "date", shell_date },
{ "time", shell_time },
{ "set_date", shell_set_date },
{ "set_time", shell_set_time },
{ "mount", shell_mount },
{ "umount", shell_unmount },
{ "format", shell_format },
{ "mkdir", shell_mkdir },
{ "rmdir", shell_rmdir },
{ "ls", shell_ls },
{ "stat", shell_stat },
{ "cat", shell_cat },
{ "write", shell_write },
{ "append", shell_append },
{ "mv", shell_mv, },
{ "cp", shell_cp, },
{ "rm", shell_rm, },
{ NULL, NULL },
};
int main(void)
{
size_t i;
rcc_init();
gpio_init();
rtc_init(NULL);
for (i = 0; i < nbuzzers; ++i) {
buzzer_init(buzzers + i);
}
user_con = console_init(1);
admin_con = console_init(0);
flash = flash_probe();
flash = ftl_mount(flash);
mufs = mufs_mount(flash);
if ((flash = flash_probe())) {
flash = ftl_mount(flash);
mufs = mufs_mount(flash);
} else {
fprintf(admin_con->fp, "error: unable to probe flash chip.\n");
}
fprintf(user_con->fp, "TBM-dev (built on " __DATE__ ")\n");
fprintf(admin_con->fp, "TBM-dev (built on " __DATE__ ")\n");
shell_init(&user_shell, user_cmds, user_con, "tbm $",
SHELL_SHOW_EXIT_CODE);
shell_init(&admin_shell, admin_cmds, admin_con, "tbm #", 0);
shell_init(&admin_shell, admin_cmds, admin_con, "tbm #",
SHELL_SHOW_EXIT_CODE);
while (1) {
shell_parse(&user_shell);

@ -104,6 +104,7 @@ size_t mufs_read(struct mufs_file *file, void *data, size_t len)
if (!(ret = mufs_tree_read(file->tree, data, file->va, len)))
return 0;
ret = min(ret, file->tree->file_size - file->va);
file->va += ret;
return ret;

@ -1,7 +1,10 @@
obj-y += source/platform/spi_flash.o
obj-y += source/platform/usart.o
obj-y += source/platform/stm32f0/alarm.o
obj-y += source/platform/stm32f0/buzzer.o
obj-y += source/platform/stm32f0/gpio.o
obj-y += source/platform/stm32f0/led.o
obj-y += source/platform/stm32f0/rcc.o
obj-y += source/platform/stm32f0/rtc.o
obj-y += source/platform/stm32f0/spi.o

@ -0,0 +1,143 @@
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/rtc.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/pwr.h>
#include <rtc.h>
static int reset = 0;
static uint8_t u8_to_bcd(uint8_t val)
{
uint32_t quot = (uint32_t)val / 10;
uint32_t rem = val - quot * 10;
return (quot << 4) | rem;
}
static inline uint32_t rtc_to_sec(uint32_t rtc)
{
uint32_t sec;
sec = (rtc & 0xf) + ((rtc >> 4) & 0xf) * 10;
sec += (((rtc >> 8) & 0xf) + ((rtc >> 12) & 0xf) * 10) * 60;
sec += (((rtc >> 16) & 0xf) + ((rtc >> 20) & 0xf) * 10) * 3600;
return sec;
}
static inline uint32_t sec_to_rtc(uint32_t sec)
{
uint32_t rtc;
uint8_t hour;
uint8_t min;
sec %= SECS_PER_DAY;
hour = sec / 3600;
rtc = u8_to_bcd(hour) << 16;
sec -= hour * 3600;
min = sec / 60;
rtc |= u8_to_bcd(min) << 8;
sec -= min * 60;
rtc |= u8_to_bcd(sec);
return rtc;
}
static void rtc_enable_alarm_interrupt(void)
{
exti_enable_request(EXTI17);
exti_set_trigger(EXTI17, EXTI_TRIGGER_RISING);
nvic_enable_irq(NVIC_RTC_IRQ);
nvic_set_priority(NVIC_RTC_IRQ, 1);
RTC_CR |= RTC_CR_ALRAIE;
}
static void rtc_disable_alarm_interrupt(void)
{
exti_disable_request(EXTI17);
nvic_disable_irq(NVIC_RTC_IRQ);
RTC_CR &= ~RTC_CR_ALRAIE;
}
void rtc_isr(void)
{
uint32_t alarm_sec;
gpio_toggle(GPIOC, GPIO8);
pwr_disable_backup_domain_write_protect();
rtc_unlock();
/* Disable the alarm. */
RTC_CR &= ~RTC_CR_ALRAE;
RTC_ISR &= ~RTC_ISR_ALRAF;
exti_reset_request(EXTI17);
if (!reset) {
reset = 1;
gpio_set(GPIOA, GPIO1);
/* Set the alarm time. */
alarm_sec = rtc_to_sec(RTC_TR);
(volatile void)RTC_DR;
RTC_ALRMAR = sec_to_rtc(alarm_sec + 5) | 0xc0000000;
/* Enable the alarm. */
RTC_CR |= RTC_CR_ALRAE;
} else {
reset = 0;
gpio_clear(GPIOA, GPIO1);
alarm_disable();
}
rtc_lock();
pwr_enable_backup_domain_write_protect();
}
int alarm_enable(uint32_t timeout)
{
uint32_t alarm_sec;
pwr_disable_backup_domain_write_protect();
rtc_unlock();
/* Set the alarm time. */
alarm_sec = rtc_to_sec(RTC_TR);
(volatile void)RTC_DR;
RTC_ALRMAR = sec_to_rtc(alarm_sec + timeout) | 0xc0000000;
RTC_CR |= RTC_CR_ALRAE;
rtc_enable_alarm_interrupt();
rtc_lock();
pwr_enable_backup_domain_write_protect();
return 0;
}
int alarm_disable(void)
{
gpio_set(GPIOC, GPIO8);
pwr_disable_backup_domain_write_protect();
rtc_unlock();
RTC_CR &= ~RTC_CR_ALRAE;
rtc_disable_alarm_interrupt();
rtc_lock();
pwr_enable_backup_domain_write_protect();
return 0;
}

@ -0,0 +1,51 @@
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#include <buzzer.h>
#include <macros.h>
struct buzzer buzzers[] = {
{ TIM1, TIM_OC1 },
{ TIM2, TIM_OC2 },
{ TIM3, TIM_OC1 },
{ TIM14, TIM_OC1 },
};
size_t nbuzzers = count_of(buzzers);
void buzzer_init(struct buzzer *buzzer)
{
timer_reset(buzzer->timer);
timer_set_mode(buzzer->timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_set_prescaler(buzzer->timer, 48);
timer_set_repetition_counter(buzzer->timer, 0);
timer_enable_preload(buzzer->timer);
timer_enable_break_main_output(buzzer->timer);
timer_continuous_mode(buzzer->timer);
timer_disable_oc_output(buzzer->timer, buzzer->channel);
timer_set_oc_mode(buzzer->timer, buzzer->channel, TIM_OCM_PWM1);
timer_set_oc_value(buzzer->timer, buzzer->channel, 0);
timer_enable_oc_output(buzzer->timer, buzzer->channel);
}
void buzzer_enable(struct buzzer *buzzer)
{
timer_enable_counter(buzzer->timer);
}
void buzzer_disable(struct buzzer *buzzer)
{
timer_disable_counter(buzzer->timer);
}
void buzzer_set_freq(struct buzzer *buzzer, uint32_t freq)
{
uint32_t period = 1000000 / freq;
timer_set_period(buzzer->timer, period);
timer_set_oc_value(buzzer->timer, buzzer->channel, period / 2);
}

@ -18,6 +18,26 @@ int gpio_init(void)
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO3);
gpio_set_af(GPIOA, GPIO_AF1, GPIO2 | GPIO3);
/* Set up GPIOs for reset. */
gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO1);
gpio_set_output_options(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, GPIO1);
/* Set up GPIOs for timers */
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8);
gpio_set_af(GPIOA, GPIO_AF2, GPIO8);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO1);
gpio_set_af(GPIOA, GPIO_AF2, GPIO1);
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO4);
gpio_set_af(GPIOB, GPIO_AF1, GPIO4);
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO1);
gpio_set_af(GPIOB, GPIO_AF2, GPIO1);
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8);
gpio_set(GPIOC, GPIO8);
return 0;
}

@ -0,0 +1,31 @@
#include <libopencm3/stm32/gpio.h>
#include <led.h>
#include <macros.h>
struct led leds[] = {
{ GPIOC, GPIO8, 0 },
};
size_t nleds = count_of(leds);
void led_enable(struct led *led)
{
if (!led)
return;
if (led->invert)
gpio_clear(led->port, led->pin);
else
gpio_set(led->port, led->pin);
}
void led_disable(struct led *led)
{
if (!led)
return;
if (led->invert)
gpio_set(led->port, led->pin);
else
gpio_clear(led->port, led->pin);
}

@ -4,11 +4,18 @@
int rcc_init(void)
{
rcc_clock_setup_in_hsi_out_48mhz();
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOC);
rcc_periph_clock_enable(RCC_SPI1);
rcc_periph_clock_enable(RCC_USART1);
rcc_periph_clock_enable(RCC_USART2);
rcc_periph_clock_enable(RCC_TIM1);
rcc_periph_clock_enable(RCC_TIM2);
rcc_periph_clock_enable(RCC_TIM3);
rcc_periph_clock_enable(RCC_TIM14);
return 0;
}

@ -1,7 +1,10 @@
obj-y += source/platform/spi_flash.o
obj-y += source/platform/usart.o
obj-y += source/platform/stm32f1/alarm.o
obj-y += source/platform/stm32f1/buzzer.o
obj-y += source/platform/stm32f1/gpio.o
obj-y += source/platform/stm32f1/led.o
obj-y += source/platform/stm32f1/rcc.o
obj-y += source/platform/stm32f1/rtc.o
obj-y += source/platform/stm32f1/spi.o

@ -0,0 +1,56 @@
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rtc.h>
#include <rtc.h>
static int reset = 0;
void rtc_alarm_isr(void)
{
if (rtc_check_flag(RTC_ALR)) {
rtc_clear_flag(RTC_ALR);
rtc_disable_alarm();
exti_reset_request(EXTI17);
if (!reset) {
reset = 1;
gpio_set(GPIOA, GPIO1);
rtc_set_alarm_time(rtc_get_counter_val() + 5);
rtc_enable_alarm();
} else {
reset = 0;
gpio_set(GPIOA, GPIO1);
alarm_disable();
}
}
}
int alarm_enable(uint32_t timeout)
{
rtc_enable_alarm();
rtc_set_alarm_time(rtc_get_counter_val() + timeout);
exti_enable_request(EXTI17);
exti_set_trigger(EXTI17, EXTI_TRIGGER_RISING);
nvic_enable_irq(NVIC_RTC_ALARM_IRQ);
nvic_set_priority(NVIC_RTC_ALARM_IRQ, 1);
rtc_interrupt_enable(RTC_ALR);
return 0;
}
int alarm_disable(void)
{
exti_disable_request(EXTI17);
nvic_disable_irq(NVIC_RTC_ALARM_IRQ);
rtc_interrupt_disable(RTC_ALR);
rtc_disable_alarm();
return 0;
}

@ -0,0 +1,49 @@
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#include <buzzer.h>
#include <macros.h>
struct buzzer buzzers[] = {
{ TIM2, TIM_OC1 },
};
size_t nbuzzers = count_of(buzzers);
void buzzer_init(struct buzzer *buzzer)
{
timer_reset(buzzer->timer);
timer_set_mode(buzzer->timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE,
TIM_CR1_DIR_UP);
timer_set_prescaler(buzzer->timer, 72);
timer_set_repetition_counter(buzzer->timer, 0);
timer_enable_preload(buzzer->timer);
timer_enable_break_main_output(buzzer->timer);
timer_continuous_mode(buzzer->timer);
timer_disable_oc_output(buzzer->timer, buzzer->channel);
timer_set_oc_mode(buzzer->timer, buzzer->channel, TIM_OCM_PWM1);
timer_set_oc_value(buzzer->timer, buzzer->channel, 0);
timer_enable_oc_output(buzzer->timer, buzzer->channel);
}
void buzzer_enable(struct buzzer *buzzer)
{
timer_enable_counter(buzzer->timer);
}
void buzzer_disable(struct buzzer *buzzer)
{
timer_disable_counter(buzzer->timer);
}
void buzzer_set_freq(struct buzzer *buzzer, uint32_t freq)
{
uint32_t period = 1000000 / freq;
timer_set_period(buzzer->timer, period);
timer_set_oc_value(buzzer->timer, buzzer->channel, period / 2);
}

@ -12,26 +12,34 @@ int gpio_init(void)
GPIO_SPI1_MOSI);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO_SPI1_MISO);
/*gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO4);
gpio_set(GPIOA, GPIO4);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO5 | GPIO6 | GPIO7);
gpio_set_af(GPIOA, GPIO_AF0, GPIO5 | GPIO6 | GPIO7);*/
/* Set up GPIOs for user console (USART 1) */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO_USART1_RX);
/*gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO10);
gpio_set_af(GPIOA, GPIO_AF1, GPIO9 | GPIO10);*/
/* Set up GPIOs for admin console (USART 2) */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO_USART2_RX);
/*gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO3);
gpio_set_af(GPIOA, GPIO_AF1, GPIO2 | GPIO3);*/
/* Set up GPIOs for reset. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN,
GPIO1);
/* Set up GPIOs for timers. */
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON,
AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP1);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_TIM2_PR1_CH1_ETR);
/* Set up GPIO for LED. */
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO0);
gpio_clear(GPIOB, GPIO0);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO10);
gpio_set(GPIOC, GPIO10);
return 0;
}

@ -0,0 +1,32 @@
#include <libopencm3/stm32/gpio.h>
#include <led.h>
#include <macros.h>
struct led leds[] = {
{ GPIOC, GPIO10, 1 },
};
size_t nleds = count_of(leds);
void led_enable(struct led *led)
{
if (!led)
return;
if (led->invert)
gpio_clear(led->port, led->pin);
else
gpio_set(led->port, led->pin);
}
void led_disable(struct led *led)
{
if (!led)
return;
if (led->invert)
gpio_set(led->port, led->pin);
else
gpio_clear(led->port, led->pin);
}

@ -7,9 +7,11 @@ int rcc_init(void)
rcc_periph_clock_enable(RCC_AFIO);
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOC);
rcc_periph_clock_enable(RCC_SPI1);
rcc_periph_clock_enable(RCC_USART1);
rcc_periph_clock_enable(RCC_USART2);
rcc_periph_clock_enable(RCC_TIM2);
return 0;
}

@ -35,7 +35,7 @@ static int rtc_set_time(struct tm *time)
int rtc_init(struct tm *time)
{
rtc_auto_awake(RCC_LSI, 0x7fff);
rtc_auto_awake(RCC_LSE, 0x7fff);
rtc_set_time(time);
return 0;

@ -16,6 +16,7 @@
#include <console.h>
#include <macros.h>
#define CONFIG_USER_ECHO 1
#define RECV_BUF_LEN 128
struct usart_console {
@ -109,6 +110,7 @@ int console_getline(struct console *console_, char *buf, size_t n)
case '\r':
#if CONFIG_USER_ECHO
usart_send_blocking(console->dev, '\r');
usart_send_blocking(console->dev, '\n');
#endif
return 0;
case 10:
@ -143,63 +145,26 @@ int console_getline(struct console *console_, char *buf, size_t n)
return -EAGAIN;
}
ssize_t console_read(struct console *console_, char *buf, size_t n)
ssize_t console_read(struct console *console, char *buf, size_t n)
{
struct usart_console *console = container_of(console_,
struct usart_console, console);
char *p = buf;
char c;
*buf = '\0';
while (console_peek(&c, console_, 1) == 0) {
while (console_peek(&c, console, 1) == 0) {
switch (c) {
case '\004':
if (buf < p)
goto out;
console_getc(&c, console_);
return 0;
case 10:
case 127:
if (buf < p) {
#if CONFIG_USER_ECHO
usart_send_blocking(console->dev, '\010');
usart_send_blocking(console->dev, ' ');
usart_send_blocking(console->dev, '\010');
#endif
--p;
}
console_getc(&c, console_);
break;
case '\r':
if (((size_t)p - (size_t)buf) >= n)
goto out;
*p++ = '\n';
#if CONFIG_USER_ECHO
usart_send_blocking(console->dev, '\r');
#endif
console_getc(&c, console_);
goto out;
console_getc(&c, console);
return p - buf;
default:
if (((size_t)p - (size_t)buf) >= n)
goto out;
return p - buf;
*p++ = c;
#if CONFIG_USER_ECHO
usart_send_blocking(console->dev, c);
#endif
console_getc(&c, console_);
console_getc(&c, console);
break;
}
}
out:
*p = '\0';
return p - buf;
}
@ -214,7 +179,6 @@ static ssize_t usart_write(void *cookie, const char *buf, size_t n)
if (buf[i] == '\n') {
usart_send_blocking(console->dev, '\r');
continue;
}
usart_send_blocking(console->dev, buf[i]);
@ -242,7 +206,7 @@ static int usart_init(struct usart_console *console)
if (usart_get_irq_no(&console->irq_no, console->dev) < 0)
return -1;
usart_set_baudrate(console->dev, 9600);
usart_set_baudrate(console->dev, 115200);
usart_set_databits(console->dev, 8);
usart_set_parity(console->dev, USART_PARITY_NONE);
usart_set_stopbits(console->dev, USART_STOPBITS_1);

@ -1,10 +1,17 @@
obj-y += source/shell/alarm.o
obj-y += source/shell/args.o
obj-y += source/shell/boot.o
obj-y += source/shell/buzzer.o
obj-y += source/shell/cmd.o
obj-y += source/shell/echo.o
obj-y += source/shell/flash.o
obj-y += source/shell/ftl.o
obj-y += source/shell/led.o
obj-y += source/shell/mufs.o
obj-y += source/shell/progress.o
obj-y += source/shell/rtc.o
obj-y += source/shell/version.o
ifeq (${TARGET},stm32f1)
obj-y += source/shell/jtag.o
endif

@ -0,0 +1,30 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libopencm3/stm32/gpio.h>
#include <console.h>
#include <rtc.h>
int shell_alarm(struct console *con, size_t argc, const char **argv)
{
int state = 0;
uint32_t timeout = 10;
(void)con;
if (argc >= 2)
timeout = strtoul(argv[0], NULL, 0);
if (argc >= 1)
state = (strcmp(argv[1], "on") == 0);
if (state) {
alarm_enable(timeout);
} else {
alarm_disable();
}
return 0;
}

@ -7,14 +7,25 @@
#include <mufs.h>
#include <shell.h>
#include <shell/alarm.h>
#include <shell/boot.h>
#include <shell/buzzer.h>
#include <shell/led.h>
#include <shell/rtc.h>
#include <shell/version.h>
extern struct mufs *mufs;
extern struct shell user_shell;
struct cmd safe_cmds[] = {
{ "booting", "", shell_boot },
{ NULL, NULL, NULL },
{ "hi", shell_version },
{ "buzzer", shell_buzzer },
{ "led", shell_led },
{ "reset", shell_alarm },
{ "date", shell_date },
{ "time", shell_time },
{ "booting", shell_boot },
{ NULL, NULL },
};
int shell_prepare(struct console *con, size_t argc, const char **argv)

@ -0,0 +1,47 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <buzzer.h>
#include <console.h>
extern struct buzzer buzzers[];
extern size_t nbuzzers;
int shell_buzzer(struct console *con, size_t argc, const char **argv)
{
struct buzzer *buzzer;
size_t buzzer_id = 0;
uint32_t freq = 0;
int state = 0;
if (argc >= 3)
freq = strtoul(argv[2], NULL, 0);
if (argc >= 2)
state = (strcmp(argv[1], "on") == 0);
if (argc >= 1)
buzzer_id = strtoul(argv[0], NULL, 0);
fprintf(con->fp, "%u %d %u\n", buzzer_id, state, freq);
if (buzzer_id >= nbuzzers) {
fprintf(con->fp, "error: invalid buzzer ID %d\n", buzzer_id);
return -1;
}
buzzer = buzzers + buzzer_id;
if (!state) {
buzzer_disable(buzzer);
return 0;
}
if (freq)
buzzer_set_freq(buzzer, freq);
buzzer_enable(buzzer);
return 0;
}

@ -9,9 +9,7 @@ int shell_echo(struct console *con, size_t argc, const char **argv)
if (argc < 1)
return -1;
fprintf(con->fp, "%s\n", argv[0]);
fputs(argv[0], con->fp);
return 0;
}

@ -57,7 +57,7 @@ static void print_hex_ascii(FILE *fp, uint32_t offset, const char *buf, size_t l
}
}
static int do_flash_probe(struct console *con, size_t argc, const char **argv)
int shell_flash_probe(struct console *con, size_t argc, const char **argv)
{
(void)argv;
(void)argc;
@ -75,7 +75,7 @@ static int do_flash_probe(struct console *con, size_t argc, const char **argv)
return 0;
}
static int do_flash_release(struct console *con, size_t argc, const char **argv)
int shell_flash_release(struct console *con, size_t argc, const char **argv)
{
(void)argv;
(void)argc;
@ -91,7 +91,7 @@ static int do_flash_release(struct console *con, size_t argc, const char **argv)
return 0;
}
static int do_flash_info(struct console *con, size_t argc, const char **argv)
int shell_flash_info(struct console *con, size_t argc, const char **argv)
{
char jedec_id[3] = { 0, 0, 0 };
size_t size, capacity;
@ -118,7 +118,7 @@ static int do_flash_info(struct console *con, size_t argc, const char **argv)
return 0;
}
static int do_flash_read(struct console *con, size_t argc, const char **argv)
int shell_flash_read(struct console *con, size_t argc, const char **argv)
{
char buf[256];
size_t addr, len, nbytes;
@ -162,7 +162,7 @@ static int do_flash_read(struct console *con, size_t argc, const char **argv)
return 0;
}
static int do_flash_write(struct console *con, size_t argc, const char **argv)
int shell_flash_write(struct console *con, size_t argc, const char **argv)
{
char buf[256];
size_t addr, len, nbytes;
@ -211,7 +211,7 @@ static int do_flash_write(struct console *con, size_t argc, const char **argv)
return 0;
}
static int do_flash_erase(struct console *con, size_t argc, const char **argv)
int shell_flash_erase(struct console *con, size_t argc, const char **argv)
{
size_t addr, len;
@ -246,23 +246,3 @@ static int do_flash_erase(struct console *con, size_t argc, const char **argv)
return 0;
}
static struct cmd flash_cmds[] = {
{ "probe", NULL, do_flash_probe },
{ "release", NULL, do_flash_release },
{ "info", NULL, do_flash_info },
{ "read", NULL, do_flash_read },
{ "write", NULL, do_flash_write },
{ "erase", NULL, do_flash_erase },
{ NULL, NULL, NULL },
};
int do_flash_cmd(struct console *con, size_t argc, const char **argv)
{
if (argc < 1) {
fprintf(con->fp, "usage: flash <command>\n");
return -1;
}
return cmd_exec(flash_cmds, con, argc, argv);
}

@ -15,7 +15,7 @@
extern struct flash_dev *flash;
static int do_ftl_probe(struct console *con, size_t argc, const char **argv)
int shell_ftl_probe(struct console *con, size_t argc, const char **argv)
{
(void)argv;
(void)argc;
@ -37,18 +37,3 @@ static int do_ftl_probe(struct console *con, size_t argc, const char **argv)
return 0;
}
static struct cmd ftl_cmds[] = {
{ "probe", NULL, do_ftl_probe },
{ NULL, NULL, NULL },
};
int do_ftl_cmd(struct console *con, size_t argc, const char **argv)
{
if (argc < 1) {
fprintf(con->fp, "usage: flash <command>\n");
return -1;
}
return cmd_exec(ftl_cmds, con, argc, argv);
}

@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libopencm3/stm32/gpio.h>
#include <console.h>
#include <led.h>
extern struct led leds[];
extern size_t nleds;
int shell_led(struct console *con, size_t argc, const char **argv)
{
size_t led_id = 0;
int state = 0;
if (argc >= 2)
state = (strcmp(argv[1], "on") == 0);
if (argc >= 1)
led_id = strtoul(argv[0], NULL, 0);
if (led_id >= nleds) {
fprintf(con->fp, "error: unknown LED ID %d\n", led_id);
return -1;
}
if (state) {
led_enable(leds + led_id);
} else {
led_disable(leds + led_id);
}
return 0;
}

@ -159,6 +159,7 @@ int shell_cat(struct console *con, size_t argc, const char **argv)
{
char data[256];
struct mufs_file *file;
size_t ret;
if (argc < 1) {
fprintf(con->fp, "usage: mufs cat <path>\n");
@ -175,8 +176,8 @@ int shell_cat(struct console *con, size_t argc, const char **argv)
return -1;
}
while (mufs_read(file, data, sizeof data) != 0) {
fwrite(data, sizeof *data, sizeof data, con->fp);
while ((ret = mufs_read(file, data, sizeof data)) != 0) {
fwrite(data, sizeof *data, ret, con->fp);
}
mufs_close(file);
@ -205,18 +206,9 @@ int shell_write(struct console *con, size_t argc, const char **argv)
return -1;
}
#if CONFIG_USER_ECHO
fprintf(con->fp, "> ");
#endif
while ((ret = console_read(con, data, sizeof data)) > 0) {
if ((ret = console_read(con, data, sizeof data)) > 0)
mufs_write(file, data, ret);
#if CONFIG_USER_ECHO
fprintf(con->fp, "\n> ");
#endif
}
mufs_close(file);
return 0;
@ -224,12 +216,12 @@ int shell_write(struct console *con, size_t argc, const char **argv)
int shell_append(struct console *con, size_t argc, const char **argv)
{
struct mufs_file *file;
char data[256];
size_t n;
struct mufs_file *file;
ssize_t ret;
if (argc < 2) {
fprintf(con->fp, "usage: mufs append <path> <line>\n");
if (argc < 1) {
fprintf(con->fp, "usage: mufs append <path>\n");
return -1;
}
@ -243,13 +235,9 @@ int shell_append(struct console *con, size_t argc, const char **argv)
return -1;
}
n = strlen(argv[1]);
memcpy(data, argv[1], n);
data[n] = '\n';
data[n + 1] = '\0';
if ((ret = console_read(con, data, sizeof data)) > 0)
mufs_write(file, data, ret);
mufs_write(file, data, n + 1);
mufs_close(file);
return 0;
@ -392,25 +380,3 @@ int shell_ls(struct console *con, size_t argc, const char **argv)
mufs_closedir(dir);
return 0;
}
static struct cmd mufs_cmds[] = {
{ "mount", NULL, shell_mount },
{ "umount", NULL, shell_unmount },
{ "format", NULL, shell_format },
{ "mkdir", NULL, shell_mkdir },
{ "rmdir", NULL, shell_rmdir },
{ "ls", NULL, shell_ls },
{ "stat", NULL, shell_stat },
{ "cat", NULL, shell_cat },
{ "write", NULL, shell_write },
{ "append", NULL, shell_append },
{ "mv", NULL, shell_mv, },
{ "cp", NULL, shell_cp, },
{ "rm", NULL, shell_rm, },
{ NULL, NULL, NULL },
};
int do_mufs_cmd(struct console *con, size_t argc, const char **argv)
{
return cmd_exec(mufs_cmds, con, argc, argv);
}

@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <console.h>
@ -36,6 +37,27 @@ int shell_time(struct console *con, size_t argc, const char **argv)
return 0;
}
int shell_set_time(struct console *con, size_t argc, const char **argv)
{
struct tm now;
time_t time;
if (argc < 1) {
fprintf(con->fp, "usage: set-time <seconds>\n");
return -1;
}
time = (time_t)strtoul(argv[0], NULL, 0);
gmtime_r(&time, &now);
rtc_init(&now);
fprintf(con->fp, "%02d:%02d:%02d %02d-%02d-%d\n",
now.tm_hour, now.tm_min, now.tm_sec,
now.tm_mday, now.tm_mon + 1, now.tm_year + 1900);
return 0;
}
int shell_set_date(struct console *con, size_t argc, const char **argv)
{
struct tm now;

@ -11,7 +11,7 @@ int shell_version(struct console *con, size_t argc, const char **argv)
if (argc < 1)
return -1;
fprintf(con->fp, "hello %s\n", TBM_VERSION);
fputs(TBM_VERSION, con->fp);
return 0;
}

Loading…
Cancel
Save