Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /**
Pawel Zarembski 0:01f31e923fe2 2 * @file power_ctrl.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief power control sequence logic for Musca B
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 8 *
Pawel Zarembski 0:01f31e923fe2 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 10 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 11 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 12 *
Pawel Zarembski 0:01f31e923fe2 13 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 18 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 19 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 20 */
Pawel Zarembski 0:01f31e923fe2 21
Pawel Zarembski 0:01f31e923fe2 22 #include "string.h"
Pawel Zarembski 0:01f31e923fe2 23 #include "stdio.h"
Pawel Zarembski 0:01f31e923fe2 24 #include "stdint.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "syscon.h"
Pawel Zarembski 0:01f31e923fe2 26 #include "gpio.h"
Pawel Zarembski 0:01f31e923fe2 27 #include "utils.h"
Pawel Zarembski 0:01f31e923fe2 28 #include "uart.h"
Pawel Zarembski 0:01f31e923fe2 29 #include "i2c_gpio.h"
Pawel Zarembski 0:01f31e923fe2 30 #include "daplink_debug.h"
Pawel Zarembski 0:01f31e923fe2 31 #include "settings.h"
Pawel Zarembski 0:01f31e923fe2 32 #include "region_defs.h"
Pawel Zarembski 0:01f31e923fe2 33
Pawel Zarembski 0:01f31e923fe2 34 // I2CIO expander init (PCA9537)
Pawel Zarembski 0:01f31e923fe2 35 void i2cio_init(void)
Pawel Zarembski 0:01f31e923fe2 36 {
Pawel Zarembski 0:01f31e923fe2 37 unsigned int data;
Pawel Zarembski 0:01f31e923fe2 38
Pawel Zarembski 0:01f31e923fe2 39 // Default I2C state
Pawel Zarembski 0:01f31e923fe2 40 LPC_GPIO->DIR[PIN_I2C_SCL_PORT] &= ~PIN_I2C_SCL;
Pawel Zarembski 0:01f31e923fe2 41 // Wait 1ms
Pawel Zarembski 0:01f31e923fe2 42 delay(1);
Pawel Zarembski 0:01f31e923fe2 43 LPC_GPIO->DIR[PIN_I2C_SDA_PORT] &= ~PIN_I2C_SDA;
Pawel Zarembski 0:01f31e923fe2 44 // Wait 1ms
Pawel Zarembski 0:01f31e923fe2 45 delay(1);
Pawel Zarembski 0:01f31e923fe2 46
Pawel Zarembski 0:01f31e923fe2 47 // Dummy read
Pawel Zarembski 0:01f31e923fe2 48 i2c_gpio_rbyte(0, &data);
Pawel Zarembski 0:01f31e923fe2 49 // Wait 1ms
Pawel Zarembski 0:01f31e923fe2 50 delay(1);
Pawel Zarembski 0:01f31e923fe2 51
Pawel Zarembski 0:01f31e923fe2 52 // Set default values
Pawel Zarembski 0:01f31e923fe2 53 // Output register (all PSUs OFF)
Pawel Zarembski 0:01f31e923fe2 54 i2c_gpio_wbyte(1, 0x00);
Pawel Zarembski 0:01f31e923fe2 55 // Wait 1ms
Pawel Zarembski 0:01f31e923fe2 56 delay(1);
Pawel Zarembski 0:01f31e923fe2 57 // Inversion register
Pawel Zarembski 0:01f31e923fe2 58 i2c_gpio_wbyte(2, 0x00);
Pawel Zarembski 0:01f31e923fe2 59 // Wait 1ms
Pawel Zarembski 0:01f31e923fe2 60 delay(1);
Pawel Zarembski 0:01f31e923fe2 61 // Configuration register
Pawel Zarembski 0:01f31e923fe2 62 i2c_gpio_wbyte(3, 0xF0);
Pawel Zarembski 0:01f31e923fe2 63 // Wait 100ms
Pawel Zarembski 0:01f31e923fe2 64 delay(100);
Pawel Zarembski 0:01f31e923fe2 65 }
Pawel Zarembski 0:01f31e923fe2 66
Pawel Zarembski 0:01f31e923fe2 67 // I2CIO expander power OFF
Pawel Zarembski 0:01f31e923fe2 68 // Sequence: ON > FLASH_PDM + /PWR_OK > /VDD_IO > /VDD_CORE > + /VDD_FLASH + /FLASH_PDM > OFF
Pawel Zarembski 0:01f31e923fe2 69 void i2cio_power_off(void)
Pawel Zarembski 0:01f31e923fe2 70 {
Pawel Zarembski 0:01f31e923fe2 71 i2c_gpio_wbyte(1, FL_ON | FLASH_PDM | CR_ON | IO_ON);
Pawel Zarembski 0:01f31e923fe2 72 LPC_GPIO->CLR[PIN_PWROK_PORT] = PIN_PWROK;
Pawel Zarembski 0:01f31e923fe2 73
Pawel Zarembski 0:01f31e923fe2 74 i2c_gpio_wbyte(1, FL_ON | FLASH_PDM | CR_ON);
Pawel Zarembski 0:01f31e923fe2 75
Pawel Zarembski 0:01f31e923fe2 76 i2c_gpio_wbyte(1, FL_ON | FLASH_PDM);
Pawel Zarembski 0:01f31e923fe2 77
Pawel Zarembski 0:01f31e923fe2 78 i2c_gpio_wbyte(1, 0);
Pawel Zarembski 0:01f31e923fe2 79 }
Pawel Zarembski 0:01f31e923fe2 80
Pawel Zarembski 0:01f31e923fe2 81 // I2CIO expander power ON
Pawel Zarembski 0:01f31e923fe2 82 // Sequence: OFF > VDD_FLASH + FLASH_PDM > VDD_CORE > /FLASH_PDM + PWR_OK > VDD_IO > ON
Pawel Zarembski 0:01f31e923fe2 83 void i2cio_power_on(void)
Pawel Zarembski 0:01f31e923fe2 84 {
Pawel Zarembski 0:01f31e923fe2 85 i2c_gpio_wbyte(1, FL_ON | FLASH_PDM);
Pawel Zarembski 0:01f31e923fe2 86 // Wait 100ms
Pawel Zarembski 0:01f31e923fe2 87 delay(100);
Pawel Zarembski 0:01f31e923fe2 88
Pawel Zarembski 0:01f31e923fe2 89 i2c_gpio_wbyte(1, FL_ON | FLASH_PDM | CR_ON);
Pawel Zarembski 0:01f31e923fe2 90 // Wait 100ms
Pawel Zarembski 0:01f31e923fe2 91 delay(100);
Pawel Zarembski 0:01f31e923fe2 92
Pawel Zarembski 0:01f31e923fe2 93 i2c_gpio_wbyte(1, FL_ON | CR_ON);
Pawel Zarembski 0:01f31e923fe2 94 LPC_GPIO->SET[PIN_PWROK_PORT] = PIN_PWROK;
Pawel Zarembski 0:01f31e923fe2 95 // Wait 100ms
Pawel Zarembski 0:01f31e923fe2 96 delay(100);
Pawel Zarembski 0:01f31e923fe2 97
Pawel Zarembski 0:01f31e923fe2 98 i2c_gpio_wbyte(1, FL_ON | CR_ON | IO_ON);
Pawel Zarembski 0:01f31e923fe2 99 // Wait 100ms
Pawel Zarembski 0:01f31e923fe2 100 delay(100);
Pawel Zarembski 0:01f31e923fe2 101 }
Pawel Zarembski 0:01f31e923fe2 102
Pawel Zarembski 0:01f31e923fe2 103 // Configure SCC
Pawel Zarembski 0:01f31e923fe2 104 void configure_syscon(unsigned int pc)
Pawel Zarembski 0:01f31e923fe2 105 {
Pawel Zarembski 0:01f31e923fe2 106 unsigned int din, dout;
Pawel Zarembski 0:01f31e923fe2 107
Pawel Zarembski 0:01f31e923fe2 108 // Dummy read
Pawel Zarembski 0:01f31e923fe2 109 syscon_readreg(0x004, &din);
Pawel Zarembski 0:01f31e923fe2 110
Pawel Zarembski 0:01f31e923fe2 111 // CPU0 boot from QSPI/eFlash0/eFlash1/SRAM
Pawel Zarembski 0:01f31e923fe2 112 // pc = 0x10000000/0x1A000000/0x1A200000/0x1A400000;
Pawel Zarembski 0:01f31e923fe2 113 syscon_writereg(0x058, pc);
Pawel Zarembski 0:01f31e923fe2 114
Pawel Zarembski 0:01f31e923fe2 115 // CPU1 boot from QSPI/eFlash0/eFlash1/SRAM
Pawel Zarembski 0:01f31e923fe2 116 // pc = 0x10000000/0x1A000000/0x1A200000/0x1A400000;
Pawel Zarembski 0:01f31e923fe2 117 syscon_writereg(0x060, pc);
Pawel Zarembski 0:01f31e923fe2 118
Pawel Zarembski 0:01f31e923fe2 119 // QSPI divider for 20MHz
Pawel Zarembski 0:01f31e923fe2 120 dout = 0x00000001;
Pawel Zarembski 0:01f31e923fe2 121 syscon_writereg(0x010, dout);
Pawel Zarembski 0:01f31e923fe2 122
Pawel Zarembski 0:01f31e923fe2 123 // Set PA[37:0] IO drive strength (4/8/4mA) and slew rate (Slow)
Pawel Zarembski 0:01f31e923fe2 124 syscon_writereg(0x0E8, 0xFFF00000);
Pawel Zarembski 0:01f31e923fe2 125 syscon_writereg(0x0EC, 0xFFFFFFC0);
Pawel Zarembski 0:01f31e923fe2 126 syscon_writereg(0x0F0, 0x000FFFFF);
Pawel Zarembski 0:01f31e923fe2 127 syscon_writereg(0x0F4, 0xFFFFFFFF);
Pawel Zarembski 0:01f31e923fe2 128 syscon_writereg(0x108, 0xFFFFFFFF);
Pawel Zarembski 0:01f31e923fe2 129 syscon_writereg(0x10C, 0x0000003F);
Pawel Zarembski 0:01f31e923fe2 130 }
Pawel Zarembski 0:01f31e923fe2 131
Pawel Zarembski 0:01f31e923fe2 132 // Brown Out Detect
Pawel Zarembski 0:01f31e923fe2 133 void enable_BOD(int enable)
Pawel Zarembski 0:01f31e923fe2 134 {
Pawel Zarembski 0:01f31e923fe2 135 if (enable)
Pawel Zarembski 0:01f31e923fe2 136 {
Pawel Zarembski 0:01f31e923fe2 137 // Set BOD interrupt to 2.80-2.90V
Pawel Zarembski 0:01f31e923fe2 138 LPC_SYSCON->BODCTRL |= 0x1C;
Pawel Zarembski 0:01f31e923fe2 139 NVIC_EnableIRQ(BOD_IRQn); /* Enable BOD interrupt */
Pawel Zarembski 0:01f31e923fe2 140 }
Pawel Zarembski 0:01f31e923fe2 141 else
Pawel Zarembski 0:01f31e923fe2 142 {
Pawel Zarembski 0:01f31e923fe2 143 LPC_SYSCON->BODCTRL = 0x00;
Pawel Zarembski 0:01f31e923fe2 144 NVIC_DisableIRQ(BOD_IRQn);
Pawel Zarembski 0:01f31e923fe2 145 NVIC_ClearPendingIRQ(BOD_IRQn);
Pawel Zarembski 0:01f31e923fe2 146 }
Pawel Zarembski 0:01f31e923fe2 147 }
Pawel Zarembski 0:01f31e923fe2 148
Pawel Zarembski 0:01f31e923fe2 149 //Power off / shutdown sequence
Pawel Zarembski 0:01f31e923fe2 150 void power_off_sequence()
Pawel Zarembski 0:01f31e923fe2 151 {
Pawel Zarembski 0:01f31e923fe2 152 // Disable Brown Out Detection
Pawel Zarembski 0:01f31e923fe2 153 enable_BOD(0);
Pawel Zarembski 0:01f31e923fe2 154
Pawel Zarembski 0:01f31e923fe2 155 // Apply CS_nSRST
Pawel Zarembski 0:01f31e923fe2 156 LPC_GPIO->CLR[PIN_nRESET_PORT] = PIN_nRESET;
Pawel Zarembski 0:01f31e923fe2 157
Pawel Zarembski 0:01f31e923fe2 158 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 159 delay(10);
Pawel Zarembski 0:01f31e923fe2 160
Pawel Zarembski 0:01f31e923fe2 161 // Apply CB_nRST
Pawel Zarembski 0:01f31e923fe2 162 LPC_GPIO->CLR[PIN_CB_nRST_PORT] = PIN_CB_nRST;
Pawel Zarembski 0:01f31e923fe2 163 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 164 delay(10);
Pawel Zarembski 0:01f31e923fe2 165
Pawel Zarembski 0:01f31e923fe2 166 // Apply CFG_nRST
Pawel Zarembski 0:01f31e923fe2 167 LPC_GPIO->CLR[PIN_CFG_nRST_PORT] = PIN_CFG_nRST;
Pawel Zarembski 0:01f31e923fe2 168
Pawel Zarembski 0:01f31e923fe2 169 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 170 delay(10);
Pawel Zarembski 0:01f31e923fe2 171 }
Pawel Zarembski 0:01f31e923fe2 172
Pawel Zarembski 0:01f31e923fe2 173 //Power on sequence
Pawel Zarembski 0:01f31e923fe2 174 void power_on_sequence()
Pawel Zarembski 0:01f31e923fe2 175 {
Pawel Zarembski 0:01f31e923fe2 176 // Drive SCC signals
Pawel Zarembski 0:01f31e923fe2 177 LPC_GPIO->DIR[PIN_SCC_CLK_PORT] |= PIN_SCC_CLK;
Pawel Zarembski 0:01f31e923fe2 178 LPC_GPIO->DIR[PIN_SCC_DATAIN_PORT] |= PIN_SCC_DATAIN;
Pawel Zarembski 0:01f31e923fe2 179 LPC_GPIO->DIR[PIN_SCC_DATAOUT_PORT] &= ~PIN_SCC_DATAOUT;
Pawel Zarembski 0:01f31e923fe2 180 LPC_GPIO->DIR[PIN_SCC_WNR_PORT] |= PIN_SCC_WNR;
Pawel Zarembski 0:01f31e923fe2 181 LPC_GPIO->DIR[PIN_SCC_LOAD_PORT] |= PIN_SCC_LOAD;
Pawel Zarembski 0:01f31e923fe2 182
Pawel Zarembski 0:01f31e923fe2 183 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 184 delay(10);
Pawel Zarembski 0:01f31e923fe2 185
Pawel Zarembski 0:01f31e923fe2 186 // Release CFG_nRST to allow SCC config
Pawel Zarembski 0:01f31e923fe2 187 LPC_GPIO->SET[PIN_CFG_nRST_PORT] = PIN_CFG_nRST;
Pawel Zarembski 0:01f31e923fe2 188
Pawel Zarembski 0:01f31e923fe2 189 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 190 delay(10);
Pawel Zarembski 0:01f31e923fe2 191
Pawel Zarembski 0:01f31e923fe2 192 // Configure SCC
Pawel Zarembski 0:01f31e923fe2 193 #if (defined MUSCA_B_BOOT_CODE_SRAM)
Pawel Zarembski 0:01f31e923fe2 194 configure_syscon(MUSCA_B_S_CODE_SRAM_START);
Pawel Zarembski 0:01f31e923fe2 195 #elif (defined MUSCA_B_BOOT_EFLASH1)
Pawel Zarembski 0:01f31e923fe2 196 configure_syscon(MUSCA_B_S_EFLASH1_START);
Pawel Zarembski 0:01f31e923fe2 197 #elif (defined MUSCA_B_BOOT_EFLASH0)
Pawel Zarembski 0:01f31e923fe2 198 configure_syscon(MUSCA_B_S_EFLASH0_START);
Pawel Zarembski 0:01f31e923fe2 199 #elif (defined MUSCA_B_BOOT_QSPI_FLASH)
Pawel Zarembski 0:01f31e923fe2 200 configure_syscon(MUSCA_B_S_FLASH_START);
Pawel Zarembski 0:01f31e923fe2 201 #endif
Pawel Zarembski 0:01f31e923fe2 202
Pawel Zarembski 0:01f31e923fe2 203 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 204 delay(10);
Pawel Zarembski 0:01f31e923fe2 205
Pawel Zarembski 0:01f31e923fe2 206 // Release SCC signals
Pawel Zarembski 0:01f31e923fe2 207 LPC_GPIO->DIR[PIN_SCC_CLK_PORT] &= ~PIN_SCC_CLK;
Pawel Zarembski 0:01f31e923fe2 208 LPC_GPIO->DIR[PIN_SCC_DATAIN_PORT] &= ~PIN_SCC_DATAIN;
Pawel Zarembski 0:01f31e923fe2 209 LPC_GPIO->DIR[PIN_SCC_DATAOUT_PORT] &= ~PIN_SCC_DATAOUT;
Pawel Zarembski 0:01f31e923fe2 210 LPC_GPIO->DIR[PIN_SCC_WNR_PORT] &= ~PIN_SCC_WNR;
Pawel Zarembski 0:01f31e923fe2 211 LPC_GPIO->DIR[PIN_SCC_LOAD_PORT] &= ~PIN_SCC_LOAD;
Pawel Zarembski 0:01f31e923fe2 212
Pawel Zarembski 0:01f31e923fe2 213 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 214 delay(10);
Pawel Zarembski 0:01f31e923fe2 215
Pawel Zarembski 0:01f31e923fe2 216 // Release CB_nRST
Pawel Zarembski 0:01f31e923fe2 217 LPC_GPIO->SET[PIN_CB_nRST_PORT] = PIN_CB_nRST;
Pawel Zarembski 0:01f31e923fe2 218
Pawel Zarembski 0:01f31e923fe2 219 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 220 delay(10);
Pawel Zarembski 0:01f31e923fe2 221
Pawel Zarembski 0:01f31e923fe2 222 // Release CS_nSRST
Pawel Zarembski 0:01f31e923fe2 223 LPC_GPIO->SET[PIN_nRESET_PORT] = PIN_nRESET;
Pawel Zarembski 0:01f31e923fe2 224
Pawel Zarembski 0:01f31e923fe2 225 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 226 delay(10);
Pawel Zarembski 0:01f31e923fe2 227
Pawel Zarembski 0:01f31e923fe2 228 // Enable Brown Out Detection
Pawel Zarembski 0:01f31e923fe2 229 enable_BOD(1);
Pawel Zarembski 0:01f31e923fe2 230 }
Pawel Zarembski 0:01f31e923fe2 231
Pawel Zarembski 0:01f31e923fe2 232 // BOD Interrupt Service Routine
Pawel Zarembski 0:01f31e923fe2 233 void BOD_IRQHandler(void)
Pawel Zarembski 0:01f31e923fe2 234 {
Pawel Zarembski 0:01f31e923fe2 235 NVIC_DisableIRQ(BOD_IRQn);
Pawel Zarembski 0:01f31e923fe2 236 gpio_set_cdc_led(GPIO_LED_OFF); // ON GREEN
Pawel Zarembski 0:01f31e923fe2 237
Pawel Zarembski 0:01f31e923fe2 238 // go into controlled shutdown
Pawel Zarembski 0:01f31e923fe2 239 power_off_sequence();
Pawel Zarembski 0:01f31e923fe2 240
Pawel Zarembski 0:01f31e923fe2 241 // Turn OFF power
Pawel Zarembski 0:01f31e923fe2 242 i2cio_power_off();
Pawel Zarembski 0:01f31e923fe2 243
Pawel Zarembski 0:01f31e923fe2 244 while(1)
Pawel Zarembski 0:01f31e923fe2 245 {
Pawel Zarembski 0:01f31e923fe2 246 delay(100);
Pawel Zarembski 0:01f31e923fe2 247 gpio_set_hid_led(GPIO_LED_ON);
Pawel Zarembski 0:01f31e923fe2 248 delay(100);
Pawel Zarembski 0:01f31e923fe2 249 gpio_set_hid_led(GPIO_LED_OFF);
Pawel Zarembski 0:01f31e923fe2 250 }
Pawel Zarembski 0:01f31e923fe2 251 }
Pawel Zarembski 0:01f31e923fe2 252
Pawel Zarembski 0:01f31e923fe2 253 // Function to wait till PBON button is pressed and released
Pawel Zarembski 0:01f31e923fe2 254 void wait_for_pbon(void)
Pawel Zarembski 0:01f31e923fe2 255 {
Pawel Zarembski 0:01f31e923fe2 256 // Standby - wait for PBON
Pawel Zarembski 0:01f31e923fe2 257 while (!gpio_get_pbon_btn())
Pawel Zarembski 0:01f31e923fe2 258 {
Pawel Zarembski 0:01f31e923fe2 259 // Do something with leds?
Pawel Zarembski 0:01f31e923fe2 260 gpio_set_cdc_led(GPIO_LED_ON);
Pawel Zarembski 0:01f31e923fe2 261 delay(100);
Pawel Zarembski 0:01f31e923fe2 262 gpio_set_cdc_led(GPIO_LED_OFF);
Pawel Zarembski 0:01f31e923fe2 263 delay(100);
Pawel Zarembski 0:01f31e923fe2 264 }
Pawel Zarembski 0:01f31e923fe2 265 // Wait for PBON to go low then high
Pawel Zarembski 0:01f31e923fe2 266 while (gpio_get_pbon_btn())
Pawel Zarembski 0:01f31e923fe2 267 {
Pawel Zarembski 0:01f31e923fe2 268 // Do something with leds?
Pawel Zarembski 0:01f31e923fe2 269 gpio_set_hid_led(GPIO_LED_ON);
Pawel Zarembski 0:01f31e923fe2 270 delay(100);
Pawel Zarembski 0:01f31e923fe2 271 gpio_set_hid_led(GPIO_LED_OFF);
Pawel Zarembski 0:01f31e923fe2 272 delay(100);
Pawel Zarembski 0:01f31e923fe2 273 }
Pawel Zarembski 0:01f31e923fe2 274 // Wait 10ms
Pawel Zarembski 0:01f31e923fe2 275 delay(10);
Pawel Zarembski 0:01f31e923fe2 276
Pawel Zarembski 0:01f31e923fe2 277 }