/*
* Copyright (C) 2015 Infineon Technologies AG. All rights reserved.
*
* Infineon Technologies AG (Infineon) is supplying this software for use with
* Infineon's microcontrollers.
* This file can be freely distributed within development tools that are
* supporting such microcontrollers.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*/
/**
* @file
* @date 12 Oct, 2015
* @version 1.0.0
*
* @brief XMC4700/4800 Relax Kit Blinky GPIO demo example based on XMC Lib
*
* This blinky example flashes the led LED1 (P5.9) of the board with a initial periodic rate of 1.0s.
* Using buttons flash rate can be adjusted in steps of 100ms. Use Button1 (P15.13) to increase flash rate.
* Use Button2 (P15.12) to decrease flash rate.
*
* History
*
* Version 1.0.0 Initial
*
*/
#include
#include "xmc_ccu4.h"
#include "xmc_gpio.h"
#include "xmc_scu.h"
// fCPU=144MHz; Prescaler set to 4096
#define CALCULATE_PERIOD(interval_in_ms) ((35155 * interval_in_ms) / 1000)
// Globale Variable für Timer-Interrupt
volatile bool timerInterruptOccurred = false;
// Globale Variable für die Timer-Periode
uint32_t timer_interval = 1000;
// Deklaration des Interrupt-Handlers für CCU43-Slice 1
extern "C" void CCU43_1_IRQHandler(void);
extern "C" void UserIRQHandler(void);
int main(void) {
bool button_edge = true;
// INITIALIZE CCU43 FOR TOGGLING OF LED
XMC_CCU4_Init(CCU43, XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR);
// Enable the clock for selected timer
XMC_CCU4_EnableClock(CCU43, 3);
// Prepare configuration
XMC_CCU4_SLICE_COMPARE_CONFIG_t slice_config = {
// .timer_mode =
(uint32_t) XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
// .monoshot =
(uint32_t) false,
// shadow_xfer_clear =
(uint32_t) 0,
// .dither_timer_period =
(uint32_t) 0,
// .dither_duty_cycle =
(uint32_t) 0,
// .prescaler_mode =
(uint32_t) XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
// .mcm_enable =
(uint32_t) 0,
// .prescaler_initval =
12, // In this case 2^12
// .float_limit =
0,
// .dither_limit =
0,
//.passive_level =
(uint32_t) XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
// .timer_concatenation =
0
};
// Configure the timer
XMC_CCU4_SLICE_CompareInit(CCU43_CC43, &slice_config);
// programs the timer period register according to time interval value
XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU43_CC43,
CALCULATE_PERIOD(timer_interval));
// Transfers value from shadow timer registers to actual timer registers
XMC_CCU4_EnableShadowTransfer(CCU43, XMC_CCU4_SHADOW_TRANSFER_SLICE_3 | XMC_CCU4_SHADOW_TRANSFER_PRESCALER_SLICE_3);
// Bind period match event to an NVIC node CCU43_1_IRQn
XMC_CCU4_SLICE_SetInterruptNode(CCU43_CC43, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH, XMC_CCU4_SLICE_SR_ID_1);
// Enables timer(period match) event
XMC_CCU4_SLICE_EnableEvent(CCU43_CC43, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
XMC_CCU4_SLICE_ClearTimer(CCU43_CC43);
XMC_CCU4_SLICE_StartTimer(CCU43_CC43);
// NVIC-Konfiguration: Priorität setzen und Interrupt aktivieren
NVIC_SetPriority(CCU43_1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 63, 0));
NVIC_EnableIRQ(CCU43_1_IRQn);
// INITIALIZE LED1 ON PORT 5.9 FOR OUTPUT (PUSH-PULL)
XMC_GPIO_SetMode(P5_9, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
// INITIALIZE BUTTON1 ON PORT 15.13 FOR INPUT
XMC_GPIO_SetMode(P15_13, XMC_GPIO_MODE_INPUT_TRISTATE);
XMC_GPIO_EnableDigitalInput(P15_13);
// INITIALIZE BUTTON2 ON PORT 15.12 FOR INPUT
XMC_GPIO_SetMode(P15_12, XMC_GPIO_MODE_INPUT_TRISTATE);
XMC_GPIO_EnableDigitalInput(P15_12);
while(1U) {
// any button pushed?
if (!XMC_GPIO_GetInput(P15_13) || !XMC_GPIO_GetInput(P15_12)) {
// new edge on any button?
if (button_edge == true) {
// which button ?
if (!XMC_GPIO_GetInput(P15_13)) {
// Button1 pushed. Decrease cycle time of flashing LED.
timer_interval = (timer_interval > 100) ? (timer_interval - 100) : timer_interval;
} else {
// Button2 pushed. Increase cycle time of flashing LED.
timer_interval = (timer_interval < 1500) ? (timer_interval + 100) : timer_interval;
}
XMC_CCU4_SLICE_StopTimer(CCU43_CC43);
XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU43_CC43, CALCULATE_PERIOD(timer_interval));
XMC_CCU4_EnableShadowTransfer(CCU43, XMC_CCU4_SHADOW_TRANSFER_SLICE_3 | XMC_CCU4_SHADOW_TRANSFER_PRESCALER_SLICE_3);
XMC_CCU4_SLICE_StartTimer(CCU43_CC43);
}
button_edge = false;
} else {
// currently no button pushed
// next trigger on button is new edge
button_edge = true;
}
}
}
// Interrupt-Service-Routine für CCU43-Slice 1
void CCU43_1_IRQHandler(void) {
// Prüfen, ob der Perioden-Match-Interrupt ausgelöst wurde
if (XMC_CCU4_SLICE_GetEvent(CCU43_CC43, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH)) {
// Interrupt-Flag löschen
XMC_CCU4_SLICE_ClearEvent(CCU43_CC43, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
// LED-Zustand umschalten
XMC_GPIO_ToggleOutput(P5_9);
}
}
void UserIRQHandler(void) {
XMC_GPIO_ToggleOutput(P5_9);
}