#include "stm32f1xx.h"
#include "stm32f1xx_hal.h"

uint32_t data[2] = {0x111111, 0x111111};
//uint32_t data[2] = {0xFF0000, 0x0000FF};
//uint32_t data[2] = { 0x0000FF, 0xFF0000};
//uint32_t data[2] = { 0x555555, 0x555555}; // alternating bits

volatile uint32_t bitcount = 0;
volatile uint32_t pixelcount = 0;

volatile uint32_t output = 0 ;

 void NextBit() {
	TIM2->CCR1 = output; // make it the first in the interrupt, then calculate the next bit
	uint32_t mask = 1 << bitcount++;
	if (pixelcount < 2) {
		// Set output
		//TIM2->CCR1 = (mask & data[pixelcount]) ? 6 : 2;
		output =  (mask & data[pixelcount]) ? 6 : 2;
	} else {
		// reset
		//TIM2->CCR1 = 0;
		output = 0 ;
	}


	if (bitcount == 24) {
		bitcount = 0;
		pixelcount++;

	}

	if (pixelcount == 3) {
		pixelcount = 0;
	}
}


void TIM2_IRQHandler (void) {

	if (TIM2->SR &0b10) {
		NextBit();
		TIM2->SR&=~0b10;
	}
	//TIM2->SR &=~0b0001111001011111;
	NVIC_ClearPendingIRQ(TIM2_IRQn);
}


void pins_init() {
  GPIO_InitTypeDef   GPIO_InitStruct;

  // Enable Timer 2 Clock
  __HAL_RCC_TIM2_CLK_ENABLE();

  // Enable GPIO Port A Clock
  __HAL_RCC_GPIOA_CLK_ENABLE();

  // Common configuration for all channels
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  // Apply pin configuration to PA0
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  // Apply pin configuration to PA1
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  // Apply pin configuration to PA2
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  // Apply pin configuration to PA3
  GPIO_InitStruct.Pin = GPIO_PIN_3;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}


void pwm_init() {

	pins_init();

	NVIC->ISER[0] |= 0x10000000;
	RCC->APB1ENR |= 1;

	TIM2->CR2 = 0;

	TIM2->DIER = 0x0010; // interrupt enable cc1 interrupt. when the signal changes, as we need to set the next value before the period ends
	//TIM2->DIER = 0x0001; // interrupt enable c

	RCC->APB1ENR |= 1;

	TIM2->ARR = 9 ; // Reload Value
	TIM2->PSC =  8 ; // Prescaler

	// When setting the prescaler to 80, the signal looks like what it supposed to be, but of course too slow

	TIM2->RCR = 0; // repetition

	TIM2->CCMR1 = ( TIM2->CCMR1  & ~(0b11110000) ) | (0b1101 << 3);  // Set Channel 1 to PWM mode 1 and enabling reload

	TIM2->CR1 |= 1 << 7; // auto reload enable

	TIM2->EGR |= 1; // Set UG bit

	TIM2->CR1 &= ~(0b1110000); // Edge aglined, upcounting
	TIM2->CR1 |= 0b100; // Event source, only over/underflow

	TIM2->CCER |= 0b1;  // output enable and polarity

	TIM2->CCR1 = 0; // output val

	TIM2->CR1 |= 0x0001; // enable

	NVIC_SetPriority(TIM2_IRQn,0);
	NVIC_ClearPendingIRQ(TIM2_IRQn);
	NVIC_EnableIRQ(TIM2_IRQn);
}
