Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers power_ctrl.c Source File

power_ctrl.c

00001 /**
00002  * @file    power_ctrl.c
00003  * @brief   power control sequence logic for Musca B
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #include "string.h"
00023 #include "stdio.h"
00024 #include "stdint.h"
00025 #include "syscon.h"
00026 #include "gpio.h"
00027 #include "utils.h"
00028 #include "uart.h"
00029 #include "i2c_gpio.h"
00030 #include "daplink_debug.h"
00031 #include "settings.h"
00032 #include "region_defs.h"
00033 
00034 // I2CIO expander init (PCA9537)
00035 void i2cio_init(void)
00036 {
00037     unsigned int data;
00038 
00039     // Default I2C state
00040     LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL;
00041     // Wait 1ms
00042     delay(1);
00043     LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA;
00044     // Wait 1ms
00045     delay(1);
00046 
00047     // Dummy read
00048     i2c_gpio_rbyte(0, &data);
00049     // Wait 1ms
00050     delay(1);
00051 
00052     // Set default values
00053     // Output register (all PSUs OFF)
00054     i2c_gpio_wbyte(1, 0x00);
00055     // Wait 1ms
00056     delay(1);
00057     // Inversion register
00058     i2c_gpio_wbyte(2, 0x00);
00059     // Wait 1ms
00060     delay(1);
00061     // Configuration register
00062     i2c_gpio_wbyte(3, 0xF0);
00063     // Wait 100ms
00064     delay(100);
00065 }
00066 
00067 // I2CIO expander power OFF
00068 // Sequence: ON > FLASH_PDM + /PWR_OK > /VDD_IO > /VDD_CORE > + /VDD_FLASH + /FLASH_PDM > OFF
00069 void i2cio_power_off(void)
00070 {
00071     i2c_gpio_wbyte(1, FL_ON | FLASH_PDM | CR_ON | IO_ON);
00072     LPC_GPIO->CLR[PIN_PWROK_PORT] = PIN_PWROK;
00073 
00074     i2c_gpio_wbyte(1, FL_ON | FLASH_PDM | CR_ON);
00075 
00076     i2c_gpio_wbyte(1, FL_ON | FLASH_PDM);
00077 
00078     i2c_gpio_wbyte(1, 0);
00079 }
00080 
00081 // I2CIO expander power ON
00082 // Sequence: OFF > VDD_FLASH + FLASH_PDM > VDD_CORE > /FLASH_PDM + PWR_OK > VDD_IO > ON
00083 void i2cio_power_on(void)
00084 {
00085     i2c_gpio_wbyte(1, FL_ON | FLASH_PDM);
00086     // Wait 100ms
00087     delay(100);
00088 
00089     i2c_gpio_wbyte(1, FL_ON | FLASH_PDM | CR_ON);
00090     // Wait 100ms
00091     delay(100);
00092 
00093     i2c_gpio_wbyte(1, FL_ON | CR_ON);
00094     LPC_GPIO->SET[PIN_PWROK_PORT] = PIN_PWROK;
00095     // Wait 100ms
00096     delay(100);
00097 
00098     i2c_gpio_wbyte(1, FL_ON | CR_ON | IO_ON);
00099     // Wait 100ms
00100     delay(100);
00101 }
00102 
00103 // Configure SCC
00104 void configure_syscon(unsigned int pc)
00105 {
00106     unsigned int din, dout;
00107 
00108     // Dummy read
00109     syscon_readreg(0x004, &din);
00110 
00111     // CPU0 boot from QSPI/eFlash0/eFlash1/SRAM
00112     // pc = 0x10000000/0x1A000000/0x1A200000/0x1A400000;
00113     syscon_writereg(0x058, pc);
00114     
00115     // CPU1 boot from QSPI/eFlash0/eFlash1/SRAM
00116     // pc = 0x10000000/0x1A000000/0x1A200000/0x1A400000;
00117     syscon_writereg(0x060, pc);
00118 
00119     // QSPI divider for 20MHz
00120     dout = 0x00000001;
00121     syscon_writereg(0x010, dout);
00122 
00123     // Set PA[37:0] IO drive strength (4/8/4mA) and slew rate (Slow)
00124     syscon_writereg(0x0E8, 0xFFF00000);
00125     syscon_writereg(0x0EC, 0xFFFFFFC0);
00126     syscon_writereg(0x0F0, 0x000FFFFF);
00127     syscon_writereg(0x0F4, 0xFFFFFFFF);
00128     syscon_writereg(0x108, 0xFFFFFFFF);
00129     syscon_writereg(0x10C, 0x0000003F);
00130 }
00131 
00132 // Brown Out Detect
00133 void enable_BOD(int enable)
00134 {
00135     if (enable)
00136     {
00137         // Set BOD interrupt to 2.80-2.90V
00138         LPC_SYSCON->BODCTRL |= 0x1C;
00139         NVIC_EnableIRQ(BOD_IRQn );           /* Enable BOD interrupt */
00140     }
00141     else
00142     {
00143         LPC_SYSCON->BODCTRL = 0x00;
00144         NVIC_DisableIRQ(BOD_IRQn );
00145         NVIC_ClearPendingIRQ(BOD_IRQn );
00146     }
00147 }
00148 
00149 //Power off / shutdown sequence
00150 void power_off_sequence()
00151 {
00152     // Disable Brown Out Detection
00153     enable_BOD(0);
00154 
00155     // Apply CS_nSRST
00156     LPC_GPIO->CLR[PIN_nRESET_PORT] = PIN_nRESET;
00157 
00158     // Wait 10ms
00159     delay(10);
00160 
00161     // Apply CB_nRST
00162     LPC_GPIO->CLR[PIN_CB_nRST_PORT] = PIN_CB_nRST;
00163     // Wait 10ms
00164     delay(10);
00165 
00166     // Apply CFG_nRST
00167     LPC_GPIO->CLR[PIN_CFG_nRST_PORT] = PIN_CFG_nRST;
00168 
00169     // Wait 10ms
00170     delay(10);
00171 }
00172 
00173 //Power on sequence
00174 void power_on_sequence()
00175 {
00176     // Drive SCC signals
00177     LPC_GPIO->DIR[PIN_SCC_CLK_PORT]     |= PIN_SCC_CLK;
00178     LPC_GPIO->DIR[PIN_SCC_DATAIN_PORT]  |= PIN_SCC_DATAIN;
00179     LPC_GPIO->DIR[PIN_SCC_DATAOUT_PORT] &= ~PIN_SCC_DATAOUT;
00180     LPC_GPIO->DIR[PIN_SCC_WNR_PORT]     |= PIN_SCC_WNR;
00181     LPC_GPIO->DIR[PIN_SCC_LOAD_PORT]    |= PIN_SCC_LOAD;
00182 
00183     // Wait 10ms
00184     delay(10);
00185 
00186     // Release CFG_nRST to allow SCC config
00187     LPC_GPIO->SET[PIN_CFG_nRST_PORT] = PIN_CFG_nRST;
00188 
00189     // Wait 10ms
00190     delay(10);
00191 
00192     // Configure SCC
00193 #if (defined MUSCA_B_BOOT_CODE_SRAM)
00194     configure_syscon(MUSCA_B_S_CODE_SRAM_START);
00195 #elif (defined MUSCA_B_BOOT_EFLASH1)
00196     configure_syscon(MUSCA_B_S_EFLASH1_START);
00197 #elif (defined MUSCA_B_BOOT_EFLASH0)
00198     configure_syscon(MUSCA_B_S_EFLASH0_START);
00199 #elif (defined MUSCA_B_BOOT_QSPI_FLASH)
00200     configure_syscon(MUSCA_B_S_FLASH_START);
00201 #endif
00202 
00203     // Wait 10ms
00204     delay(10);
00205 
00206     // Release SCC signals
00207     LPC_GPIO->DIR[PIN_SCC_CLK_PORT]     &= ~PIN_SCC_CLK;
00208     LPC_GPIO->DIR[PIN_SCC_DATAIN_PORT]  &= ~PIN_SCC_DATAIN;
00209     LPC_GPIO->DIR[PIN_SCC_DATAOUT_PORT] &= ~PIN_SCC_DATAOUT;
00210     LPC_GPIO->DIR[PIN_SCC_WNR_PORT]     &= ~PIN_SCC_WNR;
00211     LPC_GPIO->DIR[PIN_SCC_LOAD_PORT]    &= ~PIN_SCC_LOAD;
00212 
00213     // Wait 10ms
00214     delay(10);
00215 
00216     // Release CB_nRST
00217     LPC_GPIO->SET[PIN_CB_nRST_PORT] = PIN_CB_nRST;
00218 
00219     // Wait 10ms
00220     delay(10);
00221 
00222     // Release CS_nSRST
00223     LPC_GPIO->SET[PIN_nRESET_PORT] = PIN_nRESET;
00224 
00225     // Wait 10ms
00226     delay(10);
00227 
00228     // Enable Brown Out Detection
00229     enable_BOD(1);
00230 }
00231 
00232 // BOD Interrupt Service Routine
00233 void BOD_IRQHandler(void)
00234 {
00235     NVIC_DisableIRQ(BOD_IRQn );
00236     gpio_set_cdc_led(GPIO_LED_OFF);  // ON GREEN
00237 
00238     // go into controlled shutdown
00239     power_off_sequence();
00240 
00241     // Turn OFF power
00242     i2cio_power_off();
00243 
00244     while(1)
00245     {
00246         delay(100);
00247         gpio_set_hid_led(GPIO_LED_ON);
00248         delay(100);
00249         gpio_set_hid_led(GPIO_LED_OFF);
00250     }
00251 }
00252 
00253 // Function to wait till PBON button is pressed and released
00254 void wait_for_pbon(void)
00255 {
00256     // Standby - wait for PBON
00257     while (!gpio_get_pbon_btn())
00258     {
00259         // Do something with leds?
00260         gpio_set_cdc_led(GPIO_LED_ON);
00261         delay(100);
00262         gpio_set_cdc_led(GPIO_LED_OFF);
00263         delay(100);
00264     }
00265     // Wait for PBON to go low then high
00266     while (gpio_get_pbon_btn())
00267     {
00268         // Do something with leds?
00269         gpio_set_hid_led(GPIO_LED_ON);
00270         delay(100);
00271         gpio_set_hid_led(GPIO_LED_OFF);
00272         delay(100);
00273     }
00274     // Wait 10ms
00275     delay(10);
00276 
00277 }