From 29c81849a0993dcf7f9927ae2aa97839ec2f8337 Mon Sep 17 00:00:00 2001 From: Väinö Kauppila Date: Sun, 19 Apr 2026 20:16:18 +0300 Subject: interrupts working now with timer --- Makefile | 2 +- Makefile.inner | 3 ++- fw/ds18b20.c | 33 +++++++++++++++++++-------------- fw/timer0_test.c | 19 +++++++------------ hdl/dpram.vhd | 4 ++-- hdl/state_machine.vhd | 2 +- 6 files changed, 32 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index ca56c27..56f9483 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ IMAGE = fpga-tools -PODMAN = podman run --rm -v $(CURDIR):/workspace $(IMAGE) +PODMAN = podman run --rm --cpus=$(shell nproc) -v $(CURDIR):/workspace $(IMAGE) BUILD = build diff --git a/Makefile.inner b/Makefile.inner index 5838b33..635cc64 100644 --- a/Makefile.inner +++ b/Makefile.inner @@ -58,7 +58,8 @@ $(BUILD)/$(TOP).json: $(SYN_FILES) | $(BUILD) $(BUILD)/$(TOP)_pnr.json: $(BUILD)/$(TOP).json $(CST) nextpnr-himbaechel --json $< --write $@ \ --device $(DEVICE) --vopt family=GW5A-25A --vopt cst=$(CST) \ - --vopt sspi_as_gpio --freq 50 --report $(BUILD)/$(TOP)_timing.json + --vopt sspi_as_gpio --freq 50 --report $(BUILD)/$(TOP)_timing.json \ + --threads $(shell nproc) # Pack bitstream $(BUILD)/$(TOP).fs: $(BUILD)/$(TOP)_pnr.json diff --git a/fw/ds18b20.c b/fw/ds18b20.c index 0b57732..74ac1be 100644 --- a/fw/ds18b20.c +++ b/fw/ds18b20.c @@ -30,22 +30,26 @@ static const uint8_t frac_tens[16] = {0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9}; static const uint8_t frac_hund[16] = {0,6,2,8,5,1,7,4,0,6,2,8,5,1,7,3}; /* - * Timer0 delay. OPTION_REG 0x07: T0CS=0 (Fosc/4), PSA=0, PS=111 (1:256). + * Timer0 interrupt-driven delay. OPTION_REG, T0IF, T0IE, GIE from pic16f84a.h. + * OPTION_REG 0x07: T0CS=0 (Fosc/4), PSA=0, PS=111 (1:256). * At 50 MHz: overflow every 256*256 / (50M/4) = 5.24 ms. * 143 overflows ≈ 750 ms. */ -#define STATUS_RP0 0x20 -#define T0IF 0x04 - -static void wait_overflows(uint8_t n) { - INTCON &= ~T0IF; - while (n--) { - while (!(INTCON & T0IF)); - INTCON &= ~T0IF; +#define OVF_750MS 143 + +static volatile uint8_t ovf_count = 0; + +void isr(void) __interrupt(0) { + if (INTCON & 0x04) { /* T0IF = bit 2 */ + ovf_count++; + INTCON &= ~(uint8_t)0x04; } } -static void delay_750ms(void) { wait_overflows(143); } +static void delay_750ms(void) { + ovf_count = 0; + while (ovf_count < OVF_750MS); +} static void uart_send(uint8_t b) { while (UART_STATUS & 0x01); @@ -88,10 +92,11 @@ void main(void) { uint8_t lo, hi, sign, temp_int, frac; uint8_t i; - /* Configure Timer0: bank 1, OPTION_REG = 0x07 (Fosc/4, prescaler 1:256) */ - STATUS |= STATUS_RP0; - TMR0 = 0x07; - STATUS &= ~STATUS_RP0; + /* T0CS=0 (Fosc/4), PSA=0, PS=111 (1:256 prescaler) */ + OPTION_REG = 0x07; + + TMR0 = 0; + INTCON = 0xa0; /* T0IE | GIE */ /* enable Timer0 overflow interrupt */ uart_puts("\x1B[2J\x1B[H"); uart_puts("DS18B20 Temperature\r\n"); diff --git a/fw/timer0_test.c b/fw/timer0_test.c index ef5e622..658cd79 100644 --- a/fw/timer0_test.c +++ b/fw/timer0_test.c @@ -6,21 +6,18 @@ __sfr __at(0x70) UART_TX; __sfr __at(0x72) UART_STATUS; /* + * OPTION_REG, T0IF, T0IE, GIE are all provided by pic16f84a.h. * OPTION_REG 0x07: T0CS=0 (Fosc/4), PSA=0, PS=111 (1:256) * At 50 MHz: overflow every 256*256 / (50M/4) = 5.24 ms → ~191 ovf/sec */ -#define STATUS_RP0 0x20 -#define T0IF 0x04 /* INTCON bit 2 */ -#define T0IE 0x20 /* INTCON bit 5 */ -#define GIE 0x80 /* INTCON bit 7 */ #define OVF_PER_SEC 191 static volatile uint8_t ovf_count = 0; void isr(void) __interrupt(0) { - if (INTCON & T0IF) { + if (INTCON & 0x04) { /* T0IF = bit 2 */ ovf_count++; - INTCON &= ~T0IF; + INTCON &= ~(uint8_t)0x04; } } @@ -48,13 +45,11 @@ static void print_uint8(uint8_t v) { void main(void) { uint8_t seconds = 0; - /* Configure OPTION_REG (bank 1, same 7-bit addr as TMR0) */ - STATUS |= STATUS_RP0; - TMR0 = 0x07; - STATUS &= ~STATUS_RP0; + /* T0CS=0 (Fosc/4), PSA=0, PS=111 (1:256 prescaler) */ + OPTION_REG = 0x07; TMR0 = 0; - INTCON = T0IE | GIE; /* enable Timer0 overflow interrupt */ + INTCON = 0xa0; /* T0IE | GIE */ uart_puts("\x1B[2J\x1B[H"); uart_puts("Timer0 test\r\n"); @@ -62,7 +57,7 @@ void main(void) { while (1) { ovf_count = 0; - while (ovf_count < OVF_PER_SEC); /* ISR bumps ovf_count */ + while (ovf_count < OVF_PER_SEC); uart_puts("t = "); print_uint8(seconds); diff --git a/hdl/dpram.vhd b/hdl/dpram.vhd index 92b57f2..6cbc338 100644 --- a/hdl/dpram.vhd +++ b/hdl/dpram.vhd @@ -164,7 +164,7 @@ begin if we = '1' then if addr = "00000000" or addr = "10000000" then -- 0x00/0x80 INDF: indirect via FSR - mem(16#03#) <= d_status; + mem(16#03#) <= mem(16#03#)(7 downto 3) & d_status(2 downto 0); mem(to_integer(unsigned(mem(16#04#)))) <= d; elsif addr = "00000001" then -- 0x01 TMR0: routed to timer0, not RAM mem(16#03#) <= mem(16#03#)(7 downto 3) & d_status(2 downto 0); @@ -183,7 +183,7 @@ begin -- peripheral-mapped addresses: don't write to RAM mem(16#03#) <= mem(16#03#)(7 downto 3) & d_status(2 downto 0); else - mem(16#03#) <= d_status; + mem(16#03#) <= mem(16#03#)(7 downto 3) & d_status(2 downto 0); mem(to_integer(unsigned(addr))) <= d; end if; end if; diff --git a/hdl/state_machine.vhd b/hdl/state_machine.vhd index 1fb5291..33d2f33 100644 --- a/hdl/state_machine.vhd +++ b/hdl/state_machine.vhd @@ -216,7 +216,7 @@ begin we_mem <= '1'; end if; when LITERAL_OP => - if instr.op /= NOP and instr.op /= RETUR then + if instr.op /= NOP and instr.op /= RETUR and instr.op /= RETFIE then we_w <= '1'; end if; when others => null; -- cgit v1.3