/***************************************************************************//** * @brief * Initalize basic I2C master mode driver for use on the DK. * * @details * This driver only supports master mode, single bus-master. In addition * to configuring the EFM32 I2C peripheral module, it also configures DK * specific setup in order to use the I2C bus. * * @param[in] init * Pointer to I2C initialization structure. ******************************************************************************/ void I2CDRV_Init(const I2C_Init_TypeDef *init) { int i; #ifndef BSP_STK BSP_PeripheralAccess(BSP_I2C, true); #endif CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_I2C0, true); /* Output value must be set to 1 to not drive lines low. Set */ /* SCL first, to ensure it is high before changing SDA. */ GPIO_PinModeSet(I2CDRV_SCL_PORT, I2CDRV_SCL_PIN, gpioModeWiredAndPullUp, 1); GPIO_PinModeSet(I2CDRV_SDA_PORT, I2CDRV_SDA_PIN, gpioModeWiredAndPullUp, 1); /* In some situations (after a reset during an I2C transfer), the slave */ /* device may be left in an unknown state. Send 9 clock pulses just in case. */ for (i = 0; i < 9; i++) { /* * TBD: Seems to be clocking at appr 80kHz-120kHz depending on compiler * optimization when running at 14MHz. A bit high for standard mode devices, * but DK only has fast mode devices. Need however to add some time * measurement in order to not be dependable on frequency and code executed. */ GPIO_PinOutSet(I2CDRV_SCL_PORT, I2CDRV_SCL_PIN); GPIO_PinOutClear(I2CDRV_SCL_PORT, I2CDRV_SCL_PIN); } /* Enable pins at config location (3 is default which is the location used on the DK) */ I2C0->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | (I2CDRV_PORT_LOCATION << _I2C_ROUTE_LOCATION_SHIFT); I2C_Init(I2C0, init); }
//================================================================================ // PORTIO_enter_DefaultMode_from_RESET //================================================================================ extern void PORTIO_enter_DefaultMode_from_RESET(void) { // $[Port A Configuration] /* Pin PA0 is configured to Push-pull */ GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 0); /* Pin PA1 is configured to Push-pull */ GPIO_PinModeSet(gpioPortA, 1, gpioModePushPull, 0); // [Port A Configuration]$ // $[Port B Configuration] // [Port B Configuration]$ // $[Port C Configuration] // [Port C Configuration]$ // $[Port D Configuration] /* Pin PD13 is configured to Push-pull */ GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0); /* Pin PD14 is configured to Push-pull */ GPIO_PinModeSet(gpioPortD, 14, gpioModePushPull, 0); /* Pin PD15 is configured to Push-pull */ GPIO_PinModeSet(gpioPortD, 15, gpioModePushPull, 0); // [Port D Configuration]$ // $[Port E Configuration] // [Port E Configuration]$ // $[Port F Configuration] // [Port F Configuration]$ }
/**************************************************************************//** * @brief Configure Board Controller bus decode logic. * * @param[in] mode Mode of operation, use enum @ref BSP_BusControl_TypeDef mode. * On Gxxx_DK's this functions is a dummy. * * @return @ref BSP_STATUS_OK or @ref BSP_STATUS_ILLEGAL_PARAM. * @ref BSP_STATUS_NOT_IMPLEMENTED on Gxxx_DK's. *****************************************************************************/ int BSP_BusControlModeSet(BSP_BusControl_TypeDef mode) { int retVal = BSP_STATUS_OK; /* Configure GPIO pins for Board Bus mode */ /* Note: Inverter on GPIO lines to BC, so signals are active low */ CMU_ClockEnable(cmuClock_GPIO, true); busMode = mode; switch (mode) { case BSP_BusControl_OFF: /* Configure board for OFF mode on PB15 MCU_EBI_CONNECT */ GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1); /* Configure board for OFF mode on PD13 MCU_SPI_CONNECT */ GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 1); break; case BSP_BusControl_DIRECT: /* Configure board for DIRECT on PB15 MCU_EBI_CONNECT */ GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 0); /* Configure board for DIRECT on PD13 MCU_SPI_CONNECT */ GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0); break; case BSP_BusControl_SPI: /* Configure board for SPI mode on PB15 MCU_EBI_CONNECT */ GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1); /* Configure board for SPI mode on PD13 MCU_SPI_CONNECT */ GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0); break; case BSP_BusControl_EBI: /* Configure board for EBI mode on PB15 MCU_EBI_CONNECT */ GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 0); /* Configure board for EBI mode on PD13 MCU_SPI_CONNECT */ GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 1); break; default: retVal = BSP_STATUS_ILLEGAL_PARAM; break; } return retVal; }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); setupSWO(); BSP_LedsInit(); /* Enable clock for GPIO module */ CMU_ClockEnable(cmuClock_GPIO, true); /* Configure interrupt for Push Button 0 */ GPIO_PinModeSet(PB0_PORT, PB0_PIN, gpioModeInput, 1); #if defined(_EFM32_GIANT_FAMILY) NVIC_EnableIRQ(GPIO_ODD_IRQn); #else NVIC_EnableIRQ(GPIO_EVEN_IRQn); #endif GPIO_IntConfig(PB0_PORT, PB0_PIN, false, true, true); /* By turning on retention in EM4, the state of the GPIO pins * can be retained in all energy modes */ GPIO->CTRL = GPIO_CTRL_EM4RET; /* Uncomment to drive LED in all energy modes */ /* BSP_LedSet(0);*/ while (1) { switch (STATE) { case EM0: break; case EM1: EMU_EnterEM1(); break; case EM2: EMU_EnterEM2(true); break; case EM3: EMU_EnterEM3(true); case EM4: EMU_EnterEM4(); break; } } }
/**************************************************************************//** * @brief Main function * Main is called from __iar_program_start, see assembly startup file *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); /* Enable clock for GPIO module */ CMU_ClockEnable(cmuClock_GPIO, true); /* Enable clock for ADC0 module */ CMU_ClockEnable(cmuClock_ADC0, true); /* Enable clock for PRS module */ CMU_ClockEnable(cmuClock_PRS, true); /* Configure PD8 as an input for PB0 button with filter enable (out = 1)*/ GPIO_PinModeSet(gpioPortD, 8, gpioModeInput, 1); /* Select PD8 as PRS output */ GPIO->EXTIPSELH = (GPIO->EXTIPSELH & !_GPIO_EXTIPSELH_EXTIPSEL8_MASK ) | GPIO_EXTIPSELH_EXTIPSEL8_PORTD; /* Enable PRS sense */ GPIO->INSENSE = GPIO->INSENSE | GPIO_INSENSE_PRS; /* Select GPIO as source and GPIOPIN8 as signal (falling edge) */ PRS_SourceSignalSet(0, PRS_CH_CTRL_SOURCESEL_GPIOH, PRS_CH_CTRL_SIGSEL_GPIOPIN8, prsEdgeNeg); /* Initialize ADC common parts for both single conversion and scan sequence */ ADC_Init(ADC0, &ADCInit); /* Initialize ADC single sample conversion */ ADC_InitSingle(ADC0, &ADCInitSingle); /* Enable ADC Interrupt when Single Conversion Complete */ ADC0->IEN = ADC_IEN_SINGLE; /* Enable ADC interrupt vector in NVIC*/ NVIC_EnableIRQ(ADC0_IRQn); while(1) { /* Enter EM1 */ EMU_EnterEM1(); /* After ADC Single conversion wake up -> Delay 1000mS */ Delay(1000); } }
/***************************************************************************//** * @brief * Initialize the LEDs related GPIO * * @details * * @note * * @return * Error code ******************************************************************************/ rt_err_t rt_hw_led_init(void) { #if defined(EFM32_G8XX_STK) rt_uint8_t i; /* Configure GPIO */ for (i = 0; i < LEDS_MAX_NUMBER; i++) { GPIO_PinModeSet( leds_list[i][0], leds_list[i][1], gpioModePushPull, 0); } #endif return RT_EOK; }
/***************************************************************************//** * @brief * User setup function. ******************************************************************************/ void TD_USER_Setup(void) { // Define the LED pin as an output in push-pull mode GPIO_PinModeSet(LED_PORT, LED_BIT, gpioModePushPull, 1); // Forever while (true) { // Toggle the LED pin on/off GPIO_PinOutToggle(LED_PORT, LED_BIT); // Delay 500 ms TD_RTC_Delay(T500MS); } // Never reached }
void enc_init(void) { static const TIMER_Init_TypeDef txTimerInit = { false, /* Don't enable timer when init complete. */ false, /* Stop counter during debug halt. */ HIJACK_TIMER_RESOLUTION,/* ... */ timerClkSelHFPerClk, /* Select HFPER clock. */ false, /* Not 2x count mode. */ false, /* No ATI. */ timerInputActionNone, /* No action on falling input edge. */ timerInputActionNone, /* No action on rising input edge. */ timerModeUp, /* Up-counting. */ false, /* Do not clear DMA requests when DMA channel is active. */ false, /* Select X2 quadrature decode mode (if used). */ false, /* Disable one shot. */ false /* Not started/stopped/reloaded by other timers. */ }; /* Ensure core frequency has been updated */ SystemCoreClockUpdate(); /* Enable peripheral clocks. */ CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(HIJACK_TX_TIMERCLK, true); /* Configure Rx timer. */ TIMER_Init(HIJACK_TX_TIMER, &txTimerInit); /* Configure Tx timer output compare channel 0. */ HIJACK_CompareConfig(hijackOutputModeToggle); TIMER_CompareSet(HIJACK_TX_TIMER, 0, HIJACK_NUM_TICKS_PER_HALF_CYCLE); /* Route the capture channels to the correct pins, enable CC feature. */ HIJACK_TX_TIMER->ROUTE = HIJACK_TX_LOCATION | TIMER_ROUTE_CC0PEN; /* Tx: Configure the corresponding GPIO pin as an input. */ GPIO_PinModeSet(HIJACK_TX_GPIO_PORT, HIJACK_TX_GPIO_PIN, gpioModePushPull, 0); /* Enable Tx timer CC0 interrupt. */ NVIC_EnableIRQ(TIMER1_IRQn); TIMER_IntEnable(HIJACK_TX_TIMER, TIMER_IF_CC0); /* Enable the timer. */ TIMER_Enable(HIJACK_TX_TIMER, true); }
/**************************************************************************//** * @brief Toggle a GPIO pin automatically at the given frequency. * * @param[in] gpioPort GPIO port number of GPIO ping to toggle. * @param[in] gpioPin GPIO pin number. * * @return EMSTATUS code of the operation. *****************************************************************************/ EMSTATUS PAL_GpioPinAutoToggle (unsigned int gpioPort, unsigned int gpioPin, unsigned int frequency) { EMSTATUS status = EMSTATUS_OK; /* Store GPIO pin data. */ gpioPortNo = gpioPort; gpioPinNo = gpioPin; /* Setup GPIO pin. */ GPIO_PinModeSet((GPIO_Port_TypeDef)gpioPort, gpioPin, gpioModePushPull, 0 ); /* Setup RTC to generate interrupts at given frequency. */ rtcSetup(frequency); return status; }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Chip errata */ CHIP_Init(); CMU_ClockEnable(cmuClock_GPIO, true); GPIO_PinModeSet(BUTTON_PORT, BUTTON_PIN, gpioModeInput, 0); // The initial state of the button is high when not pushed bool past_button_state = 1; // Start out not blinking bool blinking = false; while (1) { // Grab the state of the button, 1 for high voltage, 0 for low bool live_button_state = GPIO_PinInGet(BUTTON_PORT, BUTTON_PIN); // Invert the blinking mode every time a button is pressed // which generates a low voltage on a pin if (past_button_state == 1 && live_button_state == 0) { past_button_state = 0; // Invert the blinking mode, so that it is buffered and will // keep blinking/not blinking when the button is released blinking = !blinking; } // Reset the past state when the button is released if (live_button_state == 1) { past_button_state = 1; } // Finally decide if there is going to be a blink cycle or not if (blinking) { blink_one_cycle(); } } }
/****************************************************************************** * @brief GPIO data structure initialization *****************************************************************************/ void initGPIO(void) { capsenseCurrent = 0; capsensePrevious = 0; /* Enable GPIO in CMU */ CMU_ClockEnable(cmuClock_GPIO, true); /* Configure cap-sense input */ GPIO_PinModeSet(CS0_0_PORT, CS0_0_PIN, gpioModeInput, 0); // CS00 GPIO_PinModeSet(CS0_1_PORT, CS0_1_PIN, gpioModeInput, 0); // CS01 GPIO_PinModeSet(CS0_2_PORT, CS0_2_PIN, gpioModeInput, 0); // CS02 GPIO_PinModeSet(CS0_3_PORT, CS0_3_PIN, gpioModeInput, 0); // CS03 GPIO_PinModeSet(CS0_4_PORT, CS0_4_PIN, gpioModeInput, 0); // CS04 GPIO_PinModeSet(CS0_5_PORT, CS0_5_PIN, gpioModeInput, 0); // CS05 GPIO_PinModeSet(CS0_6_PORT, CS0_6_PIN, gpioModeInput, 0); // CS06 }
/*============================================================================== hal_spiInit() =============================================================================*/ void* hal_spiInit(void) { /* configure SPI */ SPIDRV_Init_t spiInit = EFM32_USART; spiInit.portLocation = EFM32_USART_LOC; spiInit.csControl = spidrvCsControlApplication; /* initialize SPI */ s_hal_spi.pHndl = &s_hal_spi.hndl; SPIDRV_Init( s_hal_spi.pHndl, &spiInit ); /* configure manual chip select pin */ GPIO_PinModeSet( s_hal_spi.csPin.port, s_hal_spi.csPin.pin, s_hal_spi.csPin.mode, s_hal_spi.csPin.val ); /* set chip select pin */ GPIO_PinOutSet( s_hal_spi.csPin.port, s_hal_spi.csPin.pin ); return &s_hal_spi; } /* hal_spiInit() */
/** * \brief decode initial. */ void dec_init(void) { static const TIMER_Init_TypeDef rxTimerInit = { false, /* Don't enable timer when init complete. */ false, /* Stop counter during debug halt. */ HIJACK_TIMER_RESOLUTION,/* ... */ timerClkSelHFPerClk, /* Select HFPER clock. */ false, /* Not 2x count mode. */ false, /* No ATI. */ timerInputActionNone, /* No action on falling input edge. */ timerInputActionNone, /* No action on rising input edge. */ timerModeUp, /* Up-counting. */ false, /* Do not clear DMA requests when DMA channel is active. */ false, /* Select X2 quadrature decode mode (if used). */ false, /* Disable one shot. */ false /* Not started/stopped/reloaded by other timers. */ }; /* Ensure core frequency has been updated */ SystemCoreClockUpdate(); /* Enable RX_TIMER clock . */ CMU_ClockEnable(HIJACK_RX_TIMERCLK, true); /* Configure Rx timer. */ TIMER_Init(HIJACK_RX_TIMER, &rxTimerInit); /* Configure Rx timer input capture channel 0. */ HIJACK_CaptureConfig(hijackEdgeModeBoth); /* Route the capture channels to the correct pins, enable CC1. */ HIJACK_RX_TIMER->ROUTE = TIMER_ROUTE_LOCATION_LOC3 | TIMER_ROUTE_CC1PEN; /* Rx: Configure the corresponding GPIO pin (PortD, Ch2) as an input. */ GPIO_PinModeSet(HIJACK_RX_GPIO_PORT, HIJACK_RX_GPIO_PIN, gpioModeInput, 0); /* Enable Rx timer CC1 interrupt. */ NVIC_EnableIRQ(TIMER0_IRQn); TIMER_IntEnable(HIJACK_RX_TIMER, TIMER_IF_CC1); /* Enable the timer. */ TIMER_Enable(HIJACK_RX_TIMER, true); }
/**************************************************************************//** * @brief Enable GPIO pins for the USART/LEUART used for board communication. * * @param[in] enable Set to true to enable pins, set to false to disable. *****************************************************************************/ void BSP_BccPinsEnable( bool enable ) { if (enable) { /* Configure GPIO pin for UART TX */ /* To avoid false start, configure output as high. */ GPIO_PinModeSet( BSP_BCC_TXPORT, BSP_BCC_TXPIN, gpioModePushPull, 1 ); /* Configure GPIO pin for UART RX */ GPIO_PinModeSet( BSP_BCC_RXPORT, BSP_BCC_RXPIN, gpioModeInput, 1 ); /* Enable the switch that enables UART communication. */ GPIO_PinModeSet( BSP_BCC_ENABLE_PORT, BSP_BCC_ENABLE_PIN, gpioModePushPull, 1 ); #if defined( BSP_BCC_LEUART ) BSP_BCC_LEUART->ROUTE |= LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | BSP_BCC_LOCATION; #else #if defined( USART_ROUTEPEN_TXPEN ) BSP_BCC_USART->ROUTEPEN = USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN; BSP_BCC_USART->ROUTELOC0 = ( BSP_BCC_USART->ROUTELOC0 & ~( _USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK ) ) | ( BSP_BCC_TX_LOCATION << _USART_ROUTELOC0_TXLOC_SHIFT ) | ( BSP_BCC_RX_LOCATION << _USART_ROUTELOC0_RXLOC_SHIFT ); #else BSP_BCC_USART->ROUTE |= USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | BSP_BCC_LOCATION; #endif #endif } else { GPIO_PinModeSet( BSP_BCC_ENABLE_PORT, BSP_BCC_ENABLE_PIN, gpioModeDisabled, 0 ); #if defined( BSP_BCC_LEUART ) BSP_BCC_LEUART->ROUTE &= ~(LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN); #else #if defined( USART_ROUTEPEN_TXPEN ) BSP_BCC_USART->ROUTEPEN &= ~(USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN); #else BSP_BCC_USART->ROUTE &= ~(USART_ROUTE_RXPEN | USART_ROUTE_TXPEN); #endif #endif GPIO_PinModeSet( BSP_BCC_TXPORT, BSP_BCC_TXPIN, gpioModeDisabled, 0 ); GPIO_PinModeSet( BSP_BCC_RXPORT, BSP_BCC_RXPIN, gpioModeDisabled, 0 ); } }
__LINK_C error_t hw_gpio_configure_pin(pin_id_t pin_id, bool int_allowed, uint8_t mode, unsigned int out) { //do early-stop error checking if((gpio_pins_configured[pin_id.port] & (1<<pin_id.pin))) return EALREADY; else if(int_allowed && (interrupts[pin_id.pin].interrupt_port != 0xFF)) return EBUSY; //set the pin to be configured gpio_pins_configured[pin_id.port] |= (1<<pin_id.pin); //configure the pin itself GPIO_PinModeSet(pin_id.port, pin_id.pin, mode, out); //if interrupts are allowed: set the port to use if(int_allowed) interrupts[pin_id.pin].interrupt_port = pin_id.port; return SUCCESS; }
/****************************************************************************** * @brief usartSetup function * ******************************************************************************/ void usartSetup(void) { cmuSetup(); /* Configure GPIO pin as open drain */ GPIO_PinModeSet(SC_GPIO_DATA_PORT, SC_GPIO_DATA_PIN, gpioModeWiredAndPullUp, 1); /* Prepare struct for initializing USART in asynchronous mode*/ usartInit.enable = usartDisable; /* Don't enable USART upon intialization */ usartInit.refFreq = 0; /* Provide information on reference frequency. When set to 0, the reference frequency is */ usartInit.baudrate = SC_BAUD_RATE; /* Baud rate */ usartInit.oversampling = usartOVS16; /* Oversampling. Range is 4x, 6x, 8x or 16x */ usartInit.databits = usartDatabits8; /* Number of data bits. Range is 4 to 10 */ usartInit.parity = usartEvenParity; /* Parity mode */ usartInit.stopbits = usartStopbits1p5; /* Number of stop bits. Range is 0 to 2, 1.5 for smartcard. */ usartInit.mvdis = false; /* Disable majority voting */ usartInit.prsRxEnable = false; /* Enable USART Rx via Peripheral Reflex System */ usartInit.prsRxCh = usartPrsRxCh0; /* Select PRS channel if enabled */ /* Initialize USART with usartInit struct */ USART_InitAsync(usart, &usartInit); /* Smart card specific settings for T0 mode. */ usart->CTRL |= USART_CTRL_SCMODE | USART_CTRL_AUTOTRI | USART_CTRL_LOOPBK; /* Prepare USART Rx interrupt */ USART_IntClear(usart, _USART_IF_MASK); USART_IntEnable(usart, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(USART1_RX_IRQn); NVIC_EnableIRQ(USART1_RX_IRQn); /* Enable I/O pins at USART1 location #2 */ usart->ROUTE = USART_ROUTE_TXPEN | SC_USART_LOCATION; /* Disable reception before enabling uart to discard erroneus stuff while card is unpowered. */ usartFlushBuffer(); usartAcceptRX(false); /* Enable USART */ USART_Enable(usart, usartEnable); }
/***************************************************************************//** * @brief * User setup function. ******************************************************************************/ void TD_USER_Setup(void) { // Initialize the LED GPIO GPIO_PinModeSet(TIM2_PORT, TIM2_BIT, gpioModePushPull, 0); // Initialize the timer to generate IRQs LedTimer = TD_SCHEDULER_AppendIrq(0, 8192 , 0, TD_SCHEDULER_INFINITE, LedBlink, 0); // If the timer correctly initialized if (LedTimer != 0xFF) { // Wait for a while, the LED should keep blinking as it is on interrupt TD_RTC_Delay(T10S); // Remove timer TD_SCHEDULER_Remove(LedTimer); // Switch off the LED GPIO_PinOutClear(TIM2_PORT, TIM2_BIT); } }
void SX1276InitIo( void ) { // Configure NSS as output GPIO_PinModeSet( NSS_IOPORT, NSS_PIN, gpioModePushPull, 1 ); // Configure radio DIO as inputs GPIO_PinModeSet( DIO0_IOPORT, DIO0_PIN, gpioModeInput, 0 ); GPIO_PinModeSet( DIO1_IOPORT, DIO1_PIN, gpioModeInput, 0 ); GPIO_PinModeSet( DIO2_IOPORT, DIO2_PIN, gpioModeInput, 0 ); #ifdef DIO3_IOPORT GPIO_PinModeSet( DIO3_IOPORT, DIO3_PIN, gpioModeInput, 0 ); #endif #ifdef DIO4_IOPORT GPIO_PinModeSet( DIO4_IOPORT, DIO4_PIN, gpioModeInput, 0 ); #endif }
/**************************************************************************//** * @brief Initialize MSD device. * * @param[in] activityLedPort * Specify a GPIO port for a LED activity indicator (i.e. enum gpioPortX) * Pass -1 if no indicator LED is available. * * @param[in] activityLedPin * Pin number on activityLedPort for the LED activity indicator. *****************************************************************************/ void MSDD_Init(int activityLedPort, uint32_t activityLedPin) { if ((sizeof(MSDSCSI_Read10_TypeDef) != SCSI_READ10_LEN) || (sizeof(MSDSCSI_Write10_TypeDef) != SCSI_WRITE10_LEN) || (sizeof(MSDSCSI_RequestSense_TypeDef) != SCSI_REQUESTSENSE_LEN) || (sizeof(InquiryData) != SCSI_INQUIRYDATA_LEN) || (sizeof(NoSenseData) != SCSI_REQUESTSENSEDATA_LEN) || (sizeof(IllegalSenseData) != SCSI_REQUESTSENSEDATA_LEN) || (sizeof(MSDSCSI_ReadCapacity_TypeDef) != SCSI_READCAPACITY_LEN) || (sizeof(MSDSCSI_ReadCapacityData_TypeDef) != SCSI_READCAPACITYDATA_LEN)) { DEBUG_USB_API_PUTS("\nMSDD_Init(), typedef size error"); EFM_ASSERT(false); return; } if ( ( activityLedPort >= gpioPortA ) && ( activityLedPort <= gpioPortF ) ) ledPort = activityLedPort; else ledPort = -1; ledPin = activityLedPin; msdState = MSDD_IDLE; pSenseData = (MSDSCSI_RequestSenseData_TypeDef*) &NoSenseData; USBD_Init(&initstruct); /* Start USB. */ if ( ledPort != -1 ) { CMU_ClockEnable(cmuClock_GPIO, true); GPIO_PinModeSet((GPIO_Port_TypeDef)ledPort, ledPin, gpioModePushPull, 0); } /* * When using a debugger it is pratical to uncomment the following three * lines to force host to re-enumerate the device. */ /* USBD_Disconnect(); */ /* USBTIMER_DelayMs( 1000 ); */ /* USBD_Connect(); */ }
/***************************************************************************//** * @brief * Set the mode for a GPIO pin. * * @param[in] port * The GPIO port to access. * * @param[in] pin * The pin number in the port. * * @param[in] mode * The desired pin mode. * * @param[in] platformSpecific * Platform specific value which may need to be set. * For EFM32: * Value to set for pin in DOUT register. The DOUT setting is important for * even some input mode configurations, determining pull-up/down direction. ******************************************************************************/ EMSTATUS PAL_GpioPinModeSet(unsigned int port, unsigned int pin, PAL_GpioMode_t mode, unsigned int platformSpecific) { EMSTATUS status = PAL_EMSTATUS_OK; GPIO_Mode_TypeDef emGpioMode; /* Convert PAL pin mode to GPIO_Mode_TypeDef defined in em_gpio.h. */ switch (mode) { case palGpioModePushPull: emGpioMode = gpioModePushPull; break; default: return PAL_EMSTATUS_INVALID_PARAM; } GPIO_PinModeSet((GPIO_Port_TypeDef) port, pin, emGpioMode, platformSpecific); return status; }
/************************************************************************************//** ** \brief Initializes the microcontroller. ** \return none. ** ****************************************************************************************/ static void Init(void) { /* initialize the system and its clocks */ SystemInit(); /* handle chip errate workarounds */ CHIP_Init(); /* enable the low frequency crystal oscillator */ CMU_OscillatorEnable(cmuOsc_LFXO, true, true); /* turn on clocking of all the modules */ CMU->HFCORECLKEN0 |= 0x0F; CMU->HFPERCLKEN0 |= 0xFFFF; /* disable clocking of the modules that are not in use */ CMU_ClockEnable(cmuClock_AES, false); CMU_ClockEnable(cmuClock_DMA, false); CMU_ClockEnable(cmuClock_EBI, false); CMU_ClockEnable(cmuClock_PRS, false); CMU_ClockEnable(cmuClock_USART0, false); CMU_ClockEnable(cmuClock_USART1, false); CMU_ClockEnable(cmuClock_USART2, false); CMU_ClockEnable(cmuClock_UART0, false); CMU_ClockEnable(cmuClock_ACMP0, false); CMU_ClockEnable(cmuClock_ACMP1, false); CMU_ClockEnable(cmuClock_DAC0, false); CMU_ClockEnable(cmuClock_ADC0, false); CMU_ClockEnable(cmuClock_I2C0, false); CMU_ClockEnable(cmuClock_VCMP, false); #if (BOOT_COM_UART_ENABLE > 0) /* enable power to U2 (RS232_PWR_E) */ GPIO_PinModeSet(gpioPortB, 9, gpioModePushPullDrive, 1); /* set port B outputs to drive up to 20 mA */ GPIO_DriveModeSet(gpioPortB, gpioDriveModeHigh); #endif /* init the led driver */ LedInit(); /* init the timer driver */ TimerInit(); /* enable IRQ's, because they were initially disabled by the bootloader */ IrqInterruptEnable(); } /*** end of Init ***/
/** @brief Initialize External Device GPIOs * @param deviceIntCB The callback routine for device general interrupt * (NULL to disable) * @param deviceRdyCB The callback routine for device ready interrupt * (NULL to disable) * @return bitmask of configured features for this device * @note First initialization after bootup leaves the device powered down * and unselected. Subsequent inits don't touch the device powered * or selected states and can be used to reconfigure callback(s), * which always clears any stale/pending events. For deviceRdyCB, * its interrupt is enabled upon configuration; for deviceIntCB, * halExtDeviceIntEnable() must subsequently be called to enable it. */ HalExtDeviceConfig halExtDeviceInit(HalExtDeviceIrqCB deviceIntCB, HalExtDeviceIrqCB deviceRdyCB) { UNUSED_VAR(halExtDeviceRdyCB); // Work around potential compiler warnings UNUSED_VAR(halExtDeviceIntCB); // Work around potential compiler warnings halExtDeviceRdyCB = deviceRdyCB; halExtDeviceIntCB = deviceIntCB; CMU_ClockEnable(cmuClock_PRS, true); /* Pin is configured to Push-pull: SDN */ GPIO_PinModeSet((GPIO_Port_TypeDef) RF_SDN_PORT, RF_SDN_PIN, gpioModePushPull, 1u); /* Pin is configured to Push-pull: nSEL */ GPIO_PinModeSet((GPIO_Port_TypeDef) RF_USARTRF_CS_PORT, RF_USARTRF_CS_PIN, gpioModePushPull, 1u); /* Pin PE13 is configured input: nIRQ */ //GPIO_PinModeSet(RF_INT_PORT, RF_INT_PIN, gpioModeInput, 0u); /* Pin PA15 and PE14 are connected to GPIO0 and GPIO1 respectively. */ GPIO_PinModeSet((GPIO_Port_TypeDef) RF_GPIO0_PORT, RF_GPIO0_PIN, gpioModeInput, 0); GPIO_PinModeSet((GPIO_Port_TypeDef) RF_GPIO1_PORT, RF_GPIO1_PIN, gpioModeInput, 0); /* Pin PA0 and PA1 are output the GPIO0 and GPIO1 via PRS */ GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 0); GPIO_PinModeSet(gpioPortA, 1, gpioModePushPull, 0); /* Configure INT/PRS channels */ GPIO_IntConfig((GPIO_Port_TypeDef) RF_GPIO0_PORT, RF_GPIO0_PIN, false, false, false); GPIO_IntConfig((GPIO_Port_TypeDef) RF_GPIO1_PORT, RF_GPIO1_PIN, false, false, false); /* Setup PRS */ PRS_SourceAsyncSignalSet(0, PRS_CH_CTRL_SOURCESEL_GPIOH, PRS_CH_CTRL_SIGSEL_GPIOPIN15); PRS_SourceAsyncSignalSet(1, PRS_CH_CTRL_SOURCESEL_GPIOH, PRS_CH_CTRL_SIGSEL_GPIOPIN14); PRS->ROUTE = (PRS_ROUTE_CH0PEN | PRS_ROUTE_CH1PEN); /* Make sure PRS sensing is enabled (should be by default) */ GPIO_InputSenseSet(GPIO_INSENSE_PRS, GPIO_INSENSE_PRS); /* TODO: Check whether the removed part is required for the EZR32 implementation */ halExtDeviceRdyCfgIrq(); halExtDeviceIntCfgIrq(); return 0; }
/**************************************************************************//** * @brief Check if touch screen is "touched" * @return true if screen touched *****************************************************************************/ static bool touched( void ) { uint32_t adcValue; GPIO_PinModeSet(LCD_TOUCH_X1, gpioModePushPull, 0); GPIO_PinModeSet(LCD_TOUCH_X2, gpioModePushPull, 1); GPIO_PinModeSet(LCD_TOUCH_Y1, gpioModeInput, 0); GPIO_PinModeSet(LCD_TOUCH_Y2, gpioModePushPull, 1); delayUs( 10 ); GPIO_PinModeSet(LCD_TOUCH_Y2, gpioModeInputPull, 1); delayUs( 10 ); sInit.input = ADC_Y; ADC_InitSingle(ADC0, &sInit); adcValue = readAdc(); GPIO_PinModeSet(LCD_TOUCH_X1, gpioModeInput, 0); GPIO_PinModeSet(LCD_TOUCH_X2, gpioModeInput, 0); GPIO_PinModeSet(LCD_TOUCH_Y2, gpioModeInput, 0); return ( adcValue < 3800 ) ? true : false; }
void qk_gpio_set_mode(qk_gpio_pin pin, qk_gpio_mode mode) { unsigned int out = 0; GPIO_Mode_TypeDef efm32_mode; switch(mode) { case QK_GPIO_MODE_ANALOG: efm32_mode = gpioModeDisabled; break; case QK_GPIO_MODE_OUTPUT: efm32_mode = gpioModePushPull; break; case QK_GPIO_MODE_INPUT: efm32_mode = gpioModeInput; out = 1; break; // with filter case QK_GPIO_MODE_OUTPUT_OPEN_DRAIN: efm32_mode = gpioModeWiredAnd; break; case QK_GPIO_MODE_INPUT_PULL_UP: efm32_mode = gpioModeInputPull; out = 1; break; case QK_GPIO_MODE_INPUT_PULL_DOWN: efm32_mode = gpioModeInputPull; break; default: return; } GPIO_PinModeSet((GPIO_Port_TypeDef) _QK_GPIO_PORT(pin), (unsigned int) _QK_GPIO_BIT(pin), efm32_mode, out); // GPIO_IntConfig(_QK_GPIO_PORT(pin), _QK_GPIO_PIN(pin), false, false, false); }
void Spi_Init(void) { USART_Reset(USART1); CMU_ClockEnable(cmuClock_USART1, true); USART_InitSync_TypeDef spiinit = USART_INITSYNC_DEFAULT; spiinit.baudrate = 1000000; spiinit.msbf=1; USART_InitSync(USART1, &spiinit); GPIO_PinModeSet(SPI_MOSI_PORT, SPI_MOSI_PIN, gpioModePushPull, 1); GPIO_PinModeSet(SPI_MISO_PORT, SPI_MISO_PIN, gpioModeInput, 0); GPIO_PinModeSet(SPI_CLK_PORT, SPI_CLK_PIN, gpioModePushPull, 1); GPIO_PinModeSet(SPI_CS_PORT, SPI_CS_PIN, gpioModePushPull, 1); GPIO_PinModeSet(RF_SDN_PORT, RF_SDN_PIN, gpioModePushPull, 0); GPIO_PinModeSet(RF_nIRQ_PORT, RF_nIRQ_PIN, gpioModeInput, 0); USART1->ROUTE |= USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC1; }
/***************************************************************************//** * @brief * Initalize I2C peripheral * * @details * This driver supports master mode only, single bus-master. In addition * to configuring the I2C peripheral module, it also configures DK/STK * specific setup in order to use the I2C bus. * * @param[in] init * Pointer to I2C initialization structure ******************************************************************************/ void I2CSPM_Init(I2CSPM_Init_TypeDef *init) { int i; CMU_Clock_TypeDef i2cClock; I2C_Init_TypeDef i2cInit; EFM_ASSERT(init != NULL); CMU_ClockEnable(cmuClock_HFPER, true); /* Select I2C peripheral clock */ if (false) { #if defined( I2C0 ) } else if (init->port == I2C0) { i2cClock = cmuClock_I2C0; #endif #if defined( I2C1 ) } else if (init->port == I2C1) { i2cClock = cmuClock_I2C1; #endif } else { /* I2C clock is not defined */ EFM_ASSERT(false); return; } CMU_ClockEnable(i2cClock, true); /* Output value must be set to 1 to not drive lines low. Set SCL first, to ensure it is high before changing SDA. */ GPIO_PinModeSet(init->sclPort, init->sclPin, gpioModeWiredAndPullUp, 1); GPIO_PinModeSet(init->sdaPort, init->sdaPin, gpioModeWiredAndPullUp, 1); /* In some situations, after a reset during an I2C transfer, the slave device may be left in an unknown state. Send 9 clock pulses to set slave in a defined state. */ for (i = 0; i < 9; i++) { GPIO_PinOutSet(init->sclPort, init->sclPin); GPIO_PinOutClear(init->sclPort, init->sclPin); } /* Enable pins and set location */ #if defined (_I2C_ROUTEPEN_MASK) init->port->ROUTEPEN = I2C_ROUTEPEN_SDAPEN | I2C_ROUTEPEN_SCLPEN; init->port->ROUTELOC0 = (init->portLocationSda << _I2C_ROUTELOC0_SDALOC_SHIFT) | (init->portLocationScl << _I2C_ROUTELOC0_SCLLOC_SHIFT); #else init->port->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | (init->portLocation << _I2C_ROUTE_LOCATION_SHIFT); #endif /* Set emlib init parameters */ i2cInit.enable = true; i2cInit.master = true; /* master mode only */ i2cInit.freq = init->i2cMaxFreq; i2cInit.refFreq = init->i2cRefFreq; i2cInit.clhr = init->i2cClhr; I2C_Init(init->port, &i2cInit); }
/**************************************************************************//** * @brief ACMP_setup * Configures and starts the ACMP *****************************************************************************/ void ACMP_setup(void) { /* Enable necessary clocks */ CMU_ClockEnable(cmuClock_ACMP0, true); CMU_ClockEnable(cmuClock_GPIO, true); /* Configure PC4 as input with pull down for ACMP channel 4 input */ GPIO_PinModeSet(gpioPortC, 4, gpioModeInputPullFilter, 0); /* Analog comparator parameters */ const ACMP_Init_TypeDef acmpInit = { .fullBias = false, /* no full bias current*/ .halfBias = false, /* no half bias current */ .biasProg = 7, /* Biasprog current 1.4 uA */ .interruptOnFallingEdge = false, /* disable interrupt for falling edge */ .interruptOnRisingEdge = false, /* disable interrupt for rising edge */ .warmTime = acmpWarmTime256, /* Warm-up time in clock cycles, should be >140 cycles for >10us warm-up @ 14MHz */ .hysteresisLevel = acmpHysteresisLevel0, /* Hysteresis level 0 - no hysteresis */ .inactiveValue = 0, /* Inactive comparator output value */ .lowPowerReferenceEnabled = false, /* Low power reference mode disabled */ .vddLevel = 32, /* Vdd reference scaling of 32 */ }; /* Init ACMP and set ACMP channel 4 as positive input and scaled Vdd as negative input */ ACMP_Init(ACMP0, &acmpInit); ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel4); ACMP_Enable(ACMP0); } /**************************************************************************//** * @brief PRS_ScanChannel * Waits for activity on a selected PRS channel and writes on the LCD when activity occurs * * @param[in] timer * Pointer to TIMER peripheral register block. * * @param[in] prsCh * PRS Channel to be monitored * * @param[in] edgeType * Signal edge to be monitored/captured *****************************************************************************/ void PRS_ScanChannel(TIMER_TypeDef *timer, TIMER_PRSSEL_TypeDef prsCh, TIMER_Edge_TypeDef edgeType) { /* enable the clock for the correct timer */ #define TIMER_Clock(T) (T==TIMER0 ? cmuClock_TIMER0 : \ T==TIMER1 ? cmuClock_TIMER1 : 0) /* Enable necessary clocks */ CMU_ClockEnable((CMU_Clock_TypeDef)TIMER_Clock(timer), true); /* Initialize LCD */ SegmentLCD_Init(false); /* Select CC channel parameters */ const TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventFalling, /* input capture event control */ .edge = edgeType, /* input capture on falling edge */ .prsSel = prsCh, /* prs channel select channel 5*/ .cufoa = timerOutputActionNone, /* no action on counter underflow */ .cofoa = timerOutputActionNone, /* no action on counter overflow */ .cmoa = timerOutputActionNone, /* no action on counter match */ .mode = timerCCModeCapture, /* CC channel mode capture */ .filter = false, /* no filter */ .prsInput = true, /* CC channel PRS input */ .coist = false, /* comparator output initial state */ .outInvert = false, /* no output invert */ }; /* Initialize TIMER0 CC0 */ TIMER_InitCC(timer, 0, &timerCCInit); /* Select timer parameters */ const TIMER_Init_TypeDef timerInit = { .enable = true, /* start counting when init complete */ .debugRun = false, /* counter not running on debug halt */ .prescale = timerPrescale1024, /* prescaler of 64 */ .clkSel = timerClkSelHFPerClk, /* TIMER0 clocked by the HFPERCLK */ .fallAction = timerInputActionNone, /* stop counter on falling edge */ .riseAction = timerInputActionNone, /* reload and start on rising edge */ .mode = timerModeUp, /* counting up */ .dmaClrAct = false, /* no DMA */ .quadModeX4 = false, /* no quad decoding */ .oneShot = false, /* counting up constinuously */ .sync = false, /* no start/stop/reload by other timers */ }; /* Initialize TIMER0 */ TIMER_Init(timer, &timerInit); /* Poll the Input Capture Valid flag in the Status register The program will hang at this point waiting for activity on this channel */ while(!((TIMER0->STATUS & _TIMER_STATUS_ICV0_MASK )>>16)); } /**************************************************************************//** * @brief Main function * Main is called from __iar_program_start, see assembly startup file *****************************************************************************/ int main(void) { /* Align different chip revisions*/ CHIP_Init(); /* Initialise the ACMP */ ACMP_setup(); /* PRS setup */ /* Enable clock for PRS and select ACMP as source and ACMP0OUT (ACMP0 OUTPUT) as signal for channel 5 */ CMU_ClockEnable(cmuClock_PRS, true); PRS_SourceSignalSet(5, PRS_CH_CTRL_SOURCESEL_ACMP0, PRS_CH_CTRL_SIGSEL_ACMP0OUT, prsEdgeOff); /* Start PRS scan This function will halt the program while there is no PRS activity This function assumes that the PRS has been setup previously */ PRS_ScanChannel(TIMER0, timerPRSSELCh5, timerEdgeFalling); /* Write PRS and channel number on the LCD to acknowledge PRS activity */ SegmentLCD_Write("PRS"); SegmentLCD_Number((int)timerPRSSELCh5); while(1) { /* Enter EM1 while waiting for capture. */ EMU_EnterEM1(); } }
int main(void) { CHIP_Init(); CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_TIMER1, true); CMU_ClockEnable(cmuClock_TIMER3, true); // Set up TIMER1 for timekeeping TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT; timerInit.prescale = timerPrescale1024; TIMER_IntEnable(TIMER1, TIMER_IF_OF); // Enable TIMER1 interrupt vector in NVIC NVIC_EnableIRQ(TIMER1_IRQn); // Set TIMER Top value TIMER_TopSet(TIMER1, ONE_SECOND_TIMER_COUNT); TIMER_Init(TIMER1, &timerInit); // Wait for the timer to get going while (TIMER1->CNT == 0) ; // Enable LED output GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0); // Create the object initializer for LED PWM TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT; timerCCInit.mode = timerCCModePWM; timerCCInit.cmoa = timerOutputActionToggle; // Configure TIMER3 CC channel 2 TIMER_InitCC(TIMER3, TIMER_CHANNEL, &timerCCInit); // Route CC2 to location 1 (PE3) and enable pin for cc2 TIMER3->ROUTE |= (TIMER_ROUTE_CC2PEN | TIMER_ROUTE_LOCATION_LOC1); // Set Top Value TIMER_TopSet(TIMER3, TIMER_TOP); // Set the PWM duty cycle here! TIMER_CompareBufSet(TIMER3, TIMER_CHANNEL, 0); // Create a timerInit object, based on the API default TIMER_Init_TypeDef timerInit2 = TIMER_INIT_DEFAULT; timerInit2.prescale = timerPrescale256; TIMER_Init(TIMER3, &timerInit2); enum mode_values { RAMPING_UP, HIGH, RAMPING_DOWN, LOW}; // Check for properly sized constants uint16_t delta = MAX_BRIGHTNESS - MIN_BRIGHTNESS; if ( delta == 0 || RAMP_UP_TIME_MS % delta || RAMP_DOWN_TIME_MS % delta) { DEBUG_BREAK } // Set the initial condition uint16_t mode = RAMPING_UP; uint32_t time_step = RAMP_UP_TIME_MS / delta; uint16_t brightness = MIN_BRIGHTNESS; TIMER_CompareBufSet(TIMER3, TIMER_CHANNEL, brightness); uint64_t mode_timeout = set_ms_timeout(RAMP_UP_TIME_MS); while (1) { switch (mode) { case RAMPING_UP: delay_ms(time_step); brightness++; TIMER_CompareBufSet(TIMER3, TIMER_CHANNEL, brightness); if (expired_ms(mode_timeout)) { mode = HIGH; mode_timeout = set_ms_timeout(HIGH_DURATION_MS); } break; case HIGH: if (expired_ms(mode_timeout)) { mode = RAMPING_DOWN; time_step = RAMP_DOWN_TIME_MS / delta; mode_timeout = set_ms_timeout(RAMP_DOWN_TIME_MS); } break; case RAMPING_DOWN: delay_ms(time_step); brightness--; TIMER_CompareBufSet(TIMER3, TIMER_CHANNEL, brightness); if (expired_ms(mode_timeout)) { mode = LOW; mode_timeout = set_ms_timeout(LOW_DURATION_MS); } break; case LOW: if (expired_ms(mode_timeout)) { mode = RAMPING_UP; time_step = RAMP_UP_TIME_MS / delta; mode_timeout = set_ms_timeout(RAMP_UP_TIME_MS); } break; } } }
/**************************************************************************//** * @brief TIMER0_setup * Configures the TIMER *****************************************************************************/ void TIMER_setup(void) { /* Enable necessary clocks */ CMU_ClockEnable(cmuClock_TIMER0, true); CMU_ClockEnable(cmuClock_PRS, true); /* Select CC channel parameters */ TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventEveryEdge, /* Input capture event control */ .edge = timerEdgeBoth, /* Input capture on falling edge */ .prsSel = timerPRSSELCh5, /* Prs channel select channel 5*/ .cufoa = timerOutputActionNone, /* No action on counter underflow */ .cofoa = timerOutputActionNone, /* No action on counter overflow */ .cmoa = timerOutputActionNone, /* No action on counter match */ .mode = timerCCModeCapture, /* CC channel mode capture */ .filter = false, /* No filter */ .prsInput = true, /* CC channel PRS input */ .coist = false, /* Comparator output initial state */ .outInvert = false, /* No output invert */ }; /* Initialize TIMER0 CC0 channel */ TIMER_InitCC(HIJACK_RX_TIMER, 0, &timerCCInit); /* Select timer parameters */ const TIMER_Init_TypeDef timerInit = { .enable = false, /* Do not start counting when init complete */ .debugRun = false, /* Counter not running on debug halt */ .prescale = HIJACK_TIMER_RESOLUTION, /* Prescaler of 1 */ .clkSel = timerClkSelHFPerClk, /* TIMER0 clocked by the HFPERCLK */ .fallAction = timerInputActionReloadStart, /* Stop counter on falling edge */ .riseAction = timerInputActionReloadStart, /* Reload and start on rising edge */ .mode = timerModeUp, /* Counting up */ .dmaClrAct = false, /* No DMA */ .quadModeX4 = false, /* No quad decoding */ .oneShot = false, /* Counting up constinuously */ .sync = false, /* No start/stop/reload by other timers */ }; /* Initialize TIMER0 */ TIMER_Init(HIJACK_RX_TIMER, &timerInit); /* PRS setup */ /* Select ACMP as source and ACMP0OUT (ACMP0 OUTPUT) as signal */ PRS_SourceSignalSet(5, PRS_CH_CTRL_SOURCESEL_ACMP0, PRS_CH_CTRL_SIGSEL_ACMP0OUT, prsEdgeOff); /* Enable CC0 interrupt */ TIMER_IntEnable(HIJACK_RX_TIMER, TIMER_IF_CC0); /* Enable TIMER0 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER0_IRQn); } /**************************************************************************//** * @brief ACMP_setup * Configures and starts the ACMP *****************************************************************************/ static void ACMP_setup(void) { /* Enable necessary clocks */ CMU_ClockEnable(HIJACK_RX_ACMPCLK, true); CMU_ClockEnable(cmuClock_GPIO, true); /* Configure ACMP input pin. */ GPIO_PinModeSet(HIJACK_RX_GPIO_PORT, HIJACK_RX_GPIO_PIN, gpioModeInput, 0); /* Analog comparator parameters */ const ACMP_Init_TypeDef acmpInit = { .fullBias = false, /* No full bias current*/ .halfBias = true, /* No half bias current */ .biasProg = 2, /* Biasprog current 1.4 uA */ .interruptOnFallingEdge = false, /* Disable interrupt for falling edge */ .interruptOnRisingEdge = false, /* Disable interrupt for rising edge */ .warmTime = acmpWarmTime256, /* Warm-up time in clock cycles, should be >140 cycles for >10us warm-up @ 14MHz */ .hysteresisLevel = acmpHysteresisLevel7, /* Hysteresis level 0 - no hysteresis */ .inactiveValue = 1, /* Inactive comparator output value */ .lowPowerReferenceEnabled = false, /* Low power reference mode disabled */ .vddLevel = HIJACK_RX_ACMP_LEVEL, /* Vdd reference scaling of 32 */ }; /* Use ACMP0 output, PD6 . */ //GPIO_PinModeSet(gpioPortD, 6, gpioModePushPull, 0); //ACMP_GPIOSetup(ACMP0, 2, true, false); /* Init ACMP and set ACMP channel 4 as positive input and scaled Vdd as negative input */ ACMP_Init(HIJACK_RX_ACMP, &acmpInit); ACMP_ChannelSet(HIJACK_RX_ACMP, HIJACK_RX_ACMP_NEG, HIJACK_RX_ACMP_CH); ACMP_Enable(HIJACK_RX_ACMP); } /** * @brief calculate whether cnt is in 500us region * ticker = 64Mhz/128 = 2us * 475us < cnt < 510us * */ static chk_result_t IsTime2Detect(uint32_t inv) { chk_result_t ret; if( inv < HIJACK_DEC_NUM_TICKS_MIN){ offset = inv; ret = pass; } else if ( ( inv <= HIJACK_DEC_NUM_TICKS_MAX ) && ( inv >= HIJACK_DEC_NUM_TICKS_MIN ) ) { offset = 0; inv = 0; ret = suit; } else{ offset = 0; inv = 0; ret = error; } return ret; } /* * Find phase remain or phase reversal. */ static void dec_parser(uint8_t bit_msk, state_t state) { if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine if( falling == cur_edge ){ dec.data &= ~(1 << bit_msk); #if DEC_DEBUG == 1 uartPutChar( '+' ) ; uartPutChar( '_' ) ; #endif//DEC_DEBUG == 1 } else{ dec.data |= (1 << bit_msk); #if DEC_DEBUG == 1 uartPutChar( '_' ) ; uartPutChar( '+' ) ; #endif//DEC_DEBUG == 1 dec.odd++; } dec.state = state; //state switch } else if ( error == IsTime2Detect(inv) ){ //wait for edge detection time dec.state = Waiting; //state switch } } /**************************************************************************//** * @brief decode state machine * Invoke in TIMER_ISR for decoding. *****************************************************************************/ void decode_machine(void) { inv = offset + cur_stamp; //update offset #if 0 if( dec.state > Waiting ){ USART_printHexBy16u(inv); if(cur_edge == rising){ uartPutChar( '\\' ) ; } else{ uartPutChar( '/' ) ; } } #endif switch (dec.state){ case Waiting: /* go to start bit if rising edge exist. */ if (rising == cur_edge) { dec.state = Sta0; offset = 0; inv = 0; } break; // case Sta0: if( ( suit == IsTime2Detect(inv) ) && ( falling == cur_edge ) ){ dec.data = 0; //clear data field for store new potential data dec.odd = 0; //clear odd field parity counter dec.state = Bit0; #if DEC_DEBUG == 1 uartPutChar( 'S' ) ; uartPutChar( '+' ) ; uartPutChar( '_' ) ; #endif } else{ dec.state = Waiting; } break; // case Bit0: #if DEC_DEBUG == 1 uartPutChar( '0' ) ; #endif dec_parser(BIT0, Bit1); break; // case Bit1: #if DEC_DEBUG == 1 uartPutChar( '1' ) ; #endif dec_parser(BIT1, Bit2); break; // case Bit2: #if DEC_DEBUG == 1 uartPutChar( '2' ) ; #endif dec_parser(BIT2, Bit3); break; // case Bit3: #if DEC_DEBUG == 1 uartPutChar( '3' ) ; #endif dec_parser(BIT3, Bit4); break; // case Bit4: #if DEC_DEBUG == 1 uartPutChar( '4' ) ; #endif dec_parser(BIT4, Bit5); break; // case Bit5: #if DEC_DEBUG == 1 uartPutChar( '5' ) ; #endif dec_parser(BIT5, Bit6); break; // case Bit6: #if DEC_DEBUG == 1 uartPutChar( '6' ) ; #endif dec_parser(BIT6, Bit7); break; // case Bit7: #if DEC_DEBUG == 1 uartPutChar( '7' ) ; #endif dec_parser(BIT7, Parity); break; // case Parity: if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine if( rising == cur_edge ){ dec.odd++; #if DEC_DEBUG == 1 uartPutChar( '_' ) ; uartPutChar( '+' ) ; #endif } else{ #if DEC_DEBUG == 1 uartPutChar( '+' ) ; uartPutChar( '_' ) ; #endif } #if DEC_DEBUG == 1 uartPutChar( dec.odd + 0x30) ; #endif if( 1 == (dec.odd%2)){ //parity pass dec.state = Sto0; } else{ //parity failed dec.state = Waiting; } } else if ( error == IsTime2Detect(inv) ){ //wait for edge detection time dec.state = Waiting; } break; // case Sto0: if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine if( rising == cur_edge ){ //stop bit is rising edge USART_txByte(dec.data); #if DEC_DEBUG == 1 uartPutChar( '_' ) ; uartPutChar( '+' ) ; #endif HIJACKPutData(&dec.data, &decBuf, sizeof(uint8_t)); } else{ #if DEC_DEBUG == 1 uartPutChar( '+' ) ; uartPutChar( '_' ) ; #endif } dec.state = Waiting; #if DEC_DEBUG == 1 uartPutChar( '\r' ) ; uartPutChar( '\n' ) ; #endif } else if ( error == IsTime2Detect(inv) ){ //wait for edge detection time dec.state = Waiting; } break; // default: break; // } }
void initPWM() // Brightness should be less than TIMER_TOP (1024) { /* Enable clocks */ CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO; CMU_ClockEnable(cmuClock_TIMER1, true); /* Set pins */ GPIO_PinModeSet(gpioPortE,10,gpioModePushPull,1); GPIO_PinModeSet(gpioPortE,11,gpioModePushPull,1); /* Select CC channel parameters */ TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventEveryEdge, .edge = timerEdgeBoth, .prsSel = timerPRSSELCh0, .cufoa = timerOutputActionNone, .cofoa = timerOutputActionNone, .cmoa = timerOutputActionToggle, .mode = timerCCModePWM, .filter = false, .prsInput = false, .coist = false, .outInvert = false, }; /* Configure CC channels */ TIMER_InitCC(TIMER1, 0, &timerCCInit); TIMER_InitCC(TIMER1, 1, &timerCCInit); /* Set which pins will be set by the timer */ TIMER1->ROUTE = TIMER_ROUTE_CC0PEN | TIMER_ROUTE_CC1PEN | TIMER_ROUTE_LOCATION_LOC1; /* Set Top Value */ TIMER_TopSet(TIMER1, TIMER_TOP); /* Set compare value starting at top - it will be incremented in the interrupt handler */ TIMER_CompareBufSet(TIMER1, 0, TIMER_TOP + 1); TIMER_CompareBufSet(TIMER1, 1, TIMER_TOP + 1); /* Select timer parameters */ TIMER_Init_TypeDef timerInit = { .enable = true, .debugRun = false, .prescale = timerPrescale16, .clkSel = timerClkSelHFPerClk, .fallAction = timerInputActionNone, .riseAction = timerInputActionNone, .mode = timerModeUp, .dmaClrAct = false, .quadModeX4 = false, .oneShot = false, .sync = false, }; /* Enable overflow interrupt */ TIMER_IntEnable(TIMER1, TIMER_IF_OF); TIMER_IntClear(TIMER1, TIMER_IF_OF); /* Enable TIMER1 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER1_IRQn); /* Configure timer */ TIMER_Init(TIMER1, &timerInit); }