mirror of
https://github.com/keirf/greaseweazle-firmware.git
synced 2025-10-31 11:06:44 -07:00
blinky_test: A quick LED-blink test for valid medium-density
STM32F103 device.
This commit is contained in:
7
Makefile
7
Makefile
@@ -5,7 +5,7 @@ export FW_MINOR := 3
|
||||
PROJ = Greaseweazle
|
||||
VER := v$(FW_MAJOR).$(FW_MINOR)
|
||||
|
||||
SUBDIRS += src bootloader
|
||||
SUBDIRS += src bootloader blinky_test
|
||||
|
||||
.PHONY: all clean dist mrproper flash start serial
|
||||
|
||||
@@ -23,11 +23,16 @@ clean:
|
||||
dist:
|
||||
rm -rf $(PROJ)-*
|
||||
mkdir -p $(PROJ)-$(VER)/scripts/greaseweazle
|
||||
mkdir -p $(PROJ)-$(VER)/alt
|
||||
$(MAKE) clean
|
||||
$(MAKE) all
|
||||
cp -a $(PROJ)-$(VER).hex $(PROJ)-$(VER)/
|
||||
cp -a $(PROJ)-$(VER).upd $(PROJ)-$(VER)/
|
||||
$(MAKE) clean
|
||||
$(MAKE) -C blinky_test -f $(ROOT)/Rules.mk \
|
||||
Blinky.elf Blinky.bin Blinky.hex
|
||||
cp -a blinky_test/Blinky.hex $(PROJ)-$(VER)/alt/Blinky_Test-$(VER).hex
|
||||
$(MAKE) clean
|
||||
cp -a COPYING $(PROJ)-$(VER)/
|
||||
cp -a README.md $(PROJ)-$(VER)/
|
||||
cp -a gw.py $(PROJ)-$(VER)/
|
||||
|
||||
7
blinky_test/Blinky.ld.S
Normal file
7
blinky_test/Blinky.ld.S
Normal file
@@ -0,0 +1,7 @@
|
||||
#define FLASH_BASE 0x08000000
|
||||
#define FLASH_LEN 64K
|
||||
|
||||
#define RAM_BASE 0x20000000
|
||||
#define RAM_LEN 20K
|
||||
|
||||
#include "../scripts/stm32f1.ld.S"
|
||||
6
blinky_test/Makefile
Normal file
6
blinky_test/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
RPATH = ../src
|
||||
|
||||
OBJS += vectors.o
|
||||
OBJS += stm32f10x.o
|
||||
OBJS += blinky.o
|
||||
OBJS += util.o
|
||||
122
src/blinky.c
Normal file
122
src/blinky.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* blinky.c
|
||||
*
|
||||
* LED blink test to validate STM32F103C8 chips. This test will find
|
||||
* remarked and cloned low-density devices with less than 20kB RAM,
|
||||
* and/or missing timer TIM4.
|
||||
*
|
||||
* Tests are applied in the following order:
|
||||
* 1. If TIM4 is missing, the onboard LED (pin B12 or C13) will not light.
|
||||
* 2. If there is not at least 20kB SRAM, the onboard LED will remain light.
|
||||
* 3. If TIM4 and >=20kB SRAM are both present, the LED will blink at 2Hz.
|
||||
*
|
||||
* As the LED blinks, a character is written to USART1 at 9600 baud (8n1).
|
||||
*
|
||||
* Written & released by Keir Fraser <keir.xen@gmail.com>
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
* See the file COPYING for more details, or visit <http://unlicense.org>.
|
||||
*/
|
||||
|
||||
int EXC_reset(void) __attribute__((alias("main")));
|
||||
|
||||
void IRQ_30(void) __attribute__((alias("IRQ_tim4")));
|
||||
#define IRQ_TIM4 30
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Keep the linker happy. */
|
||||
int printk(const char *format, ...) { return 0; }
|
||||
#endif
|
||||
|
||||
static void IRQ_tim4(void)
|
||||
{
|
||||
static bool_t x;
|
||||
|
||||
/* Quiesce the IRQ source. */
|
||||
tim4->sr = 0;
|
||||
|
||||
/* Blink the LED. */
|
||||
gpio_write_pin(gpiob, 12, x);
|
||||
gpio_write_pin(gpioc, 13, x);
|
||||
x ^= 1;
|
||||
|
||||
/* Write to the serial line. */
|
||||
usart1->dr = '.';
|
||||
}
|
||||
|
||||
/* Pseudorandom LFSR. */
|
||||
static uint32_t srand = 0x87a2263c;
|
||||
static uint32_t rand(void)
|
||||
{
|
||||
uint32_t x = srand;
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
srand = x;
|
||||
return x;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Relocate DATA. Initialise BSS. */
|
||||
if (_sdat != _ldat)
|
||||
memcpy(_sdat, _ldat, _edat-_sdat);
|
||||
memset(_sbss, 0, _ebss-_sbss);
|
||||
|
||||
stm32_init();
|
||||
|
||||
/* Configure USART1: 9600,8n1. */
|
||||
rcc->apb2enr |= RCC_APB2ENR_USART1EN;
|
||||
gpio_configure_pin(gpioa, 9, AFO_pushpull(_10MHz));
|
||||
gpio_configure_pin(gpioa, 10, GPI_pull_up);
|
||||
usart1->brr = SYSCLK / 9600;
|
||||
usart1->cr1 = (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE);
|
||||
|
||||
/* Configure LED pin(s). LED is connected to VDD. */
|
||||
gpio_configure_pin(gpiob, 12, GPO_opendrain(_2MHz, HIGH));
|
||||
gpio_configure_pin(gpioc, 13, GPO_opendrain(_2MHz, HIGH));
|
||||
|
||||
/* (Attempt to) Configure TIM4 to overflow at 2Hz. */
|
||||
tim4->psc = sysclk_us(100)-1;
|
||||
tim4->arr = 5000-1;
|
||||
tim4->dier = TIM_DIER_UIE;
|
||||
tim4->cr2 = 0;
|
||||
tim4->cr1 = TIM_CR1_URS | TIM_CR1_CEN;
|
||||
|
||||
/* Enable TIM4 IRQ, to be triggered at 2Hz. */
|
||||
IRQx_set_prio(IRQ_TIM4, TIMER_IRQ_PRI);
|
||||
IRQx_clear_pending(IRQ_TIM4);
|
||||
IRQx_enable(IRQ_TIM4);
|
||||
|
||||
/* Endlessly test SRAM by filling with pseudorandom junk and then
|
||||
* testing the values read back okay. */
|
||||
for (;;) {
|
||||
uint32_t *p = (uint32_t *)_ebss, sr = srand;
|
||||
while (p < (uint32_t *)(0x20000000 + 20*1024))
|
||||
*p++ = rand();
|
||||
srand = sr;
|
||||
p = (uint32_t *)_ebss;
|
||||
while (p < (uint32_t *)(0x20000000 + 20*1024))
|
||||
if (*p++ != rand())
|
||||
goto ram_fail;
|
||||
}
|
||||
|
||||
ram_fail:
|
||||
/* On SRAM failure we light the LED(s) and hang. */
|
||||
IRQ_global_disable();
|
||||
gpio_write_pin(gpiob, 12, LOW);
|
||||
gpio_write_pin(gpioc, 13, LOW);
|
||||
for (;;) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-file-style: "Linux"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -74,7 +74,6 @@ void console_init(void)
|
||||
/* BAUD, 8n1. */
|
||||
usart1->brr = SYSCLK / BAUD;
|
||||
usart1->cr1 = (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE);
|
||||
usart1->cr3 = USART_CR3_DMAT;
|
||||
}
|
||||
|
||||
/* Debug helper: if we get stuck somewhere, calling this beforehand will cause
|
||||
|
||||
Reference in New Issue
Block a user