anybody?
On Sunday, January 19, 2025 at 2:46:25 PM UTC+1 Federico Fusco wrote:
> Hello,
> I would like to preface this by saying that I'm completely new to bare
> metal (but have a lot of experience in more high-level programming) so
> please correct any errors.
>
> I'm trying to set up interrupts for my A13 SoC, specifically the sync
> timer 0 interrupt.
> For some reason my interrupt handler isn't running, and I'm not sure if
> it's due to a misconfigured interrupt table or if I haven't correctly
> configured the sync timer.
>
> This is my linker script (derived from the sunxi-tools repo):
>
> ENTRY(_start)
>
> SECTIONS {
> . = 0x0000;
> .start : { KEEP(*(.start)) }
>
> . = 0x0100;
> .isr_vectors : { *(.isr_vectors) }
> .text : { *(.text) }
> /DISCARD/ : { *(.dynstr*) }
> /DISCARD/ : { *(.dynamic*) }
> /DISCARD/ : { *(.plt*) }
> /DISCARD/ : { *(.interp*) }
> /DISCARD/ : { *(.gnu*) }
> /DISCARD/ : { *(.note*) }
> }
>
> This is my main.c (I know it's messy, but I didn't want to write any
> functions before I know that the core logic works):
>
> #include "gpio/gpio.h"
>
> // If I call this directly in main, it works so I know it's correct
> void timer_handler(void) {
>
> // Initializes GPIO
> struct gpio_reg cfg = gpio_reg_init(GPIO_G_BANK, GPIO_CFG1_REG);
> struct gpio_reg dat = gpio_reg_init(GPIO_G_BANK, GPIO_DAT_REG);
>
> // Sets the PG9 mode to output and state to high
> gpio_set_pin_mode(&cfg, 4, GPIO_MODE_OUTPUT);
> gpio_set_pin_state(&dat, 9, GPIO_STATE_HIGH);
> }
>
> __attribute__((section(".isr_vectors"))) void (*const
> interrupt_vectors[96])(void) = {
> [82] = &timer_handler,
> };
>
> int main(void) {
>
> /*
> * Initialize interrupts
> */
>
> #define INTC_BASE (uintptr_t) 0x01c20400
>
> // Set the isr vector interrupt base addr
> // I load the binary at 0x48000000 with the command: fatload mmc 0:1
> 0x48000000 firmware.bin
> volatile uint32_t *intc_addr = (volatile uint32_t*) (INTC_BASE + 0x04);
> *intc_addr |= 0x48000000 + 0x100;
>
> // Enables the sync timer interrupt
> volatile uint32_t *int_en = (volatile uint32_t*) (INTC_BASE + 0x48);
> *int_en |= 7UL << 17;
>
> // Sets the interrupt priority
> volatile uint32_t *prio = (volatile uint32_t*) 0x01c20494;
> *prio |= 3UL << 4;
>
>
> /*
> * Initialize sync timer 0
> */
>
> #define TMR_BASE (uintptr_t) 0x01c60000
>
> // Enables interrupts for sync timer 0
> volatile uint32_t *tmr_irq_en = (volatile uint32_t*) (TMR_BASE);
> *tmr_irq_en |= 1UL;
>
> // Loads the counter value
> volatile uint32_t *low = (volatile uint32_t*) (TMR_BASE + 0x14);
> *low = 0xF44AA200;
>
> volatile uint32_t *high = (volatile uint32_t*) (TMR_BASE + 0x18);
> *high &= ~((1UL << 23) - 1);
> *high |= 0UL;
>
> // Set the sync timer AHB gating
> volatile uint32_t *ahb_gating = (volatile uint32_t*) 0x01c20060;
> *ahb_gating |= 1UL << 28;
>
> // Starts the counter
> volatile uint32_t *cntr = (volatile uint32_t*) (TMR_BASE + 0x10);
> *cntr |= 1UL;
>
> volatile uint32_t v = 0;
> while(1) { v++; } // Infinite loop
>
> return 0;
> }
>
> Any help is appreciated,
> Federico
>
--
You received this message because you are subscribed to the Google Groups
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion, visit
https://groups.google.com/d/msgid/linux-sunxi/98e50210-8f0f-4b36-8c95-dd7e8ba8a82cn%40googlegroups.com.