Spyros Papanastasiou
/
Write_to_port_directly__LED
Example program for Port access. Blink the LED using the registers.
main.cpp@0:e637d54ba0a3, 2019-07-21 (annotated)
- Committer:
- Ladon
- Date:
- Sun Jul 21 19:23:35 2019 +0000
- Revision:
- 0:e637d54ba0a3
- Child:
- 1:65c259961c26
Initial version. This program will stay as an example.
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 | 0:e637d54ba0a3 | 3 | // Board: NUCLEO-F303RE. |
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 | 0:e637d54ba0a3 | 9 | // Info: Talking to ports: |
Ladon | 0:e637d54ba0a3 | 10 | // https://developer.arm.com/tools-and-software/embedded/legacy-tools/ds-5-development-studio/resources/tutorials/accessing-memory-mapped-peripherals |
Ladon | 0:e637d54ba0a3 | 11 | // Info: #defines : |
Ladon | 0:e637d54ba0a3 | 12 | // https://raw.githubusercontent.com/ARMmbed/mbed-os/master/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/stm32f303xe.h |
Ladon | 0:e637d54ba0a3 | 13 | // Reference manual: |
Ladon | 0:e637d54ba0a3 | 14 | // https://www.st.com/resource/en/reference_manual/dm00043574.pdf |
Ladon | 0:e637d54ba0a3 | 15 | // - |
Ladon | 0:e637d54ba0a3 | 16 | // We 'll need the MODER (port mode) register (see ^reference manual) and the ODR (output data register). |
Ladon | 0:e637d54ba0a3 | 17 | // 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 | 18 | // - |
Ladon | 0:e637d54ba0a3 | 19 | // Note: |
Ladon | 0:e637d54ba0a3 | 20 | // I was unsuccessfull in the following: |
Ladon | 0:e637d54ba0a3 | 21 | // |
Ladon | 0:e637d54ba0a3 | 22 | // #define ODR ((volatile unsigned short*) (GPIOA + 0x14) |
Ladon | 0:e637d54ba0a3 | 23 | // - |
Ladon | 0:e637d54ba0a3 | 24 | |
Ladon | 0:e637d54ba0a3 | 25 | #define MODER ((volatile unsigned int*) 0x48000000) |
Ladon | 0:e637d54ba0a3 | 26 | // 32 bits. |
Ladon | 0:e637d54ba0a3 | 27 | // We 'll set pins 11,10 set to 0,1. |
Ladon | 0:e637d54ba0a3 | 28 | // - |
Ladon | 0:e637d54ba0a3 | 29 | |
Ladon | 0:e637d54ba0a3 | 30 | #define ODR ((volatile unsigned short*) 0x48000014) |
Ladon | 0:e637d54ba0a3 | 31 | // 16 bits. |
Ladon | 0:e637d54ba0a3 | 32 | // We 'll write at pin 5. |
Ladon | 0:e637d54ba0a3 | 33 | // - |
Ladon | 0:e637d54ba0a3 | 34 | |
Ladon | 0:e637d54ba0a3 | 35 | // More FUN (dwarf fortress reference). |
Ladon | 0:e637d54ba0a3 | 36 | // - |
Ladon | 0:e637d54ba0a3 | 37 | #define OTYPER ((volatile unsigned short*) (0x48000004)) |
Ladon | 0:e637d54ba0a3 | 38 | #define PUPDR ((volatile unsigned int*) (0x4800000C)) |
Ladon | 0:e637d54ba0a3 | 39 | #define BSRR ((volatile unsigned int*) (0x48000018)) |
Ladon | 0:e637d54ba0a3 | 40 | #define LCKR ((volatile unsigned int*) (0x4800001C)) |
Ladon | 0:e637d54ba0a3 | 41 | #define AFRL ((volatile unsigned int*) (0x48000020)) |
Ladon | 0:e637d54ba0a3 | 42 | |
Ladon | 0:e637d54ba0a3 | 43 | void set_bit_as_output () |
Ladon | 0:e637d54ba0a3 | 44 | { |
Ladon | 0:e637d54ba0a3 | 45 | // Set to output. |
Ladon | 0:e637d54ba0a3 | 46 | // - |
Ladon | 0:e637d54ba0a3 | 47 | unsigned int moder = *MODER; |
Ladon | 0:e637d54ba0a3 | 48 | moder |= 0x00000400U; |
Ladon | 0:e637d54ba0a3 | 49 | moder &= 0xFFFFF7FFU; |
Ladon | 0:e637d54ba0a3 | 50 | // ^ Write 0,1 to bits 11,10. |
Ladon | 0:e637d54ba0a3 | 51 | // - |
Ladon | 0:e637d54ba0a3 | 52 | *MODER = moder; |
Ladon | 0:e637d54ba0a3 | 53 | } |
Ladon | 0:e637d54ba0a3 | 54 | |
Ladon | 0:e637d54ba0a3 | 55 | void toggle_bit () |
Ladon | 0:e637d54ba0a3 | 56 | { |
Ladon | 0:e637d54ba0a3 | 57 | ///* |
Ladon | 0:e637d54ba0a3 | 58 | static unsigned short state = 0; |
Ladon | 0:e637d54ba0a3 | 59 | state ^= 0x20; |
Ladon | 0:e637d54ba0a3 | 60 | *ODR = state; |
Ladon | 0:e637d54ba0a3 | 61 | //*/ |
Ladon | 0:e637d54ba0a3 | 62 | /* |
Ladon | 0:e637d54ba0a3 | 63 | static bool state = false; |
Ladon | 0:e637d54ba0a3 | 64 | if (state) |
Ladon | 0:e637d54ba0a3 | 65 | { |
Ladon | 0:e637d54ba0a3 | 66 | *BSRR = 0x00200000U; |
Ladon | 0:e637d54ba0a3 | 67 | } |
Ladon | 0:e637d54ba0a3 | 68 | else |
Ladon | 0:e637d54ba0a3 | 69 | { |
Ladon | 0:e637d54ba0a3 | 70 | *BSRR = 0x00000020U; |
Ladon | 0:e637d54ba0a3 | 71 | } |
Ladon | 0:e637d54ba0a3 | 72 | state = !state; |
Ladon | 0:e637d54ba0a3 | 73 | */ |
Ladon | 0:e637d54ba0a3 | 74 | } |
Ladon | 0:e637d54ba0a3 | 75 | |
Ladon | 0:e637d54ba0a3 | 76 | int main () |
Ladon | 0:e637d54ba0a3 | 77 | { |
Ladon | 0:e637d54ba0a3 | 78 | set_bit_as_output(); |
Ladon | 0:e637d54ba0a3 | 79 | while (true) |
Ladon | 0:e637d54ba0a3 | 80 | { |
Ladon | 0:e637d54ba0a3 | 81 | toggle_bit(); |
Ladon | 0:e637d54ba0a3 | 82 | /* |
Ladon | 0:e637d54ba0a3 | 83 | printf("MODER = 0x%X\n", *MODER); |
Ladon | 0:e637d54ba0a3 | 84 | printf("OTYPER = 0x%X\n", *OTYPER); |
Ladon | 0:e637d54ba0a3 | 85 | printf("PUPDR = 0x%X\n", *PUPDR); |
Ladon | 0:e637d54ba0a3 | 86 | printf("ODR = 0x%hX\n", *ODR); |
Ladon | 0:e637d54ba0a3 | 87 | printf("LCKR = 0x%X\n", *LCKR); |
Ladon | 0:e637d54ba0a3 | 88 | printf("AFRL = 0x%X\n", *AFRL); |
Ladon | 0:e637d54ba0a3 | 89 | printf("\n"); |
Ladon | 0:e637d54ba0a3 | 90 | */ |
Ladon | 0:e637d54ba0a3 | 91 | wait(0.65); |
Ladon | 0:e637d54ba0a3 | 92 | // ^ : https://os.mbed.com/docs/mbed-os/v5.13/apis/wait.html |
Ladon | 0:e637d54ba0a3 | 93 | // - |
Ladon | 0:e637d54ba0a3 | 94 | } |
Ladon | 0:e637d54ba0a3 | 95 | } |