Library 44- STM32F4 unique ID and flash size
STM32F4xx devices have some parts in memory, which are read only and store some information about device. You can use them to protect your program if it is stolen from memory, or to tell programmer/debugger which device is connected with and detect flash size.
This library covers 4 things you can read from device:
- Device signature
- Device signature is something that you probably want to know when you are working with some device. This feature returns you 16-bit length device signature value.
- Device revision
- Some devices are from time to time updated in features, but with same name. This register returns you a revisionĀ in which it was made.
- Flash size
- Flash size is 16bit value stored somewhere in MCU. Value is in kB (kilo bytes)
- Unique ID
- 96-bit long identification part, where bits are factory programmed. Each device has different number, which gives you an opportunity to check if program on the device is “stolen” from another device, so you can disable functionality.
Library
Features
- Read device signature
- Read device revision
- Read device’s flash size in kB (kilo bytes)
- Read 96-bits unique ID in different read modes:
- 8bit mode
- 16bit mode
- 32bit mode
Dependencies
- CMSIS
- STM32F4xx
Values returned
- Device signature is not something like “0x0401” for STM32F401, or “0x0407” for STM32F407, etc. You have to carefully read what you get back and connect returned value with real device. Possible values in signature register are:
- 0x0413: STM32F405xx/07xx and STM32F415xx/17xx)
- 0x0419: STM32F42xxx and STM32F43xxx
- 0x0423: STM32F401xB/C
- 0x0433: STM32F401xD/E
- 0x0431: STM32F411xC/E
- Device revision is next strange format. It’s possible returns are:
- 0x1000: Revision A
- 0x1001: Revision Z
- 0x1003: Revision Y
- 0x1007: Revision 1
- 0x2001: Revision 3
- Flash size is always returned in kB value
- Unique ID is a little bit more complicated. You can’t read it with single call, so you have to make several calls. For that purpose I’ve made 3 different read modes.
- 32-bit mode: Read 32-bits at a time, pass values 0 to 2 to function, corresponding to which 32-bits you want to read. Higher number means higher 32-bits.
- 16-bit mode:Ā Read 16-bits at a time, pass values 0 to 5Ā to function, corresponding to which 16-bits you want to read. Higher number means higher 16-bits.
- 8-bit mode:Ā Read 8-bits at a time, pass values 0 to 11Ā to function, corresponding to which 8-bits you want to read. Higher number means higher 8-bits
Functions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
/** * With this "function" you are able to get signature of device. * * Possible returns: * - 0x0413: STM32F405xx/07xx and STM32F415xx/17xx) * - 0x0419: STM32F42xxx and STM32F43xxx * - 0x0423: STM32F401xB/C * - 0x0433: STM32F401xD/E * - 0x0431: STM32F411xC/E * * Returned data is in 16-bit mode, but only bits 11:0 are valid, bits 15:12 are always 0. * Defined as macro */ #define TM_ID_GetSignature() ((*(uint16_t *) (ID_DBGMCU_IDCODE)) & 0x0FFF) /** * With this "function" you are able to get revision of device. * * Revisions possible: * - 0x1000: Revision A * - 0x1001: Revision Z * - 0x1003: Revision Y * - 0x1007: Revision 1 * - 0x2001: Revision 3 * * Returned data is in 16-bit mode. * Defined as macro */ #define TM_ID_GetRevision() (*(uint16_t *) (ID_DBGMCU_IDCODE + 2)) /** * With this "function" you are able to get flash size of device. * * Returned data is in 16-bit mode, returned value is flash size in kB (kilo bytes). * Defined as macro */ #define TM_ID_GetFlashSize() (*(uint16_t *) (ID_FLASH_ADDRESS)) /** * With this "function" you are able to get unique ID of device in 8-bit (byte) read mode. * Unique ID is 96bit long, but if you need just some parts of it, you can read them with 8bit function. * * Parameters: * - uint8_t x: * Value between 0 and 11, corresponding to byte you want to read from 96bits (12bytes) * * Returned data is 8-bit * Defined as macro */ #define TM_ID_GetUnique8(x) ((x >= 0 && x < 12) ? (*(uint8_t *) (ID_UNIQUE_ADDRESS + (x))) : 0) /** * With this "function" you are able to get unique ID of device in 16-bit (byte) read mode. * Unique ID is 96bit long, but if you need just some parts of it, you can read them with 16bit function. * * Parameters: * - uint8_t x: * Value between 0 and 5, corresponding to 2-bytes you want to read from 96bits (12bytes) * * Returned data is 16-bit * Defined as macro */ #define TM_ID_GetUnique16(x) ((x >= 0 && x < 6) ? (*(uint16_t *) (ID_UNIQUE_ADDRESS + 2 * (x))) : 0) /** * With this "function" you are able to get unique ID of device in 32-bit (byte) read mode. * Unique ID is 96bit long, but if you need just some parts of it, you can read them with 32bit function. * * Parameters: * - uint8_t x: * Value between 0 and 2, corresponding to 4-bytes you want to read from 96bits (12bytes) * * Returned data is 32-bit * Defined as macro */ #define TM_ID_GetUnique32(x) ((x >= 0 && x < 3) ? (*(uint32_t *) (ID_UNIQUE_ADDRESS + 4 * (x))) : 0) |
Example
- I’ve tested bottom example with Nucleo F401-RE board.
- Data from STM are sent over USART2, TX: PA2, 115200 baud. On nucleo board, this is connected to USB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
/** * Keil project for STM32F4 Identification * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * @packs STM32F4xx Keil packs version 2.2.0 or greater required * @stdperiph STM32F4xx Standard peripheral drivers version 1.4.0 or greater required */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_usart.h" #include "tm_stm32f4_id.h" #include <stdio.h> int main(void) { char buff[200]; /* Initialize system */ SystemInit(); /* Initialize USART2, TX: PA2, on Nucleo boards connected to USB (STLink) */ TM_USART_Init(USART2, TM_USART_PinsPack_1, 115200); /* Format device signature */ sprintf(buff, "Device signature: 0x%04X\r\n", TM_ID_GetSignature()); /* Send to USART */ TM_USART_Puts(USART2, buff); /* Format device signature */ sprintf(buff, "Device revision: 0x%04X\r\n", TM_ID_GetRevision()); /* Send to USART */ TM_USART_Puts(USART2, buff); /* Format flash size */ sprintf(buff, "Flash size: %u kB\r\n", TM_ID_GetFlashSize()); /* Send to USART */ TM_USART_Puts(USART2, buff); /* Format unique ID in 32-bit read mode */ sprintf(buff, "Unique ID in 32-bit read mode: 0x%08X 0x%08X 0x%08X\r\n", TM_ID_GetUnique32(0), /* LSB */ TM_ID_GetUnique32(1), TM_ID_GetUnique32(2) /* MSB */ ); /* Send to USART */ TM_USART_Puts(USART2, buff); /* Format unique ID in 16-bit read mode */ sprintf(buff, "Unique ID in 16-bit read mode: 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X\r\n", TM_ID_GetUnique16(0), /* LSB */ TM_ID_GetUnique16(1), TM_ID_GetUnique16(2), TM_ID_GetUnique16(3), TM_ID_GetUnique16(4), TM_ID_GetUnique16(5) /* MSB */ ); /* Send to USART */ TM_USART_Puts(USART2, buff); /* Format unique ID in 8-bit read mode */ sprintf(buff, "Unique ID in 8-bit read mode: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\r\n", TM_ID_GetUnique8(0), /* LSB */ TM_ID_GetUnique8(1), TM_ID_GetUnique8(2), TM_ID_GetUnique8(3), TM_ID_GetUnique8(4), TM_ID_GetUnique8(5), TM_ID_GetUnique8(6), TM_ID_GetUnique8(7), TM_ID_GetUnique8(8), TM_ID_GetUnique8(9), TM_ID_GetUnique8(10), TM_ID_GetUnique8(11) /* MSB */ ); /* Send to USART */ TM_USART_Puts(USART2, buff); while (1) { } } |
Project is available on Github, download library below.
Recent comments