title: STM32F103C8/CoIDE/ST-LinkV2 Can't update registers
body: <p>I'm new to STM32, not to embedded development (experience with PIC, dsPIC, MSP430).</p>
  
  <h1>Environment</h1>
  
  <ul>
  <li>CooCox CoIDE</li>
  <li>arm-none-eabi-gcc</li>
  <li>ST-LINK V2 (have encountered same with Segger J-Link) over SWD</li>
  </ul>
  
  <h1>Problem Description</h1>
  
  <p>I am trying to write a basic library using direct register manipulations (STMCube HAL is cool, but I found I had to read the datasheet anyway, so register manipulation is preferred).  In essence, I'm just trying to blink an LED that is on the <code>Blue Pill</code> development board, which is pin <code>C13</code>.</p>
  
  <p>I can compile, flash, and debug, but when I debug, the LED is not flashing and the registers aren't changing.  The register values themselves don't actually matter that much, so you shouldn't need to go out and check the datasheet.  I just need to be able to manipulate them!</p>
  
  <p>Stepping through the debugger works just fine, and the <code>variables</code> watch window is also appropriately updated.</p>
  
  <h1>Things I've Tried</h1>
  
  <p>Although this isn't exhaustive (it has been several hours, so I may have forgotten to include a few), these are some of the things I have tried:</p>
  
  <ul>
  <li>Changing the <code>BOOTx</code> pin configurations</li>
  <li>Changing the debugger config (slow down, speed up, reset strategy).</li>
  <li>Changing the debugger to SEGGER J-Link</li>
  <li>Lock/Unlock GPIO pins</li>
  </ul>
  
  <p>All have had same result.  I suspect that I may be missing something in CMSIS or a necessary include file, I just can't seem to find it.</p>
  
  <p>Another point that I may be missing deals with oscillator setup.  As I understand it, there is a default configuration at startup that I don't have to worry about unless I want to change it.  Perhaps this is flawed?</p>
  
  <h2>Edit: Works with STM32CubeMX HAL</h2>
  
  <p>When I try a basic toggle using the STM32CUBEMX HAL, it works.  This makes me think that there is something fundamental that I am missing in the includes, project setup, oscillator setup... something?</p>
  
  <h1>Code</h1>
  
  <h2>main.c</h2>
  
  <pre><code>#include "gpio.h"
  
  #define LED_PIN 13
  
  
  int main(void)
  {
      uint32_t i;
  
      // initialize the peripherals
      GPIO_init();
      GPIOC_setupOutput(LED_PIN, PUSH_PULL, PIN_SPEED_50MHz);
  
      while(1)
      {
          GPIOC_setPin(LED_PIN);
          for(i=0; i&lt;4000000; i++);
          GPIOC_clearPin(LED_PIN);
          for(i=0; i&lt;4000000; i++);
      }
  }
  </code></pre>
  
  <h2>gpio.h</h2>
  
  <pre><code>#ifndef _GPIO_H
  #define _GPIO_H
  
  #include &lt;stdint.h&gt;
  #include &lt;stdbool.h&gt;
  
  typedef enum{
      ANALOG=0b00, FLOATING=0b01, PULL_UP_PULL_DOWN=0b10
  }InputPinMode;
  
  typedef enum{
      PUSH_PULL=0b00, OPEN_DRAIN=0b01, AF_PUSH_PULL=0b10, AF_OPEN_DRAIN=0b11
  }OutputPinMode;
  
  typedef enum{
      PIN_SPEED_2MHz=0b10, PIN_SPEED_10MHz=0b01, PIN_SPEED_50MHz=0b11
  }PinSpeed;
  
  void GPIO_init(void);
  void GPIOA_setupInput(uint8_t pinNumber, InputPinMode mode);
  void GPIOC_setupInput(uint8_t pinNumber, InputPinMode mode);
  void GPIOA_setupOutput(uint8_t pinNumber, OutputPinMode mode, PinSpeed speed);
  void GPIOC_setupOutput(uint8_t pinNumber, OutputPinMode mode, PinSpeed speed);
  
  bool GPIOA_readPin(uint8_t pinNumber);
  
  
  void GPIOA_setPin(uint8_t pinNumber);
  void GPIOC_setPin(uint8_t pinNumber);
  
  void GPIOA_clearPin(uint8_t pinNumber);
  void GPIOC_clearPin(uint8_t pinNumber);
  
  #endif
  </code></pre>
  
  <h2>gpio.c</h2>
  
  <pre><code>#include "stm32f1xx.h"
  #include "gpio.h"
  
  /**
   * @brief Initialize GPIO
   */
  void GPIO_init(void){
      RCC-&gt;APB2ENR |= RCC_APB2ENR_IOPAEN;
      RCC-&gt;APB2ENR |= RCC_APB2ENR_IOPBEN;
      RCC-&gt;APB2ENR |= RCC_APB2ENR_IOPCEN;
      RCC-&gt;APB2ENR |= RCC_APB2ENR_IOPDEN;
      RCC-&gt;APB2ENR |= RCC_APB2ENR_IOPEEN;
  }
  
  /**
   * @brief Setup pin as an input
   * @param pinNumber the pin number
   * @param mode the input mode
   */
  void GPIOA_setupInput(uint8_t pinNumber, InputPinMode mode){
      uint32_t pinNumberLocation, regValue;
  
      if(pinNumber &lt; 8){
          pinNumberLocation = pinNumber &lt;&lt; 2; // bit location
          regValue = (mode &lt;&lt; 2) &lt;&lt; pinNumberLocation;
  
          GPIOA-&gt;CRL &amp;= ~(0b1111 &lt;&lt; pinNumberLocation);   // clear the register
          GPIOA-&gt;CRL = regValue;
      }else{
          pinNumberLocation = (pinNumber - 8) &lt;&lt; 2;   // bit location
          regValue = (mode &lt;&lt; 2) &lt;&lt; pinNumberLocation;
  
          GPIOA-&gt;CRH &amp;= ~(0b1111 &lt;&lt; pinNumberLocation);   // clear the register
          GPIOA-&gt;CRH = regValue;
      }
  }
  
  /**
   * @brief Setup port A pin as an output
   * @brief pinNumber the pin number
   * @brief mode the output mode
   * @brief speed the pin speed (lower results in less noise)
   */
  void GPIOA_setupOutput(uint8_t pinNumber, OutputPinMode mode, PinSpeed speed){
      uint32_t pinNumberLocation, regValue;
  
      if(pinNumber &lt; 8){
          pinNumberLocation = pinNumber &lt;&lt; 2; // bit location
          regValue = ((mode &lt;&lt; 2) &lt;&lt; pinNumberLocation) + speed;
  
          GPIOA-&gt;CRL &amp;= ~(0b1111 &lt;&lt; pinNumberLocation);   // clear the register
          GPIOA-&gt;CRL |= regValue;
      }else{
          pinNumberLocation = (pinNumber - 8) &lt;&lt; 2;   // bit location
          regValue = ((mode &lt;&lt; 2) &lt;&lt; pinNumberLocation) + speed;
  
          GPIOA-&gt;CRH &amp;= ~(0b1111 &lt;&lt; pinNumberLocation);   // clear the register
          GPIOA-&gt;CRH |= regValue;
      }
  }
  
  /**
   * @brief Setup port C pin as an output
   * @brief pinNumber the pin number
   * @brief mode the output mode
   * @brief speed the pin speed (lower results in less noise)
   */
  void GPIOC_setupOutput(uint8_t pinNumber, OutputPinMode mode, PinSpeed speed){
      uint32_t pinNumberLocation, regValue;
  
      if(pinNumber &lt; 8){
          pinNumberLocation = pinNumber &lt;&lt; 2; // bit location
          regValue = ((mode &lt;&lt; 2) &lt;&lt; pinNumberLocation) + speed;
  
          GPIOC-&gt;CRL &amp;= ~(0b1111 &lt;&lt; pinNumberLocation);   // clear the register
          GPIOC-&gt;CRL |= regValue;
      }else{
          pinNumberLocation = (pinNumber - 8) &lt;&lt; 2;   // bit location
          regValue = ((mode &lt;&lt; 2) &lt;&lt; pinNumberLocation) + speed;
  
          GPIOC-&gt;CRH &amp;= ~(0b1111 &lt;&lt; pinNumberLocation);   // clear the register
          GPIOC-&gt;CRH |= regValue;
      }
  }
  
  bool GPIOA_readPin(uint8_t pinNumber){
      uint16_t mask = 1 &lt;&lt; pinNumber;
  
      if(GPIOA-&gt;IDR &amp; mask)
          return true;
      else
          return false;
  }
  
  void GPIOA_setPin(uint8_t pinNumber){ GPIOA-&gt;BSRR = (1 &lt;&lt; pinNumber);}
  void GPIOC_setPin(uint8_t pinNumber){ GPIOC-&gt;BSRR = (1 &lt;&lt; pinNumber);}
  
  void GPIOA_clearPin(uint8_t pinNumber){ GPIOA-&gt;BSRR = ~(1 &lt;&lt; (pinNumber + 16));}
  void GPIOC_clearPin(uint8_t pinNumber){ GPIOC-&gt;BSRR = ~(1 &lt;&lt; (pinNumber + 16));}
  </code></pre>