Hello,
I've already sent this message, but it doesn't seem to appear on the Google groups interface for some reason so I'm sending it again, sorry if you receive it twice.
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) = {
};
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,