From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Re: GNAT stm34f4 zfp question. Date: Wed, 18 Mar 2015 17:58:10 +0000 Organization: A noiseless patient Spider Message-ID: References: <07330c00-0317-4bb2-8ffb-67bff98dc9eb@googlegroups.com> <05f8f7cc-a934-4a2b-aa58-4f40fc540e66@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="c266ac6a7b23adb6fddc6455356f7788"; logging-data="22452"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+RBRVJhfCuHna43BNzJCUQ8cnQ5p9GDwY=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (darwin) Cancel-Lock: sha1:R/y7uYhDBfJN8QOmJ9IZL1M/Ctc= sha1:n2B+5+1dedUbsDTT5VonaUOFuTM= Xref: news.eternal-september.org comp.lang.ada:25202 Date: 2015-03-18T17:58:10+00:00 List-Id: Simon Wright writes: > And even then I'm concerned about multiplexed GPIO interrupts; as I > understand it, there is only one EXTI0 interrupt, corresponding to pin > 0 on any GPIO, so if you need more than one pin 0 interrupt you'll > need to manage all of them in one super-handler, or arrange to chain > handlers (which I don't think AdaCore's RTS supports??) Somewhat clearer about this now! There are 16 GPIO-related interrupt lines, corresponding to the 16 bits in a GPIO register. Each line is associated with one GPIO (the default is GPIOA). Each line can have interrupts enabled (and/or events???) Lines 0..4 have their own interrupts, EXTI0_IRQ to EXTI4_IRQ. Lines 5..9 are multiplexed to one interrupt, EXTI9_5_IRQ. Lines 10..15 are multiplexed to one interrupt, EXTI15_10_IRQ. So pin PC11 (GPIOC, bit 11), which is one of the unassigned pins on the STM32F429I Disco, can be interrupt-enabled (in which case no other GPIO's pin 11 can be interrupt-enabled) and will generate EXTI15_10_IRQ. If interrupts are required on lines 10, 12, 13, 14, or 15 (which can each be associated with different GPIOs) then the handler for EXTI15_10_IRQ will have to determine which is which. At the moment I'm toying with mechanical translation of the STMCube stm32f429xx.h (using -fdump-ada-spec and a sed script), and have the code below, which is fairly ugly, rather like the C equivalent. I could copy AdaCore's design (not the code, of course!) which handles multi-bit fields much better, but I'm looking for a mechanical translation at this stage. with Ada.Interrupts.Names; with Interfaces; with System; with stm32f429xx_h; use stm32f429xx_h; package body Button is -- We're going to use a pin on the left-hand side of the board: -- P1/44 is PC11. protected B with Interrupt_Priority => System.Interrupt_Priority'First is entry Wait_For_Trigger; private Triggered : Boolean := False; procedure Handler; pragma Attach_Handler (Handler, Ada.Interrupts.Names.EXTI15_10_IRQ); end B; procedure Wait_For_Button_Release is begin B.Wait_For_Trigger; end Wait_For_Button_Release; protected body B is entry Wait_For_Trigger when Triggered is begin Triggered := False; end Wait_For_Trigger; procedure Handler is use type Interfaces.Unsigned_32; begin if (EXTI.PR and EXTI_PR_PR11) /= 0 then Triggered := True; EXTI.PR := EXTI_PR_PR11; -- clear the interrupt by *writing* 1 else raise Program_Error with "unexpected interrupt"; end if; end Handler; end B; procedure Initialize is use type Interfaces.Unsigned_32; begin -- First, we need to enable GPIOC's clock. RCC.AHB1ENR := RCC.AHB1ENR or RCC_AHB1ENR_GPIOCEN; -- Don't need to configure bit 11 as an input, because that's -- the default. -- Don't need to configure OTYPER, because the pin is an input. -- Don't need to configure OSPEEDR, because the pin is an input. -- Configure PUPDR for pull-up (AdaCore have no-pull?) declare Pull_Register : Interfaces.Unsigned_32; begin Pull_Register := GPIOC.PUPDR; Pull_Register := Pull_Register and not GPIO_PUPDR_PUPDR11; Pull_Register := Pull_Register or GPIO_PUPDR_PUPDR11_0; GPIOC.PUPDR := Pull_Register; end; -- Enable SYSCFG's clock. RCC.APB2ENR := RCC.APB2ENR or RCC_APB2ENR_SYSCFGEN; -- Then, configure SYSCFG_EXTICR3[12:15] (pin 11) for GPIOC. declare Exti_Register : Interfaces.Unsigned_32; begin Exti_Register := SYSCFG.EXTICR (2); -- C indexing! Exti_Register := Exti_Register and not SYSCFG_EXTICR3_EXTI11; Exti_Register := Exti_Register or SYSCFG_EXTICR3_EXTI11_PC; SYSCFG.EXTICR (2) := Exti_Register; end; -- Then, configure EXTI on pin 11 for rising-edge (button-release) EXTI.RTSR := EXTI.RTSR or EXTI_RTSR_TR11; -- and enable interrupts on pin 11. EXTI.IMR := EXTI.IMR or EXTI_IMR_MR11; end Initialize; begin Initialize; end Button;