altos: Use explicit boot loader signal in ao_boot_reboot
[fw/altos] / src / lpc / ao_timer_lpc.c
index 51835baaa76310f94ec1381541db33e65987f210..44fb410e7f522b642d1a68f965f46681690a3d74 100644 (file)
@@ -100,18 +100,33 @@ ao_clock_init(void)
                                 (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO) |
                                 (1 << LPC_SCB_SYSAHBCLKCTRL_IOCON));
                                 
+       /* Enable the brown-out detection at the highest voltage to
+        * make sure the flash part remains happy
+        */
+
+       lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_BOD_PD);
+       lpc_scb.bodctrl = ((LPC_SCB_BOD_BODRSTLEV_2_63 << LPC_SCB_BOD_BODRSTLEV) |
+                          (LPC_SCB_BOD_BODINTVAL_RESERVED << LPC_SCB_BOD_BODINTVAL) |
+                          (1 << LPC_SCB_BOD_BODRSTENA));
+
        /* Turn the IRC clock back on */
        lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_IRC_PD);
        ao_clock_delay();
        
        /* Switch to the IRC clock */
        lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_IRC << LPC_SCB_MAINCLKSEL_SEL;
-       lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA);
        lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA);
        lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA);
        while (!(lpc_scb.mainclkuen & (1 << LPC_SCB_MAINCLKUEN_ENA)))
                ;
        
+       /* Switch USB to the main clock */
+       lpc_scb.usbclksel = (LPC_SCB_USBCLKSEL_SEL_MAIN_CLOCK << LPC_SCB_USBCLKSEL_SEL);
+       lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA);
+       lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA);
+       while (!(lpc_scb.usbclkuen & (1 << LPC_SCB_USBCLKUEN_ENA)))
+               ;
+       
        /* Find a PLL post divider ratio that gets the FCCO in range */
        for (p = 0; p < 4; p++)
                if (AO_LPC_CLKOUT << (1 + p) >= AO_LPC_FCCO_MIN)
@@ -177,4 +192,22 @@ ao_clock_init(void)
        lpc_scb.ssp1clkdiv = 0;
        lpc_scb.usbclkdiv = 0;
        lpc_scb.clkoutdiv = 0;
+
+       /* Switch USB PLL source to system osc so we can power down the IRC */
+       lpc_scb.usbpllclksel = (LPC_SCB_USBPLLCLKSEL_SEL_SYSOSC << LPC_SCB_USBPLLCLKSEL_SEL);
+       lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA);
+       lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA);
+       while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA)))
+               ;
+       
+       /* Power down everything we don't need */
+       lpc_scb.pdruncfg = ((1 << LPC_SCB_PDRUNCFG_IRCOUT_PD) |
+                           (1 << LPC_SCB_PDRUNCFG_IRC_PD) |
+                           (0 << LPC_SCB_PDRUNCFG_BOD_PD) |
+                           (1 << LPC_SCB_PDRUNCFG_ADC_PD) |
+                           (1 << LPC_SCB_PDRUNCFG_WDTOSC_PD) |
+                           (1 << LPC_SCB_PDRUNCFG_USBPLL_PD) |
+                           (1 << LPC_SCB_PDRUNCFG_USBPAD_PD) |
+                           (1 << 11) |
+                           (7 << 13));
 }