From c1a535d343d6ea6e84f99b9b0b760d9a582ad969 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Nov 2011 10:30:56 +0000 Subject: Unified STM32 registers header file stm32.h. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3526 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/gpt_lld.c | 14 +-- os/hal/platforms/STM32/gpt_lld.h | 2 +- os/hal/platforms/STM32/icu_lld.c | 12 +-- os/hal/platforms/STM32/icu_lld.h | 2 +- os/hal/platforms/STM32/pwm_lld.c | 12 +-- os/hal/platforms/STM32/pwm_lld.h | 2 +- os/hal/platforms/STM32/stm32.h | 169 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32F1xx/hal_lld.h | 43 +-------- os/hal/platforms/STM32F1xx/stm32f10x.h | 3 - os/hal/platforms/STM32F2xx/stm32f2xx.h | 3 + os/hal/platforms/STM32F4xx/hal_lld.h | 43 +-------- os/hal/platforms/STM32F4xx/stm32f4xx.h | 5 +- os/hal/platforms/STM32L1xx/hal_lld.h | 43 +-------- os/hal/platforms/STM32L1xx/stm32l1xx.h | 4 +- readme.txt | 6 +- 15 files changed, 204 insertions(+), 159 deletions(-) create mode 100644 os/hal/platforms/STM32/stm32.h diff --git a/os/hal/platforms/STM32/gpt_lld.c b/os/hal/platforms/STM32/gpt_lld.c index af8737f04..e40843ccb 100644 --- a/os/hal/platforms/STM32/gpt_lld.c +++ b/os/hal/platforms/STM32/gpt_lld.c @@ -192,7 +192,7 @@ CH_IRQ_HANDLER(TIM5_IRQHandler) { #if STM32_GPT_USE_TIM8 /** - * @brief TIM5 interrupt handler. + * @brief TIM8 interrupt handler. * * @isr */ @@ -219,37 +219,37 @@ void gpt_lld_init(void) { #if STM32_GPT_USE_TIM1 /* Driver initialization.*/ - GPTD1.tim = TIM1; + GPTD1.tim = STM32_TIM1; gptObjectInit(&GPTD1); #endif #if STM32_GPT_USE_TIM2 /* Driver initialization.*/ - GPTD2.tim = TIM2; + GPTD2.tim = STM32_TIM2; gptObjectInit(&GPTD2); #endif #if STM32_GPT_USE_TIM3 /* Driver initialization.*/ - GPTD3.tim = TIM3; + GPTD3.tim = STM32_TIM3; gptObjectInit(&GPTD3); #endif #if STM32_GPT_USE_TIM4 /* Driver initialization.*/ - GPTD4.tim = TIM4; + GPTD4.tim = STM32_TIM4; gptObjectInit(&GPTD4); #endif #if STM32_GPT_USE_TIM5 /* Driver initialization.*/ - GPTD5.tim = TIM5; + GPTD5.tim = STM32_TIM5; gptObjectInit(&GPTD5); #endif #if STM32_GPT_USE_TIM8 /* Driver initialization.*/ - GPTD5.tim = TIM8; + GPTD5.tim = STM32_TIM8; gptObjectInit(&GPTD8); #endif } diff --git a/os/hal/platforms/STM32/gpt_lld.h b/os/hal/platforms/STM32/gpt_lld.h index f61c5d030..13c5e1f4b 100644 --- a/os/hal/platforms/STM32/gpt_lld.h +++ b/os/hal/platforms/STM32/gpt_lld.h @@ -230,7 +230,7 @@ struct GPTDriver { /** * @brief Pointer to the TIMx registers block. */ - TIM_TypeDef *tim; + stm32_tim_t *tim; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c index ab3e12f26..e76f8a109 100644 --- a/os/hal/platforms/STM32/icu_lld.c +++ b/os/hal/platforms/STM32/icu_lld.c @@ -239,37 +239,37 @@ void icu_lld_init(void) { #if STM32_ICU_USE_TIM1 /* Driver initialization.*/ icuObjectInit(&ICUD1); - ICUD1.tim = TIM1; + ICUD1.tim = STM32_TIM1; #endif #if STM32_ICU_USE_TIM2 /* Driver initialization.*/ icuObjectInit(&ICUD2); - ICUD2.tim = TIM2; + ICUD2.tim = STM32_TIM2; #endif #if STM32_ICU_USE_TIM3 /* Driver initialization.*/ icuObjectInit(&ICUD3); - ICUD3.tim = TIM3; + ICUD3.tim = STM32_TIM3; #endif #if STM32_ICU_USE_TIM4 /* Driver initialization.*/ icuObjectInit(&ICUD4); - ICUD4.tim = TIM4; + ICUD4.tim = STM32_TIM4; #endif #if STM32_ICU_USE_TIM5 /* Driver initialization.*/ icuObjectInit(&ICUD5); - ICUD5.tim = TIM5; + ICUD5.tim = STM32_TIM5; #endif #if STM32_ICU_USE_TIM8 /* Driver initialization.*/ icuObjectInit(&ICUD8); - ICUD5.tim = TIM8; + ICUD5.tim = STM32_TIM8; #endif } diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h index b97930609..f5b6bf695 100644 --- a/os/hal/platforms/STM32/icu_lld.h +++ b/os/hal/platforms/STM32/icu_lld.h @@ -245,7 +245,7 @@ struct ICUDriver { /** * @brief Pointer to the TIMx registers block. */ - TIM_TypeDef *tim; + stm32_tim_t *tim; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index fb5d12adf..4392d5db9 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -297,37 +297,37 @@ void pwm_lld_init(void) { #if STM32_PWM_USE_TIM1 /* Driver initialization.*/ pwmObjectInit(&PWMD1); - PWMD1.tim = TIM1; + PWMD1.tim = STM32_TIM1; #endif #if STM32_PWM_USE_TIM2 /* Driver initialization.*/ pwmObjectInit(&PWMD2); - PWMD2.tim = TIM2; + PWMD2.tim = STM32_TIM2; #endif #if STM32_PWM_USE_TIM3 /* Driver initialization.*/ pwmObjectInit(&PWMD3); - PWMD3.tim = TIM3; + PWMD3.tim = STM32_TIM3; #endif #if STM32_PWM_USE_TIM4 /* Driver initialization.*/ pwmObjectInit(&PWMD4); - PWMD4.tim = TIM4; + PWMD4.tim = STM32_TIM4; #endif #if STM32_PWM_USE_TIM5 /* Driver initialization.*/ pwmObjectInit(&PWMD5); - PWMD5.tim = TIM5; + PWMD5.tim = STM32_TIM5; #endif #if STM32_PWM_USE_TIM8 /* Driver initialization.*/ pwmObjectInit(&PWMD8); - PWMD8.tim = TIM8; + PWMD8.tim = STM32_TIM8; #endif } diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h index 78e411592..ca890e8f0 100644 --- a/os/hal/platforms/STM32/pwm_lld.h +++ b/os/hal/platforms/STM32/pwm_lld.h @@ -327,7 +327,7 @@ struct PWMDriver { /** * @brief Pointer to the TIMx registers block. */ - TIM_TypeDef *tim; + stm32_tim_t *tim; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/stm32.h b/os/hal/platforms/STM32/stm32.h new file mode 100644 index 000000000..0ee083dcc --- /dev/null +++ b/os/hal/platforms/STM32/stm32.h @@ -0,0 +1,169 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/stm32.h + * @brief STM32 common header. + * @pre One of the following macros must be defined before including + * this header, the macro selects the inclusion of the appropriate + * vendor header: + * - STM32F10X_LD_VL for Value Line Low Density devices. + * - STM32F10X_MD_VL for Value Line Medium Density devices. + * - STM32F10X_LD for Performance Low Density devices. + * - STM32F10X_MD for Performance Medium Density devices. + * - STM32F10X_HD for Performance High Density devices. + * - STM32F10X_XL for Performance eXtra Density devices. + * - STM32F10X_CL for Connectivity Line devices. + * - STM32F2XX for High-performance STM32 F-2 devices. + * - STM32F4XX for High-performance STM32 F-4 devices. + * - STM32L1XX_MD for Ultra Low Power Medium-density devices. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef _STM32_H_ +#define _STM32_H_ + +#if defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \ + defined(STM32F10X_HD_VL) || defined(STM32F10X_LD) || \ + defined(STM32F10X_MD) || defined(STM32F10X_HD) || \ + defined(STM32F10X_XL) || defined(STM32F10X_CL) || \ + defined(__DOXYGEN__) +#include "stm32f10x.h" +#endif + +#if defined(STM32F2XX) || defined(__DOXYGEN__) +#include "stm32f2xx.h" +#endif + +#if defined(STM32F4XX) || defined(__DOXYGEN__) +#include "stm32f4xx.h" +#endif + +#if defined(STM32L1XX_MD) || defined(__DOXYGEN__) +#include "stm32l1xx.h" +#endif + +#undef TIM1 +#undef TIM2 +#undef TIM3 +#undef TIM4 +#undef TIM5 +#undef TIM6 +#undef TIM7 +#undef TIM8 +#undef TIM9 +#undef TIM10 +#undef TIM11 +#undef TIM12 +#undef TIM13 +#undef TIM14 + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 TIM registers block. + * @note Redefined from the ST headers because the non uniform + * declaration of the CCR registers among the various + * sub-families. + */ +typedef struct { + volatile uint16_t CR1; + uint16_t _resvd0; + volatile uint16_t CR2; + uint16_t _resvd1; + volatile uint16_t SMCR; + uint16_t _resvd2; + volatile uint16_t DIER; + uint16_t _resvd3; + volatile uint16_t SR; + uint16_t _resvd4; + volatile uint16_t EGR; + uint16_t _resvd5; + volatile uint16_t CCMR1; + uint16_t _resvd6; + volatile uint16_t CCMR2; + uint16_t _resvd7; + volatile uint16_t CCER; + uint16_t _resvd8; + volatile uint32_t CNT; + volatile uint16_t PSC; + uint16_t _resvd9; + volatile uint32_t ARR; + volatile uint16_t RCR; + uint16_t _resvd10; + volatile uint32_t CCR[4]; + volatile uint16_t BDTR; + uint16_t _resvd11; + volatile uint16_t DCR; + uint16_t _resvd12; + volatile uint16_t DMAR; + uint16_t _resvd13; + volatile uint16_t OR; + uint16_t _resvd14; +} stm32_tim_t; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name TIM units references + * @{ + */ +#define STM32_TIM1 ((stm32_tim_t *)TIM1_BASE) +#define STM32_TIM2 ((stm32_tim_t *)TIM2_BASE) +#define STM32_TIM3 ((stm32_tim_t *)TIM3_BASE) +#define STM32_TIM4 ((stm32_tim_t *)TIM4_BASE) +#define STM32_TIM5 ((stm32_tim_t *)TIM5_BASE) +#define STM32_TIM6 ((stm32_tim_t *)TIM6_BASE) +#define STM32_TIM7 ((stm32_tim_t *)TIM7_BASE) +#define STM32_TIM8 ((stm32_tim_t *)TIM8_BASE) +#define STM32_TIM9 ((stm32_tim_t *)TIM9_BASE) +#define STM32_TIM10 ((stm32_tim_t *)TIM10_BASE) +#define STM32_TIM11 ((stm32_tim_t *)TIM11_BASE) +#define STM32_TIM12 ((stm32_tim_t *)TIM12_BASE) +#define STM32_TIM13 ((stm32_tim_t *)TIM13_BASE) +#define STM32_TIM14 ((stm32_tim_t *)TIM14_BASE) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#endif /* _STM32_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index b1ba1a5ed..64cf0165c 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -43,7 +43,7 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -#include "stm32f10x.h" +#include "stm32.h" /*===========================================================================*/ /* Driver constants. */ @@ -102,47 +102,6 @@ /* Driver data structures and types. */ /*===========================================================================*/ -/** - * @brief STM32 TIM registers block. - * @note Removed from the ST headers and redefined because the non uniform - * declaration of the CCR registers among the various sub-families. - */ -typedef struct { - volatile uint16_t CR1; - uint16_t _resvd0; - volatile uint16_t CR2; - uint16_t _resvd1; - volatile uint16_t SMCR; - uint16_t _resvd2; - volatile uint16_t DIER; - uint16_t _resvd3; - volatile uint16_t SR; - uint16_t _resvd4; - volatile uint16_t EGR; - uint16_t _resvd5; - volatile uint16_t CCMR1; - uint16_t _resvd6; - volatile uint16_t CCMR2; - uint16_t _resvd7; - volatile uint16_t CCER; - uint16_t _resvd8; - volatile uint32_t CNT; - volatile uint16_t PSC; - uint16_t _resvd9; - volatile uint32_t ARR; - volatile uint16_t RCR; - uint16_t _resvd10; - volatile uint32_t CCR[4]; - volatile uint16_t BDTR; - uint16_t _resvd11; - volatile uint16_t DCR; - uint16_t _resvd12; - volatile uint16_t DMAR; - uint16_t _resvd13; - volatile uint16_t OR; - uint16_t _resvd14; -} TIM_TypeDef; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/stm32f10x.h b/os/hal/platforms/STM32F1xx/stm32f10x.h index e8f413763..6697b9648 100644 --- a/os/hal/platforms/STM32F1xx/stm32f10x.h +++ b/os/hal/platforms/STM32F1xx/stm32f10x.h @@ -1198,8 +1198,6 @@ typedef struct * @brief TIM */ -/* CHIBIOS FIX */ -#if 0 typedef struct { __IO uint16_t CR1; @@ -1243,7 +1241,6 @@ typedef struct __IO uint16_t DMAR; uint16_t RESERVED19; } TIM_TypeDef; -#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter diff --git a/os/hal/platforms/STM32F2xx/stm32f2xx.h b/os/hal/platforms/STM32F2xx/stm32f2xx.h index 51bcaf363..5c6e27d76 100644 --- a/os/hal/platforms/STM32F2xx/stm32f2xx.h +++ b/os/hal/platforms/STM32F2xx/stm32f2xx.h @@ -227,6 +227,7 @@ typedef enum IRQn */ #include "core_cm3.h" +/* CHIBIOS FIX */ /* #include "system_stm32f2xx.h" */ #include @@ -634,6 +635,7 @@ typedef struct /** * @brief General Purpose I/O */ +/* CHIBIOS FIX */ #if 0 typedef struct { @@ -649,6 +651,7 @@ typedef struct __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */ } GPIO_TypeDef; #endif + /** * @brief System configuration controller */ diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 29018e86f..a4dd1b775 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -38,7 +38,7 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -#include "stm32f4xx.h" +#include "stm32.h" /*===========================================================================*/ /* Driver constants. */ @@ -1291,47 +1291,6 @@ /* Driver data structures and types. */ /*===========================================================================*/ -/** - * @brief STM32 TIM registers block. - * @note Removed from the ST headers and redefined because the non uniform - * declaration of the CCR registers among the various sub-families. - */ -typedef struct { - volatile uint16_t CR1; - uint16_t _resvd0; - volatile uint16_t CR2; - uint16_t _resvd1; - volatile uint16_t SMCR; - uint16_t _resvd2; - volatile uint16_t DIER; - uint16_t _resvd3; - volatile uint16_t SR; - uint16_t _resvd4; - volatile uint16_t EGR; - uint16_t _resvd5; - volatile uint16_t CCMR1; - uint16_t _resvd6; - volatile uint16_t CCMR2; - uint16_t _resvd7; - volatile uint16_t CCER; - uint16_t _resvd8; - volatile uint32_t CNT; - volatile uint16_t PSC; - uint16_t _resvd9; - volatile uint32_t ARR; - volatile uint16_t RCR; - uint16_t _resvd10; - volatile uint32_t CCR[4]; - volatile uint16_t BDTR; - uint16_t _resvd11; - volatile uint16_t DCR; - uint16_t _resvd12; - volatile uint16_t DMAR; - uint16_t _resvd13; - volatile uint16_t OR; - uint16_t _resvd14; -} TIM_TypeDef; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F4xx/stm32f4xx.h b/os/hal/platforms/STM32F4xx/stm32f4xx.h index cd8ed7887..f4e88fc17 100644 --- a/os/hal/platforms/STM32F4xx/stm32f4xx.h +++ b/os/hal/platforms/STM32F4xx/stm32f4xx.h @@ -237,8 +237,8 @@ typedef enum IRQn * @} */ - /* CHIBIOS FIX */ #include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +/* CHIBIOS FIX */ /*#include "system_stm32f4xx.h"*/ #include @@ -868,8 +868,6 @@ typedef struct * @brief TIM */ -/* CHIBIOS FIX */ -#if 0 typedef struct { __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ @@ -909,7 +907,6 @@ typedef struct __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ uint16_t RESERVED14; /*!< Reserved, 0x52 */ } TIM_TypeDef; -#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index fe2909536..b25bad51d 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -37,7 +37,7 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -#include "stm32l1xx.h" +#include "stm32.h" /*===========================================================================*/ /* Driver constants. */ @@ -956,47 +956,6 @@ /* Driver data structures and types. */ /*===========================================================================*/ -/** - * @brief STM32 TIM registers block. - * @note Removed from the ST headers and redefined because the non uniform - * declaration of the CCR registers among the various sub-families. - */ -typedef struct { - volatile uint16_t CR1; - uint16_t _resvd0; - volatile uint16_t CR2; - uint16_t _resvd1; - volatile uint16_t SMCR; - uint16_t _resvd2; - volatile uint16_t DIER; - uint16_t _resvd3; - volatile uint16_t SR; - uint16_t _resvd4; - volatile uint16_t EGR; - uint16_t _resvd5; - volatile uint16_t CCMR1; - uint16_t _resvd6; - volatile uint16_t CCMR2; - uint16_t _resvd7; - volatile uint16_t CCER; - uint16_t _resvd8; - volatile uint32_t CNT; - volatile uint16_t PSC; - uint16_t _resvd9; - volatile uint32_t ARR; - volatile uint16_t RCR; - uint16_t _resvd10; - volatile uint32_t CCR[4]; - volatile uint16_t BDTR; - uint16_t _resvd11; - volatile uint16_t DCR; - uint16_t _resvd12; - volatile uint16_t DMAR; - uint16_t _resvd13; - volatile uint16_t OR; - uint16_t _resvd14; -} TIM_TypeDef; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32L1xx/stm32l1xx.h b/os/hal/platforms/STM32L1xx/stm32l1xx.h index 5fadee5db..9c665d29b 100644 --- a/os/hal/platforms/STM32L1xx/stm32l1xx.h +++ b/os/hal/platforms/STM32L1xx/stm32l1xx.h @@ -191,6 +191,7 @@ typedef enum IRQn */ #include "core_cm3.h" +/* CHIBIOS FIX */ /*#include "system_stm32l1xx.h"*/ #include @@ -615,8 +616,6 @@ typedef struct * @brief TIM */ -/* CHIBIOS FIX */ -#if 0 typedef struct { __IO uint16_t CR1; @@ -660,7 +659,6 @@ typedef struct __IO uint16_t OR; uint16_t RESERVED20; } TIM_TypeDef; -#endif /** * @brief Universal Synchronous Asynchronous Receiver Transmitter diff --git a/readme.txt b/readme.txt index c3762963f..fb4e4add2 100644 --- a/readme.txt +++ b/readme.txt @@ -84,6 +84,8 @@ (backported to 2.2.8). - FIX: Fixed broken TIM8 support in STM32 PWM driver (bug 3418620). - FIX: Fixed halconf.h file corrupted in some STM32 demos (bug 3418626). +- NEW: Added an unified registers file for STM32: stm32.h. This file includes + the appropriate vendor file then adds its own additional definitions. - NEW: Added demo for the ST STM32F4-Discovery kit. - NEW: STM32F4xx ADC driver implementation. - NEW: Added initialization of the NVIC VTOR register to all Cortex-Mx (v7M) @@ -94,7 +96,9 @@ - NEW: Reorganized the STM32F1xx hal_lld_xxx.h files in order to distribute the capability macros into the appropriate file (previously those were all in the common hal_lld.h). -- NEW: Added HAL, Serial, SPI support for the STM32F4xx sub-family. +- NEW: Added HAL, Serial, ADC, EXT, GPT, ICU, PWM, SPI and UART support for + the STM32F4xx sub-family. + TODO: Add CAN and SDC, the drivers need to be ported and tested. - NEW: Added handling of USART6 to the STM32 serial driver. - NEW: Added USE_COPT setting to all makefiles, contributed by Mabl. - NEW: Added EXT driver implementation for AT91SAM7x, contributed by Florian. -- cgit v1.2.3