void gpio_init(gpio_t *obj, PinName pin) { MBED_ASSERT(obj); obj->pin = pin; obj->dir = PIN_INPUT; obj->mode = PullNone; if (pin == NC) { return; } MBED_ASSERT(CY_PIN(obj->pin) < 8); // PSoC6 architecture supports 8 pins per port. /* * Perform i/o reservation only if this is called outside of critical section/interrupt context. * This is a workaround for mbed_die() implementation, which configures LED1 inside critical section. * Normally user is advised to perform all of the i/o configuration at the program beginning, * or elsewhere in the running thread context. when we detect that we are in the wrong context here, * we assume it's explicitly called from mbed_die() or other fault handling, so eventual forcing * of the pin mode is deliberate and should not cause more problems. */ if (!(IsIrqMode() || IsIrqMasked())) { if (cy_reserve_io_pin(pin)) { error("GPIO pin reservation conflict."); } } obj->port = Cy_GPIO_PortToAddr(CY_PORT(obj->pin)); const uint32_t outputVal = 0; Cy_GPIO_Pin_FastInit(obj->port, CY_PIN(obj->pin), CY_GPIO_DM_HIGHZ, outputVal, HSIOM_SEL_GPIO); }
/* * Initializes i/o pins for spi. */ static void spi_init_pins(spi_obj_t *obj) { bool conflict = false; conflict = cy_reserve_io_pin(obj->pin_sclk); if (!conflict) { pin_function(obj->pin_sclk, pinmap_function(obj->pin_sclk, PinMap_SPI_SCLK)); } if (obj->pin_mosi != NC) { if (!cy_reserve_io_pin(obj->pin_mosi)) { pin_function(obj->pin_mosi, pinmap_function(obj->pin_mosi, PinMap_SPI_MOSI)); } else { conflict = true; } } if (obj->pin_miso != NC) { if (!cy_reserve_io_pin(obj->pin_miso)) { pin_function(obj->pin_miso, pinmap_function(obj->pin_miso, PinMap_SPI_MISO)); } else { conflict = true; } } if (obj->pin_ssel != NC) { if (!cy_reserve_io_pin(obj->pin_ssel)) { pin_function(obj->pin_ssel, pinmap_function(obj->pin_ssel, PinMap_SPI_SSEL)); } else { conflict = true; } } if (conflict) { error("SPI pin reservation conflict."); } // Pin configuration in PinMap defaults to Master mode; revert for Slave. if (obj->ms_mode == CY_SCB_SPI_SLAVE) { pin_mode(obj->pin_sclk, PullNone); pin_mode(obj->pin_mosi, PullNone); pin_mode(obj->pin_miso, PushPull); pin_mode(obj->pin_ssel, PullNone); } }
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { uint32_t pin; MBED_ASSERT(obj); for (pin = 0; pin < 8; ++pin) { if (mask & (1 << pin)) { if (cy_reserve_io_pin((PinName)((port << 8)+pin))) { error("Port pin reservation conflict."); } } } obj->port_id = port; obj->port = Cy_GPIO_PortToAddr(port); obj->mask = mask & 0xff; // Only 8 bits exist on a port in PSoC. obj->direction = dir; obj->mode = PullDefault; port_init_pins(obj); }
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { uint32_t pin; MBED_ASSERT(obj); for (pin = 0; pin < 8; ++pin) { if (mask & (1 << pin)) { /* Ignore pin reservation result because there is not possibility to release * reserved HW resource. The MBED does not provide proper destructors for * doing that. */ (void) cy_reserve_io_pin((PinName)((port << 8) + pin)); } } obj->port_id = port; obj->port = Cy_GPIO_PortToAddr(port); obj->mask = mask & 0xff; // Only 8 bits exist on a port in PSoC. obj->direction = dir; obj->mode = PullDefault; port_init_pins(obj); }
static void ClockInit(void) { uint32_t status; /* Enable all source clocks */ status = Cy_SysClk_WcoEnable(500000u); if (CY_RET_SUCCESS != status) { CyClockStartupError(CYCLOCKSTART_WCO_ERROR); } Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_WCO); #if FEATURE_BLE { cy_stc_ble_bless_eco_cfg_params_t bleCfg = { .ecoXtalStartUpTime = (785 / 31.25), .loadCap = ((9.9 - 7.5) / 0.075), .ecoFreq = CY_BLE_BLESS_ECO_FREQ_32MHZ, .ecoSysDiv = CY_BLE_SYS_ECO_CLK_DIV_4 }; Cy_BLE_EcoStart(&bleCfg); } #endif // FEATURE_BLE /* Configure CPU clock dividers */ Cy_SysClk_ClkFastSetDivider(0u); Cy_SysClk_ClkPeriSetDivider((CY_CLK_HFCLK0_FREQ_HZ / CY_CLK_PERICLK_FREQ_HZ) - 1); Cy_SysClk_ClkSlowSetDivider((CY_CLK_PERICLK_FREQ_HZ / CY_CLK_SYSTEM_FREQ_HZ) - 1); /* Configure LF & HF clocks */ Cy_SysClk_ClkHfSetSource(0u, CY_SYSCLK_CLKHF_IN_CLKPATH1); Cy_SysClk_ClkHfSetDivider(0u, CY_SYSCLK_CLKHF_NO_DIVIDE); Cy_SysClk_ClkHfEnable(0u); /* Configure Path Clocks */ /* PLL path is used to clock HF domain from BLE ECO */ Cy_SysClk_ClkPathSetSource(2, CY_SYSCLK_CLKPATH_IN_IMO); Cy_SysClk_ClkPathSetSource(3, CY_SYSCLK_CLKPATH_IN_IMO); Cy_SysClk_ClkPathSetSource(4, CY_SYSCLK_CLKPATH_IN_IMO); #if FEATURE_BLE Cy_SysClk_ClkPathSetSource(0, CY_SYSCLK_CLKPATH_IN_ALTHF); Cy_SysClk_ClkPathSetSource(1, CY_SYSCLK_CLKPATH_IN_ALTHF); { const cy_stc_pll_config_t pllConfig = { .inputFreq = CY_CLK_ALTHF_FREQ_HZ, .outputFreq = CY_CLK_HFCLK0_FREQ_HZ, .lfMode = false, .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO }; #else Cy_SysClk_ClkPathSetSource(0, CY_SYSCLK_CLKPATH_IN_IMO); Cy_SysClk_ClkPathSetSource(1, CY_SYSCLK_CLKPATH_IN_IMO); { const cy_stc_pll_config_t pllConfig = { .inputFreq = CY_CLK_IMO_FREQ_HZ, .outputFreq = CY_CLK_HFCLK0_FREQ_HZ, .lfMode = false, .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO }; #endif // FEATURE_BLE status = Cy_SysClk_PllConfigure(1u, &pllConfig); if (CY_SYSCLK_SUCCESS != status) { CyClockStartupError(CYCLOCKSTART_PLL_ERROR); } } status = Cy_SysClk_PllEnable(1u, 10000u); if (CY_SYSCLK_SUCCESS != status) { CyClockStartupError(CYCLOCKSTART_PLL_ERROR); } /* Configure miscellaneous clocks */ Cy_SysClk_ClkTimerSetSource(CY_SYSCLK_CLKTIMER_IN_HF0_NODIV); Cy_SysClk_ClkTimerSetDivider(0); Cy_SysClk_ClkTimerEnable(); Cy_SysClk_ClkPumpSetSource(CY_SYSCLK_PUMP_IN_CLKPATH0); Cy_SysClk_ClkPumpSetDivider(CY_SYSCLK_PUMP_DIV_4); Cy_SysClk_ClkPumpEnable(); Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_WCO); /* Disable unused clocks started by default */ Cy_SysClk_IloDisable(); /* Set memory wait states based on HFClk[0] */ Cy_SysLib_SetWaitStates(false, (CY_CLK_HFCLK0_FREQ_HZ + 990000) / 1000000UL); } /* Analog API Functions */ /******************************************************************************* * Function Name: AnalogSetDefault ******************************************************************************** * * Summary: * Sets up the analog portions of the chip to default values based on chip * configuration options from the project. * * Parameters: * void * * Return: * void * *******************************************************************************/ static void AnalogSetDefault(void) { const cy_stc_sysanalog_config_t config = { .startup = CY_SYSANALOG_STARTUP_NORMAL, .iztat = CY_SYSANALOG_IZTAT_SOURCE_LOCAL, .vref = CY_SYSANALOG_VREF_SOURCE_LOCAL_1_2V, .deepSleep = CY_SYSANALOG_DEEPSLEEP_IPTAT_1 }; Cy_SysAnalog_Init(&config); Cy_SysAnalog_Enable(); } /******************************************************************************* * Function Name: Cy_SystemInit ******************************************************************************** * Summary: * This function is called by the start-up code for the selected device. It * performs all of the necessary device configuration based on the design * settings. This includes settings from the Design Wide Resources (DWR) such * as Clocks and Pins as well as any component configuration that is necessary. * * Parameters: * void * * Return: * void * *******************************************************************************/ void Cy_SystemInit(void) { /* Set worst case memory wait states (150 MHz), ClockInit() will update */ Cy_SysLib_SetWaitStates(false, 150); if(0u == Cy_SysLib_GetResetReason()) { /* POR, XRES, or BOD */ Cy_SysLib_ResetBackupDomain(); } /* Power Mode */ Cy_SysPm_LdoSetVoltage(CY_SYSPM_LDO_VOLTAGE_1_1V); /* PMIC Control */ Cy_SysPm_UnlockPmic(); Cy_SysPm_DisablePmicOutput(); /* Pin0_0 and Pin0_1 drive WCO, configure as analog before configuring clock */ cy_reserve_io_pin(P0_0); cy_reserve_io_pin(P0_1); Cy_GPIO_Pin_FastInit(GPIO_PRT0, 0, CY_GPIO_DM_ANALOG, 0, P0_0_GPIO); Cy_GPIO_Pin_FastInit(GPIO_PRT0, 1, CY_GPIO_DM_ANALOG, 0, P0_1_GPIO); /* Clock */ ClockInit(); /******* Pre-defined port configuration section ********/ { /* RGB LED is P_0_3 (R), P_1_1 (G) and P_11_1 (B) */ const uint32_t led_off = 1; Cy_GPIO_Pin_FastInit(GPIO_PRT0, 3, CY_GPIO_DM_STRONG_IN_OFF, led_off, P0_3_GPIO); Cy_GPIO_Pin_FastInit(GPIO_PRT1, 1, CY_GPIO_DM_STRONG_IN_OFF, led_off, P1_1_GPIO); Cy_GPIO_Pin_FastInit(GPIO_PRT11, 1, CY_GPIO_DM_STRONG_IN_OFF, led_off, P11_1_GPIO); /* USER BUTTON is P_0_4 */ Cy_GPIO_Pin_FastInit(GPIO_PRT0, 4, CY_GPIO_DM_PULLUP, 1, P0_4_GPIO); /* Configure hw debug interface on port 6 */ cy_reserve_io_pin(P6_6); cy_reserve_io_pin(P6_7); Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_PULLUP, 0, P6_6_CPUSS_SWJ_SWDIO_TMS); Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_PULLDOWN, 0, P6_7_CPUSS_SWJ_SWCLK_TCLK); } /* Perform basic analog initialization to defaults */ AnalogSetDefault(); }
void pwmout_init(pwmout_t *obj, PinName pin) { uint32_t pwm_cnt = 0; uint32_t pwm_function = 0; uint32_t abs_cnt_num = 0; MBED_ASSERT(obj); MBED_ASSERT(pin != (PinName)NC); // Allocate and setup clock. if (pwm_clock_divider == CY_INVALID_DIVIDER) { pwm_clock_divider = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT); if (pwm_clock_divider == CY_INVALID_DIVIDER) { error("PWM clock divider allocation failed."); return; } Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, pwm_clock_divider, (CY_CLK_PERICLK_FREQ_HZ / PWMOUT_BASE_CLOCK_HZ) - 1); Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, pwm_clock_divider); } pwm_cnt = pinmap_peripheral(pin, PinMap_PWM_OUT); if (pwm_cnt != (uint32_t)NC) { if (cy_reserve_io_pin(pin)) { error("PWMOUT pin reservation conflict."); } obj->base = (TCPWM_Type*)CY_PERIPHERAL_BASE(pwm_cnt); obj->pin = pin; if (obj->base == TCPWM0) { obj->counter_id = ((PWMName)pwm_cnt - PWM_32b_0) / (PWM_32b_1 - PWM_32b_0); abs_cnt_num = obj->counter_id; } else { // TCPWM1 is used. obj->counter_id = ((PWMName)pwm_cnt - PWM_16b_0) / (PWM_16b_1 - PWM_16b_0); abs_cnt_num = obj->counter_id + 8; } if (cy_reserve_tcpwm(abs_cnt_num)) { error("PWMOUT Timer/Counter reservation conflict."); } // Configure clock. pwm_function = pinmap_function(pin, PinMap_PWM_OUT); obj->clock = CY_PIN_CLOCK(pwm_function); Cy_SysClk_PeriphAssignDivider(obj->clock, CY_SYSCLK_DIV_8_BIT, pwm_clock_divider); Cy_TCPWM_PWM_Init(obj->base, obj->counter_id, &pwm_config); pin_function(pin, pwm_function); // These will be properly configured later on. obj->period = 0; obj->pulse_width = 0; obj->prescaler = 0; #if DEVICE_SLEEP && DEVICE_LPTICKER obj->pm_callback_handler.callback = pwm_pm_callback; obj->pm_callback_handler.type = CY_SYSPM_DEEPSLEEP; obj->pm_callback_handler.skipMode = 0; obj->pm_callback_handler.callbackParams = &obj->pm_callback_params; obj->pm_callback_params.base = obj->base; obj->pm_callback_params.context = obj; if (!Cy_SysPm_RegisterCallback(&obj->pm_callback_handler)) { error("PM callback registration failed!"); } #endif // DEVICE_SLEEP && DEVICE_LPTICKER } else { error("PWM OUT pinout mismatch."); } }