Spyros Papanastasiou
/
Write_to_port_directly__LED
Example program for Port access. Blink the LED using the registers.
main.cpp@2:f72c56822d58, 2019-07-22 (annotated)
- Committer:
- Ladon
- Date:
- Mon Jul 22 13:44:32 2019 +0000
- Revision:
- 2:f72c56822d58
- Parent:
- 1:65c259961c26
Replaced #defines with reinterpret_cast.
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 | 2:f72c56822d58 | 30 | // #define MODER ((volatile unsigned int*) 0x48000000U) |
Ladon | 2:f72c56822d58 | 31 | volatile unsigned int* moder = reinterpret_cast<volatile unsigned int*>( 0x48000000U); |
Ladon | 0:e637d54ba0a3 | 32 | // 32 bits. |
Ladon | 0:e637d54ba0a3 | 33 | // We 'll set pins 11,10 set to 0,1. |
Ladon | 0:e637d54ba0a3 | 34 | // - |
Ladon | 0:e637d54ba0a3 | 35 | |
Ladon | 2:f72c56822d58 | 36 | // #define ODR ((volatile unsigned short*) 0x48000014U) |
Ladon | 2:f72c56822d58 | 37 | volatile unsigned short* odr = reinterpret_cast<volatile unsigned short*>(0x48000014U); |
Ladon | 0:e637d54ba0a3 | 38 | // 16 bits. |
Ladon | 0:e637d54ba0a3 | 39 | // We 'll write at pin 5. |
Ladon | 0:e637d54ba0a3 | 40 | // - |
Ladon | 0:e637d54ba0a3 | 41 | |
Ladon | 0:e637d54ba0a3 | 42 | // More FUN (dwarf fortress reference). |
Ladon | 0:e637d54ba0a3 | 43 | // - |
Ladon | 2:f72c56822d58 | 44 | // #define OTYPER ((volatile unsigned short*) (0x48000004U)) |
Ladon | 2:f72c56822d58 | 45 | // #define PUPDR ((volatile unsigned int*) (0x4800000CU)) |
Ladon | 2:f72c56822d58 | 46 | // #define BSRR ((volatile unsigned int*) (0x48000018U)) |
Ladon | 2:f72c56822d58 | 47 | // #define LCKR ((volatile unsigned int*) (0x4800001CU)) |
Ladon | 2:f72c56822d58 | 48 | // #define AFRL ((volatile unsigned int*) (0x48000020U)) |
Ladon | 2:f72c56822d58 | 49 | volatile unsigned short* otyper = reinterpret_cast<volatile unsigned short*>(0x48000004U); |
Ladon | 2:f72c56822d58 | 50 | volatile unsigned int* pupdr = reinterpret_cast<volatile unsigned int*>( 0x4800000CU); |
Ladon | 2:f72c56822d58 | 51 | volatile unsigned int* bsrr = reinterpret_cast<volatile unsigned int*>( 0x48000018U); |
Ladon | 2:f72c56822d58 | 52 | volatile unsigned int* lckr = reinterpret_cast<volatile unsigned int*>( 0x4800001CU); |
Ladon | 2:f72c56822d58 | 53 | volatile unsigned int* afrl = reinterpret_cast<volatile unsigned int*>( 0x48000020U); |
Ladon | 0:e637d54ba0a3 | 54 | |
Ladon | 0:e637d54ba0a3 | 55 | void set_bit_as_output () |
Ladon | 0:e637d54ba0a3 | 56 | { |
Ladon | 0:e637d54ba0a3 | 57 | // Set to output. |
Ladon | 0:e637d54ba0a3 | 58 | // - |
Ladon | 2:f72c56822d58 | 59 | unsigned int tmp = *moder; |
Ladon | 2:f72c56822d58 | 60 | tmp |= 0x00000400U; |
Ladon | 2:f72c56822d58 | 61 | tmp &= 0xFFFFF7FFU; |
Ladon | 0:e637d54ba0a3 | 62 | // ^ Write 0,1 to bits 11,10. |
Ladon | 0:e637d54ba0a3 | 63 | // - |
Ladon | 2:f72c56822d58 | 64 | *moder = tmp; |
Ladon | 0:e637d54ba0a3 | 65 | } |
Ladon | 0:e637d54ba0a3 | 66 | |
Ladon | 0:e637d54ba0a3 | 67 | void toggle_bit () |
Ladon | 0:e637d54ba0a3 | 68 | { |
Ladon | 0:e637d54ba0a3 | 69 | ///* |
Ladon | 2:f72c56822d58 | 70 | *odr ^= 0x20; |
Ladon | 0:e637d54ba0a3 | 71 | //*/ |
Ladon | 0:e637d54ba0a3 | 72 | /* |
Ladon | 0:e637d54ba0a3 | 73 | static bool state = false; |
Ladon | 0:e637d54ba0a3 | 74 | if (state) |
Ladon | 0:e637d54ba0a3 | 75 | { |
Ladon | 2:f72c56822d58 | 76 | *bsrr = 0x00200000U; |
Ladon | 0:e637d54ba0a3 | 77 | } |
Ladon | 0:e637d54ba0a3 | 78 | else |
Ladon | 0:e637d54ba0a3 | 79 | { |
Ladon | 2:f72c56822d58 | 80 | *bsrr = 0x00000020U; |
Ladon | 0:e637d54ba0a3 | 81 | } |
Ladon | 0:e637d54ba0a3 | 82 | state = !state; |
Ladon | 0:e637d54ba0a3 | 83 | */ |
Ladon | 0:e637d54ba0a3 | 84 | } |
Ladon | 0:e637d54ba0a3 | 85 | |
Ladon | 0:e637d54ba0a3 | 86 | int main () |
Ladon | 0:e637d54ba0a3 | 87 | { |
Ladon | 0:e637d54ba0a3 | 88 | set_bit_as_output(); |
Ladon | 0:e637d54ba0a3 | 89 | while (true) |
Ladon | 0:e637d54ba0a3 | 90 | { |
Ladon | 0:e637d54ba0a3 | 91 | toggle_bit(); |
Ladon | 0:e637d54ba0a3 | 92 | /* |
Ladon | 2:f72c56822d58 | 93 | printf("MODER = 0x%X\n", *moder); |
Ladon | 2:f72c56822d58 | 94 | printf("OTYPER = 0x%X\n", *otyper); |
Ladon | 2:f72c56822d58 | 95 | printf("PUPDR = 0x%X\n", *pupdr); |
Ladon | 2:f72c56822d58 | 96 | printf("ODR = 0x%hX\n", *odr); |
Ladon | 2:f72c56822d58 | 97 | printf("LCKR = 0x%X\n", *lckr); |
Ladon | 2:f72c56822d58 | 98 | printf("AFRL = 0x%X\n", *afrl); |
Ladon | 0:e637d54ba0a3 | 99 | printf("\n"); |
Ladon | 0:e637d54ba0a3 | 100 | */ |
Ladon | 0:e637d54ba0a3 | 101 | wait(0.65); |
Ladon | 0:e637d54ba0a3 | 102 | // ^ : https://os.mbed.com/docs/mbed-os/v5.13/apis/wait.html |
Ladon | 0:e637d54ba0a3 | 103 | // - |
Ladon | 0:e637d54ba0a3 | 104 | } |
Ladon | 0:e637d54ba0a3 | 105 | } |