#include "stm32f10x.h"
//#include <stdio.h>

/*
 * Standalone STM32F1 led blink sample.
 *
 * This program demonstrates how to blink a led with 1Hz, using a
 * continuous loop and SysTick delays.
 *
 * The external clock frequency is specified as a preprocessor definition
 * passed to the compiler via a command line option (see the 'C/C++ General' ->
 * 'Paths and Symbols' -> the 'Symbols' tab, if you want to change it).
 * The value selected during project creation was HSE_VALUE=8000000.
 *
 * Note: The default clock settings take the user defined HSE_VALUE and try
 * to reach the maximum possible system clock. For the default 8MHz input
 * the result is guaranteed, but for other values it might not be possible,
 * so please adjust the PLL settings in libs/CMSIS/src/system_stm32f10x.c
 *
 * The build does not use startup files, and it does not even use
 * any standard library function.
 *
 * If the application requires special initialisation code present
 * in some other libraries (for example librdimon.a, for semihosting),
 * define USE_STARTUP_FILES and uncheck the corresponding option in the
 * linker configuration.
 *
 */

// ----------------------------------------------------------------------------
static void
Delay(__IO uint32_t nTime);

static void
TimingDelay_Decrement(void);

void
SysTick_Handler(void);

/* ----- SysTick definitions ----------------------------------------------- */

#define SYSTICK_FREQUENCY_HZ       1000

/* ----- LED definitions --------------------------------------------------- */

/* Olimex STM32-H103 LED definitions */
/* Adjust them for your own board. */

#define BLINK_PORT      GPIOC
#define BLINK_PIN       12
#define BLINK_RCC_BIT   RCC_APB2Periph_GPIOC

#define BLINK_TICKS     SYSTICK_FREQUENCY_HZ/2

// +++
#define DEBUG_LED_PIN_D10                        GPIO_Pin_4
#define DEBUG_LED_PIN_D11                        GPIO_Pin_5
#define DEBUG_LED_PIN_D12                        GPIO_Pin_6
#define BLINK_PORT      GPIOA // REDEF
#define LEFT_STEP  1
typedef enum {
	RIGHT = 1, LEFT = -1
} WAVE_DIRECTION;
// ----------------------------------------------------------------------------
void move_wave(int* wdix, WAVE_DIRECTION* wstep, int num_steps);
int main() {

	/*
	 * At this stage the microcontroller clock setting is already configured,
	 * this is done through SystemInit() function which is called from startup
	 * file (startup_cm.c) before to branch to application main.
	 * To reconfigure the default setting of SystemInit() function, refer to
	 * system_stm32f10x.c file
	 */

	/* Use SysTick as reference for the timer */
	SysTick_Config(SystemCoreClock / SYSTICK_FREQUENCY_HZ);

	/* GPIO Periph clock enable */
	RCC_APB2PeriphClockCmd(BLINK_RCC_BIT, ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure;

	/* Configure pin in output push/pull mode */
	// GPIO_InitStructure.GPIO_Pin = (1 << BLINK_PIN);
	GPIO_InitStructure.GPIO_Pin = DEBUG_LED_PIN_D10 | DEBUG_LED_PIN_D11
			| DEBUG_LED_PIN_D12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(BLINK_PORT, &GPIO_InitStructure);

	uint16_t wave_codes[] = {
	DEBUG_LED_PIN_D12,
	DEBUG_LED_PIN_D11,
	DEBUG_LED_PIN_D10,
	};
	const int NUM_WSTEPS = sizeof(wave_codes) / sizeof(wave_codes[0]);

	int seconds = 0;
	int widx = 0;
	WAVE_DIRECTION wstep = RIGHT;

	/* Infinite loop */
	while (1) {
		/* Assume the LED is active low */

		/* Turn on led by setting the pin low */
		GPIO_ResetBits(BLINK_PORT, wave_codes[widx]);
		widx += 1;
		widx %= NUM_WSTEPS;
		//move_wave(&widx, &wstep, NUM_WSTEPS);
		Delay(BLINK_TICKS);

		/* Turn off led by setting the pin high */
		GPIO_SetBits(BLINK_PORT, wave_codes[widx]);
		//move_wave(&widx, &wstep, NUM_WSTEPS);
		Delay(BLINK_TICKS);
		widx += 1;
		widx %= NUM_WSTEPS;
		++seconds;
	}
}

void move_wave(int* widx, WAVE_DIRECTION* wstep, int num_steps) {
	*widx += *wstep;
	if (*widx >= num_steps) {
		*widx = 0;
		*wstep = RIGHT;
	}
	if (*widx < 0) {
		*widx = 0;
		*wstep = RIGHT;
	}
}
// ----------------------------------------------------------------------------

static __IO uint32_t uwTimingDelay;

/**
 * @brief  Inserts a delay time.
 * @param  nTime: specifies the delay time length, in SysTick ticks.
 * @retval None
 */
void Delay(__IO uint32_t nTime) {
	uwTimingDelay = nTime;

	while (uwTimingDelay != 0)
		;
}

/**
 * @brief  Decrements the TimingDelay variable.
 * @param  None
 * @retval None
 */
void TimingDelay_Decrement(void) {
	if (uwTimingDelay != 0x00) {
		uwTimingDelay--;
	}
}

// ----------------------------------------------------------------------------

/**
 * @brief  This function is the SysTick Handler.
 * @param  None
 * @retval None
 */
void SysTick_Handler(void) {
	TimingDelay_Decrement();
}

// ----------------------------------------------------------------------------

