├── README.md ├── stm8s.h ├── stm8sduino.c ├── stm8sduino.h └── user-code.c /README.md: -------------------------------------------------------------------------------- 1 | # STM8Sduino 2 | Arduino port for STM8S/STM8A 8-bit MCUs 3 | 4 | 6/16/2017: minor changed to support COSMIC. Should compile for Raisonance. 5 | -------------------------------------------------------------------------------- /stm8s.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm8s.h 4 | * @author MCD Application Team 5 | * @version V2.2.0 6 | * @date 30-September-2014 7 | * @brief This file contains all HW registers definitions and memory mapping. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __STM8S_H 30 | #define __STM8S_H 31 | 32 | /** @addtogroup STM8S_StdPeriph_Driver 33 | * @{ 34 | */ 35 | 36 | /* Uncomment the line below according to the target STM8S or STM8A device used in your 37 | application. */ 38 | 39 | /* #define STM8S208 */ /*!< STM8S High density devices with CAN */ 40 | /* #define STM8S207 */ /*!< STM8S High density devices without CAN */ 41 | /* #define STM8S007 */ /*!< STM8S Value Line High density devices */ 42 | /* #define STM8AF52Ax */ /*!< STM8A High density devices with CAN */ 43 | /* #define STM8AF62Ax */ /*!< STM8A High density devices without CAN */ 44 | /* #define STM8S105 */ /*!< STM8S Medium density devices */ 45 | /* #define STM8S005 */ /*!< STM8S Value Line Medium density devices */ 46 | /* #define STM8AF626x */ /*!< STM8A Medium density devices */ 47 | /* #define STM8AF622x */ /*!< STM8A Low density devices */ 48 | /* #define STM8S103 */ /*!< STM8S Low density devices */ 49 | /* #define STM8S003 */ /*!< STM8S Value Line Low density devices */ 50 | /* #define STM8S903 */ /*!< STM8S Low density devices */ 51 | 52 | /* Tip: To avoid modifying this file each time you need to switch between these 53 | devices, you can define the device in your toolchain compiler preprocessor. 54 | 55 | - High-Density STM8A devices are the STM8AF52xx STM8AF6269/8x/Ax, 56 | STM8AF51xx, and STM8AF6169/7x/8x/9x/Ax microcontrollers where the Flash memory 57 | density ranges between 32 to 128 Kbytes 58 | - Medium-Density STM8A devices are the STM8AF622x/4x, STM8AF6266/68, 59 | STM8AF612x/4x, and STM8AF6166/68 microcontrollers where the Flash memory 60 | density ranges between 8 to 32 Kbytes 61 | - High-Density STM8S devices are the STM8S207xx, STM8S007 and STM8S208xx microcontrollers 62 | where the Flash memory density ranges between 32 to 128 Kbytes. 63 | - Medium-Density STM8S devices are the STM8S105x and STM8S005 microcontrollers 64 | where the Flash memory density ranges between 16 to 32-Kbytes. 65 | - Low-Density STM8A devices are the STM8AF622x microcontrollers where the Flash 66 | density is 8 Kbytes. 67 | - Low-Density STM8S devices are the STM8S103xx, STM8S003 and STM8S903xx microcontrollers 68 | where the Flash density is 8 Kbytes. */ 69 | 70 | #if !defined (STM8S208) && !defined (STM8S207) && !defined (STM8S105) && \ 71 | !defined (STM8S103) && !defined (STM8S903) && !defined (STM8AF52Ax) && \ 72 | !defined (STM8AF62Ax) && !defined (STM8AF626x) && !defined (STM8S007) && \ 73 | !defined (STM8S003)&& !defined (STM8S005) && !defined (STM8AF622x) 74 | #error "Please select first the target STM8S/A device used in your application (in stm8s.h file)" 75 | #endif 76 | 77 | /******************************************************************************/ 78 | /* Library configuration section */ 79 | /******************************************************************************/ 80 | /* Check the used compiler */ 81 | #if defined(__CSMC__) 82 | #define _COSMIC_ 83 | #elif defined(__RCST7__) 84 | #define _RAISONANCE_ 85 | #elif defined(__ICCSTM8__) 86 | #define _IAR_ 87 | #else 88 | #error "Unsupported Compiler!" /* Compiler defines not found */ 89 | #endif 90 | 91 | #if !defined USE_STDPERIPH_DRIVER 92 | /* Comment the line below if you will not use the peripherals drivers. 93 | In this case, these drivers will not be included and the application code will be 94 | based on direct access to peripherals registers */ 95 | #define USE_STDPERIPH_DRIVER 96 | #endif 97 | 98 | /** 99 | * @brief In the following line adjust the value of External High Speed oscillator (HSE) 100 | used in your application 101 | 102 | Tip: To avoid modifying this file each time you need to use different HSE, you 103 | can define the HSE value in your toolchain compiler preprocessor. 104 | */ 105 | #if !defined HSE_Value 106 | #if defined (STM8S208) || defined (STM8S207) || defined (STM8S007) || defined (STM8AF52Ax) || \ 107 | defined (STM8AF62Ax) || defined (STM8AF622x) 108 | #define HSE_VALUE ((uint32_t)24000000) /* Value of the External oscillator in Hz*/ 109 | #else 110 | #define HSE_VALUE ((uint32_t)16000000) /* Value of the External oscillator in Hz*/ 111 | #endif /* STM8S208 || STM8S207 || STM8S007 || STM8AF62Ax || STM8AF52Ax || STM8AF622x */ 112 | #endif /* HSE_Value */ 113 | 114 | /** 115 | * @brief Definition of Device on-chip RC oscillator frequencies 116 | */ 117 | #define HSI_VALUE ((uint32_t)16000000) /*!< Typical Value of the HSI in Hz */ 118 | #define LSI_VALUE ((uint32_t)128000) /*!< Typical Value of the LSI in Hz */ 119 | 120 | #ifdef _COSMIC_ 121 | #define FAR @far 122 | #define NEAR @near 123 | #define TINY @tiny 124 | #define EEPROM @eeprom 125 | #define CONST const 126 | #elif defined (_RAISONANCE_) /* __RCST7__ */ 127 | #define FAR far 128 | #define NEAR data 129 | #define TINY page0 130 | #define EEPROM eeprom 131 | #define CONST code 132 | #if defined (STM8S208) || defined (STM8S207) || defined (STM8S007) || defined (STM8AF52Ax) || \ 133 | defined (STM8AF62Ax) 134 | /*!< Used with memory Models for code higher than 64K */ 135 | #define MEMCPY fmemcpy 136 | #else /* STM8S903, STM8S103, STM8S003, STM8S105, STM8AF626x, STM8AF622x */ 137 | /*!< Used with memory Models for code less than 64K */ 138 | #define MEMCPY memcpy 139 | #endif /* STM8S208 or STM8S207 or STM8S007 or STM8AF62Ax or STM8AF52Ax */ 140 | #else /*_IAR_*/ 141 | #define FAR __far 142 | #define NEAR __near 143 | #define TINY __tiny 144 | #define EEPROM __eeprom 145 | #define CONST const 146 | #endif /* __CSMC__ */ 147 | 148 | /* For FLASH routines, select whether pointer will be declared as near (2 bytes, 149 | to handle code smaller than 64KB) or far (3 bytes, to handle code larger 150 | than 64K) */ 151 | 152 | #if defined (STM8S105) || defined (STM8S005) || defined (STM8S103) || defined (STM8S003) || \ 153 | defined (STM8S903) || defined (STM8AF626x) || defined (STM8AF622x) 154 | /*!< Used with memory Models for code smaller than 64K */ 155 | #define PointerAttr NEAR 156 | #define MemoryAddressCast uint16_t 157 | #else /* STM8S208 or STM8S207 or STM8AF62Ax or STM8AF52Ax */ 158 | /*!< Used with memory Models for code higher than 64K */ 159 | #define PointerAttr FAR 160 | #define MemoryAddressCast uint32_t 161 | #endif /* STM8S105 or STM8S103 or STM8S003 or STM8S903 or STM8AF626x or STM8AF622x */ 162 | 163 | /* Uncomment the line below to enable the FLASH functions execution from RAM */ 164 | #if !defined (RAM_EXECUTION) 165 | /* #define RAM_EXECUTION (1) */ 166 | #endif /* RAM_EXECUTION */ 167 | 168 | #ifdef RAM_EXECUTION 169 | #ifdef _COSMIC_ 170 | #define IN_RAM(a) a 171 | #elif defined (_RAISONANCE_) /* __RCST7__ */ 172 | #define IN_RAM(a) a inram 173 | #else /*_IAR_*/ 174 | #define IN_RAM(a) __ramfunc a 175 | #endif /* _COSMIC_ */ 176 | #else 177 | #define IN_RAM(a) a 178 | #endif /* RAM_EXECUTION */ 179 | 180 | /*!< [31:16] STM8S Standard Peripheral Library main version V2.2.0*/ 181 | #define __STM8S_STDPERIPH_VERSION_MAIN ((uint8_t)0x02) /*!< [31:24] main version */ 182 | #define __STM8S_STDPERIPH_VERSION_SUB1 ((uint8_t)0x02) /*!< [23:16] sub1 version */ 183 | #define __STM8S_STDPERIPH_VERSION_SUB2 ((uint8_t)0x00) /*!< [15:8] sub2 version */ 184 | #define __STM8S_STDPERIPH_VERSION_RC ((uint8_t)0x00) /*!< [7:0] release candidate */ 185 | #define __STM8S_STDPERIPH_VERSION ( (__STM8S_STDPERIPH_VERSION_MAIN << 24)\ 186 | |(__STM8S_STDPERIPH_VERSION_SUB1 << 16)\ 187 | |(__STM8S_STDPERIPH_VERSION_SUB2 << 8)\ 188 | |(__STM8S_STDPERIPH_VERSION_RC)) 189 | 190 | /******************************************************************************/ 191 | 192 | /* Includes ------------------------------------------------------------------*/ 193 | 194 | /* Exported types and constants ----------------------------------------------*/ 195 | 196 | /** @addtogroup Exported_types 197 | * @{ 198 | */ 199 | 200 | /** 201 | * IO definitions 202 | * 203 | * define access restrictions to peripheral registers 204 | */ 205 | #define __I volatile const /*!< defines 'read only' permissions */ 206 | #define __O volatile /*!< defines 'write only' permissions */ 207 | #define __IO volatile /*!< defines 'read / write' permissions */ 208 | 209 | /*!< Signed integer types */ 210 | typedef signed char int8_t; 211 | typedef signed short int16_t; 212 | typedef signed long int32_t; 213 | 214 | /*!< Unsigned integer types */ 215 | typedef unsigned char uint8_t; 216 | typedef unsigned short uint16_t; 217 | typedef unsigned long uint32_t; 218 | 219 | /*!< STM8 Standard Peripheral Library old types (maintained for legacy purpose) */ 220 | 221 | typedef int32_t s32; 222 | typedef int16_t s16; 223 | typedef int8_t s8; 224 | 225 | typedef uint32_t u32; 226 | typedef uint16_t u16; 227 | typedef uint8_t u8; 228 | 229 | 230 | typedef enum {FALSE = 0, TRUE = !FALSE} bool; 231 | 232 | typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus, BitStatus, BitAction; 233 | 234 | typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; 235 | #define IS_FUNCTIONALSTATE_OK(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) 236 | 237 | typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; 238 | 239 | #define U8_MAX (255) 240 | #define S8_MAX (127) 241 | #define S8_MIN (-128) 242 | #define U16_MAX (65535u) 243 | #define S16_MAX (32767) 244 | #define S16_MIN (-32768) 245 | #define U32_MAX (4294967295uL) 246 | #define S32_MAX (2147483647) 247 | #define S32_MIN (-2147483648uL) 248 | 249 | /** 250 | * @} 251 | */ 252 | 253 | /** @addtogroup MAP_FILE_Exported_Types_and_Constants 254 | * @{ 255 | */ 256 | 257 | /******************************************************************************/ 258 | /* IP registers structures */ 259 | /******************************************************************************/ 260 | 261 | /** 262 | * @brief General Purpose I/Os (GPIO) 263 | */ 264 | typedef struct GPIO_struct 265 | { 266 | __IO uint8_t ODR; /*!< Output Data Register */ 267 | __IO uint8_t IDR; /*!< Input Data Register */ 268 | __IO uint8_t DDR; /*!< Data Direction Register */ 269 | __IO uint8_t CR1; /*!< Configuration Register 1 */ 270 | __IO uint8_t CR2; /*!< Configuration Register 2 */ 271 | } 272 | GPIO_TypeDef; 273 | 274 | /** @addtogroup GPIO_Registers_Reset_Value 275 | * @{ 276 | */ 277 | 278 | #define GPIO_ODR_RESET_VALUE ((uint8_t)0x00) 279 | #define GPIO_DDR_RESET_VALUE ((uint8_t)0x00) 280 | #define GPIO_CR1_RESET_VALUE ((uint8_t)0x00) 281 | #define GPIO_CR2_RESET_VALUE ((uint8_t)0x00) 282 | 283 | /** 284 | * @} 285 | */ 286 | 287 | /*----------------------------------------------------------------------------*/ 288 | #if defined(STM8S105) || defined(STM8S005) || defined(STM8S103) || defined(STM8S003) || \ 289 | defined(STM8S903) || defined(STM8AF626x) || defined(STM8AF622x) 290 | /** 291 | * @brief Analog to Digital Converter (ADC1) 292 | */ 293 | typedef struct ADC1_struct 294 | { 295 | __IO uint8_t DB0RH; /*!< ADC1 Data Buffer Register (MSB) */ 296 | __IO uint8_t DB0RL; /*!< ADC1 Data Buffer Register (LSB) */ 297 | __IO uint8_t DB1RH; /*!< ADC1 Data Buffer Register (MSB) */ 298 | __IO uint8_t DB1RL; /*!< ADC1 Data Buffer Register (LSB) */ 299 | __IO uint8_t DB2RH; /*!< ADC1 Data Buffer Register (MSB) */ 300 | __IO uint8_t DB2RL; /*!< ADC1 Data Buffer Register (LSB) */ 301 | __IO uint8_t DB3RH; /*!< ADC1 Data Buffer Register (MSB) */ 302 | __IO uint8_t DB3RL; /*!< ADC1 Data Buffer Register (LSB) */ 303 | __IO uint8_t DB4RH; /*!< ADC1 Data Buffer Register (MSB) */ 304 | __IO uint8_t DB4RL; /*!< ADC1 Data Buffer Register (LSB) */ 305 | __IO uint8_t DB5RH; /*!< ADC1 Data Buffer Register (MSB) */ 306 | __IO uint8_t DB5RL; /*!< ADC1 Data Buffer Register (LSB) */ 307 | __IO uint8_t DB6RH; /*!< ADC1 Data Buffer Register (MSB) */ 308 | __IO uint8_t DB6RL; /*!< ADC1 Data Buffer Register (LSB) */ 309 | __IO uint8_t DB7RH; /*!< ADC1 Data Buffer Register (MSB) */ 310 | __IO uint8_t DB7RL; /*!< ADC1 Data Buffer Register (LSB) */ 311 | __IO uint8_t DB8RH; /*!< ADC1 Data Buffer Register (MSB) */ 312 | __IO uint8_t DB8RL; /*!< ADC1 Data Buffer Register (LSB) */ 313 | __IO uint8_t DB9RH; /*!< ADC1 Data Buffer Register (MSB) */ 314 | __IO uint8_t DB9RL; /*!< ADC1 Data Buffer Register (LSB) */ 315 | uint8_t RESERVED[12]; /*!< Reserved byte */ 316 | __IO uint8_t CSR; /*!< ADC1 control status register */ 317 | __IO uint8_t CR1; /*!< ADC1 configuration register 1 */ 318 | __IO uint8_t CR2; /*!< ADC1 configuration register 2 */ 319 | __IO uint8_t CR3; /*!< ADC1 configuration register 3 */ 320 | __IO uint8_t DRH; /*!< ADC1 Data high */ 321 | __IO uint8_t DRL; /*!< ADC1 Data low */ 322 | __IO uint8_t TDRH; /*!< ADC1 Schmitt trigger disable register high */ 323 | __IO uint8_t TDRL; /*!< ADC1 Schmitt trigger disable register low */ 324 | __IO uint8_t HTRH; /*!< ADC1 high threshold register High*/ 325 | __IO uint8_t HTRL; /*!< ADC1 high threshold register Low*/ 326 | __IO uint8_t LTRH; /*!< ADC1 low threshold register high */ 327 | __IO uint8_t LTRL; /*!< ADC1 low threshold register low */ 328 | __IO uint8_t AWSRH; /*!< ADC1 watchdog status register high */ 329 | __IO uint8_t AWSRL; /*!< ADC1 watchdog status register low */ 330 | __IO uint8_t AWCRH; /*!< ADC1 watchdog control register high */ 331 | __IO uint8_t AWCRL; /*!< ADC1 watchdog control register low */ 332 | } 333 | ADC1_TypeDef; 334 | 335 | /** @addtogroup ADC1_Registers_Reset_Value 336 | * @{ 337 | */ 338 | #define ADC1_CSR_RESET_VALUE ((uint8_t)0x00) 339 | #define ADC1_CR1_RESET_VALUE ((uint8_t)0x00) 340 | #define ADC1_CR2_RESET_VALUE ((uint8_t)0x00) 341 | #define ADC1_CR3_RESET_VALUE ((uint8_t)0x00) 342 | #define ADC1_TDRL_RESET_VALUE ((uint8_t)0x00) 343 | #define ADC1_TDRH_RESET_VALUE ((uint8_t)0x00) 344 | #define ADC1_HTRL_RESET_VALUE ((uint8_t)0x03) 345 | #define ADC1_HTRH_RESET_VALUE ((uint8_t)0xFF) 346 | #define ADC1_LTRH_RESET_VALUE ((uint8_t)0x00) 347 | #define ADC1_LTRL_RESET_VALUE ((uint8_t)0x00) 348 | #define ADC1_AWCRH_RESET_VALUE ((uint8_t)0x00) 349 | #define ADC1_AWCRL_RESET_VALUE ((uint8_t)0x00) 350 | /** 351 | * @} 352 | */ 353 | 354 | /** @addtogroup ADC1_Registers_Bits_Definition 355 | * @{ 356 | */ 357 | #define ADC1_CSR_EOC ((uint8_t)0x80) /*!< End of Conversion mask */ 358 | #define ADC1_CSR_AWD ((uint8_t)0x40) /*!< Analog Watch Dog Status mask */ 359 | #define ADC1_CSR_EOCIE ((uint8_t)0x20) /*!< Interrupt Enable for EOC mask */ 360 | #define ADC1_CSR_AWDIE ((uint8_t)0x10) /*!< Analog Watchdog interrupt enable mask */ 361 | #define ADC1_CSR_CH ((uint8_t)0x0F) /*!< Channel selection bits mask */ 362 | 363 | #define ADC1_CR1_SPSEL ((uint8_t)0x70) /*!< Prescaler selection mask */ 364 | #define ADC1_CR1_CONT ((uint8_t)0x02) /*!< Continuous conversion mask */ 365 | #define ADC1_CR1_ADON ((uint8_t)0x01) /*!< A/D Converter on/off mask */ 366 | 367 | #define ADC1_CR2_EXTTRIG ((uint8_t)0x40) /*!< External trigger enable mask */ 368 | #define ADC1_CR2_EXTSEL ((uint8_t)0x30) /*!< External event selection mask */ 369 | #define ADC1_CR2_ALIGN ((uint8_t)0x08) /*!< Data Alignment mask */ 370 | #define ADC1_CR2_SCAN ((uint8_t)0x02) /*!< Scan mode mask */ 371 | 372 | #define ADC1_CR3_DBUF ((uint8_t)0x80) /*!< Data Buffer Enable mask */ 373 | #define ADC1_CR3_OVR ((uint8_t)0x40) /*!< Overrun Status Flag mask */ 374 | 375 | #endif /* (STM8S105) ||(STM8S103) || (STM8S005) ||(STM8S003) || (STM8S903) || (STM8AF626x) || (STM8AF622x) */ 376 | /** 377 | * @} 378 | */ 379 | 380 | /*----------------------------------------------------------------------------*/ 381 | /** 382 | * @brief Analog to Digital Converter (ADC2) 383 | */ 384 | #if defined(STM8S208) || defined(STM8S207) || defined (STM8S007) || defined (STM8AF52Ax) || defined (STM8AF62Ax) 385 | typedef struct ADC2_struct 386 | { 387 | __IO uint8_t CSR; /*!< ADC2 control status register */ 388 | __IO uint8_t CR1; /*!< ADC2 configuration register 1 */ 389 | __IO uint8_t CR2; /*!< ADC2 configuration register 2 */ 390 | uint8_t RESERVED; /*!< Reserved byte */ 391 | __IO uint8_t DRH; /*!< ADC2 Data high */ 392 | __IO uint8_t DRL; /*!< ADC2 Data low */ 393 | __IO uint8_t TDRH; /*!< ADC2 Schmitt trigger disable register high */ 394 | __IO uint8_t TDRL; /*!< ADC2 Schmitt trigger disable register low */ 395 | } 396 | ADC2_TypeDef; 397 | 398 | /** @addtogroup ADC2_Registers_Reset_Value 399 | * @{ 400 | */ 401 | #define ADC2_CSR_RESET_VALUE ((uint8_t)0x00) 402 | #define ADC2_CR1_RESET_VALUE ((uint8_t)0x00) 403 | #define ADC2_CR2_RESET_VALUE ((uint8_t)0x00) 404 | #define ADC2_TDRL_RESET_VALUE ((uint8_t)0x00) 405 | #define ADC2_TDRH_RESET_VALUE ((uint8_t)0x00) 406 | /** 407 | * @} 408 | */ 409 | 410 | /** @addtogroup ADC2_Registers_Bits_Definition 411 | * @{ 412 | */ 413 | #define ADC2_CSR_EOC ((uint8_t)0x80) /*!< End of Conversion mask */ 414 | #define ADC2_CSR_EOCIE ((uint8_t)0x20) /*!< Interrupt Enable for EOC mask */ 415 | #define ADC2_CSR_CH ((uint8_t)0x0F) /*!< Channel selection bits mask */ 416 | 417 | #define ADC2_CR1_SPSEL ((uint8_t)0x70) /*!< Prescaler selection mask */ 418 | #define ADC2_CR1_CONT ((uint8_t)0x02) /*!< Continuous conversion mask */ 419 | #define ADC2_CR1_ADON ((uint8_t)0x01) /*!< A/D Converter on/off mask */ 420 | 421 | #define ADC2_CR2_EXTTRIG ((uint8_t)0x40) /*!< External trigger enable mask */ 422 | #define ADC2_CR2_EXTSEL ((uint8_t)0x30) /*!< External event selection mask */ 423 | #define ADC2_CR2_ALIGN ((uint8_t)0x08) /*!< Data Alignment mask */ 424 | 425 | #endif /* (STM8S208) ||(STM8S207) || defined (STM8S007) || (STM8AF62Ax) || (STM8AF52Ax) */ 426 | /** 427 | * @} 428 | */ 429 | 430 | /*----------------------------------------------------------------------------*/ 431 | 432 | /** 433 | * @brief Auto Wake Up (AWU) peripheral registers. 434 | */ 435 | typedef struct AWU_struct 436 | { 437 | __IO uint8_t CSR; /*!< AWU Control status register */ 438 | __IO uint8_t APR; /*!< AWU Asynchronous prescaler buffer */ 439 | __IO uint8_t TBR; /*!< AWU Time base selection register */ 440 | } 441 | AWU_TypeDef; 442 | 443 | /** @addtogroup AWU_Registers_Reset_Value 444 | * @{ 445 | */ 446 | #define AWU_CSR_RESET_VALUE ((uint8_t)0x00) 447 | #define AWU_APR_RESET_VALUE ((uint8_t)0x3F) 448 | #define AWU_TBR_RESET_VALUE ((uint8_t)0x00) 449 | 450 | /** 451 | * @} 452 | */ 453 | 454 | /** @addtogroup AWU_Registers_Bits_Definition 455 | * @{ 456 | */ 457 | 458 | #define AWU_CSR_AWUF ((uint8_t)0x20) /*!< Interrupt flag mask */ 459 | #define AWU_CSR_AWUEN ((uint8_t)0x10) /*!< Auto Wake-up enable mask */ 460 | #define AWU_CSR_MSR ((uint8_t)0x01) /*!< LSI Measurement enable mask */ 461 | 462 | #define AWU_APR_APR ((uint8_t)0x3F) /*!< Asynchronous Prescaler divider mask */ 463 | 464 | #define AWU_TBR_AWUTB ((uint8_t)0x0F) /*!< Timebase selection mask */ 465 | 466 | /** 467 | * @} 468 | */ 469 | 470 | /*----------------------------------------------------------------------------*/ 471 | /** 472 | * @brief Beeper (BEEP) peripheral registers. 473 | */ 474 | 475 | typedef struct BEEP_struct 476 | { 477 | __IO uint8_t CSR; /*!< BEEP Control status register */ 478 | } 479 | BEEP_TypeDef; 480 | 481 | /** @addtogroup BEEP_Registers_Reset_Value 482 | * @{ 483 | */ 484 | #define BEEP_CSR_RESET_VALUE ((uint8_t)0x1F) 485 | /** 486 | * @} 487 | */ 488 | 489 | /** @addtogroup BEEP_Registers_Bits_Definition 490 | * @{ 491 | */ 492 | #define BEEP_CSR_BEEPSEL ((uint8_t)0xC0) /*!< Beeper frequency selection mask */ 493 | #define BEEP_CSR_BEEPEN ((uint8_t)0x20) /*!< Beeper enable mask */ 494 | #define BEEP_CSR_BEEPDIV ((uint8_t)0x1F) /*!< Beeper Divider prescalar mask */ 495 | /** 496 | * @} 497 | */ 498 | 499 | /*----------------------------------------------------------------------------*/ 500 | /** 501 | * @brief Clock Controller (CLK) 502 | */ 503 | typedef struct CLK_struct 504 | { 505 | __IO uint8_t ICKR; /*!< Internal Clocks Control Register */ 506 | __IO uint8_t ECKR; /*!< External Clocks Control Register */ 507 | uint8_t RESERVED; /*!< Reserved byte */ 508 | __IO uint8_t CMSR; /*!< Clock Master Status Register */ 509 | __IO uint8_t SWR; /*!< Clock Master Switch Register */ 510 | __IO uint8_t SWCR; /*!< Switch Control Register */ 511 | __IO uint8_t CKDIVR; /*!< Clock Divider Register */ 512 | __IO uint8_t PCKENR1; /*!< Peripheral Clock Gating Register 1 */ 513 | __IO uint8_t CSSR; /*!< Clock Security System Register */ 514 | __IO uint8_t CCOR; /*!< Configurable Clock Output Register */ 515 | __IO uint8_t PCKENR2; /*!< Peripheral Clock Gating Register 2 */ 516 | uint8_t RESERVED1; /*!< Reserved byte */ 517 | __IO uint8_t HSITRIMR; /*!< HSI Calibration Trimmer Register */ 518 | __IO uint8_t SWIMCCR; /*!< SWIM clock control register */ 519 | } 520 | CLK_TypeDef; 521 | 522 | /** @addtogroup CLK_Registers_Reset_Value 523 | * @{ 524 | */ 525 | 526 | #define CLK_ICKR_RESET_VALUE ((uint8_t)0x01) 527 | #define CLK_ECKR_RESET_VALUE ((uint8_t)0x00) 528 | #define CLK_CMSR_RESET_VALUE ((uint8_t)0xE1) 529 | #define CLK_SWR_RESET_VALUE ((uint8_t)0xE1) 530 | #define CLK_SWCR_RESET_VALUE ((uint8_t)0x00) 531 | #define CLK_CKDIVR_RESET_VALUE ((uint8_t)0x18) 532 | #define CLK_PCKENR1_RESET_VALUE ((uint8_t)0xFF) 533 | #define CLK_PCKENR2_RESET_VALUE ((uint8_t)0xFF) 534 | #define CLK_CSSR_RESET_VALUE ((uint8_t)0x00) 535 | #define CLK_CCOR_RESET_VALUE ((uint8_t)0x00) 536 | #define CLK_HSITRIMR_RESET_VALUE ((uint8_t)0x00) 537 | #define CLK_SWIMCCR_RESET_VALUE ((uint8_t)0x00) 538 | 539 | /** 540 | * @} 541 | */ 542 | 543 | /** @addtogroup CLK_Registers_Bits_Definition 544 | * @{ 545 | */ 546 | #define CLK_ICKR_SWUAH ((uint8_t)0x20) /*!< Slow Wake-up from Active Halt/Halt modes */ 547 | #define CLK_ICKR_LSIRDY ((uint8_t)0x10) /*!< Low speed internal oscillator ready */ 548 | #define CLK_ICKR_LSIEN ((uint8_t)0x08) /*!< Low speed internal RC oscillator enable */ 549 | #define CLK_ICKR_FHWU ((uint8_t)0x04) /*!< Fast Wake-up from Active Halt/Halt mode */ 550 | #define CLK_ICKR_HSIRDY ((uint8_t)0x02) /*!< High speed internal RC oscillator ready */ 551 | #define CLK_ICKR_HSIEN ((uint8_t)0x01) /*!< High speed internal RC oscillator enable */ 552 | 553 | #define CLK_ECKR_HSERDY ((uint8_t)0x02) /*!< High speed external crystal oscillator ready */ 554 | #define CLK_ECKR_HSEEN ((uint8_t)0x01) /*!< High speed external crystal oscillator enable */ 555 | 556 | #define CLK_CMSR_CKM ((uint8_t)0xFF) /*!< Clock master status bits */ 557 | 558 | #define CLK_SWR_SWI ((uint8_t)0xFF) /*!< Clock master selection bits */ 559 | 560 | #define CLK_SWCR_SWIF ((uint8_t)0x08) /*!< Clock switch interrupt flag */ 561 | #define CLK_SWCR_SWIEN ((uint8_t)0x04) /*!< Clock switch interrupt enable */ 562 | #define CLK_SWCR_SWEN ((uint8_t)0x02) /*!< Switch start/stop */ 563 | #define CLK_SWCR_SWBSY ((uint8_t)0x01) /*!< Switch busy flag*/ 564 | 565 | #define CLK_CKDIVR_HSIDIV ((uint8_t)0x18) /*!< High speed internal clock prescaler */ 566 | #define CLK_CKDIVR_CPUDIV ((uint8_t)0x07) /*!< CPU clock prescaler */ 567 | 568 | #define CLK_PCKENR1_TIM1 ((uint8_t)0x80) /*!< Timer 1 clock enable */ 569 | #define CLK_PCKENR1_TIM3 ((uint8_t)0x40) /*!< Timer 3 clock enable */ 570 | #define CLK_PCKENR1_TIM2 ((uint8_t)0x20) /*!< Timer 2 clock enable */ 571 | #define CLK_PCKENR1_TIM5 ((uint8_t)0x20) /*!< Timer 5 clock enable */ 572 | #define CLK_PCKENR1_TIM4 ((uint8_t)0x10) /*!< Timer 4 clock enable */ 573 | #define CLK_PCKENR1_TIM6 ((uint8_t)0x10) /*!< Timer 6 clock enable */ 574 | #define CLK_PCKENR1_UART3 ((uint8_t)0x08) /*!< UART3 clock enable */ 575 | #define CLK_PCKENR1_UART2 ((uint8_t)0x08) /*!< UART2 clock enable */ 576 | #define CLK_PCKENR1_UART1 ((uint8_t)0x04) /*!< UART1 clock enable */ 577 | #define CLK_PCKENR1_SPI ((uint8_t)0x02) /*!< SPI clock enable */ 578 | #define CLK_PCKENR1_I2C ((uint8_t)0x01) /*!< I2C clock enable */ 579 | 580 | #define CLK_PCKENR2_CAN ((uint8_t)0x80) /*!< CAN clock enable */ 581 | #define CLK_PCKENR2_ADC ((uint8_t)0x08) /*!< ADC clock enable */ 582 | #define CLK_PCKENR2_AWU ((uint8_t)0x04) /*!< AWU clock enable */ 583 | 584 | #define CLK_CSSR_CSSD ((uint8_t)0x08) /*!< Clock security system detection */ 585 | #define CLK_CSSR_CSSDIE ((uint8_t)0x04) /*!< Clock security system detection interrupt enable */ 586 | #define CLK_CSSR_AUX ((uint8_t)0x02) /*!< Auxiliary oscillator connected to master clock */ 587 | #define CLK_CSSR_CSSEN ((uint8_t)0x01) /*!< Clock security system enable */ 588 | 589 | #define CLK_CCOR_CCOBSY ((uint8_t)0x40) /*!< Configurable clock output busy */ 590 | #define CLK_CCOR_CCORDY ((uint8_t)0x20) /*!< Configurable clock output ready */ 591 | #define CLK_CCOR_CCOSEL ((uint8_t)0x1E) /*!< Configurable clock output selection */ 592 | #define CLK_CCOR_CCOEN ((uint8_t)0x01) /*!< Configurable clock output enable */ 593 | 594 | #define CLK_HSITRIMR_HSITRIM ((uint8_t)0x07) /*!< High speed internal oscillator trimmer */ 595 | 596 | #define CLK_SWIMCCR_SWIMDIV ((uint8_t)0x01) /*!< SWIM Clock Dividing Factor */ 597 | 598 | /** 599 | * @} 600 | */ 601 | 602 | /*----------------------------------------------------------------------------*/ 603 | /** 604 | * @brief 16-bit timer with complementary PWM outputs (TIM1) 605 | */ 606 | 607 | typedef struct TIM1_struct 608 | { 609 | __IO uint8_t CR1; /*!< control register 1 */ 610 | __IO uint8_t CR2; /*!< control register 2 */ 611 | __IO uint8_t SMCR; /*!< Synchro mode control register */ 612 | __IO uint8_t ETR; /*!< external trigger register */ 613 | __IO uint8_t IER; /*!< interrupt enable register*/ 614 | __IO uint8_t SR1; /*!< status register 1 */ 615 | __IO uint8_t SR2; /*!< status register 2 */ 616 | __IO uint8_t EGR; /*!< event generation register */ 617 | __IO uint8_t CCMR1; /*!< CC mode register 1 */ 618 | __IO uint8_t CCMR2; /*!< CC mode register 2 */ 619 | __IO uint8_t CCMR3; /*!< CC mode register 3 */ 620 | __IO uint8_t CCMR4; /*!< CC mode register 4 */ 621 | __IO uint8_t CCER1; /*!< CC enable register 1 */ 622 | __IO uint8_t CCER2; /*!< CC enable register 2 */ 623 | __IO uint8_t CNTRH; /*!< counter high */ 624 | __IO uint8_t CNTRL; /*!< counter low */ 625 | __IO uint8_t PSCRH; /*!< prescaler high */ 626 | __IO uint8_t PSCRL; /*!< prescaler low */ 627 | __IO uint8_t ARRH; /*!< auto-reload register high */ 628 | __IO uint8_t ARRL; /*!< auto-reload register low */ 629 | __IO uint8_t RCR; /*!< Repetition Counter register */ 630 | __IO uint8_t CCR1H; /*!< capture/compare register 1 high */ 631 | __IO uint8_t CCR1L; /*!< capture/compare register 1 low */ 632 | __IO uint8_t CCR2H; /*!< capture/compare register 2 high */ 633 | __IO uint8_t CCR2L; /*!< capture/compare register 2 low */ 634 | __IO uint8_t CCR3H; /*!< capture/compare register 3 high */ 635 | __IO uint8_t CCR3L; /*!< capture/compare register 3 low */ 636 | __IO uint8_t CCR4H; /*!< capture/compare register 3 high */ 637 | __IO uint8_t CCR4L; /*!< capture/compare register 3 low */ 638 | __IO uint8_t BKR; /*!< Break Register */ 639 | __IO uint8_t DTR; /*!< dead-time register */ 640 | __IO uint8_t OISR; /*!< Output idle register */ 641 | } 642 | TIM1_TypeDef; 643 | 644 | /** @addtogroup TIM1_Registers_Reset_Value 645 | * @{ 646 | */ 647 | 648 | #define TIM1_CR1_RESET_VALUE ((uint8_t)0x00) 649 | #define TIM1_CR2_RESET_VALUE ((uint8_t)0x00) 650 | #define TIM1_SMCR_RESET_VALUE ((uint8_t)0x00) 651 | #define TIM1_ETR_RESET_VALUE ((uint8_t)0x00) 652 | #define TIM1_IER_RESET_VALUE ((uint8_t)0x00) 653 | #define TIM1_SR1_RESET_VALUE ((uint8_t)0x00) 654 | #define TIM1_SR2_RESET_VALUE ((uint8_t)0x00) 655 | #define TIM1_EGR_RESET_VALUE ((uint8_t)0x00) 656 | #define TIM1_CCMR1_RESET_VALUE ((uint8_t)0x00) 657 | #define TIM1_CCMR2_RESET_VALUE ((uint8_t)0x00) 658 | #define TIM1_CCMR3_RESET_VALUE ((uint8_t)0x00) 659 | #define TIM1_CCMR4_RESET_VALUE ((uint8_t)0x00) 660 | #define TIM1_CCER1_RESET_VALUE ((uint8_t)0x00) 661 | #define TIM1_CCER2_RESET_VALUE ((uint8_t)0x00) 662 | #define TIM1_CNTRH_RESET_VALUE ((uint8_t)0x00) 663 | #define TIM1_CNTRL_RESET_VALUE ((uint8_t)0x00) 664 | #define TIM1_PSCRH_RESET_VALUE ((uint8_t)0x00) 665 | #define TIM1_PSCRL_RESET_VALUE ((uint8_t)0x00) 666 | #define TIM1_ARRH_RESET_VALUE ((uint8_t)0xFF) 667 | #define TIM1_ARRL_RESET_VALUE ((uint8_t)0xFF) 668 | #define TIM1_RCR_RESET_VALUE ((uint8_t)0x00) 669 | #define TIM1_CCR1H_RESET_VALUE ((uint8_t)0x00) 670 | #define TIM1_CCR1L_RESET_VALUE ((uint8_t)0x00) 671 | #define TIM1_CCR2H_RESET_VALUE ((uint8_t)0x00) 672 | #define TIM1_CCR2L_RESET_VALUE ((uint8_t)0x00) 673 | #define TIM1_CCR3H_RESET_VALUE ((uint8_t)0x00) 674 | #define TIM1_CCR3L_RESET_VALUE ((uint8_t)0x00) 675 | #define TIM1_CCR4H_RESET_VALUE ((uint8_t)0x00) 676 | #define TIM1_CCR4L_RESET_VALUE ((uint8_t)0x00) 677 | #define TIM1_BKR_RESET_VALUE ((uint8_t)0x00) 678 | #define TIM1_DTR_RESET_VALUE ((uint8_t)0x00) 679 | #define TIM1_OISR_RESET_VALUE ((uint8_t)0x00) 680 | 681 | /** 682 | * @} 683 | */ 684 | 685 | /** @addtogroup TIM1_Registers_Bits_Definition 686 | * @{ 687 | */ 688 | /* CR1*/ 689 | #define TIM1_CR1_ARPE ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */ 690 | #define TIM1_CR1_CMS ((uint8_t)0x60) /*!< Center-aligned Mode Selection mask. */ 691 | #define TIM1_CR1_DIR ((uint8_t)0x10) /*!< Direction mask. */ 692 | #define TIM1_CR1_OPM ((uint8_t)0x08) /*!< One Pulse Mode mask. */ 693 | #define TIM1_CR1_URS ((uint8_t)0x04) /*!< Update Request Source mask. */ 694 | #define TIM1_CR1_UDIS ((uint8_t)0x02) /*!< Update DIsable mask. */ 695 | #define TIM1_CR1_CEN ((uint8_t)0x01) /*!< Counter Enable mask. */ 696 | /* CR2*/ 697 | #define TIM1_CR2_TI1S ((uint8_t)0x80) /*!< TI1S Selection mask. */ 698 | #define TIM1_CR2_MMS ((uint8_t)0x70) /*!< MMS Selection mask. */ 699 | #define TIM1_CR2_COMS ((uint8_t)0x04) /*!< Capture/Compare Control Update Selection mask. */ 700 | #define TIM1_CR2_CCPC ((uint8_t)0x01) /*!< Capture/Compare Preloaded Control mask. */ 701 | /* SMCR*/ 702 | #define TIM1_SMCR_MSM ((uint8_t)0x80) /*!< Master/Slave Mode mask. */ 703 | #define TIM1_SMCR_TS ((uint8_t)0x70) /*!< Trigger Selection mask. */ 704 | #define TIM1_SMCR_SMS ((uint8_t)0x07) /*!< Slave Mode Selection mask. */ 705 | /*ETR*/ 706 | #define TIM1_ETR_ETP ((uint8_t)0x80) /*!< External Trigger Polarity mask. */ 707 | #define TIM1_ETR_ECE ((uint8_t)0x40)/*!< External Clock mask. */ 708 | #define TIM1_ETR_ETPS ((uint8_t)0x30) /*!< External Trigger Prescaler mask. */ 709 | #define TIM1_ETR_ETF ((uint8_t)0x0F) /*!< External Trigger Filter mask. */ 710 | /*IER*/ 711 | #define TIM1_IER_BIE ((uint8_t)0x80) /*!< Break Interrupt Enable mask. */ 712 | #define TIM1_IER_TIE ((uint8_t)0x40) /*!< Trigger Interrupt Enable mask. */ 713 | #define TIM1_IER_COMIE ((uint8_t)0x20) /*!< Commutation Interrupt Enable mask.*/ 714 | #define TIM1_IER_CC4IE ((uint8_t)0x10) /*!< Capture/Compare 4 Interrupt Enable mask. */ 715 | #define TIM1_IER_CC3IE ((uint8_t)0x08) /*!< Capture/Compare 3 Interrupt Enable mask. */ 716 | #define TIM1_IER_CC2IE ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Enable mask. */ 717 | #define TIM1_IER_CC1IE ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Enable mask. */ 718 | #define TIM1_IER_UIE ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */ 719 | /*SR1*/ 720 | #define TIM1_SR1_BIF ((uint8_t)0x80) /*!< Break Interrupt Flag mask. */ 721 | #define TIM1_SR1_TIF ((uint8_t)0x40) /*!< Trigger Interrupt Flag mask. */ 722 | #define TIM1_SR1_COMIF ((uint8_t)0x20) /*!< Commutation Interrupt Flag mask. */ 723 | #define TIM1_SR1_CC4IF ((uint8_t)0x10) /*!< Capture/Compare 4 Interrupt Flag mask. */ 724 | #define TIM1_SR1_CC3IF ((uint8_t)0x08) /*!< Capture/Compare 3 Interrupt Flag mask. */ 725 | #define TIM1_SR1_CC2IF ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Flag mask. */ 726 | #define TIM1_SR1_CC1IF ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Flag mask. */ 727 | #define TIM1_SR1_UIF ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */ 728 | /*SR2*/ 729 | #define TIM1_SR2_CC4OF ((uint8_t)0x10) /*!< Capture/Compare 4 Overcapture Flag mask. */ 730 | #define TIM1_SR2_CC3OF ((uint8_t)0x08) /*!< Capture/Compare 3 Overcapture Flag mask. */ 731 | #define TIM1_SR2_CC2OF ((uint8_t)0x04) /*!< Capture/Compare 2 Overcapture Flag mask. */ 732 | #define TIM1_SR2_CC1OF ((uint8_t)0x02) /*!< Capture/Compare 1 Overcapture Flag mask. */ 733 | /*EGR*/ 734 | #define TIM1_EGR_BG ((uint8_t)0x80) /*!< Break Generation mask. */ 735 | #define TIM1_EGR_TG ((uint8_t)0x40) /*!< Trigger Generation mask. */ 736 | #define TIM1_EGR_COMG ((uint8_t)0x20) /*!< Capture/Compare Control Update Generation mask. */ 737 | #define TIM1_EGR_CC4G ((uint8_t)0x10) /*!< Capture/Compare 4 Generation mask. */ 738 | #define TIM1_EGR_CC3G ((uint8_t)0x08) /*!< Capture/Compare 3 Generation mask. */ 739 | #define TIM1_EGR_CC2G ((uint8_t)0x04) /*!< Capture/Compare 2 Generation mask. */ 740 | #define TIM1_EGR_CC1G ((uint8_t)0x02) /*!< Capture/Compare 1 Generation mask. */ 741 | #define TIM1_EGR_UG ((uint8_t)0x01) /*!< Update Generation mask. */ 742 | /*CCMR*/ 743 | #define TIM1_CCMR_ICxPSC ((uint8_t)0x0C) /*!< Input Capture x Prescaler mask. */ 744 | #define TIM1_CCMR_ICxF ((uint8_t)0xF0) /*!< Input Capture x Filter mask. */ 745 | #define TIM1_CCMR_OCM ((uint8_t)0x70) /*!< Output Compare x Mode mask. */ 746 | #define TIM1_CCMR_OCxPE ((uint8_t)0x08) /*!< Output Compare x Preload Enable mask. */ 747 | #define TIM1_CCMR_OCxFE ((uint8_t)0x04) /*!< Output Compare x Fast Enable mask. */ 748 | #define TIM1_CCMR_CCxS ((uint8_t)0x03) /*!< Capture/Compare x Selection mask. */ 749 | 750 | #define CCMR_TIxDirect_Set ((uint8_t)0x01) 751 | /*CCER1*/ 752 | #define TIM1_CCER1_CC2NP ((uint8_t)0x80) /*!< Capture/Compare 2 Complementary output Polarity mask. */ 753 | #define TIM1_CCER1_CC2NE ((uint8_t)0x40) /*!< Capture/Compare 2 Complementary output enable mask. */ 754 | #define TIM1_CCER1_CC2P ((uint8_t)0x20) /*!< Capture/Compare 2 output Polarity mask. */ 755 | #define TIM1_CCER1_CC2E ((uint8_t)0x10) /*!< Capture/Compare 2 output enable mask. */ 756 | #define TIM1_CCER1_CC1NP ((uint8_t)0x08) /*!< Capture/Compare 1 Complementary output Polarity mask. */ 757 | #define TIM1_CCER1_CC1NE ((uint8_t)0x04) /*!< Capture/Compare 1 Complementary output enable mask. */ 758 | #define TIM1_CCER1_CC1P ((uint8_t)0x02) /*!< Capture/Compare 1 output Polarity mask. */ 759 | #define TIM1_CCER1_CC1E ((uint8_t)0x01) /*!< Capture/Compare 1 output enable mask. */ 760 | /*CCER2*/ 761 | #define TIM1_CCER2_CC4P ((uint8_t)0x20) /*!< Capture/Compare 4 output Polarity mask. */ 762 | #define TIM1_CCER2_CC4E ((uint8_t)0x10) /*!< Capture/Compare 4 output enable mask. */ 763 | #define TIM1_CCER2_CC3NP ((uint8_t)0x08) /*!< Capture/Compare 3 Complementary output Polarity mask. */ 764 | #define TIM1_CCER2_CC3NE ((uint8_t)0x04) /*!< Capture/Compare 3 Complementary output enable mask. */ 765 | #define TIM1_CCER2_CC3P ((uint8_t)0x02) /*!< Capture/Compare 3 output Polarity mask. */ 766 | #define TIM1_CCER2_CC3E ((uint8_t)0x01) /*!< Capture/Compare 3 output enable mask. */ 767 | /*CNTRH*/ 768 | #define TIM1_CNTRH_CNT ((uint8_t)0xFF) /*!< Counter Value (MSB) mask. */ 769 | /*CNTRL*/ 770 | #define TIM1_CNTRL_CNT ((uint8_t)0xFF) /*!< Counter Value (LSB) mask. */ 771 | /*PSCH*/ 772 | #define TIM1_PSCH_PSC ((uint8_t)0xFF) /*!< Prescaler Value (MSB) mask. */ 773 | /*PSCL*/ 774 | #define TIM1_PSCL_PSC ((uint8_t)0xFF) /*!< Prescaler Value (LSB) mask. */ 775 | /*ARR*/ 776 | #define TIM1_ARRH_ARR ((uint8_t)0xFF) /*!< Autoreload Value (MSB) mask. */ 777 | #define TIM1_ARRL_ARR ((uint8_t)0xFF) /*!< Autoreload Value (LSB) mask. */ 778 | /*RCR*/ 779 | #define TIM1_RCR_REP ((uint8_t)0xFF) /*!< Repetition Counter Value mask. */ 780 | /*CCR1*/ 781 | #define TIM1_CCR1H_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (MSB) mask. */ 782 | #define TIM1_CCR1L_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (LSB) mask. */ 783 | /*CCR2*/ 784 | #define TIM1_CCR2H_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (MSB) mask. */ 785 | #define TIM1_CCR2L_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (LSB) mask. */ 786 | /*CCR3*/ 787 | #define TIM1_CCR3H_CCR3 ((uint8_t)0xFF) /*!< Capture/Compare 3 Value (MSB) mask. */ 788 | #define TIM1_CCR3L_CCR3 ((uint8_t)0xFF) /*!< Capture/Compare 3 Value (LSB) mask. */ 789 | /*CCR4*/ 790 | #define TIM1_CCR4H_CCR4 ((uint8_t)0xFF) /*!< Capture/Compare 4 Value (MSB) mask. */ 791 | #define TIM1_CCR4L_CCR4 ((uint8_t)0xFF) /*!< Capture/Compare 4 Value (LSB) mask. */ 792 | /*BKR*/ 793 | #define TIM1_BKR_MOE ((uint8_t)0x80) /*!< Main Output Enable mask. */ 794 | #define TIM1_BKR_AOE ((uint8_t)0x40) /*!< Automatic Output Enable mask. */ 795 | #define TIM1_BKR_BKP ((uint8_t)0x20) /*!< Break Polarity mask. */ 796 | #define TIM1_BKR_BKE ((uint8_t)0x10) /*!< Break Enable mask. */ 797 | #define TIM1_BKR_OSSR ((uint8_t)0x08) /*!< Off-State Selection for Run mode mask. */ 798 | #define TIM1_BKR_OSSI ((uint8_t)0x04) /*!< Off-State Selection for Idle mode mask. */ 799 | #define TIM1_BKR_LOCK ((uint8_t)0x03) /*!< Lock Configuration mask. */ 800 | /*DTR*/ 801 | #define TIM1_DTR_DTG ((uint8_t)0xFF) /*!< Dead-Time Generator set-up mask. */ 802 | /*OISR*/ 803 | #define TIM1_OISR_OIS4 ((uint8_t)0x40) /*!< Output Idle state 4 (OC4 output) mask. */ 804 | #define TIM1_OISR_OIS3N ((uint8_t)0x20) /*!< Output Idle state 3 (OC3N output) mask. */ 805 | #define TIM1_OISR_OIS3 ((uint8_t)0x10) /*!< Output Idle state 3 (OC3 output) mask. */ 806 | #define TIM1_OISR_OIS2N ((uint8_t)0x08) /*!< Output Idle state 2 (OC2N output) mask. */ 807 | #define TIM1_OISR_OIS2 ((uint8_t)0x04) /*!< Output Idle state 2 (OC2 output) mask. */ 808 | #define TIM1_OISR_OIS1N ((uint8_t)0x02) /*!< Output Idle state 1 (OC1N output) mask. */ 809 | #define TIM1_OISR_OIS1 ((uint8_t)0x01) /*!< Output Idle state 1 (OC1 output) mask. */ 810 | /** 811 | * @} 812 | */ 813 | 814 | /*----------------------------------------------------------------------------*/ 815 | /** 816 | * @brief 16-bit timer (TIM2) 817 | */ 818 | 819 | typedef struct TIM2_struct 820 | { 821 | __IO uint8_t CR1; /*!< control register 1 */ 822 | #if defined(STM8S103) || defined(STM8S003) 823 | uint8_t RESERVED1; /*!< Reserved register */ 824 | uint8_t RESERVED2; /*!< Reserved register */ 825 | #endif 826 | __IO uint8_t IER; /*!< interrupt enable register */ 827 | __IO uint8_t SR1; /*!< status register 1 */ 828 | __IO uint8_t SR2; /*!< status register 2 */ 829 | __IO uint8_t EGR; /*!< event generation register */ 830 | __IO uint8_t CCMR1; /*!< CC mode register 1 */ 831 | __IO uint8_t CCMR2; /*!< CC mode register 2 */ 832 | __IO uint8_t CCMR3; /*!< CC mode register 3 */ 833 | __IO uint8_t CCER1; /*!< CC enable register 1 */ 834 | __IO uint8_t CCER2; /*!< CC enable register 2 */ 835 | __IO uint8_t CNTRH; /*!< counter high */ 836 | __IO uint8_t CNTRL; /*!< counter low */ 837 | __IO uint8_t PSCR; /*!< prescaler register */ 838 | __IO uint8_t ARRH; /*!< auto-reload register high */ 839 | __IO uint8_t ARRL; /*!< auto-reload register low */ 840 | __IO uint8_t CCR1H; /*!< capture/compare register 1 high */ 841 | __IO uint8_t CCR1L; /*!< capture/compare register 1 low */ 842 | __IO uint8_t CCR2H; /*!< capture/compare register 2 high */ 843 | __IO uint8_t CCR2L; /*!< capture/compare register 2 low */ 844 | __IO uint8_t CCR3H; /*!< capture/compare register 3 high */ 845 | __IO uint8_t CCR3L; /*!< capture/compare register 3 low */ 846 | } 847 | TIM2_TypeDef; 848 | 849 | /** @addtogroup TIM2_Registers_Reset_Value 850 | * @{ 851 | */ 852 | 853 | #define TIM2_CR1_RESET_VALUE ((uint8_t)0x00) 854 | #define TIM2_IER_RESET_VALUE ((uint8_t)0x00) 855 | #define TIM2_SR1_RESET_VALUE ((uint8_t)0x00) 856 | #define TIM2_SR2_RESET_VALUE ((uint8_t)0x00) 857 | #define TIM2_EGR_RESET_VALUE ((uint8_t)0x00) 858 | #define TIM2_CCMR1_RESET_VALUE ((uint8_t)0x00) 859 | #define TIM2_CCMR2_RESET_VALUE ((uint8_t)0x00) 860 | #define TIM2_CCMR3_RESET_VALUE ((uint8_t)0x00) 861 | #define TIM2_CCER1_RESET_VALUE ((uint8_t)0x00) 862 | #define TIM2_CCER2_RESET_VALUE ((uint8_t)0x00) 863 | #define TIM2_CNTRH_RESET_VALUE ((uint8_t)0x00) 864 | #define TIM2_CNTRL_RESET_VALUE ((uint8_t)0x00) 865 | #define TIM2_PSCR_RESET_VALUE ((uint8_t)0x00) 866 | #define TIM2_ARRH_RESET_VALUE ((uint8_t)0xFF) 867 | #define TIM2_ARRL_RESET_VALUE ((uint8_t)0xFF) 868 | #define TIM2_CCR1H_RESET_VALUE ((uint8_t)0x00) 869 | #define TIM2_CCR1L_RESET_VALUE ((uint8_t)0x00) 870 | #define TIM2_CCR2H_RESET_VALUE ((uint8_t)0x00) 871 | #define TIM2_CCR2L_RESET_VALUE ((uint8_t)0x00) 872 | #define TIM2_CCR3H_RESET_VALUE ((uint8_t)0x00) 873 | #define TIM2_CCR3L_RESET_VALUE ((uint8_t)0x00) 874 | 875 | /** 876 | * @} 877 | */ 878 | 879 | /** @addtogroup TIM2_Registers_Bits_Definition 880 | * @{ 881 | */ 882 | /*CR1*/ 883 | #define TIM2_CR1_ARPE ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */ 884 | #define TIM2_CR1_OPM ((uint8_t)0x08) /*!< One Pulse Mode mask. */ 885 | #define TIM2_CR1_URS ((uint8_t)0x04) /*!< Update Request Source mask. */ 886 | #define TIM2_CR1_UDIS ((uint8_t)0x02) /*!< Update DIsable mask. */ 887 | #define TIM2_CR1_CEN ((uint8_t)0x01) /*!< Counter Enable mask. */ 888 | /*IER*/ 889 | #define TIM2_IER_CC3IE ((uint8_t)0x08) /*!< Capture/Compare 3 Interrupt Enable mask. */ 890 | #define TIM2_IER_CC2IE ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Enable mask. */ 891 | #define TIM2_IER_CC1IE ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Enable mask. */ 892 | #define TIM2_IER_UIE ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */ 893 | /*SR1*/ 894 | #define TIM2_SR1_CC3IF ((uint8_t)0x08) /*!< Capture/Compare 3 Interrupt Flag mask. */ 895 | #define TIM2_SR1_CC2IF ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Flag mask. */ 896 | #define TIM2_SR1_CC1IF ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Flag mask. */ 897 | #define TIM2_SR1_UIF ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */ 898 | /*SR2*/ 899 | #define TIM2_SR2_CC3OF ((uint8_t)0x08) /*!< Capture/Compare 3 Overcapture Flag mask. */ 900 | #define TIM2_SR2_CC2OF ((uint8_t)0x04) /*!< Capture/Compare 2 Overcapture Flag mask. */ 901 | #define TIM2_SR2_CC1OF ((uint8_t)0x02) /*!< Capture/Compare 1 Overcapture Flag mask. */ 902 | /*EGR*/ 903 | #define TIM2_EGR_CC3G ((uint8_t)0x08) /*!< Capture/Compare 3 Generation mask. */ 904 | #define TIM2_EGR_CC2G ((uint8_t)0x04) /*!< Capture/Compare 2 Generation mask. */ 905 | #define TIM2_EGR_CC1G ((uint8_t)0x02) /*!< Capture/Compare 1 Generation mask. */ 906 | #define TIM2_EGR_UG ((uint8_t)0x01) /*!< Update Generation mask. */ 907 | /*CCMR*/ 908 | #define TIM2_CCMR_ICxPSC ((uint8_t)0x0C) /*!< Input Capture x Prescaler mask. */ 909 | #define TIM2_CCMR_ICxF ((uint8_t)0xF0) /*!< Input Capture x Filter mask. */ 910 | #define TIM2_CCMR_OCM ((uint8_t)0x70) /*!< Output Compare x Mode mask. */ 911 | #define TIM2_CCMR_OCxPE ((uint8_t)0x08) /*!< Output Compare x Preload Enable mask. */ 912 | #define TIM2_CCMR_CCxS ((uint8_t)0x03) /*!< Capture/Compare x Selection mask. */ 913 | /*CCER1*/ 914 | #define TIM2_CCER1_CC2P ((uint8_t)0x20) /*!< Capture/Compare 2 output Polarity mask. */ 915 | #define TIM2_CCER1_CC2E ((uint8_t)0x10) /*!< Capture/Compare 2 output enable mask. */ 916 | #define TIM2_CCER1_CC1P ((uint8_t)0x02) /*!< Capture/Compare 1 output Polarity mask. */ 917 | #define TIM2_CCER1_CC1E ((uint8_t)0x01) /*!< Capture/Compare 1 output enable mask. */ 918 | /*CCER2*/ 919 | #define TIM2_CCER2_CC3P ((uint8_t)0x02) /*!< Capture/Compare 3 output Polarity mask. */ 920 | #define TIM2_CCER2_CC3E ((uint8_t)0x01) /*!< Capture/Compare 3 output enable mask. */ 921 | /*CNTR*/ 922 | #define TIM2_CNTRH_CNT ((uint8_t)0xFF) /*!< Counter Value (MSB) mask. */ 923 | #define TIM2_CNTRL_CNT ((uint8_t)0xFF) /*!< Counter Value (LSB) mask. */ 924 | /*PSCR*/ 925 | #define TIM2_PSCR_PSC ((uint8_t)0xFF) /*!< Prescaler Value (MSB) mask. */ 926 | /*ARR*/ 927 | #define TIM2_ARRH_ARR ((uint8_t)0xFF) /*!< Autoreload Value (MSB) mask. */ 928 | #define TIM2_ARRL_ARR ((uint8_t)0xFF) /*!< Autoreload Value (LSB) mask. */ 929 | /*CCR1*/ 930 | #define TIM2_CCR1H_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (MSB) mask. */ 931 | #define TIM2_CCR1L_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (LSB) mask. */ 932 | /*CCR2*/ 933 | #define TIM2_CCR2H_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (MSB) mask. */ 934 | #define TIM2_CCR2L_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (LSB) mask. */ 935 | /*CCR3*/ 936 | #define TIM2_CCR3H_CCR3 ((uint8_t)0xFF) /*!< Capture/Compare 3 Value (MSB) mask. */ 937 | #define TIM2_CCR3L_CCR3 ((uint8_t)0xFF) /*!< Capture/Compare 3 Value (LSB) mask. */ 938 | 939 | /** 940 | * @} 941 | */ 942 | 943 | /*----------------------------------------------------------------------------*/ 944 | /** 945 | * @brief 16-bit timer (TIM3) 946 | */ 947 | typedef struct TIM3_struct 948 | { 949 | __IO uint8_t CR1; /*!< control register 1 */ 950 | __IO uint8_t IER; /*!< interrupt enable register */ 951 | __IO uint8_t SR1; /*!< status register 1 */ 952 | __IO uint8_t SR2; /*!< status register 2 */ 953 | __IO uint8_t EGR; /*!< event generation register */ 954 | __IO uint8_t CCMR1; /*!< CC mode register 1 */ 955 | __IO uint8_t CCMR2; /*!< CC mode register 2 */ 956 | __IO uint8_t CCER1; /*!< CC enable register 1 */ 957 | __IO uint8_t CNTRH; /*!< counter high */ 958 | __IO uint8_t CNTRL; /*!< counter low */ 959 | __IO uint8_t PSCR; /*!< prescaler register */ 960 | __IO uint8_t ARRH; /*!< auto-reload register high */ 961 | __IO uint8_t ARRL; /*!< auto-reload register low */ 962 | __IO uint8_t CCR1H; /*!< capture/compare register 1 high */ 963 | __IO uint8_t CCR1L; /*!< capture/compare register 1 low */ 964 | __IO uint8_t CCR2H; /*!< capture/compare register 2 high */ 965 | __IO uint8_t CCR2L; /*!< capture/compare register 2 low */ 966 | } 967 | TIM3_TypeDef; 968 | 969 | /** @addtogroup TIM3_Registers_Reset_Value 970 | * @{ 971 | */ 972 | 973 | #define TIM3_CR1_RESET_VALUE ((uint8_t)0x00) 974 | #define TIM3_IER_RESET_VALUE ((uint8_t)0x00) 975 | #define TIM3_SR1_RESET_VALUE ((uint8_t)0x00) 976 | #define TIM3_SR2_RESET_VALUE ((uint8_t)0x00) 977 | #define TIM3_EGR_RESET_VALUE ((uint8_t)0x00) 978 | #define TIM3_CCMR1_RESET_VALUE ((uint8_t)0x00) 979 | #define TIM3_CCMR2_RESET_VALUE ((uint8_t)0x00) 980 | #define TIM3_CCER1_RESET_VALUE ((uint8_t)0x00) 981 | #define TIM3_CNTRH_RESET_VALUE ((uint8_t)0x00) 982 | #define TIM3_CNTRL_RESET_VALUE ((uint8_t)0x00) 983 | #define TIM3_PSCR_RESET_VALUE ((uint8_t)0x00) 984 | #define TIM3_ARRH_RESET_VALUE ((uint8_t)0xFF) 985 | #define TIM3_ARRL_RESET_VALUE ((uint8_t)0xFF) 986 | #define TIM3_CCR1H_RESET_VALUE ((uint8_t)0x00) 987 | #define TIM3_CCR1L_RESET_VALUE ((uint8_t)0x00) 988 | #define TIM3_CCR2H_RESET_VALUE ((uint8_t)0x00) 989 | #define TIM3_CCR2L_RESET_VALUE ((uint8_t)0x00) 990 | 991 | /** 992 | * @} 993 | */ 994 | 995 | /** @addtogroup TIM3_Registers_Bits_Definition 996 | * @{ 997 | */ 998 | /*CR1*/ 999 | #define TIM3_CR1_ARPE ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */ 1000 | #define TIM3_CR1_OPM ((uint8_t)0x08) /*!< One Pulse Mode mask. */ 1001 | #define TIM3_CR1_URS ((uint8_t)0x04) /*!< Update Request Source mask. */ 1002 | #define TIM3_CR1_UDIS ((uint8_t)0x02) /*!< Update DIsable mask. */ 1003 | #define TIM3_CR1_CEN ((uint8_t)0x01) /*!< Counter Enable mask. */ 1004 | /*IER*/ 1005 | #define TIM3_IER_CC2IE ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Enable mask. */ 1006 | #define TIM3_IER_CC1IE ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Enable mask. */ 1007 | #define TIM3_IER_UIE ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */ 1008 | /*SR1*/ 1009 | #define TIM3_SR1_CC2IF ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Flag mask. */ 1010 | #define TIM3_SR1_CC1IF ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Flag mask. */ 1011 | #define TIM3_SR1_UIF ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */ 1012 | /*SR2*/ 1013 | #define TIM3_SR2_CC2OF ((uint8_t)0x04) /*!< Capture/Compare 2 Overcapture Flag mask. */ 1014 | #define TIM3_SR2_CC1OF ((uint8_t)0x02) /*!< Capture/Compare 1 Overcapture Flag mask. */ 1015 | /*EGR*/ 1016 | #define TIM3_EGR_CC2G ((uint8_t)0x04) /*!< Capture/Compare 2 Generation mask. */ 1017 | #define TIM3_EGR_CC1G ((uint8_t)0x02) /*!< Capture/Compare 1 Generation mask. */ 1018 | #define TIM3_EGR_UG ((uint8_t)0x01) /*!< Update Generation mask. */ 1019 | /*CCMR*/ 1020 | #define TIM3_CCMR_ICxPSC ((uint8_t)0x0C) /*!< Input Capture x Prescaler mask. */ 1021 | #define TIM3_CCMR_ICxF ((uint8_t)0xF0) /*!< Input Capture x Filter mask. */ 1022 | #define TIM3_CCMR_OCM ((uint8_t)0x70) /*!< Output Compare x Mode mask. */ 1023 | #define TIM3_CCMR_OCxPE ((uint8_t)0x08) /*!< Output Compare x Preload Enable mask. */ 1024 | #define TIM3_CCMR_CCxS ((uint8_t)0x03) /*!< Capture/Compare x Selection mask. */ 1025 | /*CCER1*/ 1026 | #define TIM3_CCER1_CC2P ((uint8_t)0x20) /*!< Capture/Compare 2 output Polarity mask. */ 1027 | #define TIM3_CCER1_CC2E ((uint8_t)0x10) /*!< Capture/Compare 2 output enable mask. */ 1028 | #define TIM3_CCER1_CC1P ((uint8_t)0x02) /*!< Capture/Compare 1 output Polarity mask. */ 1029 | #define TIM3_CCER1_CC1E ((uint8_t)0x01) /*!< Capture/Compare 1 output enable mask. */ 1030 | /*CNTR*/ 1031 | #define TIM3_CNTRH_CNT ((uint8_t)0xFF) /*!< Counter Value (MSB) mask. */ 1032 | #define TIM3_CNTRL_CNT ((uint8_t)0xFF) /*!< Counter Value (LSB) mask. */ 1033 | /*PSCR*/ 1034 | #define TIM3_PSCR_PSC ((uint8_t)0xFF) /*!< Prescaler Value (MSB) mask. */ 1035 | /*ARR*/ 1036 | #define TIM3_ARRH_ARR ((uint8_t)0xFF) /*!< Autoreload Value (MSB) mask. */ 1037 | #define TIM3_ARRL_ARR ((uint8_t)0xFF) /*!< Autoreload Value (LSB) mask. */ 1038 | /*CCR1*/ 1039 | #define TIM3_CCR1H_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (MSB) mask. */ 1040 | #define TIM3_CCR1L_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (LSB) mask. */ 1041 | /*CCR2*/ 1042 | #define TIM3_CCR2H_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (MSB) mask. */ 1043 | #define TIM3_CCR2L_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (LSB) mask. */ 1044 | /** 1045 | * @} 1046 | */ 1047 | 1048 | /*----------------------------------------------------------------------------*/ 1049 | /** 1050 | * @brief 8-bit system timer (TIM4) 1051 | */ 1052 | 1053 | typedef struct TIM4_struct 1054 | { 1055 | __IO uint8_t CR1; /*!< control register 1 */ 1056 | #if defined(STM8S103) || defined(STM8S003) 1057 | uint8_t RESERVED1; /*!< Reserved register */ 1058 | uint8_t RESERVED2; /*!< Reserved register */ 1059 | #endif 1060 | __IO uint8_t IER; /*!< interrupt enable register */ 1061 | __IO uint8_t SR1; /*!< status register 1 */ 1062 | __IO uint8_t EGR; /*!< event generation register */ 1063 | __IO uint8_t CNTR; /*!< counter register */ 1064 | __IO uint8_t PSCR; /*!< prescaler register */ 1065 | __IO uint8_t ARR; /*!< auto-reload register */ 1066 | } 1067 | TIM4_TypeDef; 1068 | 1069 | /** @addtogroup TIM4_Registers_Reset_Value 1070 | * @{ 1071 | */ 1072 | 1073 | #define TIM4_CR1_RESET_VALUE ((uint8_t)0x00) 1074 | #define TIM4_IER_RESET_VALUE ((uint8_t)0x00) 1075 | #define TIM4_SR1_RESET_VALUE ((uint8_t)0x00) 1076 | #define TIM4_EGR_RESET_VALUE ((uint8_t)0x00) 1077 | #define TIM4_CNTR_RESET_VALUE ((uint8_t)0x00) 1078 | #define TIM4_PSCR_RESET_VALUE ((uint8_t)0x00) 1079 | #define TIM4_ARR_RESET_VALUE ((uint8_t)0xFF) 1080 | 1081 | /** 1082 | * @} 1083 | */ 1084 | 1085 | /** @addtogroup TIM4_Registers_Bits_Definition 1086 | * @{ 1087 | */ 1088 | /*CR1*/ 1089 | #define TIM4_CR1_ARPE ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */ 1090 | #define TIM4_CR1_OPM ((uint8_t)0x08) /*!< One Pulse Mode mask. */ 1091 | #define TIM4_CR1_URS ((uint8_t)0x04) /*!< Update Request Source mask. */ 1092 | #define TIM4_CR1_UDIS ((uint8_t)0x02) /*!< Update DIsable mask. */ 1093 | #define TIM4_CR1_CEN ((uint8_t)0x01) /*!< Counter Enable mask. */ 1094 | /*IER*/ 1095 | #define TIM4_IER_UIE ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */ 1096 | /*SR1*/ 1097 | #define TIM4_SR1_UIF ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */ 1098 | /*EGR*/ 1099 | #define TIM4_EGR_UG ((uint8_t)0x01) /*!< Update Generation mask. */ 1100 | /*CNTR*/ 1101 | #define TIM4_CNTR_CNT ((uint8_t)0xFF) /*!< Counter Value (LSB) mask. */ 1102 | /*PSCR*/ 1103 | #define TIM4_PSCR_PSC ((uint8_t)0x07) /*!< Prescaler Value mask. */ 1104 | /*ARR*/ 1105 | #define TIM4_ARR_ARR ((uint8_t)0xFF) /*!< Autoreload Value mask. */ 1106 | 1107 | /** 1108 | * @} 1109 | */ 1110 | 1111 | /*----------------------------------------------------------------------------*/ 1112 | /** 1113 | * @brief 16-bit timer with synchro module (TIM5) 1114 | */ 1115 | 1116 | typedef struct TIM5_struct 1117 | { 1118 | __IO uint8_t CR1; /*! 2715 | #define enableInterrupts() _rim_() /* enable interrupts */ 2716 | #define disableInterrupts() _sim_() /* disable interrupts */ 2717 | #define rim() _rim_() /* enable interrupts */ 2718 | #define sim() _sim_() /* disable interrupts */ 2719 | #define nop() _nop_() /* No Operation */ 2720 | #define trap() _trap_() /* Trap (soft IT) */ 2721 | #define wfi() _wfi_() /* Wait For Interrupt */ 2722 | #define halt() _halt_() /* Halt */ 2723 | #elif defined(_COSMIC_) 2724 | #define enableInterrupts() {_asm("rim\n");} /* enable interrupts */ 2725 | #define disableInterrupts() {_asm("sim\n");} /* disable interrupts */ 2726 | #define rim() {_asm("rim\n");} /* enable interrupts */ 2727 | #define sim() {_asm("sim\n");} /* disable interrupts */ 2728 | #define nop() {_asm("nop\n");} /* No Operation */ 2729 | #define trap() {_asm("trap\n");} /* Trap (soft IT) */ 2730 | #define wfi() {_asm("wfi\n");} /* Wait For Interrupt */ 2731 | #define halt() {_asm("halt\n");} /* Halt */ 2732 | #else /*_IAR_*/ 2733 | #include 2734 | #define enableInterrupts() __enable_interrupt() /* enable interrupts */ 2735 | #define disableInterrupts() __disable_interrupt() /* disable interrupts */ 2736 | #define rim() __enable_interrupt() /* enable interrupts */ 2737 | #define sim() __disable_interrupt() /* disable interrupts */ 2738 | #define nop() __no_operation() /* No Operation */ 2739 | #define trap() __trap() /* Trap (soft IT) */ 2740 | #define wfi() __wait_for_interrupt() /* Wait For Interrupt */ 2741 | #define halt() __halt() /* Halt */ 2742 | #endif /*_RAISONANCE_*/ 2743 | 2744 | /*============================== Interrupt vector Handling ========================*/ 2745 | 2746 | #ifdef _COSMIC_ 2747 | #define INTERRUPT_HANDLER(a,b) @far @interrupt void a(void) 2748 | #define INTERRUPT_HANDLER_TRAP(a) void @far @interrupt a(void) 2749 | #endif /* _COSMIC_ */ 2750 | 2751 | #ifdef _RAISONANCE_ 2752 | #define INTERRUPT_HANDLER(a,b) void a(void) interrupt b 2753 | #define INTERRUPT_HANDLER_TRAP(a) void a(void) trap 2754 | #endif /* _RAISONANCE_ */ 2755 | 2756 | #ifdef _IAR_ 2757 | #define STRINGVECTOR(x) #x 2758 | #define VECTOR_ID(x) STRINGVECTOR( vector = (x) ) 2759 | #define INTERRUPT_HANDLER( a, b ) \ 2760 | _Pragma( VECTOR_ID( (b)+2 ) ) \ 2761 | __interrupt void (a)( void ) 2762 | #define INTERRUPT_HANDLER_TRAP(a) \ 2763 | _Pragma( VECTOR_ID( 1 ) ) \ 2764 | __interrupt void (a) (void) 2765 | #endif /* _IAR_ */ 2766 | 2767 | /*============================== Interrupt Handler declaration ========================*/ 2768 | #ifdef _COSMIC_ 2769 | #define INTERRUPT @far @interrupt 2770 | #elif defined(_IAR_) 2771 | #define INTERRUPT __interrupt 2772 | #endif /* _COSMIC_ */ 2773 | 2774 | /*============================== Handling bits ====================================*/ 2775 | /*----------------------------------------------------------------------------- 2776 | Method : I 2777 | Description : Handle the bit from the character variables. 2778 | Comments : The different parameters of commands are 2779 | - VAR : Name of the character variable where the bit is located. 2780 | - Place : Bit position in the variable (7 6 5 4 3 2 1 0) 2781 | - Value : Can be 0 (reset bit) or not 0 (set bit) 2782 | The "MskBit" command allows to select some bits in a source 2783 | variables and copy it in a destination var (return the value). 2784 | The "ValBit" command returns the value of a bit in a char 2785 | variable: the bit is reset if it returns 0 else the bit is set. 2786 | This method generates not an optimised code yet. 2787 | -----------------------------------------------------------------------------*/ 2788 | #define SetBit(VAR,Place) ( (VAR) |= (uint8_t)((uint8_t)1<<(uint8_t)(Place)) ) 2789 | #define ClrBit(VAR,Place) ( (VAR) &= (uint8_t)((uint8_t)((uint8_t)1<<(uint8_t)(Place))^(uint8_t)255) ) 2790 | 2791 | #define ChgBit(VAR,Place) ( (VAR) ^= (uint8_t)((uint8_t)1<<(uint8_t)(Place)) ) 2792 | #define AffBit(VAR,Place,Value) ((Value) ? \ 2793 | ((VAR) |= ((uint8_t)1<<(Place))) : \ 2794 | ((VAR) &= (((uint8_t)1<<(Place))^(uint8_t)255))) 2795 | #define MskBit(Dest,Msk,Src) ( (Dest) = ((Msk) & (Src)) | ((~(Msk)) & (Dest)) ) 2796 | 2797 | #define ValBit(VAR,Place) ((uint8_t)(VAR) & (uint8_t)((uint8_t)1<<(uint8_t)(Place))) 2798 | 2799 | #define BYTE_0(n) ((uint8_t)((n) & (uint8_t)0xFF)) /*!< Returns the low byte of the 32-bit value */ 2800 | #define BYTE_1(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)8))) /*!< Returns the second byte of the 32-bit value */ 2801 | #define BYTE_2(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)16))) /*!< Returns the third byte of the 32-bit value */ 2802 | #define BYTE_3(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)24))) /*!< Returns the high byte of the 32-bit value */ 2803 | 2804 | /*============================== Assert Macros ====================================*/ 2805 | #define IS_STATE_VALUE_OK(SensitivityValue) \ 2806 | (((SensitivityValue) == ENABLE) || \ 2807 | ((SensitivityValue) == DISABLE)) 2808 | 2809 | /*----------------------------------------------------------------------------- 2810 | Method : II 2811 | Description : Handle directly the bit. 2812 | Comments : The idea is to handle directly with the bit name. For that, it is 2813 | necessary to have RAM area descriptions (example: HW register...) 2814 | and the following command line for each area. 2815 | This method generates the most optimized code. 2816 | -----------------------------------------------------------------------------*/ 2817 | 2818 | #define AREA 0x00 /* The area of bits begins at address 0x10. */ 2819 | 2820 | #define BitClr(BIT) ( *((unsigned char *) (AREA+(BIT)/8)) &= (~(1<<(7-(BIT)%8))) ) 2821 | #define BitSet(BIT) ( *((unsigned char *) (AREA+(BIT)/8)) |= (1<<(7-(BIT)%8)) ) 2822 | #define BitVal(BIT) ( *((unsigned char *) (AREA+(BIT)/8)) & (1<<(7-(BIT)%8)) ) 2823 | 2824 | /* Exported functions ------------------------------------------------------- */ 2825 | 2826 | #endif /* __STM8S_H */ 2827 | 2828 | /** 2829 | * @} 2830 | */ 2831 | 2832 | /** 2833 | * @} 2834 | */ 2835 | 2836 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 2837 | -------------------------------------------------------------------------------- /stm8sduino.c: -------------------------------------------------------------------------------- 1 | #include "stm8sduino.h" //we use aruidno port for stm8s 2 | 3 | //global definitions 4 | //struct used to map a pin to GPIO+mask 5 | typedef struct { 6 | volatile GPIO_TypeDef *gpio; //gpio for a pin 7 | uint8_t mask; //pin mask - 8bit 8 | } PIN2GPIO; 9 | 10 | #define PWM_PR ((1ul<SR1 &=~(1<<0); //TIM4_SR_UIF=0; //clear the flag 75 | timer_ticks+=0x100ul; //increase timer_ticks = 8-bit timer/counter + 1:1 prescaler 76 | } 77 | 78 | //user-supplied code prototype 79 | extern void setup(void); //user set-up 80 | extern void loop(void); //user loop 81 | 82 | //define your chips here 83 | //declare pins based on chip packaging 84 | 85 | //STM8S pin defs for all packaging 86 | //F: TSSOP20pin - 003F, 103f, 903f 87 | //K: LQFP32pin - 003k, 005k, 103k, 105k, 207k 88 | //S: LQFP44pin - 105s, 207s 89 | //C: LQFP48pin - 005c, 007c, 105c, 207c, 208c 90 | //R: LQFP64pin - 207r, 208r 91 | //M: LQFP80pin - 207m 92 | // 93 | //ALL PINS ARE MAPPED, WHETHER THEY EXIST OR NOT 94 | //SO MAKE SURE THAT THE PINS YOU PICKED ACTUALLY EXIST FOR YOUR PACKAGE 95 | //Pin 0.. 7 -> GPIOA 96 | //Pin 8..15 -> GPIOB 97 | //Pin 16..23 -> GPIOC 98 | //Pin 24..31 -> GPIOD 99 | //Pin 32..39 -> GPIOE 100 | //Pin 40..47 -> GPIOF 101 | //Pin 48..55 -> GPIOG 102 | //Pin 56..63 -> GPIOH 103 | //Pin 64..71 -> GPIOI 104 | const PIN2GPIO GPIO_PinDef[]={ 105 | {GPIOA, 1<<0}, //STM8Sduino Pin 0 = PA0 106 | {GPIOA, 1<<1}, //GPIOA1 = OSCI 107 | {GPIOA, 1<<2}, //GPIOA2 = OSCO 108 | {GPIOA, 1<<3}, //STM8Sduino Pin 3 = PA3 TIM2/CH3 109 | {GPIOA, 1<<4}, //STM8Sduino Pin 4 = PA4 110 | {GPIOA, 1<<5}, //STM8Sduino Pin 5 = PA5 111 | {GPIOA, 1<<6}, //STM8Sduino Pin 6 = PA6 112 | {GPIOA, 1<<7}, //STM8Sduino Pin 7 = PA7 113 | 114 | {GPIOB, 1<<0}, //STM8Sduino Pin 8 = PB0 AIN0 115 | {GPIOB, 1<<1}, //STM8Sduino Pin 9 = PB1 AIN1 116 | {GPIOB, 1<<2}, //STM8Sduino Pin 10 = PB2 AIN2 117 | {GPIOB, 1<<3}, //STM8Sduino Pin 11 = PB3 AIN3 118 | {GPIOB, 1<<4}, //STM8Sduino Pin 12 = PB4 AIN4 119 | {GPIOB, 1<<5}, //STM8Sduino Pin 13 = PB5 AIN5 120 | {GPIOB, 1<<6}, //STM8Sduino Pin 14 = PB6 AIN6 121 | {GPIOB, 1<<7}, //STM8Sduino Pin 15 = PB7 AIN7 122 | 123 | {GPIOC, 1<<0}, //STM8Sduino Pin 16 = PC0 124 | {GPIOC, 1<<1}, //STM8Sduino Pin 17 = PC1 TIM1/CH1 125 | {GPIOC, 1<<2}, //STM8Sduino Pin 18 = PC2 TIM1/CH2 126 | {GPIOC, 1<<3}, //STM8Sduino Pin 19 = PC3 TIM1/CH3 127 | {GPIOC, 1<<4}, //STM8Sduino Pin 20 = PC4 TIM1/CH4 128 | {GPIOC, 1<<5}, //STM8Sduino Pin 21 = PC5 129 | {GPIOC, 1<<6}, //STM8Sduino Pin 22 = PC6 130 | {GPIOC, 1<<7}, //STM8Sduino Pin 23 = PC7 131 | 132 | {GPIOD, 1<<0}, //STM8Sduino Pin 24 = PD0 TIM3/CH2 133 | {GPIOD, 1<<1}, //STM8Sduino Pin 25 = PD1 134 | {GPIOD, 1<<2}, //STM8Sduino Pin 26 = PD2 TIM3/CH1 135 | {GPIOD, 1<<3}, //STM8Sduino Pin 27 = PD3 TIM2/CH2 136 | {GPIOD, 1<<4}, //STM8Sduino Pin 28 = PD4 TIM2/CH1 137 | {GPIOD, 1<<5}, //STM8Sduino Pin 29 = PD5 138 | {GPIOD, 1<<6}, //STM8Sduino Pin 30 = PD6 139 | {GPIOD, 1<<7}, //STM8Sduino Pin 31 = PD7 140 | 141 | {GPIOE, 1<<0}, //STM8Sduino Pin 32 = PE0 142 | {GPIOE, 1<<1}, //STM8Sduino Pin 33 = PE1 143 | {GPIOE, 1<<2}, //STM8Sduino Pin 34 = PE2 144 | {GPIOE, 1<<3}, //STM8Sduino Pin 35 = PE3 145 | {GPIOE, 1<<4}, //STM8Sduino Pin 36 = PE4 146 | {GPIOE, 1<<5}, //STM8Sduino Pin 37 = PE5 147 | {GPIOE, 1<<6}, //STM8Sduino Pin 38 = PE6 AIN9 148 | {GPIOE, 1<<7}, //STM8Sduino Pin 39 = PE7 AIN8 149 | 150 | {GPIOF, 1<<0}, //STM8Sduino Pin 40 = PF0 151 | {GPIOF, 1<<1}, //STM8Sduino Pin 41 = PF1 152 | {GPIOF, 1<<2}, //STM8Sduino Pin 42 = PF2 153 | {GPIOF, 1<<3}, //STM8Sduino Pin 43 = PF3 154 | {GPIOF, 1<<4}, //STM8Sduino Pin 44 = PF4 AIN12 155 | {GPIOF, 1<<5}, //STM8Sduino Pin 45 = PF5 156 | {GPIOF, 1<<6}, //STM8Sduino Pin 46 = PF6 157 | {GPIOF, 1<<7}, //STM8Sduino Pin 47 = PF7 158 | 159 | #if defined(GPIOG) //GPIOG not present on all chips 160 | {GPIOG, 1<<0}, //STM8Sduino Pin 48 = PG0 161 | {GPIOG, 1<<1}, //STM8Sduino Pin 49 = PG1 162 | {GPIOG, 1<<2}, //STM8Sduino Pin 50 = PG2 163 | {GPIOG, 1<<3}, //STM8Sduino Pin 51 = PG3 164 | {GPIOG, 1<<4}, //STM8Sduino Pin 52 = PG4 165 | {GPIOG, 1<<5}, //STM8Sduino Pin 53 = PG5 166 | {GPIOG, 1<<6}, //STM8Sduino Pin 54 = PG6 167 | {GPIOG, 1<<7}, //STM8Sduino Pin 55 = PG7 168 | #endif 169 | 170 | #if defined(GPIOH) //GPIOH not present on all chips 171 | {GPIOH, 1<<0}, //STM8Sduino Pin 56 = PH0 172 | {GPIOH, 1<<1}, //STM8Sduino Pin 57 = PH1 173 | {GPIOH, 1<<2}, //STM8Sduino Pin 58 = PH2 174 | {GPIOH, 1<<3}, //STM8Sduino Pin 59 = PH3 175 | {GPIOH, 1<<4}, //STM8Sduino Pin 60 = PH4 176 | {GPIOH, 1<<5}, //STM8Sduino Pin 61 = PH5 177 | {GPIOH, 1<<6}, //STM8Sduino Pin 62 = PH6 178 | {GPIOH, 1<<7}, //STM8Sduino Pin 63 = PH7 179 | #endif 180 | 181 | #if defined(GPIOI) //GPIOI not present on all chips 182 | {GPIOI, 1<<0}, //STM8Sduino Pin 64 = PI0 183 | {GPIOI, 1<<1}, //STM8Sduino Pin 65 = PI1 184 | {GPIOI, 1<<2}, //STM8Sduino Pin 66 = PI2 185 | {GPIOI, 1<<3}, //STM8Sduino Pin 67 = PI3 186 | {GPIOI, 1<<4}, //STM8Sduino Pin 68 = PI4 187 | {GPIOI, 1<<5}, //STM8Sduino Pin 69 = PI5 188 | {GPIOI, 1<<6}, //STM8Sduino Pin 70 = PI6 189 | {GPIOI, 1<<7}, //STM8Sduino Pin 71 = PI7 190 | #endif 191 | }; 192 | 193 | //configure clock 194 | //use hsi oscillator 195 | void SystemCoreClockHSI(uint8_t CLK_HSIDIV) { 196 | /* check the parameters */ 197 | //assert_param(IS_CLK_PRESCALER_OK(CLK_HSIDIV)); 198 | 199 | //CLK_DeInit(); 200 | CLK->ICKR |= CLK_ICKR_HSIEN; //enable HSI 201 | while ((CLK->ICKR & CLK_ICKR_HSIRDY) == 0) continue; //wait until HSI is ready 202 | CLK->SWCR|= CLK_SWCR_SWEN; //start the switch 203 | CLK->SWR = 0xe1; //0xe1->HSI, 0xd2->LSI, 0xb4->HSE //CLK_HSICmd(ENABLE); 204 | while ((CLK->SWCR & CLK_SWCR_SWBSY) == 1) continue; //wait until the busy signal is no more //while(SET != CLK_GetFlagStatus(CLK_FLAG_HSIRDY)) continue; //make sure hsi is ready 205 | CLK->CKDIVR = (CLK->CKDIVR &~CLK_CKDIVR_HSIDIV) | (CLK_HSIDIV & CLK_CKDIVR_HSIDIV); //set hsi divider 206 | CLK->CKDIVR = (CLK->CKDIVR &~CLK_CKDIVR_CPUDIV) | (CLK_PRESCALER_CPUDIV1& CLK_CKDIVR_CPUDIV); //set cpu divier -> default to 1:1 207 | //update SystemCoreClock 208 | switch (CLK_HSIDIV) { 209 | case CLK_PRESCALER_HSIDIV1: SystemCoreClock = HSI_VALUE / 1; break; 210 | case CLK_PRESCALER_HSIDIV2: SystemCoreClock = HSI_VALUE / 2; break; 211 | case CLK_PRESCALER_HSIDIV4: SystemCoreClock = HSI_VALUE / 4; break; 212 | case CLK_PRESCALER_HSIDIV8: SystemCoreClock = HSI_VALUE / 8; break; 213 | default: SystemCoreClock = HSI_VALUE / 8; break; 214 | } 215 | } 216 | 217 | //use hse oscillator 218 | void SystemCoreClockHSE(void) { 219 | /* check the parameters */ 220 | //assert_param(IS_CLK_PRESCALER_OK(CLK_HSIDIV)); 221 | 222 | //CLK_DeInit(); 223 | CLK->ECKR |= CLK_ECKR_HSEEN; //enable HSE 224 | while ((CLK->ECKR & CLK_ECKR_HSERDY) == 0) continue; //wait until HSE is ready 225 | CLK->SWCR|= CLK_SWCR_SWEN; //start the switch 226 | CLK->SWR = 0xb4; //0xe1->HSI, 0xd2->LSI, 0xb4->HSE //CLK_HSICmd(ENABLE); 227 | while ((CLK->SWCR & CLK_SWCR_SWBSY) == 1) continue; //wait until the busy signal is no more //while(SET != CLK_GetFlagStatus(CLK_FLAG_HSIRDY)) continue; //make sure hsi is ready 228 | //update SystemCoreClock 229 | SystemCoreClock = HSE_VALUE; 230 | } 231 | 232 | //Arduino Functions: GPIO 233 | //set a pin mode to INPUT, INPUT_PULLUP, INPUT_PULLDN or OUTPUT 234 | //no error checking on PIN 235 | inline void pinMode(PIN_TypeDef pin, uint8_t mode) { 236 | //if (mode==INPUT) GIO_IN(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask); 237 | //else GIO_OUT(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask); 238 | switch (mode) { 239 | case OUTPUT_OD: GIO_OUTOD(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask); break; 240 | case OUTPUT: GIO_OUT(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask); break; 241 | case INPUT_PULLUP: GIO_INPU(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask); break; 242 | case INPUT: 243 | default: GIO_INFL(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask); break; 244 | } 245 | } 246 | 247 | //set / clear a pin 248 | inline void digitalWrite(PIN_TypeDef pin, uint8_t val) { 249 | if (val==LOW) GIO_CLR(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask); 250 | else GIO_SET(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask); 251 | } 252 | 253 | //read a pin 254 | inline int digitalRead(PIN_TypeDef pin) { 255 | return (GIO_GET(GPIO_PinDef[pin].gpio, GPIO_PinDef[pin].mask))?HIGH:LOW; 256 | } 257 | //end GPIO 258 | 259 | //Arduino Functions: Time 260 | //return time base ticks 261 | uint32_t ticks(void) { 262 | uint32_t m; 263 | uint8_t f; 264 | 265 | //use double reads 266 | do { 267 | m = timer_ticks; 268 | f = TIM4->CNTR; 269 | } while (m != timer_ticks); 270 | 271 | //return ((((uint32_t) m << 16) | (f << 8)) >> 10) / 2 / clockCyclesPerMicrosecond(); //128:1 prescaler 272 | return (m | f) << TIM4_PS; 273 | } 274 | 275 | //return microseconds 276 | uint32_t micros(void) { 277 | uint32_t m; //stores overflow count 278 | uint8_t f; //return the fractions / TIM4 8-bit value 279 | 280 | //use double reads 281 | do { 282 | m = timer_ticks; 283 | f = TIM4->CNTR; 284 | } while (m != timer_ticks); 285 | //now m and f are consistent 286 | return ((m | f) / clockCyclesPerMicrosecond()) << TIM4_PS; //2^TIM4_PS:1 prescaler 287 | } 288 | 289 | //return milliseconds 290 | uint32_t millis(void) { 291 | uint32_t m; 292 | uint8_t f; 293 | 294 | //use double reads 295 | do { 296 | m = timer_ticks; 297 | f = TIM4->CNTR; 298 | } while (m != timer_ticks); 299 | 300 | return (((m | f) / clockCyclesPerMicrosecond()) << TIM4_PS) / 1000; 301 | } 302 | 303 | //delay millisseconds 304 | void delay(uint32_t ms) { 305 | #if 0 //using millis() 306 | uint32_t start_time = millis(); 307 | 308 | while (millis() - start_time < ms) continue; 309 | #else //using ticks() 310 | uint32_t start_time = ticks(); 311 | 312 | ms *= (SystemCoreClock / 1000); //convert ms to ticks 313 | while (ticks() - start_time < ms) continue; 314 | #endif 315 | } 316 | 317 | //delay micros seconds 318 | void delayMicroseconds(uint32_t us) { 319 | #if 0 //using micros() 320 | uint32_t start_time = micros(); 321 | 322 | while (micros() - start_time < us) continue; 323 | #else //using ticks() 324 | uint32_t start_time = ticks(); 325 | 326 | us *= (SystemCoreClock / 1000000ul); //convert us to ticks 327 | while (ticks() - start_time < us) continue; 328 | #endif 329 | } 330 | //end Time 331 | 332 | 333 | //Arduino Functions: Advanced IO 334 | //shift in - from arduino code base / not optimized 335 | uint8_t shiftIn(PIN_TypeDef dataPin, PIN_TypeDef clockPin, uint8_t bitOrder) { 336 | uint8_t value = 0; 337 | uint8_t i; 338 | 339 | for (i = 0; i < 8; ++i) { 340 | digitalWrite(clockPin, HIGH); 341 | if (bitOrder == LSBFIRST) 342 | value |= digitalRead(dataPin) << i; 343 | else 344 | value |= digitalRead(dataPin) << (7 - i); 345 | digitalWrite(clockPin, LOW); 346 | } 347 | return value; 348 | } 349 | 350 | //shift out - from arduino code base / not optimized 351 | void shiftOut(PIN_TypeDef dataPin, PIN_TypeDef clockPin, uint8_t bitOrder, uint8_t val) { 352 | uint8_t i; 353 | 354 | for (i = 0; i < 8; i++) { 355 | if (bitOrder == LSBFIRST) 356 | digitalWrite(dataPin, !!(val & (1 << i))); 357 | else 358 | digitalWrite(dataPin, !!(val & (1 << (7 - i)))); 359 | 360 | digitalWrite(clockPin, HIGH); 361 | digitalWrite(clockPin, LOW); 362 | } 363 | } 364 | 365 | //wait for a pulse and return timing 366 | uint32_t pulseIn(PIN_TypeDef pin, uint8_t state) { 367 | uint32_t tmp; 368 | state = (state == LOW)?LOW:HIGH; 369 | while (digitalRead(pin) == state) continue; //wait for the pin to opposite 370 | //now pin is _state 371 | tmp = micros(); 372 | state = (state == LOW)?HIGH:LOW; //calculate the state to end the wait 373 | while (digitalRead(pin) == state) continue; //wait for the pin to go back to its original state 374 | tmp = micros() - tmp; //calculate the pulse width 375 | return tmp; 376 | } 377 | //end Advanced IO 378 | 379 | //pwm output - not implemented yet 380 | //top at PWMOUT_PR -> max 16-bit pwm output 381 | void analogWrite(PIN_TypeDef pin, uint16_t dc) { 382 | //bound dc range 383 | dc = (dc > PWM_PR)?PWM_PR:dc; //limit the range 384 | switch (pin) { 385 | #if defined(TIM1) && defined(USE_PWM1) 386 | //tim1 ch1/2/3/4 387 | case PC1/*17*/: //pin 17 -> PC1/TIM1CH1 388 | //load the duty cycle 389 | TIM1->CCR1H = dc>>8; 390 | TIM1->CCR1L = dc; 391 | TIM1->CCER1|= 1<<0; //1->enable OCi output, 0->disable OCi output 392 | break; 393 | case PC2/*18*/: //pin 18 -> PC2/TIM1CH2 394 | //load the duty cycle 395 | TIM1->CCR2H = dc>>8; 396 | TIM1->CCR2L = dc; 397 | TIM1->CCER1|= 1<<4; //1->enable OCi output, 0->disable OCi output 398 | break; 399 | case PC3/*19*/: //pin 19 -> PC3/TIM1CH3 400 | //load the duty cycle 401 | TIM1->CCR3H = dc>>8; 402 | TIM1->CCR3L = dc; 403 | TIM1->CCER2|= 1<<0; //1->enable OCi output, 0->disable OCi output 404 | break; 405 | case PC4/*20*/: //pin 20 -> PC4/TIM1CH4 406 | //load the duty cycle 407 | TIM1->CCR4H = dc>>8; 408 | TIM1->CCR4L = dc; 409 | TIM1->CCER2|= 1<<4; //1->enable OCi output, 0->disable OCi output 410 | break; 411 | #endif 412 | #if defined(TIM2) && defined(USE_PWM2) //3x pwm 413 | //TIM2 ch1/2/3 414 | case PD4/*28*/: //pin 28 -> PD4/TIM2CH1 415 | //load the duty cycle 416 | TIM2->CCR1H = dc>>8; 417 | TIM2->CCR1L = dc; 418 | TIM2->CCER1|= 1<<0; //1->enable OCi output, 0->disable OCi output 419 | break; 420 | case PD3/*27*/: //pin 27 -> PD3/TIM2CH2 421 | //load the duty cycle 422 | TIM2->CCR2H = dc>>8; 423 | TIM2->CCR2L = dc; 424 | TIM2->CCER1|= 1<<4; //1->enable OCi output, 0->disable OCi output 425 | break; 426 | case PA3/*3*/: //pin 3 -> PA3/TIM2CH3 427 | //load the duty cycle 428 | TIM2->CCR3H = dc>>8; 429 | TIM2->CCR3L = dc; 430 | TIM2->CCER2|= 1<<0; //1->enable OCi output, 0->disable OCi output 431 | break; 432 | #endif 433 | #if defined(TIM3) && defined(USE_PWM3) //2ch pwm 434 | //TIM3 ch1/2 435 | case PD2/*26*/: //pin 26 -> PD2/TIM3CH1 436 | //load the duty cycle 437 | TIM3->CCR1H = dc>>8; 438 | TIM3->CCR1L = dc; 439 | TIM3->CCER1|= 1<<0; //1->enable OCi output, 0->disable OCi output 440 | break; 441 | case PD0/*24*/: //pin 24 -> PD0/TIM3CH2 442 | //load the duty cycle 443 | TIM3->CCR2H = dc>>8; 444 | TIM3->CCR2L = dc; 445 | TIM3->CCER1|= 1<<4; //1->enable OCi output, 0->disable OCi output 446 | break; 447 | #endif 448 | default: break; //do nothing 449 | } 450 | } 451 | 452 | #if defined(USE_ADC1) 453 | //analog read on ADC1 454 | //read DRL first for right aligned results 455 | //user responsible for configuring ain to a gpio pin 456 | uint16_t analogRead(AIN_TypeDef ain) { 457 | uint16_t tmp; 458 | ADC1->CSR = (ADC1->CSR &~0x0f) | (ain & 0x0f); //set the channel 459 | //ADC1->CR1|= (1<<0); //start the conversion 460 | ADC1->CR1|= (1<<0); //start the conversion 461 | while ((ADC1->CSR & (1<<7)) == 0) continue; //wait for the previous conversion to end (EOC = 1 if conversion is complete) 462 | //read the adc results 463 | tmp = ADC1->DRL; //read DRL first for right aligned results 464 | tmp|= ADC1->DRH << 8; 465 | ADC1->CSR &=~(1<<7); //clear the EOC 466 | //ADC1->CR1&=~(1<<0); //power down adc 467 | return tmp; 468 | } 469 | 470 | //change analog reference - not applicable on STM8S 471 | #define analogReference(x) 472 | #endif //ADC1 473 | 474 | //beep functions 475 | //user needs to configure tone pin as output - see datasheet 476 | void tone(void) { 477 | BEEP->CSR |= (1<<5); //'1'->turn on tone, '0'->turn off tone 478 | } 479 | 480 | void noTone(void) { 481 | BEEP->CSR &=~(1<<5); //'1'->turn on tone, '0'->turn off tone 482 | } 483 | 484 | #if defined(USE_EXTI) 485 | //activate interrupt 486 | //mode: RISING, FALLING and CHANGE 487 | void attachInterrupt(PIN_TypeDef pin, void (*isrptr)(void), uint8_t mode){ 488 | //convert arduino modes to EXTI modes 489 | switch (mode) { 490 | case RISING: mode = 0x01; break; //rising edge triggered 491 | case CHANGE: mode = 0x03; break; //change triggered 492 | case FALLING: 493 | default: mode = 0x02; break; //default is falling edge triggered 494 | } 495 | 496 | //disable global interrupt first before changing EXTI->CRn registers 497 | noInterrupts(); 498 | 499 | //configure EXTI_CR1/CR2 registers 500 | if (GPIO_PinDef[pin].gpio==GPIOA) { //configure interrupt on porta 501 | _isrptr_extia = isrptr; //install user handler 502 | EXTI->CR1 = (EXTI->CR1 &~EXTI_CR1_PAIS) | ((mode << 0) & EXTI_CR1_PAIS); 503 | } 504 | 505 | if (GPIO_PinDef[pin].gpio==GPIOB) { //configure interrupt on portb 506 | _isrptr_extib = isrptr; //install user handler 507 | EXTI->CR1 = (EXTI->CR1 &~EXTI_CR1_PBIS) | ((mode << 2) & EXTI_CR1_PBIS); 508 | } 509 | 510 | if (GPIO_PinDef[pin].gpio==GPIOC) { //configure interrupt on portc 511 | _isrptr_extic = isrptr; //install user handler 512 | EXTI->CR1 = (EXTI->CR1 &~EXTI_CR1_PCIS) | ((mode << 4) & EXTI_CR1_PCIS); 513 | } 514 | 515 | if (GPIO_PinDef[pin].gpio==GPIOD) { //configure interrupt on portd 516 | _isrptr_extid = isrptr; //install user handler 517 | EXTI->CR1 = (EXTI->CR1 &~EXTI_CR1_PDIS) | ((mode << 6) & EXTI_CR1_PDIS); 518 | } 519 | 520 | if (GPIO_PinDef[pin].gpio==GPIOE) { //configure interrupt on porte 521 | _isrptr_extie = isrptr; //install user handler 522 | EXTI->CR2 = (EXTI->CR2 &~EXTI_CR2_PEIS) | ((mode << 0) & EXTI_CR2_PEIS); 523 | } 524 | 525 | //enable global interrupt 526 | interrupts(); 527 | 528 | //configure gpio pin, with interrupt capability by setting CR2 529 | GPIO_PinDef[pin].gpio->CR2 |= GPIO_PinDef[pin].mask; 530 | 531 | } 532 | 533 | //deactivate interrupt 534 | //pin revert back to input, floating mode 535 | void detachInterrupt(PIN_TypeDef pin){ 536 | uint8_t mode = 0x00; //falling and low -> default state 537 | void (*isrptr)(void) = empty_handler; //reset handler to empty_handler. for ease of coding 538 | 539 | //convert arduino modes to EXTI modes 540 | //switch (mode) { 541 | //case RISING: mode = 0x01; break; //rising edge triggered 542 | //case CHANGE: mode = 0x03; break; //change triggered 543 | //case FALLING: 544 | //default: mode = 0x02; break; //default is falling edge triggered 545 | //} 546 | 547 | //configure EXTI_CR1/CR2 registers 548 | if (GPIO_PinDef[pin].gpio==GPIOA) { //configure interrupt on porta 549 | _isrptr_extia = isrptr; //install user handler 550 | EXTI->CR1 = (EXTI->CR1 &~EXTI_CR1_PAIS) | ((mode << 0) & EXTI_CR1_PAIS); 551 | } 552 | 553 | if (GPIO_PinDef[pin].gpio==GPIOB) { //configure interrupt on portb 554 | _isrptr_extib = isrptr; //install user handler 555 | //EXTI->CR1 = (EXTI->CR1 &~EXTI_CR1_PBIS) | ((mode << 2) & EXTI_CR1_PBIS); 556 | } 557 | 558 | if (GPIO_PinDef[pin].gpio==GPIOC) { //configure interrupt on portc 559 | _isrptr_extic = isrptr; //install user handler 560 | //EXTI->CR1 = (EXTI->CR1 &~EXTI_CR1_PCIS) | ((mode << 4) & EXTI_CR1_PCIS); 561 | } 562 | 563 | if (GPIO_PinDef[pin].gpio==GPIOD) { //configure interrupt on portd 564 | _isrptr_extid = isrptr; //install user handler 565 | //EXTI->CR1 = (EXTI->CR1 &~EXTI_CR1_PDIS) | ((mode << 6) & EXTI_CR1_PDIS); 566 | } 567 | 568 | if (GPIO_PinDef[pin].gpio==GPIOE) { //configure interrupt on porte 569 | _isrptr_extie = isrptr; //install user handler 570 | //EXTI->CR2 = (EXTI->CR2 &~EXTI_CR2_PEIS) | ((mode << 0) & EXTI_CR2_PEIS); 571 | } 572 | 573 | //disable pin interrupt capability by clear CR2 574 | GPIO_PinDef[pin].gpio->CR2 &=~GPIO_PinDef[pin].mask; 575 | } 576 | #endif //exti 577 | 578 | //uart1 routines 579 | #if defined(UART1) && defined(USE_UART1) 580 | //configure uart1 -> similar configurations among UART1/2/3/4 581 | //UART1: TX on PA2, RX on PA3 582 | void serial1Begin(uint32_t BaudRate) { 583 | //route clock to uart2 584 | CLK->PCKENR1 |= CLK_PCKENR1_UART1; //'1'=clock enabled, '0'=clock disabled 585 | 586 | //user to configure TXpin (PD5) as output through serialBegin() 587 | //user to configure RXpin (PD6) as input through serialBegin() 588 | //configure UART2 RX (on PD6) 589 | 590 | //configure UART2 TX: 8-bit, 1-stop bit, no parity, syncmode disable 591 | UART1->CR1 |= (1<<5); //'1'->disable uart, '0'->enable uart transmitter 592 | 593 | uint16_t tmp = SystemCoreClock / BaudRate; //max of 16-bit 594 | //set BRR2 first, per the datasheet 595 | UART1->BRR2 = ((tmp >> 8) & 0xf0) | (tmp & 0x0f); //BRR2 is the top 4 + bottom 4 digits 596 | UART1->BRR1 = tmp >> 4; //BRR1 is the middle 4 digits 597 | 598 | UART1->CR5 = 0; //default value 599 | UART1->CR4 = (0<<6) | //'0'->LIN break detection interrupt disabled, '1'->enabled 600 | (0<<5) | //'0'->10-bit line detection, '1'->11-bit line detection 601 | (0<<4) | //'0'->line break not detected, '1'->line break detected 602 | (0<<0) | //4-bit Address of the UART note 603 | 0x00; 604 | UART1->CR3 = (0<<6) | //'0'->disable LIN, '1'->enable LIN 605 | (0<<4) | //0->1 stop bit, 1->reserved, 2->2 stop bit, 3->1.5 stop bit 606 | (0<<3) | //'0'->disable SCK, '1'->enable SCK 607 | (0<<2) | //'0'->SCK idles low, '1'->SCK idles high 608 | (0<<1) | //'0'->capture data on first clock transition, '1'->capture data on 2nd clock transition 609 | (0<<0) | //'0'->last clock pulse is not output, '1'->last clock pulse is on output 610 | 0x00; 611 | UART1->CR2 = (0<<7) | //'0'->tx interrupt disabled, '1'->tx interrupt enabled 612 | (0<<6) | //'0'->tx completion interrupt diabled, '1'->tx completion interrupt enabled 613 | (0<<5) | //'0'->rx interrupt disabled, '1'->rx interrupt enabled 614 | (0<<4) | //'0'->idle line interrupt disabled, '1'->idle line interrupt enabled 615 | (1<<3) | //'0'->tx disabled, '1'->tx enabled 616 | (1<<2) | //'0'->rx disabled, '1'->rx enabled 617 | (0<<1) | //'0'->receiver in active mode, '1'->receiver in mute mode 618 | (0<<0) | //'0'->don't send break; '1'->send break; 619 | 0x00; 620 | UART1->CR1 = (0<<7) | //9th bit for receiving in 9-bit mode (when M=1) 621 | (0<<6) | //9th bit for transmission in 9-bit mode (when M=1) 622 | (0<<5) | //'0'->uart enabled, '1'->uart disabled 623 | (0<<4) | //'0'->1start bit, 8 data bits, n stop bits; '1'->1 start bit, 9 data bits, 1 stop bit 624 | (0<<3) | //'0'->idle line, '1'->address line wakes up uart 625 | (0<<2) | //'0'->parity disabled, '1'->parity enabled 626 | (0<<1) | //'0'->even partity, '1'->odd parity 627 | (0<<0) | //'0'->parity interrupt disabled, '1'->parity interrupt enabled 628 | 0x00; 629 | //configure interrupt -> if uart2 to be interrupt-driven 630 | 631 | //enable UART1 632 | UART1->CR1 &=~(1<<5); //'0'->enable uart, '1'->disable uart 633 | 634 | } 635 | 636 | //uart1 send a char 637 | void serial1Write(unsigned char dat) { 638 | UART1->DR = dat; //load the data buffer 639 | while (!(UART1->SR & UART1_SR_TC)); //wait for the transmission to complete 640 | } 641 | 642 | //uart1 returns a char 643 | unsigned char serial1Read(void) { 644 | while (!(UART1->SR & UART1_SR_RXNE)); //wait fo the receipt to terminate 645 | return UART1->DR; //save the transmission buffer 646 | } 647 | 648 | //uart1 print a string 649 | void serial1Print(unsigned char *str) { 650 | do { 651 | while (!(UART1->SR & UART1_SR_TXE)); //wait for the transmission buffer to empty 652 | UART1->DR = *str++; //load the data into transmission buffer 653 | } while (*str); 654 | } 655 | 656 | //uart1 print a string + return 657 | void serial1Println(unsigned char *str) { 658 | serial1Print(str); //print the string 659 | serial1Print("\n\r"); //print the return 660 | } 661 | 662 | //test if uart1 is available 663 | //return true if transmission on uart1 has completed 664 | uint8_t serial1Available(void) { 665 | return (UART1->SR & UART1_SR_TC)?true:false; 666 | } 667 | #endif //use_uart1 668 | 669 | #if defined(USE_UART2) && defined(UART2) //005, 105 670 | //configure uart2 -> similar configurations among UART1/2/3/4 671 | //UART2: TX on PD5, RX on PD6 672 | void serial2Begin(uint32_t BaudRate) { 673 | uint16_t tmp; 674 | //route clock to uart2 675 | CLK->PCKENR1 |= CLK_PCKENR1_UART2; //'1'=clock enabled, '0'=clock disabled 676 | 677 | //user to configure TXpin (PD5) as output through serialBegin() 678 | //user to configure RXpin (PD6) as input through serialBegin() 679 | //configure UART2 RX (on PD6) 680 | 681 | //configure UART2 TX: 8-bit, 1-stop bit, no parity, syncmode disable 682 | UART2->CR1 |= (1<<5); //'1'->disable uart, '0'->enable uart transmitter 683 | 684 | /*uint16_t */tmp = SystemCoreClock / BaudRate; //max of 16-bit 685 | //set BRR2 first, per the datasheet 686 | UART2->BRR2 = ((tmp >> 8) & 0xf0) | (tmp & 0x0f); //BRR2 is the top 4 + bottom 4 digits 687 | UART2->BRR1 = tmp >> 4; //BRR1 is the middle 4 digits 688 | 689 | UART2->CR1 = (0<<7) | //9th bit for receiving in 9-bit mode (when M=1) 690 | (0<<6) | //9th bit for transmission in 9-bit mode (when M=1) 691 | (0<<5) | //'0'->uart enabled, '1'->uart disabled 692 | (0<<4) | //'0'->1start bit, 8 data bits, n stop bits; '1'->1 start bit, 9 data bits, 1 stop bit 693 | (0<<3) | //'0'->idle line, '1'->address line wakes up uart 694 | (0<<2) | //'0'->parity disabled, '1'->parity enabled 695 | (0<<1) | //'0'->even partity, '1'->odd parity 696 | (0<<0) | //'0'->parity interrupt disabled, '1'->parity interrupt enabled 697 | 0x00; 698 | UART2->CR2 = (0<<7) | //'0'->tx interrupt disabled, '1'->tx interrupt enabled 699 | (0<<6) | //'0'->tx completion interrupt diabled, '1'->tx completion interrupt enabled 700 | (0<<5) | //'0'->rx interrupt disabled, '1'->rx interrupt enabled 701 | (0<<4) | //'0'->idle line interrupt disabled, '1'->idle line interrupt enabled 702 | (1<<3) | //'0'->tx disabled, '1'->tx enabled 703 | (1<<2) | //'0'->rx disabled, '1'->rx enabled 704 | (0<<1) | //'0'->receiver in active mode, '1'->receiver in mute mode 705 | (0<<0) | //'0'->don't send break; '1'->send break; 706 | 0x00; 707 | UART2->CR3 = (0<<6) | //'0'->disable LIN, '1'->enable LIN 708 | (0<<4) | //0->1 stop bit, 1->reserved, 2->2 stop bit, 3->1.5 stop bit 709 | (0<<3) | //'0'->disable SCK, '1'->enable SCK 710 | (0<<2) | //'0'->SCK idles low, '1'->SCK idles high 711 | (0<<1) | //'0'->capture data on first clock transition, '1'->capture data on 2nd clock transition 712 | (0<<0) | //'0'->last clock pulse is not output, '1'->last clock pulse is on output 713 | 0x00; 714 | UART2->CR4 = (0<<6) | //'0'->LIN break detection interrupt disabled, '1'->enabled 715 | (0<<5) | //'0'->10-bit line detection, '1'->11-bit line detection 716 | (0<<4) | //'0'->line break not detected, '1'->line break detected 717 | (0<<0) | //4-bit Address of the UART note 718 | 0x00; 719 | UART2->CR5 = 0; //default value 720 | //configure interrupt -> if uart2 to be interrupt-driven 721 | 722 | //enable UART2 723 | UART2->CR1 &=~(1<<5); //'0'->enable uart, '1'->disable uart 724 | 725 | } 726 | 727 | //uart2 send a char 728 | void serial2Write(unsigned char dat) { 729 | UART2->DR = dat; //load the data buffer 730 | while (!(UART2->SR & UART2_SR_TC)); //wait for the transmission to complete 731 | } 732 | 733 | //uart2 returns a char 734 | unsigned char serial2Read(void) { 735 | while (!(UART2->SR & UART2_SR_RXNE)); //wait fo the receipt to terminate 736 | return UART2->DR; //save the transmission buffer 737 | } 738 | 739 | //uart2 print a string 740 | void serial2Print(unsigned char *str) { 741 | do { 742 | while (!(UART2->SR & UART2_SR_TXE)); //wait for the transmission buffer to empty 743 | UART2->DR = *str++; //load the data into transmission buffer 744 | } while (*str); 745 | } 746 | 747 | //uart2 print a string + return 748 | void serial2Println(unsigned char *str) { 749 | serial2Print(str); //print the string 750 | serial2Print("\n\r"); //print the return 751 | } 752 | 753 | //test if uart2 is available 754 | //return true if transmission on uart2 has completed 755 | uint8_t serial2Available(void) { 756 | return (UART2->SR & UART2_SR_TC)?true:false; 757 | } 758 | #endif //use_uart2 759 | 760 | #if defined(USE_SPI) 761 | //send char via hardware spi 762 | //MISO on PC7, MOSI on PC6, SCK on PC5 763 | //Order = LSBFIRST or MSBFIRST 764 | uint8_t SPIWrite(uint8_t order, uint8_t dat) { 765 | if (order == LSBFIRST) SPI->CR1 |= (1<<7); //'1'->LSB first 766 | else SPI->CR1 &=~(1<<7); //'0'->MSB first 767 | while ((SPI->SR & (1<<1))==0) continue; //wait for transmit buffer to be empty (bit 1 goes to 1) 768 | SPI->DR = dat; //load the transmission buffer -> transmission starts. this approach can be risk for reads 769 | //consider test busy signal 770 | while (SPI->SR & SPI_SR_BSY) continue; //'1'->SPI is buy, '0'->SPI is not busy 771 | //comment the above line for higher throughput if you don't care about the read-back 772 | return SPI->DR; //return spi data buffer 773 | } 774 | 775 | //buffer write of a string 776 | uint8_t SPIWrites(uint8_t order, uint8_t *dat, uint16_t length) { 777 | if (order == LSBFIRST) SPI->CR1 |= (1<<7); //'1'->LSB first 778 | else SPI->CR1 &=~(1<<7); //'0'->MSB first 779 | while (length--) { 780 | while ((SPI->SR & (1<<1))==0) continue; //wait for transmit buffer to be empty (bit 1 goes to 1) 781 | SPI->DR = *dat++; //load the transmission buffer -> transmission starts. this approach can be risk for reads 782 | } 783 | //consider test busy signal 784 | while (SPI->SR & SPI_SR_BSY) continue; //'1'->SPI is buy, '0'->SPI is not busy 785 | //comment the above line for higher throughput if you don't care about the read-back 786 | return SPI->DR; //return spi data buffer 787 | } 788 | 789 | //read spi 790 | //MISO on PC7, MOSI on PC6, SCK on PC5 791 | //Order = LSBFIRST or MSBFIRST 792 | uint8_t SPIRead(uint8_t order) { 793 | //uint8_t tmp; 794 | if (order == LSBFIRST) SPI->CR1 |= (1<<7); //'1'->LSB first 795 | else SPI->CR1 &=~(1<<7); //'0'->MSB first 796 | while ((SPI->SR & (1<<1))==0) continue; //wait for transmit buffer to be empty (bit 1 goes to 1) 797 | SPI->DR = /*dat*/0x00; //load the transmission buffer -> transmission starts. this approach can be risk for reads 798 | //consider test busy signal 799 | while (SPI->SR & SPI_SR_BSY) continue; //'1'->SPI is buy, '0'->SPI is not busy 800 | //comment the above line for higher throughput if you don't care about the read-back 801 | return SPI->DR; //return spi data buffer 802 | } 803 | #endif //spi 804 | 805 | #if defined(USE_I2C) 806 | //send a start condition 807 | void I2CStart(void) { 808 | I2C->CR2 |= (1<<0); //'1'->send a start condition 809 | while (!(I2C->SR1 & (1<<0))); //'1'->start bit generated 810 | (void)I2C->SR1; //clear the start condition by reading I2C->SR1 followed by a write to I2C->DR 811 | } 812 | //send a stop condition 813 | void I2CStop() { 814 | I2C->CR2 |= (1<<1); //'1'->send a stop condition 815 | while (!(I2C->SR3 & (1<<0))); //'1'->stop condition is detected on the bus 816 | } 817 | 818 | //write address 819 | void I2CWriteaddr(uint8_t addr) { 820 | I2C->DR = addr; 821 | while (!(I2C->SR1 & (1<<1))); //'1'->address sent, '0'->address not yet sent 822 | (void) I2C->SR1; //clear EV6 -> see datasheet 823 | (void) I2C->SR3; 824 | I2C->CR2 |= (1<<2); //send the ack 825 | } 826 | 827 | //send data 828 | void I2CWrite(uint8_t dat) { 829 | I2C->DR = dat; //load data 830 | while (!(I2C->SR1 & (1<<7))); //'1' when transmission buffer is empty. not set in address phase 831 | } 832 | 833 | //read i2c 834 | uint8_t I2CRead(uint8_t ack) { 835 | if (ack) 836 | I2C->CR2 |= (1<<2); //'1'->send ack 837 | else 838 | I2C->CR2 &= ~(1<<2); //'0'->don't send ack 839 | while (!(I2C->SR1 & (1<<6))); //'0'->receiver buffer is empty, '1'->receiver buffer is not empty 840 | return I2C->DR; 841 | } 842 | 843 | #endif //i2c 844 | 845 | //initialize the mcu 846 | //reset the mcu 847 | void mcu_init(void){ 848 | //configure clock sources 849 | //SystemCoreClockHSE(); //set clock to hse, @ HSE_VALUE 850 | //SystemCoreClockHSI_16MHz(); //set clock to hsi, _2MHz, _4MHz, _8MHz, _16MHz 851 | SystemCoreClockHSI_2MHz(); //default setting: set clock to hsi, _2MHz, _4MHz, _8MHz, _16MHz 852 | 853 | //disable all peripherals by default 854 | CLK->PCKENR1 = CLK->PCKENR2 = 0x00; //'0'->disable clock to a peripheral, '1'->enable clock 855 | 856 | //configure time base for micros/millis on TIM4 (or TIM2 if TIME4 isn't available) 857 | timer_ticks = 0; //reset timer ticks 858 | //enable the clock to peripheral 859 | //TIM4 running at 2^TIM4_PS prescaler 860 | CLK->PCKENR1 |= CLK_PCKENR1_TIM4; //'1'=clock enabled, '0'=clock disabled 861 | //set up the time base 862 | //stop the timer 863 | //TIM4->CR1 &=~(1<<0); //stop the timer 864 | //set up the timer 865 | TIM4->CR1 = (1<<7) | //'1'->enable auto reload buffer 866 | (0<<5) | //'0'->edge aligned. 1..3->center aligned 867 | (0<<4) | //'0'->up counter, '1' downcounter 868 | (0<<3) | //'0'->continuous mode, '1'->one pulse mode 869 | (0<<2) | //'0'-> update enable source 870 | (0<<1) | //'0'-> update enabled 871 | (0<<0); //counter disabled 872 | //TIMx->CR2 = 0; //default value 873 | //TIMx->SMCR = 0; //default value 874 | //TIMx->ETR = 0; //'0'->external trigger not inverted 875 | TIM4->PSCR = (TIM4_PS) & 0x07; //3-bit prescaler = 2^0x00 = 1:1 876 | TIM4->CNTR = 0; //TIMx->CNTRL = 0; //reset the counter 877 | TIM4->ARR = 0xff; //top at 256 //pr = pr - 1; TIMx->ARR = pr; //load up the auto reload register - msb first 878 | TIM4->SR1&=~(1<<0); //clear UIF 879 | TIM4->IER|= (1<<0); //'1'->enable overflow interrupt, '0'->disable interrupt 880 | //re-enable the counter 881 | TIM4->CR1 |= (1<<0); 882 | 883 | //configure pwm time base - not yet implemented 884 | //enable the clock to TIM1 885 | CLK->PCKENR1 |= CLK_PCKENR1_TIM1; //'1'=clock enabled, '0'=clock disabled 886 | TIM1->CR1 = (1<<7) | //'1'->enable auto reload buffer 887 | (1<<5) | //'0'->edge aligned. 1..3->center aligned 888 | (0<<4) | //'0'->up counter, '1' downcounter 889 | (0<<3) | //'0'->continuous mode, '1'->one pulse mode 890 | (0<<2) | //'0'-> update enable source 891 | (0<<1) | //'0'-> update enabled 892 | (0<<0); //counter disabled 893 | TIM1->CR2 = 0; //reset value 894 | TIM1->PSCRH = (1ul<<(PWMOUT_PS)-1)>>8; 895 | TIM1->PSCRL = (1ul<<(PWMOUT_PS)-1); //prescaler = 1:1. map'd to 3-bit prescaler to be compatible with tim2/3 896 | TIM1->CNTRH = TIM1->CNTRL = 0; //reset the counter 897 | TIM1->ARRH = (PWM_PR)>>8; 898 | TIM1->ARRL = (PWM_PR); //top at 0x0fff 899 | TIM1->SR1 &=~(1<<0); //clear uif 900 | TIM1->CR1 |= (1<<0); //start the timer 901 | 902 | #if defined(TIM1) && defined(USE_PWM1) 903 | //configure TIM1/OC1/2/3/4 -> output disabled 904 | TIM1->CCMR1 = (7<<4) | //0b110->PWM mode 1, 0b111->PWM mode 2 905 | (0<<3) | //'0'->OCiPE disabled, '1'->OCiPE enabled 906 | (0<<0); //0b00->OCi as output 907 | TIM1->CCMR4 = TIM1->CCMR3 = TIM1->CCMR2 = TIM1->CCMR1; 908 | TIM1->CCER1 = (0<<5) | //OC2: 0->active high, 1->active low 909 | (0<<4) | //OC2: 1->enable OC2, 0->disable OC2 910 | (0<<1) | //OC1: 0->active high, 1->active low 911 | (0<<0) | //OC1: 1->enable OC2, 0->disable OC2 912 | 0x00; 913 | //check CCER2 for OC3 settings 914 | TIM1->CCER2 = (0<<5) | //OC4: 0->active high, 1->active low 915 | (0<<4) | //OC4: 1->enable OC2, 0->disable OC2 916 | (0<<1) | //OC3: 0->active high, 1->active low 917 | (0<<0) | //OC3: 1->enable OC2, 0->disable OC2 918 | 0x00; 919 | #endif //tim1 920 | 921 | #if defined(TIM2) && defined(USE_PWM2) 922 | //enable the clock to TIM2 923 | CLK->PCKENR1 |= CLK_PCKENR1_TIM2; //'1'=clock enabled, '0'=clock disabled 924 | TIM2->CR1 = (1<<7) | //'1'->enable auto reload buffer 925 | //(1<<5) | //'0'->edge aligned. 1..3->center aligned 926 | //(0<<4) | //'0'->up counter, '1' downcounter 927 | (0<<3) | //'0'->continuous mode, '1'->one pulse mode 928 | (0<<2) | //'0'-> update enable source 929 | (0<<1) | //'0'-> update enabled 930 | (0<<0); //counter disabled 931 | TIM2->PSCR = (PWMOUT_PS) & 0x0f; //4-bit prescaler, valid range [0..15], 2^PSCR divider, 0 = 1:1. 932 | TIM2->CNTRH = TIM1->CNTRL = 0; //reset the counter 933 | TIM2->ARRH = (PWM_PR)>>8; 934 | TIM2->ARRL = (PWM_PR); //top at 0x0fff 935 | TIM2->SR1 &=~(1<<0); //clear uif 936 | TIM2->CR1 |= (1<<0); //start the timer 937 | 938 | //configure TIM2/OC1/2/3 -> output disabled 939 | TIM2->CCMR1 = (7<<4) | //0b110->PWM mode 1, 0b111->PWM mode 2 940 | (0<<3) | //'0'->OCiPE disabled, '1'->OCiPE enabled 941 | (0<<0); //0b00->OCi as output 942 | TIM2->CCMR3 = TIM2->CCMR2 = TIM2->CCMR1; 943 | TIM2->CCER1 = (0<<5) | //OC2: 0->active high, 1->active low 944 | (0<<4) | //OC2: 1->enable OC2, 0->disable OC2 945 | (0<<1) | //OC1: 0->active high, 1->active low 946 | (0<<0) | //OC1: 1->enable OC2, 0->disable OC2 947 | 0x00; 948 | //check CCER2 for OC3 settings 949 | TIM2->CCER2 = (0<<1) | //OC3: 0->active high, 1->active low 950 | (0<<0) | //OC3: 1->enable OC2, 0->disable OC2 951 | 0x00; 952 | #endif //tim2 953 | 954 | #if defined(TIM3) && defined(USE_PWM3) 955 | //enable the clock to TIM3 956 | CLK->PCKENR1 |= CLK_PCKENR1_TIM3; //'1'=clock enabled, '0'=clock disabled 957 | TIM3->CR1 = (1<<7) | //'1'->enable auto reload buffer 958 | //(1<<5) | //'0'->edge aligned. 1..3->center aligned 959 | //(0<<4) | //'0'->up counter, '1' downcounter 960 | (0<<3) | //'0'->continuous mode, '1'->one pulse mode 961 | (0<<2) | //'0'-> update enable source 962 | (0<<1) | //'0'-> update enabled 963 | (0<<0); //counter disabled 964 | TIM3->PSCR = (PWMOUT_PS) & 0x0f; //4-bit prescaler, valid range [0..15], 2^PSCR divider, 0 = 1:1. 965 | TIM3->CNTRH = TIM1->CNTRL = 0; //reset the counter 966 | TIM3->ARRH = (PWM_PR)>>8; 967 | TIM3->ARRL = (PWM_PR); //top at 0x0fff 968 | TIM3->SR1 &=~(1<<0); //clear uif 969 | TIM3->CR1 |= (1<<0); //start the timer 970 | 971 | //configure TIM3/OC1/2 -> output disabled 972 | TIM3->CCMR1 = (7<<4) | //0b110->PWM mode 1, 0b111->PWM mode 2 973 | (0<<3) | //'0'->OCiPE disabled, '1'->OCiPE enabled 974 | (0<<0); //0b00->OCi as output 975 | TIM3->CCMR2 = TIM3->CCMR1; 976 | TIM3->CCER1 = (0<<5) | //OC2: 0->active high, 1->active low 977 | (0<<4) | //OC2: 1->enable OC2, 0->disable OC2 978 | (0<<1) | //OC1: 0->active high, 1->active low 979 | (0<<0) | //OC1: 1->enable OC2, 0->disable OC2 980 | 0x00; 981 | //OC3 not present on TIM3 982 | 983 | #endif //tim3 984 | 985 | 986 | #if defined(USE_ADC1) 987 | //route clock to ADC 988 | CLK->PCKENR2 |= CLK_PCKENR2_ADC; //'1'=clock enabled, '0'=clock disabled 989 | //configure the adc 990 | ADC1->CR1 = ((ADC1_PS)<<4) | //3-bit adc prescaler: 7 = Fmaster / 18, 6 = Fmaster / 12, ... 991 | 0x00; 992 | ADC1->CR2 = (0<<6) | //0->conversion on external trigger disabled 993 | (0<<4) | //0->external event -> TIM1 TRGO 994 | (1<<3) | //'1'->right aligned, '0'->left aligned 995 | (0<<1) | //'0'->scan disabled, '1'->scan enabled 996 | 0x00; 997 | ADC1->CR3 = (0<<7); //'0'->data buffer disabled, read from DRH..DRL 998 | ADC1->CR1 |= (1<<0); //turn on the adc 999 | #endif //ADC1 1000 | 1001 | //configure beep / tone generator 1002 | BEEP->CSR = (0x00 << 6) | //set divider: 0b00->Fls/8, 0b01->Fls/4, 0b1x->Fls/2. default: 8x 1003 | (0<<5) | //0->disable beep, 1->enable beep 1004 | (((128000ul/ F_TONE / 8 > 2)?(128000ul / F_TONE / 8 - 2):0) & 0x1f); //set beep divider. 0x00->2:1, 0x01->3:1, 0x1e->32:1 1005 | //tone off at start-up 1006 | 1007 | #if defined(USE_EXTI) 1008 | //configure EXTI 1009 | //use default / boot-up EXTI values 1010 | #endif //exti 1011 | 1012 | #if defined(USE_SPI) 1013 | //configure SPI 1014 | //route clock to SPI 1015 | CLK->PCKENR1 |= CLK_PCKENR1_SPI; //'1'=clock enabled, '0'=clock disabled 1016 | //stop spi 1017 | //SPI->CR1 &=~(1<<6); //'1'->enable spi, '0'->disable spi 1018 | //set up the clock ... 1019 | SPI->CR1 = (0<<7) | //'0'->MSB first, '1'->LSB first 1020 | (0<<6) | //'0'->spi disabled, '1'->spi enabled 1021 | (((SPI_PS) & 0x07) << 3) | //set 3-bit spi prescaler, 0..7 -> 2:1 ... 256:1 1022 | (1<<2) | //'1'->master, '0'->slave 1023 | (0<<1) | //'0'->SCK idles low, '1'->SCK idles high 1024 | (0<<0) | //'0'->the first clock transition is the first data capture edge, '1'->the second clock transition is the first data capture edge 1025 | 0x00; 1026 | SPI->CR2 = (0<<7) | //'0'->2-line unidirectional data mode, '1'->1-line bidirectional data mode 1027 | (0<<6) | //'0'->input enabled (receive-only mode), '1'->output enabled (transmit only mode) 1028 | (0<<5) | //'0'->CRC calculation disabled, '1'->CRC calculation enabled 1029 | (0<<4) | //'0'->next transmit value is from Tx buffer, '1'->next transmit value is from Tx CRC register 1030 | (0<<2) | //'0'->full duplex (transmit and receive), '1'->output disabled (receive inly) 1031 | (0<<1) | //'0'->software slave management disabled, '1'->software slave management enabled 1032 | (0<<0) | //'0'->slave mode, '1'->Master mode. This bit has effect only when SSM bit (bit 1 of CR2) is set 1033 | 0x00; 1034 | SPI->ICR = (0<<7) | //'0'->disable TX interrupt 1035 | (0<<6) | //'0'->disable RX interrupt 1036 | (0<<5) | //'0'->disable spi error interrupt 1037 | (0<<4) | //'0'->disable spi wakeup interrupt 1038 | 0x00; 1039 | SPI->SR = 0; //'0'->clear all error status 1040 | SPI->DR = 0; //clear spi data register 1041 | SPI->CR1|= (1<<6); //'0'->disable spi, '1'->enable spi 1042 | //spi is now enabled 1043 | #endif //spi 1044 | 1045 | #if defined(USE_I2C) 1046 | //configure i2c 1047 | //route clock to i2c 1048 | CLK->PCKENR1 |= CLK_PCKENR1_I2C; //'1'=clock enabled, '0'=clock disabled 1049 | //configure i2c 1050 | I2C->CR1 &=~(1<<0); //'0'->disable i2c, '1'->enable i2c 1051 | I2C->CR2 = (0<<7) | //'0'->software reset disabled, '1'->software reset enabled 1052 | (0<<3) | //'0'->ACK bit controls acknowledge, '1'->ACK bit controls the next byte 1053 | (0<<2) | //'0'->no ACK returned, '1'->ACK returned. can only be set after PE = 1 1054 | (0<<1) | //'0'->don't generate stop condition, '1'->generate a stop condition 1055 | (0<<0) | //'0'->don't generate a start condition, '1'->generate a start condition 1056 | 0x00; 1057 | I2C->FREQR = clockCyclesPerMicrosecond(); 1058 | I2C->FREQR = (I2C->FREQR>=24)?24:((I2C->FREQR==0)?1:I2C->FREQR); //top at 24Mhz, and bottom at 1Mhz 1059 | I2C->CCRL = (clockCyclesPerMicrosecond() * 10); 1060 | I2C->CCRH = (clockCyclesPerMicrosecond() * 10) >> 8; 1061 | #if defined(I2C_FASTMODE) 1062 | I2C->CCRH = (I2C->CCRH & 0x0f) | //lowest 4 bits effective 1063 | (1<<7) | //'1'->fast mode, '0'->standard mode 1064 | (0<<6) | //'1'->duty cycle 9/(16+9), '0'->duty cycle 2/(3+2) 1065 | 0x00; 1066 | #else 1067 | I2C->CCRH = (I2C->CCRH & 0x0f) | //lowest 4 bits effective 1068 | (0<<7) | //'1'->fast mode, '0'->standard mode 1069 | (0<<6) | //'1'->duty cycle 9/(16+9), '0'->duty cycle 2/(3+2) 1070 | 0x00; 1071 | #endif 1072 | I2C->OARH = (0<<7) | //'0'-> 7-bit addressing, '1'->10-bit addressing 1073 | (1<<6) | //ADDCONF bit ***must always be 1*** 1074 | (0x00<<1) | //bit 9..8 of 10-bit own address 1075 | 0x00; 1076 | I2C->OARL = 0x00; //own address, bit 0 don't care 1077 | //I2C->TRISER must be configured before the I2C is turned on 1078 | //1000ns for standard mode and 300ns for fast mode 1079 | if (I2C->CR2 & (1<<7)) { //fast mode 1080 | I2C->TRISER = I2C->FREQR + 1; //simple math to configure I2C rise time to 1000ns for standard mode 1081 | } else { //slow mode 1082 | I2C->TRISER = I2C->FREQR * 3 / 10 + 1; //simple math to configure I2C rise time to 300ns for fast mode 1083 | } 1084 | //clear interrupt flags and then enable interrupt 1085 | 1086 | //enable i2c 1087 | I2C->CR1 |= (1<<0); //enable i2c 1088 | //enable ACK 1089 | I2C->CR2 |= (1<<2); //'1'->send ACK,'0'->don't send ACK - can only be set after PE = 1 1090 | #endif //i2c 1091 | 1092 | //always enable interrupts - for micros/millis 1093 | interrupts(); 1094 | } 1095 | 1096 | //templated code for main() 1097 | int main(void) { 1098 | mcu_init(); //reset the chip 1099 | setup(); //user-set up the code 1100 | while (1) { 1101 | loop(); //user specified loop 1102 | } 1103 | return 0; 1104 | } 1105 | 1106 | -------------------------------------------------------------------------------- /stm8sduino.h: -------------------------------------------------------------------------------- 1 | //Arduino port for STM8S family 2 | //software environment: IAR EMSTM8 + STM8S.h from ST Standard Peripheral Library 3 | //versin v0.15a 6/16/2017 4 | //added support for COSMIC and RAISONANCE compilers, in addition to IAR 5 | // 6 | //version v0.15 6/9/2017 7 | //rewrote to enhance portability 8 | // 9 | //version v0.13 6/3/2017 10 | //added I2C support 11 | // 12 | //version v0.12a 6/3/2017 13 | //added support for UART1 as well 14 | //added support for user-configurability of hardware modules -> to help manage code size on smaller chips 15 | // 16 | //version v0.12 @ 6/2/2017 17 | //added serial support off uart2: serial_begin(), serial_println(), serial_print(), serial_write(), serial_read() and serila_available() 18 | //added hardware spi support: SPIshiftOut(), and SPIshiftIn() 19 | // 20 | //version: v0.11a @ 5/29/2017 21 | //added support for attachInterrupt() and detachInterrupt() 22 | // 23 | //version: v0.11 @ 5/28/2017 24 | //added support for analogWrite() and analogRead() 25 | //added support for tone() and noTone() 26 | //added support for pulseIn() 27 | // 28 | //version: v0.10 @ 5/26/2017 29 | //initiaial release, support for STM8S chips 30 | // 31 | //Supported functions: 32 | //GPIO: pinMode(), digitalWrite(), digitalRead() 33 | //Time: millis(), micros(), delay(), delayMicroseconds() 34 | //Math: min(), max(), abs(), constrain(), map(), pow(), sqrt() 35 | //Trigonometry: sin(), cos(), tan() 36 | //Characters: isAlphaNumeric(), isAlpha(), isAscii(), isWhitespace(), isControl(), isDigit(), isGraph(), isLowerCase(), isPrintable, isPunct(), isSpace(), isUpperCase(), isHexadecimalDigit() 37 | //Random Numbers: randomSeed(), random(max). random(min, max) ported to random2(min, max) 38 | //Bits and Bytes: lowByte(), highByte(), bitRead(), bitWrite(), bitSet(), bitClear(), bit() 39 | //Analog IO: analogRead(), analogWrite(), analogReference() 40 | //Advanced IO: tone(), noTone(), shiftOut(), shiftIn(), pulseIn() 41 | //External Interrupts: attachInterrupt(), detachInterrupt() 42 | //Serial: Serial_begin(), Serial_write(), Serial_read(), Serial_print(), Serial_println(), Serial_available() 43 | // 44 | //STM8Sduino extensions: 45 | //DAC: DAC1Write(), DAC2Write() 46 | //SPI: SPIshiftOut(), SPIshiftIn() 47 | //I2C: I2C_start(), I2C_writeaddr(), I2C_write(), I2C_read(), I2C_stop() 48 | //Serial1: Serial1_begin(), Serial1_write(), Serial1_read(), Serial1_print(), Serial1_println(), Serial1_available() 49 | //Serial2: Serial2_begin(), Serial2_write(), Serial2_read(), Serial2_print(), Serial2_println(), Serial2_available() 50 | 51 | #ifndef _STM8Sduino_H 52 | #define _STM8Sduino_H 53 | 54 | #include //we use rand() 55 | #include //we use char-functions 56 | #include "stm8s.h" //we use spl's register definitions 57 | 58 | //STM8Sduino module configuration 59 | //comment out the follow macros to disable a hardware functionality 60 | //default: use all 61 | //Peripherals always used: GPIO, TIM4 62 | #define USE_PWM1 //comment out if not used - pwm using tim1 63 | #define USE_PWM2 //comment out if not used - pwm using tim2 64 | #define USE_PWM3 //comment out if not used - pwm using tim3 65 | #define USE_EXTI //comment out if not used 66 | #define USE_ADC1 //comment out if not used 67 | //#define USE_ADC2 //comment out if not used - not present on all chips 68 | #define USE_DAC //comment out if not used 69 | #define USE_SPI //comment out if not used 70 | #define USE_SPI //comment out if not used 71 | #define USE_I2C //comment out if not used 72 | #define USE_UART1 //comment out if not used - present on 003, 103, 207, 208 73 | #define USE_UART2 //comment out if not used - present on 005, 105 74 | //end STM8Sduino module configuration 75 | 76 | //STM8Sduino hardware configuration 77 | #define PWMOUT_BITs 12 //in bits. PWM output / analogWrite() resolution. 8-14 suggested -> default = 12bits 78 | #define PWMOUT_PS 1 //3-bit PMWOUT prescaler. 0x00->1:1, ..., 0x07->128:1, for timer1/2/3 79 | #define ADC1_PS 2 //3-bit ADC prescaler. 0x00->2:1, ...0x07 = 18:1 80 | #define TIM4_PS 7 //tim4 (time base for micros() and millis()) 3-bit prescaler, valid values: [0..7]. 2^TIM4_PS, 128x max 81 | #define SPI_PS 7 //3-bit SPI prescaler. [0..7]: 0->2:1, 7->256:1 82 | //#define I2C_FASTMODE //uncomment for standard mode (100Khz). 83 | #define F_TONE 1000 //beep frequency, in Hz. 500 - 8000. 84 | //end STM8Sduino hardware configuration 85 | 86 | //global defines 87 | //gpio enums - needs to match GPIO_PinDef[] 88 | typedef enum { 89 | PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, //PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, //GPIOA pin defs 90 | PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, //PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15, //GPIOB pin defs 91 | PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, //PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15, //GPIOC pin defs 92 | PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, //PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15, //GPIOD pin defs 93 | PE0, PE1, PE2, PE3, PE4, PE5, PE6, PE7, //PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15, //GPIOE pin defs 94 | PF0, PF1, PF2, PF3, PF4, PF5, PF6, PF7, //PF8, PF9, PF10, PF11, PF12, PF13, PF14, PF15, //GPIOF pin defs 95 | #if defined(GPIOG) 96 | PG0, PG1, PG2, PG3, PG4, PG5, PG6, PG7, //PG8, PG9, PG10, PG11, PG12, PG13, PG14, PG15, //GPIOG pin defs 97 | #endif 98 | #if defined(GPIOH) 99 | PH0, PH1, PH2, PH3, PH4, PH5, PH6, PH7, //PH8, PH9, PH10, PH11, PH12, PH13, PH14, PH15, //GPIOH pin defs 100 | #endif 101 | #if defined(GPIOI) 102 | PI0, PI1, PI2, PI3, PI4, PI5, PI6, PI7, //PI8, PI9, PI10, PI11, PI12, PI13, PI14, PI15, //GPIOI pin defs 103 | #endif 104 | PINMAX //max pin. for error checking 105 | } PIN_TypeDef; 106 | 107 | //analog input enum for analogRead() - not all channells are present on all chips/packages 108 | typedef enum { 109 | A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, 110 | //AVREFINT, //A16=Vrefint. nominal 1.20v 111 | //ATEMP, //A17=temperature sensor 112 | AINMAX //for error checking 113 | } AIN_TypeDef; 114 | 115 | //port/gpio oriented macros 116 | #define GIO_SET(port, pins) port->ODR |= (pins) //set bits on port 117 | #define GIO_CLR(port, pins) port->ODR &=~(pins) //clear bits on port 118 | #define GIO_FLP(port, pins) port->ODR ^= (pins) //flip bits on port 119 | #define GIO_GET(port, pins) ((port->IDR) & (pins)) //return bits on port 120 | //set a pin to output/input 121 | #define GIO_OUTPP(port, pins) do {port->DDR |= (pins); port->CR1 |= (pins); port->CR2 &=~(pins);} while (0) //push-pull mode (CR1 set, CR2 cleared) //IO_OUTPP(GPIOx, GPIO_Pins). 122 | #define GIO_OUTOD(port, pins) do {port->DDR |= (pins); port->CR1 &=~(pins); port->CR2 &=~(pins);} while (0) //open drain mode (cr1 + cr2 cleared) //_GPIO_Init(GPIOx, GPIO_Pins, GPIO_MODE_OUT_OD_LOW_FAST) 123 | #define GIO_OUT(port, pins) GIO_OUTPP(port, pins) //_GPIO_Init(GPIOx, GPIO_Pins, GPIO_MODE_OUT_PP_LOW_FAST) 124 | #define GIO_INFL(port, pins) do {port->DDR &=~(pins); port->CR1 &=~(pins); port->CR2 &=~(pins);} while (0) //floating input, no interrupt //IO_INFL(GPIOx, GPIO_Pins) 125 | #define GIO_INPU(port, pins) do {port->DDR &=~(pins); port->CR1 |= (pins); port->CR2 &=~(pins);} while (0) //pull-up, no interrupt //_GPIO_Init(GPIOx, GPIO_Pins, GPIO_MODE_IN_PU_NO_IT) 126 | #define GIO_INFLINT(port, pins) do {port->DDR &=~(pins); port->CR1 &=~(pins); port->CR2 |= (pins);} while (0) //floating input, with interrupt //IO_INFL(GPIOx, GPIO_Pins) 127 | #define GIO_INPUINT(port, pins) do {port->DDR &=~(pins); port->CR1 |= (pins); port->CR2 |= (pins);} while (0) //pull-up, with interrupt //_GPIO_Init(GPIOx, GPIO_Pins, GPIO_MODE_IN_PU_NO_IT) 128 | #define GIO_IN(port, pins) GIO_INFL(port, pins) //IO_IN(port, pins) //_GPIO_Init(GPIOx, GPIO_Pins, GPIO_MODE_IN_FL_NO_IT) 129 | 130 | //extension of pinMode, starting with 4 131 | #define OUTPUT_OD (INPUT_PULLUP+1) 132 | 133 | #define NOP() nop() //__no_operation() //asm("nop") //nop 134 | #define NOP2() {NOP(); NOP();} 135 | #define NOP4() {NOP2(); NOP2();} 136 | #define NOP8() {NOP4(); NOP4();} 137 | #define NOP16() {NOP8(); NOP8();} 138 | #define NOP16() {NOP8(); NOP8();} 139 | #define NOP24() {NOP16(); NOP8();} 140 | #define NOP32() {NOP16(); NOP16();} 141 | #define NOP40() {NOP32(); NOP8();} 142 | #define NOP64() {NOP32(); NOP32();} 143 | 144 | #ifndef ei 145 | #define ei() enableInterrupts() //asm("rim") //enable all interrupts 146 | #endif 147 | 148 | #ifndef di 149 | #define di() disableInterrupts() //asm("sim") //disable all interrupts 150 | #endif 151 | 152 | #define F_CPU (SystemCoreClock + 0*16000000ul / 1) //default fcpu @ 2Mhz = IntRC@16Mhz / 8. or use SystemCoreClock -> more code space (+200 bytes) 153 | 154 | //clock configuration 155 | #define CLK_PRESCALER_CPUDIV1 0x00 //cpu / 1 156 | #define CLK_PRESCALER_CPUDIV2 0x01 //cpu / 2 157 | #define CLK_PRESCALER_CPUDIV4 0x02 //cpu / 4 158 | #define CLK_PRESCALER_CPUDIV8 0x03 //cpu / 8 159 | #define CLK_PRESCALER_CPUDIV16 0x04 //cpu / 16 160 | #define CLK_PRESCALER_CPUDIV32 0x05 //cpu / 32 161 | #define CLK_PRESCALER_CPUDIV64 0x06 //cpu / 64 162 | #define CLK_PRESCALER_CPUDIV128 0x07 //cpu / 128 163 | #define CLK_PRESCALER_HSIDIV1 (0<<3) //hsi divider 1:1 164 | #define CLK_PRESCALER_HSIDIV2 (1<<3) //hsi divider 2:1 165 | #define CLK_PRESCALER_HSIDIV4 (2<<3) //hsi divider 4:1 166 | #define CLK_PRESCALER_HSIDIV8 (3<<3) //hsi divider 8:1 167 | 168 | //#define PWM_MAXDC 0x3fff //max duty cycle for tim1/12-bit 169 | 170 | //use hsi oscillator 171 | void SystemCoreClockHSI(uint8_t CLK_HSIDIV); 172 | 173 | //oscillator macros for HSI + dividers 174 | #define SystemCoreClockHSI_16MHz() SystemCoreClockHSI(CLK_PRESCALER_HSIDIV1) 175 | #define SystemCoreClockHSI_8MHz() SystemCoreClockHSI(CLK_PRESCALER_HSIDIV2) 176 | #define SystemCoreClockHSI_4MHz() SystemCoreClockHSI(CLK_PRESCALER_HSIDIV4) 177 | #define SystemCoreClockHSI_2MHz() SystemCoreClockHSI(CLK_PRESCALER_HSIDIV8) 178 | 179 | //arduino-specific defs 180 | #define INPUT 0 181 | #define OUTPUT 1 //(!INPUT) 182 | #define INPUT_PULLUP 2 //input with pull-up 183 | //device specific defitions exist 184 | 185 | #define LOW 0 186 | #define HIGH 1 //(!LOW) 187 | 188 | #define PI 3.1415926535897932384626433832795 189 | #define HALF_PI (PI / 2) //1.5707963267948966192313216916398 190 | #define TWO_PI (PI + PI) //6.283185307179586476925286766559 191 | #define DEG_TO_RAD (TWO_PI / 360) //0.017453292519943295769236907684886 192 | #define RAD_TO_DEG (360 / TWO_PI) //57.295779513082320876798154814105 193 | #define EULER 2.718281828459045235360287471352 //Euler's number 194 | 195 | #define SERIAL 0x0 196 | #define DISPLAY 0x1 197 | 198 | #define LSBFIRST 0 199 | #define MSBFIRST 1 //(!LSBFIRST) //1 200 | 201 | #define CHANGE 1 202 | #define FALLING 2 203 | #define RISING 3 204 | 205 | #define min(a,b) ((a)<(b)?(a):(b)) 206 | #define max(a,b) ((a)>(b)?(a):(b)) 207 | #define abs(x) ((x)>0?(x):-(x)) 208 | #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) 209 | #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) 210 | #define radians(deg) ((deg)*DEG_TO_RAD) 211 | #define degrees(rad) ((rad)*RAD_TO_DEG) 212 | #define sq(x) ((x)*(x)) 213 | 214 | #define interrupts() ei() 215 | #define noInterrupts() di() 216 | 217 | #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) 218 | #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) 219 | #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) 220 | 221 | #define lowByte(w) ((uint8_t) ((w) & 0xff)) 222 | #define highByte(w) ((uint8_t) ((w) >> 8)) 223 | 224 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 225 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 226 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 227 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 228 | #define bit(n) (1ul<<(n)) 229 | 230 | #define false 0 231 | #define true (!false) 232 | 233 | //characters 234 | #define isAlphaNumeric(c) isalnum(c) 235 | #define isAlpha(c) isalpha(c) 236 | #define isAscii(c) isascii(c) 237 | #define isWhitespace(c) isblank(c) 238 | #define isControl(c) iscntrl(c) 239 | #define isDigit(c) isdigit(c) 240 | #define isGraph(c) isgraph(c) 241 | #define isLowerCase(c) islower(c) 242 | #define isPrintable(c) isprint(c) 243 | #define isPunct(c) ispunct(c) 244 | #define isSpace(c) isspace(c) 245 | #define isUpperCase(c) isupper(c) 246 | #define isHexadecimalDigit(c) isxdigit(c) 247 | 248 | //random number 249 | #define randomSeed(seed) srand(seed) 250 | #define random(max) random2(0, max) 251 | #define random2(min, max) ((min) + (int32_t) ((max) - (min)) * rand() / 32768) 252 | 253 | //random() will need manual porting 254 | 255 | //external setup/loop - defined by user 256 | extern void setup(void); 257 | extern void loop(void); 258 | 259 | //gpio 260 | void pinMode(PIN_TypeDef pin, uint8_t mode); 261 | void digitalWrite(PIN_TypeDef pin, uint8_t mode); 262 | int digitalRead(PIN_TypeDef pin); 263 | 264 | //time base 265 | uint32_t millis(void); 266 | uint32_t micros(void); 267 | uint32_t ticks(void); 268 | void delay(uint32_t ms); 269 | void delayMicroseconds(uint32_t us); 270 | 271 | //advanced io 272 | //shiftin/out: bitOrder = MSBFIRST or LSBFIRST 273 | void tone(void); //tone frequency specified by F_TONE in STM8Sduino.h 274 | void noTone(void); 275 | uint8_t shiftIn(PIN_TypeDef dataPin, PIN_TypeDef clockPin, uint8_t bitOrder); 276 | void shiftOut(PIN_TypeDef dataPin, PIN_TypeDef clockPin, uint8_t bitOrder, uint8_t val); 277 | //wait for a pulse and return timing 278 | uint32_t pulseIn(PIN_TypeDef pin, uint8_t state); 279 | 280 | //pwm output 281 | //dc = 0x00..0x0fff for pwm2/3/4/5, 0x00..0xffff for pwm1 282 | //RP4=PWM1, RP12=PWM2, RP13=PWM3, RP14=PWM4, RP15=PWM5 283 | void analogWrite(PIN_TypeDef pin, uint16_t dc); 284 | 285 | //analog read on ADC1 286 | //read DRL first for right aligned results 287 | uint16_t analogRead(AIN_TypeDef ain); 288 | 289 | //analog reference - not applicable for STM8S 290 | #define analogReference(x) 291 | 292 | //external interrupt 293 | void attachInterrupt(PIN_TypeDef pin, void (*isrptr)(void), uint8_t mode); 294 | void detachInterrupt(PIN_TypeDef pin); 295 | 296 | //stm8s extensions 297 | //spi 298 | uint8_t SPIWrite(uint8_t order, uint8_t dat); 299 | uint8_t SPIWrites(uint8_t order, uint8_t *dat, uint16_t length); 300 | uint8_t SPIRead(uint8_t order); 301 | 302 | //i2c 303 | void I2CStart(void); 304 | void I2CStop(); 305 | void I2CWriteaddr(uint8_t addr); 306 | void I2CWrite(uint8_t dat); 307 | uint8_t I2CRead(uint8_t ack); 308 | #define I2CRestart() do {I2C_stop(); I2C_start();} while (0) 309 | 310 | //return time base ticks 311 | uint32_t ticks(void); 312 | 313 | //uart1 314 | void serial1Begin(uint32_t baudrate); 315 | void serial1Print(unsigned char *str); 316 | void serial1Println(unsigned char *str); 317 | void serial1Write(unsigned char ch); 318 | unsigned char serial1Read(void); 319 | uint8_t serial2Available(void); 320 | //uart2 321 | void serial2Begin(uint32_t baudrate); 322 | void serial2Print(unsigned char *str); 323 | void serial2Println(unsigned char *str); 324 | void serial2Write(unsigned char ch); 325 | unsigned char serial2Read(void); 326 | uint8_t serial2Available(void); 327 | //serial defaults to uart2 328 | #if defined(UART1) 329 | #define serialBegin serial1Begin 330 | #define serialPrint serial1Print 331 | #define serialPrintln serial1Println 332 | #define serialWrite serial1Write 333 | #define serialRead serial1Read 334 | #define serialAvailable serial1Available 335 | #else 336 | #define serialBegin serial2Begin 337 | #define serialPrint serial2Print 338 | #define serialPrintln serial2Println 339 | #define serialWrite serial2Write 340 | #define serialRead serial2Read 341 | #define serialAvailable serial2Available 342 | #endif 343 | //end stm8s extensions 344 | 345 | //interrupt from iostm8s105c6.h - don't change 346 | /*------------------------------------------------------------------------- 347 | * Interrupt vector numbers 348 | *-----------------------------------------------------------------------*/ 349 | #define AWU_vector 0x03 350 | #define CLK_CSS_vector 0x04 351 | #define CLK_SWITCH_vector 0x04 352 | #define EXTI0_vector 0x05 353 | #define EXTI1_vector 0x06 354 | #define EXTI2_vector 0x07 355 | #define EXTI3_vector 0x08 356 | #define EXTI4_vector 0x09 357 | #define SPI_CRCERR_vector 0x0C 358 | #define SPI_MODF_vector 0x0C 359 | #define SPI_OVR_vector 0x0C 360 | #define SPI_RXNE_vector 0x0C 361 | #define SPI_TXE_vector 0x0C 362 | #define SPI_WKUP_vector 0x0C 363 | #define TIM1_OVR_BIF_vector 0x0D 364 | #define TIM1_OVR_TIF_vector 0x0D 365 | #define TIM1_OVR_UIF_vector 0x0D 366 | #define TIM1_CAPCOM_CC1IF_vector 0x0E 367 | #define TIM1_CAPCOM_CC2IF_vector 0x0E 368 | #define TIM1_CAPCOM_CC3IF_vector 0x0E 369 | #define TIM1_CAPCOM_CC4IF_vector 0x0E 370 | #define TIM1_CAPCOM_COMIF_vector 0x0E 371 | #define TIM2_OVR_UIF_vector 0x0F 372 | #define TIM3_OVR_UIF_vector 0x11 373 | #define TIM2_CAPCOM_CC1IF_vector 0x10 374 | #define TIM2_CAPCOM_CC2IF_vector 0x10 375 | #define TIM2_CAPCOM_CC3IF_vector 0x10 376 | #define TIM2_CAPCOM_TIF_vector 0x10 377 | #define TIM3_CAPCOM_CC1IF_vector 0x12 378 | #define TIM3_CAPCOM_CC2IF_vector 0x12 379 | #define TIM3_CAPCOM_CC3IF_vector 0x12 380 | #define TIM3_CAPCOM_TIF_vector 0x12 381 | #define I2C_ADD10_vector 0x15 382 | #define I2C_ADDR_vector 0x15 383 | #define I2C_AF_vector 0x15 384 | #define I2C_ARLO_vector 0x15 385 | #define I2C_BERR_vector 0x15 386 | #define I2C_BTF_vector 0x15 387 | #define I2C_OVR_vector 0x15 388 | #define I2C_RXNE_vector 0x15 389 | #define I2C_SB_vector 0x15 390 | #define I2C_STOPF_vector 0x15 391 | #define I2C_TXE_vector 0x15 392 | #define I2C_WUFH_vector 0x15 393 | #define UART2_T_TC_vector 0x16 394 | #define UART2_T_TXE_vector 0x16 395 | #define UART2_R_IDLE_vector 0x17 396 | #define UART2_R_LBDF_vector 0x17 397 | #define UART2_R_OR_vector 0x17 398 | #define UART2_R_PE_vector 0x17 399 | #define UART2_R_RXNE_vector 0x17 400 | #define ADC1_AWDG_vector 0x18 401 | #define ADC1_AWS0_vector 0x18 402 | #define ADC1_AWS1_vector 0x18 403 | #define ADC1_AWS2_vector 0x18 404 | #define ADC1_AWS3_vector 0x18 405 | #define ADC1_AWS4_vector 0x18 406 | #define ADC1_AWS5_vector 0x18 407 | #define ADC1_AWS6_vector 0x18 408 | #define ADC1_AWS7_vector 0x18 409 | #define ADC1_AWS8_vector 0x18 410 | #define ADC1_AWS9_vector 0x18 411 | #define ADC1_EOC_vector 0x18 412 | #define TIM4_OVR_UIF_vector 0x19 413 | #define FLASH_EOP_vector 0x1A 414 | #define FLASH_WR_PG_DIS_vector 0x1A 415 | 416 | #ifdef _COSMIC_ 417 | #define inline //no inline for cosmic 418 | #endif 419 | #endif 420 | -------------------------------------------------------------------------------- /user-code.c: -------------------------------------------------------------------------------- 1 | #include "stm8sduino.h" //include stm8suduino defs 2 | 3 | #define LED PD0 //LED attached to pin 24 (=PD0 on STM8SDiscovery) 4 | #define LED_DLY 100 //waste some time, in ms 5 | #define AIN 0 //ADC ch0 6 | #define BTN PC5 //(8*2+5) //pin 21 = PC5 7 | #define LOOP_CNT 1 8 | 9 | //flip led 10 | void led_flp(void) { 11 | if (digitalRead(BTN)==HIGH) digitalWrite(LED, HIGH); 12 | else digitalWrite(LED, LOW); 13 | //digitalWrite(LED, !digitalRead(LED)); 14 | } 15 | 16 | //user setup 17 | void setup(void) { 18 | pinMode(LED, OUTPUT); digitalWrite(LED, LOW); //set LED as output 19 | pinMode(BTN, INPUT_PULLUP); 20 | //attachInterrupt(BTN, led_flp, CHANGE); //test exti 21 | //DAC1Write(100); //test dac 22 | //serialBegin(9600); 23 | } 24 | 25 | volatile uint32_t time0, time1; 26 | 27 | //user loop 28 | void loop(void) { 29 | uint16_t i; 30 | 31 | #if 0 32 | //test adc 33 | time0=ticks(); 34 | for (i=0; i10) NOP(); 37 | #endif 38 | 39 | //test GPIO 40 | time0=ticks(); 41 | for(i=0; i10) NOP(); 44 | 45 | //test timing 46 | time0=ticks(); 47 | delay(LED_DLY); //waste sometime 48 | time1=ticks() - time0; 49 | if (time1>10) NOP(); 50 | 51 | #if 0 52 | //test Uart2 53 | time0=micros(); 54 | Serial_print("0123456789012345678901234567890123456789"); 55 | time1=micros() - time0; 56 | if (time1>100) NOP(); 57 | #endif 58 | 59 | #if 0 60 | //test spi 61 | time0=micros(); 62 | for (i=0; i<1000; i++) SPIshiftOut(MSBFIRST, 0x55); 63 | time1=micros() - time0; 64 | if (time1>100) NOP(); 65 | #endif 66 | 67 | #if 0 68 | //test i2c 69 | time0=micros(); 70 | for (i=0; i<1000; i++) I2C_write(0x55); 71 | time1=micros() - time0; 72 | if (time1>100) NOP(); 73 | #endif 74 | } 75 | --------------------------------------------------------------------------------