// stm32 bluepill document
// model: STM32F103C8T6
// ref link: https://os.mbed.com/users/hudakz/code/STM32F103C8T6_Hello/
#include <stm32f1xx.h>

int main(void)
{
  RCC->APB2ENR|=1<<4;
  GPIOC->CRH&=0xf0ffffff;
  GPIOC->CRH|=0x03000000;  // PC14:0x03000000;  PC13: 0x00300000;
  GPIOC->CRH|=0x00300000;  // PC14:0x03000000;  PC13: 0x00300000;

  while(1){
    // GPIOC->BSRR=0x00004000;  //PC14:0x00004000;  PC13: 0x00002000
    // GPIOC->BSRR=0x00002000;  //PC14:0x00004000;  PC13: 0x00002000
    // delay1();
    // GPIOC->BRR=0x00004000;  //PC14:0x00004000;  PC13: 0x00002000
    // GPIOC->BRR=0x00002000;  //PC14:0x00004000;  PC13: 0x00002000
    // delay1();

    // GPIOC->BSRR=0x00004000;  //PC14:0x00004000;  PC13: 0x00002000
    // GPIOC->BSRR=0x00002000;  //PC14:0x00004000;  PC13: 0x00002000
    // delay2();
    // GPIOC->BRR=0x00004000;  //PC14:0x00004000;  PC13: 0x00002000
    // GPIOC->BRR=0x00002000;  //PC14:0x00004000;  PC13: 0x00002000
    // delay2();

    // GPIOC->BSRR=0x00004000;  //PC14:0x00004000;  PC13: 0x00002000
    // GPIOC->BSRR=0x00002000;  //PC14:0x00004000;  PC13: 0x00002000
    // delay3();
    // GPIOC->BRR=0x00004000;  //PC14:0x00004000;  PC13: 0x00002000
    // GPIOC->BRR=0x00002000;  //PC14:0x00004000;  PC13: 0x00002000
    // delay3();

    GPIOC->BSRR=0x00004000;  //PC14:0x00004000;  PC13: 0x00002000
    GPIOC->BSRR=0x00002000;  //PC14:0x00004000;  PC13: 0x00002000
    delay4();
    GPIOC->BRR=0x00004000;  //PC14:0x00004000;  PC13: 0x00002000
    GPIOC->BRR=0x00002000;  //PC14:0x00004000;  PC13: 0x00002000
    delay4();

  }
}

// compile failed due to missing the library header file
// int main(void)
// {
//   GPIO_InitTypeDef GPIO_InitStructure;
//   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
//   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;
//   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
//   GPIO_Init(GPIOC,&GPIO_InitStructure);

//   while(1)
//   {
//     GPIO_SetBits(GPIOC, GPIO_Pin_14);
//     delay1();
//     GPIO_ResetBits(GPIOC, GPIO_Pin_14);
//     delay1();
//   }
// }


// Ref: https://programfan.github.io/blog/2015/04/27/prevent-gcc-optimize-away-code/
// To prevent compiler optimization of the software delay function
// Approach1: volatile keyword before a variable 
void delay1() 
{
    volatile long k=400000;
    while(k>0) k--;
}

// To prevent compiler optimization of the software delay function
// Approach2: __attribute__((optimize("00"))) before the delay2 function
void __attribute__((optimize("O0"))) delay2() 
// __attribute__((optimize("O0"))) void delay2() 
{
    long k=600000;
    while(k>0) k--;
}

// To prevent compiler optimization of the software delay function
// Approach3: compiler specific pragma
#pragma GCC push_options
#pragma GCC optimize("O0")
void delay3() 
{
    long k=800000;
    while(k>0) k--;
}
#pragma GCC pop_options

// To prevent compiler optimization of the software delay function
// Approach4: __asm__("nop"); in the loop 
void delay4() 
{
    long k=400000;
    while(k>0) {
      k--;
      __asm__("nop");
    }
}