|  |  | @@ -27,6 +27,7 @@ static void reset_PFD(); | 
		
	
		
			
			|  |  |  | extern void systick_isr(void); | 
		
	
		
			
			|  |  |  | extern void pendablesrvreq_isr(void); | 
		
	
		
			
			|  |  |  | void configure_cache(void); | 
		
	
		
			
			|  |  |  | void configure_external_ram(void); | 
		
	
		
			
			|  |  |  | void unused_interrupt_vector(void); | 
		
	
		
			
			|  |  |  | void usb_pll_start(); | 
		
	
		
			
			|  |  |  | extern void analog_init(void); // analog.c | 
		
	
	
		
			
			|  |  | @@ -122,6 +123,9 @@ void ResetHandler(void) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | SNVS_HPCR |= SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #ifdef ARDUINO_TEENSY41 | 
		
	
		
			
			|  |  |  | configure_external_ram(); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | startup_early_hook(); | 
		
	
		
			
			|  |  |  | while (millis() < 20) ; // wait at least 20ms before starting USB | 
		
	
		
			
			|  |  |  | usb_init(); | 
		
	
	
		
			
			|  |  | @@ -248,10 +252,10 @@ FLASHMEM void configure_cache(void) | 
		
	
		
			
			|  |  |  | SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | SIZE_16M; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2 | 
		
	
		
			
			|  |  |  | SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | SIZE_256M; | 
		
	
		
			
			|  |  |  | SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | NOEXEC | SIZE_256M; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2 | 
		
	
		
			
			|  |  |  | SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | SIZE_16M; | 
		
	
		
			
			|  |  |  | SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_16M; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // TODO: protect access to power supply config | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
			|  |  | @@ -267,6 +271,171 @@ FLASHMEM void configure_cache(void) | 
		
	
		
			
			|  |  |  | SCB_CCR |= (SCB_CCR_IC | SCB_CCR_DC); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #ifdef ARDUINO_TEENSY41 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #define LUT0(opcode, pads, operand) (FLEXSPI_LUT_INSTRUCTION((opcode), (pads), (operand))) | 
		
	
		
			
			|  |  |  | #define LUT1(opcode, pads, operand) (FLEXSPI_LUT_INSTRUCTION((opcode), (pads), (operand)) << 16) | 
		
	
		
			
			|  |  |  | #define CMD_SDR         FLEXSPI_LUT_OPCODE_CMD_SDR | 
		
	
		
			
			|  |  |  | #define ADDR_SDR        FLEXSPI_LUT_OPCODE_RADDR_SDR | 
		
	
		
			
			|  |  |  | #define READ_SDR        FLEXSPI_LUT_OPCODE_READ_SDR | 
		
	
		
			
			|  |  |  | #define WRITE_SDR       FLEXSPI_LUT_OPCODE_WRITE_SDR | 
		
	
		
			
			|  |  |  | #define DUMMY_SDR       FLEXSPI_LUT_OPCODE_DUMMY_SDR | 
		
	
		
			
			|  |  |  | #define PINS1           FLEXSPI_LUT_NUM_PADS_1 | 
		
	
		
			
			|  |  |  | #define PINS4           FLEXSPI_LUT_NUM_PADS_4 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLASHMEM static void flexspi2_command(uint32_t index, uint32_t addr) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | FLEXSPI2_IPCR0 = addr; | 
		
	
		
			
			|  |  |  | FLEXSPI2_IPCR1 = FLEXSPI_IPCR1_ISEQID(index); | 
		
	
		
			
			|  |  |  | FLEXSPI2_IPCMD = FLEXSPI_IPCMD_TRG; | 
		
	
		
			
			|  |  |  | while (!(FLEXSPI2_INTR & FLEXSPI_INTR_IPCMDDONE)); // wait | 
		
	
		
			
			|  |  |  | FLEXSPI2_INTR = FLEXSPI_INTR_IPCMDDONE; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLASHMEM static uint32_t flexspi2_psram_id(uint32_t addr) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | FLEXSPI2_IPCR0 = addr; | 
		
	
		
			
			|  |  |  | FLEXSPI2_IPCR1 = FLEXSPI_IPCR1_ISEQID(3) | FLEXSPI_IPCR1_IDATSZ(4); | 
		
	
		
			
			|  |  |  | FLEXSPI2_IPCMD = FLEXSPI_IPCMD_TRG; | 
		
	
		
			
			|  |  |  | while (!(FLEXSPI2_INTR & FLEXSPI_INTR_IPCMDDONE)); // wait | 
		
	
		
			
			|  |  |  | uint32_t id = FLEXSPI2_RFDR0; | 
		
	
		
			
			|  |  |  | FLEXSPI2_INTR = FLEXSPI_INTR_IPCMDDONE | FLEXSPI_INTR_IPRXWA; | 
		
	
		
			
			|  |  |  | return id & 0xFFFF; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLASHMEM void configure_external_ram() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | // initialize pins | 
		
	
		
			
			|  |  |  | IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_22 = 0xB0E1; // 100K pullup, medium drive, max speed | 
		
	
		
			
			|  |  |  | IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_23 = 0x10E1; // keeper, medium drive, max speed | 
		
	
		
			
			|  |  |  | IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_24 = 0xB0E1; // 100K pullup, medium drive, max speed | 
		
	
		
			
			|  |  |  | IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_25 = 0x00E1; // medium drive, max speed | 
		
	
		
			
			|  |  |  | IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_26 = 0x70E1; // 47K pullup, medium drive, max speed | 
		
	
		
			
			|  |  |  | IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_27 = 0x70E1; // 47K pullup, medium drive, max speed | 
		
	
		
			
			|  |  |  | IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_28 = 0x70E1; // 47K pullup, medium drive, max speed | 
		
	
		
			
			|  |  |  | IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_29 = 0x70E1; // 47K pullup, medium drive, max speed | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_22 = 8 | 0x10; // ALT1 = FLEXSPI2_A_SS1_B (Flash) | 
		
	
		
			
			|  |  |  | IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_23 = 8 | 0x10; // ALT1 = FLEXSPI2_A_DQS | 
		
	
		
			
			|  |  |  | IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_24 = 8 | 0x10; // ALT1 = FLEXSPI2_A_SS0_B (RAM) | 
		
	
		
			
			|  |  |  | IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_25 = 8 | 0x10; // ALT1 = FLEXSPI2_A_SCLK | 
		
	
		
			
			|  |  |  | IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_26 = 8 | 0x10; // ALT1 = FLEXSPI2_A_DATA0 | 
		
	
		
			
			|  |  |  | IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_27 = 8 | 0x10; // ALT1 = FLEXSPI2_A_DATA1 | 
		
	
		
			
			|  |  |  | IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_28 = 8 | 0x10; // ALT1 = FLEXSPI2_A_DATA2 | 
		
	
		
			
			|  |  |  | IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_29 = 8 | 0x10; // ALT1 = FLEXSPI2_A_DATA3 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | IOMUXC_FLEXSPI2_IPP_IND_DQS_FA_SELECT_INPUT = 1; // GPIO_EMC_23 for Mode: ALT8, pg 986 | 
		
	
		
			
			|  |  |  | IOMUXC_FLEXSPI2_IPP_IND_IO_FA_BIT0_SELECT_INPUT = 1; // GPIO_EMC_26 for Mode: ALT8 | 
		
	
		
			
			|  |  |  | IOMUXC_FLEXSPI2_IPP_IND_IO_FA_BIT1_SELECT_INPUT = 1; // GPIO_EMC_27 for Mode: ALT8 | 
		
	
		
			
			|  |  |  | IOMUXC_FLEXSPI2_IPP_IND_IO_FA_BIT2_SELECT_INPUT = 1; // GPIO_EMC_28 for Mode: ALT8 | 
		
	
		
			
			|  |  |  | IOMUXC_FLEXSPI2_IPP_IND_IO_FA_BIT3_SELECT_INPUT = 1; // GPIO_EMC_29 for Mode: ALT8 | 
		
	
		
			
			|  |  |  | IOMUXC_FLEXSPI2_IPP_IND_SCK_FA_SELECT_INPUT = 1; // GPIO_EMC_25 for Mode: ALT8 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // turn on clock  (TODO: increase clock speed later, slow & cautious for first release) | 
		
	
		
			
			|  |  |  | CCM_CBCMR = (CCM_CBCMR & (CCM_CBCMR_FLEXSPI2_PODF_MASK | CCM_CBCMR_FLEXSPI2_CLK_SEL_MASK)) | 
		
	
		
			
			|  |  |  | | CCM_CBCMR_FLEXSPI2_PODF(7) | CCM_CBCMR_FLEXSPI2_CLK_SEL(0); // 49.5 MHz | 
		
	
		
			
			|  |  |  | CCM_CCGR7 |= CCM_CCGR7_FLEXSPI2(CCM_CCGR_ON); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLEXSPI2_MCR0 |= FLEXSPI_MCR0_MDIS; | 
		
	
		
			
			|  |  |  | FLEXSPI2_MCR0 = (FLEXSPI2_MCR0 & ~(FLEXSPI_MCR0_AHBGRANTWAIT_MASK | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR0_IPGRANTWAIT_MASK | FLEXSPI_MCR0_SCKFREERUNEN | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR0_COMBINATIONEN | FLEXSPI_MCR0_DOZEEN | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR0_HSEN | FLEXSPI_MCR0_ATDFEN | FLEXSPI_MCR0_ARDFEN | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR0_RXCLKSRC_MASK | FLEXSPI_MCR0_SWRESET)) | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR0_AHBGRANTWAIT(0xFF) | FLEXSPI_MCR0_IPGRANTWAIT(0xFF) | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR0_RXCLKSRC(1) | FLEXSPI_MCR0_MDIS; | 
		
	
		
			
			|  |  |  | FLEXSPI2_MCR1 = FLEXSPI_MCR1_SEQWAIT(0xFFFF) | FLEXSPI_MCR1_AHBBUSWAIT(0xFFFF); | 
		
	
		
			
			|  |  |  | FLEXSPI2_MCR2 = (FLEXSPI_MCR2 & ~(FLEXSPI_MCR2_RESUMEWAIT_MASK | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR2_SCKBDIFFOPT | FLEXSPI_MCR2_SAMEDEVICEEN | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR2_CLRLEARNPHASE | FLEXSPI_MCR2_CLRAHBBUFOPT)) | 
		
	
		
			
			|  |  |  | | FLEXSPI_MCR2_RESUMEWAIT(0x20) /*| FLEXSPI_MCR2_SAMEDEVICEEN*/; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLEXSPI2_AHBCR = FLEXSPI2_AHBCR & ~(FLEXSPI_AHBCR_READADDROPT | FLEXSPI_AHBCR_PREFETCHEN | 
		
	
		
			
			|  |  |  | | FLEXSPI_AHBCR_BUFFERABLEEN | FLEXSPI_AHBCR_CACHABLEEN); | 
		
	
		
			
			|  |  |  | uint32_t mask = (FLEXSPI_AHBRXBUFCR0_PREFETCHEN | FLEXSPI_AHBRXBUFCR0_PRIORITY_MASK | 
		
	
		
			
			|  |  |  | | FLEXSPI_AHBRXBUFCR0_MSTRID_MASK | FLEXSPI_AHBRXBUFCR0_BUFSZ_MASK); | 
		
	
		
			
			|  |  |  | FLEXSPI2_AHBRXBUF0CR0 = (FLEXSPI2_AHBRXBUF0CR0 & ~mask) | 
		
	
		
			
			|  |  |  | | FLEXSPI_AHBRXBUFCR0_PREFETCHEN | FLEXSPI_AHBRXBUFCR0_BUFSZ(64); | 
		
	
		
			
			|  |  |  | FLEXSPI2_AHBRXBUF1CR0 = (FLEXSPI2_AHBRXBUF0CR0 & ~mask) | 
		
	
		
			
			|  |  |  | | FLEXSPI_AHBRXBUFCR0_PREFETCHEN | FLEXSPI_AHBRXBUFCR0_BUFSZ(64); | 
		
	
		
			
			|  |  |  | FLEXSPI2_AHBRXBUF2CR0 = mask; | 
		
	
		
			
			|  |  |  | FLEXSPI2_AHBRXBUF3CR0 = mask; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // RX watermark = one 64 bit line | 
		
	
		
			
			|  |  |  | FLEXSPI2_IPRXFCR = (FLEXSPI_IPRXFCR & 0xFFFFFFC0) | FLEXSPI_IPRXFCR_CLRIPRXF; | 
		
	
		
			
			|  |  |  | // TX watermark = one 64 bit line | 
		
	
		
			
			|  |  |  | FLEXSPI2_IPTXFCR = (FLEXSPI_IPTXFCR & 0xFFFFFFC0) | FLEXSPI_IPTXFCR_CLRIPTXF; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLEXSPI2_INTEN = 0; | 
		
	
		
			
			|  |  |  | FLEXSPI2_FLSHA1CR0 = 0x2000; // 8 MByte | 
		
	
		
			
			|  |  |  | FLEXSPI2_FLSHA1CR1 = FLEXSPI_FLSHCR1_CSINTERVAL(2) | 
		
	
		
			
			|  |  |  | | FLEXSPI_FLSHCR1_TCSH(3) | FLEXSPI_FLSHCR1_TCSS(3); | 
		
	
		
			
			|  |  |  | FLEXSPI2_FLSHA1CR2 = FLEXSPI_FLSHCR2_AWRSEQID(6) | FLEXSPI_FLSHCR2_AWRSEQNUM(0) | 
		
	
		
			
			|  |  |  | | FLEXSPI_FLSHCR2_ARDSEQID(5) | FLEXSPI_FLSHCR2_ARDSEQNUM(0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLEXSPI2_FLSHA2CR0 = 0x2000; // 8 MByte | 
		
	
		
			
			|  |  |  | FLEXSPI2_FLSHA2CR1 = FLEXSPI_FLSHCR1_CSINTERVAL(2) | 
		
	
		
			
			|  |  |  | | FLEXSPI_FLSHCR1_TCSH(3) | FLEXSPI_FLSHCR1_TCSS(3); | 
		
	
		
			
			|  |  |  | FLEXSPI2_FLSHA2CR2 = FLEXSPI_FLSHCR2_AWRSEQID(6) | FLEXSPI_FLSHCR2_AWRSEQNUM(0) | 
		
	
		
			
			|  |  |  | | FLEXSPI_FLSHCR2_ARDSEQID(5) | FLEXSPI_FLSHCR2_ARDSEQNUM(0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLEXSPI2_MCR0 &= ~FLEXSPI_MCR0_MDIS; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUTKEY = FLEXSPI_LUTKEY_VALUE; | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUTCR = FLEXSPI_LUTCR_UNLOCK; | 
		
	
		
			
			|  |  |  | volatile uint32_t *luttable = &FLEXSPI2_LUT0; | 
		
	
		
			
			|  |  |  | for (int i=0; i < 64; i++) luttable[i] = 0; | 
		
	
		
			
			|  |  |  | FLEXSPI2_MCR0 |= FLEXSPI_MCR0_SWRESET; | 
		
	
		
			
			|  |  |  | while (FLEXSPI2_MCR0 & FLEXSPI_MCR0_SWRESET) ; // wait | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUTKEY = FLEXSPI_LUTKEY_VALUE; | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUTCR = FLEXSPI_LUTCR_UNLOCK; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // cmd index 0 = exit QPI mode | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT0 = LUT0(CMD_SDR, PINS4, 0xF5); | 
		
	
		
			
			|  |  |  | // cmd index 1 = reset enable | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT4 = LUT0(CMD_SDR, PINS1, 0x66); | 
		
	
		
			
			|  |  |  | // cmd index 2 = reset | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT8 = LUT0(CMD_SDR, PINS1, 0x99); | 
		
	
		
			
			|  |  |  | // cmd index 3 = read ID bytes | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT12 = LUT0(CMD_SDR, PINS1, 0x9F) | LUT1(DUMMY_SDR, PINS1, 24); | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT13 = LUT0(READ_SDR, PINS1, 1); | 
		
	
		
			
			|  |  |  | // cmd index 4 = enter QPI mode | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT16 = LUT0(CMD_SDR, PINS1, 0x35); | 
		
	
		
			
			|  |  |  | // cmd index 5 = read QPI | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT20 = LUT0(CMD_SDR, PINS4, 0xEB) | LUT1(ADDR_SDR, PINS4, 24); | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT21 = LUT0(DUMMY_SDR, PINS4, 6) | LUT1(READ_SDR, PINS4, 1); | 
		
	
		
			
			|  |  |  | // cmd index 6 = write QPI | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT24 = LUT0(CMD_SDR, PINS4, 0x38) | LUT1(ADDR_SDR, PINS4, 24); | 
		
	
		
			
			|  |  |  | FLEXSPI2_LUT25 = LUT0(WRITE_SDR, PINS4, 1); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // look for the first PSRAM chip | 
		
	
		
			
			|  |  |  | flexspi2_command(0, 0); // exit quad mode | 
		
	
		
			
			|  |  |  | flexspi2_command(1, 0); // reset enable | 
		
	
		
			
			|  |  |  | flexspi2_command(2, 0); // reset (is this really necessary?) | 
		
	
		
			
			|  |  |  | if (flexspi2_psram_id(0) == 0x5D0D) { | 
		
	
		
			
			|  |  |  | // first PSRAM chip is present, look for a second PSRAM chip | 
		
	
		
			
			|  |  |  | flexspi2_command(4, 0); | 
		
	
		
			
			|  |  |  | flexspi2_command(0, 0x800000); // exit quad mode | 
		
	
		
			
			|  |  |  | flexspi2_command(1, 0x800000); // reset enable | 
		
	
		
			
			|  |  |  | flexspi2_command(2, 0x800000); // reset (is this really necessary?) | 
		
	
		
			
			|  |  |  | if (flexspi2_psram_id(0x800000) == 0x5D0D) { | 
		
	
		
			
			|  |  |  | flexspi2_command(4, 0x800000); | 
		
	
		
			
			|  |  |  | // Two PSRAM chips are present, 16 MByte | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | // One PSRAM chip is present, 8 MByte | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | // TODO: zero uninitialized EXTMEM variables | 
		
	
		
			
			|  |  |  | // TODO: copy from flash to initialize EXTMEM variables | 
		
	
		
			
			|  |  |  | // TODO: set up for malloc_extmem() | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | // No PSRAM | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #endif // ARDUINO_TEENSY41 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | FLASHMEM void usb_pll_start() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | while (1) { |