Example program for Port access. Blink the LED using the registers.

Dependencies:   mbed

main.cpp

Committer:
Ladon
Date:
2019-07-22
Revision:
1:65c259961c26
Parent:
0:e637d54ba0a3
Child:
2:f72c56822d58

File content as of revision 1:65c259961c26:

#include <mbed.h>

// Board: NUCLEO-F303RE (STM32F303RE).
// -

// We shall write to PA5 where the LED is..
// Info: LEDs:
//      https://www.st.com/resource/en/user_manual/dm00105823.pdf (UM1724: STM32 Nucleo-64 boards (MB1136))
//
// Info: Talking to ports:
//      https://developer.arm.com/tools-and-software/embedded/legacy-tools/ds-5-development-studio/resources/tutorials/accessing-memory-mapped-peripherals
//      More info: Chapter 25.4.1 from "2014 Programming Principles and Practice Using C++"
///         (https://archive.org/details/2014ProgrammingPrinciplesAndPracticeUsingCPlusPlus/page/n636)
//
// Info: #defines : 
//      https://raw.githubusercontent.com/ARMmbed/mbed-os/master/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/stm32f303xe.h
//
// Reference manual:
//      https://www.st.com/resource/en/reference_manual/dm00043574.pdf
// -
// We 'll need the MODER (port mode) register (see ^reference manual) and the ODR (output data register).
// Register addresses are calculated taking the GPIOA base address (found in the reference manual) and adding the appropriate register's offset to it.
// -
// Note:
//      I was unsuccessfull in the following:
//
//      #define ODR ((volatile unsigned short*) (GPIOA + 0x14)
// -

#define MODER   ((volatile unsigned int*)   0x48000000)
// 32 bits.
// We 'll set pins 11,10 set to 0,1.
// -

#define ODR     ((volatile unsigned short*) 0x48000014)
// 16 bits.
// We 'll write at pin 5.
// -

// More FUN (dwarf fortress reference).
// -
#define OTYPER      ((volatile unsigned short*) (0x48000004))
#define PUPDR       ((volatile unsigned int*)   (0x4800000C))
#define BSRR        ((volatile unsigned int*)   (0x48000018))
#define LCKR        ((volatile unsigned int*)   (0x4800001C))
#define AFRL        ((volatile unsigned int*)   (0x48000020))

void set_bit_as_output ()
{
    // Set to output.
    // -
    unsigned int moder = *MODER;
    moder |= 0x00000400U;
    moder &= 0xFFFFF7FFU;
    // ^ Write 0,1 to bits 11,10.
    // -
    *MODER = moder;
}

void toggle_bit ()
{
///*
    static unsigned short state = 0;
    state ^= 0x20;
    *ODR = state;
//*/
/*
    static bool state = false;
    if (state)
    {
        *BSRR = 0x00200000U;
    }
    else
    {
        *BSRR = 0x00000020U;
    }    
    state = !state;
*/
}

int main ()
{
    set_bit_as_output();
    while (true)
    {
        toggle_bit();
/*
        printf("MODER  = 0x%X\n",  *MODER);
        printf("OTYPER = 0x%X\n",  *OTYPER);
        printf("PUPDR  = 0x%X\n",  *PUPDR);
        printf("ODR    = 0x%hX\n", *ODR);
        printf("LCKR   = 0x%X\n",  *LCKR);
        printf("AFRL   = 0x%X\n",  *AFRL);
        printf("\n");
*/
        wait(0.65);
        // ^ : https://os.mbed.com/docs/mbed-os/v5.13/apis/wait.html
        // -
    }
}