Spyros Papanastasiou
/
Write_to_port_directly__LED
Example program for Port access. Blink the LED using the registers.
main.cpp@1:65c259961c26, 2019-07-22 (annotated)
- Committer:
- Ladon
- Date:
- Mon Jul 22 12:32:29 2019 +0000
- Revision:
- 1:65c259961c26
- Parent:
- 0:e637d54ba0a3
- Child:
- 2:f72c56822d58
Added a book reference.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Ladon | 0:e637d54ba0a3 | 1 | #include <mbed.h> |
Ladon | 0:e637d54ba0a3 | 2 | |
Ladon | 1:65c259961c26 | 3 | // Board: NUCLEO-F303RE (STM32F303RE). |
Ladon | 0:e637d54ba0a3 | 4 | // - |
Ladon | 0:e637d54ba0a3 | 5 | |
Ladon | 0:e637d54ba0a3 | 6 | // We shall write to PA5 where the LED is.. |
Ladon | 0:e637d54ba0a3 | 7 | // Info: LEDs: |
Ladon | 0:e637d54ba0a3 | 8 | // https://www.st.com/resource/en/user_manual/dm00105823.pdf (UM1724: STM32 Nucleo-64 boards (MB1136)) |
Ladon | 1:65c259961c26 | 9 | // |
Ladon | 0:e637d54ba0a3 | 10 | // Info: Talking to ports: |
Ladon | 0:e637d54ba0a3 | 11 | // https://developer.arm.com/tools-and-software/embedded/legacy-tools/ds-5-development-studio/resources/tutorials/accessing-memory-mapped-peripherals |
Ladon | 1:65c259961c26 | 12 | // More info: Chapter 25.4.1 from "2014 Programming Principles and Practice Using C++" |
Ladon | 1:65c259961c26 | 13 | /// (https://archive.org/details/2014ProgrammingPrinciplesAndPracticeUsingCPlusPlus/page/n636) |
Ladon | 1:65c259961c26 | 14 | // |
Ladon | 0:e637d54ba0a3 | 15 | // Info: #defines : |
Ladon | 0:e637d54ba0a3 | 16 | // https://raw.githubusercontent.com/ARMmbed/mbed-os/master/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/stm32f303xe.h |
Ladon | 1:65c259961c26 | 17 | // |
Ladon | 0:e637d54ba0a3 | 18 | // Reference manual: |
Ladon | 0:e637d54ba0a3 | 19 | // https://www.st.com/resource/en/reference_manual/dm00043574.pdf |
Ladon | 0:e637d54ba0a3 | 20 | // - |
Ladon | 0:e637d54ba0a3 | 21 | // We 'll need the MODER (port mode) register (see ^reference manual) and the ODR (output data register). |
Ladon | 0:e637d54ba0a3 | 22 | // Register addresses are calculated taking the GPIOA base address (found in the reference manual) and adding the appropriate register's offset to it. |
Ladon | 0:e637d54ba0a3 | 23 | // - |
Ladon | 0:e637d54ba0a3 | 24 | // Note: |
Ladon | 0:e637d54ba0a3 | 25 | // I was unsuccessfull in the following: |
Ladon | 0:e637d54ba0a3 | 26 | // |
Ladon | 0:e637d54ba0a3 | 27 | // #define ODR ((volatile unsigned short*) (GPIOA + 0x14) |
Ladon | 0:e637d54ba0a3 | 28 | // - |
Ladon | 0:e637d54ba0a3 | 29 | |
Ladon | 0:e637d54ba0a3 | 30 | #define MODER ((volatile unsigned int*) 0x48000000) |
Ladon | 0:e637d54ba0a3 | 31 | // 32 bits. |
Ladon | 0:e637d54ba0a3 | 32 | // We 'll set pins 11,10 set to 0,1. |
Ladon | 0:e637d54ba0a3 | 33 | // - |
Ladon | 0:e637d54ba0a3 | 34 | |
Ladon | 0:e637d54ba0a3 | 35 | #define ODR ((volatile unsigned short*) 0x48000014) |
Ladon | 0:e637d54ba0a3 | 36 | // 16 bits. |
Ladon | 0:e637d54ba0a3 | 37 | // We 'll write at pin 5. |
Ladon | 0:e637d54ba0a3 | 38 | // - |
Ladon | 0:e637d54ba0a3 | 39 | |
Ladon | 0:e637d54ba0a3 | 40 | // More FUN (dwarf fortress reference). |
Ladon | 0:e637d54ba0a3 | 41 | // - |
Ladon | 0:e637d54ba0a3 | 42 | #define OTYPER ((volatile unsigned short*) (0x48000004)) |
Ladon | 0:e637d54ba0a3 | 43 | #define PUPDR ((volatile unsigned int*) (0x4800000C)) |
Ladon | 0:e637d54ba0a3 | 44 | #define BSRR ((volatile unsigned int*) (0x48000018)) |
Ladon | 0:e637d54ba0a3 | 45 | #define LCKR ((volatile unsigned int*) (0x4800001C)) |
Ladon | 0:e637d54ba0a3 | 46 | #define AFRL ((volatile unsigned int*) (0x48000020)) |
Ladon | 0:e637d54ba0a3 | 47 | |
Ladon | 0:e637d54ba0a3 | 48 | void set_bit_as_output () |
Ladon | 0:e637d54ba0a3 | 49 | { |
Ladon | 0:e637d54ba0a3 | 50 | // Set to output. |
Ladon | 0:e637d54ba0a3 | 51 | // - |
Ladon | 0:e637d54ba0a3 | 52 | unsigned int moder = *MODER; |
Ladon | 0:e637d54ba0a3 | 53 | moder |= 0x00000400U; |
Ladon | 0:e637d54ba0a3 | 54 | moder &= 0xFFFFF7FFU; |
Ladon | 0:e637d54ba0a3 | 55 | // ^ Write 0,1 to bits 11,10. |
Ladon | 0:e637d54ba0a3 | 56 | // - |
Ladon | 0:e637d54ba0a3 | 57 | *MODER = moder; |
Ladon | 0:e637d54ba0a3 | 58 | } |
Ladon | 0:e637d54ba0a3 | 59 | |
Ladon | 0:e637d54ba0a3 | 60 | void toggle_bit () |
Ladon | 0:e637d54ba0a3 | 61 | { |
Ladon | 0:e637d54ba0a3 | 62 | ///* |
Ladon | 0:e637d54ba0a3 | 63 | static unsigned short state = 0; |
Ladon | 0:e637d54ba0a3 | 64 | state ^= 0x20; |
Ladon | 0:e637d54ba0a3 | 65 | *ODR = state; |
Ladon | 0:e637d54ba0a3 | 66 | //*/ |
Ladon | 0:e637d54ba0a3 | 67 | /* |
Ladon | 0:e637d54ba0a3 | 68 | static bool state = false; |
Ladon | 0:e637d54ba0a3 | 69 | if (state) |
Ladon | 0:e637d54ba0a3 | 70 | { |
Ladon | 0:e637d54ba0a3 | 71 | *BSRR = 0x00200000U; |
Ladon | 0:e637d54ba0a3 | 72 | } |
Ladon | 0:e637d54ba0a3 | 73 | else |
Ladon | 0:e637d54ba0a3 | 74 | { |
Ladon | 0:e637d54ba0a3 | 75 | *BSRR = 0x00000020U; |
Ladon | 0:e637d54ba0a3 | 76 | } |
Ladon | 0:e637d54ba0a3 | 77 | state = !state; |
Ladon | 0:e637d54ba0a3 | 78 | */ |
Ladon | 0:e637d54ba0a3 | 79 | } |
Ladon | 0:e637d54ba0a3 | 80 | |
Ladon | 0:e637d54ba0a3 | 81 | int main () |
Ladon | 0:e637d54ba0a3 | 82 | { |
Ladon | 0:e637d54ba0a3 | 83 | set_bit_as_output(); |
Ladon | 0:e637d54ba0a3 | 84 | while (true) |
Ladon | 0:e637d54ba0a3 | 85 | { |
Ladon | 0:e637d54ba0a3 | 86 | toggle_bit(); |
Ladon | 0:e637d54ba0a3 | 87 | /* |
Ladon | 0:e637d54ba0a3 | 88 | printf("MODER = 0x%X\n", *MODER); |
Ladon | 0:e637d54ba0a3 | 89 | printf("OTYPER = 0x%X\n", *OTYPER); |
Ladon | 0:e637d54ba0a3 | 90 | printf("PUPDR = 0x%X\n", *PUPDR); |
Ladon | 0:e637d54ba0a3 | 91 | printf("ODR = 0x%hX\n", *ODR); |
Ladon | 0:e637d54ba0a3 | 92 | printf("LCKR = 0x%X\n", *LCKR); |
Ladon | 0:e637d54ba0a3 | 93 | printf("AFRL = 0x%X\n", *AFRL); |
Ladon | 0:e637d54ba0a3 | 94 | printf("\n"); |
Ladon | 0:e637d54ba0a3 | 95 | */ |
Ladon | 0:e637d54ba0a3 | 96 | wait(0.65); |
Ladon | 0:e637d54ba0a3 | 97 | // ^ : https://os.mbed.com/docs/mbed-os/v5.13/apis/wait.html |
Ladon | 0:e637d54ba0a3 | 98 | // - |
Ladon | 0:e637d54ba0a3 | 99 | } |
Ladon | 0:e637d54ba0a3 | 100 | } |