├── .gitmodules ├── Makefile ├── README.md ├── chconf.h ├── cmd.sh ├── halconf.h ├── lcdiic.c ├── lcdiic.h ├── main.c ├── mcuconf.h ├── pcf8574.c ├── pcf8574.h └── stm32f030f4-dev-v1.0 ├── STM32F030x4.ld ├── board.c ├── board.h └── board.mk /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "chibios"] 2 | path = chibios 3 | url = https://github.com/ChibiOS/ChibiOS.git 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Build global options 3 | # NOTE: Can be overridden externally. 4 | # 5 | 6 | # Compiler options here. 7 | ifeq ($(USE_OPT),) 8 | USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 9 | endif 10 | 11 | # C specific options here (added to USE_OPT). 12 | ifeq ($(USE_COPT),) 13 | USE_COPT = 14 | endif 15 | 16 | # C++ specific options here (added to USE_OPT). 17 | ifeq ($(USE_CPPOPT),) 18 | USE_CPPOPT = -fno-rtti 19 | endif 20 | 21 | # Enable this if you want the linker to remove unused code and data 22 | ifeq ($(USE_LINK_GC),) 23 | USE_LINK_GC = yes 24 | endif 25 | 26 | # Linker extra options here. 27 | ifeq ($(USE_LDOPT),) 28 | USE_LDOPT = 29 | endif 30 | 31 | # Enable this if you want link time optimizations (LTO) 32 | ifeq ($(USE_LTO),) 33 | USE_LTO = yes 34 | endif 35 | 36 | # If enabled, this option allows to compile the application in THUMB mode. 37 | ifeq ($(USE_THUMB),) 38 | USE_THUMB = yes 39 | endif 40 | 41 | # Enable this if you want to see the full log while compiling. 42 | ifeq ($(USE_VERBOSE_COMPILE),) 43 | USE_VERBOSE_COMPILE = no 44 | endif 45 | 46 | # If enabled, this option makes the build process faster by not compiling 47 | # modules not used in the current configuration. 48 | ifeq ($(USE_SMART_BUILD),) 49 | USE_SMART_BUILD = yes 50 | endif 51 | 52 | # 53 | # Build global options 54 | ############################################################################## 55 | 56 | ############################################################################## 57 | # Architecture or project specific options 58 | # 59 | 60 | # Stack size to be allocated to the Cortex-M process stack. This stack is 61 | # the stack used by the main() thread. 62 | ifeq ($(USE_PROCESS_STACKSIZE),) 63 | USE_PROCESS_STACKSIZE = 0x200 64 | endif 65 | 66 | # Stack size to the allocated to the Cortex-M main/exceptions stack. This 67 | # stack is used for processing interrupts and exceptions. 68 | ifeq ($(USE_EXCEPTIONS_STACKSIZE),) 69 | USE_EXCEPTIONS_STACKSIZE = 0x200 70 | endif 71 | 72 | # Enables the use of FPU (no, softfp, hard). 73 | ifeq ($(USE_FPU),) 74 | USE_FPU = no 75 | endif 76 | 77 | # 78 | # Architecture or project specific options 79 | ############################################################################## 80 | 81 | ############################################################################## 82 | # Project, sources and paths 83 | # 84 | 85 | # Define project name here 86 | PROJECT = ch 87 | 88 | # Imported source files and paths 89 | CHIBIOS = chibios 90 | # Startup files. 91 | include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f0xx.mk 92 | # HAL-OSAL files (optional). 93 | include $(CHIBIOS)/os/hal/hal.mk 94 | include $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/platform.mk 95 | include $(CHIBIOS)/../stm32f030f4-dev-v1.0/board.mk 96 | include $(CHIBIOS)/os/hal/osal/rt/osal.mk 97 | # RTOS files (optional). 98 | include $(CHIBIOS)/os/rt/rt.mk 99 | include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk 100 | # Other files (optional). 101 | include $(CHIBIOS)/test/rt/test.mk 102 | include $(CHIBIOS)/os/hal/lib/streams/streams.mk 103 | include $(CHIBIOS)/os/various/shell/shell.mk 104 | 105 | # Define linker script file here 106 | LDSCRIPT = stm32f030f4-dev-v1.0/STM32F030x4.ld 107 | 108 | # C sources that can be compiled in ARM or THUMB mode depending on the global 109 | # setting. 110 | CSRC = $(STARTUPSRC) \ 111 | $(KERNSRC) \ 112 | $(PORTSRC) \ 113 | $(OSALSRC) \ 114 | $(HALSRC) \ 115 | $(PLATFORMSRC) \ 116 | $(BOARDSRC) \ 117 | $(TESTSRC) \ 118 | $(STREAMSSRC) \ 119 | $(SHELLSRC) \ 120 | $(USERSRC) \ 121 | main.c pcf8574.c lcdiic.c 122 | 123 | # C++ sources that can be compiled in ARM or THUMB mode depending on the global 124 | # setting. 125 | CPPSRC = 126 | 127 | # C sources to be compiled in ARM mode regardless of the global setting. 128 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 129 | # option that results in lower performance and larger code size. 130 | ACSRC = 131 | 132 | # C++ sources to be compiled in ARM mode regardless of the global setting. 133 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 134 | # option that results in lower performance and larger code size. 135 | ACPPSRC = 136 | 137 | # C sources to be compiled in THUMB mode regardless of the global setting. 138 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 139 | # option that results in lower performance and larger code size. 140 | TCSRC = 141 | 142 | # C sources to be compiled in THUMB mode regardless of the global setting. 143 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 144 | # option that results in lower performance and larger code size. 145 | TCPPSRC = 146 | 147 | # List ASM source files here 148 | ASMSRC = 149 | ASMXSRC = $(STARTUPASM) $(PORTASM) $(OSALASM) 150 | 151 | INCDIR = $(CHIBIOS)/os/license \ 152 | $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \ 153 | $(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \ 154 | $(STREAMSINC) $(SHELLINC) $(USERINC) 155 | 156 | # 157 | # Project, sources and paths 158 | ############################################################################## 159 | 160 | ############################################################################## 161 | # Compiler settings 162 | # 163 | 164 | MCU = cortex-m0 165 | 166 | #TRGT = arm-elf- 167 | TRGT = arm-none-eabi- 168 | CC = $(TRGT)gcc 169 | CPPC = $(TRGT)g++ 170 | # Enable loading with g++ only if you need C++ runtime support. 171 | # NOTE: You can use C++ even without C++ support if you are careful. C++ 172 | # runtime support makes code size explode. 173 | LD = $(TRGT)gcc 174 | #LD = $(TRGT)g++ 175 | CP = $(TRGT)objcopy 176 | AS = $(TRGT)gcc -x assembler-with-cpp 177 | AR = $(TRGT)ar 178 | OD = $(TRGT)objdump 179 | SZ = $(TRGT)size 180 | HEX = $(CP) -O ihex 181 | BIN = $(CP) -O binary 182 | 183 | # ARM-specific options here 184 | AOPT = 185 | 186 | # THUMB-specific options here 187 | TOPT = -mthumb -DTHUMB 188 | 189 | # Define C warning options here 190 | CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes 191 | 192 | # Define C++ warning options here 193 | CPPWARN = -Wall -Wextra -Wundef 194 | 195 | # 196 | # Compiler settings 197 | ############################################################################## 198 | 199 | ############################################################################## 200 | # Start of user section 201 | # 202 | 203 | # List all user C define here, like -D_DEBUG=1 204 | UDEFS = -DCHPRINTF_USE_FLOAT=0 205 | 206 | # Define ASM defines here 207 | UADEFS = 208 | 209 | # List all user directories here 210 | UINCDIR = 211 | 212 | # List the user directory to look for the libraries here 213 | ULIBDIR = 214 | 215 | # List all user libraries here 216 | ULIBS = 217 | 218 | # 219 | # End of user defines 220 | ############################################################################## 221 | 222 | RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC 223 | include $(RULESPATH)/rules.mk 224 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ### Using I2C Serial Interface Module For 1602 LCD Display 3 | 4 | ![](https://www.brobwind.com/wp-content/uploads/2016/12/2016_12_10_lcdiic.png) 5 | 6 | #### Hardware requirements: 7 | ###### 1. STM32F030F4-DEV V1.0 8 | 9 | | Device | configuration | 10 | | ------ | ------------------------ | 11 | | MCU | STM32F030F4P6 | 12 | | HSE | 8MHz | 13 | | USART1 | TX - PA2, RX - PA3 | 14 | | I2C1 | SCL - PA9, SDA - PA10 | 15 | | LED | PA4 | 16 | 17 | ###### 2. Serial LCD I2C Module - PCF8574T 18 | - Pin assignment 19 | 20 | | PCF8574T | 1602 LCD | 21 | | -------- | ----------| 22 | | P0 | RS | 23 | | P1 | RW | 24 | | P2 | E | 25 | | P3 | BL | 26 | | P4 | D4 | 27 | | P5 | D5 | 28 | | P6 | D6 | 29 | | P7 | D7 | 30 | 31 | ###### 3. Two 1602 LCD displays: 32 | - Primary display(I2C address: 0x3e) will show: 33 | 1. OS name and version: ChibiOS/RT 4.0.0 34 | 2. System ticks 35 | - Secondary display(I2C address: 0x3f) will show: 36 | 1. Board name: STM32F030F4-DEV 37 | 2. Unique Device ID (12 bytes) 38 | 39 | #### Software requirements: 40 | - ChibiOS/RT: Commit ID: af64942 41 | 42 | #### For detail info, please refer: 43 | https://www.brobwind.com/archives/1324 44 | -------------------------------------------------------------------------------- /chconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file templates/chconf.h 19 | * @brief Configuration file template. 20 | * @details A copy of this file must be placed in each project directory, it 21 | * contains the application specific kernel settings. 22 | * 23 | * @addtogroup config 24 | * @details Kernel related settings and hooks. 25 | * @{ 26 | */ 27 | 28 | #ifndef CHCONF_H 29 | #define CHCONF_H 30 | 31 | #define _CHIBIOS_RT_CONF_ 32 | 33 | /*===========================================================================*/ 34 | /** 35 | * @name System timers settings 36 | * @{ 37 | */ 38 | /*===========================================================================*/ 39 | 40 | /** 41 | * @brief System time counter resolution. 42 | * @note Allowed values are 16 or 32 bits. 43 | */ 44 | #define CH_CFG_ST_RESOLUTION 32 45 | 46 | /** 47 | * @brief System tick frequency. 48 | * @details Frequency of the system timer that drives the system ticks. This 49 | * setting also defines the system tick time unit. 50 | */ 51 | #define CH_CFG_ST_FREQUENCY 1000 52 | 53 | /** 54 | * @brief Time delta constant for the tick-less mode. 55 | * @note If this value is zero then the system uses the classic 56 | * periodic tick. This value represents the minimum number 57 | * of ticks that is safe to specify in a timeout directive. 58 | * The value one is not valid, timeouts are rounded up to 59 | * this value. 60 | */ 61 | #define CH_CFG_ST_TIMEDELTA 0 62 | 63 | /** @} */ 64 | 65 | /*===========================================================================*/ 66 | /** 67 | * @name Kernel parameters and options 68 | * @{ 69 | */ 70 | /*===========================================================================*/ 71 | 72 | /** 73 | * @brief Round robin interval. 74 | * @details This constant is the number of system ticks allowed for the 75 | * threads before preemption occurs. Setting this value to zero 76 | * disables the preemption for threads with equal priority and the 77 | * round robin becomes cooperative. Note that higher priority 78 | * threads can still preempt, the kernel is always preemptive. 79 | * @note Disabling the round robin preemption makes the kernel more compact 80 | * and generally faster. 81 | * @note The round robin preemption is not supported in tickless mode and 82 | * must be set to zero in that case. 83 | */ 84 | #define CH_CFG_TIME_QUANTUM 0 85 | 86 | /** 87 | * @brief Managed RAM size. 88 | * @details Size of the RAM area to be managed by the OS. If set to zero 89 | * then the whole available RAM is used. The core memory is made 90 | * available to the heap allocator and/or can be used directly through 91 | * the simplified core memory allocator. 92 | * 93 | * @note In order to let the OS manage the whole RAM the linker script must 94 | * provide the @p __heap_base__ and @p __heap_end__ symbols. 95 | * @note Requires @p CH_CFG_USE_MEMCORE. 96 | */ 97 | #define CH_CFG_MEMCORE_SIZE 0 98 | 99 | /** 100 | * @brief Idle thread automatic spawn suppression. 101 | * @details When this option is activated the function @p chSysInit() 102 | * does not spawn the idle thread. The application @p main() 103 | * function becomes the idle thread and must implement an 104 | * infinite loop. 105 | */ 106 | #define CH_CFG_NO_IDLE_THREAD FALSE 107 | 108 | /** @} */ 109 | 110 | /*===========================================================================*/ 111 | /** 112 | * @name Performance options 113 | * @{ 114 | */ 115 | /*===========================================================================*/ 116 | 117 | /** 118 | * @brief OS optimization. 119 | * @details If enabled then time efficient rather than space efficient code 120 | * is used when two possible implementations exist. 121 | * 122 | * @note This is not related to the compiler optimization options. 123 | * @note The default is @p TRUE. 124 | */ 125 | #define CH_CFG_OPTIMIZE_SPEED TRUE 126 | 127 | /** @} */ 128 | 129 | /*===========================================================================*/ 130 | /** 131 | * @name Subsystem options 132 | * @{ 133 | */ 134 | /*===========================================================================*/ 135 | 136 | /** 137 | * @brief Time Measurement APIs. 138 | * @details If enabled then the time measurement APIs are included in 139 | * the kernel. 140 | * 141 | * @note The default is @p TRUE. 142 | */ 143 | #define CH_CFG_USE_TM FALSE 144 | 145 | /** 146 | * @brief Threads registry APIs. 147 | * @details If enabled then the registry APIs are included in the kernel. 148 | * 149 | * @note The default is @p TRUE. 150 | */ 151 | #define CH_CFG_USE_REGISTRY TRUE 152 | 153 | /** 154 | * @brief Threads synchronization APIs. 155 | * @details If enabled then the @p chThdWait() function is included in 156 | * the kernel. 157 | * 158 | * @note The default is @p TRUE. 159 | */ 160 | #define CH_CFG_USE_WAITEXIT TRUE 161 | 162 | /** 163 | * @brief Semaphores APIs. 164 | * @details If enabled then the Semaphores APIs are included in the kernel. 165 | * 166 | * @note The default is @p TRUE. 167 | */ 168 | #define CH_CFG_USE_SEMAPHORES TRUE 169 | 170 | /** 171 | * @brief Semaphores queuing mode. 172 | * @details If enabled then the threads are enqueued on semaphores by 173 | * priority rather than in FIFO order. 174 | * 175 | * @note The default is @p FALSE. Enable this if you have special 176 | * requirements. 177 | * @note Requires @p CH_CFG_USE_SEMAPHORES. 178 | */ 179 | #define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE 180 | 181 | /** 182 | * @brief Mutexes APIs. 183 | * @details If enabled then the mutexes APIs are included in the kernel. 184 | * 185 | * @note The default is @p TRUE. 186 | */ 187 | #define CH_CFG_USE_MUTEXES TRUE 188 | 189 | /** 190 | * @brief Enables recursive behavior on mutexes. 191 | * @note Recursive mutexes are heavier and have an increased 192 | * memory footprint. 193 | * 194 | * @note The default is @p FALSE. 195 | * @note Requires @p CH_CFG_USE_MUTEXES. 196 | */ 197 | #define CH_CFG_USE_MUTEXES_RECURSIVE FALSE 198 | 199 | /** 200 | * @brief Conditional Variables APIs. 201 | * @details If enabled then the conditional variables APIs are included 202 | * in the kernel. 203 | * 204 | * @note The default is @p TRUE. 205 | * @note Requires @p CH_CFG_USE_MUTEXES. 206 | */ 207 | #define CH_CFG_USE_CONDVARS TRUE 208 | 209 | /** 210 | * @brief Conditional Variables APIs with timeout. 211 | * @details If enabled then the conditional variables APIs with timeout 212 | * specification are included in the kernel. 213 | * 214 | * @note The default is @p TRUE. 215 | * @note Requires @p CH_CFG_USE_CONDVARS. 216 | */ 217 | #define CH_CFG_USE_CONDVARS_TIMEOUT TRUE 218 | 219 | /** 220 | * @brief Events Flags APIs. 221 | * @details If enabled then the event flags APIs are included in the kernel. 222 | * 223 | * @note The default is @p TRUE. 224 | */ 225 | #define CH_CFG_USE_EVENTS TRUE 226 | 227 | /** 228 | * @brief Events Flags APIs with timeout. 229 | * @details If enabled then the events APIs with timeout specification 230 | * are included in the kernel. 231 | * 232 | * @note The default is @p TRUE. 233 | * @note Requires @p CH_CFG_USE_EVENTS. 234 | */ 235 | #define CH_CFG_USE_EVENTS_TIMEOUT TRUE 236 | 237 | /** 238 | * @brief Synchronous Messages APIs. 239 | * @details If enabled then the synchronous messages APIs are included 240 | * in the kernel. 241 | * 242 | * @note The default is @p TRUE. 243 | */ 244 | #define CH_CFG_USE_MESSAGES TRUE 245 | 246 | /** 247 | * @brief Synchronous Messages queuing mode. 248 | * @details If enabled then messages are served by priority rather than in 249 | * FIFO order. 250 | * 251 | * @note The default is @p FALSE. Enable this if you have special 252 | * requirements. 253 | * @note Requires @p CH_CFG_USE_MESSAGES. 254 | */ 255 | #define CH_CFG_USE_MESSAGES_PRIORITY FALSE 256 | 257 | /** 258 | * @brief Mailboxes APIs. 259 | * @details If enabled then the asynchronous messages (mailboxes) APIs are 260 | * included in the kernel. 261 | * 262 | * @note The default is @p TRUE. 263 | * @note Requires @p CH_CFG_USE_SEMAPHORES. 264 | */ 265 | #define CH_CFG_USE_MAILBOXES TRUE 266 | 267 | /** 268 | * @brief Core Memory Manager APIs. 269 | * @details If enabled then the core memory manager APIs are included 270 | * in the kernel. 271 | * 272 | * @note The default is @p TRUE. 273 | */ 274 | #define CH_CFG_USE_MEMCORE TRUE 275 | 276 | /** 277 | * @brief Heap Allocator APIs. 278 | * @details If enabled then the memory heap allocator APIs are included 279 | * in the kernel. 280 | * 281 | * @note The default is @p TRUE. 282 | * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or 283 | * @p CH_CFG_USE_SEMAPHORES. 284 | * @note Mutexes are recommended. 285 | */ 286 | #define CH_CFG_USE_HEAP TRUE 287 | 288 | /** 289 | * @brief Memory Pools Allocator APIs. 290 | * @details If enabled then the memory pools allocator APIs are included 291 | * in the kernel. 292 | * 293 | * @note The default is @p TRUE. 294 | */ 295 | #define CH_CFG_USE_MEMPOOLS TRUE 296 | 297 | /** 298 | * @brief Dynamic Threads APIs. 299 | * @details If enabled then the dynamic threads creation APIs are included 300 | * in the kernel. 301 | * 302 | * @note The default is @p TRUE. 303 | * @note Requires @p CH_CFG_USE_WAITEXIT. 304 | * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. 305 | */ 306 | #define CH_CFG_USE_DYNAMIC TRUE 307 | 308 | /** @} */ 309 | 310 | /*===========================================================================*/ 311 | /** 312 | * @name Debug options 313 | * @{ 314 | */ 315 | /*===========================================================================*/ 316 | 317 | /** 318 | * @brief Debug option, kernel statistics. 319 | * 320 | * @note The default is @p FALSE. 321 | */ 322 | #define CH_DBG_STATISTICS FALSE 323 | 324 | /** 325 | * @brief Debug option, system state check. 326 | * @details If enabled the correct call protocol for system APIs is checked 327 | * at runtime. 328 | * 329 | * @note The default is @p FALSE. 330 | */ 331 | #define CH_DBG_SYSTEM_STATE_CHECK FALSE 332 | 333 | /** 334 | * @brief Debug option, parameters checks. 335 | * @details If enabled then the checks on the API functions input 336 | * parameters are activated. 337 | * 338 | * @note The default is @p FALSE. 339 | */ 340 | #define CH_DBG_ENABLE_CHECKS FALSE 341 | 342 | /** 343 | * @brief Debug option, consistency checks. 344 | * @details If enabled then all the assertions in the kernel code are 345 | * activated. This includes consistency checks inside the kernel, 346 | * runtime anomalies and port-defined checks. 347 | * 348 | * @note The default is @p FALSE. 349 | */ 350 | #define CH_DBG_ENABLE_ASSERTS FALSE 351 | 352 | /** 353 | * @brief Debug option, trace buffer. 354 | * @details If enabled then the trace buffer is activated. 355 | * 356 | * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. 357 | */ 358 | #define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED 359 | 360 | /** 361 | * @brief Trace buffer entries. 362 | * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is 363 | * different from @p CH_DBG_TRACE_MASK_DISABLED. 364 | */ 365 | #define CH_DBG_TRACE_BUFFER_SIZE 128 366 | 367 | /** 368 | * @brief Debug option, stack checks. 369 | * @details If enabled then a runtime stack check is performed. 370 | * 371 | * @note The default is @p FALSE. 372 | * @note The stack check is performed in a architecture/port dependent way. 373 | * It may not be implemented or some ports. 374 | * @note The default failure mode is to halt the system with the global 375 | * @p panic_msg variable set to @p NULL. 376 | */ 377 | #define CH_DBG_ENABLE_STACK_CHECK FALSE 378 | 379 | /** 380 | * @brief Debug option, stacks initialization. 381 | * @details If enabled then the threads working area is filled with a byte 382 | * value when a thread is created. This can be useful for the 383 | * runtime measurement of the used stack. 384 | * 385 | * @note The default is @p FALSE. 386 | */ 387 | #define CH_DBG_FILL_THREADS FALSE 388 | 389 | /** 390 | * @brief Debug option, threads profiling. 391 | * @details If enabled then a field is added to the @p thread_t structure that 392 | * counts the system ticks occurred while executing the thread. 393 | * 394 | * @note The default is @p FALSE. 395 | * @note This debug option is not currently compatible with the 396 | * tickless mode. 397 | */ 398 | #define CH_DBG_THREADS_PROFILING FALSE 399 | 400 | /** @} */ 401 | 402 | /*===========================================================================*/ 403 | /** 404 | * @name Kernel hooks 405 | * @{ 406 | */ 407 | /*===========================================================================*/ 408 | 409 | /** 410 | * @brief Threads descriptor structure extension. 411 | * @details User fields added to the end of the @p thread_t structure. 412 | */ 413 | #define CH_CFG_THREAD_EXTRA_FIELDS \ 414 | /* Add threads custom fields here.*/ 415 | 416 | /** 417 | * @brief Threads initialization hook. 418 | * @details User initialization code added to the @p chThdInit() API. 419 | * 420 | * @note It is invoked from within @p chThdInit() and implicitly from all 421 | * the threads creation APIs. 422 | */ 423 | #define CH_CFG_THREAD_INIT_HOOK(tp) { \ 424 | /* Add threads initialization code here.*/ \ 425 | } 426 | 427 | /** 428 | * @brief Threads finalization hook. 429 | * @details User finalization code added to the @p chThdExit() API. 430 | */ 431 | #define CH_CFG_THREAD_EXIT_HOOK(tp) { \ 432 | /* Add threads finalization code here.*/ \ 433 | } 434 | 435 | /** 436 | * @brief Context switch hook. 437 | * @details This hook is invoked just before switching between threads. 438 | */ 439 | #define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ 440 | /* Context switch code here.*/ \ 441 | } 442 | 443 | /** 444 | * @brief ISR enter hook. 445 | */ 446 | #define CH_CFG_IRQ_PROLOGUE_HOOK() { \ 447 | /* IRQ prologue code here.*/ \ 448 | } 449 | 450 | /** 451 | * @brief ISR exit hook. 452 | */ 453 | #define CH_CFG_IRQ_EPILOGUE_HOOK() { \ 454 | /* IRQ epilogue code here.*/ \ 455 | } 456 | 457 | /** 458 | * @brief Idle thread enter hook. 459 | * @note This hook is invoked within a critical zone, no OS functions 460 | * should be invoked from here. 461 | * @note This macro can be used to activate a power saving mode. 462 | */ 463 | #define CH_CFG_IDLE_ENTER_HOOK() { \ 464 | /* Idle-enter code here.*/ \ 465 | } 466 | 467 | /** 468 | * @brief Idle thread leave hook. 469 | * @note This hook is invoked within a critical zone, no OS functions 470 | * should be invoked from here. 471 | * @note This macro can be used to deactivate a power saving mode. 472 | */ 473 | #define CH_CFG_IDLE_LEAVE_HOOK() { \ 474 | /* Idle-leave code here.*/ \ 475 | } 476 | 477 | /** 478 | * @brief Idle Loop hook. 479 | * @details This hook is continuously invoked by the idle thread loop. 480 | */ 481 | #define CH_CFG_IDLE_LOOP_HOOK() { \ 482 | /* Idle loop code here.*/ \ 483 | } 484 | 485 | /** 486 | * @brief System tick event hook. 487 | * @details This hook is invoked in the system tick handler immediately 488 | * after processing the virtual timers queue. 489 | */ 490 | #define CH_CFG_SYSTEM_TICK_HOOK() { \ 491 | /* System tick event code here.*/ \ 492 | } 493 | 494 | /** 495 | * @brief System halt hook. 496 | * @details This hook is invoked in case to a system halting error before 497 | * the system is halted. 498 | */ 499 | #define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ 500 | /* System halt code here.*/ \ 501 | } 502 | 503 | /** 504 | * @brief Trace hook. 505 | * @details This hook is invoked each time a new record is written in the 506 | * trace buffer. 507 | */ 508 | #define CH_CFG_TRACE_HOOK(tep) { \ 509 | /* Trace code here.*/ \ 510 | } 511 | 512 | /** @} */ 513 | 514 | /*===========================================================================*/ 515 | /* Port-specific settings (override port settings defaulted in chcore.h). */ 516 | /*===========================================================================*/ 517 | 518 | #endif /* CHCONF_H */ 519 | 520 | /** @} */ 521 | -------------------------------------------------------------------------------- /cmd.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e -x 3 | 4 | FW=build/ch.bin 5 | ADDRESS=0x08000000 6 | 7 | OCD=/usr/local/bin/openocd 8 | #${OCD} -f interface/stlink-v2-1.cfg -f target/stm32f0x.cfg -c init -c "reset halt" -c "stm32f1x unlock 0" -c "reset halt" -c "exit" 9 | ${OCD} -f interface/stlink-v2-1.cfg -f target/stm32f0x.cfg -c init -c "reset halt" \ 10 | -c "flash write_image erase ${FW} ${ADDRESS} bin" \ 11 | -c "verify_image ${FW} ${ADDRESS} bin" -c "reset run" -c shutdown 12 | -------------------------------------------------------------------------------- /halconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file templates/halconf.h 19 | * @brief HAL configuration header. 20 | * @details HAL configuration file, this file allows to enable or disable the 21 | * various device drivers from your application. You may also use 22 | * this file in order to override the device drivers default settings. 23 | * 24 | * @addtogroup HAL_CONF 25 | * @{ 26 | */ 27 | 28 | #ifndef _HALCONF_H_ 29 | #define _HALCONF_H_ 30 | 31 | #include "mcuconf.h" 32 | 33 | /** 34 | * @brief Enables the PAL subsystem. 35 | */ 36 | #if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) 37 | #define HAL_USE_PAL TRUE 38 | #endif 39 | 40 | /** 41 | * @brief Enables the ADC subsystem. 42 | */ 43 | #if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) 44 | #define HAL_USE_ADC FALSE 45 | #endif 46 | 47 | /** 48 | * @brief Enables the CAN subsystem. 49 | */ 50 | #if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) 51 | #define HAL_USE_CAN FALSE 52 | #endif 53 | 54 | /** 55 | * @brief Enables the DAC subsystem. 56 | */ 57 | #if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) 58 | #define HAL_USE_DAC FALSE 59 | #endif 60 | 61 | /** 62 | * @brief Enables the EXT subsystem. 63 | */ 64 | #if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) 65 | #define HAL_USE_EXT FALSE 66 | #endif 67 | 68 | /** 69 | * @brief Enables the GPT subsystem. 70 | */ 71 | #if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) 72 | #define HAL_USE_GPT FALSE 73 | #endif 74 | 75 | /** 76 | * @brief Enables the I2C subsystem. 77 | */ 78 | #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) 79 | #define HAL_USE_I2C TRUE 80 | #endif 81 | 82 | /** 83 | * @brief Enables the I2S subsystem. 84 | */ 85 | #if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) 86 | #define HAL_USE_I2S FALSE 87 | #endif 88 | 89 | /** 90 | * @brief Enables the ICU subsystem. 91 | */ 92 | #if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) 93 | #define HAL_USE_ICU FALSE 94 | #endif 95 | 96 | /** 97 | * @brief Enables the MAC subsystem. 98 | */ 99 | #if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) 100 | #define HAL_USE_MAC FALSE 101 | #endif 102 | 103 | /** 104 | * @brief Enables the MMC_SPI subsystem. 105 | */ 106 | #if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) 107 | #define HAL_USE_MMC_SPI FALSE 108 | #endif 109 | 110 | /** 111 | * @brief Enables the PWM subsystem. 112 | */ 113 | #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) 114 | #define HAL_USE_PWM FALSE 115 | #endif 116 | 117 | /** 118 | * @brief Enables the RTC subsystem. 119 | */ 120 | #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) 121 | #define HAL_USE_RTC FALSE 122 | #endif 123 | 124 | /** 125 | * @brief Enables the SDC subsystem. 126 | */ 127 | #if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) 128 | #define HAL_USE_SDC FALSE 129 | #endif 130 | 131 | /** 132 | * @brief Enables the SERIAL subsystem. 133 | */ 134 | #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) 135 | #define HAL_USE_SERIAL TRUE 136 | #endif 137 | 138 | /** 139 | * @brief Enables the SERIAL over USB subsystem. 140 | */ 141 | #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 142 | #define HAL_USE_SERIAL_USB FALSE 143 | #endif 144 | 145 | /** 146 | * @brief Enables the SPI subsystem. 147 | */ 148 | #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) 149 | #define HAL_USE_SPI FALSE 150 | #endif 151 | 152 | /** 153 | * @brief Enables the UART subsystem. 154 | */ 155 | #if !defined(HAL_USE_UART) || defined(__DOXYGEN__) 156 | #define HAL_USE_UART FALSE 157 | #endif 158 | 159 | /** 160 | * @brief Enables the USB subsystem. 161 | */ 162 | #if !defined(HAL_USE_USB) || defined(__DOXYGEN__) 163 | #define HAL_USE_USB FALSE 164 | #endif 165 | 166 | /** 167 | * @brief Enables the WDG subsystem. 168 | */ 169 | #if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) 170 | #define HAL_USE_WDG FALSE 171 | #endif 172 | 173 | /*===========================================================================*/ 174 | /* ADC driver related settings. */ 175 | /*===========================================================================*/ 176 | 177 | /** 178 | * @brief Enables synchronous APIs. 179 | * @note Disabling this option saves both code and data space. 180 | */ 181 | #if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) 182 | #define ADC_USE_WAIT TRUE 183 | #endif 184 | 185 | /** 186 | * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. 187 | * @note Disabling this option saves both code and data space. 188 | */ 189 | #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 190 | #define ADC_USE_MUTUAL_EXCLUSION TRUE 191 | #endif 192 | 193 | /*===========================================================================*/ 194 | /* CAN driver related settings. */ 195 | /*===========================================================================*/ 196 | 197 | /** 198 | * @brief Sleep mode related APIs inclusion switch. 199 | */ 200 | #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) 201 | #define CAN_USE_SLEEP_MODE TRUE 202 | #endif 203 | 204 | /*===========================================================================*/ 205 | /* I2C driver related settings. */ 206 | /*===========================================================================*/ 207 | 208 | /** 209 | * @brief Enables the mutual exclusion APIs on the I2C bus. 210 | */ 211 | #if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 212 | #define I2C_USE_MUTUAL_EXCLUSION TRUE 213 | #endif 214 | 215 | /*===========================================================================*/ 216 | /* MAC driver related settings. */ 217 | /*===========================================================================*/ 218 | 219 | /** 220 | * @brief Enables an event sources for incoming packets. 221 | */ 222 | #if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) 223 | #define MAC_USE_ZERO_COPY FALSE 224 | #endif 225 | 226 | /** 227 | * @brief Enables an event sources for incoming packets. 228 | */ 229 | #if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) 230 | #define MAC_USE_EVENTS TRUE 231 | #endif 232 | 233 | /*===========================================================================*/ 234 | /* MMC_SPI driver related settings. */ 235 | /*===========================================================================*/ 236 | 237 | /** 238 | * @brief Delays insertions. 239 | * @details If enabled this options inserts delays into the MMC waiting 240 | * routines releasing some extra CPU time for the threads with 241 | * lower priority, this may slow down the driver a bit however. 242 | * This option is recommended also if the SPI driver does not 243 | * use a DMA channel and heavily loads the CPU. 244 | */ 245 | #if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) 246 | #define MMC_NICE_WAITING TRUE 247 | #endif 248 | 249 | /*===========================================================================*/ 250 | /* SDC driver related settings. */ 251 | /*===========================================================================*/ 252 | 253 | /** 254 | * @brief Number of initialization attempts before rejecting the card. 255 | * @note Attempts are performed at 10mS intervals. 256 | */ 257 | #if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) 258 | #define SDC_INIT_RETRY 100 259 | #endif 260 | 261 | /** 262 | * @brief Include support for MMC cards. 263 | * @note MMC support is not yet implemented so this option must be kept 264 | * at @p FALSE. 265 | */ 266 | #if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) 267 | #define SDC_MMC_SUPPORT FALSE 268 | #endif 269 | 270 | /** 271 | * @brief Delays insertions. 272 | * @details If enabled this options inserts delays into the MMC waiting 273 | * routines releasing some extra CPU time for the threads with 274 | * lower priority, this may slow down the driver a bit however. 275 | */ 276 | #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) 277 | #define SDC_NICE_WAITING TRUE 278 | #endif 279 | 280 | /*===========================================================================*/ 281 | /* SERIAL driver related settings. */ 282 | /*===========================================================================*/ 283 | 284 | /** 285 | * @brief Default bit rate. 286 | * @details Configuration parameter, this is the baud rate selected for the 287 | * default configuration. 288 | */ 289 | #if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) 290 | #define SERIAL_DEFAULT_BITRATE 115200 291 | #endif 292 | 293 | /** 294 | * @brief Serial buffers size. 295 | * @details Configuration parameter, you can change the depth of the queue 296 | * buffers depending on the requirements of your application. 297 | * @note The default is 16 bytes for both the transmission and receive 298 | * buffers. 299 | */ 300 | #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) 301 | #define SERIAL_BUFFERS_SIZE 16 302 | #endif 303 | 304 | /*===========================================================================*/ 305 | /* SERIAL_USB driver related setting. */ 306 | /*===========================================================================*/ 307 | 308 | /** 309 | * @brief Serial over USB buffers size. 310 | * @details Configuration parameter, the buffer size must be a multiple of 311 | * the USB data endpoint maximum packet size. 312 | * @note The default is 64 bytes for both the transmission and receive 313 | * buffers. 314 | */ 315 | #if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) 316 | #define SERIAL_USB_BUFFERS_SIZE 64 317 | #endif 318 | 319 | /** 320 | * @brief Serial over USB number of buffers. 321 | * @note The default is 2 buffers. 322 | */ 323 | #if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) 324 | #define SERIAL_USB_BUFFERS_NUMBER 2 325 | #endif 326 | 327 | /*===========================================================================*/ 328 | /* SPI driver related settings. */ 329 | /*===========================================================================*/ 330 | 331 | /** 332 | * @brief Enables synchronous APIs. 333 | * @note Disabling this option saves both code and data space. 334 | */ 335 | #if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) 336 | #define SPI_USE_WAIT TRUE 337 | #endif 338 | 339 | /** 340 | * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. 341 | * @note Disabling this option saves both code and data space. 342 | */ 343 | #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 344 | #define SPI_USE_MUTUAL_EXCLUSION TRUE 345 | #endif 346 | 347 | /*===========================================================================*/ 348 | /* UART driver related settings. */ 349 | /*===========================================================================*/ 350 | 351 | /** 352 | * @brief Enables synchronous APIs. 353 | * @note Disabling this option saves both code and data space. 354 | */ 355 | #if !defined(UART_USE_WAIT) || defined(__DOXYGEN__) 356 | #define UART_USE_WAIT FALSE 357 | #endif 358 | 359 | /** 360 | * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs. 361 | * @note Disabling this option saves both code and data space. 362 | */ 363 | #if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 364 | #define UART_USE_MUTUAL_EXCLUSION FALSE 365 | #endif 366 | 367 | /*===========================================================================*/ 368 | /* USB driver related settings. */ 369 | /*===========================================================================*/ 370 | 371 | /** 372 | * @brief Enables synchronous APIs. 373 | * @note Disabling this option saves both code and data space. 374 | */ 375 | #if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) 376 | #define USB_USE_WAIT FALSE 377 | #endif 378 | 379 | #endif /* _HALCONF_H_ */ 380 | 381 | /** @} */ 382 | -------------------------------------------------------------------------------- /lcdiic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 https://www.brobwind.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "hal.h" 17 | #include "lcdiic.h" 18 | 19 | 20 | /** 21 | * Reference manual: 22 | * 1. Datasheet: https://www.sparkfun.com/datasheets/LCD/HD44780.pdf 23 | * 2. Wiki: https://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller 24 | */ 25 | 26 | /*===========================================================================*/ 27 | /* Driver local functions. */ 28 | /*===========================================================================*/ 29 | 30 | static void lcdiicWriteLocked(LCDIICDriver *drvp, lcdiic_bus_mode_t mode, uint8_t val) { 31 | PCF8574Driver *portdrvp = drvp->config->drvp; 32 | uint8_t buf[6], cnt = 0; 33 | 34 | drvp->port.u.dt = (val >> 4) & 0x0F; 35 | buf[cnt++] = drvp->port.v; 36 | 37 | drvp->port.u.en = 0x01; 38 | buf[cnt++] = drvp->port.v; 39 | 40 | drvp->port.u.en = 0x00; 41 | buf[cnt++] = drvp->port.v; 42 | 43 | if (mode == LCDIIC_BUS_MODE_8BIT) { 44 | goto done; 45 | } 46 | 47 | drvp->port.u.dt = (val >> 0) & 0x0F; 48 | buf[cnt++] = drvp->port.v; 49 | 50 | drvp->port.u.en = 0x01; 51 | buf[cnt++] = drvp->port.v; 52 | 53 | drvp->port.u.en = 0x00; 54 | buf[cnt++] = drvp->port.v; 55 | 56 | done: 57 | pcf8574SetPort(portdrvp, 1, buf, cnt); 58 | 59 | // Max execution time(!Clear display & !Return home) is 37us when f(OSC) is 270kHz 60 | drvp->delayUs(37); 61 | } 62 | 63 | static msg_t lcdiicReadLocked(LCDIICDriver *drvp, lcdiic_bus_mode_t mode, uint8_t *val) { 64 | PCF8574Driver *portdrvp = drvp->config->drvp; 65 | lcdiic_port_cfg portval; 66 | msg_t ret; 67 | uint8_t buf[2]; 68 | 69 | drvp->port.u.dt = 0x0f; 70 | buf[0] = drvp->port.v; 71 | drvp->port.u.en = 0x01; 72 | buf[1] = drvp->port.v; 73 | pcf8574SetPort(portdrvp, 1, buf, 2); 74 | 75 | ret = pcf8574GetPortOb(portdrvp, &portval.v); 76 | if (ret != MSG_OK) goto out; 77 | 78 | *val = portval.u.dt << 4; 79 | 80 | if (mode == LCDIIC_BUS_MODE_8BIT) goto done; 81 | 82 | drvp->port.u.en = 0x00; 83 | buf[0] = drvp->port.v; 84 | drvp->port.u.en = 0x01; 85 | buf[1] = drvp->port.v; 86 | pcf8574SetPort(portdrvp, 1, buf, 2); 87 | 88 | ret = pcf8574GetPortOb(portdrvp, &portval.v); 89 | if (ret != MSG_OK) goto out; 90 | 91 | *val |= portval.u.dt; 92 | 93 | done: 94 | drvp->port.u.en = 0x00; 95 | pcf8574SetPortOb(portdrvp, 1, drvp->port.v); 96 | 97 | if (drvp->port.u.rs != 0x00 && drvp->port.u.rw != 0x01) { 98 | drvp->delayUs(37); 99 | } 100 | 101 | out: 102 | return ret; 103 | } 104 | 105 | /* Write to instruction register */ 106 | static void lcdiicIrWrite(LCDIICDriver *drvp, lcdiic_bus_mode_t mode, uint8_t val) { 107 | chMtxLock(&drvp->mutex); 108 | drvp->port.u.rs = 0x00; 109 | drvp->port.u.rw = 0x00; 110 | lcdiicWriteLocked(drvp, mode, val); 111 | chMtxUnlock(&drvp->mutex); 112 | } 113 | 114 | /* Check if busy: 0 - idle, 1 - busy */ 115 | static int8_t lcdiicCheckBusy(LCDIICDriver *drvp, lcdiic_bus_mode_t mode, uint8_t *addr) { 116 | uint8_t val; 117 | msg_t ret; 118 | 119 | chMtxLock(&drvp->mutex); 120 | drvp->port.u.rs = 0x00; 121 | drvp->port.u.rw = 0x01; 122 | ret = lcdiicReadLocked(drvp, mode, &val); 123 | chMtxUnlock(&drvp->mutex); 124 | 125 | if (addr != NULL) { 126 | *addr = (ret == MSG_OK) ? (val & LCD_ADDRESS_COUNTER) : 0xff; 127 | } 128 | 129 | return ret == MSG_OK ? (val & LCD_BUSY_FLAG) != 0 : 1; 130 | } 131 | 132 | /* Write to data register */ 133 | static void lcdiicDrWrite(LCDIICDriver *drvp, lcdiic_bus_mode_t mode, uint8_t val) { 134 | chMtxLock(&drvp->mutex); 135 | drvp->port.u.rs = 0x01; 136 | drvp->port.u.rw = 0x00; 137 | lcdiicWriteLocked(drvp, mode, val); 138 | chMtxUnlock(&drvp->mutex); 139 | } 140 | 141 | /* Read from data register */ 142 | static msg_t lcdiicDrRead(LCDIICDriver *drvp, lcdiic_bus_mode_t mode, uint8_t *val) { 143 | msg_t ret; 144 | 145 | chMtxLock(&drvp->mutex); 146 | drvp->port.u.rs = 0x01; 147 | drvp->port.u.rw = 0x01; 148 | ret = lcdiicReadLocked(drvp, mode, val); 149 | chMtxUnlock(&drvp->mutex); 150 | 151 | return ret; 152 | } 153 | 154 | static uint8_t isBusy(void *ip) { 155 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 156 | return lcdiicCheckBusy(drvp, LCDIIC_BUS_MODE_4BIT, NULL); 157 | } 158 | 159 | static void setBacklight(void *ip, uint8_t on) { 160 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 161 | PCF8574Driver *portdrvp = drvp->config->drvp; 162 | 163 | drvp->port.u.bl = !!on; 164 | pcf8574SetPortOb(portdrvp, 1, drvp->port.v); 165 | } 166 | 167 | static void toggleBacklight(void *ip) { 168 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 169 | 170 | setBacklight(drvp, !drvp->port.u.bl); 171 | } 172 | 173 | static void setDisplay(void *ip, uint8_t display, uint8_t cursor, uint8_t blink) { 174 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 175 | uint8_t ctrl = 0; 176 | 177 | if (display) ctrl |= LCD_DISPLAY_ON; 178 | if (cursor) ctrl |= LCD_CURSOR_ON; 179 | if (blink) ctrl |= LCD_CURSOR_BLINK_ON; 180 | 181 | lcdiicIrWrite(drvp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_DISPLAY_CONTROL | ctrl); 182 | } 183 | 184 | static void clearScreen(void *ip) { 185 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 186 | 187 | lcdiicIrWrite(drvp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_CLEAR_DISPLAY); 188 | drvp->delayMs(2); 189 | } 190 | 191 | static void shiftContent(void *ip, uint8_t display, uint8_t right) { 192 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 193 | uint8_t ctrl = 0; 194 | if (display) ctrl |= LCD_SHIFT_DISPLAY; 195 | if (right) ctrl |= LCD_SHIFT_TO_RIGHT; 196 | lcdiicIrWrite(drvp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_CONTENT_SHIFT | ctrl); 197 | } 198 | 199 | static void returnHome(void *ip) { 200 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 201 | 202 | lcdiicIrWrite(drvp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_RETURN_HOME); 203 | drvp->delayMs(2); 204 | } 205 | 206 | static void updatePattern(void *ip, uint8_t pos, const uint8_t *pat) { 207 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 208 | uint8_t idx; 209 | 210 | pos = (pos & 0x07) << 3; 211 | lcdiicIrWrite(drvp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_SET_CGRAM_ADDR | pos); 212 | 213 | for (idx = 0; idx < 8; idx++) { 214 | lcdiicDrWrite(drvp, LCDIIC_BUS_MODE_4BIT, pat[idx]); 215 | } 216 | } 217 | 218 | static void moveTo(void *ip, uint8_t row, uint8_t col) { 219 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 220 | uint8_t pos = (row * LCD_LINE_MAX_LEN + col) & LCD_DDRAM_ADDR_MASK; 221 | 222 | lcdiicIrWrite(drvp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_SET_DDRAM_ADDR | pos); 223 | } 224 | 225 | static msg_t readData(void *ip, uint8_t ddram, uint8_t offset, uint8_t *val) { 226 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 227 | uint8_t pos; 228 | 229 | if (ddram) { 230 | pos = offset & LCD_DDRAM_ADDR_MASK; 231 | lcdiicIrWrite(drvp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_SET_DDRAM_ADDR | pos); 232 | } else { 233 | pos = offset & LCD_CGRAM_ADDR_MASK; 234 | lcdiicIrWrite(drvp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_SET_CGRAM_ADDR | pos); 235 | } 236 | 237 | return lcdiicDrRead(drvp, LCDIIC_BUS_MODE_4BIT, val); 238 | } 239 | 240 | static void addChar(void *ip, uint8_t ch) { 241 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 242 | lcdiicDrWrite(drvp, LCDIIC_BUS_MODE_4BIT, ch); 243 | } 244 | 245 | static uint8_t drawText(void *ip, uint8_t row, uint8_t col, const char *text, uint8_t len) { 246 | LCDIICDriver *drvp = (LCDIICDriver *)ip; 247 | uint8_t idx; 248 | 249 | moveTo(drvp, row, col); 250 | 251 | for (idx = 0; idx < LCD_LINE_MAX_LEN && idx < len; idx++) { 252 | lcdiicDrWrite(drvp, LCDIIC_BUS_MODE_4BIT, text[idx]); 253 | } 254 | return idx; 255 | } 256 | 257 | static const struct LCDIICVMT vmt_lcdiic = { 258 | isBusy, setBacklight, toggleBacklight, setDisplay, clearScreen, 259 | shiftContent, returnHome, updatePattern, moveTo, readData, 260 | addChar, drawText, 261 | }; 262 | 263 | /*===========================================================================*/ 264 | /* Driver exported functions. */ 265 | /*===========================================================================*/ 266 | 267 | void lcdiicObjectInit(LCDIICDriver *devp, void (*delayUs)(uint32_t), void (*delayMs)(uint32_t)) { 268 | devp->vmt = &vmt_lcdiic; 269 | devp->delayUs = delayUs; 270 | devp->delayMs = delayMs; 271 | 272 | devp->port.v = 0x00; 273 | devp->port.u.bl = 0x01; 274 | 275 | devp->config = NULL; 276 | 277 | chMtxObjectInit(&devp->mutex); 278 | 279 | devp->state = LCDIIC_STOP; 280 | } 281 | 282 | void lcdiicStart(LCDIICDriver *devp, const LCDIICConfig *config) { 283 | chDbgCheck((devp != NULL) && (config != NULL)); 284 | 285 | chDbgAssert((devp->state == LCDIIC_STOP) || (devp->state == LCDIIC_READY), 286 | "lcdiicStart(), invalid state"); 287 | 288 | devp->config = config; 289 | 290 | /* LCD Initialize - 4-Bit Interface */ 291 | 292 | /* 1. Wait time > 40ms */ 293 | devp->delayMs(40); 294 | 295 | /* 2. Mode selection: from unknown mode to 4-bit mode */ 296 | /* https://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller */ 297 | /* - State1: 8-bit mode */ 298 | /* - State2: 4-bit mode, waiting for the first set of 4 bits */ 299 | /* - State3: 4-bit mode, waiting for the second set of 4 bits */ 300 | lcdiicIrWrite(devp, LCDIIC_BUS_MODE_8BIT, LCD_CMD_FUNCTION_SET | LCD_BUS_MODE); 301 | /* Wait time > 4.1ms */ 302 | devp->delayMs(5); 303 | 304 | lcdiicIrWrite(devp, LCDIIC_BUS_MODE_8BIT, LCD_CMD_FUNCTION_SET | LCD_BUS_MODE); 305 | /* Wait time > 100us */ 306 | devp->delayMs(1); 307 | 308 | /* The LCD is now in either state1 or state3 */ 309 | lcdiicIrWrite(devp, LCDIIC_BUS_MODE_8BIT, LCD_CMD_FUNCTION_SET | LCD_BUS_MODE); 310 | 311 | /* Now that the LCD is definitely in 8-bit mode, switch to 4-bit mode */ 312 | lcdiicIrWrite(devp, LCDIIC_BUS_MODE_8BIT, LCD_CMD_FUNCTION_SET); 313 | 314 | /* 3. Function set: number of display lines and character font */ 315 | lcdiicIrWrite(devp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_FUNCTION_SET | 316 | LCD_DISPLAY_MODE); // Set to 2-line and font size to 5x8 317 | 318 | /* 4. Display off */ 319 | lcdiicIrWrite(devp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_DISPLAY_CONTROL); 320 | 321 | /* 5. Display clear */ 322 | clearScreen(devp); 323 | 324 | /* 6. Entry mode set */ 325 | lcdiicIrWrite(devp, LCDIIC_BUS_MODE_4BIT, LCD_CMD_ENTRY_MODE_SET | LCD_ENTRY_MODE_INC); 326 | 327 | /* 7. Return home */ 328 | returnHome(devp); 329 | 330 | lcdiicCheckBusy(devp, LCDIIC_BUS_MODE_4BIT, NULL); 331 | 332 | /* 8. Display on, cursor off, blink off */ 333 | setDisplay(devp, 1, 0, 0); 334 | 335 | devp->state = LCDIIC_READY; 336 | } 337 | 338 | void lcdiicStop(LCDIICDriver *devp) { 339 | chDbgAssert((devp->state == LCDIIC_STOP) || (devp->state == LCDIIC_READY), 340 | "lcdiicStop(), invalid state"); 341 | 342 | /* 1. Display off */ 343 | setDisplay(devp, 0, 0, 0); 344 | 345 | /* 2. Backlight off */ 346 | setBacklight(devp, 0); 347 | 348 | devp->state = LCDIIC_STOP; 349 | } 350 | -------------------------------------------------------------------------------- /lcdiic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 https://www.brobwind.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __LCDIIC_H__ 17 | #define __LCDIIC_H__ 18 | 19 | #include "hal.h" 20 | #include "pcf8574.h" 21 | 22 | 23 | /*===========================================================================*/ 24 | /* Driver constants. */ 25 | /*===========================================================================*/ 26 | 27 | #define LCD_LINE_MAX_LEN 0x40 28 | 29 | /** 30 | * ========================================================= 31 | * DISPLAY CONTROL INSTRUCTION 32 | * ========================================================= 33 | */ 34 | 35 | /** 36 | * 1. Clear display 37 | * - Execution time: 1.52ms 38 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 39 | * 0 0 0 0 0 0 0 0 0 1 40 | */ 41 | #define LCD_CMD_CLEAR_DISPLAY 0x01 42 | 43 | /** 44 | * 2. Return home 45 | * - Execution time: 1.52ms 46 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 47 | * 0 0 0 0 0 0 0 0 1 - 48 | */ 49 | #define LCD_CMD_RETURN_HOME 0x02 50 | 51 | 52 | /** 53 | * 3. Entry mode set 54 | * - Execution time: 38us 55 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 56 | * 0 0 0 0 0 0 0 1 I/D SH 57 | * | `- Shift of entire display: 1 - shift 58 | * `- Increment/decrement of DDRAM address: 0 - dec, 1 - inc 59 | */ 60 | #define LCD_CMD_ENTRY_MODE_SET 0x04 61 | 62 | #define LCD_ENTRY_MODE_SHIFT 0x01 /* Shift of entire display */ 63 | #define LCD_ENTRY_MODE_INC 0x02 /* Increment of DDRAM address */ 64 | 65 | /** 66 | * 4. Display on/off control: 67 | * - Execution time: 38us 68 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 69 | * 0 0 0 0 0 0 1 D C B 70 | * | | `- Cursor Blink ON/OFF: 0 - off, 1 - on 71 | * | `- Cursor ON/OFF: 0 - off, 1 - on 72 | * `- Display ON/OFF: 0 - off, 1 - on 73 | */ 74 | #define LCD_CMD_DISPLAY_CONTROL 0x08 75 | 76 | #define LCD_CURSOR_BLINK_ON 0x01 /* Cursor blink on */ 77 | #define LCD_CURSOR_ON 0x02 /* Cursor on */ 78 | #define LCD_DISPLAY_ON 0x04 /* Display on */ 79 | 80 | /** 81 | * 5. Cursor or display shift 82 | * - Execution time: 38us 83 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 84 | * 0 0 0 0 0 1 S/C R/L - - 85 | * 0 0 - Shift cursor to the left, AC is decreased by 1 86 | * 0 1 - Shift cursor to the right, AC is increased by 1 87 | * 1 0 - Shift all the display to the left, cursor moves according to the display 88 | * 1 1 - Shift all the display to the right, cursor moves according to the display 89 | */ 90 | #define LCD_CMD_CONTENT_SHIFT 0x10 91 | 92 | #define LCD_SHIFT_TO_RIGHT 0x04 /* Shift to the right */ 93 | #define LCD_SHIFT_DISPLAY 0x08 /* Shift display */ 94 | 95 | /** 96 | * 6. Function set: 97 | * - Execution time: 38us 98 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 99 | * 0 0 0 0 1 DL N F - - 100 | * | | `- Display font type: 0 - 5x8 dots, 1 - 5x11 dots 101 | * | `- Display line number: 0 - 1-line, 1 - 2-line 102 | * `- Interface data length: 0 - 4-bit, 1 - 8 bit 103 | */ 104 | #define LCD_CMD_FUNCTION_SET 0x20 105 | 106 | #define LCD_DISPLAY_FONT_TYPE 0x04 /* 5x11 dots format display mode */ 107 | #define LCD_DISPLAY_MODE 0x08 /* 2-line display mode */ 108 | #define LCD_BUS_MODE 0x10 /* 8-bit bus mode */ 109 | 110 | /** 111 | * 7. Set CGRAM address 112 | * - Execution time: 38us 113 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 114 | * 0 0 0 1 AC5 AC4 AC3 AC2 AC1 AC0 115 | */ 116 | #define LCD_CMD_SET_CGRAM_ADDR 0x40 117 | 118 | #define LCD_CGRAM_ADDR_MASK 0x3f /* CGRAM address mask */ 119 | 120 | /** 121 | * 8. Set DDRAM address 122 | * - Execution time: 38us 123 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 124 | * 0 0 1 AC6 AC5 AC4 AC3 AC2 AC1 AC0 125 | */ 126 | #define LCD_CMD_SET_DDRAM_ADDR 0x80 127 | 128 | #define LCD_DDRAM_ADDR_MASK 0x7f /* DDRAM address mask */ 129 | 130 | /** 131 | * 9. Read busy flag & address 132 | * - Execution time: 0us 133 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 134 | * 0 1 BF AC6 AC5 AC4 AC3 AC2 AC1 AC0 135 | * `- busy flag: 0 - idle, 1 - busy 136 | */ 137 | #define LCD_ADDRESS_COUNTER 0x7f /* Address counter mask */ 138 | #define LCD_BUSY_FLAG 0x80 /* Read busy flag */ 139 | 140 | /** 141 | * 10. Write data from RAM 142 | * - Execution time: 38us 143 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 144 | * 1 0 D7 D6 D5 D4 D3 D2 D1 D0 145 | */ 146 | 147 | /** 148 | * 11. Read data from RAM 149 | * - Execution time: 38us 150 | * RS|R/W | DB7|DB6|DB5|DB4|DB3|DB2|DB1|DB0 151 | * 1 1 D7 D6 D5 D4 D3 D2 D1 D0 152 | */ 153 | 154 | /*===========================================================================*/ 155 | /* Driver data structures and types. */ 156 | /*===========================================================================*/ 157 | 158 | typedef enum { 159 | LCDIIC_UNINIT = 0, 160 | LCDIIC_STOP = 1, 161 | LCDIIC_READY = 2, 162 | } lcdiic_state_t; 163 | 164 | typedef enum { 165 | LCDIIC_BUS_MODE_4BIT = 0, 166 | LCDIIC_BUS_MODE_8BIT = 1, 167 | } lcdiic_bus_mode_t; 168 | 169 | typedef union { 170 | struct { 171 | uint8_t rs: 1; 172 | uint8_t rw: 1; 173 | uint8_t en: 1; 174 | uint8_t bl: 1; 175 | uint8_t dt: 4; 176 | } u; 177 | uint8_t v; 178 | } lcdiic_port_cfg; 179 | 180 | typedef struct { 181 | PCF8574Driver *drvp; 182 | const PCF8574Config *drvcfg; 183 | } LCDIICConfig; 184 | 185 | #define _lcdiic_methods \ 186 | uint8_t (*isBusy)(void *instance); \ 187 | void (*setBacklight)(void *instance, uint8_t on); \ 188 | void (*toggleBacklight)(void *instance); \ 189 | void (*setDisplay)(void *instance, uint8_t display, uint8_t cursor, uint8_t blink); \ 190 | void (*clearScreen)(void *instance); \ 191 | void (*shiftContent)(void *instance, uint8_t display, uint8_t right); \ 192 | void (*returnHome)(void *instance); \ 193 | void (*updatePattern)(void *instance, uint8_t pos, const uint8_t *pat); \ 194 | void (*moveTo)(void *instance, uint8_t row, uint8_t col); \ 195 | msg_t (*readData)(void *instance, uint8_t ddram, uint8_t offset, uint8_t *val); \ 196 | void (*addChar)(void *instance, uint8_t ch); \ 197 | uint8_t (*drawText)(void *instance, uint8_t row, uint8_t col, const char *text, uint8_t len); 198 | 199 | struct LCDIICVMT { 200 | _lcdiic_methods 201 | }; 202 | 203 | #define _lcdiic_data \ 204 | lcdiic_port_cfg port; \ 205 | lcdiic_state_t state; \ 206 | const LCDIICConfig *config; \ 207 | mutex_t mutex; 208 | 209 | typedef struct LCDIICDriver { 210 | const struct LCDIICVMT *vmt; 211 | void (*delayUs)(uint32_t val); 212 | void (*delayMs)(uint32_t val); 213 | _lcdiic_data; 214 | } LCDIICDriver; 215 | 216 | /*===========================================================================*/ 217 | /* Driver macros. */ 218 | /*===========================================================================*/ 219 | 220 | #define lcdiicIsBusy(ip) \ 221 | (ip)->vmt->isBusy(ip) 222 | 223 | #define lcdiicSetBacklight(ip, on) \ 224 | (ip)->vmt->setBacklight(ip, on) 225 | 226 | #define lcdiicToggleBacklight(ip) \ 227 | (ip)->vmt->toggleBacklight(ip) 228 | 229 | #define lcdiicSetDisplay(ip, display, cursor, blink) \ 230 | (ip)->vmt->setDisplay(ip, display, cursor, blink) 231 | 232 | #define lcdiicShiftContent(ip, display, right) \ 233 | (ip)->vmt->shiftContent(ip, display, right) 234 | 235 | #define lcdiicClearScreen(ip) \ 236 | (ip)->vmt->clearScreen(ip) 237 | 238 | #define lcdiicReturnHome(ip) \ 239 | (ip)->vmt->returnHome(ip) 240 | 241 | #define lcdiicUpdatePattern(ip, pos, pat) \ 242 | (ip)->vmt->updatePattern(ip, pos, pat) 243 | 244 | #define lcdiicMoveTo(ip, row, col) \ 245 | (ip)->vmt->moveTo(ip, row, col) 246 | 247 | #define lcdiicReadData(ip, ddram, offset, val) \ 248 | (ip)->vmt->readData(ip, ddram, offset, val) 249 | 250 | #define lcdiicAddChar(ip, ch) \ 251 | (ip)->vmt->addChar(ip, ch) 252 | 253 | #define lcdiicDrawText(ip, row, col, text, len) \ 254 | (ip)->vmt->drawText(ip, row, col, text, len) 255 | 256 | /*===========================================================================*/ 257 | /* External declarations. */ 258 | /*===========================================================================*/ 259 | 260 | #ifdef __cplusplus 261 | extern "C" { 262 | #endif 263 | 264 | void lcdiicObjectInit(LCDIICDriver *devp, void (*delayUs)(uint32_t), void (*delayMs)(uint32_t)); 265 | void lcdiicStart(LCDIICDriver *devp, const LCDIICConfig *config); 266 | void lcdiicStop(LCDIICDriver *devp); 267 | 268 | #ifdef __cplusplus 269 | } 270 | #endif 271 | 272 | #endif /* __LCDIIC_H__ */ 273 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 https://www.brobwind.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | #include "ch.h" 19 | #include "hal.h" 20 | 21 | #include "chprintf.h" 22 | 23 | #include "pcf8574.h" 24 | #include "lcdiic.h" 25 | 26 | 27 | /*===========================================================================*/ 28 | /* LED blinker */ 29 | /*===========================================================================*/ 30 | 31 | static THD_WORKING_AREA(waLedBlinker, 32); 32 | static THD_FUNCTION(LedBlinker, arg) { 33 | 34 | (void)arg; 35 | chRegSetThreadName("LedBlinker"); 36 | while (true) { 37 | palClearPad(GPIOA, GPIOA_LED_GREEN); 38 | chThdSleepMilliseconds(500); 39 | palSetPad(GPIOA, GPIOA_LED_GREEN); 40 | chThdSleepMilliseconds(500); 41 | } 42 | } 43 | 44 | /*===========================================================================*/ 45 | /* LCD display */ 46 | /*===========================================================================*/ 47 | 48 | static const I2CConfig i2ccfg = { // I2CCLK=48MHz, SCL=~100kHz 49 | STM32_TIMINGR_PRESC(0x0B) | 50 | STM32_TIMINGR_SCLDEL(0x04) | STM32_TIMINGR_SDADEL(0x02) | 51 | STM32_TIMINGR_SCLH(0x0F) | STM32_TIMINGR_SCLL(0x13), 52 | 0, 53 | 0 54 | }; 55 | 56 | /* Primary LCD display configuration */ 57 | static const PCF8574Config pcf8574cfg = { 58 | &I2CD1, 59 | &i2ccfg, 60 | PCF8574A_SAD_0X3E, 61 | 0x00, 62 | 0x00, 63 | }; 64 | 65 | static PCF8574Driver PCF8574D1; 66 | 67 | static const LCDIICConfig lcdiiccfg = { 68 | &PCF8574D1, 69 | &pcf8574cfg, 70 | }; 71 | 72 | static LCDIICDriver LCDIICD1; 73 | 74 | /* Secondary LCD display configuration */ 75 | static const PCF8574Config pcf8574cfgadv = { 76 | &I2CD1, 77 | &i2ccfg, 78 | PCF8574A_SAD_0X3F, 79 | 0x00, 80 | 0x00, 81 | }; 82 | 83 | static PCF8574Driver PCF8574D2; 84 | 85 | static const LCDIICConfig lcdiiccfgadv = { 86 | &PCF8574D2, 87 | &pcf8574cfgadv, 88 | }; 89 | 90 | static LCDIICDriver LCDIICD2; 91 | 92 | /* Delay function, used in control LCD display */ 93 | static void delayUs(uint32_t val) { 94 | (void)val; 95 | } 96 | 97 | static void delayMs(uint32_t val) { 98 | chThdSleepMilliseconds(val); 99 | } 100 | 101 | /* Primary LCD display thread */ 102 | static THD_WORKING_AREA(waLcdDisplay, 256); 103 | static __attribute__((noreturn)) THD_FUNCTION(LcdDisplay, arg) { 104 | (void)arg; 105 | chRegSetThreadName("LcdDisplay"); 106 | 107 | pcf8574ObjectInit(&PCF8574D1); 108 | pcf8574Start(&PCF8574D1, &pcf8574cfg); 109 | 110 | lcdiicObjectInit(&LCDIICD1, &delayUs, &delayMs); 111 | lcdiicStart(&LCDIICD1, &lcdiiccfg); 112 | 113 | { 114 | const uint8_t SYMBOL[][8] = { 115 | { 0x04, 0x0e, 0x0e, 0x0e, 0x1f, 0x00, 0x04, 0x00 }, // bell 116 | { 0x02, 0x03, 0x02, 0x0e, 0x1e, 0x0c, 0x00, 0x00 }, // note 117 | { 0x00, 0x0e, 0x15, 0x17, 0x11, 0x0e, 0x00, 0x00 }, // clock 118 | { 0x00, 0x0a, 0x1f, 0x1f, 0x0e, 0x04, 0x00, 0x00 }, // heart 119 | { 0x00, 0x0c, 0x1d, 0x0f, 0x0f, 0x06, 0x00, 0x00 }, // duck 120 | { 0x00, 0x01, 0x03, 0x16, 0x1c, 0x08, 0x00, 0x00 }, // check 121 | { 0x00, 0x1b, 0x0e, 0x04, 0x0e, 0x1b, 0x00, 0x00 }, // cross 122 | { 0x01, 0x01, 0x05, 0x09, 0x1f, 0x08, 0x04, 0x00 }, // retarrow 123 | }; 124 | uint8_t idx; 125 | 126 | for (idx = 0; idx < sizeof(SYMBOL) / sizeof(SYMBOL[0]); idx++) { 127 | lcdiicUpdatePattern(&LCDIICD1, idx, SYMBOL[idx]); 128 | } 129 | 130 | for (idx = 0; idx < sizeof(SYMBOL) / sizeof(SYMBOL[0][0]); idx++) { 131 | uint8_t tmp; 132 | lcdiicReadData(&LCDIICD1, 0, idx, &tmp); 133 | 134 | if (idx % 8 == 0) { 135 | chprintf((BaseSequentialStream *)&SD1, "---- dump pattern: %d ----\r\n", idx / 8); 136 | } 137 | 138 | chprintf((BaseSequentialStream*)&SD1, "%02x", tmp); 139 | if (idx % 8 == 7) { 140 | chprintf((BaseSequentialStream *)&SD1, "\r\n"); 141 | } else { 142 | chprintf((BaseSequentialStream *)&SD1, " "); 143 | } 144 | } 145 | } 146 | 147 | while (true) { 148 | char buf[32]; 149 | systime_t millisec; 150 | 151 | chsnprintf(buf, sizeof(buf), "ChibiOS/RT %s", CH_KERNEL_VERSION); 152 | lcdiicDrawText(&LCDIICD1, 0, 0, buf, strlen(buf)); 153 | 154 | millisec = ST2MS(chVTGetSystemTime()); 155 | chsnprintf(buf, sizeof(buf), "%6d:%02d:%02d.%03d", millisec / 3600 / 1000, 156 | (millisec / 60 / 1000) % 60, (millisec / 1000) % 60, millisec % 1000); 157 | lcdiicDrawText(&LCDIICD1, 1, 0, buf, strlen(buf)); 158 | 159 | chThdSleepMilliseconds(200); 160 | } 161 | 162 | lcdiicStop(&LCDIICD1); 163 | pcf8574Stop(&PCF8574D1); 164 | } 165 | 166 | /* Secondary LCD display thread */ 167 | static THD_WORKING_AREA(waLcdDisplayAdv, 256); 168 | static __attribute__((noreturn)) THD_FUNCTION(LcdDisplayAdv, arg) { 169 | (void)arg; 170 | uint8_t next = 0, ch, idx = 0; 171 | chRegSetThreadName("LcdDisplayAdv"); 172 | 173 | pcf8574ObjectInit(&PCF8574D2); 174 | pcf8574Start(&PCF8574D2, &pcf8574cfgadv); 175 | 176 | lcdiicObjectInit(&LCDIICD2, &delayUs, &delayMs); 177 | lcdiicStart(&LCDIICD2, &lcdiiccfgadv); 178 | 179 | while (true) { 180 | char buf[32]; 181 | volatile uint32_t *uuid = (volatile uint32_t *)0x1FFFF7AC; 182 | 183 | switch (next++) { 184 | case 0: ch = '+'; break; 185 | case 1: ch = '*'; next = 0; break; 186 | } 187 | 188 | chsnprintf(buf, sizeof(buf), "%c%s", ch, BOARD_NAME); 189 | lcdiicDrawText(&LCDIICD2, 0, 0, buf, strlen(buf)); 190 | 191 | chsnprintf(buf, sizeof(buf), "UID: %08x[%d]", uuid[idx], idx); 192 | lcdiicDrawText(&LCDIICD2, 1, 0, buf, strlen(buf)); 193 | 194 | if (idx++ == 2) idx = 0; 195 | 196 | chThdSleepMilliseconds(1000); 197 | } 198 | 199 | lcdiicStop(&LCDIICD1); 200 | pcf8574Stop(&PCF8574D1); 201 | } 202 | 203 | /* 204 | * Application entry point. 205 | */ 206 | int __attribute__((noreturn)) main(void) 207 | { 208 | /* 209 | * System initializations. 210 | * - HAL initialization, this also initializes the configured device drivers 211 | * and performs the board-specific initializations. 212 | * - Kernel initialization, the main() function becomes a thread and the 213 | * RTOS is active. 214 | */ 215 | halInit(); 216 | chSysInit(); 217 | 218 | /* 219 | * I2CD1 I/O pins setup.(It bypasses board.h configurations) 220 | */ 221 | palSetPadMode(GPIOA, GPIOA_PIN9, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_HIGHEST); /* SCL */ 222 | palSetPadMode(GPIOA, GPIOA_PIN10, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_HIGHEST); /* SDA */ 223 | 224 | /* 225 | * Activates the serial driver 1 using the driver default configuration. 226 | */ 227 | sdStart(&SD1, NULL); 228 | 229 | /* 230 | * Creates the blinker thread. 231 | */ 232 | chThdCreateStatic(waLedBlinker, sizeof(waLedBlinker), NORMALPRIO, LedBlinker, NULL); 233 | 234 | /* 235 | * Creates the LCD display thread. 236 | */ 237 | chThdCreateStatic(waLcdDisplay, sizeof(waLcdDisplay), NORMALPRIO + 1, LcdDisplay, NULL); 238 | chThdCreateStatic(waLcdDisplayAdv, sizeof(waLcdDisplayAdv), NORMALPRIO + 1, LcdDisplayAdv, NULL); 239 | 240 | while(TRUE){ 241 | chThdSleepMilliseconds(500); 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /mcuconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef MCUCONF_H 18 | #define MCUCONF_H 19 | 20 | /* 21 | * STM32F0xx drivers configuration. 22 | * The following settings override the default settings present in 23 | * the various device driver implementation headers. 24 | * Note that the settings for each driver only have effect if the whole 25 | * driver is enabled in halconf.h. 26 | * 27 | * IRQ priorities: 28 | * 3...0 Lowest...Highest. 29 | * 30 | * DMA priorities: 31 | * 0...3 Lowest...Highest. 32 | */ 33 | 34 | #define STM32F0xx_MCUCONF 35 | 36 | /* 37 | * HAL driver system settings. 38 | */ 39 | #define STM32_NO_INIT FALSE 40 | #define STM32_PVD_ENABLE FALSE 41 | #define STM32_PLS STM32_PLS_LEV0 42 | #define STM32_HSI_ENABLED FALSE 43 | #define STM32_HSI14_ENABLED TRUE 44 | #define STM32_LSI_ENABLED TRUE 45 | #define STM32_HSE_ENABLED TRUE 46 | #define STM32_LSE_ENABLED FALSE 47 | #define STM32_SW STM32_SW_PLL 48 | #define STM32_PLLSRC STM32_PLLSRC_HSE 49 | #define STM32_PREDIV_VALUE 1 50 | #define STM32_PLLMUL_VALUE 6 51 | #define STM32_HPRE STM32_HPRE_DIV1 52 | #define STM32_PPRE STM32_PPRE_DIV1 53 | #define STM32_MCOSEL STM32_MCOSEL_NOCLOCK 54 | #define STM32_MCOPRE STM32_MCOPRE_DIV1 55 | #define STM32_PLLNODIV STM32_PLLNODIV_DIV2 56 | #define STM32_CECSW STM32_CECSW_OFF 57 | #define STM32_I2C1SW STM32_I2C1SW_SYSCLK 58 | #define STM32_USART1SW STM32_USART1SW_PCLK 59 | #define STM32_RTCSEL STM32_RTCSEL_LSI 60 | 61 | /* 62 | * ADC driver system settings. 63 | */ 64 | #define STM32_ADC_USE_ADC1 FALSE 65 | #define STM32_ADC_ADC1_CKMODE STM32_ADC_CKMODE_ADCCLK 66 | #define STM32_ADC_ADC1_DMA_PRIORITY 2 67 | #define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2 68 | #define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) 69 | 70 | /* 71 | * EXT driver system settings. 72 | */ 73 | #define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3 74 | #define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3 75 | #define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3 76 | #define STM32_EXT_EXTI16_IRQ_PRIORITY 3 77 | #define STM32_EXT_EXTI17_20_IRQ_PRIORITY 3 78 | 79 | /* 80 | * GPT driver system settings. 81 | */ 82 | #define STM32_GPT_USE_TIM1 FALSE 83 | #define STM32_GPT_USE_TIM3 FALSE 84 | #define STM32_GPT_USE_TIM14 FALSE 85 | #define STM32_GPT_TIM1_IRQ_PRIORITY 2 86 | #define STM32_GPT_TIM3_IRQ_PRIORITY 2 87 | #define STM32_GPT_TIM14_IRQ_PRIORITY 2 88 | 89 | /* 90 | * I2C driver system settings. 91 | */ 92 | #define STM32_I2C_USE_I2C1 TRUE 93 | #define STM32_I2C_USE_I2C2 FALSE 94 | #define STM32_I2C_BUSY_TIMEOUT 50 95 | #define STM32_I2C_I2C1_IRQ_PRIORITY 3 96 | #define STM32_I2C_I2C2_IRQ_PRIORITY 3 97 | #define STM32_I2C_USE_DMA FALSE 98 | #define STM32_I2C_I2C1_DMA_PRIORITY 1 99 | #define STM32_I2C_I2C2_DMA_PRIORITY 1 100 | #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 101 | #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 102 | #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 103 | #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 104 | #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") 105 | 106 | /* 107 | * I2S driver system settings. 108 | */ 109 | #define STM32_I2S_USE_SPI1 FALSE 110 | #define STM32_I2S_USE_SPI2 FALSE 111 | #define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \ 112 | STM32_I2S_MODE_RX) 113 | #define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_MASTER | \ 114 | STM32_I2S_MODE_RX) 115 | #define STM32_I2S_SPI1_IRQ_PRIORITY 2 116 | #define STM32_I2S_SPI2_IRQ_PRIORITY 2 117 | #define STM32_I2S_SPI1_DMA_PRIORITY 1 118 | #define STM32_I2S_SPI2_DMA_PRIORITY 1 119 | #define STM32_I2S_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 120 | #define STM32_I2S_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 121 | #define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 122 | #define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 123 | #define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure") 124 | 125 | /* 126 | * ICU driver system settings. 127 | */ 128 | #define STM32_ICU_USE_TIM1 FALSE 129 | #define STM32_ICU_USE_TIM3 FALSE 130 | #define STM32_ICU_TIM1_IRQ_PRIORITY 3 131 | #define STM32_ICU_TIM3_IRQ_PRIORITY 3 132 | 133 | /* 134 | * PWM driver system settings. 135 | */ 136 | #define STM32_PWM_USE_ADVANCED FALSE 137 | #define STM32_PWM_USE_TIM1 FALSE 138 | #define STM32_PWM_USE_TIM3 FALSE 139 | #define STM32_PWM_TIM1_IRQ_PRIORITY 3 140 | #define STM32_PWM_TIM3_IRQ_PRIORITY 3 141 | 142 | /* 143 | * SERIAL driver system settings. 144 | */ 145 | #define STM32_SERIAL_USE_USART1 TRUE 146 | #define STM32_SERIAL_USE_USART2 FALSE 147 | #define STM32_SERIAL_USART1_PRIORITY 3 148 | #define STM32_SERIAL_USART2_PRIORITY 3 149 | 150 | /* 151 | * SPI driver system settings. 152 | */ 153 | #define STM32_SPI_USE_SPI1 FALSE 154 | #define STM32_SPI_USE_SPI2 FALSE 155 | #define STM32_SPI_SPI1_DMA_PRIORITY 1 156 | #define STM32_SPI_SPI2_DMA_PRIORITY 1 157 | #define STM32_SPI_SPI1_IRQ_PRIORITY 2 158 | #define STM32_SPI_SPI2_IRQ_PRIORITY 2 159 | #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 160 | #define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 161 | #define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 162 | #define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 163 | #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") 164 | 165 | /* 166 | * ST driver system settings. 167 | */ 168 | #define STM32_ST_IRQ_PRIORITY 2 169 | #define STM32_ST_USE_TIMER 3 170 | 171 | /* 172 | * UART driver system settings. 173 | */ 174 | #define STM32_UART_USE_USART1 FALSE 175 | #define STM32_UART_USE_USART2 FALSE 176 | #define STM32_UART_USART1_IRQ_PRIORITY 3 177 | #define STM32_UART_USART2_IRQ_PRIORITY 3 178 | #define STM32_UART_USART1_DMA_PRIORITY 0 179 | #define STM32_UART_USART2_DMA_PRIORITY 0 180 | #define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 181 | #define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 182 | #define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 183 | #define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 184 | #define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") 185 | 186 | /* 187 | * WDG driver system settings. 188 | */ 189 | #define STM32_WDG_USE_IWDG FALSE 190 | 191 | #endif /* MCUCONF_H */ 192 | -------------------------------------------------------------------------------- /pcf8574.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 https://www.brobwind.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "hal.h" 17 | #include "pcf8574.h" 18 | 19 | 20 | /** 21 | * Reference manual: 22 | * 1. NXP: http://www.nxp.com/documents/data_sheet/PCF8574_PCF8574A.pdf 23 | * 2. TI: http://www.ti.com/lit/ds/symlink/pcf8574.pdf 24 | */ 25 | 26 | /*===========================================================================*/ 27 | /* Driver local functions. */ 28 | /*===========================================================================*/ 29 | 30 | static msg_t pcf8574ReadRegister(I2CDriver *i2cp, pcf8574_sad_t sad, uint8_t *rxbuf, size_t n) { 31 | return i2cMasterReceiveTimeout(i2cp, sad, rxbuf, n, TIME_INFINITE); 32 | } 33 | 34 | static msg_t pcf8574WriteRegister(I2CDriver *i2cp, pcf8574_sad_t sad, uint8_t *txbuf, uint8_t n) { 35 | return i2cMasterTransmitTimeout(i2cp, sad, txbuf, n, NULL, 0, TIME_INFINITE); 36 | } 37 | 38 | static msg_t setPort(void *ip, uint8_t modify, uint8_t *val, uint8_t len) { 39 | uint8_t ret; 40 | const PCF8574Driver *drv = (PCF8574Driver *)ip; 41 | 42 | if (modify) { 43 | uint8_t idx; 44 | for (idx = 0; idx < len; idx++) 45 | val[idx] = drv->config->mask | val[idx]; 46 | } 47 | 48 | i2cAcquireBus(drv->config->i2cp); 49 | i2cStart(drv->config->i2cp, drv->config->i2ccfg); 50 | 51 | ret = pcf8574WriteRegister(drv->config->i2cp, drv->config->sad, val, len); 52 | 53 | i2cReleaseBus(drv->config->i2cp); 54 | 55 | return ret; 56 | } 57 | 58 | static msg_t getPort(void *ip, uint8_t *val, uint8_t len) { 59 | msg_t ret; 60 | const PCF8574Driver *drv = (PCF8574Driver *)ip; 61 | 62 | i2cAcquireBus(drv->config->i2cp); 63 | i2cStart(drv->config->i2cp, drv->config->i2ccfg); 64 | 65 | ret = pcf8574ReadRegister(drv->config->i2cp, drv->config->sad, val, len); 66 | 67 | i2cReleaseBus(drv->config->i2cp); 68 | 69 | return ret; 70 | } 71 | 72 | static msg_t setPortOb(void *ip, uint8_t modify, uint8_t val) { 73 | return setPort(ip, modify, &val, 1); 74 | } 75 | 76 | static msg_t getPortOb(void *ip, uint8_t *val) { 77 | return getPort(ip, val, 1); 78 | } 79 | 80 | static const struct PCF8574VMT vmt_pcf8574 = { 81 | setPort, getPort, 82 | setPortOb, getPortOb 83 | }; 84 | 85 | /*===========================================================================*/ 86 | /* Driver exported functions. */ 87 | /*===========================================================================*/ 88 | 89 | void pcf8574ObjectInit(PCF8574Driver *devp) { 90 | devp->vmt = &vmt_pcf8574; 91 | devp->config = NULL; 92 | 93 | devp->state = PCF8574_STOP; 94 | } 95 | 96 | void pcf8574Start(PCF8574Driver *devp, const PCF8574Config *config) { 97 | chDbgCheck((devp != NULL) && (config != NULL)); 98 | 99 | chDbgAssert((devp->state == PCF8574_STOP) || (devp->state == PCF8574_READY), 100 | "pcf8574Start(), invalid state"); 101 | 102 | devp->config = config; 103 | 104 | /* Init port */ 105 | setPortOb(devp, 0, devp->config->mask | devp->config->value); 106 | 107 | devp->state = PCF8574_READY; 108 | } 109 | 110 | void pcf8574Stop(PCF8574Driver *devp) { 111 | chDbgAssert((devp->state == PCF8574_STOP) || (devp->state == PCF8574_READY), 112 | "pcf8574Stop(), invalid state"); 113 | 114 | if (devp->state == PCF8574_READY) { 115 | /* Set all I/O pin to input */ 116 | setPortOb(devp, 0, 0xff); 117 | } 118 | 119 | devp->state = PCF8574_STOP; 120 | } 121 | -------------------------------------------------------------------------------- /pcf8574.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 https://www.brobwind.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __PCF8574_H__ 17 | #define __PCF8574_H__ 18 | 19 | #include "hal.h" 20 | 21 | /*===========================================================================*/ 22 | /* Derived constants and error checks. */ 23 | /*===========================================================================*/ 24 | 25 | #if !HAL_USE_I2C 26 | #error "PCF8574 requires HAL_USE_I2C" 27 | #endif 28 | 29 | /*===========================================================================*/ 30 | /* Driver data structures and types. */ 31 | /*===========================================================================*/ 32 | 33 | typedef enum { 34 | /* PCF8574 slave address range: A2 | A1 | A0 */ 35 | PCF8574_SAD_0X20 = 0x20, // 0 0 0 36 | PCF8574_SAD_0X21 = 0x21, // 0 0 1 37 | PCF8574_SAD_0X22 = 0x22, // 0 1 0 38 | PCF8574_SAD_0X23 = 0x23, // 0 1 1 39 | PCF8574_SAD_0X24 = 0x24, // 1 0 0 40 | PCF8574_SAD_0X25 = 0x25, // 1 0 1 41 | PCF8574_SAD_0X26 = 0x26, // 1 1 0 42 | PCF8574_SAD_0X27 = 0x27, // 1 1 1 43 | 44 | /* PCF8574A slave address range: A2 | A1 | A0 */ 45 | PCF8574A_SAD_0X38 = 0x38, // 0 0 0 46 | PCF8574A_SAD_0X39 = 0x39, // 0 0 1 47 | PCF8574A_SAD_0X3A = 0x3A, // 0 1 0 48 | PCF8574A_SAD_0X3B = 0x3B, // 0 1 1 49 | PCF8574A_SAD_0X3C = 0x3C, // 1 0 0 50 | PCF8574A_SAD_0X3D = 0x3D, // 1 0 1 51 | PCF8574A_SAD_0X3E = 0x3E, // 1 1 0 52 | PCF8574A_SAD_0X3F = 0x3F, // 1 1 1 53 | } pcf8574_sad_t; 54 | 55 | typedef enum { 56 | PCF8574_UNINIT = 0, 57 | PCF8574_STOP = 1, 58 | PCF8574_READY = 2, 59 | } pcf8574_state_t; 60 | 61 | typedef struct { 62 | I2CDriver *i2cp; 63 | const I2CConfig *i2ccfg; 64 | 65 | pcf8574_sad_t sad; 66 | uint8_t mask; 67 | uint8_t value; 68 | } PCF8574Config; 69 | 70 | #define _pcf8574_methods \ 71 | msg_t (*setPort)(void *instance, uint8_t modify, uint8_t *val, uint8_t len); \ 72 | msg_t (*getPort)(void *instance, uint8_t *val, uint8_t len); \ 73 | msg_t (*setPortOb)(void *instance, uint8_t modify, uint8_t val); \ 74 | msg_t (*getPortOb)(void *instance, uint8_t *val); \ 75 | 76 | struct PCF8574VMT { 77 | _pcf8574_methods 78 | }; 79 | 80 | #define _pcf8574_data \ 81 | pcf8574_state_t state; \ 82 | const PCF8574Config *config; 83 | 84 | typedef struct PCF8574Driver { 85 | const struct PCF8574VMT *vmt; 86 | _pcf8574_data; 87 | } PCF8574Driver; 88 | 89 | /*===========================================================================*/ 90 | /* Driver macros. */ 91 | /*===========================================================================*/ 92 | 93 | #define pcf8574SetPort(ip, modify, val, len) \ 94 | (ip)->vmt->setPort(ip, modify, val, len) 95 | 96 | #define pcf8574GetPort(ip, val) \ 97 | (ip)->vmt->getPort(ip, val, len) 98 | 99 | #define pcf8574SetPortOb(ip, modify, val) \ 100 | (ip)->vmt->setPortOb(ip, modify, val) 101 | 102 | #define pcf8574GetPortOb(ip, val) \ 103 | (ip)->vmt->getPortOb(ip, val) 104 | 105 | /*===========================================================================*/ 106 | /* External declarations. */ 107 | /*===========================================================================*/ 108 | 109 | #ifdef __cplusplus 110 | extern "C" { 111 | #endif 112 | 113 | void pcf8574ObjectInit(PCF8574Driver *devp); 114 | void pcf8574Start(PCF8574Driver *devp, const PCF8574Config *config); 115 | void pcf8574Stop(PCF8574Driver *devp); 116 | 117 | #ifdef __cplusplus 118 | } 119 | #endif 120 | 121 | #endif /* __PCF8574_H__ */ 122 | -------------------------------------------------------------------------------- /stm32f030f4-dev-v1.0/STM32F030x4.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | * STM32F030x4 memory setup. 19 | */ 20 | MEMORY 21 | { 22 | flash0 : org = 0x08000000, len = 16k 23 | flash1 : org = 0x00000000, len = 0 24 | flash2 : org = 0x00000000, len = 0 25 | flash3 : org = 0x00000000, len = 0 26 | flash4 : org = 0x00000000, len = 0 27 | flash5 : org = 0x00000000, len = 0 28 | flash6 : org = 0x00000000, len = 0 29 | flash7 : org = 0x00000000, len = 0 30 | ram0 : org = 0x20000000, len = 4k 31 | ram1 : org = 0x00000000, len = 0 32 | ram2 : org = 0x00000000, len = 0 33 | ram3 : org = 0x00000000, len = 0 34 | ram4 : org = 0x00000000, len = 0 35 | ram5 : org = 0x00000000, len = 0 36 | ram6 : org = 0x00000000, len = 0 37 | ram7 : org = 0x00000000, len = 0 38 | } 39 | 40 | /* For each data/text section two region are defined, a virtual region 41 | and a load region (_LMA suffix).*/ 42 | 43 | /* Flash region to be used for exception vectors.*/ 44 | REGION_ALIAS("VECTORS_FLASH", flash0); 45 | REGION_ALIAS("VECTORS_FLASH_LMA", flash0); 46 | 47 | /* Flash region to be used for constructors and destructors.*/ 48 | REGION_ALIAS("XTORS_FLASH", flash0); 49 | REGION_ALIAS("XTORS_FLASH_LMA", flash0); 50 | 51 | /* Flash region to be used for code text.*/ 52 | REGION_ALIAS("TEXT_FLASH", flash0); 53 | REGION_ALIAS("TEXT_FLASH_LMA", flash0); 54 | 55 | /* Flash region to be used for read only data.*/ 56 | REGION_ALIAS("RODATA_FLASH", flash0); 57 | REGION_ALIAS("RODATA_FLASH_LMA", flash0); 58 | 59 | /* Flash region to be used for various.*/ 60 | REGION_ALIAS("VARIOUS_FLASH", flash0); 61 | REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); 62 | 63 | /* Flash region to be used for RAM(n) initialization data.*/ 64 | REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); 65 | 66 | /* RAM region to be used for Main stack. This stack accommodates the processing 67 | of all exceptions and interrupts.*/ 68 | REGION_ALIAS("MAIN_STACK_RAM", ram0); 69 | 70 | /* RAM region to be used for the process stack. This is the stack used by 71 | the main() function.*/ 72 | REGION_ALIAS("PROCESS_STACK_RAM", ram0); 73 | 74 | /* RAM region to be used for data segment.*/ 75 | REGION_ALIAS("DATA_RAM", ram0); 76 | REGION_ALIAS("DATA_RAM_LMA", flash0); 77 | 78 | /* RAM region to be used for BSS segment.*/ 79 | REGION_ALIAS("BSS_RAM", ram0); 80 | 81 | /* RAM region to be used for the default heap.*/ 82 | REGION_ALIAS("HEAP_RAM", ram0); 83 | 84 | /* Generic rules inclusion.*/ 85 | INCLUDE rules.ld 86 | -------------------------------------------------------------------------------- /stm32f030f4-dev-v1.0/board.c: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "hal.h" 18 | 19 | #if HAL_USE_PAL || defined(__DOXYGEN__) 20 | /** 21 | * @brief PAL setup. 22 | * @details Digital I/O ports static configuration as defined in @p board.h. 23 | * This variable is used by the HAL when initializing the PAL driver. 24 | */ 25 | const PALConfig pal_default_config = { 26 | #if STM32_HAS_GPIOA 27 | {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, 28 | VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH}, 29 | #endif 30 | #if STM32_HAS_GPIOB 31 | {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, 32 | VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH}, 33 | #endif 34 | #if STM32_HAS_GPIOC 35 | {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, 36 | VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH}, 37 | #endif 38 | #if STM32_HAS_GPIOD 39 | {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, 40 | VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH}, 41 | #endif 42 | #if STM32_HAS_GPIOE 43 | {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, 44 | VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH}, 45 | #endif 46 | #if STM32_HAS_GPIOF 47 | {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, 48 | VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH}, 49 | #endif 50 | #if STM32_HAS_GPIOG 51 | {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, 52 | VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH}, 53 | #endif 54 | #if STM32_HAS_GPIOH 55 | {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, 56 | VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH}, 57 | #endif 58 | #if STM32_HAS_GPIOI 59 | {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, 60 | VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH} 61 | #endif 62 | }; 63 | #endif 64 | 65 | /** 66 | * @brief Early initialization code. 67 | * @details This initialization must be performed just after stack setup 68 | * and before any other initialization. 69 | */ 70 | void __early_init(void) { 71 | 72 | stm32_clock_init(); 73 | } 74 | 75 | #if HAL_USE_MMC_SPI || defined(__DOXYGEN__) 76 | /** 77 | * @brief MMC_SPI card detection. 78 | */ 79 | bool mmc_lld_is_card_inserted(MMCDriver *mmcp) { 80 | 81 | (void)mmcp; 82 | /* TODO: Fill the implementation.*/ 83 | return true; 84 | } 85 | 86 | /** 87 | * @brief MMC_SPI card write protection detection. 88 | */ 89 | bool mmc_lld_is_write_protected(MMCDriver *mmcp) { 90 | 91 | (void)mmcp; 92 | /* TODO: Fill the implementation.*/ 93 | return false; 94 | } 95 | #endif 96 | 97 | /** 98 | * @brief Board-specific initialization code. 99 | * @todo Add your board-specific code, if any. 100 | */ 101 | void boardInit(void) { 102 | } 103 | -------------------------------------------------------------------------------- /stm32f030f4-dev-v1.0/board.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _BOARD_H_ 18 | #define _BOARD_H_ 19 | 20 | /* 21 | * Setup for STMicroelectronics STM32F030F4-DEV V1.0 board. 22 | */ 23 | 24 | /* 25 | * Board identifier. 26 | */ 27 | #define BOARD_STM32F030F4_DEV_V1_0 28 | #define BOARD_NAME "STM32F030F4-DEV V1.0" 29 | 30 | /* 31 | * Board oscillators-related settings. 32 | * NOTE: LSE not fitted. 33 | * NOTE: HSE not fitted. 34 | */ 35 | #if !defined(STM32_LSECLK) 36 | #define STM32_LSECLK 0U 37 | #endif 38 | 39 | #define STM32_LSEDRV (3U << 3U) 40 | 41 | #if !defined(STM32_HSECLK) 42 | #define STM32_HSECLK 8000000U 43 | #endif 44 | 45 | //#define STM32_HSE_BYPASS 46 | 47 | /* 48 | * MCU type as defined in the ST header. 49 | */ 50 | #define STM32F030x6 51 | 52 | /* 53 | * IO pins assignments. 54 | */ 55 | #define GPIOA_PIN0 0U 56 | #define GPIOA_PIN1 1U 57 | #define GPIOA_USART_TX 2U 58 | #define GPIOA_USART_RX 3U 59 | #define GPIOA_LED_GREEN 4U 60 | #define GPIOA_PIN5 5U 61 | #define GPIOA_PIN6 6U 62 | #define GPIOA_PIN7 7U 63 | #define GPIOA_PIN8 8U 64 | #define GPIOA_PIN9 9U 65 | #define GPIOA_PIN10 10U 66 | #define GPIOA_PIN11 11U 67 | #define GPIOA_PIN12 12U 68 | #define GPIOA_SWDIO 13U 69 | #define GPIOA_SWCLK 14U 70 | #define GPIOA_PIN15 15U 71 | 72 | #define GPIOB_PIN0 0U 73 | #define GPIOB_PIN1 1U 74 | #define GPIOB_PIN2 2U 75 | #define GPIOB_PIN3 3U 76 | #define GPIOB_PIN4 4U 77 | #define GPIOB_PIN5 5U 78 | #define GPIOB_PIN6 6U 79 | #define GPIOB_PIN7 7U 80 | #define GPIOB_PIN8 8U 81 | #define GPIOB_PIN9 9U 82 | #define GPIOB_PIN10 10U 83 | #define GPIOB_PIN11 11U 84 | #define GPIOB_PIN12 12U 85 | #define GPIOB_PIN13 13U 86 | #define GPIOB_PIN14 14U 87 | #define GPIOB_PIN15 15U 88 | 89 | #define GPIOC_PIN0 0U 90 | #define GPIOC_PIN1 1U 91 | #define GPIOC_PIN2 2U 92 | #define GPIOC_PIN3 3U 93 | #define GPIOC_PIN4 4U 94 | #define GPIOC_PIN5 5U 95 | #define GPIOC_PIN6 6U 96 | #define GPIOC_PIN7 7U 97 | #define GPIOC_PIN8 8U 98 | #define GPIOC_PIN9 9U 99 | #define GPIOC_PIN10 10U 100 | #define GPIOC_PIN11 11U 101 | #define GPIOC_PIN12 12U 102 | #define GPIOC_PIN13 13U 103 | #define GPIOC_PIN14 14U 104 | #define GPIOC_PIN15 15U 105 | 106 | #define GPIOD_PIN0 0U 107 | #define GPIOD_PIN1 1U 108 | #define GPIOD_PIN2 2U 109 | #define GPIOD_PIN3 3U 110 | #define GPIOD_PIN4 4U 111 | #define GPIOD_PIN5 5U 112 | #define GPIOD_PIN6 6U 113 | #define GPIOD_PIN7 7U 114 | #define GPIOD_PIN8 8U 115 | #define GPIOD_PIN9 9U 116 | #define GPIOD_PIN10 10U 117 | #define GPIOD_PIN11 11U 118 | #define GPIOD_PIN12 12U 119 | #define GPIOD_PIN13 13U 120 | #define GPIOD_PIN14 14U 121 | #define GPIOD_PIN15 15U 122 | 123 | #define GPIOF_OSC_IN 0U 124 | #define GPIOF_OSC_OUT 1U 125 | #define GPIOF_PIN2 2U 126 | #define GPIOF_PIN3 3U 127 | #define GPIOF_PIN4 4U 128 | #define GPIOF_PIN5 5U 129 | #define GPIOF_PIN6 6U 130 | #define GPIOF_PIN7 7U 131 | #define GPIOF_PIN8 8U 132 | #define GPIOF_PIN9 9U 133 | #define GPIOF_PIN10 10U 134 | #define GPIOF_PIN11 11U 135 | #define GPIOF_PIN12 12U 136 | #define GPIOF_PIN13 13U 137 | #define GPIOF_PIN14 14U 138 | #define GPIOF_PIN15 15U 139 | 140 | /* 141 | * IO lines assignments. 142 | */ 143 | #define LINE_LED_GREEN PAL_LINE(GPIOA, 1U) 144 | #define LINE_USART_TX PAL_LINE(GPIOA, 2U) 145 | #define LINE_USART_RX PAL_LINE(GPIOA, 3U) 146 | #define LINE_SWDIO PAL_LINE(GPIOA, 13U) 147 | #define LINE_SWCLK PAL_LINE(GPIOA, 14U) 148 | 149 | #define LINE_OSC_IN PAL_LINE(GPIOF, 0U) 150 | #define LINE_OSC_OUT PAL_LINE(GPIOF, 1U) 151 | 152 | /* 153 | * I/O ports initial setup, this configuration is established soon after reset 154 | * in the initialization code. 155 | * Please refer to the STM32 Reference Manual for details. 156 | */ 157 | #define PIN_MODE_INPUT(n) (0U << ((n) * 2U)) 158 | #define PIN_MODE_OUTPUT(n) (1U << ((n) * 2U)) 159 | #define PIN_MODE_ALTERNATE(n) (2U << ((n) * 2U)) 160 | #define PIN_MODE_ANALOG(n) (3U << ((n) * 2U)) 161 | #define PIN_ODR_LOW(n) (0U << (n)) 162 | #define PIN_ODR_HIGH(n) (1U << (n)) 163 | #define PIN_OTYPE_PUSHPULL(n) (0U << (n)) 164 | #define PIN_OTYPE_OPENDRAIN(n) (1U << (n)) 165 | #define PIN_OSPEED_VERYLOW(n) (0U << ((n) * 2U)) 166 | #define PIN_OSPEED_LOW(n) (1U << ((n) * 2U)) 167 | #define PIN_OSPEED_MEDIUM(n) (2U << ((n) * 2U)) 168 | #define PIN_OSPEED_HIGH(n) (3U << ((n) * 2U)) 169 | #define PIN_PUPDR_FLOATING(n) (0U << ((n) * 2U)) 170 | #define PIN_PUPDR_PULLUP(n) (1U << ((n) * 2U)) 171 | #define PIN_PUPDR_PULLDOWN(n) (2U << ((n) * 2U)) 172 | #define PIN_AFIO_AF(n, v) ((v) << (((n) % 8U) * 4U)) 173 | 174 | /* 175 | * GPIOA setup: 176 | * 177 | * PA0 - PIN0 (input pullup). 178 | * PA1 - LED_GREEN (output pushpull high). 179 | * PA2 - USART_TX (alternate 1). 180 | * PA3 - USART_RX (alternate 1). 181 | * PA4 - PIN4 (input pullup). 182 | * PA5 - PIN5 (input pullup). 183 | * PA6 - PIN6 (input pullup). 184 | * PA7 - PIN7 (input pullup). 185 | * PA8 - PIN8 (input pullup). 186 | * PA9 - PIN9 (input pullup). 187 | * PA10 - PIN10 (input pullup). 188 | * PA11 - PIN11 (input pullup). 189 | * PA12 - PIN12 (input pullup). 190 | * PA13 - SWDIO (alternate 0). 191 | * PA14 - SWCLK (alternate 0). 192 | * PA15 - PIN15 (input pullup). 193 | */ 194 | #define VAL_GPIOA_MODER (PIN_MODE_INPUT(GPIOA_PIN0) | \ 195 | PIN_MODE_INPUT(GPIOA_PIN1) | \ 196 | PIN_MODE_ALTERNATE(GPIOA_USART_TX) | \ 197 | PIN_MODE_ALTERNATE(GPIOA_USART_RX) | \ 198 | PIN_MODE_OUTPUT(GPIOA_LED_GREEN) | \ 199 | PIN_MODE_INPUT(GPIOA_PIN5) | \ 200 | PIN_MODE_INPUT(GPIOA_PIN6) | \ 201 | PIN_MODE_INPUT(GPIOA_PIN7) | \ 202 | PIN_MODE_INPUT(GPIOA_PIN8) | \ 203 | PIN_MODE_INPUT(GPIOA_PIN9) | \ 204 | PIN_MODE_INPUT(GPIOA_PIN10) | \ 205 | PIN_MODE_INPUT(GPIOA_PIN11) | \ 206 | PIN_MODE_INPUT(GPIOA_PIN12) | \ 207 | PIN_MODE_ALTERNATE(GPIOA_SWDIO) | \ 208 | PIN_MODE_ALTERNATE(GPIOA_SWCLK) | \ 209 | PIN_MODE_INPUT(GPIOA_PIN15)) 210 | #define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_PIN0) | \ 211 | PIN_OTYPE_PUSHPULL(GPIOA_PIN1) | \ 212 | PIN_OTYPE_PUSHPULL(GPIOA_USART_TX) | \ 213 | PIN_OTYPE_PUSHPULL(GPIOA_USART_RX) | \ 214 | PIN_OTYPE_PUSHPULL(GPIOA_LED_GREEN) | \ 215 | PIN_OTYPE_PUSHPULL(GPIOA_PIN5) | \ 216 | PIN_OTYPE_PUSHPULL(GPIOA_PIN6) | \ 217 | PIN_OTYPE_PUSHPULL(GPIOA_PIN7) | \ 218 | PIN_OTYPE_PUSHPULL(GPIOA_PIN8) | \ 219 | PIN_OTYPE_PUSHPULL(GPIOA_PIN9) | \ 220 | PIN_OTYPE_PUSHPULL(GPIOA_PIN10) | \ 221 | PIN_OTYPE_PUSHPULL(GPIOA_PIN11) | \ 222 | PIN_OTYPE_PUSHPULL(GPIOA_PIN12) | \ 223 | PIN_OTYPE_PUSHPULL(GPIOA_SWDIO) | \ 224 | PIN_OTYPE_PUSHPULL(GPIOA_SWCLK) | \ 225 | PIN_OTYPE_PUSHPULL(GPIOA_PIN15)) 226 | #define VAL_GPIOA_OSPEEDR (PIN_OSPEED_HIGH(GPIOA_PIN0) | \ 227 | PIN_OSPEED_HIGH(GPIOA_PIN1) | \ 228 | PIN_OSPEED_LOW(GPIOA_USART_TX) | \ 229 | PIN_OSPEED_LOW(GPIOA_USART_RX) | \ 230 | PIN_OSPEED_LOW(GPIOA_LED_GREEN) | \ 231 | PIN_OSPEED_HIGH(GPIOA_PIN5) | \ 232 | PIN_OSPEED_HIGH(GPIOA_PIN6) | \ 233 | PIN_OSPEED_HIGH(GPIOA_PIN7) | \ 234 | PIN_OSPEED_HIGH(GPIOA_PIN8) | \ 235 | PIN_OSPEED_HIGH(GPIOA_PIN9) | \ 236 | PIN_OSPEED_HIGH(GPIOA_PIN10) | \ 237 | PIN_OSPEED_HIGH(GPIOA_PIN11) | \ 238 | PIN_OSPEED_HIGH(GPIOA_PIN12) | \ 239 | PIN_OSPEED_HIGH(GPIOA_SWDIO) | \ 240 | PIN_OSPEED_HIGH(GPIOA_SWCLK) | \ 241 | PIN_OSPEED_HIGH(GPIOA_PIN15)) 242 | #define VAL_GPIOA_PUPDR (PIN_PUPDR_PULLUP(GPIOA_PIN0) | \ 243 | PIN_PUPDR_PULLUP(GPIOA_PIN1) | \ 244 | PIN_PUPDR_FLOATING(GPIOA_USART_TX) | \ 245 | PIN_PUPDR_FLOATING(GPIOA_USART_RX) | \ 246 | PIN_PUPDR_FLOATING(GPIOA_LED_GREEN) | \ 247 | PIN_PUPDR_PULLUP(GPIOA_PIN5) | \ 248 | PIN_PUPDR_PULLUP(GPIOA_PIN6) | \ 249 | PIN_PUPDR_PULLUP(GPIOA_PIN7) | \ 250 | PIN_PUPDR_PULLUP(GPIOA_PIN8) | \ 251 | PIN_PUPDR_PULLUP(GPIOA_PIN9) | \ 252 | PIN_PUPDR_PULLUP(GPIOA_PIN10) | \ 253 | PIN_PUPDR_PULLUP(GPIOA_PIN11) | \ 254 | PIN_PUPDR_PULLUP(GPIOA_PIN12) | \ 255 | PIN_PUPDR_PULLUP(GPIOA_SWDIO) | \ 256 | PIN_PUPDR_PULLDOWN(GPIOA_SWCLK) | \ 257 | PIN_PUPDR_PULLUP(GPIOA_PIN15)) 258 | #define VAL_GPIOA_ODR (PIN_ODR_HIGH(GPIOA_PIN0) | \ 259 | PIN_ODR_HIGH(GPIOA_PIN1) | \ 260 | PIN_ODR_HIGH(GPIOA_USART_TX) | \ 261 | PIN_ODR_HIGH(GPIOA_USART_RX) | \ 262 | PIN_ODR_LOW(GPIOA_LED_GREEN) | \ 263 | PIN_ODR_HIGH(GPIOA_PIN5) | \ 264 | PIN_ODR_HIGH(GPIOA_PIN6) | \ 265 | PIN_ODR_HIGH(GPIOA_PIN7) | \ 266 | PIN_ODR_HIGH(GPIOA_PIN8) | \ 267 | PIN_ODR_HIGH(GPIOA_PIN9) | \ 268 | PIN_ODR_HIGH(GPIOA_PIN10) | \ 269 | PIN_ODR_HIGH(GPIOA_PIN11) | \ 270 | PIN_ODR_HIGH(GPIOA_PIN12) | \ 271 | PIN_ODR_HIGH(GPIOA_SWDIO) | \ 272 | PIN_ODR_HIGH(GPIOA_SWCLK) | \ 273 | PIN_ODR_HIGH(GPIOA_PIN15)) 274 | #define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_PIN0, 0) | \ 275 | PIN_AFIO_AF(GPIOA_PIN1, 0) | \ 276 | PIN_AFIO_AF(GPIOA_USART_TX, 1) | \ 277 | PIN_AFIO_AF(GPIOA_USART_RX, 1) | \ 278 | PIN_AFIO_AF(GPIOA_LED_GREEN, 0) | \ 279 | PIN_AFIO_AF(GPIOA_PIN5, 0) | \ 280 | PIN_AFIO_AF(GPIOA_PIN6, 0) | \ 281 | PIN_AFIO_AF(GPIOA_PIN7, 0)) 282 | #define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_PIN8, 0) | \ 283 | PIN_AFIO_AF(GPIOA_PIN9, 0) | \ 284 | PIN_AFIO_AF(GPIOA_PIN10, 0) | \ 285 | PIN_AFIO_AF(GPIOA_PIN11, 0) | \ 286 | PIN_AFIO_AF(GPIOA_PIN12, 0) | \ 287 | PIN_AFIO_AF(GPIOA_SWDIO, 0) | \ 288 | PIN_AFIO_AF(GPIOA_SWCLK, 0) | \ 289 | PIN_AFIO_AF(GPIOA_PIN15, 0)) 290 | 291 | /* 292 | * GPIOB setup: 293 | * 294 | * PB0 - PIN0 (input pullup). 295 | * PB1 - PIN1 (input pullup). 296 | * PB2 - PIN2 (input pullup). 297 | * PB3 - PIN3 (input pullup). 298 | * PB4 - PIN4 (input pullup). 299 | * PB5 - PIN5 (input pullup). 300 | * PB6 - PIN6 (input pullup). 301 | * PB7 - PIN7 (input pullup). 302 | * PB8 - PIN8 (input pullup). 303 | * PB9 - PIN9 (input pullup). 304 | * PB10 - PIN10 (input pullup). 305 | * PB11 - PIN11 (input pullup). 306 | * PB12 - PIN12 (input pullup). 307 | * PB13 - PIN13 (input pullup). 308 | * PB14 - PIN14 (input pullup). 309 | * PB15 - PIN15 (input pullup). 310 | */ 311 | #define VAL_GPIOB_MODER (PIN_MODE_INPUT(GPIOB_PIN0) | \ 312 | PIN_MODE_INPUT(GPIOB_PIN1) | \ 313 | PIN_MODE_INPUT(GPIOB_PIN2) | \ 314 | PIN_MODE_INPUT(GPIOB_PIN3) | \ 315 | PIN_MODE_INPUT(GPIOB_PIN4) | \ 316 | PIN_MODE_INPUT(GPIOB_PIN5) | \ 317 | PIN_MODE_INPUT(GPIOB_PIN6) | \ 318 | PIN_MODE_INPUT(GPIOB_PIN7) | \ 319 | PIN_MODE_INPUT(GPIOB_PIN8) | \ 320 | PIN_MODE_INPUT(GPIOB_PIN9) | \ 321 | PIN_MODE_INPUT(GPIOB_PIN10) | \ 322 | PIN_MODE_INPUT(GPIOB_PIN11) | \ 323 | PIN_MODE_INPUT(GPIOB_PIN12) | \ 324 | PIN_MODE_INPUT(GPIOB_PIN13) | \ 325 | PIN_MODE_INPUT(GPIOB_PIN14) | \ 326 | PIN_MODE_INPUT(GPIOB_PIN15)) 327 | #define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(GPIOB_PIN0) | \ 328 | PIN_OTYPE_PUSHPULL(GPIOB_PIN1) | \ 329 | PIN_OTYPE_PUSHPULL(GPIOB_PIN2) | \ 330 | PIN_OTYPE_PUSHPULL(GPIOB_PIN3) | \ 331 | PIN_OTYPE_PUSHPULL(GPIOB_PIN4) | \ 332 | PIN_OTYPE_PUSHPULL(GPIOB_PIN5) | \ 333 | PIN_OTYPE_PUSHPULL(GPIOB_PIN6) | \ 334 | PIN_OTYPE_PUSHPULL(GPIOB_PIN7) | \ 335 | PIN_OTYPE_PUSHPULL(GPIOB_PIN8) | \ 336 | PIN_OTYPE_PUSHPULL(GPIOB_PIN9) | \ 337 | PIN_OTYPE_PUSHPULL(GPIOB_PIN10) | \ 338 | PIN_OTYPE_PUSHPULL(GPIOB_PIN11) | \ 339 | PIN_OTYPE_PUSHPULL(GPIOB_PIN12) | \ 340 | PIN_OTYPE_PUSHPULL(GPIOB_PIN13) | \ 341 | PIN_OTYPE_PUSHPULL(GPIOB_PIN14) | \ 342 | PIN_OTYPE_PUSHPULL(GPIOB_PIN15)) 343 | #define VAL_GPIOB_OSPEEDR (PIN_OSPEED_HIGH(GPIOB_PIN0) | \ 344 | PIN_OSPEED_HIGH(GPIOB_PIN1) | \ 345 | PIN_OSPEED_HIGH(GPIOB_PIN2) | \ 346 | PIN_OSPEED_HIGH(GPIOB_PIN3) | \ 347 | PIN_OSPEED_HIGH(GPIOB_PIN4) | \ 348 | PIN_OSPEED_HIGH(GPIOB_PIN5) | \ 349 | PIN_OSPEED_HIGH(GPIOB_PIN6) | \ 350 | PIN_OSPEED_HIGH(GPIOB_PIN7) | \ 351 | PIN_OSPEED_HIGH(GPIOB_PIN8) | \ 352 | PIN_OSPEED_HIGH(GPIOB_PIN9) | \ 353 | PIN_OSPEED_HIGH(GPIOB_PIN10) | \ 354 | PIN_OSPEED_HIGH(GPIOB_PIN11) | \ 355 | PIN_OSPEED_HIGH(GPIOB_PIN12) | \ 356 | PIN_OSPEED_HIGH(GPIOB_PIN13) | \ 357 | PIN_OSPEED_HIGH(GPIOB_PIN14) | \ 358 | PIN_OSPEED_HIGH(GPIOB_PIN15)) 359 | #define VAL_GPIOB_PUPDR (PIN_PUPDR_PULLUP(GPIOB_PIN0) | \ 360 | PIN_PUPDR_PULLUP(GPIOB_PIN1) | \ 361 | PIN_PUPDR_PULLUP(GPIOB_PIN2) | \ 362 | PIN_PUPDR_PULLUP(GPIOB_PIN3) | \ 363 | PIN_PUPDR_PULLUP(GPIOB_PIN4) | \ 364 | PIN_PUPDR_PULLUP(GPIOB_PIN5) | \ 365 | PIN_PUPDR_PULLUP(GPIOB_PIN6) | \ 366 | PIN_PUPDR_PULLUP(GPIOB_PIN7) | \ 367 | PIN_PUPDR_PULLUP(GPIOB_PIN8) | \ 368 | PIN_PUPDR_PULLUP(GPIOB_PIN9) | \ 369 | PIN_PUPDR_PULLUP(GPIOB_PIN10) | \ 370 | PIN_PUPDR_PULLUP(GPIOB_PIN11) | \ 371 | PIN_PUPDR_PULLUP(GPIOB_PIN12) | \ 372 | PIN_PUPDR_PULLUP(GPIOB_PIN13) | \ 373 | PIN_PUPDR_PULLUP(GPIOB_PIN14) | \ 374 | PIN_PUPDR_PULLUP(GPIOB_PIN15)) 375 | #define VAL_GPIOB_ODR (PIN_ODR_HIGH(GPIOB_PIN0) | \ 376 | PIN_ODR_HIGH(GPIOB_PIN1) | \ 377 | PIN_ODR_HIGH(GPIOB_PIN2) | \ 378 | PIN_ODR_HIGH(GPIOB_PIN3) | \ 379 | PIN_ODR_HIGH(GPIOB_PIN4) | \ 380 | PIN_ODR_HIGH(GPIOB_PIN5) | \ 381 | PIN_ODR_HIGH(GPIOB_PIN6) | \ 382 | PIN_ODR_HIGH(GPIOB_PIN7) | \ 383 | PIN_ODR_HIGH(GPIOB_PIN8) | \ 384 | PIN_ODR_HIGH(GPIOB_PIN9) | \ 385 | PIN_ODR_HIGH(GPIOB_PIN10) | \ 386 | PIN_ODR_HIGH(GPIOB_PIN11) | \ 387 | PIN_ODR_HIGH(GPIOB_PIN12) | \ 388 | PIN_ODR_HIGH(GPIOB_PIN13) | \ 389 | PIN_ODR_HIGH(GPIOB_PIN14) | \ 390 | PIN_ODR_HIGH(GPIOB_PIN15)) 391 | #define VAL_GPIOB_AFRL (PIN_AFIO_AF(GPIOB_PIN0, 0) | \ 392 | PIN_AFIO_AF(GPIOB_PIN1, 0) | \ 393 | PIN_AFIO_AF(GPIOB_PIN2, 0) | \ 394 | PIN_AFIO_AF(GPIOB_PIN3, 0) | \ 395 | PIN_AFIO_AF(GPIOB_PIN4, 0) | \ 396 | PIN_AFIO_AF(GPIOB_PIN5, 0) | \ 397 | PIN_AFIO_AF(GPIOB_PIN6, 0) | \ 398 | PIN_AFIO_AF(GPIOB_PIN7, 0)) 399 | #define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_PIN8, 0) | \ 400 | PIN_AFIO_AF(GPIOB_PIN9, 0) | \ 401 | PIN_AFIO_AF(GPIOB_PIN10, 0) | \ 402 | PIN_AFIO_AF(GPIOB_PIN11, 0) | \ 403 | PIN_AFIO_AF(GPIOB_PIN12, 0) | \ 404 | PIN_AFIO_AF(GPIOB_PIN13, 0) | \ 405 | PIN_AFIO_AF(GPIOB_PIN14, 0) | \ 406 | PIN_AFIO_AF(GPIOB_PIN15, 0)) 407 | 408 | /* 409 | * GPIOC setup: 410 | * 411 | * PC0 - PIN0 (input pullup). 412 | * PC1 - PIN1 (input pullup). 413 | * PC2 - PIN2 (input pullup). 414 | * PC3 - PIN3 (input pullup). 415 | * PC4 - PIN4 (input pullup). 416 | * PC5 - PIN5 (input pullup). 417 | * PC6 - PIN6 (input pullup). 418 | * PC7 - PIN7 (input pullup). 419 | * PC8 - PIN8 (input pullup). 420 | * PC9 - PIN9 (input pullup). 421 | * PC10 - PIN10 (input pullup). 422 | * PC11 - PIN11 (input pullup). 423 | * PC12 - PIN12 (input pullup). 424 | * PC13 - PIN13 (input pullup). 425 | * PC14 - PIN14 (input pullup). 426 | * PC15 - PIN15 (input pullup). 427 | */ 428 | #define VAL_GPIOC_MODER (PIN_MODE_INPUT(GPIOC_PIN0) | \ 429 | PIN_MODE_INPUT(GPIOC_PIN1) | \ 430 | PIN_MODE_INPUT(GPIOC_PIN2) | \ 431 | PIN_MODE_INPUT(GPIOC_PIN3) | \ 432 | PIN_MODE_INPUT(GPIOC_PIN4) | \ 433 | PIN_MODE_INPUT(GPIOC_PIN5) | \ 434 | PIN_MODE_INPUT(GPIOC_PIN6) | \ 435 | PIN_MODE_INPUT(GPIOC_PIN7) | \ 436 | PIN_MODE_INPUT(GPIOC_PIN8) | \ 437 | PIN_MODE_INPUT(GPIOC_PIN9) | \ 438 | PIN_MODE_INPUT(GPIOC_PIN10) | \ 439 | PIN_MODE_INPUT(GPIOC_PIN11) | \ 440 | PIN_MODE_INPUT(GPIOC_PIN12) | \ 441 | PIN_MODE_INPUT(GPIOC_PIN13) | \ 442 | PIN_MODE_INPUT(GPIOC_PIN14) | \ 443 | PIN_MODE_INPUT(GPIOC_PIN15)) 444 | #define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(GPIOC_PIN0) | \ 445 | PIN_OTYPE_PUSHPULL(GPIOC_PIN1) | \ 446 | PIN_OTYPE_PUSHPULL(GPIOC_PIN2) | \ 447 | PIN_OTYPE_PUSHPULL(GPIOC_PIN3) | \ 448 | PIN_OTYPE_PUSHPULL(GPIOC_PIN4) | \ 449 | PIN_OTYPE_PUSHPULL(GPIOC_PIN5) | \ 450 | PIN_OTYPE_PUSHPULL(GPIOC_PIN6) | \ 451 | PIN_OTYPE_PUSHPULL(GPIOC_PIN7) | \ 452 | PIN_OTYPE_PUSHPULL(GPIOC_PIN8) | \ 453 | PIN_OTYPE_PUSHPULL(GPIOC_PIN9) | \ 454 | PIN_OTYPE_PUSHPULL(GPIOC_PIN10) | \ 455 | PIN_OTYPE_PUSHPULL(GPIOC_PIN11) | \ 456 | PIN_OTYPE_PUSHPULL(GPIOC_PIN12) | \ 457 | PIN_OTYPE_PUSHPULL(GPIOC_PIN13) | \ 458 | PIN_OTYPE_PUSHPULL(GPIOC_PIN14) | \ 459 | PIN_OTYPE_PUSHPULL(GPIOC_PIN15)) 460 | #define VAL_GPIOC_OSPEEDR (PIN_OSPEED_HIGH(GPIOC_PIN0) | \ 461 | PIN_OSPEED_HIGH(GPIOC_PIN1) | \ 462 | PIN_OSPEED_HIGH(GPIOC_PIN2) | \ 463 | PIN_OSPEED_HIGH(GPIOC_PIN3) | \ 464 | PIN_OSPEED_HIGH(GPIOC_PIN4) | \ 465 | PIN_OSPEED_HIGH(GPIOC_PIN5) | \ 466 | PIN_OSPEED_HIGH(GPIOC_PIN6) | \ 467 | PIN_OSPEED_HIGH(GPIOC_PIN7) | \ 468 | PIN_OSPEED_HIGH(GPIOC_PIN8) | \ 469 | PIN_OSPEED_HIGH(GPIOC_PIN9) | \ 470 | PIN_OSPEED_HIGH(GPIOC_PIN10) | \ 471 | PIN_OSPEED_HIGH(GPIOC_PIN11) | \ 472 | PIN_OSPEED_HIGH(GPIOC_PIN12) | \ 473 | PIN_OSPEED_HIGH(GPIOC_PIN13) | \ 474 | PIN_OSPEED_HIGH(GPIOC_PIN14) | \ 475 | PIN_OSPEED_HIGH(GPIOC_PIN15)) 476 | #define VAL_GPIOC_PUPDR (PIN_PUPDR_PULLUP(GPIOC_PIN0) | \ 477 | PIN_PUPDR_PULLUP(GPIOC_PIN1) | \ 478 | PIN_PUPDR_PULLUP(GPIOC_PIN2) | \ 479 | PIN_PUPDR_PULLUP(GPIOC_PIN3) | \ 480 | PIN_PUPDR_PULLUP(GPIOC_PIN4) | \ 481 | PIN_PUPDR_PULLUP(GPIOC_PIN5) | \ 482 | PIN_PUPDR_PULLUP(GPIOC_PIN6) | \ 483 | PIN_PUPDR_PULLUP(GPIOC_PIN7) | \ 484 | PIN_PUPDR_PULLUP(GPIOC_PIN8) | \ 485 | PIN_PUPDR_PULLUP(GPIOC_PIN9) | \ 486 | PIN_PUPDR_PULLUP(GPIOC_PIN10) | \ 487 | PIN_PUPDR_PULLUP(GPIOC_PIN11) | \ 488 | PIN_PUPDR_PULLUP(GPIOC_PIN12) | \ 489 | PIN_PUPDR_PULLUP(GPIOC_PIN13) | \ 490 | PIN_PUPDR_PULLUP(GPIOC_PIN14) | \ 491 | PIN_PUPDR_PULLUP(GPIOC_PIN15)) 492 | #define VAL_GPIOC_ODR (PIN_ODR_HIGH(GPIOC_PIN0) | \ 493 | PIN_ODR_HIGH(GPIOC_PIN1) | \ 494 | PIN_ODR_HIGH(GPIOC_PIN2) | \ 495 | PIN_ODR_HIGH(GPIOC_PIN3) | \ 496 | PIN_ODR_HIGH(GPIOC_PIN4) | \ 497 | PIN_ODR_HIGH(GPIOC_PIN5) | \ 498 | PIN_ODR_HIGH(GPIOC_PIN6) | \ 499 | PIN_ODR_HIGH(GPIOC_PIN7) | \ 500 | PIN_ODR_HIGH(GPIOC_PIN8) | \ 501 | PIN_ODR_HIGH(GPIOC_PIN9) | \ 502 | PIN_ODR_HIGH(GPIOC_PIN10) | \ 503 | PIN_ODR_HIGH(GPIOC_PIN11) | \ 504 | PIN_ODR_HIGH(GPIOC_PIN12) | \ 505 | PIN_ODR_HIGH(GPIOC_PIN13) | \ 506 | PIN_ODR_HIGH(GPIOC_PIN14) | \ 507 | PIN_ODR_HIGH(GPIOC_PIN15)) 508 | #define VAL_GPIOC_AFRL (PIN_AFIO_AF(GPIOC_PIN0, 0) | \ 509 | PIN_AFIO_AF(GPIOC_PIN1, 0) | \ 510 | PIN_AFIO_AF(GPIOC_PIN2, 0) | \ 511 | PIN_AFIO_AF(GPIOC_PIN3, 0) | \ 512 | PIN_AFIO_AF(GPIOC_PIN4, 0) | \ 513 | PIN_AFIO_AF(GPIOC_PIN5, 0) | \ 514 | PIN_AFIO_AF(GPIOC_PIN6, 0) | \ 515 | PIN_AFIO_AF(GPIOC_PIN7, 0)) 516 | #define VAL_GPIOC_AFRH (PIN_AFIO_AF(GPIOC_PIN8, 0) | \ 517 | PIN_AFIO_AF(GPIOC_PIN9, 0) | \ 518 | PIN_AFIO_AF(GPIOC_PIN10, 0) | \ 519 | PIN_AFIO_AF(GPIOC_PIN11, 0) | \ 520 | PIN_AFIO_AF(GPIOC_PIN12, 0) | \ 521 | PIN_AFIO_AF(GPIOC_PIN13, 0) | \ 522 | PIN_AFIO_AF(GPIOC_PIN14, 0) | \ 523 | PIN_AFIO_AF(GPIOC_PIN15, 0)) 524 | 525 | 526 | /* 527 | * GPIOF setup: 528 | * 529 | * PF0 - OSC_IN (input floating). 530 | * PF1 - OSC_OUT (input floating). 531 | * PF2 - PIN2 (input pullup). 532 | * PF3 - PIN3 (input pullup). 533 | * PF4 - PIN4 (input pullup). 534 | * PF5 - PIN5 (input pullup). 535 | * PF6 - PIN6 (input pullup). 536 | * PF7 - PIN7 (input pullup). 537 | * PF8 - PIN8 (input pullup). 538 | * PF9 - PIN9 (input pullup). 539 | * PF10 - PIN10 (input pullup). 540 | * PF11 - PIN11 (input pullup). 541 | * PF12 - PIN12 (input pullup). 542 | * PF13 - PIN13 (input pullup). 543 | * PF14 - PIN14 (input pullup). 544 | * PF15 - PIN15 (input pullup). 545 | */ 546 | #define VAL_GPIOF_MODER (PIN_MODE_INPUT(GPIOF_OSC_IN) | \ 547 | PIN_MODE_INPUT(GPIOF_OSC_OUT) | \ 548 | PIN_MODE_INPUT(GPIOF_PIN2) | \ 549 | PIN_MODE_INPUT(GPIOF_PIN3) | \ 550 | PIN_MODE_INPUT(GPIOF_PIN4) | \ 551 | PIN_MODE_INPUT(GPIOF_PIN5) | \ 552 | PIN_MODE_INPUT(GPIOF_PIN6) | \ 553 | PIN_MODE_INPUT(GPIOF_PIN7) | \ 554 | PIN_MODE_INPUT(GPIOF_PIN8) | \ 555 | PIN_MODE_INPUT(GPIOF_PIN9) | \ 556 | PIN_MODE_INPUT(GPIOF_PIN10) | \ 557 | PIN_MODE_INPUT(GPIOF_PIN11) | \ 558 | PIN_MODE_INPUT(GPIOF_PIN12) | \ 559 | PIN_MODE_INPUT(GPIOF_PIN13) | \ 560 | PIN_MODE_INPUT(GPIOF_PIN14) | \ 561 | PIN_MODE_INPUT(GPIOF_PIN15)) 562 | #define VAL_GPIOF_OTYPER (PIN_OTYPE_PUSHPULL(GPIOF_OSC_IN) | \ 563 | PIN_OTYPE_PUSHPULL(GPIOF_OSC_OUT) | \ 564 | PIN_OTYPE_PUSHPULL(GPIOF_PIN2) | \ 565 | PIN_OTYPE_PUSHPULL(GPIOF_PIN3) | \ 566 | PIN_OTYPE_PUSHPULL(GPIOF_PIN4) | \ 567 | PIN_OTYPE_PUSHPULL(GPIOF_PIN5) | \ 568 | PIN_OTYPE_PUSHPULL(GPIOF_PIN6) | \ 569 | PIN_OTYPE_PUSHPULL(GPIOF_PIN7) | \ 570 | PIN_OTYPE_PUSHPULL(GPIOF_PIN8) | \ 571 | PIN_OTYPE_PUSHPULL(GPIOF_PIN9) | \ 572 | PIN_OTYPE_PUSHPULL(GPIOF_PIN10) | \ 573 | PIN_OTYPE_PUSHPULL(GPIOF_PIN11) | \ 574 | PIN_OTYPE_PUSHPULL(GPIOF_PIN12) | \ 575 | PIN_OTYPE_PUSHPULL(GPIOF_PIN13) | \ 576 | PIN_OTYPE_PUSHPULL(GPIOF_PIN14) | \ 577 | PIN_OTYPE_PUSHPULL(GPIOF_PIN15)) 578 | #define VAL_GPIOF_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOF_OSC_IN) | \ 579 | PIN_OSPEED_VERYLOW(GPIOF_OSC_OUT) | \ 580 | PIN_OSPEED_VERYLOW(GPIOF_PIN2) | \ 581 | PIN_OSPEED_VERYLOW(GPIOF_PIN3) | \ 582 | PIN_OSPEED_VERYLOW(GPIOF_PIN4) | \ 583 | PIN_OSPEED_VERYLOW(GPIOF_PIN5) | \ 584 | PIN_OSPEED_VERYLOW(GPIOF_PIN6) | \ 585 | PIN_OSPEED_VERYLOW(GPIOF_PIN7) | \ 586 | PIN_OSPEED_VERYLOW(GPIOF_PIN8) | \ 587 | PIN_OSPEED_VERYLOW(GPIOF_PIN9) | \ 588 | PIN_OSPEED_VERYLOW(GPIOF_PIN10) | \ 589 | PIN_OSPEED_VERYLOW(GPIOF_PIN11) | \ 590 | PIN_OSPEED_VERYLOW(GPIOF_PIN12) | \ 591 | PIN_OSPEED_VERYLOW(GPIOF_PIN13) | \ 592 | PIN_OSPEED_VERYLOW(GPIOF_PIN14) | \ 593 | PIN_OSPEED_VERYLOW(GPIOF_PIN15)) 594 | #define VAL_GPIOF_PUPDR (PIN_PUPDR_FLOATING(GPIOF_OSC_IN) | \ 595 | PIN_PUPDR_FLOATING(GPIOF_OSC_OUT) | \ 596 | PIN_PUPDR_PULLUP(GPIOF_PIN2) | \ 597 | PIN_PUPDR_PULLUP(GPIOF_PIN3) | \ 598 | PIN_PUPDR_PULLUP(GPIOF_PIN4) | \ 599 | PIN_PUPDR_PULLUP(GPIOF_PIN5) | \ 600 | PIN_PUPDR_PULLUP(GPIOF_PIN6) | \ 601 | PIN_PUPDR_PULLUP(GPIOF_PIN7) | \ 602 | PIN_PUPDR_PULLUP(GPIOF_PIN8) | \ 603 | PIN_PUPDR_PULLUP(GPIOF_PIN9) | \ 604 | PIN_PUPDR_PULLUP(GPIOF_PIN10) | \ 605 | PIN_PUPDR_PULLUP(GPIOF_PIN11) | \ 606 | PIN_PUPDR_PULLUP(GPIOF_PIN12) | \ 607 | PIN_PUPDR_PULLUP(GPIOF_PIN13) | \ 608 | PIN_PUPDR_PULLUP(GPIOF_PIN14) | \ 609 | PIN_PUPDR_PULLUP(GPIOF_PIN15)) 610 | #define VAL_GPIOF_ODR (PIN_ODR_HIGH(GPIOF_OSC_IN) | \ 611 | PIN_ODR_HIGH(GPIOF_OSC_OUT) | \ 612 | PIN_ODR_HIGH(GPIOF_PIN2) | \ 613 | PIN_ODR_HIGH(GPIOF_PIN3) | \ 614 | PIN_ODR_HIGH(GPIOF_PIN4) | \ 615 | PIN_ODR_HIGH(GPIOF_PIN5) | \ 616 | PIN_ODR_HIGH(GPIOF_PIN6) | \ 617 | PIN_ODR_HIGH(GPIOF_PIN7) | \ 618 | PIN_ODR_HIGH(GPIOF_PIN8) | \ 619 | PIN_ODR_HIGH(GPIOF_PIN9) | \ 620 | PIN_ODR_HIGH(GPIOF_PIN10) | \ 621 | PIN_ODR_HIGH(GPIOF_PIN11) | \ 622 | PIN_ODR_HIGH(GPIOF_PIN12) | \ 623 | PIN_ODR_HIGH(GPIOF_PIN13) | \ 624 | PIN_ODR_HIGH(GPIOF_PIN14) | \ 625 | PIN_ODR_HIGH(GPIOF_PIN15)) 626 | #define VAL_GPIOF_AFRL (PIN_AFIO_AF(GPIOF_OSC_IN, 0) | \ 627 | PIN_AFIO_AF(GPIOF_OSC_OUT, 0) | \ 628 | PIN_AFIO_AF(GPIOF_PIN2, 0) | \ 629 | PIN_AFIO_AF(GPIOF_PIN3, 0) | \ 630 | PIN_AFIO_AF(GPIOF_PIN4, 0) | \ 631 | PIN_AFIO_AF(GPIOF_PIN5, 0) | \ 632 | PIN_AFIO_AF(GPIOF_PIN6, 0) | \ 633 | PIN_AFIO_AF(GPIOF_PIN7, 0)) 634 | #define VAL_GPIOF_AFRH (PIN_AFIO_AF(GPIOF_PIN8, 0) | \ 635 | PIN_AFIO_AF(GPIOF_PIN9, 0) | \ 636 | PIN_AFIO_AF(GPIOF_PIN10, 0) | \ 637 | PIN_AFIO_AF(GPIOF_PIN11, 0) | \ 638 | PIN_AFIO_AF(GPIOF_PIN12, 0) | \ 639 | PIN_AFIO_AF(GPIOF_PIN13, 0) | \ 640 | PIN_AFIO_AF(GPIOF_PIN14, 0) | \ 641 | PIN_AFIO_AF(GPIOF_PIN15, 0)) 642 | 643 | 644 | #if !defined(_FROM_ASM_) 645 | #ifdef __cplusplus 646 | extern "C" { 647 | #endif 648 | void boardInit(void); 649 | #ifdef __cplusplus 650 | } 651 | #endif 652 | #endif /* _FROM_ASM_ */ 653 | 654 | #endif /* _BOARD_H_ */ 655 | -------------------------------------------------------------------------------- /stm32f030f4-dev-v1.0/board.mk: -------------------------------------------------------------------------------- 1 | # List of all the board related files. 2 | BOARDSRC = stm32f030f4-dev-v1.0/board.c 3 | 4 | # Required include directories 5 | BOARDINC = stm32f030f4-dev-v1.0 6 | --------------------------------------------------------------------------------