/* * main.c * * Copyright (C) 2018, 2019 Mind Chasers Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "board.h" #include "peripherals.h" #include "pin_mux.h" #include "clock_config.h" #include "MK02F12810.h" #include "fsl_debug_console.h" #include "fsl_gpio.h" #include "fsl_i2c.h" #include "fsl_dspi.h" #include "pin_mux.h" #include "fsl_pit.h" #include "pmic.h" #include "utils.h" #include "cmds.h" #include "spi.h" #include "pwr_driver.h" #include "phy_driver.h" #include "ecp5_driver.h" #include "main.h" /******************************************************************************* * Global Variables ******************************************************************************/ bool power = true; volatile int pit_cnt = 40; bool interactive = true; uint8_t cnt_scl_clk = 0; uint8_t cnt_bit = 0; uint8_t buf[100]; i2c_master_config_t i2c_masterConfig; i2c_master_transfer_t i2c_masterXfer; /* * Todo: Make sure the operations are atomic inside and outside the ISR */ void PIT0_IRQHandler(void) { /* Clear interrupt flag.*/ PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag); pit_cnt--; if (pit_cnt == 0) { pit_cnt = 40; } } /*! * @brief PHY Interrupt. Handle PTD5 (fpga_int) * */ void PORTD_IRQHandler(void) { uint8_t data; volatile uint32_t temp; i2c_write(&i2c_masterXfer, I2C_ECP5_ADDR, (uint8_t*) &c_init_pcsr, sizeof(c_init_pcsr)); i2c_write(&i2c_masterXfer, I2C_ECP5_ADDR, (uint8_t*) &c_init1, sizeof(c_init1)); temp = GPIO_PinRead(GPIOD, 0x5); // clear int src bits data=0; write_spi(SPI_DEV_AD_INT_SEL, 1, &data, 1); /* Clear external interrupt flag. */ GPIO_PortClearInterruptFlags(GPIOD, 0x1<<5); temp = GPIO_PortGetInterruptFlags(GPIOD); } /* * @brief Application entry point. */ int main(void) { int size; uint32_t sourceClock; volatile static int i = 0; volatile uint32_t temp; pit_config_t pitConfig; // Periodic Interrupt Timer gpio_pin_config_t pb7; // (10) PTE24 gpio_pin_config_t pb6; // (11) PTE25 gpio_pin_config_t pmic_dcdc_e; // (17) PTA18 gpio_pin_config_t pmic_ldo_e; // (18) PTA19 gpio_pin_config_t fcfg_pgmn; // (20) PTB0 gpio_pin_config_t fcfg_done; // (21) PTB1 gpio_pin_config_t fpga_gpio; // (22) PTC1 gpio_pin_config_t fpga_resetn; // (29) PTD4 gpio_pin_config_t fpga_int; // (30) PTD5 dspi_master_config_t spi_masterConfig; /* Init board hardware. */ BOARD_InitBootPins(); BOARD_InitBootClocks(); BOARD_InitBootPeripherals(); BOARD_InitDebugConsole(); /* Init GPIO */ pmic_ldo_e.pinDirection = kGPIO_DigitalOutput; pmic_ldo_e.outputLogic = 0; GPIO_PinInit(GPIOA, 19, &pmic_ldo_e); // Negate FPGA_RESETN GPIO_WritePinOutput(BOARD_INITPINS_FPGA_RESETN_GPIO, BOARD_INITPINS_FPGA_RESETN_PIN, 1); /* * Initialize PIT module * pitConfig.enableRunInDebug = false; * Calls CLOCK_EnableCLock to enable PIT clock (gate control) in SIM_SCGC6 * Configures PIT MCR register to enable clock for PIT timer and disable run during debug */ PIT_GetDefaultConfig(&pitConfig); PIT_Init(PIT, &pitConfig); /* Set timer period for channel 0, * calls CLOCK_GetFreq() * sets PIT_LDVAL0 */ PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, USEC_TO_COUNT(100U, CLOCK_GetFreq(kCLOCK_BusClk))); /* Enable timer interrupts for channel 0 , * set PIT_TCTRL0 = 2 (Timer Interrupt Enable ) */ PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable); /* Start PIT channel 0 */ PIT_StartTimer(PIT, kPIT_Chnl_0); printf("Initialize I2C0.\n"); I2C_MasterGetDefaultConfig(&i2c_masterConfig); i2c_masterConfig.baudRate_Bps = I2C_BAUDRATE; sourceClock = CLOCK_GetFreq(I2C_MASTER_CLK_SRC); I2C_MasterInit(I2C_MASTER_BASEADDR, &i2c_masterConfig, sourceClock); memset(&i2c_masterXfer, 0, sizeof(i2c_masterXfer)); // set up defaults applicable to all transfers i2c_masterXfer.subaddress = 0; i2c_masterXfer.subaddressSize = 0; i2c_masterXfer.flags = kI2C_TransferDefaultFlag; if (power) { printf("Initialize Power\n\r"); power_init(&i2c_masterXfer, buf); } // wait for the FPGA to be ready // TODO: add a robust handshake that also interrogates the FPGA image while (i2c_read(&i2c_masterXfer, I2C_ECP5_ADDR, buf, 8) < 0) { PRINTF("."); } spi_init(spi_masterConfig); PRINTF("\r\n Darsena! \r\n"); i=0; while (phy_init(&i2c_masterXfer, buf) < 0) { i++; } i=0; while (ecp5_pcs_init(&i2c_masterXfer, buf) < 0) { i++; } /* buf[0]=192; buf[1]=168; buf[2]=3; buf[3]=1; for (i = 0; i< 100; i++) { PRINTF("\r\n test_spi() \r\n"); write_spi(SPI_DEV_AD_DPRAM_RX, 0, buf, 4); read_spi(SPI_DEV_AD_DPRAM_RX, 0, buf, 4); write_spi(SPI_DEV_AD_DPRAM_TX, 0, buf, 4); read_spi(SPI_DEV_AD_DPRAM_TX, 0, buf, 4); write_spi(SPI_DEV_AD_PKT_FILTER_01, 0, buf, 4); read_spi(SPI_DEV_AD_SCI_SEL_CH_0, 0, buf, 4); } */ temp = GPIO_PortGetInterruptFlags(GPIOD); EnableIRQ(PIT0_IRQn); EnableIRQ(PORTD_IRQn); while(interactive) { PRINTF("\r\n I2C Command Line. Hit enter to continue \r\n"); DbgConsole_Flush(); do { size = get_cmd(buf, 10); PRINTF("\r\n received %d bytes \r\n", size); if (size != 0) { if (buf[0] == 'T') { phy_compliance_test(&i2c_masterXfer, buf[1]); } else { i2c_write(&i2c_masterXfer, I2C_ECP5_ADDR, buf, size); i2c_read(&i2c_masterXfer, I2C_ECP5_ADDR, buf, 8); dump_data((uint8_t*) buf, 4, true ); } } } while(size != 0); } /* Force the counter to be placed into memory. */ while(1) { PRINTF("."); i++; } return 0 ; } /* p_reg = (uint32_t*) 0x40037104; temp_reg = *p_reg; temp_reg = PIT_GetStatusFlags(PIT, kPIT_Chnl_0); if (temp_reg != 0) { // *pTFLG = 1; temp_reg = __get_PRIMASK(); temp_reg = __get_IPSR(); temp_reg = NVIC_GetActive(PIT0_IRQn); temp_reg = NVIC_GetEnableIRQ(PIT0_IRQn); } */