Compare commits
6 Commits
master
...
wip/virtua
Author | SHA1 | Date |
---|---|---|
Merlijn Wajer | 4be866edeb | 5 years ago |
Merlijn Wajer | fe3b178d3c | 5 years ago |
Merlijn Wajer | ff82126348 | 5 years ago |
Merlijn Wajer | eee687316e | 5 years ago |
Merlijn Wajer | b9580b17fd | 5 years ago |
Merlijn Wajer | 4b49f643ca | 5 years ago |
@ -1 +1 @@ |
||||
tbm-obj-y += source/core/flash.o
|
||||
tbm-obj-y += source/core/flash.o source/core/spi.o
|
||||
|
@ -0,0 +1,64 @@ |
||||
/*
|
||||
#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,61 @@ |
||||
/*
|
||||
#include <libopencm3/stm32/gpio.h> |
||||
#include <libopencm3/stm32/rcc.h> |
||||
#include <libopencm3/stm32/timer.h> |
||||
*/ |
||||
|
||||
#include <sys/types.h> |
||||
#include <stdint.h> |
||||
#include <buzzer.h> |
||||
#include <macros.h> |
||||
|
||||
struct buzzer buzzers[] = { |
||||
{ }, |
||||
}; |
||||
|
||||
size_t nbuzzers = count_of(buzzers); |
||||
|
||||
void buzzer_init(struct buzzer *buzzer) |
||||
{ |
||||
/*
|
||||
rcc_periph_reset_pulse(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); |
||||
*/ |
||||
} |
@ -0,0 +1,53 @@ |
||||
/*
|
||||
#include <libopencm3/stm32/gpio.h> |
||||
*/ |
||||
|
||||
#include <gpio.h> |
||||
|
||||
int gpio_init(void) |
||||
{ |
||||
#if 0 |
||||
/* Set up GPIOs for SPI 1 */ |
||||
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, |
||||
GPIO_CNF_OUTPUT_PUSHPULL, GPIO_SPI1_NSS); |
||||
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, |
||||
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI1_SCK | |
||||
GPIO_SPI1_MOSI); |
||||
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, |
||||
GPIO_SPI1_MISO); |
||||
|
||||
/* 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); |
||||
|
||||
/* 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); |
||||
|
||||
/* 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); |
||||
#endif |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void gpio_cleanup(void) |
||||
{ |
||||
} |
@ -0,0 +1,40 @@ |
||||
/*
|
||||
#include <libopencm3/stm32/gpio.h> |
||||
*/ |
||||
|
||||
#include <stdint.h> |
||||
#include <sys/types.h> |
||||
#include <led.h> |
||||
#include <macros.h> |
||||
|
||||
struct led leds[] = { |
||||
{ }, |
||||
}; |
||||
|
||||
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); |
||||
*/ |
||||
} |
@ -0,0 +1,25 @@ |
||||
/*
|
||||
#include <libopencm3/stm32/rcc.h> |
||||
*/ |
||||
|
||||
#include <rcc.h> |
||||
|
||||
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; |
||||
} |
||||
|
||||
void rcc_cleanup(void) |
||||
{ |
||||
} |
@ -0,0 +1,22 @@ |
||||
#include <macros.h> |
||||
#include <rtc.h> |
||||
|
||||
int rtc_get_time(struct tm *time) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
static int rtc_set_time(struct tm *time) |
||||
{ |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int rtc_init(struct tm *time) |
||||
{ |
||||
/*
|
||||
rtc_set_time(time); |
||||
*/ |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,150 @@ |
||||
#define _GNU_SOURCE |
||||
#include <stdint.h> |
||||
#include <stdlib.h> |
||||
|
||||
#include <spi.h> |
||||
|
||||
#include <stdio.h> |
||||
#include <sys/mman.h> |
||||
#include <unistd.h> |
||||
#include <string.h> |
||||
#include <spi_flash.h> |
||||
|
||||
// XXX: 16 is used in other places in this file too
|
||||
#define FLASH_SIZE (1 << 16) |
||||
|
||||
static int virtual_spi_tx_rx(struct spi_dev *dev, void *rx_buf, size_t rx_len, |
||||
const void *tx_buf, size_t tx_len); |
||||
|
||||
static struct spi_ops virtual_spi_ops = { |
||||
.tx_rx = virtual_spi_tx_rx, |
||||
}; |
||||
|
||||
// XXX: make part of dev struct
|
||||
static unsigned char *flash_map; |
||||
|
||||
static int virtual_spi_init(void) |
||||
{ |
||||
/* TODO: close this fd */ |
||||
FILE *flash_fd; |
||||
int exists = 0; |
||||
|
||||
exists = access("flash", F_OK) != -1; |
||||
/* XXX: treat not existing separately from existing file, since we want to
|
||||
* null one that doesn't exist yet */ |
||||
flash_fd = fopen("flash", "ab+"); |
||||
if (!exists) { |
||||
fprintf(stderr, |
||||
"flash doesn't exist yet, creating and filling now\n"); |
||||
char buf[FLASH_SIZE]; |
||||
int ret = fwrite(buf, sizeof(char), FLASH_SIZE, flash_fd); |
||||
fprintf(stderr, "fwrite ret: %d\n", ret); |
||||
} |
||||
|
||||
if (flash_fd == NULL) { |
||||
perror("flash_open"); |
||||
fprintf(stderr, "spi init failed\n"); |
||||
return 1; |
||||
} |
||||
flash_map = |
||||
mmap(NULL, FLASH_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, |
||||
fileno(flash_fd), 0); |
||||
fprintf(stderr, "flash: %p\n", flash_map); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
struct spi_dev *spi_probe(void) |
||||
{ |
||||
struct spi_dev *dev; |
||||
|
||||
if (!(dev = malloc(sizeof *dev))) |
||||
return NULL; |
||||
|
||||
dev->ops = &virtual_spi_ops; |
||||
/*
|
||||
dev->dev_id = SPI1; |
||||
|
||||
*/ |
||||
if (virtual_spi_init()) { |
||||
free(dev); |
||||
return NULL; |
||||
} |
||||
|
||||
return dev; |
||||
} |
||||
|
||||
void spi_release(struct spi_dev *dev) |
||||
{ |
||||
free(dev); |
||||
/* TODO: close fd, close mmap */ |
||||
} |
||||
|
||||
static int virtual_spi_tx_rx(struct spi_dev *dev, void *rx_buf, size_t rx_len, |
||||
const void *tx_buf, size_t tx_len) |
||||
{ |
||||
unsigned char *rx_buf_c = (unsigned char *)rx_buf; |
||||
unsigned char *tx_buf_c = (unsigned char *)tx_buf; |
||||
|
||||
unsigned char cmd = tx_buf_c[0]; |
||||
|
||||
fprintf(stderr, "? RX len: %ld\n", rx_len); |
||||
|
||||
if (tx_buf != NULL) { |
||||
fprintf(stderr, "? TX Command: %d\n", cmd); |
||||
fprintf(stderr, "? TX len: %ld\n", tx_len); |
||||
if (cmd == SPI_FLASH_JEDEC_ID) { |
||||
if (rx_len != 3) { |
||||
fprintf(stderr, "UNEXPECTED RX_LEN\n"); |
||||
} |
||||
fprintf(stderr, "SPI_FLASH_JEDEC_ID\n"); |
||||
rx_buf_c[0] = 0x1; |
||||
rx_buf_c[1] = 0x1; |
||||
rx_buf_c[2] = 16; |
||||
} |
||||
|
||||
if (cmd == SPI_FLASH_READ) { |
||||
fprintf(stderr, "SPI_FLASH_READ\n"); |
||||
unsigned int addr = (tx_buf_c[1] << 16) + |
||||
(tx_buf_c[2] << 8) + tx_buf_c[3]; |
||||
fprintf(stderr, "addr: %d\n", addr); |
||||
fprintf(stderr, "memmove: %d\n", addr); |
||||
memmove(rx_buf_c, flash_map + addr, rx_len); |
||||
} |
||||
|
||||
if (cmd == SPI_FLASH_PAGE_PROGRAM) { |
||||
fprintf(stderr, "SPI_FLASH_PAGE_PROGRAM\n"); |
||||
unsigned int addr = (tx_buf_c[1] << 16) + |
||||
(tx_buf_c[2] << 8) + tx_buf_c[3]; |
||||
fprintf(stderr, "addr: %d\n", addr); |
||||
fprintf(stderr, "memmove: %d\n", addr); |
||||
memmove(flash_map + addr, tx_buf_c + 4, tx_len - 4); |
||||
} |
||||
|
||||
if (cmd == SPI_FLASH_ERASE_4K) { |
||||
fprintf(stderr, "SPI_FLASH_ERASE_4K\n"); |
||||
unsigned int addr = (tx_buf_c[1] << 16) + |
||||
(tx_buf_c[2] << 8) + tx_buf_c[3]; |
||||
fprintf(stderr, "addr: %d\n", addr); |
||||
memset(flash_map + addr, 0, 4096); |
||||
} |
||||
|
||||
if (cmd == SPI_FLASH_READ_SR1) { |
||||
fprintf(stderr, "SPI_FLASH_READ_SR1\n"); |
||||
/* Just report read/write/erase as done, we are never busy with mmap */ |
||||
rx_buf_c[0] = 0; |
||||
} |
||||
|
||||
if (cmd == SPI_FLASH_WRITE_ENABLE) { |
||||
fprintf(stderr, "SPI_FLASH_WRITE_ENABLE\n"); |
||||
/* These can be stubs */ |
||||
} |
||||
|
||||
if (cmd == SPI_FLASH_WRITE_DISABLE) { |
||||
fprintf(stderr, "SPI_FLASH_WRITE_DISABLE\n"); |
||||
/* These can be stubs */ |
||||
} |
||||
} |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue