diff options
author | Karl Palsson <karlp@tweak.net.au> | 2018-07-25 01:30:07 +0300 |
---|---|---|
committer | Karl Palsson <karlp@tweak.net.au> | 2018-07-29 23:31:17 +0300 |
commit | 231f21296f55cd7dc7d8449169ea92fbb539da75 (patch) | |
tree | b9104aa203b2a4a136898000e963dfacc71eef30 | |
parent | 46d4103c1dddd00ee3e5ff9d38a5b42923fc7fc0 (diff) |
stm32: f247: flash: use common code.
This shows what is _actually_ different for f7. A couple of option
bits, and a renaming of bit 7 of the status register, from Program
Sequence Error to Erase Sequence Error.
We keep the separate implementation of wait_for_last_operation, to meet
the "suggestions" of the reference manual to insert a DSB instruction.
Keeping the renamed bit/functions also requires us to keep separate
implementations of the flag clearing functions
-rw-r--r-- | include/libopencm3/stm32/common/flash_common_f24.h | 3 | ||||
-rw-r--r-- | include/libopencm3/stm32/f2/flash.h | 10 | ||||
-rw-r--r-- | include/libopencm3/stm32/f4/flash.h | 10 | ||||
-rw-r--r-- | include/libopencm3/stm32/f7/flash.h | 89 | ||||
-rw-r--r-- | lib/stm32/common/flash_common_f24.c | 26 | ||||
-rw-r--r-- | lib/stm32/f2/flash.c | 25 | ||||
-rw-r--r-- | lib/stm32/f4/flash.c | 25 | ||||
-rw-r--r-- | lib/stm32/f7/Makefile | 3 | ||||
-rw-r--r-- | lib/stm32/f7/flash.c | 278 |
9 files changed, 83 insertions, 386 deletions
diff --git a/include/libopencm3/stm32/common/flash_common_f24.h b/include/libopencm3/stm32/common/flash_common_f24.h index d504345c..bc71eacf 100644 --- a/include/libopencm3/stm32/common/flash_common_f24.h +++ b/include/libopencm3/stm32/common/flash_common_f24.h @@ -82,7 +82,6 @@ /* --- FLASH_SR values ----------------------------------------------------- */ #define FLASH_SR_BSY (1 << 16) -#define FLASH_SR_PGSERR (1 << 7) #define FLASH_SR_PGPERR (1 << 6) #define FLASH_SR_PGAERR (1 << 5) #define FLASH_SR_WRPERR (1 << 4) @@ -118,7 +117,6 @@ /* FLASH_OBR[15:8]: RDP */ #define FLASH_OPTCR_NRST_STDBY (1 << 7) #define FLASH_OPTCR_NRST_STOP (1 << 6) -#define FLASH_OPTCR_WDG_SW (1 << 5) #define FLASH_OPTCR_OPTSTRT (1 << 1) #define FLASH_OPTCR_OPTLOCK (1 << 0) #define FLASH_OPTCR_BOR_LEVEL_3 (0x00 << 2) @@ -143,7 +141,6 @@ BEGIN_DECLS void flash_lock_option_bytes(void); -void flash_clear_pgserr_flag(void); void flash_clear_pgperr_flag(void); void flash_clear_wrperr_flag(void); void flash_clear_pgaerr_flag(void); diff --git a/include/libopencm3/stm32/f2/flash.h b/include/libopencm3/stm32/f2/flash.h index d7d0e046..ed0e91ea 100644 --- a/include/libopencm3/stm32/f2/flash.h +++ b/include/libopencm3/stm32/f2/flash.h @@ -35,5 +35,15 @@ #include <libopencm3/stm32/common/flash_common_f.h> #include <libopencm3/stm32/common/flash_common_f24.h> +#define FLASH_SR_PGSERR (1 << 7) +#define FLASH_OPTCR_WDG_SW (1 << 5) + + +BEGIN_DECLS + +void flash_clear_pgserr_flag(void); + +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/flash.h b/include/libopencm3/stm32/f4/flash.h index 5a5d7761..dafe839d 100644 --- a/include/libopencm3/stm32/f4/flash.h +++ b/include/libopencm3/stm32/f4/flash.h @@ -35,5 +35,13 @@ #include <libopencm3/stm32/common/flash_common_f.h> #include <libopencm3/stm32/common/flash_common_f24.h> -#endif +#define FLASH_SR_PGSERR (1 << 7) +#define FLASH_OPTCR_WDG_SW (1 << 5) + +BEGIN_DECLS + +void flash_clear_pgserr_flag(void); +END_DECLS + +#endif diff --git a/include/libopencm3/stm32/f7/flash.h b/include/libopencm3/stm32/f7/flash.h index 451f5593..e0c5e1ad 100644 --- a/include/libopencm3/stm32/f7/flash.h +++ b/include/libopencm3/stm32/f7/flash.h @@ -34,22 +34,13 @@ #include <libopencm3/stm32/common/flash_common_all.h> #include <libopencm3/stm32/common/flash_common_f.h> -/* - * For details see: - * PM0081 Programming manual: STM32F40xxx and STM32F41xxx Flash programming - * September 2011, Doc ID 018520 Rev 1 - * https://github.com/libopencm3/libopencm3-archive/blob/master/st_micro/DM00023388.pdf - */ +#include <libopencm3/stm32/common/flash_common_f24.h> /* * Differences between F7 and F4: * 1. icache and dcache are now combined into a unified ART cache. The CPU has * its own d/i-caches, but those are unrelated to this. They are on the * AXIM bus. - * 2. There's an OPTCR1 is now used for boot addresses. Write protect bits - * are in OPTCR. Why does F4 have 2 copies of nWRP? - * 3. Latency field in FLASH_ACR is now 4 bits. Some CPU frequencies supported - * by F7 require more than 7 wait states. * 4. FLASH_SR_PGSERR (programming sequence error) is now FLASH_SR_ERSERR ( * erase sequence error). * 6. There are now two watchdogs - IWDG (independent watchdog) and WWDG ( @@ -57,66 +48,18 @@ */ /**@{*/ -/* --- FLASH registers ----------------------------------------------------- */ - -#define FLASH_ACR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x00) -#define FLASH_KEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x04) -#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) -#define FLASH_SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) -#define FLASH_CR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) -#define FLASH_OPTCR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) -#define FLASH_OPTCR1 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x18) - -/* --- FLASH Keys -----------------------------------------------------------*/ - -#define FLASH_KEYR_KEY1 0x45670123UL -#define FLASH_KEYR_KEY2 0xcdef89abUL -#define FLASH_OPTKEYR_KEY1 0x08192a3bUL -#define FLASH_OPTKEYR_KEY2 0x4c5d6e7fUL /* --- FLASH_ACR values ---------------------------------------------------- */ +/** @addtogroup flash_acr_values FLASH_ACR_VALUES + * @ingroup flash_registers +@{*/ #define FLASH_ACR_ARTRST (1 << 11) #define FLASH_ACR_ARTEN (1 << 9) #define FLASH_ACR_PRFTEN (1 << 8) +/*@}*/ -#define FLASH_ACR_LATENCY_SHIFT 0 -#define FLASH_ACR_LATENCY_MASK 0x0f - -/* --- FLASH_SR values ----------------------------------------------------- */ - -#define FLASH_SR_BSY (1 << 16) #define FLASH_SR_ERSERR (1 << 7) -#define FLASH_SR_PGPERR (1 << 6) -#define FLASH_SR_PGAERR (1 << 5) -#define FLASH_SR_WRPERR (1 << 4) -#define FLASH_SR_OPERR (1 << 1) -#define FLASH_SR_EOP (1 << 0) - -/* --- FLASH_CR values ----------------------------------------------------- */ - -#define FLASH_CR_LOCK (1 << 31) -#define FLASH_CR_ERRIE (1 << 25) -#define FLASH_CR_EOPIE (1 << 24) -#define FLASH_CR_STRT (1 << 16) - -#define FLASH_CR_PROGRAM_MASK 0x3 -#define FLASH_CR_PROGRAM_SHIFT 8 -/** @defgroup flash_cr_program_width Flash programming width -@ingroup flash_group -@{*/ -#define FLASH_CR_PROGRAM_X8 0 -#define FLASH_CR_PROGRAM_X16 1 -#define FLASH_CR_PROGRAM_X32 2 -#define FLASH_CR_PROGRAM_X64 3 -/**@}*/ - -#define FLASH_CR_SNB_SHIFT 3 -#define FLASH_CR_SNB_MASK 0x1f - -#define FLASH_CR_MER (1 << 2) -#define FLASH_CR_SER (1 << 1) -#define FLASH_CR_PG (1 << 0) /* --- FLASH_OPTCR values -------------------------------------------------- */ @@ -129,18 +72,9 @@ #define FLASH_OPTCR_RDP_SHIFT 8 #define FLASH_OPTCR_RDP_MASK 0xff -#define FLASH_OPTCR_NRST_STDBY (1 << 7) -#define FLASH_OPTCR_NRST_STOP (1 << 6) #define FLASH_OPTCR_IWDG_SW (1 << 5) #define FLASH_OPTCR_WWDG_SW (1 << 4) -#define FLASH_OPTCR_BOR_LEV_MASK 3 -#define FLASH_OPTCR_BOR_LEV_SHIFT 2 -#define FLASH_OPTCR_BOR_LEV_3 0x00 -#define FLASH_OPTCR_BOR_LEV_2 0x01 -#define FLASH_OPTCR_BOR_LEV_1 0x02 -#define FLASH_OPTCR_BOR_OFF 0x03 - #define FLASH_OPTCR_OPTSTRT (1 << 1) #define FLASH_OPTCR_OPTLOCK (1 << 0) @@ -154,23 +88,10 @@ BEGIN_DECLS -void flash_clear_pgperr_flag(void); - -void flash_lock_option_bytes(void); void flash_clear_erserr_flag(void); -void flash_clear_wrperr_flag(void); -void flash_clear_pgaerr_flag(void); void flash_art_enable(void); void flash_art_disable(void); void flash_art_reset(void); -void flash_erase_all_sectors(uint32_t program_size); -void flash_erase_sector(uint8_t sector, uint32_t program_size); -void flash_program_double_word(uint32_t address, uint64_t data); -void flash_program_word(uint32_t address, uint32_t data); -void flash_program_half_word(uint32_t address, uint16_t data); -void flash_program_byte(uint32_t address, uint8_t data); -void flash_program(uint32_t address, uint8_t *data, uint32_t len); -void flash_program_option_bytes(uint32_t data); END_DECLS /**@}*/ diff --git a/lib/stm32/common/flash_common_f24.c b/lib/stm32/common/flash_common_f24.c index 366c9e74..6f7de578 100644 --- a/lib/stm32/common/flash_common_f24.c +++ b/lib/stm32/common/flash_common_f24.c @@ -42,17 +42,6 @@ static inline void flash_set_program_size(uint32_t psize) } /*---------------------------------------------------------------------------*/ -/** @brief Clear the Programming Sequence Error Flag - -This flag is set when incorrect programming configuration has been made. -*/ - -void flash_clear_pgserr_flag(void) -{ - FLASH_SR |= FLASH_SR_PGSERR; -} - -/*---------------------------------------------------------------------------*/ /** @brief Clear the Programming Alignment Error Flag */ @@ -80,21 +69,6 @@ void flash_clear_wrperr_flag(void) } /*---------------------------------------------------------------------------*/ -/** @brief Clear All Status Flags - -Program error, end of operation, write protect error, busy. -*/ - -void flash_clear_status_flags(void) -{ - flash_clear_pgserr_flag(); - flash_clear_pgaerr_flag(); - flash_clear_wrperr_flag(); - flash_clear_pgperr_flag(); - flash_clear_eop_flag(); -} - -/*---------------------------------------------------------------------------*/ /** @brief Lock the Option Byte Access This disables write access to the option bytes. It is locked by default on diff --git a/lib/stm32/f2/flash.c b/lib/stm32/f2/flash.c index be458637..c2a0b3ba 100644 --- a/lib/stm32/f2/flash.c +++ b/lib/stm32/f2/flash.c @@ -54,5 +54,30 @@ void flash_wait_for_last_operation(void) while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); } +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Sequence Error Flag + +This flag is set when incorrect programming configuration has been made. +*/ + +void flash_clear_pgserr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGSERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear All Status Flags + +Program error, end of operation, write protect error, busy. +*/ +void flash_clear_status_flags(void) +{ + flash_clear_pgserr_flag(); + flash_clear_pgaerr_flag(); + flash_clear_wrperr_flag(); + flash_clear_pgperr_flag(); + flash_clear_eop_flag(); +} + /**@}*/ diff --git a/lib/stm32/f4/flash.c b/lib/stm32/f4/flash.c index 020861d7..8891be6e 100644 --- a/lib/stm32/f4/flash.c +++ b/lib/stm32/f4/flash.c @@ -54,5 +54,30 @@ void flash_wait_for_last_operation(void) while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); } +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Sequence Error Flag + +This flag is set when incorrect programming configuration has been made. +*/ + +void flash_clear_pgserr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGSERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear All Status Flags + +Program error, end of operation, write protect error, busy. +*/ +void flash_clear_status_flags(void) +{ + flash_clear_pgserr_flag(); + flash_clear_pgaerr_flag(); + flash_clear_wrperr_flag(); + flash_clear_pgperr_flag(); + flash_clear_eop_flag(); +} + /**@}*/ diff --git a/lib/stm32/f7/Makefile b/lib/stm32/f7/Makefile index f53194d5..e4b317a0 100644 --- a/lib/stm32/f7/Makefile +++ b/lib/stm32/f7/Makefile @@ -42,8 +42,9 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs -OBJS = flash_common_all.o flash_common_f.o flash.o pwr.o rcc.o +OBJS = flash_common_all.o flash_common_f.o flash_common_f24.o flash.o OBJS += gpio.o gpio_common_all.o gpio_common_f0234.o +OBJS += pwr.o rcc.o OBJS += rcc_common_all.o diff --git a/lib/stm32/f7/flash.c b/lib/stm32/f7/flash.c index a81815a9..9ec3e219 100644 --- a/lib/stm32/f7/flash.c +++ b/lib/stm32/f7/flash.c @@ -28,21 +28,6 @@ #include <libopencm3/stm32/flash.h> /*---------------------------------------------------------------------------*/ -/** @brief Set the Program Parallelism Size - -Set the programming word width. Note carefully the power supply voltage -restrictions under which the different word sizes may be used. See the -programming manual for more information. -@param[in] psize The programming word width one of: @ref flash_cr_program_width -*/ - -static inline void flash_set_program_size(uint32_t psize) -{ - FLASH_CR &= ~(FLASH_CR_PROGRAM_MASK << FLASH_CR_PROGRAM_SHIFT); - FLASH_CR |= psize << FLASH_CR_PROGRAM_SHIFT; -} - -/*---------------------------------------------------------------------------*/ /** @brief Issue Pipeline Stall Issue a pipeline stall to make sure all write operations completed. @@ -59,23 +44,11 @@ static inline void flash_pipeline_stall(void) } /*---------------------------------------------------------------------------*/ -/** @brief Clear the Programming Error Status Flag - -*/ - -void flash_clear_pgperr_flag(void) -{ - FLASH_SR |= FLASH_SR_PGPERR; -} - - -/*---------------------------------------------------------------------------*/ /** @brief Wait until Last Operation has Ended This loops indefinitely until an operation (write or erase) has completed by testing the busy flag. */ - void flash_wait_for_last_operation(void) { flash_pipeline_stall(); @@ -83,71 +56,17 @@ void flash_wait_for_last_operation(void) } /*---------------------------------------------------------------------------*/ -/** @brief Lock the Option Byte Access - -This disables write access to the option bytes. It is locked by default on -reset. -*/ - -void flash_lock_option_bytes(void) -{ - FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK; -} - -/*---------------------------------------------------------------------------*/ /** @brief Clear the Erase Sequence Error Flag This flag is set when an erase operation is performed with control register has not been correctly set. */ - void flash_clear_erserr_flag(void) { FLASH_SR |= FLASH_SR_ERSERR; } /*---------------------------------------------------------------------------*/ -/** @brief Clear the Programming Alignment Error Flag - -*/ - -void flash_clear_pgaerr_flag(void) -{ - FLASH_SR |= FLASH_SR_PGAERR; -} - -/*---------------------------------------------------------------------------*/ -/** @brief Clear the Write Protect Error Flag - -*/ - -void flash_clear_wrperr_flag(void) -{ - FLASH_SR |= FLASH_SR_WRPERR; -} - -/*---------------------------------------------------------------------------*/ -/** @brief Enable the ART Cache - -*/ - -void flash_art_enable(void) -{ - FLASH_ACR |= FLASH_ACR_ARTEN; -} - -/*---------------------------------------------------------------------------*/ -/** @brief Reset the ART Cache - -The ART cache must be disabled for this to have effect. -*/ - -void flash_art_reset(void) -{ - FLASH_ACR |= FLASH_ACR_ARTRST; -} - -/*---------------------------------------------------------------------------*/ /** @brief Clear All Status Flags Program error, end of operation, write protect error. @@ -163,207 +82,24 @@ void flash_clear_status_flags(void) } /*---------------------------------------------------------------------------*/ -/** @brief Erase All FLASH - -This performs all operations necessary to erase all sectors in the FLASH -memory. - -@param program_size: 0 (8-bit), 1 (16-bit), 2 (32-bit), 3 (64-bit) -*/ - -void flash_erase_all_sectors(uint32_t program_size) -{ - flash_wait_for_last_operation(); - flash_set_program_size(program_size); - - FLASH_CR |= FLASH_CR_MER; /* Enable mass erase. */ - FLASH_CR |= FLASH_CR_STRT; /* Trigger the erase. */ - - flash_wait_for_last_operation(); - FLASH_CR &= ~FLASH_CR_MER; /* Disable mass erase. */ -} - -/*---------------------------------------------------------------------------*/ -/** @brief Erase a Sector of FLASH - -This performs all operations necessary to erase a sector in FLASH memory. -The page should be checked to ensure that it was properly erased. A sector must -first be fully erased before attempting to program it. - -See the reference manual or the FLASH programming manual for details. - -@param[in] sector (0 - 11 for some parts, 0-23 on others) -@param program_size: 0 (8-bit), 1 (16-bit), 2 (32-bit), 3 (64-bit) -*/ - -void flash_erase_sector(uint8_t sector, uint32_t program_size) -{ - flash_wait_for_last_operation(); - flash_set_program_size(program_size); - - FLASH_CR &= ~(FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT); - FLASH_CR |= (sector & FLASH_CR_SNB_MASK) << FLASH_CR_SNB_SHIFT; - FLASH_CR |= FLASH_CR_SER; - FLASH_CR |= FLASH_CR_STRT; - - flash_wait_for_last_operation(); - FLASH_CR &= ~FLASH_CR_SER; - FLASH_CR &= ~(FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT); -} - -/*---------------------------------------------------------------------------*/ -/** @brief Program a 64 bit Word to FLASH - -This performs all operations necessary to program a 64 bit word to FLASH memory. -The program error flag should be checked separately for the event that memory -was not properly erased. - -@param[in] address Starting address in Flash. -@param[in] data Double word to write -*/ - -void flash_program_double_word(uint32_t address, uint64_t data) -{ - /* Ensure that all flash operations are complete. */ - flash_wait_for_last_operation(); - flash_set_program_size(FLASH_CR_PROGRAM_X64); - - /* Enable writes to flash. */ - FLASH_CR |= FLASH_CR_PG; - - /* Program the double_word. */ - MMIO64(address) = data; - - /* Wait for the write to complete. */ - flash_wait_for_last_operation(); - - /* Disable writes to flash. */ - FLASH_CR &= ~FLASH_CR_PG; -} - -/*---------------------------------------------------------------------------*/ -/** @brief Program a 32 bit Word to FLASH - -This performs all operations necessary to program a 32 bit word to FLASH memory. -The program error flag should be checked separately for the event that memory -was not properly erased. - -@param[in] address Starting address in Flash. -@param[in] data word to write -*/ - -void flash_program_word(uint32_t address, uint32_t data) -{ - /* Ensure that all flash operations are complete. */ - flash_wait_for_last_operation(); - flash_set_program_size(FLASH_CR_PROGRAM_X32); - - /* Enable writes to flash. */ - FLASH_CR |= FLASH_CR_PG; - - /* Program the word. */ - MMIO32(address) = data; - - /* Wait for the write to complete. */ - flash_wait_for_last_operation(); - - /* Disable writes to flash. */ - FLASH_CR &= ~FLASH_CR_PG; -} - -/*---------------------------------------------------------------------------*/ -/** @brief Program a Half Word to FLASH - -This performs all operations necessary to program a 16 bit word to FLASH memory. -The program error flag should be checked separately for the event that memory -was not properly erased. - -@param[in] address Starting address in Flash. -@param[in] data half word to write -*/ - -void flash_program_half_word(uint32_t address, uint16_t data) -{ - flash_wait_for_last_operation(); - flash_set_program_size(FLASH_CR_PROGRAM_X16); - - FLASH_CR |= FLASH_CR_PG; - - MMIO16(address) = data; - - flash_wait_for_last_operation(); - - FLASH_CR &= ~FLASH_CR_PG; /* Disable the PG bit. */ -} - -/*---------------------------------------------------------------------------*/ -/** @brief Program an 8 bit Byte to FLASH - -This performs all operations necessary to program an 8 bit byte to FLASH memory. -The program error flag should be checked separately for the event that memory -was not properly erased. +/** @brief Enable the ART Cache -@param[in] address Starting address in Flash. -@param[in] data byte to write */ -void flash_program_byte(uint32_t address, uint8_t data) +void flash_art_enable(void) { - flash_wait_for_last_operation(); - flash_set_program_size(FLASH_CR_PROGRAM_X8); - - FLASH_CR |= FLASH_CR_PG; - - MMIO8(address) = data; - - flash_wait_for_last_operation(); - - FLASH_CR &= ~FLASH_CR_PG; /* Disable the PG bit. */ + FLASH_ACR |= FLASH_ACR_ARTEN; } /*---------------------------------------------------------------------------*/ -/** @brief Program a Data Block to FLASH - -This programs an arbitrary length data block to FLASH memory. All the addresses -written to must have been erased (by calling flash_erase_sector). -The program error flag should be checked separately for the event that memory -was not properly erased. +/** @brief Reset the ART Cache -@param[in] address Starting address in Flash. -@param[in] data Pointer to start of data block. -@param[in] len Length of data block. +The ART cache must be disabled for this to have effect. */ -void flash_program(uint32_t address, uint8_t *data, uint32_t len) +void flash_art_reset(void) { - /* TODO: Use dword and word size program operations where possible for - * turbo speed. - */ - uint32_t i; - for (i = 0; i < len; i++) { - flash_program_byte(address+i, data[i]); - } + FLASH_ACR |= FLASH_ACR_ARTRST; } -/*---------------------------------------------------------------------------*/ -/** @brief Program the Option Bytes - -This performs all operations necessary to program the option bytes. -The option bytes do not need to be erased first. - -@param[in] data value to be programmed. -*/ - -void flash_program_option_bytes(uint32_t data) -{ - flash_wait_for_last_operation(); - - if (FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) { - flash_unlock_option_bytes(); - } - - FLASH_OPTCR = data & ~0x3; - FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT; /* Enable option byte prog. */ - flash_wait_for_last_operation(); -} /**@}*/ |