aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-06-07 14:34:59 +0000
committerbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-06-07 14:34:59 +0000
commit5cad241306f64d0a3c0f7829421e4bf8f4b18fbe (patch)
treeebbcad6d0cdb19fa5ef0bf5f6dc5cf80dfbdc4d1 /os
parent152f34a80c6ffe5fd17809732272823091b854e8 (diff)
parentaec912f13f9aa85cd677353fa556f679c3832970 (diff)
downloadChibiOS-5cad241306f64d0a3c0f7829421e4bf8f4b18fbe.tar.gz
ChibiOS-5cad241306f64d0a3c0f7829421e4bf8f4b18fbe.tar.bz2
ChibiOS-5cad241306f64d0a3c0f7829421e4bf8f4b18fbe.zip
I2C. Merged code from trunk.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3036 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/dox/adc.dox10
-rw-r--r--os/hal/dox/can.dox6
-rw-r--r--os/hal/dox/gpt.dox78
-rw-r--r--os/hal/dox/hal.dox24
-rw-r--r--os/hal/dox/i2c.dox8
-rw-r--r--os/hal/dox/icu.dox115
-rw-r--r--os/hal/dox/mac.dox7
-rw-r--r--os/hal/dox/mmc_spi.dox5
-rw-r--r--os/hal/dox/pal.dox29
-rw-r--r--os/hal/dox/pwm.dox13
-rw-r--r--os/hal/dox/sdc.dox109
-rw-r--r--os/hal/dox/serial.dox43
-rw-r--r--os/hal/dox/serial_usb.dox56
-rw-r--r--os/hal/dox/spi.dox9
-rw-r--r--os/hal/dox/uart.dox44
-rw-r--r--os/hal/dox/usb.dox239
-rw-r--r--os/hal/hal.dox6
-rw-r--r--os/hal/hal.mk3
-rw-r--r--os/hal/include/adc.h61
-rw-r--r--os/hal/include/can.h5
-rw-r--r--os/hal/include/gpt.h105
-rw-r--r--os/hal/include/hal.h6
-rw-r--r--os/hal/include/i2c.h3
-rw-r--r--os/hal/include/icu.h169
-rw-r--r--os/hal/include/mac.h5
-rw-r--r--os/hal/include/mii.h8
-rw-r--r--os/hal/include/mmc_spi.h31
-rw-r--r--os/hal/include/pal.h34
-rw-r--r--os/hal/include/pwm.h129
-rw-r--r--os/hal/include/sdc.h234
-rw-r--r--os/hal/include/serial.h3
-rw-r--r--os/hal/include/serial_usb.h34
-rw-r--r--os/hal/include/spi.h33
-rw-r--r--os/hal/include/uart.h3
-rw-r--r--os/hal/include/usb.h286
-rw-r--r--os/hal/include/usb_cdc.h66
-rw-r--r--os/hal/platforms/AT91SAM7/at91sam7.h3
-rw-r--r--os/hal/platforms/AT91SAM7/at91sam7_mii.c3
-rw-r--r--os/hal/platforms/AT91SAM7/at91sam7_mii.h3
-rw-r--r--os/hal/platforms/AT91SAM7/hal_lld.c3
-rw-r--r--os/hal/platforms/AT91SAM7/hal_lld.h3
-rw-r--r--os/hal/platforms/AT91SAM7/mac_lld.c47
-rw-r--r--os/hal/platforms/AT91SAM7/mac_lld.h28
-rw-r--r--os/hal/platforms/AT91SAM7/pal_lld.c3
-rw-r--r--os/hal/platforms/AT91SAM7/pal_lld.h24
-rw-r--r--os/hal/platforms/AT91SAM7/platform.dox47
-rw-r--r--os/hal/platforms/AT91SAM7/serial_lld.c7
-rw-r--r--os/hal/platforms/AT91SAM7/serial_lld.h3
-rw-r--r--os/hal/platforms/AT91SAM7/spi_lld.c97
-rw-r--r--os/hal/platforms/AT91SAM7/spi_lld.h23
-rw-r--r--os/hal/platforms/AVR/hal_lld.c3
-rw-r--r--os/hal/platforms/AVR/hal_lld.h3
-rw-r--r--os/hal/platforms/AVR/platform.dox5
-rw-r--r--os/hal/platforms/AVR/serial_lld.c13
-rw-r--r--os/hal/platforms/AVR/serial_lld.h5
-rw-r--r--os/hal/platforms/LPC11xx/core_cm0.h3
-rw-r--r--os/hal/platforms/LPC11xx/gpt_lld.c342
-rw-r--r--os/hal/platforms/LPC11xx/gpt_lld.h208
-rw-r--r--os/hal/platforms/LPC11xx/hal_lld.c3
-rw-r--r--os/hal/platforms/LPC11xx/hal_lld.h3
-rw-r--r--os/hal/platforms/LPC11xx/pal_lld.c3
-rw-r--r--os/hal/platforms/LPC11xx/pal_lld.h3
-rw-r--r--os/hal/platforms/LPC11xx/platform.dox63
-rw-r--r--os/hal/platforms/LPC11xx/platform.mk1
-rw-r--r--os/hal/platforms/LPC11xx/serial_lld.c3
-rw-r--r--os/hal/platforms/LPC11xx/serial_lld.h3
-rw-r--r--os/hal/platforms/LPC11xx/spi_lld.c105
-rw-r--r--os/hal/platforms/LPC11xx/spi_lld.h37
-rw-r--r--os/hal/platforms/LPC13xx/core_cm3.h3
-rw-r--r--os/hal/platforms/LPC13xx/gpt_lld.c342
-rw-r--r--os/hal/platforms/LPC13xx/gpt_lld.h212
-rw-r--r--os/hal/platforms/LPC13xx/hal_lld.c3
-rw-r--r--os/hal/platforms/LPC13xx/hal_lld.h3
-rw-r--r--os/hal/platforms/LPC13xx/pal_lld.c3
-rw-r--r--os/hal/platforms/LPC13xx/pal_lld.h3
-rw-r--r--os/hal/platforms/LPC13xx/platform.dox63
-rw-r--r--os/hal/platforms/LPC13xx/platform.mk1
-rw-r--r--os/hal/platforms/LPC13xx/serial_lld.c3
-rw-r--r--os/hal/platforms/LPC13xx/serial_lld.h3
-rw-r--r--os/hal/platforms/LPC13xx/spi_lld.c103
-rw-r--r--os/hal/platforms/LPC13xx/spi_lld.h35
-rw-r--r--os/hal/platforms/LPC214x/hal_lld.c3
-rw-r--r--os/hal/platforms/LPC214x/hal_lld.h3
-rw-r--r--os/hal/platforms/LPC214x/lpc214x.h3
-rw-r--r--os/hal/platforms/LPC214x/pal_lld.c3
-rw-r--r--os/hal/platforms/LPC214x/pal_lld.h16
-rw-r--r--os/hal/platforms/LPC214x/platform.dox45
-rw-r--r--os/hal/platforms/LPC214x/serial_lld.c3
-rw-r--r--os/hal/platforms/LPC214x/serial_lld.h3
-rw-r--r--os/hal/platforms/LPC214x/spi_lld.c99
-rw-r--r--os/hal/platforms/LPC214x/spi_lld.h37
-rw-r--r--os/hal/platforms/LPC214x/vic.c3
-rw-r--r--os/hal/platforms/LPC214x/vic.h3
-rw-r--r--os/hal/platforms/MSP430/hal_lld.c3
-rw-r--r--os/hal/platforms/MSP430/hal_lld.h3
-rw-r--r--os/hal/platforms/MSP430/pal_lld.c3
-rw-r--r--os/hal/platforms/MSP430/pal_lld.h7
-rw-r--r--os/hal/platforms/MSP430/platform.dox7
-rw-r--r--os/hal/platforms/MSP430/serial_lld.c5
-rw-r--r--os/hal/platforms/MSP430/serial_lld.h3
-rw-r--r--os/hal/platforms/Posix/console.c3
-rw-r--r--os/hal/platforms/Posix/console.h3
-rw-r--r--os/hal/platforms/Posix/hal_lld.c3
-rw-r--r--os/hal/platforms/Posix/hal_lld.h3
-rw-r--r--os/hal/platforms/Posix/pal_lld.c3
-rw-r--r--os/hal/platforms/Posix/pal_lld.h12
-rw-r--r--os/hal/platforms/Posix/serial_lld.c3
-rw-r--r--os/hal/platforms/Posix/serial_lld.h3
-rw-r--r--os/hal/platforms/SPC56x/hal_lld.c3
-rw-r--r--os/hal/platforms/SPC56x/hal_lld.h7
-rw-r--r--os/hal/platforms/SPC56x/platform.dox5
-rw-r--r--os/hal/platforms/SPC56x/serial_lld.c3
-rw-r--r--os/hal/platforms/SPC56x/serial_lld.h3
-rw-r--r--os/hal/platforms/SPC56x/typedefs.h3
-rw-r--r--os/hal/platforms/STM32/adc_lld.c104
-rw-r--r--os/hal/platforms/STM32/adc_lld.h61
-rw-r--r--os/hal/platforms/STM32/can_lld.c143
-rw-r--r--os/hal/platforms/STM32/can_lld.h83
-rw-r--r--os/hal/platforms/STM32/core_cm3.h3
-rw-r--r--os/hal/platforms/STM32/gpt_lld.c417
-rw-r--r--os/hal/platforms/STM32/gpt_lld.h256
-rw-r--r--os/hal/platforms/STM32/hal_lld.c68
-rw-r--r--os/hal/platforms/STM32/hal_lld.h7
-rw-r--r--os/hal/platforms/STM32/hal_lld_f100.h3
-rw-r--r--os/hal/platforms/STM32/hal_lld_f103.h13
-rw-r--r--os/hal/platforms/STM32/hal_lld_f105_f107.h142
-rw-r--r--os/hal/platforms/STM32/icu_lld.c425
-rw-r--r--os/hal/platforms/STM32/icu_lld.h290
-rw-r--r--os/hal/platforms/STM32/pal_lld.c18
-rw-r--r--os/hal/platforms/STM32/pal_lld.h10
-rw-r--r--os/hal/platforms/STM32/platform.dox116
-rw-r--r--os/hal/platforms/STM32/platform.mk3
-rw-r--r--os/hal/platforms/STM32/pwm_lld.c249
-rw-r--r--os/hal/platforms/STM32/pwm_lld.h238
-rw-r--r--os/hal/platforms/STM32/sdc_lld.c722
-rw-r--r--os/hal/platforms/STM32/sdc_lld.h203
-rw-r--r--os/hal/platforms/STM32/serial_lld.c3
-rw-r--r--os/hal/platforms/STM32/serial_lld.h3
-rw-r--r--os/hal/platforms/STM32/spi_lld.c269
-rw-r--r--os/hal/platforms/STM32/spi_lld.h67
-rw-r--r--os/hal/platforms/STM32/stm32_dma.c398
-rw-r--r--os/hal/platforms/STM32/stm32_dma.h48
-rw-r--r--os/hal/platforms/STM32/stm32_usb.h10
-rw-r--r--os/hal/platforms/STM32/stm32f10x.h485
-rw-r--r--os/hal/platforms/STM32/uart_lld.c385
-rw-r--r--os/hal/platforms/STM32/uart_lld.h89
-rw-r--r--os/hal/platforms/STM32/usb_lld.c517
-rw-r--r--os/hal/platforms/STM32/usb_lld.h236
-rw-r--r--os/hal/platforms/STM8L/hal_lld.c3
-rw-r--r--os/hal/platforms/STM8L/hal_lld.h3
-rw-r--r--os/hal/platforms/STM8L/hal_lld_stm8l_hd.h3
-rw-r--r--os/hal/platforms/STM8L/hal_lld_stm8l_md.h3
-rw-r--r--os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h3
-rw-r--r--os/hal/platforms/STM8L/pal_lld.c3
-rw-r--r--os/hal/platforms/STM8L/pal_lld.h8
-rw-r--r--os/hal/platforms/STM8L/platform.dox7
-rw-r--r--os/hal/platforms/STM8L/serial_lld.c3
-rw-r--r--os/hal/platforms/STM8L/serial_lld.h15
-rw-r--r--os/hal/platforms/STM8L/shared_isr.c3
-rw-r--r--os/hal/platforms/STM8S/hal_lld.c3
-rw-r--r--os/hal/platforms/STM8S/hal_lld.h5
-rw-r--r--os/hal/platforms/STM8S/pal_lld.c3
-rw-r--r--os/hal/platforms/STM8S/pal_lld.h8
-rw-r--r--os/hal/platforms/STM8S/platform.dox45
-rw-r--r--os/hal/platforms/STM8S/serial_lld.c5
-rw-r--r--os/hal/platforms/STM8S/serial_lld.h3
-rw-r--r--os/hal/platforms/STM8S/spi_lld.c49
-rw-r--r--os/hal/platforms/STM8S/spi_lld.h31
-rw-r--r--os/hal/platforms/Win32/console.c3
-rw-r--r--os/hal/platforms/Win32/console.h3
-rw-r--r--os/hal/platforms/Win32/hal_lld.c3
-rw-r--r--os/hal/platforms/Win32/hal_lld.h3
-rw-r--r--os/hal/platforms/Win32/pal_lld.c3
-rw-r--r--os/hal/platforms/Win32/pal_lld.h12
-rw-r--r--os/hal/platforms/Win32/serial_lld.c3
-rw-r--r--os/hal/platforms/Win32/serial_lld.h3
-rw-r--r--os/hal/platforms/platforms.dox3
-rw-r--r--os/hal/src/adc.c81
-rw-r--r--os/hal/src/can.c83
-rw-r--r--os/hal/src/gpt.c229
-rw-r--r--os/hal/src/hal.c12
-rw-r--r--os/hal/src/i2c.c3
-rw-r--r--os/hal/src/icu.c151
-rw-r--r--os/hal/src/mac.c17
-rw-r--r--os/hal/src/mmc_spi.c202
-rw-r--r--os/hal/src/pal.c15
-rw-r--r--os/hal/src/pwm.c62
-rw-r--r--os/hal/src/sdc.c392
-rw-r--r--os/hal/src/serial.c3
-rw-r--r--os/hal/src/serial_usb.c107
-rw-r--r--os/hal/src/spi.c80
-rw-r--r--os/hal/src/uart.c100
-rw-r--r--os/hal/src/usb.c547
-rw-r--r--os/hal/templates/adc_lld.c7
-rw-r--r--os/hal/templates/adc_lld.h25
-rw-r--r--os/hal/templates/can_lld.c5
-rw-r--r--os/hal/templates/can_lld.h55
-rw-r--r--os/hal/templates/gpt_lld.c135
-rw-r--r--os/hal/templates/gpt_lld.h134
-rw-r--r--os/hal/templates/hal_lld.c3
-rw-r--r--os/hal/templates/hal_lld.h3
-rw-r--r--os/hal/templates/halconf.h68
-rw-r--r--os/hal/templates/i2c_lld.c3
-rw-r--r--os/hal/templates/i2c_lld.h3
-rw-r--r--os/hal/templates/icu_lld.c145
-rw-r--r--os/hal/templates/icu_lld.h138
-rw-r--r--os/hal/templates/mac_lld.c3
-rw-r--r--os/hal/templates/mac_lld.h17
-rw-r--r--os/hal/templates/meta/driver.c23
-rw-r--r--os/hal/templates/meta/driver.h3
-rw-r--r--os/hal/templates/meta/driver_lld.c9
-rw-r--r--os/hal/templates/meta/driver_lld.h7
-rw-r--r--os/hal/templates/pal_lld.c3
-rw-r--r--os/hal/templates/pal_lld.h3
-rw-r--r--os/hal/templates/pwm_lld.c38
-rw-r--r--os/hal/templates/pwm_lld.h98
-rw-r--r--os/hal/templates/serial_lld.c3
-rw-r--r--os/hal/templates/serial_lld.h3
-rw-r--r--os/hal/templates/spi_lld.c5
-rw-r--r--os/hal/templates/spi_lld.h19
-rw-r--r--os/hal/templates/uart_lld.c3
-rw-r--r--os/hal/templates/uart_lld.h21
-rw-r--r--os/hal/templates/usb_lld.c346
-rw-r--r--os/hal/templates/usb_lld.h310
-rw-r--r--os/kernel/include/ch.h9
-rw-r--r--os/kernel/include/chbsem.h5
-rw-r--r--os/kernel/include/chcond.h3
-rw-r--r--os/kernel/include/chdebug.h5
-rw-r--r--os/kernel/include/chdynamic.h3
-rw-r--r--os/kernel/include/chevents.h39
-rw-r--r--os/kernel/include/chfiles.h3
-rw-r--r--os/kernel/include/chheap.h7
-rw-r--r--os/kernel/include/chinline.h3
-rw-r--r--os/kernel/include/chioch.h3
-rw-r--r--os/kernel/include/chlists.h3
-rw-r--r--os/kernel/include/chmboxes.h6
-rw-r--r--os/kernel/include/chmemcore.h19
-rw-r--r--os/kernel/include/chmempools.h5
-rw-r--r--os/kernel/include/chmsg.h44
-rw-r--r--os/kernel/include/chmtx.h3
-rw-r--r--os/kernel/include/chqueues.h105
-rw-r--r--os/kernel/include/chregistry.h3
-rw-r--r--os/kernel/include/chschd.h15
-rw-r--r--os/kernel/include/chsem.h5
-rw-r--r--os/kernel/include/chstreams.h3
-rw-r--r--os/kernel/include/chsys.h7
-rw-r--r--os/kernel/include/chthreads.h31
-rw-r--r--os/kernel/include/chvt.h5
-rw-r--r--os/kernel/kernel.dox5
-rw-r--r--os/kernel/src/chcond.c25
-rw-r--r--os/kernel/src/chdebug.c5
-rw-r--r--os/kernel/src/chdynamic.c3
-rw-r--r--os/kernel/src/chevents.c29
-rw-r--r--os/kernel/src/chheap.c11
-rw-r--r--os/kernel/src/chlists.c3
-rw-r--r--os/kernel/src/chmboxes.c86
-rw-r--r--os/kernel/src/chmemcore.c47
-rw-r--r--os/kernel/src/chmempools.c7
-rw-r--r--os/kernel/src/chmsg.c62
-rw-r--r--os/kernel/src/chmtx.c13
-rw-r--r--os/kernel/src/chqueues.c174
-rw-r--r--os/kernel/src/chregistry.c3
-rw-r--r--os/kernel/src/chschd.c15
-rw-r--r--os/kernel/src/chsem.c28
-rw-r--r--os/kernel/src/chsys.c21
-rw-r--r--os/kernel/src/chthreads.c12
-rw-r--r--os/kernel/src/chvt.c17
-rw-r--r--os/kernel/templates/chconf.h47
-rw-r--r--os/kernel/templates/chcore.c3
-rw-r--r--os/kernel/templates/chcore.h87
-rw-r--r--os/kernel/templates/chtypes.h5
-rw-r--r--os/ports/GCC/ARM/AT91SAM7/armparams.h3
-rw-r--r--os/ports/GCC/ARM/AT91SAM7/vectors.s3
-rw-r--r--os/ports/GCC/ARM/AT91SAM7/wfi.h3
-rw-r--r--os/ports/GCC/ARM/LPC214x/armparams.h3
-rw-r--r--os/ports/GCC/ARM/LPC214x/vectors.s3
-rw-r--r--os/ports/GCC/ARM/LPC214x/wfi.h3
-rw-r--r--os/ports/GCC/ARM/chcore.c3
-rw-r--r--os/ports/GCC/ARM/chcore.h57
-rw-r--r--os/ports/GCC/ARM/chcoreasm.s3
-rw-r--r--os/ports/GCC/ARM/chtypes.h3
-rw-r--r--os/ports/GCC/ARM/crt0.s3
-rw-r--r--os/ports/GCC/ARM/port.dox3
-rw-r--r--os/ports/GCC/ARMCMx/LPC11xx/cmparams.h3
-rw-r--r--os/ports/GCC/ARMCMx/LPC11xx/port.mk5
-rw-r--r--os/ports/GCC/ARMCMx/LPC11xx/vectors.c7
-rw-r--r--os/ports/GCC/ARMCMx/LPC13xx/cmparams.h3
-rw-r--r--os/ports/GCC/ARMCMx/LPC13xx/port.mk5
-rw-r--r--os/ports/GCC/ARMCMx/LPC13xx/vectors.c7
-rw-r--r--os/ports/GCC/ARMCMx/STM32/cmparams.h3
-rw-r--r--os/ports/GCC/ARMCMx/STM32/port.mk5
-rw-r--r--os/ports/GCC/ARMCMx/STM32/vectors.c12
-rw-r--r--os/ports/GCC/ARMCMx/chcore.c3
-rw-r--r--os/ports/GCC/ARMCMx/chcore.h228
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v6m.c121
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v6m.h178
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v7m.c47
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v7m.h181
-rw-r--r--os/ports/GCC/ARMCMx/chtypes.h3
-rw-r--r--os/ports/GCC/ARMCMx/crt0.c274
-rw-r--r--os/ports/GCC/ARMCMx/crt0_v6m.s3
-rw-r--r--os/ports/GCC/ARMCMx/crt0_v7m.s3
-rw-r--r--os/ports/GCC/ARMCMx/nvic.c3
-rw-r--r--os/ports/GCC/ARMCMx/nvic.h3
-rw-r--r--os/ports/GCC/ARMCMx/old/chcore_v7m.c18
-rw-r--r--os/ports/GCC/ARMCMx/old/chcore_v7m.h13
-rw-r--r--os/ports/GCC/ARMCMx/port.dox71
-rw-r--r--os/ports/GCC/AVR/chcore.c7
-rw-r--r--os/ports/GCC/AVR/chcore.h33
-rw-r--r--os/ports/GCC/AVR/chtypes.h3
-rw-r--r--os/ports/GCC/AVR/port.dox3
-rw-r--r--os/ports/GCC/MSP430/chcore.c3
-rw-r--r--os/ports/GCC/MSP430/chcore.h31
-rw-r--r--os/ports/GCC/MSP430/chtypes.h3
-rw-r--r--os/ports/GCC/MSP430/port.dox3
-rw-r--r--os/ports/GCC/PPC/SPC56x/ivor.s3
-rw-r--r--os/ports/GCC/PPC/SPC56x/vectors.s3
-rw-r--r--os/ports/GCC/PPC/chcore.c3
-rw-r--r--os/ports/GCC/PPC/chcore.h39
-rw-r--r--os/ports/GCC/PPC/chtypes.h3
-rw-r--r--os/ports/GCC/PPC/crt0.s3
-rw-r--r--os/ports/GCC/PPC/port.dox3
-rw-r--r--os/ports/GCC/SIMIA32/chcore.c3
-rw-r--r--os/ports/GCC/SIMIA32/chcore.h27
-rw-r--r--os/ports/GCC/SIMIA32/chtypes.h3
-rw-r--r--os/ports/IAR/ARMCMx/LPC11xx/cmparams.h3
-rw-r--r--os/ports/IAR/ARMCMx/LPC11xx/vectors.s3
-rw-r--r--os/ports/IAR/ARMCMx/LPC13xx/cmparams.h3
-rw-r--r--os/ports/IAR/ARMCMx/LPC13xx/vectors.s3
-rw-r--r--os/ports/IAR/ARMCMx/STM32/cmparams.h3
-rw-r--r--os/ports/IAR/ARMCMx/STM32/vectors.s3
-rw-r--r--os/ports/IAR/ARMCMx/chcore.c3
-rw-r--r--os/ports/IAR/ARMCMx/chcore.h231
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v6m.c13
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v6m.h147
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v7m.c3
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v7m.h169
-rw-r--r--os/ports/IAR/ARMCMx/chcoreasm_v6m.s109
-rw-r--r--os/ports/IAR/ARMCMx/chcoreasm_v7m.s66
-rw-r--r--os/ports/IAR/ARMCMx/chtypes.h3
-rw-r--r--os/ports/IAR/ARMCMx/cstartup.s3
-rw-r--r--os/ports/IAR/ARMCMx/nvic.c3
-rw-r--r--os/ports/IAR/ARMCMx/nvic.h3
-rw-r--r--os/ports/IAR/ARMCMx/port.dox55
-rw-r--r--os/ports/RC/STM8/chcore.c3
-rw-r--r--os/ports/RC/STM8/chcore.h29
-rw-r--r--os/ports/RC/STM8/chtypes.h3
-rw-r--r--os/ports/RC/STM8/port.dox3
-rw-r--r--os/ports/RVCT/ARMCMx/LPC11xx/cmparams.h3
-rw-r--r--os/ports/RVCT/ARMCMx/LPC11xx/vectors.s3
-rw-r--r--os/ports/RVCT/ARMCMx/LPC13xx/cmparams.h3
-rw-r--r--os/ports/RVCT/ARMCMx/LPC13xx/vectors.s3
-rw-r--r--os/ports/RVCT/ARMCMx/STM32/cmparams.h3
-rw-r--r--os/ports/RVCT/ARMCMx/STM32/vectors.s3
-rw-r--r--os/ports/RVCT/ARMCMx/chcore.c3
-rw-r--r--os/ports/RVCT/ARMCMx/chcore.h226
-rw-r--r--os/ports/RVCT/ARMCMx/chcore_v6m.c13
-rw-r--r--os/ports/RVCT/ARMCMx/chcore_v6m.h154
-rw-r--r--os/ports/RVCT/ARMCMx/chcore_v7m.c3
-rw-r--r--os/ports/RVCT/ARMCMx/chcore_v7m.h181
-rw-r--r--os/ports/RVCT/ARMCMx/chcoreasm_v6m.s107
-rw-r--r--os/ports/RVCT/ARMCMx/chcoreasm_v7m.s66
-rw-r--r--os/ports/RVCT/ARMCMx/chtypes.h3
-rw-r--r--os/ports/RVCT/ARMCMx/cstartup.s3
-rw-r--r--os/ports/RVCT/ARMCMx/nvic.c3
-rw-r--r--os/ports/RVCT/ARMCMx/nvic.h3
-rw-r--r--os/ports/RVCT/ARMCMx/port.dox55
-rw-r--r--os/ports/cosmic/STM8/chcore.c3
-rw-r--r--os/ports/cosmic/STM8/chcore.h29
-rw-r--r--os/ports/cosmic/STM8/chtypes.h3
-rw-r--r--os/ports/cosmic/STM8/port.dox3
-rw-r--r--os/ports/ports.dox3
-rw-r--r--os/various/ch.cpp13
-rw-r--r--os/various/ch.hpp16
-rw-r--r--os/various/evtimer.c3
-rw-r--r--os/various/evtimer.h3
-rw-r--r--os/various/memstreams.c3
-rw-r--r--os/various/memstreams.h3
-rw-r--r--os/various/shell.c3
-rw-r--r--os/various/shell.h3
-rw-r--r--os/various/syscalls.c3
-rw-r--r--os/various/usb_msc.c303
-rw-r--r--os/various/usb_msc.h167
-rw-r--r--os/various/various.dox3
384 files changed, 14277 insertions, 4749 deletions
diff --git a/os/hal/dox/adc.dox b/os/hal/dox/adc.dox
index 9ebfca99c..bb8ff014f 100644
--- a/os/hal/dox/adc.dox
+++ b/os/hal/dox/adc.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -20,7 +21,8 @@
/**
* @defgroup ADC ADC Driver
* @brief Generic ADC Driver.
- * @details This module implements a generic ADC driver.
+ * @details This module implements a generic ADC (Analog to Digital Converter)
+ * driver supporting a variety of buffer and conversion modes.
* @pre In order to use the ADC driver the @p HAL_USE_ADC option
* must be enabled in @p halconf.h.
*
@@ -52,7 +54,7 @@
active -> ready [label="\nadcStopConversion()\nsync return"];
active -> active [label="\nasync callback (half buffer)\nasync callback (full buffer circular)\n>acg_endcb<"];
active -> complete [label="\nasync callback (full buffer)\n>acg_endcb<"];
- complete -> active [label="\nadcStartConversionI()\nthen\ncallback return()"];
+ complete -> active [label="\nadcStartConversionI()\nthen\ncallback return"];
complete -> ready [label="\ncallback return"];
}
* @enddot
@@ -78,7 +80,7 @@
active -> ready [label="\nadcStopConversion()\nsync return"];
active -> active [label="\nasync callback (half buffer)\nasync callback (full buffer circular)\n>acg_endcb<"];
active -> complete [label="\nasync callback (full buffer)\n>acg_endcb<"];
- complete -> active [label="\nadcStartConversionI()\nthen\ncallback return()"];
+ complete -> active [label="\nadcStartConversionI()\nthen\ncallback return"];
complete -> ready [label="\ncallback return"];
}
* @enddot
diff --git a/os/hal/dox/can.dox b/os/hal/dox/can.dox
index 81ee24e8b..1a0c81c0d 100644
--- a/os/hal/dox/can.dox
+++ b/os/hal/dox/can.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -20,7 +21,8 @@
/**
* @defgroup CAN CAN Driver
* @brief Generic CAN Driver.
- * @details This module implements a generic CAN driver.
+ * @details This module implements a generic CAN (Controller Area Network)
+ * driver allowing the exchange of information at frame level.
* @pre In order to use the CAN driver the @p HAL_USE_CAN option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/gpt.dox b/os/hal/dox/gpt.dox
new file mode 100644
index 000000000..d51ad6af3
--- /dev/null
+++ b/os/hal/dox/gpt.dox
@@ -0,0 +1,78 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup GPT GPT Driver
+ * @brief Generic GPT Driver.
+ * @details This module implements a generic GPT (General Purpose Timer)
+ * driver. The timer can be programmed in order to trigger callbacks
+ * after a specified time period or continuously with a specified
+ * interval.
+ * @pre In order to use the GPT driver the @p HAL_USE_GPT option
+ * must be enabled in @p halconf.h.
+ *
+ * @section gpt_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ stop [label="GPT_STOP\nLow Power"];
+ uninit [label="GPT_UNINIT", style="bold"];
+ ready [label="GPT_READY\nClock Enabled"];
+ continuous [label="GPT_CONT..S\nContinuous\nMode"];
+ oneshot [label="GPT_ONESHOT\nOne Shot\nMode"];
+
+ uninit -> stop [label=" gptInit()", constraint=false];
+ stop -> stop [label="\ngptStop()"];
+ stop -> ready [label="\ngptStart()"];
+ ready -> stop [label="\ngptStop()"];
+ ready -> ready [label="\ngptStart()"];
+ ready -> continuous [label="\ngptStartContinuous()"];
+ continuous -> ready [label="\ngptStopTimer()"];
+ continuous -> continuous [label=">callback<"];
+ ready -> oneshot [label="\ngptStartOneShot()\ngptPolledDelay()"];
+ oneshot -> ready [label="\n>callback<\nor\nDelay Over"];
+ }
+ * @enddot
+ *
+ * @section gpt_2 GPT Operations.
+ * This driver abstracts a generic timer composed of:
+ * - A clock prescaler.
+ * - A main up counter.
+ * - A comparator register that resets the main counter to zero when the limit
+ * is reached. A callback is invoked when this happens.
+ * .
+ * The timer can operate in three different modes:
+ * - <b>Continuous Mode</b>, a periodic callback is invoked until the driver
+ * is explicitly stopped.
+ * - <b>One Shot Mode</b>, a callback is invoked after the programmed period
+ * and then the timer automatically stops.
+ * - <b>Delay Mode</b>, the timer is used for inserting a brief delay into
+ * the execution flow, no callback is invoked in this mode.
+ * .
+ * @ingroup IO
+ */
diff --git a/os/hal/dox/hal.dox b/os/hal/dox/hal.dox
index 02d09c0d8..15b4401fb 100644
--- a/os/hal/dox/hal.dox
+++ b/os/hal/dox/hal.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,16 +20,17 @@
/**
* @defgroup HAL HAL Driver
- * @brief Hardware Abstraction Layer.
- * @details The HAL driver performs the system initialization and includes
- * the platform support code shared by the other drivers. This driver does
- * contain any API function except for a general initialization function
- * @p halInit() that must be invoked before any HAL service can be used,
- * usually the HAL initialization should be performed immediately before the
- * kernel initialization.<br>
- * Some HAL driver implementations also offer a custom early clock
- * setum function that can be invoked before the C runtime initialization
- * in order to accellerate the startup time.
+ * @brief Hardware Abstraction Layer.
+ * @details The HAL (Hardware Abstraction Layer) driver performs the system
+ * initialization and includes the platform support code shared by
+ * the other drivers. This driver does contain any API function
+ * except for a general initialization function @p halInit() that
+ * must be invoked before any HAL service can be used, usually the
+ * HAL initialization should be performed immediately before the
+ * kernel initialization.<br>
+ * Some HAL driver implementations also offer a custom early clock
+ * setup function that can be invoked before the C runtime
+ * initialization in order to accelerate the startup time.
*
* @ingroup IO
*/
diff --git a/os/hal/dox/i2c.dox b/os/hal/dox/i2c.dox
index 151c7a66e..1ffd2da47 100644
--- a/os/hal/dox/i2c.dox
+++ b/os/hal/dox/i2c.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,8 +20,9 @@
/**
* @defgroup I2C I2C Driver
- * @brief Generic I2C Driver.
- * @details This module implements a generic I2C driver.
+ * @brief Generic I2C Driver.
+ * @details This module implements a generic I2C (Inter-Integrated Circuit)
+ * driver.
* @pre In order to use the I2C driver the @p HAL_USE_I2C option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/icu.dox b/os/hal/dox/icu.dox
new file mode 100644
index 000000000..c90dc237d
--- /dev/null
+++ b/os/hal/dox/icu.dox
@@ -0,0 +1,115 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup ICU ICU Driver
+ * @brief Generic ICU Driver.
+ * @details This module implements a generic ICU (Input Capture Unit) driver.
+ * @pre In order to use the ICU driver the @p HAL_USE_ICU option
+ * must be enabled in @p halconf.h.
+ *
+ * @section icu_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @if LATEX_PDF
+ * @dot
+ digraph example {
+ size="5, 7";
+ rankdir="LR";
+
+ node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
+ edge [fontname=Sans, fontsize=8];
+
+ stop [label="ICU_STOP\nLow Power"];
+ uninit [label="ICU_UNINIT", style="bold"];
+ ready [label="ICU_READY\nClock Enabled"];
+ waiting [label="ICU_WAITING"];
+ active [label="ICU_ACTIVE"];
+ idle [label="ICU_IDLE"];
+
+ uninit -> stop [label=" icuInit()", constraint=false];
+ stop -> stop [label="\nicuStop()"];
+ stop -> ready [label="\nicuStart()"];
+ ready -> stop [label="\nicuStop()"];
+ ready -> ready [label="\nicuStart()\nicuDisable()"];
+ ready -> waiting [label="\nicuEnable()"];
+ waiting -> active [label="\nStart Front"];
+ waiting -> ready [label="\nicuDisable()"];
+ active -> idle [label="\nStop Front\n>width_cb<"];
+ active -> ready [label="\nicuDisable()\nicuDisableI()"];
+ idle -> active [label="\nStart Front\n>period_cb<"];
+ idle -> ready [label="\nicuDisable()\nicuDisableI()"];
+ }
+ * @enddot
+ * @else
+ * @dot
+ digraph example {
+ rankdir="LR";
+
+ node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
+ edge [fontname=Sans, fontsize=8];
+
+ stop [label="ICU_STOP\nLow Power"];
+ uninit [label="ICU_UNINIT", style="bold"];
+ ready [label="ICU_READY\nClock Enabled"];
+ waiting [label="ICU_WAITING"];
+ active [label="ICU_ACTIVE"];
+ idle [label="ICU_IDLE"];
+
+ uninit -> stop [label=" icuInit()", constraint=false];
+ stop -> stop [label="\nicuStop()"];
+ stop -> ready [label="\nicuStart()"];
+ ready -> stop [label="\nicuStop()"];
+ ready -> ready [label="\nicuStart()\nicuDisable()"];
+ ready -> waiting [label="\nicuEnable()"];
+ waiting -> active [label="\nStart Front"];
+ waiting -> ready [label="\nicuDisable()"];
+ active -> idle [label="\nStop Front\n>width_cb<"];
+ active -> ready [label="\nicuDisable()\nicuDisableI()"];
+ idle -> active [label="\nStart Front\n>period_cb<"];
+ idle -> ready [label="\nicuDisable()\nicuDisableI()"];
+ }
+ * @enddot
+ * @endif
+ *
+ * @section icu_2 ICU Operations.
+ * This driver abstracts a generic Input Capture Unit composed of:
+ * - A clock prescaler.
+ * - A main up counter.
+ * - Two capture registers triggered by the rising and falling edges on
+ * the sampled input.
+ * .
+ * The ICU unit can be programmed to synchronize on the rising or falling
+ * edge of the sample input:
+ * - <b>ICU_INPUT_ACTIVE_HIGH</b>, a rising edge is the start signal.
+ * - <b>ICU_INPUT_ACTIVE_LOW</b>, a falling edge is the start signal.
+ * .
+ * After the activation the ICU unit can be in one of the following
+ * states at any time:
+ * - <b>ICU_WAITING</b>, waiting the first start signal.
+ * - <b>ICU_ACTIVE</b>, after a start signal.
+ * - <b>ICU_IDLE</b>, after a stop signal.
+ * .
+ * Callbacks are invoked when start or stop signals occur.
+ *
+ * @ingroup IO
+ */
diff --git a/os/hal/dox/mac.dox b/os/hal/dox/mac.dox
index 778795f15..01a89d825 100644
--- a/os/hal/dox/mac.dox
+++ b/os/hal/dox/mac.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -20,8 +21,8 @@
/**
* @defgroup MAC MAC Driver
* @brief Generic MAC driver.
- * @details This module implements a generic interface for MAC (Media
- * Access Control) drivers, as example Ethernet controllers.
+ * @details This module implements a generic MAC (Media Access Control)
+ * driver for Ethernet controllers.
* @pre In order to use the MAC driver the @p HAL_USE_MAC option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/mmc_spi.dox b/os/hal/dox/mmc_spi.dox
index e18ff1a8a..480240c00 100644
--- a/os/hal/dox/mmc_spi.dox
+++ b/os/hal/dox/mmc_spi.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -20,7 +21,7 @@
/**
* @defgroup MMC_SPI MMC over SPI Driver
* @brief Generic MMC driver.
- * @details This module implements a portable MMC driver that uses a SPI
+ * @details This module implements a portable MMC/SD driver that uses a SPI
* driver as physical layer.
* @pre In order to use the MMC_SPI driver the @p HAL_USE_MMC_SPI option
* must be enabled in @p halconf.h.
diff --git a/os/hal/dox/pal.dox b/os/hal/dox/pal.dox
index 4c7fe685a..5ffc763a8 100644
--- a/os/hal/dox/pal.dox
+++ b/os/hal/dox/pal.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,19 +20,21 @@
/**
* @defgroup PAL PAL Driver
- * @brief I/O Ports Abstraction Layer
+ * @brief I/O Ports Abstraction Layer
* @details This module defines an abstract interface for digital I/O ports.
- * Note that most I/O ports functions are just macros. The macros
- * have default software implementations that can be redefined in a
- * PAL Low Level Driver if the target hardware supports special features like,
- * as example, atomic bit set/reset/masking. Please refer to the ports specific
- * documentation for details.<br>
- * The @ref PAL has the advantage to make the access to the I/O ports platform
- * independent and still be optimized for the specific architectures.<br>
- * Note that the PAL Low Level Driver may also offer non standard macro and
- * functions in order to support specific features but, of course, the use of
- * such interfaces would not be portable. Such interfaces shall be marked with
- * the architecture name inside the function names.
+ * Note that most I/O ports functions are just macros. The macros
+ * have default software implementations that can be redefined in a
+ * PAL Low Level Driver if the target hardware supports special
+ * features like, for example, atomic bit set/reset/masking. Please
+ * refer to the ports specific documentation for details.<br>
+ * The @ref PAL has the advantage to make the access to the I/O
+ * ports platform independent and still be optimized for the specific
+ * architectures.<br>
+ * Note that the PAL Low Level Driver may also offer non standard
+ * macro and functions in order to support specific features but,
+ * of course, the use of such interfaces would not be portable.
+ * Such interfaces shall be marked with the architecture name inside
+ * the function names.
* @pre In order to use the PAL driver the @p HAL_USE_PAL option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/pwm.dox b/os/hal/dox/pwm.dox
index 6fbe2efa1..fbf61ca9f 100644
--- a/os/hal/dox/pwm.dox
+++ b/os/hal/dox/pwm.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,8 +20,9 @@
/**
* @defgroup PWM PWM Driver
- * @brief Generic PWM Driver.
- * @details This module implements a generic PWM driver.
+ * @brief Generic PWM Driver.
+ * @details This module implements a generic PWM (Pulse Width Modulation)
+ * driver.
* @pre In order to use the PWM driver the @p HAL_USE_PWM option
* must be enabled in @p halconf.h.
*
@@ -45,8 +47,9 @@
}
* @enddot
*
- * @section pwm_1 PWM Operations.
- * This driver abstracts a generic PWM times composed of:
+ * @section pwm_2 PWM Operations.
+ * This driver abstracts a generic PWM timer composed of:
+ * - A clock prescaler.
* - A main up counter.
* - A comparator register that resets the main counter to zero when the limit
* is reached. An optional callback can be generated when this happens.
diff --git a/os/hal/dox/sdc.dox b/os/hal/dox/sdc.dox
new file mode 100644
index 000000000..df88796af
--- /dev/null
+++ b/os/hal/dox/sdc.dox
@@ -0,0 +1,109 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup SDC SDC Driver
+ * @brief Generic SD Card Driver.
+ * @details This module implements a generic SDC (Secure Digital Card) driver.
+ * @pre In order to use the SDC driver the @p HAL_USE_SDC option
+ * must be enabled in @p halconf.h.
+ *
+ * @section sdc_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @if LATEX_PDF
+ * @dot
+ digraph example {
+ size="5, 7";
+ rankdir="LR";
+
+ node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
+ edge [fontname=Sans, fontsize=8];
+
+ stop [label="SDC_STOP\nLow Power"];
+ uninit [label="SDC_UNINIT", style="bold"];
+ ready [label="SDC_READY\nClock Enabled"];
+ connecting [label="SDC_CONN.ING\nConnecting"];
+ disconnecting [label="SDC_DISC.ING\nDisconnecting"];
+ active [label="SDC_ACTIVE\nCard Ready"];
+ reading [label="SDC_READING\nReading"];
+ writing [label="SDC_WRITING\nWriting"];
+
+ uninit -> stop [label=" sdcInit()", constraint=false];
+ stop -> stop [label="\nsdcStop()"];
+ stop -> ready [label="\nsdcStart()"];
+ ready -> stop [label="\nsdcStop()"];
+ ready -> ready [label="\nsdcStart()\nsdcDisconnect()"];
+ ready -> connecting [label="\nsdcConnect()"];
+ connecting -> active [label="\nconnection\nsuccessful"];
+ connecting -> active [label="\nsdcConnect()", dir="back"];
+ connecting -> ready [label="\nconnection\nfailed"];
+ disconnecting -> active [label="\nsdcDisconnect()", dir="back"];
+ ready -> disconnecting [label="\ndisconnection\nfinished", dir="back"];
+ active -> reading [label="\nsdcRead()"];
+ reading -> active [label="\nread finished\nread error"];
+ active -> writing [label="\nsdcWrite()"];
+ writing -> active [label="\nwrite finished\nwrite error"];
+ }
+ * @enddot
+ * @else
+ * @dot
+ digraph example {
+ rankdir="LR";
+
+ node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
+ edge [fontname=Sans, fontsize=8];
+
+ stop [label="SDC_STOP\nLow Power"];
+ uninit [label="SDC_UNINIT", style="bold"];
+ ready [label="SDC_READY\nClock Enabled"];
+ connecting [label="SDC_CONN.ING\nConnecting"];
+ disconnecting [label="SDC_DISC.ING\nDisconnecting"];
+ active [label="SDC_ACTIVE\nCard Ready"];
+ reading [label="SDC_READING\nReading"];
+ writing [label="SDC_WRITING\nWriting"];
+
+ uninit -> stop [label=" sdcInit()", constraint=false];
+ stop -> stop [label="\nsdcStop()"];
+ stop -> ready [label="\nsdcStart()"];
+ ready -> stop [label="\nsdcStop()"];
+ ready -> ready [label="\nsdcStart()\nsdcDisconnect()"];
+ ready -> connecting [label="\nsdcConnect()"];
+ connecting -> active [label="\nconnection\nsuccessful"];
+ connecting -> active [label="\nsdcConnect()", dir="back"];
+ connecting -> ready [label="\nconnection\nfailed"];
+ disconnecting -> active [label="\nsdcDisconnect()", dir="back"];
+ ready -> disconnecting [label="\ndisconnection\nfinished", dir="back"];
+ active -> reading [label="\nsdcRead()"];
+ reading -> active [label="\nread finished\nread error"];
+ active -> writing [label="\nsdcWrite()"];
+ writing -> active [label="\nwrite finished\nwrite error"];
+ }
+ * @enddot
+ * @endif
+ *
+ * @section sdc_2 SDC Operations.
+ * This driver allows to read or write single or multiple 512 bytes blocks
+ * on a SD Card.
+ *
+ * @ingroup IO
+ */
diff --git a/os/hal/dox/serial.dox b/os/hal/dox/serial.dox
index 071b2dac5..5b68f9c9c 100644
--- a/os/hal/dox/serial.dox
+++ b/os/hal/dox/serial.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,16 +20,42 @@
/**
* @defgroup SERIAL Serial Driver
- * @brief Generic Serial Driver.
+ * @brief Generic Serial Driver.
* @details This module implements a generic full duplex serial driver. The
- * driver implements a @p SerialDriver interface and uses I/O Queues for
- * communication between the upper and the lower driver. Event flags are used
- * to notify the application about incoming data, outgoing data and other I/O
- * events.<br>
- * The module also contains functions that make the implementation of the
- * interrupt service routines much easier.
+ * driver implements a @p SerialDriver interface and uses I/O Queues
+ * for communication between the upper and the lower driver. Event
+ * flags are used to notify the application about incoming data,
+ * outgoing data and other I/O events.<br>
+ * The module also contains functions that make the implementation
+ * of the interrupt service routines much easier.
* @pre In order to use the SERIAL driver the @p HAL_USE_SERIAL option
* must be enabled in @p halconf.h.
*
+ *
+ * @section serial_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ uninit [label="SD_UNINIT", style="bold"];
+ stop [label="SD_STOP\nLow Power"];
+ ready [label="SD_READY\nClock Enabled"];
+
+ uninit -> stop [label=" sdInit()"];
+ stop -> stop [label="\nsdStop()"];
+ stop -> ready [label="\nsdStart()"];
+ ready -> stop [label="\nsdStop()"];
+ ready -> ready [label="\nsdStart()"];
+ ready -> ready [label="\nAny I/O operation"];
+ }
+ * @enddot
+ *
* @ingroup IO
*/
diff --git a/os/hal/dox/serial_usb.dox b/os/hal/dox/serial_usb.dox
new file mode 100644
index 000000000..c477b5288
--- /dev/null
+++ b/os/hal/dox/serial_usb.dox
@@ -0,0 +1,56 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup SERIAL_USB Serial over USB Driver
+ * @brief Serial over USB Driver.
+ * @details This module implements an USB Communication Device Class
+ * (CDC) as a normal serial communication port accessible from
+ * the device application.
+ * @pre In order to use the USB over Serial driver the
+ * @p HAL_USE_SERIAL_USB option must be enabled in @p halconf.h.
+ *
+ * @section usb_serial_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ uninit [label="SDU_UNINIT", style="bold"];
+ stop [label="SDU_STOP\nLow Power"];
+ ready [label="SDU_READY\nClock Enabled"];
+
+ uninit -> stop [label=" sduInit()"];
+ stop -> stop [label="\nsduStop()"];
+ stop -> ready [label="\nsduStart()"];
+ ready -> stop [label="\nsduStop()"];
+ ready -> ready [label="\nsduStart()"];
+ ready -> ready [label="\nAny I/O operation"];
+ }
+ * @enddot
+ *
+ * @ingroup IO
+ */
diff --git a/os/hal/dox/spi.dox b/os/hal/dox/spi.dox
index 7f68f3c40..047ff646e 100644
--- a/os/hal/dox/spi.dox
+++ b/os/hal/dox/spi.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,8 +20,10 @@
/**
* @defgroup SPI SPI Driver
- * @brief Generic SPI Driver.
- * @details This module implements a generic SPI driver.
+ * @brief Generic SPI Driver.
+ * @details This module implements a generic SPI (Serial Peripheral Interface)
+ * driver allowing bidirectional and monodirectional transfers,
+ * complex atomic transactions are supported as well.
* @pre In order to use the SPI driver the @p HAL_USE_SPI option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/uart.dox b/os/hal/dox/uart.dox
index 192ce4d91..7fea38dcb 100644
--- a/os/hal/dox/uart.dox
+++ b/os/hal/dox/uart.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,26 +20,27 @@
/**
* @defgroup UART UART Driver
- * @brief Generic UART Driver.
- * @details This driver abstracts a generic UART peripheral, the API is
- * designed to be:
- * - Unbuffered and copy-less, transfers are always directly performed
- * from/to the application-level buffers without extra copy operations.
- * - Asynchronous, the API is always non blocking.
- * - Callbacks capable, operations completion and other events are notified
- * via callbacks.
- * .
- * Special hardware features like deep hardware buffers, DMA transfers
- * are hidden to the user but fully supportable by the low level
- * implementations.<br>
- * This driver model is best used where communication events are meant to
- * drive an higher level state machine, as example:
- * - RS485 drivers.
- * - Multipoint network drivers.
- * - Serial protocol decoders.
- * .
- * If your application requires a synchronoyus buffered driver then the
- * @ref SERIAL should be used instead.
+ * @brief Generic UART Driver.
+ * @details This driver abstracts a generic UART (Universal Asynchronous
+ * Receiver Transmitter) peripheral, the API is designed to be:
+ * - Unbuffered and copy-less, transfers are always directly performed
+ * from/to the application-level buffers without extra copy
+ * operations.
+ * - Asynchronous, the API is always non blocking.
+ * - Callbacks capable, operations completion and other events are
+ * notified using callbacks.
+ * .
+ * Special hardware features like deep hardware buffers, DMA transfers
+ * are hidden to the user but fully supportable by the low level
+ * implementations.<br>
+ * This driver model is best used where communication events are
+ * meant to drive an higher level state machine, as example:
+ * - RS485 drivers.
+ * - Multipoint network drivers.
+ * - Serial protocol decoders.
+ * .
+ * If your application requires a synchronoyus buffered driver then
+ * the @ref SERIAL should be used instead.
* @pre In order to use the UART driver the @p HAL_USE_UART option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/usb.dox b/os/hal/dox/usb.dox
new file mode 100644
index 000000000..62b3aaf12
--- /dev/null
+++ b/os/hal/dox/usb.dox
@@ -0,0 +1,239 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup USB USB Driver
+ * @brief Generic USB Driver.
+ * @details This module implements a generic USB (Universal Serial Bus) driver
+ * supporting device-mode operations.
+ * @pre In order to use the USB driver the @p HAL_USE_USB option
+ * must be enabled in @p halconf.h.
+ *
+ * @section usb_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @if LATEX_PDF
+ * @dot
+ digraph example {
+ size="5, 7";
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ stop [label="USB_STOP\nLow Power"];
+ uninit [label="USB_UNINIT", style="bold"];
+ ready [label="USB_READY\nClock Enabled"];
+ selected [label="\nUSB_SELECTED\naddress\nassigned"];
+ configured [label="\nUSB_ACTIVE\nconfiguration\nselected"];
+
+ uninit -> stop [label=" usbInit()", constraint=false];
+ stop -> stop [label="\nusbStop()"];
+ stop -> ready [label="\nusbStart()"];
+ ready -> stop [label="\nusbStop()"];
+ ready -> ready [label="\n\nusbStart()"];
+ ready -> ready [label="\nSUSPEND/WAKEUP\n>event_cb<"];
+ ready -> selected [label="\nSET_ADDRESS\n>event_cb<"];
+ selected -> ready [label="\nUSB RESET\n>event_cb<"];
+ selected -> selected [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<"];
+ selected -> configured [label="\nSET_CONF(n)\n>event_cb<"];
+ configured -> selected [label="\nSET_CONF(0)\n>event_cb<"];
+ configured -> configured [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<\n\nEndpoints Activity\n >in_cb< or >out_cb<"];
+ configured -> ready [label="\nUSB RESET\n>event_cb<"];
+ }
+ * @enddot
+ * @else
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ stop [label="USB_STOP\nLow Power"];
+ uninit [label="USB_UNINIT", style="bold"];
+ ready [label="USB_READY\nClock Enabled"];
+ selected [label="\nUSB_SELECTED\naddress\nassigned"];
+ configured [label="\nUSB_ACTIVE\nconfiguration\nselected"];
+
+ uninit -> stop [label=" usbInit()", constraint=false];
+ stop -> stop [label="\nusbStop()"];
+ stop -> ready [label="\nusbStart()"];
+ ready -> stop [label="\nusbStop()"];
+ ready -> ready [label="\n\nusbStart()"];
+ ready -> ready [label="\nSUSPEND/WAKEUP\n>event_cb<"];
+ ready -> selected [label="\nSET_ADDRESS\n>event_cb<"];
+ selected -> ready [label="\nUSB RESET\n>event_cb<"];
+ selected -> selected [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<"];
+ selected -> configured [label="\nSET_CONF(n)\n>event_cb<"];
+ configured -> selected [label="\nSET_CONF(0)\n>event_cb<"];
+ configured -> configured [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<\n\nEndpoints Activity\n >in_cb< or >out_cb<"];
+ configured -> ready [label="\nUSB RESET\n>event_cb<"];
+ }
+ * @enddot
+ * @endif
+ *
+ * @section usb_2 USB Operations
+ * The USB driver is quite complex and USB is complex in itself, it is
+ * recommended to study the USB specification before trying to use the
+ * driver.
+ *
+ * @subsection usb_2_1 USB Implementation
+ * The USB driver abstracts the inner details of the underlying USB hardware.
+ * The driver works asynchronously and communicates with the application
+ * using callbacks. The application is responsible of the descriptors and
+ * strings required by the USB device class to be implemented and of the
+ * handling of the specific messages sent over the endpoint zero. Standard
+ * messages are handled internally to the driver. The application can use
+ * hooks in order to handle custom messages or override the handling of the
+ * default handling of standard messages.
+ *
+ * @subsection usb_2_2 USB Endpoints
+ * USB endpoints are the objects that the application uses to exchange
+ * data with the host. There are two kind of endpoints:
+ * - <b>IN</b> endpoints are used by the application to transmit data to
+ * the host.<br>
+ * - <b>OUT</b> endpoints are used by the application to receive data from
+ * the host.
+ * .
+ * In ChibiOS/RT the endpoints can be configured in two distinct ways:
+ * - <b>Packet Mode</b>. In this mode the driver invokes a callback each
+ * time a packet has been received or transmitted. This mode is especially
+ * suited for those applications handling continuous streams of data.
+ * <br><br>
+ * States diagram for OUT endpoints in packet mode:
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ disabled [label="EP_DISABLED\nDisabled", style="bold"];
+ receiving [label="EP_BUSY\nReceiving Packet"];
+ idle [label="EP_IDLE\nPacket in Buffer"];
+
+ disabled -> receiving [label="\usbInitEndpointI()"];
+ receiving -> idle [label="\npacket received\n>out_cb<"];
+ idle -> receiving [label="\nusbReadPacketI()"];
+ receiving -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ }
+ * @enddot
+ * <br><br>
+ * States diagram for IN endpoints in packet mode:
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ disabled [label="EP_DISABLED\nDisabled", style="bold"];
+ transmitting [label="EP_BUSY\nSending Packet"];
+ idle [label="EP_IDLE\nBuffer Empty"];
+
+ disabled -> idle [label="\usbInitEndpointI()"];
+ idle -> transmitting [label="\nusbWritePacketI()"];
+ transmitting -> idle [label="\npacket sent\n>in_cb<"];
+ transmitting -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ }
+ * @enddot
+ * <br><br>
+ * - <b>Transaction Mode</b>. In this mode the driver invokes a callback
+ * only after a large, potentially multi-packet, transfer has been
+ * completed, a callback is invoked only at the end of the transfer.
+ * <br><br>
+ * States diagram for OUT endpoints in transaction mode:
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ disabled [label="EP_DISABLED\nDisabled", style="bold"];
+ receiving [label="EP_BUSY\nReceiving"];
+ idle [label="EP_IDLE\nReady"];
+
+ disabled -> idle [label="\usbInitEndpointI()"];
+ idle -> receiving [label="\usbStartReceiveI()"];
+ receiving -> receiving [label="\nmore packets"];
+ receiving -> idle [label="\nreception end\n>out_cb<"];
+ receiving -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ }
+ * @enddot
+ * <br><br>
+ * States diagram for IN endpoints in transaction mode:
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ disabled [label="EP_DISABLED\nDisabled", style="bold"];
+ transmitting [label="EP_BUSY\nTransmitting"];
+ idle [label="EP_IDLE\nReady"];
+
+ disabled -> idle [label="\usbInitEndpointI()"];
+ idle -> transmitting [label="\nusbStartTransmitI()"];
+ transmitting -> transmitting [label="\nmore packets"];
+ transmitting -> idle [label="\ntransmission end\n>in_cb<"];
+ transmitting -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ }
+ * @enddot
+ * <br><br>
+ * .
+ * @subsection usb_2_3 USB Packet Buffers
+ * An important difference between packet and transaction modes is that there
+ * is a dedicated endpoint buffer in packet mode while in transaction mode
+ * the application has to specify its own buffer for duration of the whole
+ * transfer.<br>
+ * Packet buffers cannot be accessed directly by the application because those
+ * could not be necessarily memory mapped, a buffer could be a FIFO or some
+ * other kind of memory accessible in a special way depending on the
+ * underlying hardware architecture, the functions @p usbReadPacketI() and
+ * @p usbWritePacketI() allow to access packet buffers in an abstract way.
+ *
+ * @subsection usb_2_4 USB Callbacks
+ * The USB driver uses callbacks in order to interact with the application.
+ * There are several kinds of callbacks to be handled:
+ * - Driver events callback. As example errors, suspend event, reset event
+ * etc.
+ * - Messages Hook callback. This hook allows the application to implement
+ * handling of custom messages or to override the default handling of
+ * standard messages on endpoint zero.
+ * - Descriptor Requested callback. When the driver endpoint zero handler
+ * receives a GET DESCRIPTOR message and needs to send a descriptor to
+ * the host it queries the application using this callback.
+ * - Start of Frame callback. This callback is invoked each time a SOF
+ * packet is received.
+ * - Endpoint callbacks. Each endpoint informs the application about I/O
+ * conditions using those callbacks.
+ * .
+ *
+ * @ingroup IO
+ */
diff --git a/os/hal/hal.dox b/os/hal/hal.dox
index 65c320d31..6ed44eacc 100644
--- a/os/hal/hal.dox
+++ b/os/hal/hal.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -50,14 +51,17 @@
* @subsection hal_device_driver_diagram Diagram
* @dot
digraph example {
+ graph [size="5, 7", pad="1.5, 0"];
node [shape=rectangle, fontname=Helvetica, fontsize=8,
fixedsize="true", width="2.0", height="0.4"];
edge [fontname=Helvetica, fontsize=8];
+
app [label="Application"];
hld [label="High Level Driver"];
lld [label="Low Level Driver"];
hw [label="Microcontroller Hardware"];
hal_lld [label="HAL shared low level code"];
+
app->hld;
hld->lld;
lld-> hw;
diff --git a/os/hal/hal.mk b/os/hal/hal.mk
index 233ac66d1..762bda57f 100644
--- a/os/hal/hal.mk
+++ b/os/hal/hal.mk
@@ -3,10 +3,13 @@
HALSRC = ${CHIBIOS}/os/hal/src/hal.c \
${CHIBIOS}/os/hal/src/adc.c \
${CHIBIOS}/os/hal/src/can.c \
+ ${CHIBIOS}/os/hal/src/gpt.c \
${CHIBIOS}/os/hal/src/i2c.c \
+ ${CHIBIOS}/os/hal/src/icu.c \
${CHIBIOS}/os/hal/src/mac.c \
${CHIBIOS}/os/hal/src/pal.c \
${CHIBIOS}/os/hal/src/pwm.c \
+ ${CHIBIOS}/os/hal/src/sdc.c \
${CHIBIOS}/os/hal/src/serial.c \
${CHIBIOS}/os/hal/src/spi.c \
${CHIBIOS}/os/hal/src/uart.c \
diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h
index d94d99aa3..a236a040a 100644
--- a/os/hal/include/adc.h
+++ b/os/hal/include/adc.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -92,9 +93,9 @@ typedef enum {
* @notapi
*/
#define _adc_reset_i(adcp) { \
- if ((adcp)->ad_thread != NULL) { \
- Thread *tp = (adcp)->ad_thread; \
- (adcp)->ad_thread = NULL; \
+ if ((adcp)->thread != NULL) { \
+ Thread *tp = (adcp)->thread; \
+ (adcp)->thread = NULL; \
tp->p_u.rdymsg = RDY_RESET; \
chSchReadyI(tp); \
} \
@@ -108,9 +109,9 @@ typedef enum {
* @notapi
*/
#define _adc_reset_s(adcp) { \
- if ((adcp)->ad_thread != NULL) { \
- Thread *tp = (adcp)->ad_thread; \
- (adcp)->ad_thread = NULL; \
+ if ((adcp)->thread != NULL) { \
+ Thread *tp = (adcp)->thread; \
+ (adcp)->thread = NULL; \
chSchWakeupS(tp, RDY_RESET); \
} \
}
@@ -123,10 +124,11 @@ typedef enum {
* @notapi
*/
#define _adc_wakeup_isr(adcp) { \
- if ((adcp)->ad_thread != NULL) { \
- Thread *tp = (adcp)->ad_thread; \
- (adcp)->ad_thread = NULL; \
+ if ((adcp)->thread != NULL) { \
+ Thread *tp; \
chSysLockFromIsr(); \
+ tp = (adcp)->thread; \
+ (adcp)->thread = NULL; \
tp->p_u.rdymsg = RDY_OK; \
chSchReadyI(tp); \
chSysUnlockFromIsr(); \
@@ -152,9 +154,8 @@ typedef enum {
* @notapi
*/
#define _adc_isr_half_code(adcp) { \
- if ((adcp)->ad_grpp->acg_endcb != NULL) { \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
- (adcp)->ad_depth / 2); \
+ if ((adcp)->grpp->end_cb != NULL) { \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth / 2); \
} \
}
@@ -173,40 +174,40 @@ typedef enum {
* @notapi
*/
#define _adc_isr_full_code(adcp) { \
- if ((adcp)->ad_grpp->acg_circular) { \
+ if ((adcp)->grpp->circular) { \
/* Callback handling.*/ \
- if ((adcp)->ad_grpp->acg_endcb != NULL) { \
- if ((adcp)->ad_depth > 1) { \
+ if ((adcp)->grpp->end_cb != NULL) { \
+ if ((adcp)->depth > 1) { \
/* Invokes the callback passing the 2nd half of the buffer.*/ \
- size_t half = (adcp)->ad_depth / 2; \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples + half, half); \
+ size_t half = (adcp)->depth / 2; \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples + half, half); \
} \
else { \
/* Invokes the callback passing the whole buffer.*/ \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
- (adcp)->ad_depth); \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
} \
} \
} \
else { \
/* End conversion.*/ \
adc_lld_stop_conversion(adcp); \
- if ((adcp)->ad_grpp->acg_endcb != NULL) { \
- (adcp)->ad_state = ADC_COMPLETE; \
- if ((adcp)->ad_depth > 1) { \
+ if ((adcp)->grpp->end_cb != NULL) { \
+ (adcp)->state = ADC_COMPLETE; \
+ if ((adcp)->depth > 1) { \
/* Invokes the callback passing the 2nd half of the buffer.*/ \
- size_t half = (adcp)->ad_depth / 2; \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples + half, half); \
+ size_t half = (adcp)->depth / 2; \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples + half, half); \
} \
else { \
/* Invokes the callback passing the whole buffer.*/ \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
- (adcp)->ad_depth); \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
} \
- if ((adcp)->ad_state == ADC_COMPLETE) \
- (adcp)->ad_state = ADC_READY; \
+ if ((adcp)->state == ADC_COMPLETE) \
+ (adcp)->state = ADC_READY; \
} \
- (adcp)->ad_grpp = NULL; \
+ else \
+ (adcp)->state = ADC_READY; \
+ (adcp)->grpp = NULL; \
_adc_wakeup_isr(adcp); \
} \
}
diff --git a/os/hal/include/can.h b/os/hal/include/can.h
index dc258193a..538284b3b 100644
--- a/os/hal/include/can.h
+++ b/os/hal/include/can.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -103,7 +104,7 @@ typedef enum {
*
* @iclass
*/
-#define canAddFlagsI(canp, mask) ((canp)->cd_status |= (mask))
+#define canAddFlagsI(canp, mask) ((canp)->status |= (mask))
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/include/gpt.h b/os/hal/include/gpt.h
new file mode 100644
index 000000000..5bb385078
--- /dev/null
+++ b/os/hal/include/gpt.h
@@ -0,0 +1,105 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file gpt.h
+ * @brief GPT Driver macros and structures.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_H_
+#define _GPT_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ GPT_UNINIT = 0, /**< Not initialized. */
+ GPT_STOP = 1, /**< Stopped. */
+ GPT_READY = 2, /**< Ready. */
+ GPT_CONTINUOUS = 3, /**< Active in continuous mode. */
+ GPT_ONESHOT = 4 /**< Active in one shot mode. */
+} gptstate_t;
+
+/**
+ * @brief Type of a structure representing a GPT driver.
+ */
+typedef struct GPTDriver GPTDriver;
+
+/**
+ * @brief GPT notification callback type.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+typedef void (*gptcallback_t)(GPTDriver *gptp);
+
+#include "gpt_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gptInit(void);
+ void gptObjectInit(GPTDriver *gptp);
+ void gptStart(GPTDriver *gptp, const GPTConfig *config);
+ void gptStop(GPTDriver *gptp);
+ void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval);
+ void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval);
+ void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval);
+ void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval);
+ void gptStopTimer(GPTDriver *gptp);
+ void gptStopTimerI(GPTDriver *gptp);
+ void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_H_ */
+
+/** @} */
diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h
index 822dafc35..1ed893aab 100644
--- a/os/hal/include/hal.h
+++ b/os/hal/include/hal.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -36,10 +37,13 @@
#include "pal.h"
#include "adc.h"
#include "can.h"
+#include "gpt.h"
#include "i2c.h"
+#include "icu.h"
#include "mac.h"
#include "pwm.h"
#include "serial.h"
+#include "sdc.h"
#include "spi.h"
#include "uart.h"
#include "usb.h"
diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h
index 1c9238859..f5465985b 100644
--- a/os/hal/include/i2c.h
+++ b/os/hal/include/i2c.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/include/icu.h b/os/hal/include/icu.h
new file mode 100644
index 000000000..38fed2788
--- /dev/null
+++ b/os/hal/include/icu.h
@@ -0,0 +1,169 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file icu.h
+ * @brief ICU Driver macros and structures.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#ifndef _ICU_H_
+#define _ICU_H_
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ ICU_UNINIT = 0, /**< Not initialized. */
+ ICU_STOP = 1, /**< Stopped. */
+ ICU_READY = 2, /**< Ready. */
+ ICU_WAITING = 3, /**< Waiting first edge. */
+ ICU_ACTIVE = 4, /**< Active cycle phase. */
+ ICU_IDLE = 5, /**< Idle cycle phase. */
+} icustate_t;
+
+/**
+ * @brief Type of a structure representing an ICU driver.
+ */
+typedef struct ICUDriver ICUDriver;
+
+/**
+ * @brief ICU notification callback type.
+ *
+ * @param[in] icup pointer to a @p ICUDriver object
+ */
+typedef void (*icucallback_t)(ICUDriver *icup);
+
+#include "icu_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @iclass
+ */
+#define icuEnableI(icup) icu_lld_enable(icup)
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @iclass
+ */
+#define icuDisableI(icup) icu_lld_disable(icup)
+
+/**
+ * @brief Returns the width of the latest pulse.
+ * @details The pulse width is defined as number of ticks between the start
+ * edge and the stop edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @iclass
+ */
+#define icuGetWidthI(icup) icu_lld_get_width(icup)
+
+/**
+ * @brief Returns the width of the latest cycle.
+ * @details The cycle width is defined as number of ticks between a start
+ * edge and the next start edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @iclass
+ */
+#define icuGetPeriodI(icup) icu_lld_get_period(icup)
+
+/**
+ * @brief Common ISR code, ICU width event.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+#define _icu_isr_invoke_width_cb(icup) { \
+ (icup)->state = ICU_IDLE; \
+ (icup)->config->width_cb(icup); \
+}
+
+/**
+ * @brief Common ISR code, ICU period event.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+#define _icu_isr_invoke_period_cb(icup) { \
+ icustate_t previous_state = (icup)->state; \
+ (icup)->state = ICU_ACTIVE; \
+ if (previous_state != ICU_WAITING) \
+ (icup)->config->period_cb(icup); \
+}
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void icuInit(void);
+ void icuObjectInit(ICUDriver *icup);
+ void icuStart(ICUDriver *icup, const ICUConfig *config);
+ void icuStop(ICUDriver *icup);
+ void icuEnable(ICUDriver *icup);
+ void icuDisable(ICUDriver *icup);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ICU */
+
+#endif /* _ICU_H_ */
+
+/** @} */
diff --git a/os/hal/include/mac.h b/os/hal/include/mac.h
index 8978f007e..ad3c7b4dc 100644
--- a/os/hal/include/mac.h
+++ b/os/hal/include/mac.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -64,7 +65,7 @@
* @api
*/
#if CH_USE_EVENTS || defined(__DOXYGEN__)
-#define macGetReceiveEventSource(macp) (&(macp)->md_rdevent)
+#define macGetReceiveEventSource(macp) (&(macp)->rdevent)
#endif
/**
diff --git a/os/hal/include/mii.h b/os/hal/include/mii.h
index 87612273a..7199ee86d 100644
--- a/os/hal/include/mii.h
+++ b/os/hal/include/mii.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,7 +19,8 @@
*/
/*
- * Parts of this file are borrowed by the Linux include file linux/mii.h:
+ * Parts of this file have been borrowed from the Linux include file
+ * linux/mii.h:
* Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
*/
@@ -185,4 +187,4 @@
#endif /* _MII_H_ */
-/*-* @} */
+/** @} */
diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h
index 241fae54a..6940ca479 100644
--- a/os/hal/include/mmc_spi.h
+++ b/os/hal/include/mmc_spi.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,7 +19,7 @@
*/
/**
- * @file mmc_spi.h
+ * @file spi.h
* @brief MMC over SPI driver header.
*
* @addtogroup MMC_SPI
@@ -133,47 +134,47 @@ typedef struct {
/**
* @brief Driver state.
*/
- mmcstate_t mmc_state;
+ mmcstate_t state;
/**
* @brief Current configuration data.
*/
- const MMCConfig *mmc_config;
+ const MMCConfig *config;
/**
* @brief SPI driver associated to this MMC driver.
*/
- SPIDriver *mmc_spip;
+ SPIDriver *spip;
/**
* @brief SPI low speed configuration used during initialization.
*/
- const SPIConfig *mmc_lscfg;
+ const SPIConfig *lscfg;
/**
* @brief SPI high speed configuration used during transfers.
*/
- const SPIConfig *mmc_hscfg;
+ const SPIConfig *hscfg;
/**
* @brief Write protect status query function.
*/
- mmcquery_t mmc_is_protected;
+ mmcquery_t is_protected;
/**
* @brief Insertion status query function.
*/
- mmcquery_t mmc_is_inserted;
+ mmcquery_t is_inserted;
/**
* @brief Card insertion event source.
*/
- EventSource mmc_inserted_event;
+ EventSource inserted_event;
/**
* @brief Card removal event source.
*/
- EventSource mmc_removed_event;
+ EventSource removed_event;
/**
* @brief MMC insertion polling timer.
*/
- VirtualTimer mmc_vt;
+ VirtualTimer vt;
/**
* @brief Insertion counter.
*/
- uint_fast8_t mmc_cnt;
+ uint_fast8_t cnt;
} MMCDriver;
/*===========================================================================*/
@@ -188,7 +189,7 @@ typedef struct {
*
* @api
*/
-#define mmcGetDriverState(mmcp) ((mmcp)->mmc_state)
+#define mmcGetDriverState(mmcp) ((mmcp)->state)
/**
* @brief Returns the write protect status.
@@ -200,7 +201,7 @@ typedef struct {
*
* @api
*/
-#define mmcIsWriteProtected(mmcp) ((mmcp)->mmc_is_protected())
+#define mmcIsWriteProtected(mmcp) ((mmcp)->is_protected())
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/include/pal.h b/os/hal/include/pal.h
index 6f3c4a7e5..e9d0e31d8 100644
--- a/os/hal/include/pal.h
+++ b/os/hal/include/pal.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -123,17 +124,17 @@ typedef struct {
/**
* @brief Port identifier.
*/
- ioportid_t bus_portid;
+ ioportid_t portid;
/**
* @brief Bus mask aligned to port bit 0.
* @note The bus mask implicitly define the bus width. A logical AND is
* performed on the bus data.
*/
- ioportmask_t bus_mask;
+ ioportmask_t mask;
/**
* @brief Offset, within the port, of the least significant bit of the bus.
*/
- uint_fast8_t bus_offset;
+ uint_fast8_t offset;
} IOBus;
/*===========================================================================*/
@@ -262,9 +263,8 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_setport) || defined(__DOXYGEN__)
-#define palSetPort(port, bits) { \
- palWritePort(port, palReadLatch(port) | (bits)); \
-}
+#define palSetPort(port, bits) \
+ palWritePort(port, palReadLatch(port) | (bits))
#else
#define palSetPort(port, bits) pal_lld_setport(port, bits)
#endif
@@ -285,9 +285,8 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_clearport) || defined(__DOXYGEN__)
-#define palClearPort(port, bits) { \
- palWritePort(port, palReadLatch(port) & ~(bits)); \
-}
+#define palClearPort(port, bits) \
+ palWritePort(port, palReadLatch(port) & ~(bits))
#else
#define palClearPort(port, bits) pal_lld_clearport(port, bits)
#endif
@@ -308,9 +307,8 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_toggleport) || defined(__DOXYGEN__)
-#define palTogglePort(port, bits) { \
- palWritePort(port, palReadLatch(port) ^ (bits)); \
-}
+#define palTogglePort(port, bits) \
+ palWritePort(port, palReadLatch(port) ^ (bits))
#else
#define palTogglePort(port, bits) pal_lld_toggleport(port, bits)
#endif
@@ -346,10 +344,9 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_writegroup) || defined(__DOXYGEN__)
-#define palWriteGroup(port, mask, offset, bits) { \
+#define palWriteGroup(port, mask, offset, bits) \
palWritePort(port, (palReadLatch(port) & ~((mask) << (offset))) | \
- (((bits) & (mask)) << (offset))); \
-}
+ (((bits) & (mask)) << (offset)))
#else
#define palWriteGroup(port, mask, offset, bits) \
pal_lld_writegroup(port, mask, offset, bits)
@@ -415,10 +412,9 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_writepad) || defined(__DOXYGEN__)
-#define palWritePad(port, pad, bit) { \
+#define palWritePad(port, pad, bit) \
palWritePort(port, (palReadLatch(port) & ~PAL_PORT_BIT(pad)) | \
- (((bit) & 1) << pad)); \
-}
+ (((bit) & 1) << pad))
#else
#define palWritePad(port, pad, bit) pal_lld_writepad(port, pad, bit)
#endif
diff --git a/os/hal/include/pwm.h b/os/hal/include/pwm.h
index 6570e9fdf..2ffd3599c 100644
--- a/os/hal/include/pwm.h
+++ b/os/hal/include/pwm.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -34,6 +35,26 @@
/* Driver constants. */
/*===========================================================================*/
+/**
+ * @brief Standard output modes mask.
+ */
+#define PWM_OUTPUT_MASK 0x0F
+
+/**
+ * @brief Output not driven, callback only.
+ */
+#define PWM_OUTPUT_DISABLED 0x00
+
+/**
+ * @brief Positive PWM logic, active is logic level one.
+ */
+#define PWM_OUTPUT_ACTIVE_HIGH 0x01
+
+/**
+ * @brief Inverse PWM logic, active is logic level zero.
+ */
+#define PWM_OUTPUT_ACTIVE_LOW 0x02
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -56,13 +77,16 @@ typedef enum {
} pwmstate_t;
/**
- * @brief PWM logic mode.
+ * @brief Type of a structure representing a PWM driver.
*/
-typedef enum {
- PWM_OUTPUT_DISABLED = 0, /**< Output not driven, callback only. */
- PWM_OUTPUT_ACTIVE_HIGH = 1, /**< Idle is logic level 0. */
- PWM_OUTPUT_ACTIVE_LOW = 2 /**< Idle is logic level 1. */
-} pwmmode_t;
+typedef struct PWMDriver PWMDriver;
+
+/**
+ * @brief PWM notification callback type.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ */
+typedef void (*pwmcallback_t)(PWMDriver *pwmp);
#include "pwm_lld.h"
@@ -71,12 +95,85 @@ typedef enum {
/*===========================================================================*/
/**
+ * @brief Converts from fraction to pulse width.
+ * @note Be careful with rounding errors, this is integer math not magic.
+ * You can specify tenths of thousandth but make sure you have the
+ * proper hardware resolution by carefully choosing the clock source
+ * and prescaler settings, see @p PWM_COMPUTE_PSC.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] denominator denominator of the fraction
+ * @param[in] numerator numerator of the fraction
+ * @return The pulse width to be passed to @p pwmEnableChannel().
+ *
+ * @api
+ */
+#define PWM_FRACTION_TO_WIDTH(pwmp, denominator, numerator) \
+ ((uint16_t)((((uint32_t)(pwmp)->period) * \
+ (uint32_t)(numerator)) / (uint32_t)(denominator)))
+
+/**
+ * @brief Converts from degrees to pulse width.
+ * @note Be careful with rounding errors, this is integer math not magic.
+ * You can specify hundredths of degrees but make sure you have the
+ * proper hardware resolution by carefully choosing the clock source
+ * and prescaler settings, see @p PWM_COMPUTE_PSC.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] degrees degrees as an integer between 0 and 36000
+ * @return The pulse width to be passed to @p pwmEnableChannel().
+ *
+ * @api
+ */
+#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \
+ PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees)
+
+/**
+ * @brief Converts from percentage to pulse width.
+ * @note Be careful with rounding errors, this is integer math not magic.
+ * You can specify tenths of thousandth but make sure you have the
+ * proper hardware resolution by carefully choosing the clock source
+ * and prescaler settings, see @p PWM_COMPUTE_PSC.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] percentage percentage as an integer between 0 and 10000
+ * @return The pulse width to be passed to @p pwmEnableChannel().
+ *
+ * @api
+ */
+#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
+ PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
+
+/**
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] period new cycle time in ticks
+ *
+ * @iclass
+ */
+#define pwmChangePeriodI(pwmp, period) { \
+ (pwmp)->period = (period); \
+ pwm_lld_change_period(pwmp, period); \
+}
+
+/**
* @brief Enables a PWM channel.
- * @details Programs (or reprograms) a PWM channel.
- * @note This function has to be invoked from a lock zone.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
* @param[in] width PWM pulse width as clock pulses number
*
* @iclass
@@ -85,13 +182,16 @@ typedef enum {
pwm_lld_enable_channel(pwmp, channel, width)
/**
- * @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @brief Disables a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
- * @note This function has to be invoked from a lock zone.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
*
* @iclass
*/
@@ -109,6 +209,7 @@ extern "C" {
void pwmObjectInit(PWMDriver *pwmp);
void pwmStart(PWMDriver *pwmp, const PWMConfig *config);
void pwmStop(PWMDriver *pwmp);
+ void pwmChangePeriod(PWMDriver *pwmp, pwmcnt_t period);
void pwmEnableChannel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width);
diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h
new file mode 100644
index 000000000..afc3a6aba
--- /dev/null
+++ b/os/hal/include/sdc.h
@@ -0,0 +1,234 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file sdc.h
+ * @brief SDC Driver macros and structures.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#ifndef _SDC_H_
+#define _SDC_H_
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define SDC_BLOCK_SIZE 512 /**< Fixed block size. */
+
+/**
+ * @brief Fixed pattern for CMD8.
+ */
+#define SDC_CMD8_PATTERN 0x000001AA
+
+#define SDC_MODE_CARDTYPE_MASK 0xF /**< @brief Card type mask. */
+#define SDC_MODE_CARDTYPE_SDV11 0 /**< @brief Card is SD V1.1.*/
+#define SDC_MODE_CARDTYPE_SDV20 1 /**< @brief Card is SD V2.0.*/
+#define SDC_MODE_CARDTYPE_MMC 2 /**< @brief Card is MMC. */
+#define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */
+
+/**
+ * @brief Mask of error bits in R1 responses.
+ */
+#define SDC_R1_ERROR_MASK 0xFDFFE008
+
+#define SDC_STS_IDLE 0
+#define SDC_STS_READY 1
+#define SDC_STS_IDENT 2
+#define SDC_STS_STBY 3
+#define SDC_STS_TRAN 4
+#define SDC_STS_DATA 5
+#define SDC_STS_RCV 6
+#define SDC_STS_PRG 7
+#define SDC_STS_DIS 8
+
+#define SDC_CMD_GO_IDLE_STATE 0
+#define SDC_CMD_INIT 1
+#define SDC_CMD_ALL_SEND_CID 2
+#define SDC_CMD_SEND_RELATIVE_ADDR 3
+#define SDC_CMD_SET_BUS_WIDTH 6
+#define SDC_CMD_SEL_DESEL_CARD 7
+#define SDC_CMD_SEND_IF_COND 8
+#define SDC_CMD_SEND_CSD 9
+#define SDC_CMD_STOP_TRANSMISSION 12
+#define SDC_CMD_SEND_STATUS 13
+#define SDC_CMD_SET_BLOCKLEN 16
+#define SDC_CMD_READ_SINGLE_BLOCK 17
+#define SDC_CMD_READ_MULTIPLE_BLOCK 18
+#define SDC_CMD_SET_BLOCK_COUNT 23
+#define SDC_CMD_WRITE_BLOCK 24
+#define SDC_CMD_WRITE_MULTIPLE_BLOCK 25
+#define SDC_CMD_APP_OP_COND 41
+#define SDC_CMD_LOCK_UNLOCK 42
+#define SDC_CMD_APP_CMD 55
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intevals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ SDC_UNINIT = 0, /**< Not initialized. */
+ SDC_STOP = 1, /**< Stopped. */
+ SDC_READY = 2, /**< Ready. */
+ SDC_CONNECTING = 3, /**< Card connection in progress. */
+ SDC_DISCONNECTING = 4, /**< Card disconnection in progress. */
+ SDC_ACTIVE = 5, /**< Cart initialized. */
+ SDC_READING = 6, /**< Read operation in progress. */
+ SDC_WRITING = 7, /**< Write operation in progress. */
+} sdcstate_t;
+
+#include "sdc_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Evaluates to @p TRUE if the R1 response contains error flags.
+ *
+ * @param[in] r1 the r1 response
+ */
+#define SDC_R1_ERROR(r1) (((r1) & SDC_R1_ERROR_MASK) != 0)
+
+/**
+ * @brief Returns the status field of an R1 response.
+ *
+ * @param[in] r1 the r1 response
+ */
+#define SDC_R1_STS(r1) (((r1) >> 9) & 15)
+
+/**
+ * @brief Evaluates to @p TRUE if the R1 response indicates a locked card.
+ *
+ * @param[in] r1 the r1 response
+ */
+#define SDC_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1)
+
+/**
+ * @brief Returns the driver state.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The driver state.
+ *
+ * @api
+ */
+#define sdcGetDriverState(sdcp) ((sdcp)->state)
+
+/**
+ * @brief Returns the card insertion status.
+ * @note This macro wraps a low level function named
+ * @p sdc_lld_is_card_inserted(), this function must be
+ * provided by the application because it is not part of the
+ * SDC driver.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The card state.
+ * @retval FALSE card not inserted.
+ * @retval TRUE card inserted.
+ *
+ * @api
+ */
+#define sdcIsCardInserted(sdcp) (sdc_lld_is_card_inserted(sdcp))
+
+/**
+ * @brief Returns the write protect status.
+ * @note This macro wraps a low level function named
+ * @p sdc_lld_is_write_protected(), this function must be
+ * provided by the application because it is not part of the
+ * SDC driver.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The card state.
+ * @retval FALSE card not inserted.
+ * @retval TRUE card inserted.
+ *
+ * @api
+ */
+#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdcInit(void);
+ void sdcObjectInit(SDCDriver *sdcp);
+ void sdcStart(SDCDriver *sdcp, const SDCConfig *config);
+ void sdcStop(SDCDriver *sdcp);
+ bool_t sdcConnect(SDCDriver *sdcp);
+ bool_t sdcDisconnect(SDCDriver *sdcp);
+ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buffer, uint32_t n);
+ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buffer, uint32_t n);
+ bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SDC */
+
+#endif /* _SDC_H_ */
+
+/** @} */
diff --git a/os/hal/include/serial.h b/os/hal/include/serial.h
index 57240e78b..a8c3c1aca 100644
--- a/os/hal/include/serial.h
+++ b/os/hal/include/serial.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/include/serial_usb.h b/os/hal/include/serial_usb.h
index b75f6fe59..8e518238d 100644
--- a/os/hal/include/serial_usb.h
+++ b/os/hal/include/serial_usb.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -53,8 +54,9 @@
/* Derived constants and error checks. */
/*===========================================================================*/
-#if !HAL_USE_USB && !CH_USE_EVENTS
-#error "Serial over USB Driver requires HAL_USE_USB and CH_USE_EVENTS"
+#if !HAL_USE_USB && !CH_USE_QUEUES && !CH_USE_EVENTS
+#error "Serial over USB Driver requires HAL_USE_USB, CH_USE_QUEUES, "
+ "CH_USE_EVENTS"
#endif
/*===========================================================================*/
@@ -84,23 +86,11 @@ typedef struct {
/**
* @brief USB driver to use.
*/
- USBDriver *usbp;
+ USBDriver *usbp;
/**
* @brief USB driver configuration structure.
*/
- USBConfig usb_config;
- /*
- * @brief Endpoint used for data transmission.
- */
- usbep_t data_request_ep;
- /*
- * @brief Endpoint used for data reception.
- */
- usbep_t data_available_ep;
- /*
- * @brief Endpoint used for interrupt request.
- */
- usbep_t interrupt_request_ep;
+ USBConfig usb_config;
} SerialUSBConfig;
/**
@@ -114,9 +104,9 @@ typedef struct {
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
- /* Input circular buffer.*/ \
+ /* Input buffer.*/ \
uint8_t ib[SERIAL_USB_BUFFERS_SIZE]; \
- /* Output circular buffer.*/ \
+ /* Output buffer.*/ \
uint8_t ob[SERIAL_USB_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Current configuration data.*/ \
@@ -164,9 +154,9 @@ extern "C" {
void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config);
void sduStop(SerialUSBDriver *sdup);
bool_t sduRequestsHook(USBDriver *usbp);
- void sduDataRequest(USBDriver *usbp, usbep_t ep);
- void sduDataAvailable(USBDriver *usbp, usbep_t ep);
- void sduInterruptRequest(USBDriver *usbp, usbep_t ep);
+ void sduDataTransmitted(USBDriver *usbp, usbep_t ep);
+ void sduDataReceived(USBDriver *usbp, usbep_t ep);
+ void sduInterruptTransmitted(USBDriver *usbp, usbep_t ep);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/include/spi.h b/os/hal/include/spi.h
index ccf3e4e63..104dd9d3e 100644
--- a/os/hal/include/spi.h
+++ b/os/hal/include/spi.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -120,7 +121,7 @@ typedef enum {
* @iclass
*/
#define spiStartIgnoreI(spip, n) { \
- (spip)->spd_state = SPI_ACTIVE; \
+ (spip)->state = SPI_ACTIVE; \
spi_lld_ignore(spip, n); \
}
@@ -142,7 +143,7 @@ typedef enum {
* @iclass
*/
#define spiStartExchangeI(spip, n, txbuf, rxbuf) { \
- (spip)->spd_state = SPI_ACTIVE; \
+ (spip)->state = SPI_ACTIVE; \
spi_lld_exchange(spip, n, txbuf, rxbuf); \
}
@@ -162,7 +163,7 @@ typedef enum {
* @iclass
*/
#define spiStartSendI(spip, n, txbuf) { \
- (spip)->spd_state = SPI_ACTIVE; \
+ (spip)->state = SPI_ACTIVE; \
spi_lld_send(spip, n, txbuf); \
}
@@ -182,7 +183,7 @@ typedef enum {
* @iclass
*/
#define spiStartReceiveI(spip, n, rxbuf) { \
- (spip)->spd_state = SPI_ACTIVE; \
+ (spip)->state = SPI_ACTIVE; \
spi_lld_receive(spip, n, rxbuf); \
}
@@ -215,9 +216,9 @@ typedef enum {
* @notapi
*/
#define _spi_wait_s(spip) { \
- chDbgAssert((spip)->spd_thread == NULL, \
+ chDbgAssert((spip)->thread == NULL, \
"_spi_wait(), #1", "already waiting"); \
- (spip)->spd_thread = chThdSelf(); \
+ (spip)->thread = chThdSelf(); \
chSchGoSleepS(THD_STATE_SUSPENDED); \
}
@@ -229,9 +230,9 @@ typedef enum {
* @notapi
*/
#define _spi_wakeup_isr(spip) { \
- if ((spip)->spd_thread != NULL) { \
- Thread *tp = (spip)->spd_thread; \
- (spip)->spd_thread = NULL; \
+ if ((spip)->thread != NULL) { \
+ Thread *tp = (spip)->thread; \
+ (spip)->thread = NULL; \
chSysLockFromIsr(); \
chSchReadyI(tp); \
chSysUnlockFromIsr(); \
@@ -257,12 +258,14 @@ typedef enum {
* @notapi
*/
#define _spi_isr_code(spip) { \
- if ((spip)->spd_config->spc_endcb) { \
- (spip)->spd_state = SPI_COMPLETE; \
- (spip)->spd_config->spc_endcb(spip); \
- if ((spip)->spd_state == SPI_COMPLETE) \
- (spip)->spd_state = SPI_READY; \
+ if ((spip)->config->end_cb) { \
+ (spip)->state = SPI_COMPLETE; \
+ (spip)->config->end_cb(spip); \
+ if ((spip)->state == SPI_COMPLETE) \
+ (spip)->state = SPI_READY; \
} \
+ else \
+ (spip)->state = SPI_READY; \
_spi_wakeup_isr(spip); \
}
diff --git a/os/hal/include/uart.h b/os/hal/include/uart.h
index 2ea69309f..148aa6877 100644
--- a/os/hal/include/uart.h
+++ b/os/hal/include/uart.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h
index 9f0d95837..c4cf68fe2 100644
--- a/os/hal/include/usb.h
+++ b/os/hal/include/usb.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -73,6 +74,112 @@
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1
#define USB_FEATURE_TEST_MODE 2
+#define USB_EARLY_SET_ADDRESS 0
+#define USB_LATE_SET_ADDRESS 1
+
+/**
+ * @brief Helper macro for index values into descriptor strings.
+ */
+#define USB_DESC_INDEX(i) ((uint8_t)(i))
+
+/**
+ * @brief Helper macro for byte values into descriptor strings.
+ */
+#define USB_DESC_BYTE(b) ((uint8_t)(b))
+
+/**
+ * @brief Helper macro for word values into descriptor strings.
+ */
+#define USB_DESC_WORD(w) \
+ (uint8_t)((w) & 255), \
+ (uint8_t)(((w) >> 8) & 255)
+
+/**
+ * @brief Helper macro for BCD values into descriptor strings.
+ */
+#define USB_DESC_BCD(bcd) \
+ (uint8_t)((bcd) & 255), \
+ (uint8_t)(((bcd) >> 8) & 255)
+
+/**
+ * @brief Device Descriptor helper macro.
+ */
+#define USB_DESC_DEVICE(bcdUSB, bDeviceClass, bDeviceSubClass, \
+ bDeviceProtocol, bMaxPacketSize, idVendor, \
+ idProduct, bcdDevice, iManufacturer, \
+ iProduct, iSerialNumber, bNumConfigurations) \
+ USB_DESC_BYTE(18), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_DEVICE), \
+ USB_DESC_BCD(bcdUSB), \
+ USB_DESC_BYTE(bDeviceClass), \
+ USB_DESC_BYTE(bDeviceSubClass), \
+ USB_DESC_BYTE(bDeviceProtocol), \
+ USB_DESC_BYTE(bMaxPacketSize), \
+ USB_DESC_WORD(idVendor), \
+ USB_DESC_WORD(idProduct), \
+ USB_DESC_BCD(bcdDevice), \
+ USB_DESC_INDEX(iManufacturer), \
+ USB_DESC_INDEX(iProduct), \
+ USB_DESC_INDEX(iSerialNumber), \
+ USB_DESC_BYTE(bNumConfigurations)
+
+/**
+ * @brief Configuration Descriptor helper macro.
+ */
+#define USB_DESC_CONFIGURATION(wTotalLength, bNumInterfaces, \
+ bConfigurationValue, iConfiguration, \
+ bmAttributes, bMaxPower) \
+ USB_DESC_BYTE(9), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_CONFIGURATION), \
+ USB_DESC_WORD(wTotalLength), \
+ USB_DESC_BYTE(bNumInterfaces), \
+ USB_DESC_BYTE(bConfigurationValue), \
+ USB_DESC_INDEX(iConfiguration), \
+ USB_DESC_BYTE(bmAttributes), \
+ USB_DESC_BYTE(bMaxPower)
+
+/**
+ * @brief Interface Descriptor helper macro.
+ */
+#define USB_DESC_INTERFACE(bInterfaceNumber, bAlternateSetting, \
+ bNumEndpoints, bInterfaceClass, \
+ bInterfaceSubClass, bInterfaceProtocol, \
+ iInterface) \
+ USB_DESC_BYTE(9), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_INTERFACE), \
+ USB_DESC_BYTE(bInterfaceNumber), \
+ USB_DESC_BYTE(bAlternateSetting), \
+ USB_DESC_BYTE(bNumEndpoints), \
+ USB_DESC_BYTE(bInterfaceClass), \
+ USB_DESC_BYTE(bInterfaceSubClass), \
+ USB_DESC_BYTE(bInterfaceProtocol), \
+ USB_DESC_INDEX(iInterface)
+
+/**
+ * @brief Endpoint Descriptor helper macro.
+ */
+#define USB_DESC_ENDPOINT(bEndpointAddress, bmAttributes, wMaxPacketSize, \
+ bInterval) \
+ USB_DESC_BYTE(7), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_ENDPOINT), \
+ USB_DESC_BYTE(bEndpointAddress), \
+ USB_DESC_BYTE(bmAttributes), \
+ USB_DESC_WORD(wMaxPacketSize), \
+ USB_DESC_BYTE(bInterval)
+
+/**
+ * @brief Returned by some functions to report a busy endpoint.
+ */
+#define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF)
+
+#define USB_EP_MODE_TYPE 0x0003 /**< Endpoint type mask. */
+#define USB_EP_MODE_TYPE_CTRL 0x0000 /**< Control endpoint. */
+#define USB_EP_MODE_TYPE_ISOC 0x0001 /**< Isochronous endpoint. */
+#define USB_EP_MODE_TYPE_BULK 0x0002 /**< Bulk endpoint. */
+#define USB_EP_MODE_TYPE_INTR 0x0003 /**< Interrupt endpoint. */
+#define USB_EP_MODE_TRANSACTION 0x0000 /**< Transaction mode. */
+#define USB_EP_MODE_PACKET 0x0010 /**< Packet mode enabled. */
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -107,20 +214,10 @@ typedef enum {
} usbstate_t;
/**
- * @brief Type of an endpoint type.
- */
-typedef enum {
- EP_TYPE_CTRL = 0, /**< Control endpoint. */
- EP_TYPE_ISOC = 1, /**< Isochronous endpoint. */
- EP_TYPE_BULK = 2, /**< Bulk endpoint. */
- EP_TYPE_INTR = 3 /**< Interrupt endpoint. */
-} usbeptype_t;
-
-/**
* @brief Type of an endpoint status.
*/
typedef enum {
- EP_STATUS_DISABLED = 0, /**< Endpoint not opened. */
+ EP_STATUS_DISABLED = 0, /**< Endpoint not active. */
EP_STATUS_STALLED = 1, /**< Endpoint opened but stalled. */
EP_STATUS_ACTIVE = 2 /**< Active endpoint. */
} usbepstatus_t;
@@ -133,7 +230,8 @@ typedef enum {
USB_EP0_TX, /**< Trasmitting. */
USB_EP0_WAITING_STS, /**< Waiting status. */
USB_EP0_RX, /**< Receiving. */
- USB_EP0_SENDING_STS /**< Sending status. */
+ USB_EP0_SENDING_STS, /**< Sending status. */
+ USB_EP0_ERROR /**< Error, EP0 stalled. */
} usbep0state_t;
/**
@@ -144,7 +242,7 @@ typedef enum {
USB_EVENT_ADDRESS = 1, /**< Address assigned. */
USB_EVENT_CONFIGURED = 2, /**< Configuration selected. */
USB_EVENT_SUSPEND = 3, /**< Entering suspend mode. */
- USB_EVENT_RESUME = 4, /**< Leaving suspend mode. */
+ USB_EVENT_WAKEUP = 4, /**< Leaving suspend mode. */
USB_EVENT_STALLED = 5, /**< Endpoint 0 error, stalled. */
} usbevent_t;
@@ -219,70 +317,66 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] usbp pointer to the @p USBDriver object
* @return The current frame number.
*
- * @notapi
+ * @api
*/
#define usbGetFrameNumber(usbp) usb_lld_get_frame_number(usbp)
/**
- * @brief Returns the number of bytes readable from the receive packet
- * buffer.
+ * @brief Returns the status of an IN endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @return The number of bytes that are effectively available.
- * @retval 0 Data not yet available.
+ * @return The operation status.
+ * @retval FALSE Endpoint ready.
+ * @retval TRUE Endpoint transmitting.
*
* @iclass
*/
-#define usbGetReadableI(usbp, ep) usb_lld_get_readable(usbp, ep)
+#define usbGetTransmitStatusI(usbp, ep) ((usbp)->transmitting & (1 << (ep)))
/**
- * @brief Endpoint read.
- * @details The buffered packet is copied into the user buffer and then
- * the endpoint is brought to the valid state in order to allow
- * reception of more data.
+ * @brief Returns the status of an OUT endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[out] buf buffer where to copy the endpoint data
- * @param[in] n maximum number of bytes to copy
- * @return The number of bytes that were effectively available.
- * @retval 0 Data not yet available.
+ * @return The operation status.
+ * @retval FALSE Endpoint ready.
+ * @retval TRUE Endpoint receiving.
*
* @iclass
*/
-#define usbReadI(usbp, ep, buf, n) usb_lld_read(usbp, ep, buf, n)
+#define usbGetReceiveStatusI(usbp, ep) ((usbp)->receiving & (1 << (ep)))
/**
- * @brief Returns the number of bytes writeable to the transmit packet
- * buffer.
+ * @brief Returns the exact size of a receive transaction.
+ * @details The received size can be different from the size specified in
+ * @p usbStartReceiveI() because the last packet could have a size
+ * different from the expected one.
+ * @pre The OUT endpoint must have been configured in transaction mode
+ * in order to use this function.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @return The number of bytes that can be written.
- * @retval 0 Endpoint not ready for transmission.
+ * @return Received data size.
*
* @iclass
*/
-#define usbGetWriteableI(usbp, ep) usb_lld_get_readable(usbp, ep)
+#define usbGetReceiveTransactionSizeI(usbp, ep) \
+ usb_lld_get_transaction_size(usbp, ep)
/**
- * @brief Endpoint write.
- * @details The user data is copied in the packer memory and then
- * the endpoint is brought to the valid state in order to allow
- * transmission.
+ * @brief Returns the exact size of a received packet.
+ * @pre The OUT endpoint must have been configured in packet mode
+ * in order to use this function.
*
- * @param[in] usbp pointer to the @p USBDriver object triggering the
- * callback
+ * @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[in] buf buffer where to copy the endpoint data
- * @param[in] n maximum number of bytes to copy
- * @return The number of bytes that were effectively written.
- * @retval 0 Endpoint not ready for transmission.
+ * @return Received data size.
*
* @iclass
*/
-#define usbWriteI(usbp, ep, buf, n) usb_lld_write(usbp, ep, buf, n)
+#define usbGetReceivePacketSizeI(usbp, ep) \
+ usb_lld_get_packet_size(usbp, ep)
/**
* @brief Request transfer setup.
@@ -292,14 +386,93 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] buf pointer to a buffer for the transaction data
* @param[in] n number of bytes to be transferred
- * @param[in] endcb transfer complete callback
+ * @param[in] endcb callback to be invoked after the transfer or @p NULL
*
* @api
*/
#define usbSetupTransfer(usbp, buf, n, endcb) { \
- (usbp)->usb_ep0next = (buf); \
- (usbp)->usb_ep0n = (n); \
- (usbp)->usb_ep0endcb = (endcb); \
+ (usbp)->ep0next = (buf); \
+ (usbp)->ep0n = (n); \
+ (usbp)->ep0endcb = (endcb); \
+}
+
+/**
+ * @brief Reads a setup packet from the dedicated packet buffer.
+ * @details This function must be invoked in the context of the @p setup_cb
+ * callback in order to read the received setup packet.
+ * @pre In order to use this function the endpoint must have been
+ * initialized as a control endpoint.
+ * @post The endpoint is ready to accept another packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ *
+ * @special
+ */
+#define usbReadSetup(usbp, ep, buf) usb_lld_read_setup(usbp, ep, buf)
+
+/**
+ * @brief Common ISR code, usb event callback.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] evt USB event code
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_event_cb(usbp, evt) { \
+ if (((usbp)->config->event_cb) != NULL) \
+ (usbp)->config->event_cb(usbp, evt); \
+}
+
+/**
+ * @brief Common ISR code, SOF callback.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_sof_cb(usbp) { \
+ if (((usbp)->config->sof_cb) != NULL) \
+ (usbp)->config->sof_cb(usbp); \
+}
+
+/**
+ * @brief Common ISR code, setup packet callback.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_setup_cb(usbp, ep) { \
+ (usbp)->epc[ep]->setup_cb(usbp, ep); \
+}
+
+/**
+ * @brief Common ISR code, IN endpoint callback.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_in_cb(usbp, ep) { \
+ (usbp)->transmitting &= ~(1 << (ep)); \
+ (usbp)->epc[ep]->in_cb(usbp, ep); \
+}
+
+/**
+ * @brief Common ISR code, OUT endpoint event.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_out_cb(usbp, ep) { \
+ (usbp)->receiving &= ~(1 << (ep)); \
+ (usbp)->epc[ep]->out_cb(usbp, ep); \
}
/*===========================================================================*/
@@ -313,9 +486,22 @@ extern "C" {
void usbObjectInit(USBDriver *usbp);
void usbStart(USBDriver *usbp, const USBConfig *config);
void usbStop(USBDriver *usbp);
- void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
+ void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
const USBEndpointConfig *epcp);
+ void usbDisableEndpointsI(USBDriver *usbp);
+ void usbReadSetupI(USBDriver *usbp, usbep_t ep, uint8_t *buf);
+ size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep);
+ bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep);
void _usb_reset(USBDriver *usbp);
+ void _usb_ep0setup(USBDriver *usbp, usbep_t ep);
void _usb_ep0in(USBDriver *usbp, usbep_t ep);
void _usb_ep0out(USBDriver *usbp, usbep_t ep);
#ifdef __cplusplus
diff --git a/os/hal/include/usb_cdc.h b/os/hal/include/usb_cdc.h
index c1d3da3e7..a388f9f70 100644
--- a/os/hal/include/usb_cdc.h
+++ b/os/hal/include/usb_cdc.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -17,7 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/**
+/*-*
* @file usb_cdc.h
* @brief USB Communication Device Class support header.
*
@@ -28,6 +29,10 @@
#ifndef _USB_CDC_H_
#define _USB_CDC_H_
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
#define CDC_SET_COMM_FEATURE 0x02
@@ -48,6 +53,49 @@
#define CDC_SET_OPERATION_PARMS 0x32
#define CDC_GET_OPERATION_PARMS 0x33
+#define LC_STOP_1 0
+#define LC_STOP_1P5 1
+#define LC_STOP_2 2
+
+#define LC_PARITY_NONE 0
+#define LC_PARITY_ODD 1
+#define LC_PARITY_EVEN 2
+#define LC_PARITY_MARK 3
+#define LC_PARITY_SPACE 4
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Endpoint number for bulk IN.
+ */
+#if !defined(DATA_REQUEST_EP) || defined(__DOXYGEN__)
+#define DATA_REQUEST_EP 1
+#endif
+
+/**
+ * @brief Endpoint number for interrupt IN.
+ */
+#if !defined(INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__)
+#define INTERRUPT_REQUEST_EP 2
+#endif
+
+/**
+ * @brief Endpoint number for bulk OUT.
+ */
+#if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__)
+#define DATA_AVAILABLE_EP 3
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
/**
* @brief Type of Line Coding structure.
*/
@@ -58,15 +106,13 @@ typedef struct {
uint8_t bDataBits;
} cdc_linecoding_t;
-#define LC_STOP_1 0
-#define LC_STOP_1P5 1
-#define LC_STOP_2 2
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
-#define LC_PARITY_NONE 0
-#define LC_PARITY_ODD 1
-#define LC_PARITY_EVEN 2
-#define LC_PARITY_MARK 3
-#define LC_PARITY_SPACE 4
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
#endif /* _USB_CDC_H_ */
diff --git a/os/hal/platforms/AT91SAM7/at91sam7.h b/os/hal/platforms/AT91SAM7/at91sam7.h
index a34ab62d4..e62f6a5aa 100644
--- a/os/hal/platforms/AT91SAM7/at91sam7.h
+++ b/os/hal/platforms/AT91SAM7/at91sam7.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/at91sam7_mii.c b/os/hal/platforms/AT91SAM7/at91sam7_mii.c
index 54f1b8d57..707a373b9 100644
--- a/os/hal/platforms/AT91SAM7/at91sam7_mii.c
+++ b/os/hal/platforms/AT91SAM7/at91sam7_mii.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/at91sam7_mii.h b/os/hal/platforms/AT91SAM7/at91sam7_mii.h
index c417a0d15..897a5e584 100644
--- a/os/hal/platforms/AT91SAM7/at91sam7_mii.h
+++ b/os/hal/platforms/AT91SAM7/at91sam7_mii.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/hal_lld.c b/os/hal/platforms/AT91SAM7/hal_lld.c
index 40c355659..a95293e5c 100644
--- a/os/hal/platforms/AT91SAM7/hal_lld.c
+++ b/os/hal/platforms/AT91SAM7/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/hal_lld.h b/os/hal/platforms/AT91SAM7/hal_lld.h
index c033f13e8..e40cc533f 100644
--- a/os/hal/platforms/AT91SAM7/hal_lld.h
+++ b/os/hal/platforms/AT91SAM7/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/mac_lld.c b/os/hal/platforms/AT91SAM7/mac_lld.c
index ee71b2e23..43055b94d 100644
--- a/os/hal/platforms/AT91SAM7/mac_lld.c
+++ b/os/hal/platforms/AT91SAM7/mac_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -100,9 +101,9 @@ static void serve_interrupt(void) {
if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) {
if (rsr & AT91C_EMAC_REC) {
chSysLockFromIsr();
- chSemResetI(&ETH1.md_rdsem, 0);
+ chSemResetI(&ETH1.rdsem, 0);
#if CH_USE_EVENTS
- chEvtBroadcastI(&ETH1.md_rdevent);
+ chEvtBroadcastI(&ETH1.rdevent);
#endif
chSysUnlockFromIsr();
}
@@ -112,7 +113,7 @@ static void serve_interrupt(void) {
if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) {
if (tsr & AT91C_EMAC_COMP) {
chSysLockFromIsr();
- chSemResetI(&ETH1.md_tdsem, 0);
+ chSemResetI(&ETH1.tdsem, 0);
chSysUnlockFromIsr();
}
AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS;
@@ -291,9 +292,9 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
else
edp->w2 = W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER;
chSysUnlock();
- tdp->td_offset = 0;
- tdp->td_size = EMAC_TRANSMIT_BUFFERS_SIZE;
- tdp->td_physdesc = edp;
+ tdp->offset = 0;
+ tdp->size = EMAC_TRANSMIT_BUFFERS_SIZE;
+ tdp->physdesc = edp;
return RDY_OK;
}
@@ -315,13 +316,13 @@ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size) {
- if (size > tdp->td_size - tdp->td_offset)
- size = tdp->td_size - tdp->td_offset;
+ if (size > tdp->size - tdp->offset)
+ size = tdp->size - tdp->offset;
if (size > 0) {
- memcpy((uint8_t *)(tdp->td_physdesc->w1 & W1_T_ADDRESS_MASK) +
- tdp->td_offset,
+ memcpy((uint8_t *)(tdp->physdesc->w1 & W1_T_ADDRESS_MASK) +
+ tdp->offset,
buf, size);
- tdp->td_offset += size;
+ tdp->offset += size;
}
return size;
}
@@ -337,9 +338,9 @@ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
chSysLock();
- tdp->td_physdesc->w2 = (tdp->td_physdesc->w2 &
+ tdp->physdesc->w2 = (tdp->physdesc->w2 &
~(W2_T_LOCKED | W2_T_USED | W2_T_LENGTH_MASK)) |
- tdp->td_offset;
+ tdp->offset;
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
chSysUnlock();
}
@@ -400,9 +401,9 @@ restart:
* End Of Frame found.
*/
if (rxptr->w2 & W2_R_FRAME_END) {
- rdp->rd_offset = 0;
- rdp->rd_size = rxptr->w2 & W2_T_LENGTH_MASK;
- rdp->rd_physdesc = edp;
+ rdp->offset = 0;
+ rdp->size = rxptr->w2 & W2_T_LENGTH_MASK;
+ rdp->physdesc = edp;
return RDY_OK;
}
@@ -435,11 +436,11 @@ restart:
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *buf,
size_t size) {
- if (size > rdp->rd_size - rdp->rd_offset)
- size = rdp->rd_size - rdp->rd_offset;
+ if (size > rdp->size - rdp->offset)
+ size = rdp->size - rdp->offset;
if (size > 0) {
- uint8_t *src = (uint8_t *)(rdp->rd_physdesc->w1 & W1_R_ADDRESS_MASK) +
- rdp->rd_offset;
+ uint8_t *src = (uint8_t *)(rdp->physdesc->w1 & W1_R_ADDRESS_MASK) +
+ rdp->offset;
uint8_t *limit = &rb[EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE];
if (src >= limit)
src -= EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE;
@@ -449,7 +450,7 @@ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
}
else
memcpy(buf, src, size);
- rdp->rd_offset += size;
+ rdp->offset += size;
}
return size;
}
@@ -465,7 +466,7 @@ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
*/
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
bool_t done;
- EMACDescriptor *edp = rdp->rd_physdesc;
+ EMACDescriptor *edp = rdp->physdesc;
unsigned n = EMAC_RECEIVE_DESCRIPTORS;
do {
diff --git a/os/hal/platforms/AT91SAM7/mac_lld.h b/os/hal/platforms/AT91SAM7/mac_lld.h
index 21503dd53..9f30e0426 100644
--- a/os/hal/platforms/AT91SAM7/mac_lld.h
+++ b/os/hal/platforms/AT91SAM7/mac_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,7 +67,7 @@
#define W1_T_ADDRESS_MASK 0xFFFFFFFF
#define W2_T_LENGTH_MASK 0x000007FF
-#define W2_T_LOCKED 0x00000800 /* Not an EMAC flag, used by the driver */
+#define W2_T_LOCKED 0x00000800 /* Not an EMAC flag. */
#define W2_T_RFU1 0x00003000
#define W2_T_LAST_BUFFER 0x00008000
#define W2_T_NO_CRC 0x00010000
@@ -130,10 +131,10 @@ typedef struct {
* @brief Structure representing a MAC driver.
*/
typedef struct {
- Semaphore md_tdsem; /**< Transmit semaphore. */
- Semaphore md_rdsem; /**< Receive semaphore. */
+ Semaphore tdsem; /**< Transmit semaphore. */
+ Semaphore rdsem; /**< Receive semaphore. */
#if CH_USE_EVENTS
- EventSource md_rdevent; /**< Receive event source. */
+ EventSource rdevent; /**< Receive event source. */
#endif
/* End of the mandatory fields.*/
} MACDriver;
@@ -142,22 +143,23 @@ typedef struct {
* @brief Structure representing a transmit descriptor.
*/
typedef struct {
- size_t td_offset; /**< Current write offset. */
- size_t td_size; /**< Available space size. */
+ size_t offset; /**< Current write offset. */
+ size_t size; /**< Available space size. */
/* End of the mandatory fields.*/
- EMACDescriptor *td_physdesc; /**< Pointer to the physical
- descriptor. */
+ EMACDescriptor *physdesc; /**< Pointer to the physical
+ descriptor. */
} MACTransmitDescriptor;
/**
* @brief Structure representing a receive descriptor.
*/
typedef struct {
- size_t rd_offset; /**< Current read offset. */
- size_t rd_size; /**< Available data size. */
+ size_t offset; /**< Current read offset. */
+ size_t size; /**< Available data size. */
/* End of the mandatory fields.*/
- EMACDescriptor *rd_physdesc; /**< Pointer to the first descriptor
- of the buffers chain. */
+ EMACDescriptor *physdesc; /**< Pointer to the first
+ descriptor of the buffers
+ chain. */
} MACReceiveDescriptor;
/*===========================================================================*/
diff --git a/os/hal/platforms/AT91SAM7/pal_lld.c b/os/hal/platforms/AT91SAM7/pal_lld.c
index 4b43cd8d6..0e2136da1 100644
--- a/os/hal/platforms/AT91SAM7/pal_lld.c
+++ b/os/hal/platforms/AT91SAM7/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/pal_lld.h b/os/hal/platforms/AT91SAM7/pal_lld.h
index afcc7c238..9c5796a40 100644
--- a/os/hal/platforms/AT91SAM7/pal_lld.h
+++ b/os/hal/platforms/AT91SAM7/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -154,9 +155,7 @@ typedef AT91PS_PIO ioportid_t;
*
* @notapi
*/
-#define pal_lld_writeport(port, bits) { \
- (port)->PIO_ODSR = (bits); \
-}
+#define pal_lld_writeport(port, bits) ((port)->PIO_ODSR = (bits))
/**
* @brief Sets a bits mask on a I/O port.
@@ -168,9 +167,7 @@ typedef AT91PS_PIO ioportid_t;
*
* @notapi
*/
-#define pal_lld_setport(port, bits) { \
- (port)->PIO_SODR = (bits); \
-}
+#define pal_lld_setport(port, bits) ((port)->PIO_SODR = (bits))
/**
* @brief Clears a bits mask on a I/O port.
@@ -182,9 +179,7 @@ typedef AT91PS_PIO ioportid_t;
*
* @notapi
*/
-#define pal_lld_clearport(port, bits) { \
- (port)->PIO_CODR = (bits); \
-}
+#define pal_lld_clearport(port, bits) ((port)->PIO_CODR = (bits))
/**
* @brief Writes a group of bits.
@@ -200,11 +195,10 @@ typedef AT91PS_PIO ioportid_t;
*
* @notapi
*/
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- (port)->PIO_OWER = (mask) << (offset); \
- (port)->PIO_ODSR = (bits) << (offset); \
- (port)->PIO_OWDR = (mask) << (offset); \
-}
+#define pal_lld_writegroup(port, mask, offset, bits) \
+ ((port)->PIO_OWER = (mask) << (offset), \
+ (port)->PIO_ODSR = (bits) << (offset), \
+ (port)->PIO_OWDR = (mask) << (offset))
/**
* @brief Pads group mode setup.
diff --git a/os/hal/platforms/AT91SAM7/platform.dox b/os/hal/platforms/AT91SAM7/platform.dox
index af4816486..84f19fac5 100644
--- a/os/hal/platforms/AT91SAM7/platform.dox
+++ b/os/hal/platforms/AT91SAM7/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -42,7 +43,7 @@
*/
/**
- * @defgroup AT91SAM7_MAC AT91SAM7 EMAC Support
+ * @defgroup AT91SAM7_MAC AT91SAM7 MAC Support
* @details The AT91SAM7 MAC driver supports the EMAC peripheral.
*
* @section at91sam7_mac_1 Supported HW resources
@@ -62,7 +63,7 @@
*/
/**
- * @defgroup AT91SAM7_PAL AT91SAM7 PIO Support
+ * @defgroup AT91SAM7_PAL AT91SAM7 PAL Support
* @details The AT91SAM7 PAL driver supports the PIO peripherals.
*
* @section at91sam7_pal_1 Supported HW resources
@@ -99,26 +100,7 @@
*/
/**
- * @defgroup AT91SAM7_SPI AT91SAM7 SPI Support
- * @details The SPI driver supports the AT91SAM7 SPI peripherals using DMA
- * channels for maximum performance.
- *
- * @section at91sam7_spi_1 Supported HW resources
- * - SPI1.
- * - SPI2.
- * .
- * @section at91sam7_spi_2 AT91SAM7 SPI driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Each SPI can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Programmable interrupt priority levels for each SPI.
- * - DMA is used for receiving and transmitting.
- * .
- * @ingroup AT91SAM7
- */
-
-/**
- * @defgroup AT91SAM7_SERIAL AT91SAM7 USART Support (buffered)
+ * @defgroup AT91SAM7_SERIAL AT91SAM7 Serial Support
* @details The AT91SAM7 Serial driver uses the USART/UART peripherals in a
* buffered, interrupt driven, implementation.
*
@@ -137,3 +119,22 @@
* .
* @ingroup AT91SAM7
*/
+
+/**
+ * @defgroup AT91SAM7_SPI AT91SAM7 SPI Support
+ * @details The SPI driver supports the AT91SAM7 SPI peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section at91sam7_spi_1 Supported HW resources
+ * - SPI1.
+ * - SPI2.
+ * .
+ * @section at91sam7_spi_2 AT91SAM7 SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each SPI can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable interrupt priority levels for each SPI.
+ * - DMA is used for receiving and transmitting.
+ * .
+ * @ingroup AT91SAM7
+ */
diff --git a/os/hal/platforms/AT91SAM7/serial_lld.c b/os/hal/platforms/AT91SAM7/serial_lld.c
index f34f2b6d8..eff24a804 100644
--- a/os/hal/platforms/AT91SAM7/serial_lld.c
+++ b/os/hal/platforms/AT91SAM7/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -225,7 +226,7 @@ static void notify3(GenericQueue *qp) {
/**
* @brief USART0 interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART0IrqHandler) {
@@ -331,7 +332,7 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
AIC_EnableIT(AT91C_ID_US1);
}
#endif
- /* Note - no explicit start for SD3 (DBGU_UART) since it's not included
+ /* Note - no explicit start for SD3 (DBGU_UART) since it's not included
in the AIC or PMC.*/
}
usart_init(sdp, config);
diff --git a/os/hal/platforms/AT91SAM7/serial_lld.h b/os/hal/platforms/AT91SAM7/serial_lld.h
index 94aca128b..20b47562f 100644
--- a/os/hal/platforms/AT91SAM7/serial_lld.h
+++ b/os/hal/platforms/AT91SAM7/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/spi_lld.c b/os/hal/platforms/AT91SAM7/spi_lld.c
index 316ff65c9..218793d1e 100644
--- a/os/hal/platforms/AT91SAM7/spi_lld.c
+++ b/os/hal/platforms/AT91SAM7/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -55,7 +56,7 @@ SPIDriver SPID2;
* somewhere.
* @note This buffer size also limits the maximum transfer size, 512B,
* for @p spiReceive() and @p spiIgnore(). @p spiSend() and
- * @p spiExchange are not affected.
+ * @p spiExchange are not affected.
*/
static const uint16_t idle_buf[] = {
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
@@ -97,7 +98,7 @@ static const uint16_t idle_buf[] = {
/*===========================================================================*/
/**
- * @brief Initializes a SPI device.
+ * @brief Initializes a SPI device.
*/
static void spi_init(AT91PS_SPI spi) {
@@ -116,19 +117,19 @@ static void spi_init(AT91PS_SPI spi) {
__attribute__((noinline))
#endif
/**
- * @brief Shared interrupt handling code.
+ * @brief Shared interrupt handling code.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_lld_serve_interrupt(SPIDriver *spip) {
- uint32_t sr = spip->spd_spi->SPI_SR;
+ uint32_t sr = spip->spi->SPI_SR;
if ((sr & AT91C_SPI_ENDRX) != 0) {
- (void)spip->spd_spi->SPI_RDR; /* Clears eventual overflow.*/
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTDIS |
+ (void)spip->spi->SPI_RDR; /* Clears eventual overflow.*/
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTDIS |
AT91C_PDC_TXTDIS; /* PDC disabled. */
- spip->spd_spi->SPI_IDR = AT91C_SPI_ENDRX; /* Interrupt disabled. */
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIDIS; /* SPI disabled. */
+ spip->spi->SPI_IDR = AT91C_SPI_ENDRX; /* Interrupt disabled. */
+ spip->spi->SPI_CR = AT91C_SPI_SPIDIS; /* SPI disabled. */
/* Portable SPI ISR code defined in the high level driver, note, it is
a macro.*/
_spi_isr_code(spip);
@@ -182,7 +183,7 @@ void spi_lld_init(void) {
#if AT91SAM7_SPI_USE_SPI0
spiObjectInit(&SPID1);
- SPID1.spd_spi = AT91C_BASE_SPI0;
+ SPID1.spi = AT91C_BASE_SPI0;
spi_init(AT91C_BASE_SPI0);
AT91C_BASE_PIOA->PIO_PDR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
AT91C_BASE_PIOA->PIO_ASR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
@@ -194,7 +195,7 @@ void spi_lld_init(void) {
#if AT91SAM7_SPI_USE_SPI1
spiObjectInit(&SPID2);
- SPID2.spd_spi = AT91C_BASE_SPI1;
+ SPID2.spi = AT91C_BASE_SPI1;
spi_init(AT91C_BASE_SPI1);
AT91C_BASE_PIOA->PIO_PDR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
AT91C_BASE_PIOA->PIO_BSR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
@@ -214,7 +215,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
#if AT91SAM7_SPI_USE_SPI0
if (&SPID1 == spip) {
/* Clock activation.*/
@@ -233,7 +234,7 @@ void spi_lld_start(SPIDriver *spip) {
#endif
}
/* Configuration.*/
- spip->spd_spi->SPI_CSR[0] = spip->spd_config->spc_csr;
+ spip->spi->SPI_CSR[0] = spip->config->csr;
}
/**
@@ -245,7 +246,7 @@ void spi_lld_start(SPIDriver *spip) {
*/
void spi_lld_stop(SPIDriver *spip) {
- if (spip->spd_state != SPI_STOP) {
+ if (spip->state != SPI_STOP) {
#if AT91SAM7_SPI_USE_SPI0
if (&SPID1 == spip) {
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_SPI0);
@@ -270,7 +271,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -283,7 +284,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -299,13 +300,13 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_spi->SPI_TCR = n;
- spip->spd_spi->SPI_RCR = n;
- spip->spd_spi->SPI_TPR = (AT91_REG)idle_buf;
- spip->spd_spi->SPI_RPR = (AT91_REG)idle_buf;
- spip->spd_spi->SPI_IER = AT91C_SPI_ENDRX;
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ spip->spi->SPI_TCR = n;
+ spip->spi->SPI_RCR = n;
+ spip->spi->SPI_TPR = (AT91_REG)idle_buf;
+ spip->spi->SPI_RPR = (AT91_REG)idle_buf;
+ spip->spi->SPI_IER = AT91C_SPI_ENDRX;
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
/**
@@ -323,13 +324,13 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_spi->SPI_TCR = n;
- spip->spd_spi->SPI_RCR = n;
- spip->spd_spi->SPI_TPR = (AT91_REG)txbuf;
- spip->spd_spi->SPI_RPR = (AT91_REG)rxbuf;
- spip->spd_spi->SPI_IER = AT91C_SPI_ENDRX;
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ spip->spi->SPI_TCR = n;
+ spip->spi->SPI_RCR = n;
+ spip->spi->SPI_TPR = (AT91_REG)txbuf;
+ spip->spi->SPI_RPR = (AT91_REG)rxbuf;
+ spip->spi->SPI_IER = AT91C_SPI_ENDRX;
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
/**
@@ -344,13 +345,13 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_spi->SPI_TCR = n;
- spip->spd_spi->SPI_RCR = n;
- spip->spd_spi->SPI_TPR = (AT91_REG)txbuf;
- spip->spd_spi->SPI_RPR = (AT91_REG)idle_buf;
- spip->spd_spi->SPI_IER = AT91C_SPI_ENDRX;
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ spip->spi->SPI_TCR = n;
+ spip->spi->SPI_RCR = n;
+ spip->spi->SPI_TPR = (AT91_REG)txbuf;
+ spip->spi->SPI_RPR = (AT91_REG)idle_buf;
+ spip->spi->SPI_IER = AT91C_SPI_ENDRX;
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
/**
@@ -365,13 +366,13 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_spi->SPI_TCR = n;
- spip->spd_spi->SPI_RCR = n;
- spip->spd_spi->SPI_TPR = (AT91_REG)idle_buf;
- spip->spd_spi->SPI_RPR = (AT91_REG)rxbuf;
- spip->spd_spi->SPI_IER = AT91C_SPI_ENDRX;
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ spip->spi->SPI_TCR = n;
+ spip->spi->SPI_RCR = n;
+ spip->spi->SPI_TPR = (AT91_REG)idle_buf;
+ spip->spi->SPI_RPR = (AT91_REG)rxbuf;
+ spip->spi->SPI_IER = AT91C_SPI_ENDRX;
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
/**
@@ -388,11 +389,11 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_TDR = frame;
- while ((spip->spd_spi->SPI_SR & AT91C_SPI_RDRF) == 0)
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_TDR = frame;
+ while ((spip->spi->SPI_SR & AT91C_SPI_RDRF) == 0)
;
- return spip->spd_spi->SPI_RDR;
+ return spip->spi->SPI_RDR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/AT91SAM7/spi_lld.h b/os/hal/platforms/AT91SAM7/spi_lld.h
index 3b0bfaaba..8949a1703 100644
--- a/os/hal/platforms/AT91SAM7/spi_lld.h
+++ b/os/hal/platforms/AT91SAM7/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -127,20 +128,20 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SPI Chip Select Register initialization data.
*/
- uint32_t spc_csr;
+ uint32_t csr;
} SPIConfig;
/**
@@ -150,25 +151,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -178,7 +179,7 @@ struct SPIDriver {
/**
* @brief Pointer to the SPIx registers block.
*/
- AT91PS_SPI spd_spi;
+ AT91PS_SPI spi;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/AVR/hal_lld.c b/os/hal/platforms/AVR/hal_lld.c
index a3d3f4ab8..421401158 100644
--- a/os/hal/platforms/AVR/hal_lld.c
+++ b/os/hal/platforms/AVR/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AVR/hal_lld.h b/os/hal/platforms/AVR/hal_lld.h
index 647c2f142..c3d65f167 100644
--- a/os/hal/platforms/AVR/hal_lld.h
+++ b/os/hal/platforms/AVR/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AVR/platform.dox b/os/hal/platforms/AVR/platform.dox
index 9b8cf3e6b..bc29954b6 100644
--- a/os/hal/platforms/AVR/platform.dox
+++ b/os/hal/platforms/AVR/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -35,7 +36,7 @@
*/
/**
- * @defgroup AVR_SERIAL AVR USART Support (buffered)
+ * @defgroup AVR_SERIAL AVR Serial Support
* @details The AVR Serial driver uses the USART peripherals in a
* buffered, interrupt driven, implementation.
*
diff --git a/os/hal/platforms/AVR/serial_lld.c b/os/hal/platforms/AVR/serial_lld.c
index f78abac18..a61d6b0c2 100644
--- a/os/hal/platforms/AVR/serial_lld.c
+++ b/os/hal/platforms/AVR/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -154,7 +155,7 @@ static void usart1_deinit(void) {
/**
* @brief USART0 RX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART0_RX_vect) {
uint8_t sra;
@@ -174,7 +175,7 @@ CH_IRQ_HANDLER(USART0_RX_vect) {
/**
* @brief USART0 TX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART0_UDRE_vect) {
msg_t b;
@@ -182,7 +183,7 @@ CH_IRQ_HANDLER(USART0_UDRE_vect) {
CH_IRQ_PROLOGUE();
chSysLockFromIsr();
- b = sdRequestDataI(&SER1);
+ b = sdRequestDataI(&SD1);
chSysUnlockFromIsr();
if (b < Q_OK)
UCSR0B &= ~(1 << UDRIE);
@@ -197,7 +198,7 @@ CH_IRQ_HANDLER(USART0_UDRE_vect) {
/**
* @brief USART1 RX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART1_RX_vect) {
uint8_t sra;
@@ -217,7 +218,7 @@ CH_IRQ_HANDLER(USART1_RX_vect) {
/**
* @brief USART1 TX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART1_UDRE_vect) {
msg_t b;
diff --git a/os/hal/platforms/AVR/serial_lld.h b/os/hal/platforms/AVR/serial_lld.h
index 4a2ff843a..f660b7d2d 100644
--- a/os/hal/platforms/AVR/serial_lld.h
+++ b/os/hal/platforms/AVR/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -105,7 +106,7 @@ typedef struct {
* @brief Macro for baud rate computation.
* @note Make sure the final baud rate is within tolerance.
*/
-#define UBRR(b) ((F_CPU / (b << 4)) - 1)
+#define UBRR(b) (((F_CPU / b) >> 4) - 1)
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/platforms/LPC11xx/core_cm0.h b/os/hal/platforms/LPC11xx/core_cm0.h
index af27881d4..662099a21 100644
--- a/os/hal/platforms/LPC11xx/core_cm0.h
+++ b/os/hal/platforms/LPC11xx/core_cm0.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/gpt_lld.c b/os/hal/platforms/LPC11xx/gpt_lld.c
new file mode 100644
index 000000000..df90ac630
--- /dev/null
+++ b/os/hal/platforms/LPC11xx/gpt_lld.c
@@ -0,0 +1,342 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file LPC11xx/gpt_lld.c
+ * @brief LPC11xx GPT subsystem low level driver source.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver identifier.
+ * @note The driver GPT1 allocates the complex timer CT16B0 when enabled.
+ */
+#if LPC11xx_GPT_USE_CT16B0 || defined(__DOXYGEN__)
+GPTDriver GPTD1;
+#endif
+
+/**
+ * @brief GPT2 driver identifier.
+ * @note The driver GPT2 allocates the timer CT16B1 when enabled.
+ */
+#if LPC11xx_GPT_USE_CT16B1 || defined(__DOXYGEN__)
+GPTDriver GPTD2;
+#endif
+
+/**
+ * @brief GPT3 driver identifier.
+ * @note The driver GPT3 allocates the timer CT32B0 when enabled.
+ */
+#if LPC11xx_GPT_USE_CT32B0 || defined(__DOXYGEN__)
+GPTDriver GPTD3;
+#endif
+
+/**
+ * @brief GPT4 driver identifier.
+ * @note The driver GPT4 allocates the timer CT32B1 when enabled.
+ */
+#if LPC11xx_GPT_USE_CT32B1 || defined(__DOXYGEN__)
+GPTDriver GPTD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1; /* Clear interrupt on match MR0.*/
+ if (gptp->state == GPT_ONESHOT) {
+ gptp->state = GPT_READY; /* Back in GPT_READY state. */
+ gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
+ }
+ gptp->config->callback(gptp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if LPC11xx_GPT_USE_CT16B0
+/**
+ * @brief CT16B0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector80) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC11xx_GPT_USE_CT16B0 */
+
+#if LPC11xx_GPT_USE_CT16B1
+/**
+ * @brief CT16B1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector84) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC11xx_GPT_USE_CT16B0 */
+
+#if LPC11xx_GPT_USE_CT32B0
+/**
+ * @brief CT32B0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector88) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC11xx_GPT_USE_CT32B0 */
+
+#if LPC11xx_GPT_USE_CT32B1
+/**
+ * @brief CT32B1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector8C) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC11xx_GPT_USE_CT32B1 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+#if LPC11xx_GPT_USE_CT16B0
+ /* Driver initialization.*/
+ GPTD1.tmr = LPC_TMR16B0;
+ gptObjectInit(&GPTD1);
+#endif
+
+#if LPC11xx_GPT_USE_CT16B1
+ /* Driver initialization.*/
+ GPTD2.tmr = LPC_TMR16B1;
+ gptObjectInit(&GPTD2);
+#endif
+
+#if LPC11xx_GPT_USE_CT32B0
+ /* Driver initialization.*/
+ GPTD3.tmr = LPC_TMR32B0;
+ gptObjectInit(&GPTD3);
+#endif
+
+#if LPC11xx_GPT_USE_CT32B1
+ /* Driver initialization.*/
+ GPTD4.tmr = LPC_TMR32B1;
+ gptObjectInit(&GPTD4);
+#endif
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint32_t pr;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+#if LPC11xx_GPT_USE_CT16B0
+ if (&GPTD1 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7);
+ NVICEnableVector(TIMER_16_0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC11xx_GPT_USE_CT16B1
+ if (&GPTD2 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
+ NVICEnableVector(TIMER_16_1_IRQn, CORTEX_PRIORITY_MASK(3));
+ }
+#endif
+#if LPC11xx_GPT_USE_CT32B0
+ if (&GPTD3 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9);
+ NVICEnableVector(TIMER_32_0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC11xx_GPT_USE_CT32B1
+ if (&GPTD4 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
+ NVICEnableVector(TIMER_32_1_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+ }
+
+ /* Prescaler value calculation.*/
+ pr = (uint16_t)((LPC11xx_SYSCLK / gptp->config->frequency) - 1);
+ chDbgAssert(((uint32_t)(pr + 1) * gptp->config->frequency) == LPC11xx_SYSCLK,
+ "gpt_lld_start(), #1", "invalid frequency");
+
+ /* Timer configuration.*/
+ gptp->tmr->PR = pr;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+
+#if LPC11xx_GPT_USE_CT16B0
+ if (&GPTD1 == gptp) {
+ NVICDisableVector(TIMER_16_0_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 7);
+ }
+#endif
+#if LPC11xx_GPT_USE_CT16B1
+ if (&GPTD2 == gptp) {
+ NVICDisableVector(TIMER_16_1_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8);
+ }
+#endif
+#if LPC11xx_GPT_USE_CT32B0
+ if (&GPTD3 == gptp) {
+ NVICDisableVector(TIMER_32_0_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 9);
+ }
+#endif
+#if LPC11xx_GPT_USE_CT32B1
+ if (&GPTD4 == gptp) {
+ NVICDisableVector(TIMER_32_1_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 10);
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 3; /* IRQ and clr TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 4; /* Stop TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+ while (gptp->tmr->TCR & 1)
+ ;
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/platforms/LPC11xx/gpt_lld.h b/os/hal/platforms/LPC11xx/gpt_lld.h
new file mode 100644
index 000000000..1aa1e3b90
--- /dev/null
+++ b/os/hal/platforms/LPC11xx/gpt_lld.h
@@ -0,0 +1,208 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file LPC11xx/gpt_lld.h
+ * @brief LPC11xx GPT subsystem low level driver header.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver enable switch.
+ * @details If set to @p TRUE the support for GPT1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC11xx_GPT_USE_CT16B0) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_USE_CT16B0 TRUE
+#endif
+
+/**
+ * @brief GPT2 driver enable switch.
+ * @details If set to @p TRUE the support for GPT2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC11xx_GPT_USE_CT16B1) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_USE_CT16B1 TRUE
+#endif
+
+/**
+ * @brief GPT3 driver enable switch.
+ * @details If set to @p TRUE the support for GPT3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC11xx_GPT_USE_CT32B0) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_USE_CT32B0 TRUE
+#endif
+
+/**
+ * @brief GPT4 driver enable switch.
+ * @details If set to @p TRUE the support for GPT4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC11xx_GPT_USE_CT32B1) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_USE_CT32B1 TRUE
+#endif
+
+/**
+ * @brief GPT1 interrupt priority level setting.
+ */
+#if !defined(LPC11xx_GPT_CT16B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_CT16B0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT2 interrupt priority level setting.
+ */
+#if !defined(LPC11xx_GPT_CT16B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_CT16B1_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT3 interrupt priority level setting.
+ */
+#if !defined(LPC11xx_GPT_CT32B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_CT32B0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT4 interrupt priority level setting.
+ */
+#if !defined(LPC11xx_GPT_CT32B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_CT32B1_IRQ_PRIORITY 2
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !LPC11xx_GPT_USE_CT16B0 && !LPC11xx_GPT_USE_CT16B1 && \
+ !LPC11xx_GPT_USE_CT32B0 && !LPC11xx_GPT_USE_CT32B1
+#error "GPT driver activated but no CT peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint32_t gptcnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the CTxxBy registers block.
+ */
+ LPC_TMR_TypeDef *tmr;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if LPC11xx_GPT_USE_CT16B0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD1;
+#endif
+
+#if LPC11xx_GPT_USE_CT16B1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD2;
+#endif
+
+#if LPC11xx_GPT_USE_CT32B0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD3;
+#endif
+
+#if LPC11xx_GPT_USE_CT32B1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD4;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC11xx/hal_lld.c b/os/hal/platforms/LPC11xx/hal_lld.c
index 8bb79f866..89db29491 100644
--- a/os/hal/platforms/LPC11xx/hal_lld.c
+++ b/os/hal/platforms/LPC11xx/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/hal_lld.h b/os/hal/platforms/LPC11xx/hal_lld.h
index f94b058fd..267ce9105 100644
--- a/os/hal/platforms/LPC11xx/hal_lld.h
+++ b/os/hal/platforms/LPC11xx/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/pal_lld.c b/os/hal/platforms/LPC11xx/pal_lld.c
index c8d831a82..6ce6ba876 100644
--- a/os/hal/platforms/LPC11xx/pal_lld.c
+++ b/os/hal/platforms/LPC11xx/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/pal_lld.h b/os/hal/platforms/LPC11xx/pal_lld.h
index 4201f5114..d60b4ef71 100644
--- a/os/hal/platforms/LPC11xx/pal_lld.h
+++ b/os/hal/platforms/LPC11xx/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/platform.dox b/os/hal/platforms/LPC11xx/platform.dox
index 19dd542ae..593a82fdf 100644
--- a/os/hal/platforms/LPC11xx/platform.dox
+++ b/os/hal/platforms/LPC11xx/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -43,7 +44,25 @@
*/
/**
- * @defgroup LPC11xx_PAL LPC11xx GPIO Support
+ * @defgroup LPC11xx_GPT LPC11xx GPT Support
+ * @details The LPC11xx GPT driver uses the CTxxBy peripherals.
+ *
+ * @section lpc11xx_gpt_1 Supported HW resources
+ * - CT16B0.
+ * - CT16B1.
+ * - CT32B0.
+ * - CT32B1.
+ * .
+ * @section lpc11xx_gpt_2 LPC11xx GPT driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable CTxxBy interrupts priority level.
+ * .
+ * @ingroup LPC11xx
+ */
+
+/**
+ * @defgroup LPC11xx_PAL LPC11xx PAL Support
* @details The LPC11xx PAL driver uses the GPIO peripherals.
*
* @section lpc11xx_pal_1 Supported HW resources
@@ -79,7 +98,26 @@
*/
/**
- * @defgroup LPC11xx_SPI LPC11xx SSP Support
+ * @defgroup LPC11xx_SERIAL LPC11xx Serial Support
+ * @details The LPC11xx Serial driver uses the UART peripheral in a
+ * buffered, interrupt driven, implementation. The serial driver
+ * also takes advantage of the LPC11xx UARTs deep hardware buffers.
+ *
+ * @section lpc11xx_serial_1 Supported HW resources
+ * The serial driver can support any of the following hardware resources:
+ * - UART.
+ * .
+ * @section lpc11xx_serial_2 LPC11xx Serial driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Fully interrupt driven.
+ * - Programmable priority level.
+ * - Takes advantage of the input and output FIFOs.
+ * .
+ * @ingroup LPC11xx
+ */
+
+/**
+ * @defgroup LPC11xx_SPI LPC11xx SPI Support
* @details The SPI driver supports the LPC11xx SSP peripherals in an interrupt
* driven implementation.
* @note Being the SPI a fast peripheral, much care must be taken to
@@ -100,22 +138,3 @@
* .
* @ingroup LPC11xx
*/
-
-/**
- * @defgroup LPC11xx_SERIAL LPC11xx UART Support (buffered)
- * @details The LPC11xx Serial driver uses the UART peripheral in a
- * buffered, interrupt driven, implementation. The serial driver
- * also takes advantage of the LPC11xx UARTs deep hardware buffers.
- *
- * @section lpc11xx_serial_1 Supported HW resources
- * The serial driver can support any of the following hardware resources:
- * - UART.
- * .
- * @section lpc11xx_serial_2 LPC11xx Serial driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Fully interrupt driven.
- * - Programmable priority level.
- * - Takes advantage of the input and output FIFOs.
- * .
- * @ingroup LPC11xx
- */
diff --git a/os/hal/platforms/LPC11xx/platform.mk b/os/hal/platforms/LPC11xx/platform.mk
index ade33695f..4f0d19547 100644
--- a/os/hal/platforms/LPC11xx/platform.mk
+++ b/os/hal/platforms/LPC11xx/platform.mk
@@ -1,5 +1,6 @@
# List of all the LPC11xx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC11xx/hal_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC11xx/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/LPC11xx/pal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC11xx/serial_lld.c \
${CHIBIOS}/os/hal/platforms/LPC11xx/spi_lld.c
diff --git a/os/hal/platforms/LPC11xx/serial_lld.c b/os/hal/platforms/LPC11xx/serial_lld.c
index ecd080eaf..269a5a8e5 100644
--- a/os/hal/platforms/LPC11xx/serial_lld.c
+++ b/os/hal/platforms/LPC11xx/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/serial_lld.h b/os/hal/platforms/LPC11xx/serial_lld.h
index a2e8acc4b..ffe9a8ae6 100644
--- a/os/hal/platforms/LPC11xx/serial_lld.h
+++ b/os/hal/platforms/LPC11xx/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/spi_lld.c b/os/hal/platforms/LPC11xx/spi_lld.c
index 47766088c..5704b17f3 100644
--- a/os/hal/platforms/LPC11xx/spi_lld.c
+++ b/os/hal/platforms/LPC11xx/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -58,27 +59,27 @@ SPIDriver SPID2;
* @param[in] spip pointer to the @p SPIDriver object
*/
static void ssp_fifo_preload(SPIDriver *spip) {
- LPC_SSP_TypeDef *ssp = spip->spd_ssp;
- uint32_t n = spip->spd_txcnt > LPC11xx_SSP_FIFO_DEPTH ?
- LPC11xx_SSP_FIFO_DEPTH : spip->spd_txcnt;
+ LPC_SSP_TypeDef *ssp = spip->ssp;
+ uint32_t n = spip->txcnt > LPC11xx_SSP_FIFO_DEPTH ?
+ LPC11xx_SSP_FIFO_DEPTH : spip->txcnt;
while(((ssp->SR & SR_TNF) != 0) && (n > 0)) {
- if (spip->spd_txptr != NULL) {
+ if (spip->txptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
- const uint16_t *p = spip->spd_txptr;
+ const uint16_t *p = spip->txptr;
ssp->DR = *p++;
- spip->spd_txptr = p;
+ spip->txptr = p;
}
else {
- const uint8_t *p = spip->spd_txptr;
+ const uint8_t *p = spip->txptr;
ssp->DR = *p++;
- spip->spd_txptr = p;
+ spip->txptr = p;
}
}
else
ssp->DR = 0xFFFFFFFF;
n--;
- spip->spd_txcnt--;
+ spip->txcnt--;
}
}
@@ -88,7 +89,7 @@ static void ssp_fifo_preload(SPIDriver *spip) {
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_serve_interrupt(SPIDriver *spip) {
- LPC_SSP_TypeDef *ssp = spip->spd_ssp;
+ LPC_SSP_TypeDef *ssp = spip->ssp;
if ((ssp->MIS & MIS_ROR) != 0) {
/* The overflow condition should never happen because priority is given
@@ -97,22 +98,22 @@ static void spi_serve_interrupt(SPIDriver *spip) {
}
ssp->ICR = ICR_RT | ICR_ROR;
while ((ssp->SR & SR_RNE) != 0) {
- if (spip->spd_rxptr != NULL) {
+ if (spip->rxptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
- uint16_t *p = spip->spd_rxptr;
+ uint16_t *p = spip->rxptr;
*p++ = ssp->DR;
- spip->spd_rxptr = p;
+ spip->rxptr = p;
}
else {
- uint8_t *p = spip->spd_rxptr;
+ uint8_t *p = spip->rxptr;
*p++ = ssp->DR;
- spip->spd_rxptr = p;
+ spip->rxptr = p;
}
}
else
(void)ssp->DR;
- if (--spip->spd_rxcnt == 0) {
- chDbgAssert(spip->spd_txcnt == 0,
+ if (--spip->rxcnt == 0) {
+ chDbgAssert(spip->txcnt == 0,
"spi_serve_interrupt(), #1", "counter out of synch");
/* Stops the IRQ sources.*/
ssp->IMSC = 0;
@@ -123,7 +124,7 @@ static void spi_serve_interrupt(SPIDriver *spip) {
}
}
ssp_fifo_preload(spip);
- if (spip->spd_txcnt == 0)
+ if (spip->txcnt == 0)
ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
@@ -176,7 +177,7 @@ void spi_lld_init(void) {
#if LPC11xx_SPI_USE_SSP0
spiObjectInit(&SPID1);
- SPID1.spd_ssp = LPC_SSP0;
+ SPID1.ssp = LPC_SSP0;
LPC_IOCON->SCK_LOC = LPC11xx_SPI_SCK0_SELECTOR;
#if LPC11xx_SPI_SCK0_SELECTOR == SCK0_IS_PIO0_10
LPC_IOCON->JTAG_TCK_PIO0_10 = 0xC2; /* SCK0 without resistors. */
@@ -191,7 +192,7 @@ void spi_lld_init(void) {
#if LPC11xx_SPI_USE_SSP1
spiObjectInit(&SPID2);
- SPID2.spd_ssp = LPC_SSP1;
+ SPID2.ssp = LPC_SSP1;
LPC_IOCON->PIO2_1 = 0xC2; /* SCK1 without resistors. */
LPC_IOCON->PIO2_2 = 0xC2; /* MISO1 without resistors. */
LPC_IOCON->PIO2_3 = 0xC2; /* MOSI1 without resistors. */
@@ -207,7 +208,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
/* Clock activation.*/
#if LPC11xx_SPI_USE_SSP0
if (&SPID1 == spip) {
@@ -229,11 +230,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
}
/* Configuration.*/
- spip->spd_ssp->CR1 = 0;
- spip->spd_ssp->ICR = ICR_RT | ICR_ROR;
- spip->spd_ssp->CR0 = spip->spd_config->spc_cr0;
- spip->spd_ssp->CPSR = spip->spd_config->spc_cpsr;
- spip->spd_ssp->CR1 = CR1_SSE;
+ spip->ssp->CR1 = 0;
+ spip->ssp->ICR = ICR_RT | ICR_ROR;
+ spip->ssp->CR0 = spip->config->cr0;
+ spip->ssp->CPSR = spip->config->cpsr;
+ spip->ssp->CR1 = CR1_SSE;
}
/**
@@ -245,10 +246,10 @@ void spi_lld_start(SPIDriver *spip) {
*/
void spi_lld_stop(SPIDriver *spip) {
- if (spip->spd_state != SPI_STOP) {
- spip->spd_ssp->CR1 = 0;
- spip->spd_ssp->CR0 = 0;
- spip->spd_ssp->CPSR = 0;
+ if (spip->state != SPI_STOP) {
+ spip->ssp->CR1 = 0;
+ spip->ssp->CR0 = 0;
+ spip->ssp->CPSR = 0;
#if LPC11xx_SPI_USE_SSP0
if (&SPID1 == spip) {
LPC_SYSCON->PRESETCTRL &= ~1;
@@ -277,7 +278,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -290,7 +291,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -306,11 +307,11 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -331,11 +332,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -353,11 +354,11 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -375,11 +376,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -396,10 +397,10 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_ssp->DR = (uint32_t)frame;
- while ((spip->spd_ssp->SR & SR_RNE) == 0)
+ spip->ssp->DR = (uint32_t)frame;
+ while ((spip->ssp->SR & SR_RNE) == 0)
;
- return (uint16_t)spip->spd_ssp->DR;
+ return (uint16_t)spip->ssp->DR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/LPC11xx/spi_lld.h b/os/hal/platforms/LPC11xx/spi_lld.h
index e0525387a..47df7d94b 100644
--- a/os/hal/platforms/LPC11xx/spi_lld.h
+++ b/os/hal/platforms/LPC11xx/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -194,13 +195,13 @@
/**
* @brief SSP0 clock.
*/
-#define LPC11xx_SERIAL_SSP0_PCLK \
+#define LPC11xx_SERIAL_SSP0_PCLK \
(LPC11xx_MAINCLK / LPC11xx_SERIAL_SSP0CLKDIV)
/**
* @brief SSP1 clock.
*/
-#define LPC11xx_SERIAL_SSP1_PCLK \
+#define LPC11xx_SERIAL_SSP1_PCLK \
(LPC11xx_MAINCLK / LPC11xx_SERIAL_SSP1CLKDIV)
/*===========================================================================*/
@@ -227,24 +228,24 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SSP CR0 initialization data.
*/
- uint16_t spc_cr0;
+ uint16_t cr0;
/**
* @brief SSP CPSR initialization data.
*/
- uint32_t spc_cpsr;
+ uint32_t cpsr;
} SPIConfig;
/**
@@ -254,25 +255,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -282,23 +283,23 @@ struct SPIDriver {
/**
* @brief Pointer to the SSP registers block.
*/
- LPC_SSP_TypeDef *spd_ssp;
+ LPC_SSP_TypeDef *ssp;
/**
* @brief Number of bytes yet to be received.
*/
- uint32_t spd_rxcnt;
+ uint32_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
- void *spd_rxptr;
+ void *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
- uint32_t spd_txcnt;
+ uint32_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
- const void *spd_txptr;
+ const void *txptr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/LPC13xx/core_cm3.h b/os/hal/platforms/LPC13xx/core_cm3.h
index 5c75ec859..387221bc6 100644
--- a/os/hal/platforms/LPC13xx/core_cm3.h
+++ b/os/hal/platforms/LPC13xx/core_cm3.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/gpt_lld.c b/os/hal/platforms/LPC13xx/gpt_lld.c
new file mode 100644
index 000000000..7d6961889
--- /dev/null
+++ b/os/hal/platforms/LPC13xx/gpt_lld.c
@@ -0,0 +1,342 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file LPC13xx/gpt_lld.c
+ * @brief LPC13xx GPT subsystem low level driver source.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver identifier.
+ * @note The driver GPT1 allocates the complex timer CT16B0 when enabled.
+ */
+#if LPC13xx_GPT_USE_CT16B0 || defined(__DOXYGEN__)
+GPTDriver GPTD1;
+#endif
+
+/**
+ * @brief GPT2 driver identifier.
+ * @note The driver GPT2 allocates the timer CT16B1 when enabled.
+ */
+#if LPC13xx_GPT_USE_CT16B1 || defined(__DOXYGEN__)
+GPTDriver GPTD2;
+#endif
+
+/**
+ * @brief GPT3 driver identifier.
+ * @note The driver GPT3 allocates the timer CT32B0 when enabled.
+ */
+#if LPC13xx_GPT_USE_CT32B0 || defined(__DOXYGEN__)
+GPTDriver GPTD3;
+#endif
+
+/**
+ * @brief GPT4 driver identifier.
+ * @note The driver GPT4 allocates the timer CT32B1 when enabled.
+ */
+#if LPC13xx_GPT_USE_CT32B1 || defined(__DOXYGEN__)
+GPTDriver GPTD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1; /* Clear interrupt on match MR0.*/
+ if (gptp->state == GPT_ONESHOT) {
+ gptp->state = GPT_READY; /* Back in GPT_READY state. */
+ gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
+ }
+ gptp->config->callback(gptp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if LPC13xx_GPT_USE_CT16B0
+/**
+ * @brief CT16B0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorE4) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC13xx_GPT_USE_CT16B0 */
+
+#if LPC13xx_GPT_USE_CT16B1
+/**
+ * @brief CT16B1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorE8) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC13xx_GPT_USE_CT16B0 */
+
+#if LPC13xx_GPT_USE_CT32B0
+/**
+ * @brief CT32B0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorEC) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC13xx_GPT_USE_CT32B0 */
+
+#if LPC13xx_GPT_USE_CT32B1
+/**
+ * @brief CT32B1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorF0) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC13xx_GPT_USE_CT32B1 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+#if LPC13xx_GPT_USE_CT16B0
+ /* Driver initialization.*/
+ GPTD1.tmr = LPC_TMR16B0;
+ gptObjectInit(&GPTD1);
+#endif
+
+#if LPC13xx_GPT_USE_CT16B1
+ /* Driver initialization.*/
+ GPTD2.tmr = LPC_TMR16B1;
+ gptObjectInit(&GPTD2);
+#endif
+
+#if LPC13xx_GPT_USE_CT32B0
+ /* Driver initialization.*/
+ GPTD3.tmr = LPC_TMR32B0;
+ gptObjectInit(&GPTD3);
+#endif
+
+#if LPC13xx_GPT_USE_CT32B1
+ /* Driver initialization.*/
+ GPTD4.tmr = LPC_TMR32B1;
+ gptObjectInit(&GPTD4);
+#endif
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint32_t pr;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+#if LPC13xx_GPT_USE_CT16B0
+ if (&GPTD1 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7);
+ NVICEnableVector(TIMER_16_0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC13xx_GPT_USE_CT16B1
+ if (&GPTD2 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
+ NVICEnableVector(TIMER_16_1_IRQn, CORTEX_PRIORITY_MASK(3));
+ }
+#endif
+#if LPC13xx_GPT_USE_CT32B0
+ if (&GPTD3 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9);
+ NVICEnableVector(TIMER_32_0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC13xx_GPT_USE_CT32B1
+ if (&GPTD4 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
+ NVICEnableVector(TIMER_32_1_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+ }
+
+ /* Prescaler value calculation.*/
+ pr = (uint16_t)((LPC13xx_SYSCLK / gptp->config->frequency) - 1);
+ chDbgAssert(((uint32_t)(pr + 1) * gptp->config->frequency) == LPC13xx_SYSCLK,
+ "gpt_lld_start(), #1", "invalid frequency");
+
+ /* Timer configuration.*/
+ gptp->tmr->PR = pr;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+
+#if LPC13xx_GPT_USE_CT16B0
+ if (&GPTD1 == gptp) {
+ NVICDisableVector(TIMER_16_0_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 7);
+ }
+#endif
+#if LPC13xx_GPT_USE_CT16B1
+ if (&GPTD2 == gptp) {
+ NVICDisableVector(TIMER_16_1_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8);
+ }
+#endif
+#if LPC13xx_GPT_USE_CT32B0
+ if (&GPTD3 == gptp) {
+ NVICDisableVector(TIMER_32_0_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 9);
+ }
+#endif
+#if LPC13xx_GPT_USE_CT32B1
+ if (&GPTD4 == gptp) {
+ NVICDisableVector(TIMER_32_1_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 10);
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 3; /* IRQ and clr TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 4; /* Stop TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+ while (gptp->tmr->TCR & 1)
+ ;
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/platforms/LPC13xx/gpt_lld.h b/os/hal/platforms/LPC13xx/gpt_lld.h
new file mode 100644
index 000000000..e4a53224b
--- /dev/null
+++ b/os/hal/platforms/LPC13xx/gpt_lld.h
@@ -0,0 +1,212 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file LPC13xx/gpt_lld.h
+ * @brief LPC13xx GPT subsystem low level driver header.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver enable switch.
+ * @details If set to @p TRUE the support for GPT1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC13xx_GPT_USE_CT16B0) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_USE_CT16B0 TRUE
+#endif
+
+/**
+ * @brief GPT2 driver enable switch.
+ * @details If set to @p TRUE the support for GPT2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC13xx_GPT_USE_CT16B1) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_USE_CT16B1 TRUE
+#endif
+
+/**
+ * @brief GPT3 driver enable switch.
+ * @details If set to @p TRUE the support for GPT3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC13xx_GPT_USE_CT32B0) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_USE_CT32B0 TRUE
+#endif
+
+/**
+ * @brief GPT4 driver enable switch.
+ * @details If set to @p TRUE the support for GPT4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC13xx_GPT_USE_CT32B1) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_USE_CT32B1 TRUE
+#endif
+
+/**
+ * @brief GPT1 interrupt priority level setting.
+ */
+#if !defined(LPC13xx_GPT_CT16B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_CT16B0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT2 interrupt priority level setting.
+ */
+#if !defined(LPC13xx_GPT_CT16B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_CT16B1_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT3 interrupt priority level setting.
+ */
+#if !defined(LPC13xx_GPT_CT32B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_CT32B0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT4 interrupt priority level setting.
+ */
+#if !defined(LPC13xx_GPT_CT32B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_CT32B1_IRQ_PRIORITY 2
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !LPC13xx_GPT_USE_CT16B0 && !LPC13xx_GPT_USE_CT16B1 && \
+ !LPC13xx_GPT_USE_CT32B0 && !LPC13xx_GPT_USE_CT32B1
+#error "GPT driver activated but no CT peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint32_t gptcnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer base clock.
+ */
+ uint32_t clock;
+ /**
+ * @brief Pointer to the CTxxBy registers block.
+ */
+ LPC_TMR_TypeDef *tmr;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if LPC13xx_GPT_USE_CT16B0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD1;
+#endif
+
+#if LPC13xx_GPT_USE_CT16B1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD2;
+#endif
+
+#if LPC13xx_GPT_USE_CT32B0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD3;
+#endif
+
+#if LPC13xx_GPT_USE_CT32B1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD4;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC13xx/hal_lld.c b/os/hal/platforms/LPC13xx/hal_lld.c
index 5babb8d2d..da09ebf43 100644
--- a/os/hal/platforms/LPC13xx/hal_lld.c
+++ b/os/hal/platforms/LPC13xx/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/hal_lld.h b/os/hal/platforms/LPC13xx/hal_lld.h
index ff7445df9..0f6b1f611 100644
--- a/os/hal/platforms/LPC13xx/hal_lld.h
+++ b/os/hal/platforms/LPC13xx/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/pal_lld.c b/os/hal/platforms/LPC13xx/pal_lld.c
index f80faaa24..6a66f1ead 100644
--- a/os/hal/platforms/LPC13xx/pal_lld.c
+++ b/os/hal/platforms/LPC13xx/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/pal_lld.h b/os/hal/platforms/LPC13xx/pal_lld.h
index 2c5a1d118..bbf4db0e8 100644
--- a/os/hal/platforms/LPC13xx/pal_lld.h
+++ b/os/hal/platforms/LPC13xx/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/platform.dox b/os/hal/platforms/LPC13xx/platform.dox
index 7b1e09a60..00b3dd1ad 100644
--- a/os/hal/platforms/LPC13xx/platform.dox
+++ b/os/hal/platforms/LPC13xx/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -43,7 +44,25 @@
*/
/**
- * @defgroup LPC13xx_PAL LPC13xx GPIO Support
+ * @defgroup LPC13xx_GPT LPC13xx GPT Support
+ * @details The LPC13xx GPT driver uses the CTxxBy peripherals.
+ *
+ * @section lpc13xx_gpt_1 Supported HW resources
+ * - CT16B0.
+ * - CT16B1.
+ * - CT32B0.
+ * - CT32B1.
+ * .
+ * @section lpc13xx_gpt_2 LPC13xx GPT driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable CTxxBy interrupts priority level.
+ * .
+ * @ingroup LPC13xx
+ */
+
+/**
+ * @defgroup LPC13xx_PAL LPC13xx PAL Support
* @details The LPC13xx PAL driver uses the GPIO peripherals.
*
* @section lpc13xx_pal_1 Supported HW resources
@@ -79,7 +98,26 @@
*/
/**
- * @defgroup LPC13xx_SPI LPC13xx SSP Support
+ * @defgroup LPC13xx_SERIAL LPC13xx Serial Support
+ * @details The LPC13xx Serial driver uses the UART peripheral in a
+ * buffered, interrupt driven, implementation. The serial driver
+ * also takes advantage of the LPC13xx UARTs deep hardware buffers.
+ *
+ * @section lpc13xx_serial_1 Supported HW resources
+ * The serial driver can support any of the following hardware resources:
+ * - UART.
+ * .
+ * @section lpc13xx_serial_2 LPC13xx Serial driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Fully interrupt driven.
+ * - Programmable priority level.
+ * - Takes advantage of the input and output FIFOs.
+ * .
+ * @ingroup LPC13xx
+ */
+
+/**
+ * @defgroup LPC13xx_SPI LPC13xx SPI Support
* @details The SPI driver supports the LPC13xx SSP peripherals in an interrupt
* driven implementation.
* @note Being the SPI a fast peripheral, much care must be taken to
@@ -100,22 +138,3 @@
* .
* @ingroup LPC13xx
*/
-
-/**
- * @defgroup LPC13xx_SERIAL LPC13xx UART Support (buffered)
- * @details The LPC13xx Serial driver uses the UART peripheral in a
- * buffered, interrupt driven, implementation. The serial driver
- * also takes advantage of the LPC13xx UARTs deep hardware buffers.
- *
- * @section lpc13xx_serial_1 Supported HW resources
- * The serial driver can support any of the following hardware resources:
- * - UART.
- * .
- * @section lpc13xx_serial_2 LPC13xx Serial driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Fully interrupt driven.
- * - Programmable priority level.
- * - Takes advantage of the input and output FIFOs.
- * .
- * @ingroup LPC13xx
- */
diff --git a/os/hal/platforms/LPC13xx/platform.mk b/os/hal/platforms/LPC13xx/platform.mk
index 66c39058e..1171af7d7 100644
--- a/os/hal/platforms/LPC13xx/platform.mk
+++ b/os/hal/platforms/LPC13xx/platform.mk
@@ -1,5 +1,6 @@
# List of all the LPC13xx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC13xx/hal_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC13xx/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/pal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/serial_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/spi_lld.c
diff --git a/os/hal/platforms/LPC13xx/serial_lld.c b/os/hal/platforms/LPC13xx/serial_lld.c
index b0f53d97a..b4f7844c4 100644
--- a/os/hal/platforms/LPC13xx/serial_lld.c
+++ b/os/hal/platforms/LPC13xx/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/serial_lld.h b/os/hal/platforms/LPC13xx/serial_lld.h
index 3636f224a..e00f44de9 100644
--- a/os/hal/platforms/LPC13xx/serial_lld.h
+++ b/os/hal/platforms/LPC13xx/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/spi_lld.c b/os/hal/platforms/LPC13xx/spi_lld.c
index 1a98a7a15..ec207f19e 100644
--- a/os/hal/platforms/LPC13xx/spi_lld.c
+++ b/os/hal/platforms/LPC13xx/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -53,27 +54,27 @@ SPIDriver SPID1;
* @param[in] spip pointer to the @p SPIDriver object
*/
static void ssp_fifo_preload(SPIDriver *spip) {
- LPC_SSP_TypeDef *ssp = spip->spd_ssp;
- uint32_t n = spip->spd_txcnt > LPC13xx_SSP_FIFO_DEPTH ?
- LPC13xx_SSP_FIFO_DEPTH : spip->spd_txcnt;
+ LPC_SSP_TypeDef *ssp = spip->ssp;
+ uint32_t n = spip->txcnt > LPC13xx_SSP_FIFO_DEPTH ?
+ LPC13xx_SSP_FIFO_DEPTH : spip->txcnt;
while(((ssp->SR & SR_TNF) != 0) && (n > 0)) {
- if (spip->spd_txptr != NULL) {
+ if (spip->txptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
- const uint16_t *p = spip->spd_txptr;
+ const uint16_t *p = spip->txptr;
ssp->DR = *p++;
- spip->spd_txptr = p;
+ spip->txptr = p;
}
else {
- const uint8_t *p = spip->spd_txptr;
+ const uint8_t *p = spip->txptr;
ssp->DR = *p++;
- spip->spd_txptr = p;
+ spip->txptr = p;
}
}
else
ssp->DR = 0xFFFFFFFF;
n--;
- spip->spd_txcnt--;
+ spip->txcnt--;
}
}
@@ -83,7 +84,7 @@ static void ssp_fifo_preload(SPIDriver *spip) {
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_serve_interrupt(SPIDriver *spip) {
- LPC_SSP_TypeDef *ssp = spip->spd_ssp;
+ LPC_SSP_TypeDef *ssp = spip->ssp;
if ((ssp->MIS & MIS_ROR) != 0) {
/* The overflow condition should never happen because priority is given
@@ -92,22 +93,22 @@ static void spi_serve_interrupt(SPIDriver *spip) {
}
ssp->ICR = ICR_RT | ICR_ROR;
while ((ssp->SR & SR_RNE) != 0) {
- if (spip->spd_rxptr != NULL) {
+ if (spip->rxptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
- uint16_t *p = spip->spd_rxptr;
+ uint16_t *p = spip->rxptr;
*p++ = ssp->DR;
- spip->spd_rxptr = p;
+ spip->rxptr = p;
}
else {
- uint8_t *p = spip->spd_rxptr;
+ uint8_t *p = spip->rxptr;
*p++ = ssp->DR;
- spip->spd_rxptr = p;
+ spip->rxptr = p;
}
}
else
(void)ssp->DR;
- if (--spip->spd_rxcnt == 0) {
- chDbgAssert(spip->spd_txcnt == 0,
+ if (--spip->rxcnt == 0) {
+ chDbgAssert(spip->txcnt == 0,
"spi_serve_interrupt(), #1", "counter out of synch");
/* Stops the IRQ sources.*/
ssp->IMSC = 0;
@@ -118,7 +119,7 @@ static void spi_serve_interrupt(SPIDriver *spip) {
}
}
ssp_fifo_preload(spip);
- if (spip->spd_txcnt == 0)
+ if (spip->txcnt == 0)
ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
@@ -155,7 +156,7 @@ void spi_lld_init(void) {
#if LPC13xx_SPI_USE_SSP0
spiObjectInit(&SPID1);
- SPID1.spd_ssp = LPC_SSP;
+ SPID1.ssp = LPC_SSP;
LPC_IOCON->SCKLOC = LPC13xx_SPI_SCK0_SELECTOR;
#if LPC13xx_SPI_SCK0_SELECTOR == SCK0_IS_PIO0_10
LPC_IOCON->JTAG_TCK_PIO0_10 = 0xC2; /* SCK0 without resistors. */
@@ -178,7 +179,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
/* Clock activation.*/
#if LPC13xx_SPI_USE_SSP0
if (&SPID1 == spip) {
@@ -191,11 +192,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
}
/* Configuration.*/
- spip->spd_ssp->CR1 = 0;
- spip->spd_ssp->ICR = ICR_RT | ICR_ROR;
- spip->spd_ssp->CR0 = spip->spd_config->spc_cr0;
- spip->spd_ssp->CPSR = spip->spd_config->spc_cpsr;
- spip->spd_ssp->CR1 = CR1_SSE;
+ spip->ssp->CR1 = 0;
+ spip->ssp->ICR = ICR_RT | ICR_ROR;
+ spip->ssp->CR0 = spip->config->cr0;
+ spip->ssp->CPSR = spip->config->cpsr;
+ spip->ssp->CR1 = CR1_SSE;
}
/**
@@ -207,10 +208,10 @@ void spi_lld_start(SPIDriver *spip) {
*/
void spi_lld_stop(SPIDriver *spip) {
- if (spip->spd_state != SPI_STOP) {
- spip->spd_ssp->CR1 = 0;
- spip->spd_ssp->CR0 = 0;
- spip->spd_ssp->CPSR = 0;
+ if (spip->state != SPI_STOP) {
+ spip->ssp->CR1 = 0;
+ spip->ssp->CR0 = 0;
+ spip->ssp->CPSR = 0;
#if LPC13xx_SPI_USE_SSP0
if (&SPID1 == spip) {
LPC_SYSCON->PRESETCTRL &= ~1;
@@ -231,7 +232,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -244,7 +245,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -260,11 +261,11 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -285,11 +286,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -307,11 +308,11 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -329,11 +330,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -350,10 +351,10 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_ssp->DR = (uint32_t)frame;
- while ((spip->spd_ssp->SR & SR_RNE) == 0)
+ spip->ssp->DR = (uint32_t)frame;
+ while ((spip->ssp->SR & SR_RNE) == 0)
;
- return (uint16_t)spip->spd_ssp->DR;
+ return (uint16_t)spip->ssp->DR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/LPC13xx/spi_lld.h b/os/hal/platforms/LPC13xx/spi_lld.h
index 153ce815b..b5f63f40b 100644
--- a/os/hal/platforms/LPC13xx/spi_lld.h
+++ b/os/hal/platforms/LPC13xx/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -167,7 +168,7 @@
/**
* @brief SSP0 clock.
*/
-#define LPC13xx_SERIAL_SSP0_PCLK \
+#define LPC13xx_SERIAL_SSP0_PCLK \
(LPC13xx_MAINCLK / LPC13xx_SERIAL_SSP0CLKDIV)
/*===========================================================================*/
@@ -194,24 +195,24 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SSP CR0 initialization data.
*/
- uint16_t spc_cr0;
+ uint16_t cr0;
/**
* @brief SSP CPSR initialization data.
*/
- uint32_t spc_cpsr;
+ uint32_t cpsr;
} SPIConfig;
/**
@@ -221,25 +222,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -249,23 +250,23 @@ struct SPIDriver {
/**
* @brief Pointer to the SSP registers block.
*/
- LPC_SSP_TypeDef *spd_ssp;
+ LPC_SSP_TypeDef *ssp;
/**
* @brief Number of bytes yet to be received.
*/
- uint32_t spd_rxcnt;
+ uint32_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
- void *spd_rxptr;
+ void *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
- uint32_t spd_txcnt;
+ uint32_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
- const void *spd_txptr;
+ const void *txptr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/LPC214x/hal_lld.c b/os/hal/platforms/LPC214x/hal_lld.c
index 3f63e65c1..942b60777 100644
--- a/os/hal/platforms/LPC214x/hal_lld.c
+++ b/os/hal/platforms/LPC214x/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/hal_lld.h b/os/hal/platforms/LPC214x/hal_lld.h
index 54d91b881..70349ae30 100644
--- a/os/hal/platforms/LPC214x/hal_lld.h
+++ b/os/hal/platforms/LPC214x/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/lpc214x.h b/os/hal/platforms/LPC214x/lpc214x.h
index f2ddac376..b30996568 100644
--- a/os/hal/platforms/LPC214x/lpc214x.h
+++ b/os/hal/platforms/LPC214x/lpc214x.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/pal_lld.c b/os/hal/platforms/LPC214x/pal_lld.c
index 4d6f14fa9..2e503c631 100644
--- a/os/hal/platforms/LPC214x/pal_lld.c
+++ b/os/hal/platforms/LPC214x/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/pal_lld.h b/os/hal/platforms/LPC214x/pal_lld.h
index 8f9d3a457..1a45cd6a9 100644
--- a/os/hal/platforms/LPC214x/pal_lld.h
+++ b/os/hal/platforms/LPC214x/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -193,11 +194,10 @@ typedef FIO * ioportid_t;
*
* @notapi
*/
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- (port)->FIO_MASK = ~((mask) << (offset)); \
- (port)->FIO_PIN = (bits) << (offset); \
- (port)->FIO_MASK = 0; \
-}
+#define pal_lld_writegroup(port, mask, offset, bits) \
+ ((port)->FIO_MASK = ~((mask) << (offset)), \
+ (port)->FIO_PIN = (bits) << (offset), \
+ (port)->FIO_MASK = 0)
/**
* @brief Pads group mode setup.
@@ -235,9 +235,7 @@ typedef FIO * ioportid_t;
*
* @notapi
*/
-#define pal_lld_lpc214x_set_direction(port, dir) { \
- (port)->FIO_DIR = (dir); \
-}
+#define pal_lld_lpc214x_set_direction(port, dir) ((port)->FIO_DIR = (dir))
extern const PALConfig pal_default_config;
diff --git a/os/hal/platforms/LPC214x/platform.dox b/os/hal/platforms/LPC214x/platform.dox
index b07cce8c6..cfd9a4078 100644
--- a/os/hal/platforms/LPC214x/platform.dox
+++ b/os/hal/platforms/LPC214x/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -43,7 +44,7 @@
*/
/**
- * @defgroup LPC214x_PAL LPC214x FIO Support
+ * @defgroup LPC214x_PAL LPC214x PAL Support
* @details The LPC214x PAL driver uses the FIO peripherals.
*
* @section lpc214x_pal_1 Supported HW resources
@@ -74,26 +75,7 @@
*/
/**
- * @defgroup LPC214x_SPI LPC214x SSP Support
- * @details The SPI driver supports the LPC214x SSP peripheral in an interrupt
- * driven implementation.
- * @note Being the SPI a fast peripheral, much care must be taken to
- * not saturate the CPU bandwidth with an excessive IRQ rate. The
- * maximum transfer bit rate is likely limited by the IRQ
- * handling.
- *
- * @section lpc214x_spi_1 Supported HW resources
- * - SSP (SPI0).
- * .
- * @section lpc214x_spi_2 LPC214x SPI driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Programmable interrupt priority level.
- * .
- * @ingroup LPC214x
- */
-
-/**
- * @defgroup LPC214x_SERIAL LPC214x UART Support (buffered)
+ * @defgroup LPC214x_SERIAL LPC214x Serial Support
* @details The LPC214x Serial driver uses the UART peripherals in a
* buffered, interrupt driven, implementation. The serial driver
* also takes advantage of the LPC214x UARTs deep hardware buffers.
@@ -113,6 +95,25 @@
*/
/**
+ * @defgroup LPC214x_SPI LPC214x SPI Support
+ * @details The SPI driver supports the LPC214x SSP peripheral in an interrupt
+ * driven implementation.
+ * @note Being the SPI a fast peripheral, much care must be taken to
+ * not saturate the CPU bandwidth with an excessive IRQ rate. The
+ * maximum transfer bit rate is likely limited by the IRQ
+ * handling.
+ *
+ * @section lpc214x_spi_1 Supported HW resources
+ * - SSP (SPI0).
+ * .
+ * @section lpc214x_spi_2 LPC214x SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Programmable interrupt priority level.
+ * .
+ * @ingroup LPC214x
+ */
+
+/**
* @defgroup LPC214x_VIC LPC214x VIC Support
* @details This VIC helper driver is used by the other drivers in order to
* access the shared VIC resources in a consistent way.
diff --git a/os/hal/platforms/LPC214x/serial_lld.c b/os/hal/platforms/LPC214x/serial_lld.c
index cc6280d79..91c6d560a 100644
--- a/os/hal/platforms/LPC214x/serial_lld.c
+++ b/os/hal/platforms/LPC214x/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/serial_lld.h b/os/hal/platforms/LPC214x/serial_lld.h
index 4dac88f20..b51fb395d 100644
--- a/os/hal/platforms/LPC214x/serial_lld.h
+++ b/os/hal/platforms/LPC214x/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/spi_lld.c b/os/hal/platforms/LPC214x/spi_lld.c
index f920ecf87..e59087b25 100644
--- a/os/hal/platforms/LPC214x/spi_lld.c
+++ b/os/hal/platforms/LPC214x/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -53,21 +54,21 @@ SPIDriver SPID1;
* @param[in] spip pointer to the @p SPIDriver object
*/
static void ssp_fifo_preload(SPIDriver *spip) {
- SSP *ssp = spip->spd_ssp;
- uint32_t n = spip->spd_txcnt > LPC214x_SSP_FIFO_DEPTH ?
- LPC214x_SSP_FIFO_DEPTH : spip->spd_txcnt;
+ SSP *ssp = spip->ssp;
+ uint32_t n = spip->txcnt > LPC214x_SSP_FIFO_DEPTH ?
+ LPC214x_SSP_FIFO_DEPTH : spip->txcnt;
while(((ssp->SSP_SR & SR_TNF) != 0) && (n > 0)) {
- if (spip->spd_txptr != NULL) {
+ if (spip->txptr != NULL) {
if ((ssp->SSP_CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
- ssp->SSP_DR = *(uint16_t *)spip->spd_txptr++;
+ ssp->SSP_DR = *(uint16_t *)spip->txptr++;
else
- ssp->SSP_DR = *(uint8_t *)spip->spd_txptr++;
+ ssp->SSP_DR = *(uint8_t *)spip->txptr++;
}
else
ssp->SSP_DR = 0xFFFFFFFF;
n--;
- spip->spd_txcnt--;
+ spip->txcnt--;
}
}
@@ -80,7 +81,7 @@ __attribute__((noinline))
* @param[in] spip pointer to the @p SPIDriver object
*/
static void serve_interrupt(SPIDriver *spip) {
- SSP *ssp = spip->spd_ssp;
+ SSP *ssp = spip->ssp;
if ((ssp->SSP_MIS & MIS_ROR) != 0) {
/* The overflow condition should never happen because priority is given
@@ -89,16 +90,16 @@ static void serve_interrupt(SPIDriver *spip) {
}
ssp->SSP_ICR = ICR_RT | ICR_ROR;
while ((ssp->SSP_SR & SR_RNE) != 0) {
- if (spip->spd_rxptr != NULL) {
+ if (spip->rxptr != NULL) {
if ((ssp->SSP_CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
- *(uint16_t *)spip->spd_rxptr++ = ssp->SSP_DR;
+ *(uint16_t *)spip->rxptr++ = ssp->SSP_DR;
else
- *(uint8_t *)spip->spd_rxptr++ = ssp->SSP_DR;
+ *(uint8_t *)spip->rxptr++ = ssp->SSP_DR;
}
else
(void)ssp->SSP_DR;
- if (--spip->spd_rxcnt == 0) {
- chDbgAssert(spip->spd_txcnt == 0,
+ if (--spip->rxcnt == 0) {
+ chDbgAssert(spip->txcnt == 0,
"spi_serve_interrupt(), #1", "counter out of synch");
/* Stops the IRQ sources.*/
ssp->SSP_IMSC = 0;
@@ -109,7 +110,7 @@ static void serve_interrupt(SPIDriver *spip) {
}
}
ssp_fifo_preload(spip);
- if (spip->spd_txcnt == 0)
+ if (spip->txcnt == 0)
ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
@@ -147,7 +148,7 @@ void spi_lld_init(void) {
#if LPC214x_SPI_USE_SSP
spiObjectInit(&SPID1);
- SPID1.spd_ssp = SSPBase;
+ SPID1.ssp = SSPBase;
SetVICVector(SPI1IrqHandler, LPC214x_SPI_SSP_IRQ_PRIORITY, SOURCE_SPI1);
#endif
}
@@ -161,7 +162,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
/* Clock activation.*/
#if LPC214x_SPI_USE_SSP
if (&SPID1 == spip) {
@@ -171,14 +172,14 @@ void spi_lld_start(SPIDriver *spip) {
#endif
}
/* Configuration.*/
- spip->spd_ssp->SSP_CR1 = 0;
+ spip->ssp->SSP_CR1 = 0;
/* Emptying the receive FIFO, it happens to not be empty while debugging.*/
- while (spip->spd_ssp->SSP_SR & SR_RNE)
- (void) spip->spd_ssp->SSP_DR;
- spip->spd_ssp->SSP_ICR = ICR_RT | ICR_ROR;
- spip->spd_ssp->SSP_CR0 = spip->spd_config->spc_cr0;
- spip->spd_ssp->SSP_CPSR = spip->spd_config->spc_cpsr;
- spip->spd_ssp->SSP_CR1 = CR1_SSE;
+ while (spip->ssp->SSP_SR & SR_RNE)
+ (void) spip->ssp->SSP_DR;
+ spip->ssp->SSP_ICR = ICR_RT | ICR_ROR;
+ spip->ssp->SSP_CR0 = spip->config->cr0;
+ spip->ssp->SSP_CPSR = spip->config->cpsr;
+ spip->ssp->SSP_CR1 = CR1_SSE;
}
/**
@@ -190,10 +191,10 @@ void spi_lld_start(SPIDriver *spip) {
*/
void spi_lld_stop(SPIDriver *spip) {
- if (spip->spd_state != SPI_STOP) {
- spip->spd_ssp->SSP_CR1 = 0;
- spip->spd_ssp->SSP_CR0 = 0;
- spip->spd_ssp->SSP_CPSR = 0;
+ if (spip->state != SPI_STOP) {
+ spip->ssp->SSP_CR1 = 0;
+ spip->ssp->SSP_CR0 = 0;
+ spip->ssp->SSP_CPSR = 0;
#if LPC214x_SPI_USE_SSP
if (&SPID1 == spip) {
PCONP = (PCONP & PCALL) & ~PCSPI1;
@@ -212,7 +213,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -225,7 +226,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -241,11 +242,11 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -266,11 +267,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -288,11 +289,11 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -310,11 +311,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -331,10 +332,10 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_ssp->SSP_DR = (uint32_t)frame;
- while ((spip->spd_ssp->SSP_SR & SR_RNE) == 0)
+ spip->ssp->SSP_DR = (uint32_t)frame;
+ while ((spip->ssp->SSP_SR & SR_RNE) == 0)
;
- return (uint16_t)spip->spd_ssp->SSP_DR;
+ return (uint16_t)spip->ssp->SSP_DR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/LPC214x/spi_lld.h b/os/hal/platforms/LPC214x/spi_lld.h
index 0e9a3e782..e6a76bd8f 100644
--- a/os/hal/platforms/LPC214x/spi_lld.h
+++ b/os/hal/platforms/LPC214x/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -35,7 +36,7 @@
/*===========================================================================*/
/**
- * @brief Hardware FIFO depth.
+ * @brief Hardware FIFO depth.
*/
#define LPC214x_SSP_FIFO_DEPTH 8
@@ -99,24 +100,24 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SSP CR0 initialization data.
*/
- uint16_t spc_cr0;
+ uint16_t cr0;
/**
* @brief SSP CPSR initialization data.
*/
- uint32_t spc_cpsr;
+ uint32_t cpsr;
} SPIConfig;
/**
@@ -126,25 +127,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -154,23 +155,23 @@ struct SPIDriver {
/**
* @brief Pointer to the SSP registers block.
*/
- SSP *spd_ssp;
+ SSP *ssp;
/**
- * @brief Number of bytes yet to be received.
+ * @brief Number of bytes yet to be received.
*/
- uint32_t spd_rxcnt;
+ uint32_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
- void *spd_rxptr;
+ void *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
- uint32_t spd_txcnt;
+ uint32_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
- const void *spd_txptr;
+ const void *txptr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/LPC214x/vic.c b/os/hal/platforms/LPC214x/vic.c
index f1b75aa80..d613f3af7 100644
--- a/os/hal/platforms/LPC214x/vic.c
+++ b/os/hal/platforms/LPC214x/vic.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/vic.h b/os/hal/platforms/LPC214x/vic.h
index c0fd3ea3e..a6184ce97 100644
--- a/os/hal/platforms/LPC214x/vic.h
+++ b/os/hal/platforms/LPC214x/vic.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/MSP430/hal_lld.c b/os/hal/platforms/MSP430/hal_lld.c
index 0de477f43..0d3de0632 100644
--- a/os/hal/platforms/MSP430/hal_lld.c
+++ b/os/hal/platforms/MSP430/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/MSP430/hal_lld.h b/os/hal/platforms/MSP430/hal_lld.h
index 8f9ae59af..c2c23342f 100644
--- a/os/hal/platforms/MSP430/hal_lld.h
+++ b/os/hal/platforms/MSP430/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/MSP430/pal_lld.c b/os/hal/platforms/MSP430/pal_lld.c
index 5ea89254e..073a6af93 100644
--- a/os/hal/platforms/MSP430/pal_lld.c
+++ b/os/hal/platforms/MSP430/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/MSP430/pal_lld.h b/os/hal/platforms/MSP430/pal_lld.h
index ce5d47dce..31ee669a0 100644
--- a/os/hal/platforms/MSP430/pal_lld.h
+++ b/os/hal/platforms/MSP430/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -254,9 +255,7 @@ typedef msp430_ioport_t *ioportid_t;
*
* @notapi
*/
-#define pal_lld_writeport(port, bits) { \
- (port)->iop_common.out.reg_p = (bits); \
-}
+#define pal_lld_writeport(port, bits) ((port)->iop_common.out.reg_p = (bits))
/**
* @brief Pads group mode setup.
diff --git a/os/hal/platforms/MSP430/platform.dox b/os/hal/platforms/MSP430/platform.dox
index ec6bbd535..e326b90ef 100644
--- a/os/hal/platforms/MSP430/platform.dox
+++ b/os/hal/platforms/MSP430/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -41,7 +42,7 @@
*/
/**
- * @defgroup MSP430_PAL MSP430 PORT Support
+ * @defgroup MSP430_PAL MSP430 PAL Support
* @details The MSP430 PAL driver uses the PORT peripherals.
*
* @section msp430_pal_1 Supported HW resources
@@ -79,7 +80,7 @@
*/
/**
- * @defgroup MSP430_SERIAL MSP430 USART Support (buffered)
+ * @defgroup MSP430_SERIAL MSP430 Serial Support
* @details The MSP430 Serial driver uses the USART peripherals in a
* buffered, interrupt driven, implementation.
*
diff --git a/os/hal/platforms/MSP430/serial_lld.c b/os/hal/platforms/MSP430/serial_lld.c
index c6000d7a8..04a58a580 100644
--- a/os/hal/platforms/MSP430/serial_lld.c
+++ b/os/hal/platforms/MSP430/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -174,7 +175,7 @@ static void usart1_deinit(void) {
/**
* @brief USART0 TX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART0TX_VECTOR) {
msg_t b;
diff --git a/os/hal/platforms/MSP430/serial_lld.h b/os/hal/platforms/MSP430/serial_lld.h
index 42788abcf..9f965b2cd 100644
--- a/os/hal/platforms/MSP430/serial_lld.h
+++ b/os/hal/platforms/MSP430/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/console.c b/os/hal/platforms/Posix/console.c
index 737cf92bf..4f29b7900 100644
--- a/os/hal/platforms/Posix/console.c
+++ b/os/hal/platforms/Posix/console.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/console.h b/os/hal/platforms/Posix/console.h
index 3a30e6295..b803a5de7 100644
--- a/os/hal/platforms/Posix/console.h
+++ b/os/hal/platforms/Posix/console.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/hal_lld.c b/os/hal/platforms/Posix/hal_lld.c
index 6f1433586..1eb0af355 100644
--- a/os/hal/platforms/Posix/hal_lld.c
+++ b/os/hal/platforms/Posix/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/hal_lld.h b/os/hal/platforms/Posix/hal_lld.h
index 69892ce6f..192f7fefc 100644
--- a/os/hal/platforms/Posix/hal_lld.h
+++ b/os/hal/platforms/Posix/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/pal_lld.c b/os/hal/platforms/Posix/pal_lld.c
index 3dc664878..c3d88a8fb 100644
--- a/os/hal/platforms/Posix/pal_lld.c
+++ b/os/hal/platforms/Posix/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/pal_lld.h b/os/hal/platforms/Posix/pal_lld.h
index 3612e4498..1984c06f0 100644
--- a/os/hal/platforms/Posix/pal_lld.h
+++ b/os/hal/platforms/Posix/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -128,10 +129,9 @@ typedef sim_vio_port_t *ioportid_t;
*
* @param[in] config architecture-dependent ports configuration
*/
-#define pal_lld_init(config) { \
- vio_port_1 = (config)->VP1Data; \
- vio_port_2 = (config)->VP2Data; \
-}
+#define pal_lld_init(config) \
+ (vio_port_1 = (config)->VP1Data, \
+ vio_port_2 = (config)->VP2Data)
/**
* @brief Reads the physical I/O port states.
@@ -177,7 +177,7 @@ typedef sim_vio_port_t *ioportid_t;
* @param[in] mask group mask
* @param[in] mode group mode
*/
-#define pal_lld_setgroupmode(port, mask, mode) \
+#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
#if !defined(__DOXYGEN__)
diff --git a/os/hal/platforms/Posix/serial_lld.c b/os/hal/platforms/Posix/serial_lld.c
index 128f3e2fb..31be73825 100644
--- a/os/hal/platforms/Posix/serial_lld.c
+++ b/os/hal/platforms/Posix/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/serial_lld.h b/os/hal/platforms/Posix/serial_lld.h
index 282b68314..c0a28b819 100644
--- a/os/hal/platforms/Posix/serial_lld.h
+++ b/os/hal/platforms/Posix/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/SPC56x/hal_lld.c b/os/hal/platforms/SPC56x/hal_lld.c
index 4d4a10c41..afb93b73d 100644
--- a/os/hal/platforms/SPC56x/hal_lld.c
+++ b/os/hal/platforms/SPC56x/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/SPC56x/hal_lld.h b/os/hal/platforms/SPC56x/hal_lld.h
index c61089a38..48b12b19d 100644
--- a/os/hal/platforms/SPC56x/hal_lld.h
+++ b/os/hal/platforms/SPC56x/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -112,7 +113,7 @@
* @note The effective divider factor is this value plus one.
*/
#if !defined(SPC563_CLK_PREDIV) || defined(__DOXYGEN__)
-#define SPC563_CLK_PREDIV 0
+#define SPC563_CLK_PREDIV 2
#endif
/**
@@ -120,7 +121,7 @@
* @note Must be in range 32...96.
*/
#if !defined(SPC563_CLK_MFD) || defined(__DOXYGEN__)
-#define SPC563_CLK_MFD 40
+#define SPC563_CLK_MFD 80
#endif
/**
diff --git a/os/hal/platforms/SPC56x/platform.dox b/os/hal/platforms/SPC56x/platform.dox
index 3308731e9..18e4eaeb9 100644
--- a/os/hal/platforms/SPC56x/platform.dox
+++ b/os/hal/platforms/SPC56x/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -49,7 +50,7 @@
*/
/**
- * @defgroup SPC563_SERIAL SPC563Mx ESCI Support (buffered)
+ * @defgroup SPC563_SERIAL SPC563Mx Serial Support
* @details The SPC563Mx/MPC563xM Serial driver uses the ESCI peripherals
* in a buffered, interrupt driven, implementation.
*
diff --git a/os/hal/platforms/SPC56x/serial_lld.c b/os/hal/platforms/SPC56x/serial_lld.c
index afb23086a..fa31a211e 100644
--- a/os/hal/platforms/SPC56x/serial_lld.c
+++ b/os/hal/platforms/SPC56x/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/SPC56x/serial_lld.h b/os/hal/platforms/SPC56x/serial_lld.h
index 510e3298e..9d4c1bead 100644
--- a/os/hal/platforms/SPC56x/serial_lld.h
+++ b/os/hal/platforms/SPC56x/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/SPC56x/typedefs.h b/os/hal/platforms/SPC56x/typedefs.h
index b9611bf2c..1ee9e1f10 100644
--- a/os/hal/platforms/SPC56x/typedefs.h
+++ b/os/hal/platforms/SPC56x/typedefs.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/adc_lld.c b/os/hal/platforms/STM32/adc_lld.c
index 91fd8a6e8..8a8027e55 100644
--- a/os/hal/platforms/STM32/adc_lld.c
+++ b/os/hal/platforms/STM32/adc_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -47,39 +48,35 @@ ADCDriver ADCD1;
/* Driver local functions. */
/*===========================================================================*/
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
/**
- * @brief ADC1 DMA interrupt handler (channel 1).
+ * @brief Shared ADC DMA ISR service routine.
*
- * @isr
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
- uint32_t isr;
+static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
- CH_IRQ_PROLOGUE();
-
- isr = STM32_DMA1->ISR;
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
- if ((isr & DMA_ISR_TEIF1) != 0) {
- /* DMA error processing.*/
- STM32_ADC1_DMA_ERROR_HOOK();
+ /* DMA errors handling.*/
+#if defined(STM32_ADC_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_ADC_DMA_ERROR_HOOK(spip);
}
- if ((isr & DMA_ISR_HTIF1) != 0) {
+#else
+ (void)flags;
+#endif
+ if ((flags & DMA_ISR_HTIF1) != 0) {
/* Half transfer processing.*/
- _adc_isr_half_code(&ADCD1);
+ _adc_isr_half_code(adcp);
}
- if ((isr & DMA_ISR_TCIF1) != 0) {
+ if ((flags & DMA_ISR_TCIF1) != 0) {
/* Transfer complete processing.*/
- _adc_isr_full_code(&ADCD1);
+ _adc_isr_full_code(adcp);
}
-
- CH_IRQ_EPILOGUE();
}
-#endif
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
@@ -93,15 +90,11 @@ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
void adc_lld_init(void) {
#if STM32_ADC_USE_ADC1
- /* ADC reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB2RSTR = RCC_APB2RSTR_ADC1RST;
- RCC->APB2RSTR = 0;
-
/* Driver initialization.*/
adcObjectInit(&ADCD1);
- ADCD1.ad_adc = ADC1;
- ADCD1.ad_dmachp = STM32_DMA1_CH1;
- ADCD1.ad_dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) |
+ ADCD1.adc = ADC1;
+ ADCD1.dmachp = STM32_DMA1_CH1;
+ ADCD1.dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) |
DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 |
DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE;
@@ -136,21 +129,22 @@ void adc_lld_init(void) {
void adc_lld_start(ADCDriver *adcp) {
/* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->ad_state == ADC_STOP) {
+ if (adcp->state == ADC_STOP) {
#if STM32_ADC_USE_ADC1
if (&ADCD1 == adcp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_1,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp);
NVICEnableVector(DMA1_Channel1_IRQn,
CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY));
- dmaChannelSetPeripheral(adcp->ad_dmachp, &ADC1->DR);
+ dmaChannelSetPeripheral(adcp->dmachp, &ADC1->DR);
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
}
#endif
/* ADC setup, the calibration procedure has already been performed
during initialization.*/
- adcp->ad_adc->CR1 = ADC_CR1_SCAN;
- adcp->ad_adc->CR2 = 0;
+ adcp->adc->CR1 = ADC_CR1_SCAN;
+ adcp->adc->CR2 = 0;
}
}
@@ -164,13 +158,13 @@ void adc_lld_start(ADCDriver *adcp) {
void adc_lld_stop(ADCDriver *adcp) {
/* If in ready state then disables the ADC clock.*/
- if (adcp->ad_state == ADC_READY) {
+ if (adcp->state == ADC_READY) {
#if STM32_ADC_USE_ADC1
if (&ADCD1 == adcp) {
ADC1->CR1 = 0;
ADC1->CR2 = 0;
NVICDisableVector(DMA1_Channel1_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1);
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
}
#endif
@@ -186,34 +180,34 @@ void adc_lld_stop(ADCDriver *adcp) {
*/
void adc_lld_start_conversion(ADCDriver *adcp) {
uint32_t ccr, n;
- const ADCConversionGroup *grpp = adcp->ad_grpp;
+ const ADCConversionGroup *grpp = adcp->grpp;
/* DMA setup.*/
- ccr = adcp->ad_dmaccr;
- if (grpp->acg_circular)
+ ccr = adcp->dmaccr;
+ if (grpp->circular)
ccr |= DMA_CCR1_CIRC;
- if (adcp->ad_depth > 1) {
+ if (adcp->depth > 1) {
/* If the buffer depth is greater than one then the half transfer interrupt
interrupt is enabled in order to allows streaming processing.*/
ccr |= DMA_CCR1_HTIE;
- n = (uint32_t)grpp->acg_num_channels * (uint32_t)adcp->ad_depth;
+ n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth;
}
else
- n = (uint32_t)grpp->acg_num_channels;
- dmaChannelSetup(adcp->ad_dmachp, n, adcp->ad_samples, ccr);
+ n = (uint32_t)grpp->num_channels;
+ dmaChannelSetup(adcp->dmachp, n, adcp->samples, ccr);
/* ADC setup.*/
- adcp->ad_adc->CR1 = grpp->acg_cr1 | ADC_CR1_SCAN;
- adcp->ad_adc->CR2 = grpp->acg_cr2 | ADC_CR2_DMA |
+ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN;
+ adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA |
ADC_CR2_CONT | ADC_CR2_ADON;
- adcp->ad_adc->SMPR1 = grpp->acg_smpr1;
- adcp->ad_adc->SMPR2 = grpp->acg_smpr2;
- adcp->ad_adc->SQR1 = grpp->acg_sqr1;
- adcp->ad_adc->SQR2 = grpp->acg_sqr2;
- adcp->ad_adc->SQR3 = grpp->acg_sqr3;
+ adcp->adc->SMPR1 = grpp->smpr1;
+ adcp->adc->SMPR2 = grpp->smpr2;
+ adcp->adc->SQR1 = grpp->sqr1;
+ adcp->adc->SQR2 = grpp->sqr2;
+ adcp->adc->SQR3 = grpp->sqr3;
/* ADC start by writing ADC_CR2_ADON a second time.*/
- adcp->ad_adc->CR2 = grpp->acg_cr2 | ADC_CR2_DMA |
+ adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA |
ADC_CR2_CONT | ADC_CR2_ADON;
}
@@ -226,8 +220,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
*/
void adc_lld_stop_conversion(ADCDriver *adcp) {
- dmaChannelDisable(adcp->ad_dmachp);
- adcp->ad_adc->CR2 = 0;
+ dmaChannelDisable(adcp->dmachp);
+ adcp->adc->CR2 = 0;
}
#endif /* HAL_USE_ADC */
diff --git a/os/hal/platforms/STM32/adc_lld.h b/os/hal/platforms/STM32/adc_lld.h
index 876560fca..ce93e60ed 100644
--- a/os/hal/platforms/STM32/adc_lld.h
+++ b/os/hal/platforms/STM32/adc_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -82,7 +83,7 @@
* @brief ADC1 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 3
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
#endif
/**
@@ -93,12 +94,12 @@
#endif
/**
- * @brief ADC1 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @brief ADC DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
*/
-#if !defined(STM32_ADC1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
#endif
/*===========================================================================*/
@@ -113,6 +114,10 @@
#error "ADC driver activated but no ADC peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -154,56 +159,56 @@ typedef struct {
/**
* @brief Enables the circular buffer mode for the group.
*/
- bool_t acg_circular;
+ bool_t circular;
/**
* @brief Number of the analog channels belonging to the conversion group.
*/
- adc_channels_num_t acg_num_channels;
+ adc_channels_num_t num_channels;
/**
* @brief Callback function associated to the group or @p NULL.
*/
- adccallback_t acg_endcb;
+ adccallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief ADC CR1 register initialization data.
* @note All the required bits must be defined into this field except
* @p ADC_CR1_SCAN that is enforced inside the driver.
*/
- uint32_t acg_cr1;
+ uint32_t cr1;
/**
* @brief ADC CR2 register initialization data.
* @note All the required bits must be defined into this field except
* @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are
* enforced inside the driver.
*/
- uint32_t acg_cr2;
+ uint32_t cr2;
/**
* @brief ADC SMPR1 register initialization data.
* @details In this field must be specified the sample times for channels
* 10...17.
*/
- uint32_t acg_smpr1;
+ uint32_t smpr1;
/**
* @brief ADC SMPR2 register initialization data.
* @details In this field must be specified the sample times for channels
* 0...9.
*/
- uint32_t acg_smpr2;
+ uint32_t smpr2;
/**
* @brief ADC SQR1 register initialization data.
* @details Conversion group sequence 13...16 + sequence length.
*/
- uint32_t acg_sqr1;
+ uint32_t sqr1;
/**
* @brief ADC SQR2 register initialization data.
* @details Conversion group sequence 7...12.
*/
- uint32_t acg_sqr2;
+ uint32_t sqr2;
/**
* @brief ADC SQR3 register initialization data.
* @details Conversion group sequence 0...6.
*/
- uint32_t acg_sqr3;
+ uint32_t sqr3;
} ADCConversionGroup;
/**
@@ -221,37 +226,37 @@ struct ADCDriver {
/**
* @brief Driver state.
*/
- adcstate_t ad_state;
+ adcstate_t state;
/**
* @brief Current configuration data.
*/
- const ADCConfig *ad_config;
+ const ADCConfig *config;
/**
* @brief Current samples buffer pointer or @p NULL.
*/
- adcsample_t *ad_samples;
+ adcsample_t *samples;
/**
* @brief Current samples buffer depth or @p 0.
*/
- size_t ad_depth;
+ size_t depth;
/**
* @brief Current conversion group pointer or @p NULL.
*/
- const ADCConversionGroup *ad_grpp;
+ const ADCConversionGroup *grpp;
#if ADC_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *ad_thread;
+ Thread *thread;
#endif
#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the peripheral.
*/
- Mutex ad_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore ad_semaphore;
+ Semaphore semaphore;
#endif
#endif /* ADC_USE_MUTUAL_EXCLUSION */
#if defined(ADC_DRIVER_EXT_FIELDS)
@@ -261,15 +266,15 @@ struct ADCDriver {
/**
* @brief Pointer to the ADCx registers block.
*/
- ADC_TypeDef *ad_adc;
+ ADC_TypeDef *adc;
/**
* @brief Pointer to the DMA registers block.
*/
- stm32_dma_channel_t *ad_dmachp;
+ stm32_dma_channel_t *dmachp;
/**
* @brief DMA CCR register bit mask.
*/
- uint32_t ad_dmaccr;
+ uint32_t dmaccr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/can_lld.c b/os/hal/platforms/STM32/can_lld.c
index 24a944c0f..e180a87cb 100644
--- a/os/hal/platforms/STM32/can_lld.c
+++ b/os/hal/platforms/STM32/can_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -63,9 +64,9 @@ CH_IRQ_HANDLER(CAN1_TX_IRQHandler) {
/* No more events until a message is transmitted.*/
CAN1->TSR = CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2;
chSysLockFromIsr();
- while (chSemGetCounterI(&CAND1.cd_txsem) < 0)
- chSemSignalI(&CAND1.cd_txsem);
- chEvtBroadcastI(&CAND1.cd_txempty_event);
+ while (chSemGetCounterI(&CAND1.txsem) < 0)
+ chSemSignalI(&CAND1.txsem);
+ chEvtBroadcastI(&CAND1.txempty_event);
chSysUnlockFromIsr();
CH_IRQ_EPILOGUE();
@@ -86,9 +87,9 @@ CH_IRQ_HANDLER(CAN1_RX0_IRQHandler) {
/* No more receive events until the queue 0 has been emptied.*/
CAN1->IER &= ~CAN_IER_FMPIE0;
chSysLockFromIsr();
- while (chSemGetCounterI(&CAND1.cd_rxsem) < 0)
- chSemSignalI(&CAND1.cd_rxsem);
- chEvtBroadcastI(&CAND1.cd_rxfull_event);
+ while (chSemGetCounterI(&CAND1.rxsem) < 0)
+ chSemSignalI(&CAND1.rxsem);
+ chEvtBroadcastI(&CAND1.rxfull_event);
chSysUnlockFromIsr();
}
if ((rf0r & CAN_RF0R_FOVR0) > 0) {
@@ -96,7 +97,7 @@ CH_IRQ_HANDLER(CAN1_RX0_IRQHandler) {
CAN1->RF0R = CAN_RF0R_FOVR0;
canAddFlagsI(&CAND1, CAN_OVERFLOW_ERROR);
chSysLockFromIsr();
- chEvtBroadcastI(&CAND1.cd_error_event);
+ chEvtBroadcastI(&CAND1.error_event);
chSysUnlockFromIsr();
}
@@ -132,7 +133,7 @@ CH_IRQ_HANDLER(CAN1_SCE_IRQHandler) {
/* Wakeup event.*/
if (msr & CAN_MSR_WKUI) {
chSysLockFromIsr();
- chEvtBroadcastI(&CAND1.cd_wakeup_event);
+ chEvtBroadcastI(&CAND1.wakeup_event);
chSysUnlockFromIsr();
}
/* Error event.*/
@@ -146,7 +147,7 @@ CH_IRQ_HANDLER(CAN1_SCE_IRQHandler) {
flags |= CAN_FRAMING_ERROR;
chSysLockFromIsr();
canAddFlagsI(&CAND1, flags | (canstatus_t)(flags < 16));
- chEvtBroadcastI(&CAND1.cd_error_event);
+ chEvtBroadcastI(&CAND1.error_event);
chSysUnlockFromIsr();
}
@@ -165,13 +166,9 @@ CH_IRQ_HANDLER(CAN1_SCE_IRQHandler) {
void can_lld_init(void) {
#if STM32_CAN_USE_CAN1
- /* CAN reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_CAN1RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
canObjectInit(&CAND1);
- CAND1.cd_can = CAN1;
+ CAND1.can = CAN1;
#endif
}
@@ -200,37 +197,37 @@ void can_lld_start(CANDriver *canp) {
#endif
/* Entering initialization mode. */
- canp->cd_state = CAN_STARTING;
- canp->cd_can->MCR = CAN_MCR_INRQ;
- while ((canp->cd_can->MSR & CAN_MSR_INAK) == 0)
+ canp->state = CAN_STARTING;
+ canp->can->MCR = CAN_MCR_INRQ;
+ while ((canp->can->MSR & CAN_MSR_INAK) == 0)
chThdSleepS(1);
/* BTR initialization.*/
- canp->cd_can->BTR = canp->cd_config->cc_btr;
+ canp->can->BTR = canp->config->btr;
/* MCR initialization.*/
- canp->cd_can->MCR = canp->cd_config->cc_mcr;
+ canp->can->MCR = canp->config->mcr;
/* Filters initialization.*/
- canp->cd_can->FMR |= CAN_FMR_FINIT;
- if (canp->cd_config->cc_num > 0) {
+ canp->can->FMR |= CAN_FMR_FINIT;
+ if (canp->config->num > 0) {
uint32_t i, fmask;
CAN_FilterRegister_TypeDef *cfp;
- canp->cd_can->FA1R = 0;
- canp->cd_can->FM1R = 0;
- canp->cd_can->FS1R = 0;
- canp->cd_can->FFA1R = 0;
- cfp = canp->cd_can->sFilterRegister;
+ canp->can->FA1R = 0;
+ canp->can->FM1R = 0;
+ canp->can->FS1R = 0;
+ canp->can->FFA1R = 0;
+ cfp = canp->can->sFilterRegister;
fmask = 1;
for (i = 0; i < CAN_MAX_FILTERS; i++) {
- if (i < canp->cd_config->cc_num) {
- if (canp->cd_config->cc_filters[i].cf_mode)
- canp->cd_can->FM1R |= fmask;
- if (canp->cd_config->cc_filters[i].cf_scale)
- canp->cd_can->FS1R |= fmask;
- if (canp->cd_config->cc_filters[i].cf_assignment)
- canp->cd_can->FFA1R |= fmask;
- cfp->FR1 = canp->cd_config->cc_filters[i].cf_register1;
- cfp->FR2 = canp->cd_config->cc_filters[i].cf_register2;
- canp->cd_can->FA1R |= fmask;
+ if (i < canp->config->num) {
+ if (canp->config->filters[i].mode)
+ canp->can->FM1R |= fmask;
+ if (canp->config->filters[i].scale)
+ canp->can->FS1R |= fmask;
+ if (canp->config->filters[i].assignment)
+ canp->can->FFA1R |= fmask;
+ cfp->FR1 = canp->config->filters[i].register1;
+ cfp->FR2 = canp->config->filters[i].register2;
+ canp->can->FA1R |= fmask;
}
else {
cfp->FR1 = 0;
@@ -245,16 +242,16 @@ void can_lld_start(CANDriver *canp) {
}
else {
/* Setup a default filter.*/
- canp->cd_can->sFilterRegister[0].FR1 = 0;
- canp->cd_can->sFilterRegister[0].FR2 = 0;
- canp->cd_can->FM1R = 0;
- canp->cd_can->FFA1R = 0;
- canp->cd_can->FS1R = 1;
- canp->cd_can->FA1R = 1;
+ canp->can->sFilterRegister[0].FR1 = 0;
+ canp->can->sFilterRegister[0].FR2 = 0;
+ canp->can->FM1R = 0;
+ canp->can->FFA1R = 0;
+ canp->can->FS1R = 1;
+ canp->can->FA1R = 1;
}
- canp->cd_can->FMR &= ~CAN_FMR_FINIT;
+ canp->can->FMR &= ~CAN_FMR_FINIT;
/* Interrupt sources initialization.*/
- canp->cd_can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
+ canp->can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
CAN_IER_WKUIE | CAN_IER_ERRIE | CAN_IER_LECIE |
CAN_IER_BOFIE | CAN_IER_EPVIE | CAN_IER_EWGIE |
CAN_IER_FOVIE0 | CAN_IER_FOVIE1;
@@ -270,7 +267,7 @@ void can_lld_start(CANDriver *canp) {
void can_lld_stop(CANDriver *canp) {
/* If in ready state then disables the CAN peripheral.*/
- if (canp->cd_state == CAN_READY) {
+ if (canp->state == CAN_READY) {
#if STM32_CAN_USE_CAN1
if (&CAND1 == canp) {
CAN1->MCR = 0x00010002; /* Register reset value. */
@@ -298,7 +295,7 @@ void can_lld_stop(CANDriver *canp) {
*/
bool_t can_lld_can_transmit(CANDriver *canp) {
- return (canp->cd_can->TSR & CAN_TSR_TME) != 0;
+ return (canp->can->TSR & CAN_TSR_TME) != 0;
}
/**
@@ -314,18 +311,18 @@ void can_lld_transmit(CANDriver *canp, const CANTxFrame *ctfp) {
CAN_TxMailBox_TypeDef *tmbp;
/* Pointer to a free transmission mailbox.*/
- tmbp = &canp->cd_can->sTxMailBox[(canp->cd_can->TSR & CAN_TSR_CODE) >> 24];
+ tmbp = &canp->can->sTxMailBox[(canp->can->TSR & CAN_TSR_CODE) >> 24];
/* Preparing the message.*/
- if (ctfp->cf_IDE)
- tir = ((uint32_t)ctfp->cf_EID << 3) | ((uint32_t)ctfp->cf_RTR << 1) |
+ if (ctfp->IDE)
+ tir = ((uint32_t)ctfp->EID << 3) | ((uint32_t)ctfp->RTR << 1) |
CAN_TI0R_IDE;
else
- tir = ((uint32_t)ctfp->cf_SID << 21) | ((uint32_t)ctfp->cf_RTR << 1);
- tmbp->TDTR = ctfp->cf_DLC;
- tmbp->TDLR = ctfp->cf_data32[0];
- tmbp->TDHR = ctfp->cf_data32[1];
- tmbp->TIR = tir | CAN_TI0R_TXRQ;
+ tir = ((uint32_t)ctfp->SID << 21) | ((uint32_t)ctfp->RTR << 1);
+ tmbp->TDTR = ctfp->DLC;
+ tmbp->TDLR = ctfp->data32[0];
+ tmbp->TDHR = ctfp->data32[1];
+ tmbp->TIR = tir | CAN_TI0R_TXRQ;
}
/**
@@ -341,7 +338,7 @@ void can_lld_transmit(CANDriver *canp, const CANTxFrame *ctfp) {
*/
bool_t can_lld_can_receive(CANDriver *canp) {
- return (canp->cd_can->RF0R & CAN_RF0R_FMP0) > 0;
+ return (canp->can->RF0R & CAN_RF0R_FMP0) > 0;
}
/**
@@ -356,27 +353,27 @@ void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
uint32_t r;
/* Fetches the message.*/
- r = canp->cd_can->sFIFOMailBox[0].RIR;
- crfp->cf_RTR = (r & CAN_RI0R_RTR) >> 1;
- crfp->cf_IDE = (r & CAN_RI0R_IDE) >> 2;
- if (crfp->cf_IDE)
- crfp->cf_EID = r >> 3;
+ r = canp->can->sFIFOMailBox[0].RIR;
+ crfp->RTR = (r & CAN_RI0R_RTR) >> 1;
+ crfp->IDE = (r & CAN_RI0R_IDE) >> 2;
+ if (crfp->IDE)
+ crfp->EID = r >> 3;
else
- crfp->cf_SID = r >> 21;
- r = canp->cd_can->sFIFOMailBox[0].RDTR;
- crfp->cf_DLC = r & CAN_RDT0R_DLC;
- crfp->cf_FMI = (uint8_t)(r >> 8);
- crfp->cf_TIME = (uint16_t)(r >> 16);
- crfp->cf_data32[0] = canp->cd_can->sFIFOMailBox[0].RDLR;
- crfp->cf_data32[1] = canp->cd_can->sFIFOMailBox[0].RDHR;
+ crfp->SID = r >> 21;
+ r = canp->can->sFIFOMailBox[0].RDTR;
+ crfp->DLC = r & CAN_RDT0R_DLC;
+ crfp->FMI = (uint8_t)(r >> 8);
+ crfp->TIME = (uint16_t)(r >> 16);
+ crfp->data32[0] = canp->can->sFIFOMailBox[0].RDLR;
+ crfp->data32[1] = canp->can->sFIFOMailBox[0].RDHR;
/* Releases the mailbox.*/
- canp->cd_can->RF0R = CAN_RF0R_RFOM0;
+ canp->can->RF0R = CAN_RF0R_RFOM0;
/* If the queue is empty re-enables the interrupt in order to generate
events again.*/
- if ((canp->cd_can->RF0R & CAN_RF0R_FMP0) == 0)
- canp->cd_can->IER |= CAN_IER_FMPIE0;
+ if ((canp->can->RF0R & CAN_RF0R_FMP0) == 0)
+ canp->can->IER |= CAN_IER_FMPIE0;
}
#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
@@ -389,7 +386,7 @@ void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
*/
void can_lld_sleep(CANDriver *canp) {
- canp->cd_can->MCR |= CAN_MCR_SLEEP;
+ canp->can->MCR |= CAN_MCR_SLEEP;
}
/**
@@ -401,7 +398,7 @@ void can_lld_sleep(CANDriver *canp) {
*/
void can_lld_wakeup(CANDriver *canp) {
- canp->cd_can->MCR &= ~CAN_MCR_SLEEP;
+ canp->can->MCR &= ~CAN_MCR_SLEEP;
}
#endif /* CAN_USE_SLEEP_MODE */
diff --git a/os/hal/platforms/STM32/can_lld.h b/os/hal/platforms/STM32/can_lld.h
index 0d4c9b615..a9a086e5b 100644
--- a/os/hal/platforms/STM32/can_lld.h
+++ b/os/hal/platforms/STM32/can_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -121,22 +122,22 @@ typedef uint32_t canstatus_t;
*/
typedef struct {
struct {
- uint8_t cf_DLC:4; /**< @brief Data length. */
- uint8_t cf_RTR:1; /**< @brief Frame type. */
- uint8_t cf_IDE:1; /**< @brief Identifier type. */
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
};
union {
struct {
- uint32_t cf_SID:11; /**< @brief Standard identifier.*/
+ uint32_t SID:11; /**< @brief Standard identifier.*/
};
struct {
- uint32_t cf_EID:29; /**< @brief Extended identifier.*/
+ uint32_t EID:29; /**< @brief Extended identifier.*/
};
};
union {
- uint8_t cf_data8[8]; /**< @brief Frame data. */
- uint16_t cf_data16[4]; /**< @brief Frame data. */
- uint32_t cf_data32[2]; /**< @brief Frame data. */
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
};
} CANTxFrame;
@@ -147,26 +148,26 @@ typedef struct {
*/
typedef struct {
struct {
- uint8_t cf_FMI; /**< @brief Filter id. */
- uint16_t cf_TIME; /**< @brief Time stamp. */
+ uint8_t FMI; /**< @brief Filter id. */
+ uint16_t TIME; /**< @brief Time stamp. */
};
struct {
- uint8_t cf_DLC:4; /**< @brief Data length. */
- uint8_t cf_RTR:1; /**< @brief Frame type. */
- uint8_t cf_IDE:1; /**< @brief Identifier type. */
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
};
union {
struct {
- uint32_t cf_SID:11; /**< @brief Standard identifier.*/
+ uint32_t SID:11; /**< @brief Standard identifier.*/
};
struct {
- uint32_t cf_EID:29; /**< @brief Extended identifier.*/
+ uint32_t EID:29; /**< @brief Extended identifier.*/
};
};
union {
- uint8_t cf_data8[8]; /**< @brief Frame data. */
- uint16_t cf_data16[4]; /**< @brief Frame data. */
- uint32_t cf_data32[2]; /**< @brief Frame data. */
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
};
} CANRxFrame;
@@ -180,27 +181,27 @@ typedef struct {
* @note This bit represent the CAN_FM1R register bit associated to this
* filter (0=mask mode, 1=list mode).
*/
- uint32_t cf_mode:1;
+ uint32_t mode:1;
/**
* @brief Filter sclae.
* @note This bit represent the CAN_FS1R register bit associated to this
* filter (0=16 bits mode, 1=32 bits mode).
*/
- uint32_t cf_scale:1;
+ uint32_t scale:1;
/**
* @brief Filter mode.
* @note This bit represent the CAN_FFA1R register bit associated to this
* filter, must be set to zero in this version of the driver.
*/
- uint32_t cf_assignment:1;
+ uint32_t assignment:1;
/**
* @brief Filter register 1 (identifier).
*/
- uint32_t cf_register1;
+ uint32_t register1;
/**
- * @brief Filter register 2 (mask/identifier depending on cf_mode=0/1).
+ * @brief Filter register 2 (mask/identifier depending on mode=0/1).
*/
- uint32_t cf_register2;
+ uint32_t register2;
} CANFilter;
/**
@@ -212,25 +213,25 @@ typedef struct {
* @note Some bits in this register are enforced by the driver regardless
* their status in this field.
*/
- uint32_t cc_mcr;
+ uint32_t mcr;
/**
* @brief CAN BTR register initialization data.
* @note Some bits in this register are enforced by the driver regardless
* their status in this field.
*/
- uint32_t cc_btr;
+ uint32_t btr;
/**
* @brief Number of elements into the filters array.
* @note By setting this field to zero a default filter is enabled that
* allows all frames, this should be adequate for simple applications.
*/
- uint32_t cc_num;
+ uint32_t num;
/**
* @brief Pointer to an array of @p CANFilter structures.
- * @note This field can be set to @p NULL if the field @p cc_num is set to
+ * @note This field can be set to @p NULL if the field @p num is set to
* zero.
*/
- const CANFilter *cc_filters;
+ const CANFilter *filters;
} CANConfig;
/**
@@ -240,19 +241,19 @@ typedef struct {
/**
* @brief Driver state.
*/
- canstate_t cd_state;
+ canstate_t state;
/**
* @brief Current configuration data.
*/
- const CANConfig *cd_config;
+ const CANConfig *config;
/**
* @brief Transmission queue semaphore.
*/
- Semaphore cd_txsem;
+ Semaphore txsem;
/**
* @brief Receive queue semaphore.
*/
- Semaphore cd_rxsem;
+ Semaphore rxsem;
/**
* @brief One or more frames become available.
* @note After broadcasting this event it will not be broadcasted again
@@ -262,34 +263,34 @@ typedef struct {
* invoking @p chReceive() when listening to this event. This behavior
* minimizes the interrupt served by the system because CAN traffic.
*/
- EventSource cd_rxfull_event;
+ EventSource rxfull_event;
/**
* @brief One or more transmission slots become available.
*/
- EventSource cd_txempty_event;
+ EventSource txempty_event;
/**
* @brief A CAN bus error happened.
*/
- EventSource cd_error_event;
+ EventSource error_event;
/**
* @brief Error flags set when an error event is broadcasted.
*/
- canstatus_t cd_status;
+ canstatus_t status;
#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
/**
* @brief Entering sleep state event.
*/
- EventSource cd_sleep_event;
+ EventSource sleep_event;
/**
* @brief Exiting sleep state event.
*/
- EventSource cd_wakeup_event;
+ EventSource wakeup_event;
#endif /* CAN_USE_SLEEP_MODE */
/* End of the mandatory fields.*/
/**
* @brief Pointer to the CAN registers.
*/
- CAN_TypeDef *cd_can;
+ CAN_TypeDef *can;
} CANDriver;
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/core_cm3.h b/os/hal/platforms/STM32/core_cm3.h
index 5c75ec859..387221bc6 100644
--- a/os/hal/platforms/STM32/core_cm3.h
+++ b/os/hal/platforms/STM32/core_cm3.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/gpt_lld.c b/os/hal/platforms/STM32/gpt_lld.c
new file mode 100644
index 000000000..8419cad68
--- /dev/null
+++ b/os/hal/platforms/STM32/gpt_lld.c
@@ -0,0 +1,417 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/gpt_lld.c
+ * @brief STM32 GPT subsystem low level driver source.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/* There are differences in vector names in the ST header for devices
+ including TIM15, TIM16, TIM17.*/
+#if STM32_HAS_TIM15
+#define TIM1_BRK_IRQn TIM1_BRK_TIM15_IRQn
+#endif
+#if STM32_HAS_TIM16
+#define TIM1_UP_IRQn TIM1_UP_TIM16_IRQn
+#endif
+#if STM32_HAS_TIM17
+#define TIM1_TRG_COM_IRQn TIM1_TRG_COM_TIM17_IRQn
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief GPTD1 driver identifier.
+ * @note The driver GPTD1 allocates the complex timer TIM1 when enabled.
+ */
+#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__)
+GPTDriver GPTD1;
+#endif
+
+/**
+ * @brief GPTD2 driver identifier.
+ * @note The driver GPTD2 allocates the timer TIM2 when enabled.
+ */
+#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__)
+GPTDriver GPTD2;
+#endif
+
+/**
+ * @brief GPTD3 driver identifier.
+ * @note The driver GPTD3 allocates the timer TIM3 when enabled.
+ */
+#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__)
+GPTDriver GPTD3;
+#endif
+
+/**
+ * @brief GPTD4 driver identifier.
+ * @note The driver GPTD4 allocates the timer TIM4 when enabled.
+ */
+#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__)
+GPTDriver GPTD4;
+#endif
+
+/**
+ * @brief GPTD5 driver identifier.
+ * @note The driver GPTD5 allocates the timer TIM5 when enabled.
+ */
+#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__)
+GPTDriver GPTD5;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
+
+ gptp->tim->SR = 0;
+ if (gptp->state == GPT_ONESHOT) {
+ gptp->state = GPT_READY; /* Back in GPT_READY state. */
+ gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
+ }
+ gptp->config->callback(gptp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_GPT_USE_TIM1
+/**
+ * @brief TIM2 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM1_UP_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM1 */
+
+#if STM32_GPT_USE_TIM2
+/**
+ * @brief TIM2 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM2_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM2 */
+
+#if STM32_GPT_USE_TIM3
+/**
+ * @brief TIM3 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM3_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM3 */
+
+#if STM32_GPT_USE_TIM4
+/**
+ * @brief TIM4 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM4_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM4 */
+
+#if STM32_GPT_USE_TIM5
+/**
+ * @brief TIM5 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM5_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD5);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM5 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+#if STM32_GPT_USE_TIM1
+ /* Driver initialization.*/
+ GPTD1.tim = TIM1;
+ gptObjectInit(&GPTD1);
+#endif
+
+#if STM32_GPT_USE_TIM2
+ /* Driver initialization.*/
+ GPTD2.tim = TIM2;
+ gptObjectInit(&GPTD2);
+#endif
+
+#if STM32_GPT_USE_TIM3
+ /* Driver initialization.*/
+ GPTD3.tim = TIM3;
+ gptObjectInit(&GPTD3);
+#endif
+
+#if STM32_GPT_USE_TIM4
+ /* Driver initialization.*/
+ GPTD4.tim = TIM4;
+ gptObjectInit(&GPTD4);
+#endif
+
+#if STM32_GPT_USE_TIM5
+ /* Driver initialization.*/
+ GPTD5.tim = TIM5;
+ gptObjectInit(&GPTD5);
+#endif
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint16_t psc;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+#if STM32_GPT_USE_TIM1
+ if (&GPTD1 == gptp) {
+ RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
+ RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST;
+ RCC->APB2RSTR = 0;
+ NVICEnableVector(TIM1_UP_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM1_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK2;
+ }
+#endif
+#if STM32_GPT_USE_TIM2
+ if (&GPTD2 == gptp) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM2_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM2_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK1;
+ }
+#endif
+#if STM32_GPT_USE_TIM3
+ if (&GPTD3 == gptp) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM3_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM3_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK1;
+ }
+#endif
+#if STM32_GPT_USE_TIM4
+ if (&GPTD4 == gptp) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM4_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM4_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK1;
+ }
+#endif
+
+#if STM32_GPT_USE_TIM5
+ if (&GPTD5 == gptp) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM5_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM5_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK1;
+ }
+#endif
+ }
+
+ /* Prescaler value calculation.*/
+ psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1);
+ chDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock,
+ "gpt_lld_start(), #1", "invalid frequency");
+
+ /* Timer configuration.*/
+ gptp->tim->CR1 = 0; /* Initially stopped. */
+ gptp->tim->CR2 = TIM_CR2_CCDS; /* DMA on UE (if any). */
+ gptp->tim->PSC = psc; /* Prescaler value. */
+ gptp->tim->DIER = 0;
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ gptp->tim->CR1 = 0; /* Timer disabled. */
+ gptp->tim->DIER = 0; /* All IRQs disabled. */
+ gptp->tim->SR = 0; /* Clear eventual pending IRQs. */
+
+#if STM32_GPT_USE_TIM1
+ if (&GPTD1 == gptp) {
+ NVICDisableVector(TIM1_UP_IRQn);
+ RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
+ }
+#endif
+#if STM32_GPT_USE_TIM2
+ if (&GPTD2 == gptp) {
+ NVICDisableVector(TIM2_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN;
+ }
+#endif
+#if STM32_GPT_USE_TIM3
+ if (&GPTD3 == gptp) {
+ NVICDisableVector(TIM3_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN;
+ }
+#endif
+#if STM32_GPT_USE_TIM4
+ if (&GPTD4 == gptp) {
+ NVICDisableVector(TIM4_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN;
+ }
+#endif
+#if STM32_GPT_USE_TIM5
+ if (&GPTD5 == gptp) {
+ NVICDisableVector(TIM5_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN;
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tim->ARR = interval - 1; /* Time constant. */
+ gptp->tim->EGR = TIM_EGR_UG; /* Update event. */
+ gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
+ gptp->tim->DIER = TIM_DIER_UIE; /* Update Event IRQ enabled. */
+ gptp->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+ gptp->tim->CR1 = 0; /* Initially stopped. */
+ gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
+ gptp->tim->DIER = 0; /* Interrupts disabled. */
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tim->ARR = interval - 1; /* Time constant. */
+ gptp->tim->EGR = TIM_EGR_UG; /* Update event. */
+ gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
+ gptp->tim->CR1 = TIM_CR1_OPM | TIM_CR1_URS | TIM_CR1_CEN;
+ while (!(gptp->tim->SR & TIM_SR_UIF))
+ ;
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/gpt_lld.h b/os/hal/platforms/STM32/gpt_lld.h
new file mode 100644
index 000000000..cf749077f
--- /dev/null
+++ b/os/hal/platforms/STM32/gpt_lld.h
@@ -0,0 +1,256 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/gpt_lld.h
+ * @brief STM32 GPT subsystem low level driver header.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief GPTD1 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM1) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM1 TRUE
+#endif
+
+/**
+ * @brief GPTD2 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM2) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM2 TRUE
+#endif
+
+/**
+ * @brief GPTD3 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM3) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM3 TRUE
+#endif
+
+/**
+ * @brief GPTD4 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM4) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM4 TRUE
+#endif
+
+/**
+ * @brief GPTD5 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD5 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM5) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM5 TRUE
+#endif
+
+/**
+ * @brief GPTD1 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM1_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD2 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM2_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD3 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM3_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD4 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM4_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD5 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM5_IRQ_PRIORITY 7
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_GPT_USE_TIM1 && !STM32_HAS_TIM1
+#error "TIM1 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM2 && !STM32_HAS_TIM2
+#error "TIM2 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM3 && !STM32_HAS_TIM3
+#error "TIM3 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM4 && !STM32_HAS_TIM4
+#error "TIM4 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM5 && !STM32_HAS_TIM5
+#error "TIM5 not present in the selected device"
+#endif
+
+#if !STM32_GPT_USE_TIM1 && !STM32_GPT_USE_TIM2 && \
+ !STM32_GPT_USE_TIM3 && !STM32_GPT_USE_TIM4 && \
+ !STM32_GPT_USE_TIM5
+#error "GPT driver activated but no TIM peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint16_t gptcnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+#if defined(GPT_DRIVER_EXT_FIELDS)
+ GPT_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer base clock.
+ */
+ uint32_t clock;
+ /**
+ * @brief Pointer to the TIMx registers block.
+ */
+ TIM_TypeDef *tim;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_GPT_USE_TIM1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD1;
+#endif
+
+#if STM32_GPT_USE_TIM2 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD2;
+#endif
+
+#if STM32_GPT_USE_TIM3 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD3;
+#endif
+
+#if STM32_GPT_USE_TIM4 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD4;
+#endif
+
+#if STM32_GPT_USE_TIM5 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD5;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/hal_lld.c b/os/hal/platforms/STM32/hal_lld.c
index 8d8322033..9b4feb982 100644
--- a/os/hal/platforms/STM32/hal_lld.c
+++ b/os/hal/platforms/STM32/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -57,6 +58,12 @@
*/
void hal_lld_init(void) {
+ /* Reset of all peripherals.*/
+ RCC->APB1RSTR = 0xFFFFFFFF;
+ RCC->APB2RSTR = 0xFFFFFFFF;
+ RCC->APB1RSTR = 0;
+ RCC->APB2RSTR = 0;
+
/* SysTick initialization using the system clock.*/
SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
@@ -64,7 +71,7 @@ void hal_lld_init(void) {
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
-#if HAL_USE_ADC || HAL_USE_SPI || HAL_USE_UART
+#if defined(STM32_DMA_REQUIRED)
dmaInit();
#endif
}
@@ -76,9 +83,10 @@ void hal_lld_init(void) {
*
* @special
*/
-#if defined(STM32F10X_LD) || defined(STM32F10X_MD) || \
- defined(STM32F10X_HD) || defined(STM32F10X_LD_VL) || \
- defined(STM32F10X_MD_VL) || defined(__DOXYGEN__)
+#if defined(STM32F10X_LD) || defined(STM32F10X_LD_VL) || \
+ defined(STM32F10X_MD) || defined(STM32F10X_MD_VL) || \
+ defined(STM32F10X_HD) || defined(STM32F10X_XL) || \
+ defined(__DOXYGEN__)
/*
* Clocks initialization for the LD, MD and HD sub-families.
*/
@@ -140,43 +148,51 @@ void stm32_clock_init(void) {
*/
void stm32_clock_init(void) {
- /* HSI setup, it enforces the reset situation in order to handle possible
- problems with JTAG probes and re-initializations.*/
+ /* HSI setup.*/
RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */
while (!(RCC->CR & RCC_CR_HSIRDY))
; /* Wait until HSI is stable. */
+ RCC->CFGR = 0;
RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */
- RCC->CFGR = 0; /* CFGR reset value. */
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
; /* Wait until HSI is the source.*/
- RCC->CFGR2 = 0;
- /* HSE setup, it is only performed if the HSE clock is selected as source
- of the system clock (directly or through the PLLs).*/
-#if (STM32_SW == STM32_SW_HSE) || \
- ((STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_PREDIV1))
+ /* HSE setup, it is only performed if the current configuration uses
+ it somehow.*/
+#if STM32_ACTIVATE_PLL2 || \
+ STM32_ACTIVATE_PLL3 || \
+ (STM32_SW == STM32_SW_HSE) || \
+ ((STM32_PREDIV1SRC == STM32_PREDIV1SRC_HSE) && \
+ (STM32_PLLSRC == STM32_PLLSRC_PREDIV1))
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY))
; /* Waits until HSE is stable. */
#endif
- /* PLL2 setup, it is only performed if the PLL2 clock is selected as source
- for the PLL clock else it is left disabled.*/
-#if STM32_SW == STM32_SW_PLL
-#if STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2
- RCC->CFGR2 |= STM32_PREDIV2 | STM32_PLL2MUL;
- RCC->CR |= RCC_CR_PLL2ON;
+ /* Settings of various dividers and multipliers in CFGR2.*/
+ RCC->CFGR2 = STM32_PLL3MUL | STM32_PLL2MUL | STM32_PREDIV2 |
+ STM32_PREDIV1 | STM32_PREDIV1SRC;
+
+ /* PLL2 setup, if activated.*/
+#if STM32_ACTIVATE_PLL2
+ RCC->CR |= RCC_CR_PLL2ON;
while (!(RCC->CR & RCC_CR_PLL2RDY))
- ; /* Waits until PLL is stable. */
+ ; /* Waits until PLL2 is stable. */
#endif
- /* PLL setup, it is only performed if the PLL is the selected source of
- the system clock else it is left disabled.*/
- RCC->CFGR2 |= STM32_PREDIV1 | STM32_PREDIV1SRC;
- RCC->CFGR |= STM32_PLLMUL | STM32_PLLSRC;
- RCC->CR |= RCC_CR_PLLON;
+ /* PLL3 setup, if activated.*/
+#if STM32_ACTIVATE_PLL3
+ RCC->CR |= RCC_CR_PLL3ON;
+ while (!(RCC->CR & RCC_CR_PLL3RDY))
+ ; /* Waits until PLL3 is stable. */
+#endif
+
+ /* PLL1 setup, if activated.*/
+#if STM32_ACTIVATE_PLL1
+ RCC->CFGR |= STM32_PLLMUL | STM32_PLLSRC;
+ RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
- ; /* Waits until PLL2 is stable. */
+ ; /* Waits until PLL1 is stable. */
#endif
/* Clock settings.*/
diff --git a/os/hal/platforms/STM32/hal_lld.h b/os/hal/platforms/STM32/hal_lld.h
index 0abac770c..b9c71dbbe 100644
--- a/os/hal/platforms/STM32/hal_lld.h
+++ b/os/hal/platforms/STM32/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -31,7 +32,7 @@
* - STM32F10X_LD for Performance Low Density devices.
* - STM32F10X_MD for Performance Medium Density devices.
* - STM32F10X_HD for Performance High Density devices.
- * - STM32F10X_XD for Performance eXtra Density devices.
+ * - STM32F10X_XL for Performance eXtra Density devices.
* - STM32F10X_CL for Connectivity Line devices.
* .
*
@@ -395,7 +396,7 @@
#define STM32_HAS_USB TRUE
#define STM32_HAS_OTG1 FALSE
-#elif defined(STM32F10X_XD)
+#elif defined(STM32F10X_XL)
/*
* Capability flags for Performance Line eXtra Density devices.
*/
diff --git a/os/hal/platforms/STM32/hal_lld_f100.h b/os/hal/platforms/STM32/hal_lld_f100.h
index 1ce918079..571682e38 100644
--- a/os/hal/platforms/STM32/hal_lld_f100.h
+++ b/os/hal/platforms/STM32/hal_lld_f100.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/hal_lld_f103.h b/os/hal/platforms/STM32/hal_lld_f103.h
index 6ea53571a..1f11da249 100644
--- a/os/hal/platforms/STM32/hal_lld_f103.h
+++ b/os/hal/platforms/STM32/hal_lld_f103.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -127,28 +128,19 @@
#define TIM1_CC_IRQHandler VectorAC /**< TIM1 Capture Compare. */
#define TIM2_IRQHandler VectorB0 /**< TIM2. */
#define TIM3_IRQHandler VectorB4 /**< TIM3. */
-#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
#define TIM4_IRQHandler VectorB8 /**< TIM4. */
-#endif
#define I2C1_EV_IRQHandler VectorBC /**< I2C1 Event. */
#define I2C1_ER_IRQHandler VectorC0 /**< I2C1 Error. */
-#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
#define I2C2_EV_IRQHandler VectorC4 /**< I2C2 Event. */
#define I2C2_ER_IRQHandler VectorC8 /**< I2C2 Error. */
-#endif
#define SPI1_IRQHandler VectorCC /**< SPI1. */
-#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
#define SPI2_IRQHandler VectorD0 /**< SPI2. */
-#endif
#define USART1_IRQHandler VectorD4 /**< USART1. */
#define USART2_IRQHandler VectorD8 /**< USART2. */
-#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
#define USART3_IRQHandler VectorDC /**< USART3. */
-#endif
#define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */
#define RTCAlarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */
#define USBWakeUp_IRQHandler VectorE8 /**< USB Wakeup from suspend. */
-#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
#define TIM8_BRK_IRQHandler VectorEC /**< TIM8 Break. */
#define TIM8_UP_IRQHandler VectorF0 /**< TIM8 Update. */
#define TIM8_TRG_COM_IRQHandler VectorF4 /**< TIM8 Trigger and
@@ -167,7 +159,6 @@
#define DMA2_Ch2_IRQHandler Vector124 /**< DMA2 Channel2. */
#define DMA2_Ch3_IRQHandler Vector128 /**< DMA2 Channel3. */
#define DMA2_Ch4_5_IRQHandler Vector12C /**< DMA2 Channel4 & Channel5. */
-#endif
/*===========================================================================*/
/* Driver pre-compile time settings. */
diff --git a/os/hal/platforms/STM32/hal_lld_f105_f107.h b/os/hal/platforms/STM32/hal_lld_f105_f107.h
index d4477e705..ce8147ae0 100644
--- a/os/hal/platforms/STM32/hal_lld_f105_f107.h
+++ b/os/hal/platforms/STM32/hal_lld_f105_f107.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -171,9 +172,34 @@
/*===========================================================================*/
/**
+ * @brief PLL1 main switch.
+ * @note If this constant is set to @p TRUE then the PLL1 is initialized
+ * and started.
+ */
+#if !defined(STM32_ACTIVATE_PLL1) || defined(__DOXYGEN__)
+#define STM32_ACTIVATE_PLL1 TRUE
+#endif
+
+/**
+ * @brief PLL2 main switch.
+ * @note If this constant is set to @p TRUE then the PLL2 is initialized
+ * and started.
+ */
+#if !defined(STM32_ACTIVATE_PLL2) || defined(__DOXYGEN__)
+#define STM32_ACTIVATE_PLL2 TRUE
+#endif
+
+/**
+ * @brief PLL3 main switch.
+ * @note If this constant is set to @p TRUE then the PLL3 is initialized
+ * and started.
+ */
+#if !defined(STM32_ACTIVATE_PLL3) || defined(__DOXYGEN__)
+#define STM32_ACTIVATE_PLL3 TRUE
+#endif
+
+/**
* @brief Main clock source selection.
- * @note If the selected clock source is not the PLL then the PLL is not
- * initialized and started.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
*/
@@ -183,8 +209,6 @@
/**
* @brief Clock source for the PLL.
- * @note This setting has only effect if the PLL is selected as the
- * system clock source.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
*/
@@ -194,8 +218,6 @@
/**
* @brief PREDIV1 clock source.
- * @note This setting has only effect if the PLL is selected as the
- * system clock source.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
*/
@@ -205,8 +227,6 @@
/**
* @brief PREDIV1 division factor.
- * @note This setting has only effect if the PLL is selected as the
- * system clock source.
* @note The allowed range is 1...16.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
@@ -227,8 +247,6 @@
/**
* @brief PREDIV2 division factor.
- * @note This setting has only effect if the PLL2 is selected as the
- * clock source for the PLL.
* @note The allowed range is 1...16.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
@@ -247,6 +265,15 @@
#endif
/**
+ * @brief PLL3 multiplier value.
+ * @note The default value is calculated for a 50MHz clock from
+ * a 25MHz crystal.
+ */
+#if !defined(STM32_PLL3MUL_VALUE) || defined(__DOXYGEN__)
+#define STM32_PLL3MUL_VALUE 10
+#endif
+
+/**
* @brief AHB prescaler value.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
@@ -294,6 +321,13 @@
/* Derived constants and error checks. */
/*===========================================================================*/
+/* PLL2 usage check.*/
+#if STM32_ACTIVATE_PLL2 && \
+ (STM32_PREDIV1SRC != STM32_PREDIV1SRC_PLL2) && \
+ (STM32_MCO != STM32_MCO_PLL2)
+#error "PLL2 activated but not used"
+#endif
+
/**
* @brief PREDIV1 field.
*/
@@ -338,9 +372,22 @@
#error "invalid STM32_PLL2MUL_VALUE value specified"
#endif
-/* The following values are only used if PLL2 clock is selected as source
- for the PLL clock */
-#if (STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2) || defined(__DOXYGEN__)
+/**
+ * @brief PLL3MUL field.
+ */
+#if ((STM32_PLL3MUL_VALUE >= 8) && (STM32_PLL3MUL_VALUE <= 14)) || \
+ defined(__DOXYGEN__)
+#define STM32_PLL3MUL ((STM32_PLL3MUL_VALUE - 2) << 12)
+#elif (STM32_PLL3MUL_VALUE == 16)
+#define STM32_PLL3MUL (14 << 12)
+#elif (STM32_PLL3MUL_VALUE == 20)
+#define STM32_PLL3MUL (15 << 12)
+#else
+#error "invalid STM32_PLL3MUL_VALUE value specified"
+#endif
+
+/* The following values are only used if PLL2 is activated */
+#if STM32_ACTIVATE_PLL2
/**
* @brief PLL2 input frequency.
*/
@@ -356,16 +403,54 @@
*/
#define STM32_PLL2CLKOUT (STM32_PLL2CLKIN * STM32_PLL2MUL_VALUE)
+/**
+ * @brief PLL2 VCO clock frequency.
+ */
+#define STM32_PLL2VCO (STM32_PLL2CLKOUT * 2)
+
/* PLL2 output frequency range check.*/
-#if (STM32_PLL2CLKOUT < 40000000) || (STM32_PLL2CLKOUT > 74000000)
-#error "STM32_PLL2CLKOUT outside acceptable range (40...74MHz)"
+#if (STM32_PLL2VCO < 80000000) || (STM32_PLL2VCO > 148000000)
+#error "STM32_PLL2VCO outside acceptable range (80...148MHz)"
+#endif
+#endif /* STM32_ACTIVATE_PLL2 */
+
+/* The following values are only used if PLL3 is activated */
+#if STM32_ACTIVATE_PLL3
+/**
+ * @brief PLL3 input frequency.
+ */
+#define STM32_PLL3CLKIN (STM32_HSECLK / STM32_PREDIV2_VALUE)
+
+/* PLL3 input frequency range check.*/
+#if (STM32_PLL3CLKIN < 3000000) || (STM32_PLL3CLKIN > 5000000)
+#error "STM32_PLL3CLKIN outside acceptable range (3...5MHz)"
#endif
-#endif /* STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2 */
/**
+ * @brief PLL3 output clock frequency.
+ */
+#define STM32_PLL3CLKOUT (STM32_PLL3CLKIN * STM32_PLL3MUL_VALUE)
+
+/**
+ * @brief PLL3 VCO clock frequency.
+ */
+#define STM32_PLL3VCO (STM32_PLL3CLKOUT * 2)
+
+/* PLL3 output frequency range check.*/
+#if (STM32_PLL3VCO < 80000000) || (STM32_PLL3VCO > 148000000)
+#error "STM32_PLL3CLKOUT outside acceptable range (80...148MHz)"
+#endif
+#endif /* STM32_ACTIVATE_PLL3 */
+
+/* The following values are only used if PLL1 is activated */
+#if STM32_ACTIVATE_PLL1
+/**
* @brief PREDIV1 input frequency.
*/
#if (STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2) || defined(__DOXYGEN__)
+#if !STM32_ACTIVATE_PLL2
+#error "PLL2 selected as clock source for STM32_PREDIV1SRC but not activated"
+#endif
#define STM32_PREDIV1CLK STM32_PLL2CLKOUT
#elif STM32_PREDIV1SRC == STM32_PREDIV1SRC_HSE
#define STM32_PREDIV1CLK STM32_HSECLK
@@ -377,9 +462,9 @@
* @brief PLL input clock frequency.
*/
#if (STM32_PLLSRC == STM32_PLLSRC_PREDIV1) || defined(__DOXYGEN__)
-#define STM32_PLLCLKIN (STM32_PREDIV1CLK / STM32_PREDIV1_VALUE)
+#define STM32_PLLCLKIN (STM32_PREDIV1CLK / STM32_PREDIV1_VALUE)
#elif STM32_PLLSRC == STM32_PLLSRC_HSI
-#define STM32_PLLCLKIN (STM32_HSICLK / 2)
+#define STM32_PLLCLKIN (STM32_HSICLK / 2)
#else
#error "invalid STM32_PLLSRC value specified"
#endif
@@ -392,17 +477,26 @@
/**
* @brief PLL output clock frequency.
*/
-#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
+#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
+
+/**
+ * @brief PLL VCO clock frequency.
+ */
+#define STM32_PLLVCO (STM32_PLLCLKOUT * 2)
/* PLL output frequency range check.*/
-#if (STM32_PLLCLKOUT < 18000000) || (STM32_PLLCLKOUT > 72000000)
-#error "STM32_PLLCLKOUT outside acceptable range (18...72MHz)"
+#if (STM32_PLLVCO < 36000000) || (STM32_PLLVCO > 144000000)
+#error "STM32_PLLVCO outside acceptable range (36...144MHz)"
#endif
+#endif /* STM32_ACTIVATE_PLL1 */
/**
* @brief System clock source.
*/
#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__)
+#if !STM32_ACTIVATE_PLL1
+#error "PLL1 selected as clock source for STM32_SYSCLK but not activated"
+#endif
#define STM32_SYSCLK STM32_PLLCLKOUT
#elif (STM32_SW == STM32_SW_HSI)
#define STM32_SYSCLK STM32_HSICLK
@@ -515,9 +609,9 @@
* @brief OTG frequency.
*/
#if (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV3) || defined(__DOXYGEN__)
-#define STM32_OTGFSCLK ((STM32_PLLCLKOUT * 2) / 3)
+#define STM32_OTGFSCLK (STM32_PLLVCO / 3)
#elif (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV2)
-#define STM32_OTGFSCLK STM32_PLLCLKOUT
+#define STM32_OTGFSCLK (STM32_PLLVCO / 2)
#else
#error "invalid STM32_OTGFSPRE value specified"
#endif
diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c
new file mode 100644
index 000000000..ae3287ef9
--- /dev/null
+++ b/os/hal/platforms/STM32/icu_lld.c
@@ -0,0 +1,425 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/icu_lld.c
+ * @brief STM32 ICU subsystem low level driver header.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief ICUD1 driver identifier.
+ * @note The driver ICUD1 allocates the complex timer TIM1 when enabled.
+ */
+#if STM32_ICU_USE_TIM1 || defined(__DOXYGEN__)
+ICUDriver ICUD1;
+#endif
+
+/**
+ * @brief ICUD2 driver identifier.
+ * @note The driver ICUD1 allocates the timer TIM2 when enabled.
+ */
+#if STM32_ICU_USE_TIM2 || defined(__DOXYGEN__)
+ICUDriver ICUD2;
+#endif
+
+/**
+ * @brief ICUD3 driver identifier.
+ * @note The driver ICUD1 allocates the timer TIM3 when enabled.
+ */
+#if STM32_ICU_USE_TIM3 || defined(__DOXYGEN__)
+ICUDriver ICUD3;
+#endif
+
+/**
+ * @brief ICUD4 driver identifier.
+ * @note The driver ICUD4 allocates the timer TIM4 when enabled.
+ */
+#if STM32_ICU_USE_TIM4 || defined(__DOXYGEN__)
+ICUDriver ICUD4;
+#endif
+
+/**
+ * @brief ICUD5 driver identifier.
+ * @note The driver ICUD5 allocates the timer TIM5 when enabled.
+ */
+#if STM32_ICU_USE_TIM5 || defined(__DOXYGEN__)
+ICUDriver ICUD5;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ */
+static void icu_lld_serve_interrupt(ICUDriver *icup) {
+ uint16_t sr;
+
+ sr = icup->tim->SR & icup->tim->DIER;
+ icup->tim->SR = 0;
+ if ((sr & TIM_SR_CC1IF) != 0)
+ _icu_isr_invoke_period_cb(icup);
+ if ((sr & TIM_SR_CC2IF) != 0)
+ _icu_isr_invoke_width_cb(icup);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ICU_USE_TIM1
+/**
+ * @brief TIM1 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM1_CC_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM1 */
+
+#if STM32_ICU_USE_TIM2
+/**
+ * @brief TIM2 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM2_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM2 */
+
+#if STM32_ICU_USE_TIM3
+/**
+ * @brief TIM3 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM3_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM3 */
+
+#if STM32_ICU_USE_TIM4
+/**
+ * @brief TIM4 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM4_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM4 */
+
+#if STM32_ICU_USE_TIM5
+/**
+ * @brief TIM5 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM5_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD5);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM5 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ICU driver initialization.
+ *
+ * @notapi
+ */
+void icu_lld_init(void) {
+
+#if STM32_ICU_USE_TIM1
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD1);
+ ICUD1.tim = TIM1;
+#endif
+
+#if STM32_ICU_USE_TIM2
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD2);
+ ICUD2.tim = TIM2;
+#endif
+
+#if STM32_ICU_USE_TIM3
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD3);
+ ICUD3.tim = TIM3;
+#endif
+
+#if STM32_ICU_USE_TIM4
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD4);
+ ICUD4.tim = TIM4;
+#endif
+
+#if STM32_ICU_USE_TIM5
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD5);
+ ICUD5.tim = TIM5;
+#endif
+}
+
+/**
+ * @brief Configures and activates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_start(ICUDriver *icup) {
+ uint32_t clock, psc;
+
+ if (icup->state == ICU_STOP) {
+ /* Clock activation and timer reset.*/
+#if STM32_ICU_USE_TIM1
+ if (&ICUD1 == icup) {
+ RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
+ RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST;
+ RCC->APB2RSTR = 0;
+ NVICEnableVector(TIM1_CC_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM1_IRQ_PRIORITY));
+ clock = STM32_TIMCLK2;
+ }
+#endif
+#if STM32_ICU_USE_TIM2
+ if (&ICUD2 == icup) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM2_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM2_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
+ }
+#endif
+#if STM32_ICU_USE_TIM3
+ if (&ICUD3 == icup) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM3_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM3_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
+ }
+#endif
+#if STM32_ICU_USE_TIM4
+ if (&ICUD4 == icup) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM4_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM4_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
+ }
+#endif
+
+#if STM32_ICU_USE_TIM5
+ if (&ICUD5 == icup) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM5_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM5_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
+ }
+#endif
+ }
+ else {
+ /* Driver re-configuration scenario, it must be stopped first.*/
+ icup->tim->CR1 = 0; /* Timer disabled. */
+ icup->tim->DIER = 0; /* All IRQs disabled. */
+ icup->tim->SR = 0; /* Clear eventual pending IRQs. */
+ icup->tim->CCR1 = 0; /* Comparator 1 disabled. */
+ icup->tim->CCR2 = 0; /* Comparator 2 disabled. */
+ icup->tim->CNT = 0; /* Counter reset to zero. */
+ }
+
+ /* Timer configuration.*/
+ psc = (clock / icup->config->frequency) - 1;
+ chDbgAssert((psc <= 0xFFFF) &&
+ ((psc + 1) * icup->config->frequency) == clock,
+ "icu_lld_start(), #1", "invalid frequency");
+ icup->tim->PSC = (uint16_t)psc;
+ icup->tim->ARR = 0xFFFF;
+
+ /* CCMR1_CC1S = 01 = CH1 Input on TI1.
+ CCMR1_CC2S = 10 = CH2 Input on TI2.*/
+ icup->tim->CCMR1 = TIM_CCMR1_CC1S_0 |
+ TIM_CCMR1_CC2S_1;
+ /* SMCR_TS = 101, input is TI1FP1.
+ SMCR_SMS = 100, reset on rising edge.*/
+ icup->tim->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_0 |
+ TIM_SMCR_SMS_2;
+ /* The CCER settings depend on the selected trigger mode.
+ ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
+ ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/
+ if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH)
+ icup->tim->CCER = TIM_CCER_CC1E |
+ TIM_CCER_CC2E | TIM_CCER_CC2P;
+ else
+ icup->tim->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P |
+ TIM_CCER_CC2E;
+}
+
+/**
+ * @brief Deactivates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_stop(ICUDriver *icup) {
+
+ if (icup->state == ICU_READY) {
+ /* Clock deactivation.*/
+ icup->tim->CR1 = 0; /* Timer disabled. */
+ icup->tim->DIER = 0; /* All IRQs disabled. */
+ icup->tim->SR = 0; /* Clear eventual pending IRQs. */
+
+#if STM32_ICU_USE_TIM1
+ if (&ICUD1 == icup) {
+ NVICDisableVector(TIM1_CC_IRQn);
+ RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
+ }
+#endif
+ }
+#if STM32_ICU_USE_TIM2
+ if (&ICUD2 == icup) {
+ NVICDisableVector(TIM2_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN;
+ }
+#endif
+#if STM32_ICU_USE_TIM3
+ if (&ICUD3 == icup) {
+ NVICDisableVector(TIM3_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN;
+ }
+#endif
+#if STM32_ICU_USE_TIM4
+ if (&ICUD4 == icup) {
+ NVICDisableVector(TIM4_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN;
+ }
+#endif
+#if STM32_ICU_USE_TIM5
+ if (&ICUD5 == icup) {
+ NVICDisableVector(TIM5_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN;
+ }
+#endif
+}
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_enable(ICUDriver *icup) {
+
+ icup->tim->SR = 0; /* Clear pending IRQs (if any). */
+ if (icup->config->period_cb != NULL)
+ icup->tim->DIER |= TIM_DIER_CC1IE;
+ if (icup->config->width_cb != NULL)
+ icup->tim->DIER |= TIM_DIER_CC2IE;
+ icup->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
+}
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_disable(ICUDriver *icup) {
+
+ icup->tim->CR1 = 0; /* Initially stopped. */
+ icup->tim->SR = 0; /* Clear pending IRQs (if any). */
+ icup->tim->DIER = 0; /* Interrupts disabled. */
+}
+
+#endif /* HAL_USE_ICU */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h
new file mode 100644
index 000000000..b98b8bf86
--- /dev/null
+++ b/os/hal/platforms/STM32/icu_lld.h
@@ -0,0 +1,290 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/icu_lld.h
+ * @brief STM32 ICU subsystem low level driver header.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#ifndef _ICU_LLD_H_
+#define _ICU_LLD_H_
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief ICUD1 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM1) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM1 TRUE
+#endif
+
+/**
+ * @brief ICUD2 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM2) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM2 TRUE
+#endif
+
+/**
+ * @brief ICUD3 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM3) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM3 TRUE
+#endif
+
+/**
+ * @brief ICUD4 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM4) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM4 TRUE
+#endif
+
+/**
+ * @brief ICUD5 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD5 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM5) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM5 TRUE
+#endif
+
+/**
+ * @brief ICUD1 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM1_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD2 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM2_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD3 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM3_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD4 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM4_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD5 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM5_IRQ_PRIORITY 7
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_ICU_USE_TIM1 && !STM32_HAS_TIM1
+#error "TIM1 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM2 && !STM32_HAS_TIM2
+#error "TIM2 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM3 && !STM32_HAS_TIM3
+#error "TIM3 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM4 && !STM32_HAS_TIM4
+#error "TIM4 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM5 && !STM32_HAS_TIM5
+#error "TIM5 not present in the selected device"
+#endif
+
+#if !STM32_ICU_USE_TIM1 && !STM32_ICU_USE_TIM2 && \
+ !STM32_ICU_USE_TIM3 && !STM32_ICU_USE_TIM4 && \
+ !STM32_ICU_USE_TIM5
+#error "ICU driver activated but no TIM peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ICU driver mode.
+ */
+typedef enum {
+ ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
+ ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
+} icumode_t;
+
+/**
+ * @brief ICU frequency type.
+ */
+typedef uint32_t icufreq_t;
+
+/**
+ * @brief ICU counter type.
+ */
+typedef uint16_t icucnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Driver mode.
+ */
+ icumode_t mode;
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ icufreq_t frequency;
+ /**
+ * @brief Callback for pulse width measurement.
+ */
+ icucallback_t width_cb;
+ /**
+ * @brief Callback for cycle period measurement.
+ */
+ icucallback_t period_cb;
+ /* End of the mandatory fields.*/
+} ICUConfig;
+
+/**
+ * @brief Structure representing an ICU driver.
+ */
+struct ICUDriver {
+ /**
+ * @brief Driver state.
+ */
+ icustate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const ICUConfig *config;
+#if defined(ICU_DRIVER_EXT_FIELDS)
+ ICU_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the TIMx registers block.
+ */
+ TIM_TypeDef *tim;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the width of the latest pulse.
+ * @details The pulse width is defined as number of ticks between the start
+ * edge and the stop edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+#define icu_lld_get_width(icup) ((icup)->tim->CCR2 + 1)
+
+/**
+ * @brief Returns the width of the latest cycle.
+ * @details The cycle width is defined as number of ticks between a start
+ * edge and the next start edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+#define icu_lld_get_period(icup) ((icup)->tim->CCR1 + 1)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ICU_USE_TIM1 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD1;
+#endif
+
+#if STM32_ICU_USE_TIM2 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD2;
+#endif
+
+#if STM32_ICU_USE_TIM3 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD3;
+#endif
+
+#if STM32_ICU_USE_TIM4 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD4;
+#endif
+
+#if STM32_ICU_USE_TIM5 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD5;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void icu_lld_init(void);
+ void icu_lld_start(ICUDriver *icup);
+ void icu_lld_stop(ICUDriver *icup);
+ void icu_lld_enable(ICUDriver *icup);
+ void icu_lld_disable(ICUDriver *icup);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ICU */
+
+#endif /* _ICU_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/pal_lld.c b/os/hal/platforms/STM32/pal_lld.c
index ac90883f7..c56996db7 100644
--- a/os/hal/platforms/STM32/pal_lld.c
+++ b/os/hal/platforms/STM32/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -31,25 +32,15 @@
#if HAL_USE_PAL || defined(__DOXYGEN__)
#if STM32_HAS_GPIOG
-#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
- RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
- RCC_APB2RSTR_IOPERST | RCC_APB2RSTR_IOPFRST | \
- RCC_APB2RSTR_IOPGRST | RCC_APB2RSTR_AFIORST);
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPFEN | \
RCC_APB2ENR_IOPGEN | RCC_APB2ENR_AFIOEN)
#elif STM32_HAS_GPIOE
-#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
- RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
- RCC_APB2RSTR_IOPERST | RCC_APB2RSTR_AFIORST);
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN)
#else
-#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
- RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
- RCC_APB2RSTR_AFIORST)
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
RCC_APB2ENR_AFIOEN)
@@ -91,11 +82,8 @@ void _pal_lld_init(const PALConfig *config) {
RCC->APB2ENR |= APB2_EN_MASK;
/*
- * Resets the GPIO ports and AFIO.
+ * Initial GPIO setup.
*/
- RCC->APB2RSTR = APB2_RST_MASK;
- RCC->APB2RSTR = 0;
-
GPIOA->ODR = config->PAData.odr;
GPIOA->CRH = config->PAData.crh;
GPIOA->CRL = config->PAData.crl;
diff --git a/os/hal/platforms/STM32/pal_lld.h b/os/hal/platforms/STM32/pal_lld.h
index a6d1236ae..2919c91f6 100644
--- a/os/hal/platforms/STM32/pal_lld.h
+++ b/os/hal/platforms/STM32/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -278,10 +279,9 @@ typedef GPIO_TypeDef * ioportid_t;
*
* @notapi
*/
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- (port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \
- (((bits) & (mask)) << (offset)); \
-}
+#define pal_lld_writegroup(port, mask, offset, bits) \
+ ((port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \
+ (((bits) & (mask)) << (offset)))
/**
* @brief Pads group mode setup.
diff --git a/os/hal/platforms/STM32/platform.dox b/os/hal/platforms/STM32/platform.dox
index 91f0addca..50ab84f38 100644
--- a/os/hal/platforms/STM32/platform.dox
+++ b/os/hal/platforms/STM32/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -61,7 +62,7 @@
* - Programmable ADC interrupt priority level.
* - Programmable DMA bus priority for each DMA channel.
* - Programmable DMA interrupt priority for each DMA channel.
- * - Programmable DMA error hook for each DMA channel.
+ * - Programmable DMA error hook.
* .
* @ingroup STM32_DRIVERS
*/
@@ -100,7 +101,45 @@
*/
/**
- * @defgroup STM32_PAL STM32 GPIO Support
+ * @defgroup STM32_GPT STM32 GPT Support
+ * @details The STM32 GPT driver uses the TIMx peripherals.
+ *
+ * @section stm32_gpt_1 Supported HW resources
+ * - TIM1.
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * - TIM5.
+ * .
+ * @section stm32_gpt_2 STM32 GPT driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32_DRIVERS
+ */
+
+/**
+ * @defgroup STM32_ICU STM32 ICU Support
+ * @details The STM32 ICU driver uses the TIMx peripherals.
+ *
+ * @section stm32_icu_1 Supported HW resources
+ * - TIM1.
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * - TIM5.
+ * .
+ * @section stm32_icu_2 STM32 ICU driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32_DRIVERS
+ */
+
+/**
+ * @defgroup STM32_PAL STM32 PAL Support
* @details The STM32 PAL driver uses the GPIO peripherals.
*
* @section stm32_pal_1 Supported HW resources
@@ -158,6 +197,7 @@
* - TIM2.
* - TIM3.
* - TIM4.
+ * - TIM5.
* .
* @section stm32_pwm_2 STM32 PWM driver implementation features
* - Each timer can be independently enabled and programmed. Unused
@@ -169,32 +209,24 @@
*/
/**
- * @defgroup STM32_SPI STM32 SPI Support
- * @details The SPI driver supports the STM32 SPI peripherals using DMA
- * channels for maximum performance.
+ * @defgroup STM32_SDC STM32 SDC Support
+ * @details The STM32 SDC driver uses the SDIO peripheral.
*
- * @section stm32_spi_1 Supported HW resources
- * - SPI1.
- * - SPI2.
- * - SPI3 (where present).
- * - DMA1.
- * - DMA2 (where present).
+ * @section stm32_sdc_1 Supported HW resources
+ * - SDIO.
+ * - DMA2.
* .
- * @section stm32_spi_2 STM32 SPI driver implementation features
+ * @section stm32_sdc_2 STM32 SDC driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
- * - Each SPI can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Programmable interrupt priority levels for each SPI.
+ * - Programmable interrupt priority.
* - DMA is used for receiving and transmitting.
* - Programmable DMA bus priority for each DMA channel.
- * - Programmable DMA interrupt priority for each DMA channel.
- * - Programmable DMA error hook for each DMA channel.
* .
* @ingroup STM32_DRIVERS
*/
/**
- * @defgroup STM32_SERIAL STM32 USART Support (buffered)
+ * @defgroup STM32_SERIAL STM32 Serial Support
* @details The STM32 Serial driver uses the USART/UART peripherals in a
* buffered, interrupt driven, implementation.
*
@@ -217,7 +249,32 @@
*/
/**
- * @defgroup STM32_UART STM32 USART Support (unbuffered)
+ * @defgroup STM32_SPI STM32 SPI Support
+ * @details The SPI driver supports the STM32 SPI peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section stm32_spi_1 Supported HW resources
+ * - SPI1.
+ * - SPI2.
+ * - SPI3 (where present).
+ * - DMA1.
+ * - DMA2 (where present).
+ * .
+ * @section stm32_spi_2 STM32 SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each SPI can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable interrupt priority levels for each SPI.
+ * - DMA is used for receiving and transmitting.
+ * - Programmable DMA bus priority for each DMA channel.
+ * - Programmable DMA interrupt priority for each DMA channel.
+ * - Programmable DMA error hook.
+ * .
+ * @ingroup STM32_DRIVERS
+ */
+
+/**
+ * @defgroup STM32_UART STM32 UART Support
* @details The UART driver supports the STM32 USART peripherals using DMA
* channels for maximum performance.
*
@@ -226,6 +283,7 @@
* - USART1.
* - USART2.
* - USART3 (where present).
+ * - UART4 (where present).
* - DMA1.
* - DMA2 (where present).
* .
@@ -237,7 +295,23 @@
* - DMA is used for receiving and transmitting.
* - Programmable DMA bus priority for each DMA channel.
* - Programmable DMA interrupt priority for each DMA channel.
- * - Programmable DMA error hook for each DMA channel.
+ * - Programmable DMA error hook.
+ * .
+ * @ingroup STM32_DRIVERS
+ */
+
+/**
+ * @defgroup STM32_USB STM32 USB Support
+ * @details The USB driver supports the STM32 USB peripheral.
+ *
+ * @section stm32_usb_1 Supported HW resources
+ * The USB driver can support any of the following hardware resources:
+ * - USB.
+ * .
+ * @section stm32_usb_2 STM32 USB driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Programmable interrupt priority levels.
+ * - Each endpoint programmable in Control, Bulk and Interrupt modes.
* .
* @ingroup STM32_DRIVERS
*/
diff --git a/os/hal/platforms/STM32/platform.mk b/os/hal/platforms/STM32/platform.mk
index 35717687f..02f090e5e 100644
--- a/os/hal/platforms/STM32/platform.mk
+++ b/os/hal/platforms/STM32/platform.mk
@@ -2,8 +2,11 @@
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32/hal_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/adc_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/can_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/pal_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/sdc_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \
diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c
index f78896e95..bb6dad8f2 100644
--- a/os/hal/platforms/STM32/pwm_lld.c
+++ b/os/hal/platforms/STM32/pwm_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -47,40 +48,40 @@
/*===========================================================================*/
/**
- * @brief PWM1 driver identifier.
- * @note The driver PWM1 allocates the complex timer TIM1 when enabled.
+ * @brief PWMD1 driver identifier.
+ * @note The driver PWMD1 allocates the complex timer TIM1 when enabled.
*/
#if STM32_PWM_USE_TIM1 || defined(__DOXYGEN__)
PWMDriver PWMD1;
#endif
/**
- * @brief PWM2 driver identifier.
- * @note The driver PWM2 allocates the timer TIM2 when enabled.
+ * @brief PWMD2 driver identifier.
+ * @note The driver PWMD2 allocates the timer TIM2 when enabled.
*/
#if STM32_PWM_USE_TIM2 || defined(__DOXYGEN__)
PWMDriver PWMD2;
#endif
/**
- * @brief PWM3 driver identifier.
- * @note The driver PWM3 allocates the timer TIM3 when enabled.
+ * @brief PWMD3 driver identifier.
+ * @note The driver PWMD3 allocates the timer TIM3 when enabled.
*/
#if STM32_PWM_USE_TIM3 || defined(__DOXYGEN__)
PWMDriver PWMD3;
#endif
/**
- * @brief PWM4 driver identifier.
- * @note The driver PWM4 allocates the timer TIM4 when enabled.
+ * @brief PWMD4 driver identifier.
+ * @note The driver PWMD4 allocates the timer TIM4 when enabled.
*/
#if STM32_PWM_USE_TIM4 || defined(__DOXYGEN__)
PWMDriver PWMD4;
#endif
/**
- * @brief PWM5 driver identifier.
- * @note The driver PWM5 allocates the timer TIM5 when enabled.
+ * @brief PWMD5 driver identifier.
+ * @note The driver PWMD5 allocates the timer TIM5 when enabled.
*/
#if STM32_PWM_USE_TIM5 || defined(__DOXYGEN__)
PWMDriver PWMD5;
@@ -101,24 +102,26 @@ PWMDriver PWMD5;
* @note It is assumed that the various sources are only activated if the
* associated callback pointer is not equal to @p NULL in order to not
* perform an extra check in a potentially critical interrupt handler.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
*/
static void serve_interrupt(PWMDriver *pwmp) {
uint16_t sr;
- sr = pwmp->pd_tim->SR;
- sr &= pwmp->pd_tim->DIER;
- pwmp->pd_tim->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF |
- TIM_SR_CC4IF | TIM_SR_UIF);
+ sr = pwmp->tim->SR;
+ sr &= pwmp->tim->DIER;
+ pwmp->tim->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF |
+ TIM_SR_CC4IF | TIM_SR_UIF);
if ((sr & TIM_SR_CC1IF) != 0)
- pwmp->pd_config->pc_channels[0].pcc_callback(pwmp);
+ pwmp->config->channels[0].callback(pwmp);
if ((sr & TIM_SR_CC2IF) != 0)
- pwmp->pd_config->pc_channels[1].pcc_callback(pwmp);
+ pwmp->config->channels[1].callback(pwmp);
if ((sr & TIM_SR_CC3IF) != 0)
- pwmp->pd_config->pc_channels[2].pcc_callback(pwmp);
+ pwmp->config->channels[2].callback(pwmp);
if ((sr & TIM_SR_CC4IF) != 0)
- pwmp->pd_config->pc_channels[3].pcc_callback(pwmp);
+ pwmp->config->channels[3].callback(pwmp);
if ((sr & TIM_SR_UIF) != 0)
- pwmp->pd_config->pc_callback(pwmp);
+ pwmp->config->callback(pwmp);
}
#endif /* STM32_PWM_USE_TIM2 || ... || STM32_PWM_USE_TIM5 */
@@ -140,7 +143,7 @@ CH_IRQ_HANDLER(TIM1_UP_IRQHandler) {
CH_IRQ_PROLOGUE();
TIM1->SR = ~TIM_SR_UIF;
- PWMD1.pd_config->pc_callback(&PWMD1);
+ PWMD1.config->callback(&PWMD1);
CH_IRQ_EPILOGUE();
}
@@ -161,13 +164,13 @@ CH_IRQ_HANDLER(TIM1_CC_IRQHandler) {
sr = TIM1->SR & TIM1->DIER;
TIM1->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF);
if ((sr & TIM_SR_CC1IF) != 0)
- PWMD1.pd_config->pc_channels[0].pcc_callback(&PWMD1);
+ PWMD1.config->channels[0].callback(&PWMD1);
if ((sr & TIM_SR_CC2IF) != 0)
- PWMD1.pd_config->pc_channels[1].pcc_callback(&PWMD1);
+ PWMD1.config->channels[1].callback(&PWMD1);
if ((sr & TIM_SR_CC3IF) != 0)
- PWMD1.pd_config->pc_channels[2].pcc_callback(&PWMD1);
+ PWMD1.config->channels[2].callback(&PWMD1);
if ((sr & TIM_SR_CC4IF) != 0)
- PWMD1.pd_config->pc_channels[3].pcc_callback(&PWMD1);
+ PWMD1.config->channels[3].callback(&PWMD1);
CH_IRQ_EPILOGUE();
}
@@ -249,75 +252,50 @@ CH_IRQ_HANDLER(TIM5_IRQHandler) {
void pwm_lld_init(void) {
#if STM32_PWM_USE_TIM1
- /* TIM1 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST;
- RCC->APB2RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD1);
- PWMD1.pd_enabled_channels = 0;
- PWMD1.pd_tim = TIM1;
+ PWMD1.tim = TIM1;
#endif
#if STM32_PWM_USE_TIM2
- /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD2);
- PWMD2.pd_enabled_channels = 0;
- PWMD2.pd_tim = TIM2;
+ PWMD2.tim = TIM2;
#endif
#if STM32_PWM_USE_TIM3
- /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD3);
- PWMD3.pd_enabled_channels = 0;
- PWMD3.pd_tim = TIM3;
+ PWMD3.tim = TIM3;
#endif
#if STM32_PWM_USE_TIM4
- /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD4);
- PWMD4.pd_enabled_channels = 0;
- PWMD4.pd_tim = TIM4;
+ PWMD4.tim = TIM4;
#endif
#if STM32_PWM_USE_TIM5
- /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD5);
- PWMD5.pd_enabled_channels = 0;
- PWMD5.pd_tim = TIM5;
+ PWMD5.tim = TIM5;
#endif
}
/**
* @brief Configures and activates the PWM peripheral.
+ * @note Starting a driver that is already in the @p PWM_READY state
+ * disables all the active channels.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*
* @notapi
*/
void pwm_lld_start(PWMDriver *pwmp) {
+ uint32_t clock, psc;
uint16_t ccer;
- /* Reset channels.*/
- pwmp->pd_enabled_channels = 0; /* All channels disabled. */
-
- if (pwmp->pd_state == PWM_STOP) {
+ if (pwmp->state == PWM_STOP) {
/* Clock activation and timer reset.*/
#if STM32_PWM_USE_TIM1
if (&PWMD1 == pwmp) {
@@ -328,6 +306,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY));
NVICEnableVector(TIM1_CC_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY));
+ clock = STM32_TIMCLK2;
}
#endif
#if STM32_PWM_USE_TIM2
@@ -337,6 +316,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
RCC->APB1RSTR = 0;
NVICEnableVector(TIM2_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM2_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
}
#endif
#if STM32_PWM_USE_TIM3
@@ -346,6 +326,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
RCC->APB1RSTR = 0;
NVICEnableVector(TIM3_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM3_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
}
#endif
#if STM32_PWM_USE_TIM4
@@ -355,6 +336,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
RCC->APB1RSTR = 0;
NVICEnableVector(TIM4_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM4_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
}
#endif
@@ -365,41 +347,45 @@ void pwm_lld_start(PWMDriver *pwmp) {
RCC->APB1RSTR = 0;
NVICEnableVector(TIM5_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM5_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
}
#endif
-
/* All channels configured in PWM1 mode with preload enabled and will
stay that way until the driver is stopped.*/
- pwmp->pd_tim->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
- TIM_CCMR1_OC1PE |
- TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 |
- TIM_CCMR1_OC2PE;
- pwmp->pd_tim->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
- TIM_CCMR2_OC3PE |
- TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 |
- TIM_CCMR2_OC4PE;
+ pwmp->tim->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
+ TIM_CCMR1_OC1PE |
+ TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 |
+ TIM_CCMR1_OC2PE;
+ pwmp->tim->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
+ TIM_CCMR2_OC3PE |
+ TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 |
+ TIM_CCMR2_OC4PE;
}
else {
/* Driver re-configuration scenario, it must be stopped first.*/
- /* Really required ?????????? */
- pwmp->pd_tim->CR1 = 0; /* Timer stopped. */
- pwmp->pd_tim->CR2 = 0; /* Timer stopped. */
- pwmp->pd_tim->SMCR = 0; /* Slave mode disabled. */
- pwmp->pd_tim->CCR1 = 0; /* Comparator 1 disabled. */
- pwmp->pd_tim->CCR2 = 0; /* Comparator 2 disabled. */
- pwmp->pd_tim->CCR3 = 0; /* Comparator 3 disabled. */
- pwmp->pd_tim->CCR4 = 0; /* Comparator 4 disabled. */
- pwmp->pd_tim->CNT = 0;
+ pwmp->tim->CR1 = 0; /* Timer disabled. */
+ pwmp->tim->DIER = 0; /* All IRQs disabled. */
+ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
+ pwmp->tim->CCR1 = 0; /* Comparator 1 disabled. */
+ pwmp->tim->CCR2 = 0; /* Comparator 2 disabled. */
+ pwmp->tim->CCR3 = 0; /* Comparator 3 disabled. */
+ pwmp->tim->CCR4 = 0; /* Comparator 4 disabled. */
+ pwmp->tim->CNT = 0; /* Counter reset to zero. */
}
/* Timer configuration.*/
- pwmp->pd_tim->CR2 = pwmp->pd_config->pc_cr2;
- pwmp->pd_tim->PSC = pwmp->pd_config->pc_psc;
- pwmp->pd_tim->ARR = pwmp->pd_config->pc_arr;
+ psc = (clock / pwmp->config->frequency) - 1;
+ chDbgAssert((psc <= 0xFFFF) &&
+ ((psc + 1) * pwmp->config->frequency) == clock,
+ "pwm_lld_start(), #1", "invalid frequency");
+ pwmp->tim->PSC = (uint16_t)psc;
+ pwmp->tim->ARR = (uint16_t)(pwmp->period - 1);
+ pwmp->tim->CR2 = pwmp->config->cr2;
+
/* Output enables and polarities setup.*/
ccer = 0;
- switch (pwmp->pd_config->pc_channels[0].pcc_mode) {
+ switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC1P;
case PWM_OUTPUT_ACTIVE_HIGH:
@@ -407,7 +393,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
default:
;
}
- switch (pwmp->pd_config->pc_channels[1].pcc_mode) {
+ switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC2P;
case PWM_OUTPUT_ACTIVE_HIGH:
@@ -415,7 +401,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
default:
;
}
- switch (pwmp->pd_config->pc_channels[2].pcc_mode) {
+ switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC3P;
case PWM_OUTPUT_ACTIVE_HIGH:
@@ -423,7 +409,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
default:
;
}
- switch (pwmp->pd_config->pc_channels[3].pcc_mode) {
+ switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC4P;
case PWM_OUTPUT_ACTIVE_HIGH:
@@ -431,13 +417,46 @@ void pwm_lld_start(PWMDriver *pwmp) {
default:
;
}
- pwmp->pd_tim->CCER = ccer;
- pwmp->pd_tim->EGR = TIM_EGR_UG; /* Update event. */
- pwmp->pd_tim->SR = 0; /* Clear pending IRQs. */
- pwmp->pd_tim->DIER = pwmp->pd_config->pc_callback == NULL ? 0 : TIM_DIER_UIE;
- pwmp->pd_tim->BDTR = TIM_BDTR_MOE;
+#if STM32_PWM_USE_ADVANCED
+ if (&PWMD1 == pwmp) {
+ switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= TIM_CCER_CC1NP;
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= TIM_CCER_CC1NE;
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= TIM_CCER_CC2NP;
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= TIM_CCER_CC2NE;
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= TIM_CCER_CC3NP;
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= TIM_CCER_CC3NE;
+ default:
+ ;
+ }
+ }
+#endif /* STM32_PWM_USE_ADVANCED*/
+
+ pwmp->tim->CCER = ccer;
+ pwmp->tim->EGR = TIM_EGR_UG; /* Update event. */
+ pwmp->tim->DIER = pwmp->config->callback == NULL ? 0 : TIM_DIER_UIE;
+ pwmp->tim->SR = 0; /* Clear pending IRQs. */
+#if STM32_PWM_USE_ADVANCED
+ pwmp->tim->BDTR = pwmp->config->bdtr | TIM_BDTR_MOE;
+#else
+ pwmp->tim->BDTR = TIM_BDTR_MOE;
+#endif
/* Timer configured and started.*/
- pwmp->pd_tim->CR1 = TIM_CR1_ARPE | TIM_CR1_URS | TIM_CR1_CEN;
+ pwmp->tim->CR1 = TIM_CR1_ARPE | TIM_CR1_URS | TIM_CR1_CEN;
}
/**
@@ -448,20 +467,13 @@ void pwm_lld_start(PWMDriver *pwmp) {
* @notapi
*/
void pwm_lld_stop(PWMDriver *pwmp) {
+
/* If in ready state then disables the PWM clock.*/
- if (pwmp->pd_state == PWM_READY) {
- pwmp->pd_enabled_channels = 0; /* All channels disabled. */
- pwmp->pd_tim->CR1 = 0;
- pwmp->pd_tim->CR2 = 0;
- pwmp->pd_tim->CCER = 0; /* Outputs disabled. */
- pwmp->pd_tim->CCR1 = 0; /* Comparator 1 disabled. */
- pwmp->pd_tim->CCR2 = 0; /* Comparator 2 disabled. */
- pwmp->pd_tim->CCR3 = 0; /* Comparator 3 disabled. */
- pwmp->pd_tim->CCR4 = 0; /* Comparator 4 disabled. */
- pwmp->pd_tim->BDTR = 0;
- pwmp->pd_tim->DIER = 0;
- pwmp->pd_tim->SR = 0;
- pwmp->pd_tim->EGR = TIM_EGR_UG; /* Update event. */
+ if (pwmp->state == PWM_READY) {
+ pwmp->tim->CR1 = 0; /* Timer disabled. */
+ pwmp->tim->DIER = 0; /* All IRQs disabled. */
+ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
+ pwmp->tim->BDTR = 0;
#if STM32_PWM_USE_TIM1
if (&PWMD1 == pwmp) {
@@ -499,6 +511,9 @@ void pwm_lld_stop(PWMDriver *pwmp) {
/**
* @brief Enables a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note The function has effect at the next cycle start.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -510,23 +525,26 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width) {
- *(&pwmp->pd_tim->CCR1 + (channel * 2)) = width; /* New duty cycle. */
- if ((pwmp->pd_enabled_channels & (1 << channel)) == 0) {
- /* The channel is not enabled yet.*/
- pwmp->pd_enabled_channels |= (1 << channel);
- /* If there is a callback associated to the channel then the proper
- interrupt is cleared and enabled.*/
- if (pwmp->pd_config->pc_channels[channel].pcc_callback) {
- pwmp->pd_tim->SR = ~(2 << channel);
- pwmp->pd_tim->DIER |= (2 << channel);
+ *(&pwmp->tim->CCR1 + (channel * 2)) = width; /* New duty cycle. */
+ /* If there is a callback defined for the channel then the associated
+ interrupt must be enabled.*/
+ if (pwmp->config->channels[channel].callback != NULL) {
+ uint32_t dier = pwmp->tim->DIER;
+ /* If the IRQ is not already enabled care must be taken to clear it,
+ it is probably already pending because the timer is running.*/
+ if ((dier & (2 << channel)) == 0) {
+ pwmp->tim->DIER = dier | (2 << channel);
+ pwmp->tim->SR = ~(2 << channel);
}
}
}
/**
* @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
+ * @note The function has effect at the next cycle start.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -535,9 +553,8 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
*/
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
- *(&pwmp->pd_tim->CCR1 + (channel * 2)) = 0;
- pwmp->pd_tim->DIER &= ~(2 << channel);
- pwmp->pd_enabled_channels &= ~(1 << channel);
+ *(&pwmp->tim->CCR1 + (channel * 2)) = 0;
+ pwmp->tim->DIER &= ~(2 << channel);
}
#endif /* HAL_USE_PWM */
diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h
index 1e9dd855a..2b3ce7183 100644
--- a/os/hal/platforms/STM32/pwm_lld.h
+++ b/os/hal/platforms/STM32/pwm_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -37,15 +38,55 @@
/**
* @brief Number of PWM channels per PWM driver.
*/
-#define PWM_CHANNELS 4
+#define PWM_CHANNELS 4
+
+/**
+ * @brief Complementary output modes mask.
+ * @note This is an STM32-specific setting.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_MASK 0xF0
+
+/**
+ * @brief Complementary output not driven.
+ * @note This is an STM32-specific setting.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_DISABLED 0x00
+
+/**
+ * @brief Complementary output, active is logic level one.
+ * @note This is an STM32-specific setting.
+ * @note This setting is only available if the configuration option
+ * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
+ * timers TIM1 and TIM8.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH 0x10
+
+/**
+ * @brief Complementary output, active is logic level zero.
+ * @note This is an STM32-specific setting.
+ * @note This setting is only available if the configuration option
+ * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
+ * timers TIM1 and TIM8.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW 0x20
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
- * @brief PWM1 driver enable switch.
- * @details If set to @p TRUE the support for PWM1 is included.
+ * @brief If advanced timer features switch.
+ * @details If set to @p TRUE the advanced features for TIM1 and TIM8 are
+ * enabled.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_PWM_USE_ADVANCED) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_ADVANCED TRUE
+#endif
+
+/**
+ * @brief PWMD1 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD1 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM1) || defined(__DOXYGEN__)
@@ -53,8 +94,8 @@
#endif
/**
- * @brief PWM2 driver enable switch.
- * @details If set to @p TRUE the support for PWM2 is included.
+ * @brief PWMD2 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD2 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM2) || defined(__DOXYGEN__)
@@ -62,8 +103,8 @@
#endif
/**
- * @brief PWM3 driver enable switch.
- * @details If set to @p TRUE the support for PWM3 is included.
+ * @brief PWMD3 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD3 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM3) || defined(__DOXYGEN__)
@@ -71,8 +112,8 @@
#endif
/**
- * @brief PWM4 driver enable switch.
- * @details If set to @p TRUE the support for PWM4 is included.
+ * @brief PWMD4 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD4 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM4) || defined(__DOXYGEN__)
@@ -80,8 +121,8 @@
#endif
/**
- * @brief PWM5 driver enable switch.
- * @details If set to @p TRUE the support for PWM5 is included.
+ * @brief PWMD5 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD5 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM5) || defined(__DOXYGEN__)
@@ -89,35 +130,35 @@
#endif
/**
- * @brief PWM1 interrupt priority level setting.
+ * @brief PWMD1 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM1_IRQ_PRIORITY 7
#endif
/**
- * @brief PWM2 interrupt priority level setting.
+ * @brief PWMD2 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM2_IRQ_PRIORITY 7
#endif
/**
- * @brief PWM3 interrupt priority level setting.
+ * @brief PWMD3 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM3_IRQ_PRIORITY 7
#endif
/**
- * @brief PWM4 interrupt priority level setting.
+ * @brief PWMD4 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM4_IRQ_PRIORITY 7
#endif
/**
- * @brief PWM5 interrupt priority level setting.
+ * @brief PWMD5 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM5_IRQ_PRIORITY 7
@@ -153,11 +194,20 @@
#error "PWM driver activated but no TIM peripheral assigned"
#endif
+#if STM32_PWM_USE_ADVANCED && !STM32_PWM_USE_TIM1
+#error "advanced mode selected but no advanced timer assigned"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
+ * @brief PWM mode type.
+ */
+typedef uint32_t pwmmode_t;
+
+/**
* @brief PWM channel type.
*/
typedef uint8_t pwmchannel_t;
@@ -168,31 +218,19 @@ typedef uint8_t pwmchannel_t;
typedef uint16_t pwmcnt_t;
/**
- * @brief Type of a structure representing an PWM driver.
- */
-typedef struct PWMDriver PWMDriver;
-
-/**
- * @brief PWM notification callback type.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- */
-typedef void (*pwmcallback_t)(PWMDriver *pwmp);
-
-/**
* @brief PWM driver channel configuration structure.
*/
typedef struct {
/**
* @brief Channel active logic level.
*/
- pwmmode_t pcc_mode;
+ pwmmode_t mode;
/**
* @brief Channel callback pointer.
* @note This callback is invoked on the channel compare event. If set to
* @p NULL then the callback is disabled.
*/
- pwmcallback_t pcc_callback;
+ pwmcallback_t callback;
/* End of the mandatory fields.*/
} PWMChannelConfig;
@@ -201,29 +239,40 @@ typedef struct {
*/
typedef struct {
/**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ uint32_t frequency;
+ /**
+ * @brief PWM period in ticks.
+ * @note The low level can use assertions in order to catch invalid
+ * period specifications.
+ */
+ pwmcnt_t period;
+ /**
* @brief Periodic callback pointer.
* @note This callback is invoked on PWM counter reset. If set to
* @p NULL then the callback is disabled.
*/
- pwmcallback_t pc_callback;
+ pwmcallback_t callback;
/**
* @brief Channels configurations.
*/
- PWMChannelConfig pc_channels[PWM_CHANNELS];
+ PWMChannelConfig channels[PWM_CHANNELS];
/* End of the mandatory fields.*/
/**
- * @brief TIM PSC (pre-scaler) register initialization data.
- */
- uint16_t pc_psc;
- /**
- * @brief TIM ARR (auto-reload) register initialization data.
- */
- uint16_t pc_arr;
- /**
* @brief TIM CR2 register initialization data.
* @note The value of this field should normally be equal to zero.
*/
- uint16_t pc_cr2;
+ uint16_t cr2;
+#if STM32_PWM_USE_ADVANCED || defined(__DOXYGEN__)
+ /**
+ * @brief TIM BDTR (break & dead-time) register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ */ \
+ uint16_t bdtr;
+#endif
} PWMConfig;
/**
@@ -233,23 +282,23 @@ struct PWMDriver {
/**
* @brief Driver state.
*/
- pwmstate_t pd_state;
+ pwmstate_t state;
/**
* @brief Current driver configuration data.
*/
- const PWMConfig *pd_config;
+ const PWMConfig *config;
+ /**
+ * @brief Current PWM period in ticks.
+ */
+ pwmcnt_t period;
#if defined(PWM_DRIVER_EXT_FIELDS)
PWM_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
- * @brief Bit mask of the enabled channels.
- */
- uint32_t pd_enabled_channels;
- /**
* @brief Pointer to the TIMx registers block.
*/
- TIM_TypeDef *pd_tim;
+ TIM_TypeDef *tim;
};
/*===========================================================================*/
@@ -257,88 +306,23 @@ struct PWMDriver {
/*===========================================================================*/
/**
- * @brief PWM clock prescaler initialization utility.
- * @note The real clock value is rounded to the lower valid value, please
- * make sure that the source clock frequency is a multiple of the
- * requested PWM clock frequency.
- * @note The calculated value must fit into an unsigned 16 bits integer.
- *
- * @param[in] clksrc clock source frequency, depending on the target timer
- * cell it can be one of:
- * - STM32_TIMCLK1
- * - STM32_TIMCLK2
- * .
- * Please refer to the STM32 HAL driver documentation
- * and/or the STM32 Reference Manual for the right clock
- * source.
- * @param[in] pwmclk PWM clock frequency in cycles
- * @return The value to be stored in the @p pc_psc field of the
- * @p PWMConfig structure.
- */
-#define PWM_COMPUTE_PSC(clksrc, pwmclk) \
- ((uint16_t)(((clksrc) / (pwmclk)) - 1))
-
-/**
- * @brief PWM cycle period initialization utility.
- * @note The calculated value must fit into an unsigned 16 bits integer.
- *
- * @param[in] pwmclk PWM clock frequency in cycles
- * @param[in] pwmperiod PWM cycle period in nanoseconds
- * @return The value to be stored in the @p pc_arr field of the
- * @p PWMConfig structure.
- */
-#define PWM_COMPUTE_ARR(pwmclk, pwmperiod) \
- ((uint16_t)(((pwmclk) / (1000000000 / (pwmperiod))) - 1))
-
-/**
- * @brief Converts from fraction to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify tenths of thousandth but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] numerator numerator of the fraction
- * @param[in] denominator percentage as an integer between 0 and numerator
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_FRACTION_TO_WIDTH(pwmp, numerator, denominator) \
- ((uint16_t)((((uint32_t)(pwmp)->pd_config->pc_arr + 1UL) * \
- (uint32_t)(denominator)) / (uint32_t)(numerator)))
-
-/**
- * @brief Converts from degrees to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify hundredths of degrees but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] degrees degrees as an integer between 0 and 36000
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \
- PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees)
-
-/**
- * @brief Converts from percentage to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify tenths of thousandth but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note The function has effect at the next cycle start.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] percentage percentage as an integer between 0 and 10000
- * @return The pulse width to be passed to @p pwmEnableChannel().
+ * @param[in] period new cycle time in ticks
*
- * @api
+ * @notapi
*/
-#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
- PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
+#define pwm_lld_change_period(pwmp, period) \
+ ((pwmp)->tim->ARR = (uint16_t)((period) - 1))
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c
new file mode 100644
index 000000000..a88ad53fa
--- /dev/null
+++ b/os/hal/platforms/STM32/sdc_lld.c
@@ -0,0 +1,722 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/sdc_lld.c
+ * @brief STM32 SDC subsystem low level driver source.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#include <string.h>
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief SDCD1 driver identifier.*/
+SDCDriver SDCD1;
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+#if STM32_SDC_UNALIGNED_SUPPORT
+/**
+ * @brief Buffer for temporary storage during unaligned transfers.
+ */
+static union {
+ uint32_t alignment;
+ uint8_t buf[SDC_BLOCK_SIZE];
+} u;
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer, it must be aligned to
+ * four bytes boundary
+ * @param[in] n number of blocks to read
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @notapi
+ */
+static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n) {
+ uint32_t resp[1];
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Prepares the DMA channel for reading.*/
+ dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
+ (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
+ (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
+ DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
+ DMA_CCR1_MINC);
+
+ /* Setting up data transfer.
+ Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE;
+ SDIO->DLEN = n * SDC_BLOCK_SIZE;
+ SDIO->DCTRL = SDIO_DCTRL_DTDIR |
+ SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ /* DMA channel activation.*/
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ /* Read multiple blocks command.*/
+ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
+ startblk *= SDC_BLOCK_SIZE;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK,
+ startblk, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto error;
+
+ chSysLock();
+ if (SDIO->MASK != 0) {
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_read_multiple(), #1", "not NULL");
+ sdcp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_read_multiple(), #2", "not NULL");
+ }
+ if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
+ chSysUnlock();
+ goto error;
+ }
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->DCTRL = 0;
+ chSysUnlock();
+
+ return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
+error:
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = 0;
+ SDIO->DCTRL = 0;
+ return TRUE;
+}
+
+/**
+ * @brief Reads one block.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer, it must be aligned to
+ * four bytes boundary
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @notapi
+ */
+static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf) {
+ uint32_t resp[1];
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Prepares the DMA channel for reading.*/
+ dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
+ SDC_BLOCK_SIZE / sizeof (uint32_t), buf,
+ (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
+ DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
+ DMA_CCR1_MINC);
+
+ /* Setting up data transfer.
+ Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE;
+ SDIO->DLEN = SDC_BLOCK_SIZE;
+ SDIO->DCTRL = SDIO_DCTRL_DTDIR |
+ SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ /* DMA channel activation.*/
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ /* Read single block command.*/
+ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
+ startblk *= SDC_BLOCK_SIZE;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK,
+ startblk, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto error;
+
+ chSysLock();
+ if (SDIO->MASK != 0) {
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_read_single(), #1", "not NULL");
+ sdcp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_read_single(), #2", "not NULL");
+ }
+ if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
+ chSysUnlock();
+ goto error;
+ }
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->DCTRL = 0;
+ chSysUnlock();
+
+ return FALSE;
+error:
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = 0;
+ SDIO->DCTRL = 0;
+ return TRUE;
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer, it must be aligned to
+ * four bytes boundary
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @notapi
+ */
+static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n) {
+ uint32_t resp[1];
+
+ /* Checks for errors and waits for the card to be ready for writing.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
+ (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
+ (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
+ DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
+ DMA_CCR1_MINC | DMA_CCR1_DIR);
+
+ /* Write multiple blocks command.*/
+ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
+ startblk *= SDC_BLOCK_SIZE;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK,
+ startblk, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ return TRUE;
+
+ /* Setting up data transfer.
+ Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE |
+ SDIO_MASK_STBITERRIE;
+ SDIO->DLEN = n * SDC_BLOCK_SIZE;
+ SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ /* DMA channel activation.*/
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ /* Note the mask is checked before going to sleep because the interrupt
+ may have occurred before reaching the critical zone.*/
+ chSysLock();
+ if (SDIO->MASK != 0) {
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_write_multiple(), #1", "not NULL");
+ sdcp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_write_multiple(), #2", "not NULL");
+ }
+ if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
+ chSysUnlock();
+ goto error;
+ }
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->DCTRL = 0;
+ chSysUnlock();
+
+ return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
+error:
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = 0;
+ SDIO->DCTRL = 0;
+ return TRUE;
+}
+
+/**
+ * @brief Writes one block.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer, it must be aligned to
+ * four bytes boundary
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @notapi
+ */
+static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf) {
+ uint32_t resp[1];
+
+ /* Checks for errors and waits for the card to be ready for writing.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
+ SDC_BLOCK_SIZE / sizeof (uint32_t), buf,
+ (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
+ DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
+ DMA_CCR1_MINC | DMA_CCR1_DIR);
+
+ /* Write single block command.*/
+ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
+ startblk *= SDC_BLOCK_SIZE;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK,
+ startblk, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ return TRUE;
+
+ /* Setting up data transfer.
+ Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE |
+ SDIO_MASK_STBITERRIE;
+ SDIO->DLEN = SDC_BLOCK_SIZE;
+ SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ /* DMA channel activation.*/
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ /* Note the mask is checked before going to sleep because the interrupt
+ may have occurred before reaching the critical zone.*/
+ chSysLock();
+ if (SDIO->MASK != 0) {
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_write_single(), #1", "not NULL");
+ sdcp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_write_single(), #2", "not NULL");
+ }
+ if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
+ chSysUnlock();
+ goto error;
+ }
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->DCTRL = 0;
+ chSysUnlock();
+
+ return FALSE;
+error:
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = 0;
+ SDIO->DCTRL = 0;
+ return TRUE;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief SDIO IRQ handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SDIO_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ chSysLockFromIsr();
+ if (SDCD1.thread != NULL) {
+ chSchReadyI(SDCD1.thread);
+ SDCD1.thread = NULL;
+ }
+ chSysUnlockFromIsr();
+
+ /* Disables the source but the status flags are not reset because the
+ read/write functions need to check them.*/
+ SDIO->MASK = 0;
+
+ CH_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SDC driver initialization.
+ *
+ * @notapi
+ */
+void sdc_lld_init(void) {
+
+ sdcObjectInit(&SDCD1);
+ SDCD1.thread = NULL;
+}
+
+/**
+ * @brief Configures and activates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object, must be @p NULL,
+ * this driver does not require any configuration
+ *
+ * @notapi
+ */
+void sdc_lld_start(SDCDriver *sdcp) {
+
+ if (sdcp->state == SDC_STOP) {
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_4, NULL, NULL);
+ dmaChannelSetPeripheral(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], &SDIO->FIFO);
+ NVICEnableVector(SDIO_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY));
+ RCC->AHBENR |= RCC_AHBENR_SDIOEN;
+ }
+ /* Configuration, card clock is initially stopped.*/
+ SDIO->POWER = 0;
+ SDIO->CLKCR = 0;
+ SDIO->DCTRL = 0;
+ SDIO->DTIMER = STM32_SDC_DATATIMEOUT;
+}
+
+/**
+ * @brief Deactivates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop(SDCDriver *sdcp) {
+
+ if ((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE)) {
+ SDIO->POWER = 0;
+ SDIO->CLKCR = 0;
+ SDIO->DCTRL = 0;
+ SDIO->DTIMER = 0;
+
+ /* Clock deactivation.*/
+ NVICDisableVector(SDIO_IRQn);
+ dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_4);
+ }
+}
+
+/**
+ * @brief Starts the SDIO clock and sets it to init mode (400KHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_start_clk(SDCDriver *sdcp) {
+
+ (void)sdcp;
+ /* Initial clock setting: 400KHz, 1bit mode.*/
+ SDIO->CLKCR = STM32_SDIO_DIV_LS;
+ SDIO->POWER |= SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1;
+ SDIO->CLKCR |= SDIO_CLKCR_CLKEN;
+}
+
+/**
+ * @brief Sets the SDIO clock to data mode (25MHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_set_data_clk(SDCDriver *sdcp) {
+
+ (void)sdcp;
+ SDIO->CLKCR = (SDIO->CLKCR & 0xFFFFFF00) | STM32_SDIO_DIV_HS;
+}
+
+/**
+ * @brief Stops the SDIO clock.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop_clk(SDCDriver *sdcp) {
+
+ (void)sdcp;
+ SDIO->CLKCR = 0;
+ SDIO->POWER = 0;
+}
+
+/**
+ * @brief Switches the bus to 4 bits mode.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] mode bus mode
+ *
+ * @notapi
+ */
+void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
+ uint32_t clk = SDIO->CLKCR & ~SDIO_CLKCR_WIDBUS;
+
+ (void)sdcp;
+ switch (mode) {
+ case SDC_MODE_1BIT:
+ SDIO->CLKCR = clk;
+ break;
+ case SDC_MODE_4BIT:
+ SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_0;
+ break;
+ case SDC_MODE_8BIT:
+ SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_1;
+ }
+}
+
+/**
+ * @brief Sends an SDIO command with no response expected.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ *
+ * @notapi
+ */
+void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
+
+ (void)sdcp;
+ SDIO->ARG = arg;
+ SDIO->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN;
+ while ((SDIO->STA & SDIO_STA_CMDSENT) == 0)
+ ;
+ SDIO->ICR = SDIO_ICR_CMDSENTC;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected.
+ * @note The CRC is not verified.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed because timeout, CRC check or
+ * other errors.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ (void)sdcp;
+ SDIO->ARG = arg;
+ SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
+ while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
+ if ((sta & (SDIO_STA_CTIMEOUT)) != 0)
+ return TRUE;
+ *resp = SDIO->RESP1;
+ return FALSE;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed because timeout, CRC check or
+ * other errors.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ (void)sdcp;
+ SDIO->ARG = arg;
+ SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
+ while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
+ if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
+ return TRUE;
+ *resp = SDIO->RESP1;
+ return FALSE;
+}
+
+/**
+ * @brief Sends an SDIO command with a long response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (four words)
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed because timeout, CRC check or
+ * other errors.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+
+ uint32_t sta;
+
+ (void)sdcp;
+ SDIO->ARG = arg;
+ SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_WAITRESP_1 |
+ SDIO_CMD_CPSMEN;
+ while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
+ if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
+ return TRUE;
+ *resp = SDIO->RESP1;
+ return FALSE;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] n number of blocks to read
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n) {
+
+#if STM32_SDC_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < n; i++) {
+ if (sdc_lld_read_single(sdcp, startblk, u.buf))
+ return TRUE;
+ memcpy(buf, u.buf, SDC_BLOCK_SIZE);
+ buf += SDC_BLOCK_SIZE;
+ startblk++;
+ }
+ return FALSE;
+ }
+#endif
+ if (n == 1)
+ return sdc_lld_read_single(sdcp, startblk, buf);
+ return sdc_lld_read_multiple(sdcp, startblk, buf, n);
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n) {
+
+ #if STM32_SDC_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < n; i++) {
+ memcpy(u.buf, buf, SDC_BLOCK_SIZE);
+ buf += SDC_BLOCK_SIZE;
+ if (sdc_lld_write_single(sdcp, startblk, u.buf))
+ return TRUE;
+ startblk++;
+ }
+ return FALSE;
+ }
+#endif
+ if (n == 1)
+ return sdc_lld_write_single(sdcp, startblk, buf);
+ return sdc_lld_write_multiple(sdcp, startblk, buf, n);
+}
+
+#endif /* HAL_USE_SDC */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h
new file mode 100644
index 000000000..5466eacad
--- /dev/null
+++ b/os/hal/platforms/STM32/sdc_lld.h
@@ -0,0 +1,203 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/sdc_lld.h
+ * @brief STM32 SDC subsystem low level driver header.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#ifndef _SDC_LLD_H_
+#define _SDC_LLD_H_
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief SDIO data timeout in SDIO clock cycles.
+ */
+#if !defined(STM32_SDC_DATATIMEOUT) || defined(__DOXYGEN__)
+#define STM32_SDC_DATATIMEOUT 0x000FFFFF
+#endif
+
+/**
+ * @brief SDIO DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_SDC_SDIO_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDIO_DMA_PRIORITY 3
+#endif
+
+/**
+ * @brief SDIO interrupt priority level setting.
+ */
+#if !defined(STM32_SDC_SDIO_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDIO_IRQ_PRIORITY 9
+#endif
+
+/**
+ * @brief SDIO support for unaligned transfers.
+ */
+#if !defined(STM32_SDC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__)
+#define STM32_SDC_UNALIGNED_SUPPORT TRUE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !STM32_HAS_SDIO
+#error "SDIO not present in the selected device"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*
+ * SDIO clock divider.
+ */
+#if STM32_HCLK > 48000000
+#define STM32_SDIO_DIV_HS 0x01
+#define STM32_SDIO_DIV_LS 0xB2
+#else
+#define STM32_SDIO_DIV_HS 0x00
+#define STM32_SDIO_DIV_LS 0x76
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of SDIO bus mode.
+ */
+typedef enum {
+ SDC_MODE_1BIT = 0,
+ SDC_MODE_4BIT,
+ SDC_MODE_8BIT
+} sdcbusmode_t;
+
+/**
+ * @brief Type of card flags.
+ */
+typedef uint32_t sdcmode_t;
+
+/**
+ * @brief Type of a structure representing an SDC driver.
+ */
+typedef struct SDCDriver SDCDriver;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ uint32_t dummy;
+} SDCConfig;
+
+/**
+ * @brief Structure representing an SDC driver.
+ */
+struct SDCDriver {
+ /**
+ * @brief Driver state.
+ */
+ sdcstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const SDCConfig *config;
+ /**
+ * @brief Various flags regarding the mounted card.
+ */
+ sdcmode_t cardmode;
+ /**
+ * @brief Card CID.
+ */
+ uint32_t cid[4];
+ /**
+ * @brief Card CSD.
+ */
+ uint32_t csd[4];
+ /**
+ * @brief Card RCA.
+ */
+ uint32_t rca;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Tthread waiting for I/O completion IRQ.
+ */
+ Thread *thread;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern SDCDriver SDCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdc_lld_init(void);
+ void sdc_lld_start(SDCDriver *sdcp);
+ void sdc_lld_stop(SDCDriver *sdcp);
+ void sdc_lld_start_clk(SDCDriver *sdcp);
+ void sdc_lld_set_data_clk(SDCDriver *sdcp);
+ void sdc_lld_stop_clk(SDCDriver *sdcp);
+ void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode);
+ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg);
+ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n);
+ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n);
+ bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp);
+ bool_t sdc_lld_is_write_protected(SDCDriver *sdcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SDC */
+
+#endif /* _SDC_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/serial_lld.c b/os/hal/platforms/STM32/serial_lld.c
index b20c2a933..5aaa60de9 100644
--- a/os/hal/platforms/STM32/serial_lld.c
+++ b/os/hal/platforms/STM32/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/serial_lld.h b/os/hal/platforms/STM32/serial_lld.h
index d16e1923d..ceeccff67 100644
--- a/os/hal/platforms/STM32/serial_lld.h
+++ b/os/hal/platforms/STM32/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c
index dfe72822a..d8ae657a7 100644
--- a/os/hal/platforms/STM32/spi_lld.c
+++ b/os/hal/platforms/STM32/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,8 +67,8 @@ static uint16_t dummyrx;
* @param[in] spip pointer to the @p SPIDriver object
*/
#define dma_stop(spip) { \
- dmaChannelDisable(spip->spd_dmatx); \
- dmaChannelDisable(spip->spd_dmarx); \
+ dmaChannelDisable(spip->dmatx); \
+ dmaChannelDisable(spip->dmarx); \
}
/**
@@ -76,16 +77,26 @@ static uint16_t dummyrx;
* @param[in] spip pointer to the @p SPIDriver object
*/
#define dma_start(spip) { \
- dmaChannelEnable((spip)->spd_dmarx); \
- dmaChannelEnable((spip)->spd_dmatx); \
+ dmaChannelEnable((spip)->dmarx); \
+ dmaChannelEnable((spip)->dmatx); \
}
/**
- * @brief Shared end-of-transfer service routine.
+ * @brief Shared end-of-rx service routine.
*
* @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_interrupt(SPIDriver *spip) {
+static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)flags;
+#endif
/* Stop everything.*/
dma_stop(spip);
@@ -95,114 +106,29 @@ static void serve_interrupt(SPIDriver *spip) {
_spi_isr_code(spip);
}
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
/**
- * @brief SPI1 RX DMA interrupt handler (channel 2).
+ * @brief Shared end-of-tx service routine.
*
- * @isr
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
+static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
- STM32_SPI_SPI1_DMA_ERROR_HOOK();
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ (void)spip;
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
}
- serve_interrupt(&SPID1);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief SPI1 TX DMA interrupt handler (channel 3).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI1_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
-
- CH_IRQ_EPILOGUE();
-}
+#else
+ (void)spip;
+ (void)flags;
#endif
-
-#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
-/**
- * @brief SPI2 RX DMA interrupt handler (channel 4).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
- STM32_SPI_SPI2_DMA_ERROR_HOOK();
- }
- serve_interrupt(&SPID2);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
-
- CH_IRQ_EPILOGUE();
}
-/**
- * @brief SPI2 TX DMA interrupt handler (channel 5).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI2_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
-
- CH_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
-/**
- * @brief SPI3 RX DMA interrupt handler (DMA2, channel 1).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA2->ISR & DMA_ISR_TEIF1) != 0) {
- STM32_SPI_SPI3_DMA_ERROR_HOOK();
- }
- serve_interrupt(&SPID3);
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief SPI3 TX DMA2 interrupt handler (DMA2, channel 2).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI3_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
-
- CH_IRQ_EPILOGUE();
-}
-#endif
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
@@ -218,33 +144,27 @@ void spi_lld_init(void) {
dummytx = 0xFFFF;
#if STM32_SPI_USE_SPI1
- RCC->APB2RSTR = RCC_APB2RSTR_SPI1RST;
- RCC->APB2RSTR = 0;
spiObjectInit(&SPID1);
- SPID1.spd_thread = NULL;
- SPID1.spd_spi = SPI1;
- SPID1.spd_dmarx = STM32_DMA1_CH2;
- SPID1.spd_dmatx = STM32_DMA1_CH3;
+ SPID1.thread = NULL;
+ SPID1.spi = SPI1;
+ SPID1.dmarx = STM32_DMA1_CH2;
+ SPID1.dmatx = STM32_DMA1_CH3;
#endif
#if STM32_SPI_USE_SPI2
- RCC->APB1RSTR = RCC_APB1RSTR_SPI2RST;
- RCC->APB1RSTR = 0;
spiObjectInit(&SPID2);
- SPID2.spd_thread = NULL;
- SPID2.spd_spi = SPI2;
- SPID2.spd_dmarx = STM32_DMA1_CH4;
- SPID2.spd_dmatx = STM32_DMA1_CH5;
+ SPID2.thread = NULL;
+ SPID2.spi = SPI2;
+ SPID2.dmarx = STM32_DMA1_CH4;
+ SPID2.dmatx = STM32_DMA1_CH5;
#endif
#if STM32_SPI_USE_SPI3
- RCC->APB1RSTR = RCC_APB1RSTR_SPI3RST;
- RCC->APB1RSTR = 0;
spiObjectInit(&SPID3);
- SPID3.spd_thread = NULL;
- SPID3.spd_spi = SPI3;
- SPID3.spd_dmarx = STM32_DMA2_CH1;
- SPID3.spd_dmatx = STM32_DMA2_CH2;
+ SPID3.thread = NULL;
+ SPID3.spi = SPI3;
+ SPID3.dmarx = STM32_DMA2_CH1;
+ SPID3.dmatx = STM32_DMA2_CH2;
#endif
}
@@ -258,10 +178,14 @@ void spi_lld_init(void) {
void spi_lld_start(SPIDriver *spip) {
/* If in stopped state then enables the SPI and DMA clocks.*/
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
#if STM32_SPI_USE_SPI1
if (&SPID1 == spip) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA1_Channel2_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel3_IRQn,
@@ -271,7 +195,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
#if STM32_SPI_USE_SPI2
if (&SPID2 == spip) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA1_Channel4_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel5_IRQn,
@@ -281,7 +209,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
#if STM32_SPI_USE_SPI3
if (&SPID3 == spip) {
- dmaEnable(DMA2_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_1,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA2_Channel1_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY));
NVICEnableVector(DMA2_Channel2_IRQn,
@@ -291,23 +223,25 @@ void spi_lld_start(SPIDriver *spip) {
#endif
/* DMA setup.*/
- dmaChannelSetPeripheral(spip->spd_dmarx, &spip->spd_spi->DR);
- dmaChannelSetPeripheral(spip->spd_dmatx, &spip->spd_spi->DR);
+ dmaChannelSetPeripheral(spip->dmarx, &spip->spi->DR);
+ dmaChannelSetPeripheral(spip->dmatx, &spip->spi->DR);
}
/* More DMA setup.*/
- if ((spip->spd_config->spc_cr1 & SPI_CR1_DFF) == 0)
- spip->spd_dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
- DMA_CCR1_TEIE; /* 8 bits transfers. */
+ if ((spip->config->cr1 & SPI_CR1_DFF) == 0)
+ spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
+ DMA_CCR1_TEIE; /* 8 bits transfers. */
else
- spip->spd_dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
- DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 |
- DMA_CCR1_PSIZE_0; /* 16 bits transfers. */
+ spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
+ DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 |
+ DMA_CCR1_PSIZE_0; /* 16 bits transfers. */
/* SPI setup and enable.*/
- spip->spd_spi->CR1 = 0;
- spip->spd_spi->CR2 = SPI_CR2_SSOE | SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
- spip->spd_spi->CR1 = spip->spd_config->spc_cr1 | SPI_CR1_MSTR | SPI_CR1_SPE;
+ spip->spi->CR1 = 0;
+ spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR | SPI_CR1_SSM |
+ SPI_CR1_SSI;
+ spip->spi->CR2 = SPI_CR2_SSOE | SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
+ spip->spi->CR1 |= SPI_CR1_SPE;
}
/**
@@ -320,16 +254,17 @@ void spi_lld_start(SPIDriver *spip) {
void spi_lld_stop(SPIDriver *spip) {
/* If in ready state then disables the SPI clock.*/
- if (spip->spd_state == SPI_READY) {
+ if (spip->state == SPI_READY) {
/* SPI disable.*/
- spip->spd_spi->CR1 = 0;
+ spip->spi->CR1 = 0;
#if STM32_SPI_USE_SPI1
if (&SPID1 == spip) {
NVICDisableVector(DMA1_Channel2_IRQn);
NVICDisableVector(DMA1_Channel3_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN;
}
#endif
@@ -337,7 +272,8 @@ void spi_lld_stop(SPIDriver *spip) {
if (&SPID2 == spip) {
NVICDisableVector(DMA1_Channel4_IRQn);
NVICDisableVector(DMA1_Channel5_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN;
}
#endif
@@ -345,7 +281,8 @@ void spi_lld_stop(SPIDriver *spip) {
if (&SPID3 == spip) {
NVICDisableVector(DMA2_Channel1_IRQn);
NVICDisableVector(DMA2_Channel2_IRQn);
- dmaDisable(DMA2_ID);
+ dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1);
+ dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2);
RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN;
}
#endif
@@ -361,7 +298,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -374,7 +311,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -390,10 +327,10 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- dmaChannelSetup(spip->spd_dmarx, n, &dummyrx,
- spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
- dmaChannelSetup(spip->spd_dmatx, n, &dummytx,
- spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
+ dmaChannelSetup(spip->dmarx, n, &dummyrx,
+ spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
+ dmaChannelSetup(spip->dmatx, n, &dummytx,
+ spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
}
/**
@@ -414,11 +351,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- dmaChannelSetup(spip->spd_dmarx, n, rxbuf,
- spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
+ dmaChannelSetup(spip->dmarx, n, rxbuf,
+ spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
DMA_CCR1_EN);
- dmaChannelSetup(spip->spd_dmatx, n, txbuf,
- spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
+ dmaChannelSetup(spip->dmatx, n, txbuf,
+ spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
DMA_CCR1_EN);
}
@@ -437,10 +374,10 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- dmaChannelSetup(spip->spd_dmarx, n, &dummyrx,
- spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
- dmaChannelSetup(spip->spd_dmatx, n, txbuf,
- spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
+ dmaChannelSetup(spip->dmarx, n, &dummyrx,
+ spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
+ dmaChannelSetup(spip->dmatx, n, txbuf,
+ spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
DMA_CCR1_EN);
}
@@ -459,11 +396,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- dmaChannelSetup(spip->spd_dmarx, n, rxbuf,
- spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
+ dmaChannelSetup(spip->dmarx, n, rxbuf,
+ spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
DMA_CCR1_EN);
- dmaChannelSetup(spip->spd_dmatx, n, &dummytx,
- spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
+ dmaChannelSetup(spip->dmatx, n, &dummytx,
+ spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
}
/**
@@ -480,10 +417,10 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_spi->DR = frame;
- while ((spip->spd_spi->SR & SPI_SR_RXNE) == 0)
+ spip->spi->DR = frame;
+ while ((spip->spi->SR & SPI_SR_RXNE) == 0)
;
- return spip->spd_spi->DR;
+ return spip->spi->DR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h
index 9e29c5d68..6f1e94096 100644
--- a/os/hal/platforms/STM32/spi_lld.h
+++ b/os/hal/platforms/STM32/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -72,7 +73,7 @@
* over the TX channel.
*/
#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_DMA_PRIORITY 2
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
#endif
/**
@@ -82,7 +83,7 @@
* over the TX channel.
*/
#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_DMA_PRIORITY 2
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
#endif
/**
@@ -92,7 +93,7 @@
* over the TX channel.
*/
#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_DMA_PRIORITY 2
+#define STM32_SPI_SPI3_DMA_PRIORITY 1
#endif
/**
@@ -117,30 +118,12 @@
#endif
/**
- * @brief SPI1 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @brief SPI DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
*/
-#if !defined(STM32_SPI_SPI1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief SPI2 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_SPI_SPI2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief SPI3 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_SPI_SPI3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
#endif
/*===========================================================================*/
@@ -163,6 +146,10 @@
#error "SPI driver activated but no SPI peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -187,20 +174,20 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SPI initialization data.
*/
- uint16_t spc_cr1;
+ uint16_t cr1;
} SPIConfig;
/**
@@ -210,25 +197,25 @@ struct SPIDriver{
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -238,19 +225,19 @@ struct SPIDriver{
/**
* @brief Pointer to the SPIx registers block.
*/
- SPI_TypeDef *spd_spi;
+ SPI_TypeDef *spi;
/**
* @brief Pointer to the receive DMA channel registers block.
*/
- stm32_dma_channel_t *spd_dmarx;
+ stm32_dma_channel_t *dmarx;
/**
* @brief Pointer to the transmit DMA channel registers block.
*/
- stm32_dma_channel_t *spd_dmatx;
+ stm32_dma_channel_t *dmatx;
/**
* @brief DMA priority bit mask.
*/
- uint32_t spd_dmaccr;
+ uint32_t dmaccr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/stm32_dma.c b/os/hal/platforms/STM32/stm32_dma.c
index e25e05ad1..2232df448 100644
--- a/os/hal/platforms/STM32/stm32_dma.c
+++ b/os/hal/platforms/STM32/stm32_dma.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -22,23 +23,43 @@
* @brief STM32 DMA helper driver code.
*
* @addtogroup STM32_DMA
+ * @details DMA sharing helper driver. In the STM32 the DMA channels are a
+ * shared resource, this driver allows to allocate and free DMA
+ * channels at runtime in order to allow all the other device
+ * drivers to coordinate the access to the resource.
+ * @note The DMA ISR handlers are all declared into this module because
+ * sharing, the various device drivers can associate a callback to
+ * IRSs when allocating channels.
* @{
*/
#include "ch.h"
#include "hal.h"
+#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
-/* Driver local variables. */
+/* Driver local variables and types. */
/*===========================================================================*/
-static cnt_t dmacnt1;
+/**
+ * @brief DMA ISR redirector type.
+ */
+typedef struct {
+ stm32_dmaisr_t dmaisrfunc;
+ void *dmaisrparam;
+} dma_isr_redir_t;
+
+static uint32_t dmamsk1;
+static dma_isr_redir_t dma1[7];
+
#if STM32_HAS_DMA2
-static cnt_t dmacnt2;
+static uint32_t dmamsk2;
+static dma_isr_redir_t dma2[5];
#endif
/*===========================================================================*/
@@ -49,6 +70,258 @@ static cnt_t dmacnt2;
/* Driver interrupt handlers. */
/*===========================================================================*/
+/**
+ * @brief DMA1 channel 1 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
+ if (dma1[0].dmaisrfunc)
+ dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 2 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
+ if (dma1[1].dmaisrfunc)
+ dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 3 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
+ if (dma1[2].dmaisrfunc)
+ dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 4 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
+ if (dma1[3].dmaisrfunc)
+ dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 5 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
+ if (dma1[4].dmaisrfunc)
+ dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 6 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
+ if (dma1[5].dmaisrfunc)
+ dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 7 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
+ if (dma1[6].dmaisrfunc)
+ dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 channel 1 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
+ if (dma2[0].dmaisrfunc)
+ dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 2 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
+ if (dma2[1].dmaisrfunc)
+ dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 3 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3);
+ if (dma2[2].dmaisrfunc)
+ dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if defined(STM32F10X_CL) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 channel 4 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ if (dma2[3].dmaisrfunc)
+ dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 5 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
+ if (dma2[4].dmaisrfunc)
+ dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#else /* !STM32F10X_CL */
+/**
+ * @brief DMA2 channels 4 and 5 shared interrupt handler.
+ * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a
+ * bit less efficient because an extra check.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ /* Check on channel 4.*/
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
+ if (isr & DMA_ISR_GIF1) {
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
+ if (dma2[3].dmaisrfunc)
+ dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
+ }
+
+ /* Check on channel 5.*/
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
+ if (isr & DMA_ISR_GIF1) {
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
+ if (dma2[4].dmaisrfunc)
+ dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
+ }
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* !STM32F10X_CL */
+#endif /* STM32_HAS_DMA2 */
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -61,66 +334,135 @@ static cnt_t dmacnt2;
void dmaInit(void) {
int i;
- dmacnt1 = 0;
- for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--)
+ dmamsk1 = 0;
+ for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) {
dmaDisableChannel(STM32_DMA1, i);
+ dma1[i].dmaisrfunc = NULL;
+ }
STM32_DMA1->IFCR = 0xFFFFFFFF;
#if STM32_HAS_DMA2
- dmacnt2 = 0;
- for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--)
+ dmamsk2 = 0;
+ for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) {
dmaDisableChannel(STM32_DMA2, i);
+ dma2[i].dmaisrfunc = NULL;
+ }
STM32_DMA1->IFCR = 0xFFFFFFFF;
#endif
}
/**
- * @brief Enables the specified DMA controller clock.
+ * @brief Allocates a DMA channel.
+ * @details The channel is allocated and, if required, the DMA clock enabled.
+ * Trying to allocate a channel already allocated is an illegal
+ * operation and is trapped if assertions are enabled.
+ * @pre The channel must not be already in use.
+ * @post The channel is allocated and the default ISR handler redirected
+ * to the specified function.
+ * @post The channel must be freed using @p dmaRelease() before it can
+ * be reused with another peripheral.
+ * @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dma the DMA controller id
+ * @param[in] dma DMA controller id
+ * @param[in] channel requested channel id
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return The operation status.
+ * @retval FALSE operation successfully allocated.
+ * @retval TRUE the channel was already in use.
*
- * @api
+ * @special
*/
-void dmaEnable(uint32_t dma) {
+void dmaAllocate(uint32_t dma, uint32_t channel,
+ stm32_dmaisr_t func, void *param) {
+ chDbgCheck(func != NULL, "dmaAllocate");
+
+#if STM32_HAS_DMA2
switch (dma) {
- case DMA1_ID:
- if (dmacnt1++ == 0) {
+ case STM32_DMA1_ID:
+#else
+ (void)dma;
+#endif
+ /* Check if the channel is already taken.*/
+ chDbgAssert((dmamsk1 & (1 << channel)) == 0,
+ "dmaAllocate(), #1", "already allocated");
+
+ /* If the DMA unit was idle then the clock is enabled.*/
+ if (dmamsk1 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1->IFCR = 0x0FFFFFFF;
}
- break;
+
+ dmamsk1 |= 1 << channel;
+ dma1[channel].dmaisrfunc = func;
+ dma1[channel].dmaisrparam = param;
#if STM32_HAS_DMA2
- case DMA2_ID:
- if (dmacnt2++ == 0) {
+ break;
+ case STM32_DMA2_ID:
+ /* Check if the channel is already taken.*/
+ chDbgAssert((dmamsk2 & (1 << channel)) == 0,
+ "dmaAllocate(), #2", "already allocated");
+
+ /* If the DMA unit was idle then the clock is enabled.*/
+ if (dmamsk2 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
DMA2->IFCR = 0x0FFFFFFF;
}
+
+ dmamsk2 |= 1 << channel;
+ dma2[channel].dmaisrfunc = func;
+ dma2[channel].dmaisrparam = param;
break;
-#endif
}
+#endif
}
/**
- * @brief Disables the specified DMA controller clock.
+ * @brief Releases a DMA channel.
+ * @details The channel is freed and, if required, the DMA clock disabled.
+ * Trying to release a unallocated channel is an illegal operation
+ * and is trapped if assertions are enabled.
+ * @pre The channel must have been allocated using @p dmaRequest().
+ * @post The channel is again available.
+ * @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dma the DMA controller id
+ * @param[in] dma DMA controller id
+ * @param[in] channel requested channel id
*
- * @api
+ * @special
*/
-void dmaDisable(uint32_t dma) {
+void dmaRelease(uint32_t dma, uint32_t channel) {
+#if STM32_HAS_DMA2
switch (dma) {
- case DMA1_ID:
- if (--dmacnt1 == 0)
+ case STM32_DMA1_ID:
+#else
+ (void)dma;
+#endif
+ /* Check if the channel is not taken.*/
+ chDbgAssert((dmamsk1 & (1 << channel)) != 0,
+ "dmaRelease(), #1", "not allocated");
+
+ dma1[channel].dmaisrfunc = NULL;
+ dmamsk1 &= ~(1 << channel);
+ if (dmamsk1 == 0)
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
- break;
#if STM32_HAS_DMA2
- case DMA2_ID:
- if (--dmacnt2 == 0)
+ break;
+ case STM32_DMA2_ID:
+ /* Check if the channel is not taken.*/
+ chDbgAssert((dmamsk2 & (1 << channel)) != 0,
+ "dmaRelease(), #2", "not allocated");
+
+ dma2[channel].dmaisrfunc = NULL;
+ dmamsk2 &= ~(1 << channel);
+ if (dmamsk2 == 0)
RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
break;
-#endif
}
+#endif
}
+#endif /* STM32_DMA_REQUIRED */
+
/** @} */
diff --git a/os/hal/platforms/STM32/stm32_dma.h b/os/hal/platforms/STM32/stm32_dma.h
index 806f79c56..66a2f8c69 100644
--- a/os/hal/platforms/STM32/stm32_dma.h
+++ b/os/hal/platforms/STM32/stm32_dma.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -35,11 +36,11 @@
/*===========================================================================*/
/** @brief DMA1 identifier.*/
-#define DMA1_ID 0
+#define STM32_DMA1_ID 0
/** @brief DMA2 identifier.*/
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
-#define DMA2_ID 1
+#define STM32_DMA2_ID 1
#endif
/*===========================================================================*/
@@ -55,7 +56,7 @@
/*===========================================================================*/
/**
- * @brief STM32 DMA channel memory structure.
+ * @brief STM32 DMA channel memory structure type.
*/
typedef struct {
volatile uint32_t CCR;
@@ -66,7 +67,7 @@ typedef struct {
} stm32_dma_channel_t;
/**
- * @brief STM32 DMA subsystem memory structure.
+ * @brief STM32 DMA subsystem memory structure type.
* @note This structure has been redefined here because it is convenient to
* have the channels organized as an array, the ST header does not
* do that.
@@ -77,6 +78,14 @@ typedef struct {
stm32_dma_channel_t channels[7];
} stm32_dma_t;
+/**
+ * @brief STM32 DMA ISR function type.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
+
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
@@ -127,11 +136,12 @@ typedef struct {
/**
* @brief Associates a peripheral data register to a DMA channel.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
* @param[in] cpar value to be written in the CPAR register
*
- * @api
+ * @special
*/
#define dmaChannelSetPeripheral(dmachp, cpar) { \
(dmachp)->CPAR = (uint32_t)(cpar); \
@@ -142,13 +152,14 @@ typedef struct {
* @note This macro does not change the CPAR register because that register
* value does not change frequently, it usually points to a peripheral
* data register.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
* @param[in] cndtr value to be written in the CNDTR register
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*
- * @api
+ * @special
*/
#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \
(dmachp)->CNDTR = (uint32_t)(cndtr); \
@@ -158,10 +169,11 @@ typedef struct {
/**
* @brief DMA channel enable by channel pointer.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
*
- * @api
+ * @special
*/
#define dmaChannelEnable(dmachp) { \
(dmachp)->CCR |= DMA_CCR1_EN; \
@@ -170,10 +182,11 @@ typedef struct {
/**
* @brief DMA channel disable by channel pointer.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
*
- * @api
+ * @special
*/
#define dmaChannelDisable(dmachp) { \
(dmachp)->CCR = 0; \
@@ -186,6 +199,7 @@ typedef struct {
* data register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
@@ -193,7 +207,7 @@ typedef struct {
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*
- * @api
+ * @special
*/
#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \
dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \
@@ -203,11 +217,12 @@ typedef struct {
* @brief DMA channel enable by channel ID.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaEnableChannel(dmap, ch) { \
dmaChannelEnable(&(dmap)->channels[ch]); \
@@ -217,11 +232,12 @@ typedef struct {
* @brief DMA channel disable by channel ID.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaDisableChannel(dmap, ch) { \
dmaChannelDisable(&(dmap)->channels[ch]); \
@@ -233,11 +249,12 @@ typedef struct {
* withdraw all the pending interrupt bits from the ISR register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaClearChannel(dmap, ch){ \
(dmap)->IFCR = 1 << ((ch) * 4); \
@@ -251,8 +268,9 @@ typedef struct {
extern "C" {
#endif
void dmaInit(void);
- void dmaEnable(uint32_t dma);
- void dmaDisable(uint32_t dma);
+ void dmaAllocate(uint32_t dma, uint32_t channel,
+ stm32_dmaisr_t func, void *param);
+ void dmaRelease(uint32_t dma, uint32_t channel);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/platforms/STM32/stm32_usb.h b/os/hal/platforms/STM32/stm32_usb.h
index 8c04ba85f..51e7510c4 100644
--- a/os/hal/platforms/STM32/stm32_usb.h
+++ b/os/hal/platforms/STM32/stm32_usb.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -108,11 +109,16 @@ typedef struct {
#define STM32_USB ((stm32_usb_t *)STM32_USB_BASE)
/**
- * @brief Pointer to the USB RAM.
+ * @brief Pointer to the USB RAM.
*/
#define STM32_USBRAM ((uint32_t *)STM32_USBRAM_BASE)
/**
+ * @brief Size of the dedicated packet memory.
+ */
+#define USB_PMA_SIZE 512
+
+/**
* @brief Mask of all the toggling bits in the EPR register.
*/
#define EPR_TOGGLE_MASK (EPR_STAT_TX_MASK | EPR_DTOG_TX | \
diff --git a/os/hal/platforms/STM32/stm32f10x.h b/os/hal/platforms/STM32/stm32f10x.h
index a6f71cbdb..a187f0a84 100644
--- a/os/hal/platforms/STM32/stm32f10x.h
+++ b/os/hal/platforms/STM32/stm32f10x.h
@@ -2,14 +2,15 @@
******************************************************************************
* @file stm32f10x.h
* @author MCD Application Team
- * @version V3.3.0
- * @date 04/16/2010
- * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File.
- * This file contains all the peripheral register's definitions, bits
- * definitions and memory mapping for STM32F10x Connectivity line, High
- * density, Medium density, Medium density Value line, Low density
- * and Low density Value line and XL-density devices.
- ******************************************************************************
+ * @version V3.4.0
+ * @date 10/15/2010
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File.
+ * This file contains all the peripheral register's definitions, bits
+ * definitions and memory mapping for STM32F10x Connectivity line,
+ * High density, High density value line, Medium density,
+ * Medium density Value line, Low density, Low density Value line
+ * and XL-density devices.
+ ******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
@@ -29,77 +30,84 @@
/** @addtogroup stm32f10x
* @{
*/
-
+
#ifndef __STM32F10x_H
#define __STM32F10x_H
#ifdef __cplusplus
extern "C" {
-#endif
-
+#endif
+
/** @addtogroup Library_configuration_section
* @{
*/
-
+
/* Uncomment the line below according to the target STM32 device used in your
- application
+ application
*/
-#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
/* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */
- /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
+ /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
/* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
- /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
+ /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
/* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
- #define STM32F10X_XL /*!< STM32F10X_XL: STM32 XL-density devices */
+ /* #define STM32F10X_HD_VL */ /*!< STM32F10X_HD_VL: STM32 High density value line devices */
+ /* #define STM32F10X_XL */ /*!< STM32F10X_XL: STM32 XL-density devices */
/* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */
#endif
/* Tip: To avoid modifying this file each time you need to switch between these
devices, you can define the device in your toolchain compiler preprocessor.
- - Low density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
+ - Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
where the Flash memory density ranges between 16 and 32 Kbytes.
- Low-density value line devices are STM32F100xx microcontrollers where the Flash
memory density ranges between 16 and 32 Kbytes.
- - Medium density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
+ - Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
where the Flash memory density ranges between 64 and 128 Kbytes.
- - Medium-density value line devices are STM32F100xx microcontrollers where the
- Flash memory density ranges between 64 and 128 Kbytes.
- - High density devices are STM32F101xx and STM32F103xx microcontrollers where
+ - Medium-density value line devices are STM32F100xx microcontrollers where the
+ Flash memory density ranges between 64 and 128 Kbytes.
+ - High-density devices are STM32F101xx and STM32F103xx microcontrollers where
the Flash memory density ranges between 256 and 512 Kbytes.
+ - High-density value line devices are STM32F100xx microcontrollers where the
+ Flash memory density ranges between 256 and 512 Kbytes.
- XL-density devices are STM32F101xx and STM32F103xx microcontrollers where
the Flash memory density ranges between 512 and 1024 Kbytes.
- Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
*/
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
+ #error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
+#endif
+
#if !defined USE_STDPERIPH_DRIVER
/**
* @brief Comment the line below if you will not use the peripherals drivers.
- In this case, these drivers will not be included and the application code will
- be based on direct access to peripherals registers
+ In this case, these drivers will not be included and the application code will
+ be based on direct access to peripherals registers
*/
/*#define USE_STDPERIPH_DRIVER*/
#endif
/**
* @brief In the following line adjust the value of External High Speed oscillator (HSE)
- used in your application
-
+ used in your application
+
Tip: To avoid modifying this file each time you need to use different HSE, you
can define the HSE value in your toolchain compiler preprocessor.
- */
+ */
#if !defined HSE_VALUE
- #ifdef STM32F10X_CL
+ #ifdef STM32F10X_CL
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
- #else
+ #else
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* STM32F10X_CL */
#endif /* HSE_VALUE */
/**
- * @brief In the following line adjust the External High Speed oscillator (HSE) Startup
- Timeout value
+ * @brief In the following line adjust the External High Speed oscillator (HSE) Startup
+ Timeout value
*/
#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */
@@ -109,7 +117,7 @@
* @brief STM32F10x Standard Peripheral Library version number
*/
#define __STM32F10X_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:16] STM32F10x Standard Peripheral Library main version */
-#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x03) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */
+#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x04) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */
#define __STM32F10X_STDPERIPH_VERSION_SUB2 (0x00) /*!< [7:0] STM32F10x Standard Peripheral Library sub2 version */
#define __STM32F10X_STDPERIPH_VERSION ((__STM32F10X_STDPERIPH_VERSION_MAIN << 16)\
| (__STM32F10X_STDPERIPH_VERSION_SUB1 << 8)\
@@ -124,7 +132,7 @@
*/
/**
- * @brief Configuration of the Cortex-M3 Processor and Core Peripherals
+ * @brief Configuration of the Cortex-M3 Processor and Core Peripherals
*/
#ifdef STM32F10X_XL
#define __MPU_PRESENT 1 /*!< STM32 XL-density devices provide an MPU */
@@ -135,8 +143,8 @@
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
/**
- * @brief STM32F10x Interrupt Number Definition, according to the selected device
- * in @ref Library_configuration_section
+ * @brief STM32F10x Interrupt Number Definition, according to the selected device
+ * in @ref Library_configuration_section
*/
typedef enum IRQn
{
@@ -190,8 +198,8 @@ typedef enum IRQn
USART2_IRQn = 38, /*!< USART2 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
- USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
-#endif /* STM32F10X_LD */
+ USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+#endif /* STM32F10X_LD */
#ifdef STM32F10X_LD_VL
ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
@@ -209,9 +217,9 @@ typedef enum IRQn
USART2_IRQn = 38, /*!< USART2 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
- CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
- TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
- TIM7_IRQn = 55 /*!< TIM7 Interrupt */
+ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
+ TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
+ TIM7_IRQn = 55 /*!< TIM7 Interrupt */
#endif /* STM32F10X_LD_VL */
#ifdef STM32F10X_MD
@@ -239,8 +247,8 @@ typedef enum IRQn
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
- USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
-#endif /* STM32F10X_MD */
+ USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+#endif /* STM32F10X_MD */
#ifdef STM32F10X_MD_VL
ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
@@ -263,9 +271,9 @@ typedef enum IRQn
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
- CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
- TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
- TIM7_IRQn = 55 /*!< TIM7 Interrupt */
+ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
+ TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
+ TIM7_IRQn = 55 /*!< TIM7 Interrupt */
#endif /* STM32F10X_MD_VL */
#ifdef STM32F10X_HD
@@ -311,7 +319,48 @@ typedef enum IRQn
DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
-#endif /* STM32F10X_HD */
+#endif /* STM32F10X_HD */
+
+#ifdef STM32F10X_HD_VL
+ ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
+ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
+ TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */
+ TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */
+ TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */
+ TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
+ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
+ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
+ TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
+ I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
+ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
+ I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
+ I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
+ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
+ SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
+ USART1_IRQn = 37, /*!< USART1 global Interrupt */
+ USART2_IRQn = 38, /*!< USART2 global Interrupt */
+ USART3_IRQn = 39, /*!< USART3 global Interrupt */
+ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
+ RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
+ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
+ TIM12_IRQn = 43, /*!< TIM12 global Interrupt */
+ TIM13_IRQn = 44, /*!< TIM13 global Interrupt */
+ TIM14_IRQn = 45, /*!< TIM14 global Interrupt */
+ FSMC_IRQn = 48, /*!< FSMC global Interrupt */
+ TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
+ SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
+ UART4_IRQn = 52, /*!< UART4 global Interrupt */
+ UART5_IRQn = 53, /*!< UART5 global Interrupt */
+ TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
+ TIM7_IRQn = 55, /*!< TIM7 Interrupt */
+ DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
+ DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
+ DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
+ DMA2_Channel4_5_IRQn = 59, /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
+ DMA2_Channel5_IRQn = 60 /*!< DMA2 Channel 5 global Interrupt (DMA2 Channel 5 is
+ mapped at postion 60 only if the MISC_REMAP bit in
+ the AFIO_MAPR2 register is set) */
+#endif /* STM32F10X_HD_VL */
#ifdef STM32F10X_XL
ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
@@ -356,7 +405,7 @@ typedef enum IRQn
DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
-#endif /* STM32F10X_XL */
+#endif /* STM32F10X_XL */
#ifdef STM32F10X_CL
ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
@@ -402,7 +451,7 @@ typedef enum IRQn
CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */
CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */
OTG_FS_IRQn = 67 /*!< USB OTG FS global Interrupt */
-#endif /* STM32F10X_CL */
+#endif /* STM32F10X_CL */
} IRQn_Type;
/**
@@ -415,7 +464,7 @@ typedef enum IRQn
/** @addtogroup Exported_types
* @{
- */
+ */
/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */
typedef int32_t s32;
@@ -450,10 +499,6 @@ typedef __I uint32_t vuc32; /*!< Read Only */
typedef __I uint16_t vuc16; /*!< Read Only */
typedef __I uint8_t vuc8; /*!< Read Only */
-#ifndef __cplusplus
-typedef enum {FALSE = 0, TRUE = !FALSE} bool;
-#endif
-
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
@@ -471,10 +516,10 @@ typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
/** @addtogroup Peripheral_registers_structures
* @{
- */
+ */
-/**
- * @brief Analog to Digital Converter
+/**
+ * @brief Analog to Digital Converter
*/
typedef struct
@@ -501,8 +546,8 @@ typedef struct
__IO uint32_t DR;
} ADC_TypeDef;
-/**
- * @brief Backup Registers
+/**
+ * @brief Backup Registers
*/
typedef struct
@@ -527,7 +572,7 @@ typedef struct
__IO uint16_t DR9;
uint16_t RESERVED9;
__IO uint16_t DR10;
- uint16_t RESERVED10;
+ uint16_t RESERVED10;
__IO uint16_t RTCCR;
uint16_t RESERVED11;
__IO uint16_t CR;
@@ -573,7 +618,7 @@ typedef struct
__IO uint16_t DR29;
uint16_t RESERVED32;
__IO uint16_t DR30;
- uint16_t RESERVED33;
+ uint16_t RESERVED33;
__IO uint16_t DR31;
uint16_t RESERVED34;
__IO uint16_t DR32;
@@ -597,11 +642,11 @@ typedef struct
__IO uint16_t DR41;
uint16_t RESERVED44;
__IO uint16_t DR42;
- uint16_t RESERVED45;
+ uint16_t RESERVED45;
} BKP_TypeDef;
-
-/**
- * @brief Controller Area Network TxMailBox
+
+/**
+ * @brief Controller Area Network TxMailBox
*/
typedef struct
@@ -612,10 +657,10 @@ typedef struct
__IO uint32_t TDHR;
} CAN_TxMailBox_TypeDef;
-/**
- * @brief Controller Area Network FIFOMailBox
+/**
+ * @brief Controller Area Network FIFOMailBox
*/
-
+
typedef struct
{
__IO uint32_t RIR;
@@ -624,20 +669,20 @@ typedef struct
__IO uint32_t RDHR;
} CAN_FIFOMailBox_TypeDef;
-/**
- * @brief Controller Area Network FilterRegister
+/**
+ * @brief Controller Area Network FilterRegister
*/
-
+
typedef struct
{
__IO uint32_t FR1;
__IO uint32_t FR2;
} CAN_FilterRegister_TypeDef;
-/**
- * @brief Controller Area Network
+/**
+ * @brief Controller Area Network
*/
-
+
typedef struct
{
__IO uint32_t MCR;
@@ -665,10 +710,10 @@ typedef struct
CAN_FilterRegister_TypeDef sFilterRegister[14];
#else
CAN_FilterRegister_TypeDef sFilterRegister[28];
-#endif /* STM32F10X_CL */
+#endif /* STM32F10X_CL */
} CAN_TypeDef;
-/**
+/**
* @brief Consumer Electronics Control (CEC)
*/
typedef struct
@@ -679,11 +724,11 @@ typedef struct
__IO uint32_t ESR;
__IO uint32_t CSR;
__IO uint32_t TXD;
- __IO uint32_t RXD;
+ __IO uint32_t RXD;
} CEC_TypeDef;
-/**
- * @brief CRC calculation unit
+/**
+ * @brief CRC calculation unit
*/
typedef struct
@@ -695,7 +740,7 @@ typedef struct
__IO uint32_t CR;
} CRC_TypeDef;
-/**
+/**
* @brief Digital to Analog Converter
*/
@@ -714,22 +759,22 @@ typedef struct
__IO uint32_t DHR8RD;
__IO uint32_t DOR1;
__IO uint32_t DOR2;
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
__IO uint32_t SR;
#endif
} DAC_TypeDef;
-/**
+/**
* @brief Debug MCU
*/
typedef struct
{
__IO uint32_t IDCODE;
- __IO uint32_t CR;
+ __IO uint32_t CR;
}DBGMCU_TypeDef;
-/**
+/**
* @brief DMA Controller
*/
@@ -747,7 +792,7 @@ typedef struct
__IO uint32_t IFCR;
} DMA_TypeDef;
-/**
+/**
* @brief Ethernet MAC
*/
@@ -818,7 +863,7 @@ typedef struct
__IO uint32_t DMACHRBAR;
} ETH_TypeDef;
-/**
+/**
* @brief External Interrupt/Event Controller
*/
@@ -832,7 +877,7 @@ typedef struct
__IO uint32_t PR;
} EXTI_TypeDef;
-/**
+/**
* @brief FLASH Registers
*/
@@ -848,19 +893,19 @@ typedef struct
__IO uint32_t OBR;
__IO uint32_t WRPR;
#ifdef STM32F10X_XL
- uint32_t RESERVED1[8];
+ uint32_t RESERVED1[8];
__IO uint32_t KEYR2;
- uint32_t RESERVED2;
+ uint32_t RESERVED2;
__IO uint32_t SR2;
__IO uint32_t CR2;
- __IO uint32_t AR2;
-#endif /* STM32F10X_XL */
+ __IO uint32_t AR2;
+#endif /* STM32F10X_XL */
} FLASH_TypeDef;
-/**
+/**
* @brief Option Bytes Registers
*/
-
+
typedef struct
{
__IO uint16_t RDP;
@@ -873,66 +918,66 @@ typedef struct
__IO uint16_t WRP3;
} OB_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller
*/
typedef struct
{
- __IO uint32_t BTCR[8];
-} FSMC_Bank1_TypeDef;
+ __IO uint32_t BTCR[8];
+} FSMC_Bank1_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller Bank1E
*/
-
+
typedef struct
{
__IO uint32_t BWTR[7];
} FSMC_Bank1E_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller Bank2
*/
-
+
typedef struct
{
__IO uint32_t PCR2;
__IO uint32_t SR2;
__IO uint32_t PMEM2;
__IO uint32_t PATT2;
- uint32_t RESERVED0;
- __IO uint32_t ECCR2;
-} FSMC_Bank2_TypeDef;
+ uint32_t RESERVED0;
+ __IO uint32_t ECCR2;
+} FSMC_Bank2_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller Bank3
*/
-
+
typedef struct
{
__IO uint32_t PCR3;
__IO uint32_t SR3;
__IO uint32_t PMEM3;
__IO uint32_t PATT3;
- uint32_t RESERVED0;
- __IO uint32_t ECCR3;
-} FSMC_Bank3_TypeDef;
+ uint32_t RESERVED0;
+ __IO uint32_t ECCR3;
+} FSMC_Bank3_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller Bank4
*/
-
+
typedef struct
{
__IO uint32_t PCR4;
__IO uint32_t SR4;
__IO uint32_t PMEM4;
__IO uint32_t PATT4;
- __IO uint32_t PIO4;
-} FSMC_Bank4_TypeDef;
+ __IO uint32_t PIO4;
+} FSMC_Bank4_TypeDef;
-/**
+/**
* @brief General Purpose I/O
*/
@@ -947,7 +992,7 @@ typedef struct
__IO uint32_t LCKR;
} GPIO_TypeDef;
-/**
+/**
* @brief Alternate Function I/O
*/
@@ -957,9 +1002,9 @@ typedef struct
__IO uint32_t MAPR;
__IO uint32_t EXTICR[4];
uint32_t RESERVED0;
- __IO uint32_t MAPR2;
+ __IO uint32_t MAPR2;
} AFIO_TypeDef;
-/**
+/**
* @brief Inter-integrated Circuit Interface
*/
@@ -985,7 +1030,7 @@ typedef struct
uint16_t RESERVED8;
} I2C_TypeDef;
-/**
+/**
* @brief Independent WATCHDOG
*/
@@ -997,7 +1042,7 @@ typedef struct
__IO uint32_t SR;
} IWDG_TypeDef;
-/**
+/**
* @brief Power Control
*/
@@ -1007,7 +1052,7 @@ typedef struct
__IO uint32_t CSR;
} PWR_TypeDef;
-/**
+/**
* @brief Reset and Clock Control
*/
@@ -1024,18 +1069,18 @@ typedef struct
__IO uint32_t BDCR;
__IO uint32_t CSR;
-#ifdef STM32F10X_CL
+#ifdef STM32F10X_CL
__IO uint32_t AHBRSTR;
__IO uint32_t CFGR2;
-#endif /* STM32F10X_CL */
+#endif /* STM32F10X_CL */
-#if defined STM32F10X_LD_VL || defined STM32F10X_MD_VL
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
uint32_t RESERVED0;
__IO uint32_t CFGR2;
-#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL */
+#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */
} RCC_TypeDef;
-/**
+/**
* @brief Real-Time Clock
*/
@@ -1063,7 +1108,7 @@ typedef struct
uint16_t RESERVED9;
} RTC_TypeDef;
-/**
+/**
* @brief SD host Interface
*/
@@ -1091,7 +1136,7 @@ typedef struct
__IO uint32_t FIFO;
} SDIO_TypeDef;
-/**
+/**
* @brief Serial Peripheral Interface
*/
@@ -1114,10 +1159,10 @@ typedef struct
__IO uint16_t I2SCFGR;
uint16_t RESERVED7;
__IO uint16_t I2SPR;
- uint16_t RESERVED8;
+ uint16_t RESERVED8;
} SPI_TypeDef;
-/**
+/**
* @brief TIM
*/
@@ -1165,10 +1210,10 @@ typedef struct
uint16_t RESERVED19;
} TIM_TypeDef;
-/**
+/**
* @brief Universal Synchronous Asynchronous Receiver Transmitter
*/
-
+
typedef struct
{
__IO uint16_t SR;
@@ -1187,7 +1232,7 @@ typedef struct
uint16_t RESERVED6;
} USART_TypeDef;
-/**
+/**
* @brief Window WATCHDOG
*/
@@ -1201,16 +1246,18 @@ typedef struct
/**
* @}
*/
-
+
/** @addtogroup Peripheral_memory_map
* @{
*/
-#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the alias region */
-#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the alias region */
-#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the bit-band region */
-#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the bit-band region */
+#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */
+#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */
+#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
+
+#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */
+#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */
#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */
@@ -1308,10 +1355,10 @@ typedef struct
/**
* @}
*/
-
+
/** @addtogroup Peripheral_declaration
* @{
- */
+ */
#define TIM2 ((TIM_TypeDef *) TIM2_BASE)
#define TIM3 ((TIM_TypeDef *) TIM3_BASE)
@@ -1379,7 +1426,7 @@ typedef struct
#define RCC ((RCC_TypeDef *) RCC_BASE)
#define CRC ((CRC_TypeDef *) CRC_BASE)
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
-#define OB ((OB_TypeDef *) OB_BASE)
+#define OB ((OB_TypeDef *) OB_BASE)
#define ETH ((ETH_TypeDef *) ETH_BASE)
#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)
#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)
@@ -1395,11 +1442,11 @@ typedef struct
/** @addtogroup Exported_constants
* @{
*/
-
+
/** @addtogroup Peripheral_Registers_Bits_Definition
* @{
*/
-
+
/******************************************************************************/
/* Peripheral Registers_Bits_Definition */
/******************************************************************************/
@@ -1727,9 +1774,9 @@ typedef struct
#define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock * 8 */
#define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock * 9 */
#define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x00340000) /*!< PLL input clock * 6.5 */
-
+
#define RCC_CFGR_OTGFSPRE ((uint32_t)0x00400000) /*!< USB OTG FS prescaler */
-
+
/*!< MCO configuration */
#define RCC_CFGR_MCO ((uint32_t)0x0F000000) /*!< MCO[3:0] bits (Microcontroller Clock Output) */
#define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */
@@ -1746,7 +1793,7 @@ typedef struct
#define RCC_CFGR_MCO_PLL3CLK_Div2 ((uint32_t)0x09000000) /*!< PLL3 clock divided by 2 selected as MCO source*/
#define RCC_CFGR_MCO_Ext_HSE ((uint32_t)0x0A000000) /*!< XT1 external 3-25 MHz oscillator clock selected as MCO source */
#define RCC_CFGR_MCO_PLL3CLK ((uint32_t)0x0B000000) /*!< PLL3 clock selected as MCO source */
-#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */
#define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */
@@ -1853,7 +1900,7 @@ typedef struct
#define RCC_APB2RSTR_IOPDRST ((uint32_t)0x00000020) /*!< I/O port D reset */
#define RCC_APB2RSTR_ADC1RST ((uint32_t)0x00000200) /*!< ADC 1 interface reset */
-#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL)
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
#define RCC_APB2RSTR_ADC2RST ((uint32_t)0x00000400) /*!< ADC 2 interface reset */
#endif
@@ -1861,7 +1908,7 @@ typedef struct
#define RCC_APB2RSTR_SPI1RST ((uint32_t)0x00001000) /*!< SPI 1 reset */
#define RCC_APB2RSTR_USART1RST ((uint32_t)0x00004000) /*!< USART1 reset */
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_APB2RSTR_TIM15RST ((uint32_t)0x00010000) /*!< TIM15 Timer reset */
#define RCC_APB2RSTR_TIM16RST ((uint32_t)0x00020000) /*!< TIM16 Timer reset */
#define RCC_APB2RSTR_TIM17RST ((uint32_t)0x00040000) /*!< TIM17 Timer reset */
@@ -1878,6 +1925,11 @@ typedef struct
#define RCC_APB2RSTR_ADC3RST ((uint32_t)0x00008000) /*!< ADC3 interface reset */
#endif
+#if defined (STM32F10X_HD_VL)
+ #define RCC_APB2RSTR_IOPFRST ((uint32_t)0x00000080) /*!< I/O port F reset */
+ #define RCC_APB2RSTR_IOPGRST ((uint32_t)0x00000100) /*!< I/O port G reset */
+#endif
+
#ifdef STM32F10X_XL
#define RCC_APB2RSTR_TIM9RST ((uint32_t)0x00080000) /*!< TIM9 Timer reset */
#define RCC_APB2RSTR_TIM10RST ((uint32_t)0x00100000) /*!< TIM10 Timer reset */
@@ -1891,7 +1943,7 @@ typedef struct
#define RCC_APB1RSTR_USART2RST ((uint32_t)0x00020000) /*!< USART 2 reset */
#define RCC_APB1RSTR_I2C1RST ((uint32_t)0x00200000) /*!< I2C 1 reset */
-#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL)
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
#define RCC_APB1RSTR_CAN1RST ((uint32_t)0x02000000) /*!< CAN1 reset */
#endif
@@ -1919,11 +1971,21 @@ typedef struct
#define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */
#endif
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */
#define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */
#define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */
- #define RCC_APB1RSTR_CECRST ((uint32_t)0x40000000) /*!< CEC interface reset */
+ #define RCC_APB1RSTR_CECRST ((uint32_t)0x40000000) /*!< CEC interface reset */
+#endif
+
+#if defined (STM32F10X_HD_VL)
+ #define RCC_APB1RSTR_TIM5RST ((uint32_t)0x00000008) /*!< Timer 5 reset */
+ #define RCC_APB1RSTR_TIM12RST ((uint32_t)0x00000040) /*!< TIM12 Timer reset */
+ #define RCC_APB1RSTR_TIM13RST ((uint32_t)0x00000080) /*!< TIM13 Timer reset */
+ #define RCC_APB1RSTR_TIM14RST ((uint32_t)0x00000100) /*!< TIM14 Timer reset */
+ #define RCC_APB1RSTR_SPI3RST ((uint32_t)0x00008000) /*!< SPI 3 reset */
+ #define RCC_APB1RSTR_UART4RST ((uint32_t)0x00080000) /*!< UART 4 reset */
+ #define RCC_APB1RSTR_UART5RST ((uint32_t)0x00100000) /*!< UART 5 reset */
#endif
#ifdef STM32F10X_CL
@@ -1942,7 +2004,7 @@ typedef struct
#define RCC_AHBENR_FLITFEN ((uint16_t)0x0010) /*!< FLITF clock enable */
#define RCC_AHBENR_CRCEN ((uint16_t)0x0040) /*!< CRC clock enable */
-#if defined (STM32F10X_HD) || defined (STM32F10X_CL)
+#if defined (STM32F10X_HD) || defined (STM32F10X_CL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_XL)
#define RCC_AHBENR_DMA2EN ((uint16_t)0x0002) /*!< DMA2 clock enable */
#endif
@@ -1951,6 +2013,10 @@ typedef struct
#define RCC_AHBENR_SDIOEN ((uint16_t)0x0400) /*!< SDIO clock enable */
#endif
+#if defined (STM32F10X_HD_VL)
+ #define RCC_AHBENR_FSMCEN ((uint16_t)0x0100) /*!< FSMC clock enable */
+#endif
+
#ifdef STM32F10X_CL
#define RCC_AHBENR_OTGFSEN ((uint32_t)0x00001000) /*!< USB OTG FS clock enable */
#define RCC_AHBENR_ETHMACEN ((uint32_t)0x00004000) /*!< ETHERNET MAC clock enable */
@@ -1966,7 +2032,7 @@ typedef struct
#define RCC_APB2ENR_IOPDEN ((uint32_t)0x00000020) /*!< I/O port D clock enable */
#define RCC_APB2ENR_ADC1EN ((uint32_t)0x00000200) /*!< ADC 1 interface clock enable */
-#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL)
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
#define RCC_APB2ENR_ADC2EN ((uint32_t)0x00000400) /*!< ADC 2 interface clock enable */
#endif
@@ -1974,7 +2040,7 @@ typedef struct
#define RCC_APB2ENR_SPI1EN ((uint32_t)0x00001000) /*!< SPI 1 clock enable */
#define RCC_APB2ENR_USART1EN ((uint32_t)0x00004000) /*!< USART1 clock enable */
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_APB2ENR_TIM15EN ((uint32_t)0x00010000) /*!< TIM15 Timer clock enable */
#define RCC_APB2ENR_TIM16EN ((uint32_t)0x00020000) /*!< TIM16 Timer clock enable */
#define RCC_APB2ENR_TIM17EN ((uint32_t)0x00040000) /*!< TIM17 Timer clock enable */
@@ -1991,6 +2057,11 @@ typedef struct
#define RCC_APB2ENR_ADC3EN ((uint32_t)0x00008000) /*!< DMA1 clock enable */
#endif
+#if defined (STM32F10X_HD_VL)
+ #define RCC_APB2ENR_IOPFEN ((uint32_t)0x00000080) /*!< I/O port F clock enable */
+ #define RCC_APB2ENR_IOPGEN ((uint32_t)0x00000100) /*!< I/O port G clock enable */
+#endif
+
#ifdef STM32F10X_XL
#define RCC_APB2ENR_TIM9EN ((uint32_t)0x00080000) /*!< TIM9 Timer clock enable */
#define RCC_APB2ENR_TIM10EN ((uint32_t)0x00100000) /*!< TIM10 Timer clock enable */
@@ -2004,7 +2075,7 @@ typedef struct
#define RCC_APB1ENR_USART2EN ((uint32_t)0x00020000) /*!< USART 2 clock enable */
#define RCC_APB1ENR_I2C1EN ((uint32_t)0x00200000) /*!< I2C 1 clock enable */
-#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL)
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
#define RCC_APB1ENR_CAN1EN ((uint32_t)0x02000000) /*!< CAN1 clock enable */
#endif
@@ -2032,13 +2103,23 @@ typedef struct
#define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */
#endif
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */
#define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */
#define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */
- #define RCC_APB1ENR_CECEN ((uint32_t)0x40000000) /*!< CEC interface clock enable */
+ #define RCC_APB1ENR_CECEN ((uint32_t)0x40000000) /*!< CEC interface clock enable */
#endif
+#ifdef STM32F10X_HD_VL
+ #define RCC_APB1ENR_TIM5EN ((uint32_t)0x00000008) /*!< Timer 5 clock enable */
+ #define RCC_APB1ENR_TIM12EN ((uint32_t)0x00000040) /*!< TIM12 Timer clock enable */
+ #define RCC_APB1ENR_TIM13EN ((uint32_t)0x00000080) /*!< TIM13 Timer clock enable */
+ #define RCC_APB1ENR_TIM14EN ((uint32_t)0x00000100) /*!< TIM14 Timer clock enable */
+ #define RCC_APB1ENR_SPI3EN ((uint32_t)0x00008000) /*!< SPI 3 clock enable */
+ #define RCC_APB1ENR_UART4EN ((uint32_t)0x00080000) /*!< UART 4 clock enable */
+ #define RCC_APB1ENR_UART5EN ((uint32_t)0x00100000) /*!< UART 5 clock enable */
+#endif /* STM32F10X_HD_VL */
+
#ifdef STM32F10X_CL
#define RCC_APB1ENR_CAN2EN ((uint32_t)0x04000000) /*!< CAN2 clock enable */
#endif /* STM32F10X_CL */
@@ -2067,7 +2148,7 @@ typedef struct
#define RCC_BDCR_RTCEN ((uint32_t)0x00008000) /*!< RTC clock enable */
#define RCC_BDCR_BDRST ((uint32_t)0x00010000) /*!< Backup domain software reset */
-/******************* Bit definition for RCC_CSR register ********************/
+/******************* Bit definition for RCC_CSR register ********************/
#define RCC_CSR_LSION ((uint32_t)0x00000001) /*!< Internal Low Speed oscillator enable */
#define RCC_CSR_LSIRDY ((uint32_t)0x00000002) /*!< Internal Low Speed oscillator Ready */
#define RCC_CSR_RMVF ((uint32_t)0x01000000) /*!< Remove reset flag */
@@ -2173,7 +2254,7 @@ typedef struct
#define RCC_CFGR2_I2S3SRC ((uint32_t)0x00040000) /*!< I2S3 clock source */
#endif /* STM32F10X_CL */
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
/******************* Bit definition for RCC_CFGR2 register ******************/
/*!< PREDIV1 configuration */
#define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */
@@ -2199,7 +2280,7 @@ typedef struct
#define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */
#define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */
#endif
-
+
/******************************************************************************/
/* */
/* General Purpose and Alternate Function I/O */
@@ -2609,7 +2690,7 @@ typedef struct
#define AFIO_EXTICR1_EXTI1_PF ((uint16_t)0x0050) /*!< PF[1] pin */
#define AFIO_EXTICR1_EXTI1_PG ((uint16_t)0x0060) /*!< PG[1] pin */
-/*!< EXTI2 configuration */
+/*!< EXTI2 configuration */
#define AFIO_EXTICR1_EXTI2_PA ((uint16_t)0x0000) /*!< PA[2] pin */
#define AFIO_EXTICR1_EXTI2_PB ((uint16_t)0x0100) /*!< PB[2] pin */
#define AFIO_EXTICR1_EXTI2_PC ((uint16_t)0x0200) /*!< PC[2] pin */
@@ -2651,7 +2732,7 @@ typedef struct
#define AFIO_EXTICR2_EXTI5_PF ((uint16_t)0x0050) /*!< PF[5] pin */
#define AFIO_EXTICR2_EXTI5_PG ((uint16_t)0x0060) /*!< PG[5] pin */
-/*!< EXTI6 configuration */
+/*!< EXTI6 configuration */
#define AFIO_EXTICR2_EXTI6_PA ((uint16_t)0x0000) /*!< PA[6] pin */
#define AFIO_EXTICR2_EXTI6_PB ((uint16_t)0x0100) /*!< PB[6] pin */
#define AFIO_EXTICR2_EXTI6_PC ((uint16_t)0x0200) /*!< PC[6] pin */
@@ -2693,7 +2774,7 @@ typedef struct
#define AFIO_EXTICR3_EXTI9_PF ((uint16_t)0x0050) /*!< PF[9] pin */
#define AFIO_EXTICR3_EXTI9_PG ((uint16_t)0x0060) /*!< PG[9] pin */
-/*!< EXTI10 configuration */
+/*!< EXTI10 configuration */
#define AFIO_EXTICR3_EXTI10_PA ((uint16_t)0x0000) /*!< PA[10] pin */
#define AFIO_EXTICR3_EXTI10_PB ((uint16_t)0x0100) /*!< PB[10] pin */
#define AFIO_EXTICR3_EXTI10_PC ((uint16_t)0x0200) /*!< PC[10] pin */
@@ -2735,7 +2816,7 @@ typedef struct
#define AFIO_EXTICR4_EXTI13_PF ((uint16_t)0x0050) /*!< PF[13] pin */
#define AFIO_EXTICR4_EXTI13_PG ((uint16_t)0x0060) /*!< PG[13] pin */
-/*!< EXTI14 configuration */
+/*!< EXTI14 configuration */
#define AFIO_EXTICR4_EXTI14_PA ((uint16_t)0x0000) /*!< PA[14] pin */
#define AFIO_EXTICR4_EXTI14_PB ((uint16_t)0x0100) /*!< PB[14] pin */
#define AFIO_EXTICR4_EXTI14_PC ((uint16_t)0x0200) /*!< PC[14] pin */
@@ -2753,7 +2834,7 @@ typedef struct
#define AFIO_EXTICR4_EXTI15_PF ((uint16_t)0x5000) /*!< PF[15] pin */
#define AFIO_EXTICR4_EXTI15_PG ((uint16_t)0x6000) /*!< PG[15] pin */
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
/****************** Bit definition for AFIO_MAPR2 register ******************/
#define AFIO_MAPR2_TIM15_REMAP ((uint32_t)0x00000001) /*!< TIM15 remapping */
#define AFIO_MAPR2_TIM16_REMAP ((uint32_t)0x00000002) /*!< TIM16 remapping */
@@ -2762,7 +2843,16 @@ typedef struct
#define AFIO_MAPR2_TIM1_DMA_REMAP ((uint32_t)0x00000010) /*!< TIM1_DMA remapping */
#endif
-#ifdef STM32F10X_XL
+#ifdef STM32F10X_HD_VL
+#define AFIO_MAPR2_TIM13_REMAP ((uint32_t)0x00000100) /*!< TIM13 remapping */
+#define AFIO_MAPR2_TIM14_REMAP ((uint32_t)0x00000200) /*!< TIM14 remapping */
+#define AFIO_MAPR2_FSMC_NADV_REMAP ((uint32_t)0x00000400) /*!< FSMC NADV remapping */
+#define AFIO_MAPR2_TIM67_DAC_DMA_REMAP ((uint32_t)0x00000800) /*!< TIM6/TIM7 and DAC DMA remapping */
+#define AFIO_MAPR2_TIM12_REMAP ((uint32_t)0x00001000) /*!< TIM12 remapping */
+#define AFIO_MAPR2_MISC_REMAP ((uint32_t)0x00002000) /*!< Miscellaneous remapping */
+#endif
+
+#ifdef STM32F10X_XL
/****************** Bit definition for AFIO_MAPR2 register ******************/
#define AFIO_MAPR2_TIM9_REMAP ((uint32_t)0x00000020) /*!< TIM9 remapping */
#define AFIO_MAPR2_TIM10_REMAP ((uint32_t)0x00000040) /*!< TIM10 remapping */
@@ -3630,7 +3720,7 @@ typedef struct
#define ADC_CR1_JAWDEN ((uint32_t)0x00400000) /*!<Analog watchdog enable on injected channels */
#define ADC_CR1_AWDEN ((uint32_t)0x00800000) /*!<Analog watchdog enable on regular channels */
-
+
/******************* Bit definition for ADC_CR2 register ********************/
#define ADC_CR2_ADON ((uint32_t)0x00000001) /*!<A/D Converter ON / OFF */
#define ADC_CR2_CONT ((uint32_t)0x00000002) /*!<Continuous Conversion */
@@ -3888,7 +3978,7 @@ typedef struct
#define ADC_SQR3_SQ6_4 ((uint32_t)0x20000000) /*!<Bit 4 */
/******************* Bit definition for ADC_JSQR register *******************/
-#define ADC_JSQR_JSQ1 ((uint32_t)0x0000001F) /*!<JSQ1[4:0] bits (1st conversion in injected sequence) */
+#define ADC_JSQR_JSQ1 ((uint32_t)0x0000001F) /*!<JSQ1[4:0] bits (1st conversion in injected sequence) */
#define ADC_JSQR_JSQ1_0 ((uint32_t)0x00000001) /*!<Bit 0 */
#define ADC_JSQR_JSQ1_1 ((uint32_t)0x00000002) /*!<Bit 1 */
#define ADC_JSQR_JSQ1_2 ((uint32_t)0x00000004) /*!<Bit 2 */
@@ -4300,6 +4390,7 @@ typedef struct
#define TIM_CCER_CC3NP ((uint16_t)0x0800) /*!<Capture/Compare 3 Complementary output Polarity */
#define TIM_CCER_CC4E ((uint16_t)0x1000) /*!<Capture/Compare 4 output enable */
#define TIM_CCER_CC4P ((uint16_t)0x2000) /*!<Capture/Compare 4 output Polarity */
+#define TIM_CCER_CC4NP ((uint16_t)0x8000) /*!<Capture/Compare 4 Complementary output Polarity */
/******************* Bit definition for TIM_CNT register ********************/
#define TIM_CNT_CNT ((uint16_t)0xFFFF) /*!<Counter Value */
@@ -4493,6 +4584,7 @@ typedef struct
#define FSMC_BCR1_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
#define FSMC_BCR1_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
#define FSMC_BCR1_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR1_ASYNCWAIT ((uint32_t)0x00008000) /*!<Asynchronous wait */
#define FSMC_BCR1_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
/****************** Bit definition for FSMC_BCR2 register *******************/
@@ -4515,6 +4607,7 @@ typedef struct
#define FSMC_BCR2_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
#define FSMC_BCR2_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
#define FSMC_BCR2_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR2_ASYNCWAIT ((uint32_t)0x00008000) /*!<Asynchronous wait */
#define FSMC_BCR2_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
/****************** Bit definition for FSMC_BCR3 register *******************/
@@ -4537,6 +4630,7 @@ typedef struct
#define FSMC_BCR3_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
#define FSMC_BCR3_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
#define FSMC_BCR3_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR3_ASYNCWAIT ((uint32_t)0x00008000) /*!<Asynchronous wait */
#define FSMC_BCR3_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
/****************** Bit definition for FSMC_BCR4 register *******************/
@@ -4559,6 +4653,7 @@ typedef struct
#define FSMC_BCR4_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
#define FSMC_BCR4_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
#define FSMC_BCR4_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR4_ASYNCWAIT ((uint32_t)0x00008000) /*!<Asynchronous wait */
#define FSMC_BCR4_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
/****************** Bit definition for FSMC_BTR1 register ******************/
@@ -5674,7 +5769,7 @@ typedef struct
#define USB_DADDR_EF ((uint8_t)0x80) /*!<Enable Function */
-/****************** Bit definition for USB_BTABLE register ******************/
+/****************** Bit definition for USB_BTABLE register ******************/
#define USB_BTABLE_BTABLE ((uint16_t)0xFFF8) /*!<Buffer Table */
/*!<Buffer descriptor table */
@@ -6258,7 +6353,7 @@ typedef struct
#define CAN_TI2R_EXID ((uint32_t)0x001FFFF8) /*!<Extended identifier */
#define CAN_TI2R_STID ((uint32_t)0xFFE00000) /*!<Standard Identifier or Extended Identifier */
-/******************* Bit definition for CAN_TDT2R register ******************/
+/******************* Bit definition for CAN_TDT2R register ******************/
#define CAN_TDT2R_DLC ((uint32_t)0x0000000F) /*!<Data Length Code */
#define CAN_TDT2R_TGT ((uint32_t)0x00000100) /*!<Transmit Global Time */
#define CAN_TDT2R_TIME ((uint32_t)0xFFFF0000) /*!<Message Time Stamp */
@@ -7771,10 +7866,10 @@ typedef struct
#define ETH_MACCR_IFG_88Bit ((uint32_t)0x00020000) /* Minimum IFG between frames during transmission is 88Bit */
#define ETH_MACCR_IFG_80Bit ((uint32_t)0x00040000) /* Minimum IFG between frames during transmission is 80Bit */
#define ETH_MACCR_IFG_72Bit ((uint32_t)0x00060000) /* Minimum IFG between frames during transmission is 72Bit */
- #define ETH_MACCR_IFG_64Bit ((uint32_t)0x00080000) /* Minimum IFG between frames during transmission is 64Bit */
+ #define ETH_MACCR_IFG_64Bit ((uint32_t)0x00080000) /* Minimum IFG between frames during transmission is 64Bit */
#define ETH_MACCR_IFG_56Bit ((uint32_t)0x000A0000) /* Minimum IFG between frames during transmission is 56Bit */
#define ETH_MACCR_IFG_48Bit ((uint32_t)0x000C0000) /* Minimum IFG between frames during transmission is 48Bit */
- #define ETH_MACCR_IFG_40Bit ((uint32_t)0x000E0000) /* Minimum IFG between frames during transmission is 40Bit */
+ #define ETH_MACCR_IFG_40Bit ((uint32_t)0x000E0000) /* Minimum IFG between frames during transmission is 40Bit */
#define ETH_MACCR_CSD ((uint32_t)0x00010000) /* Carrier sense disable (during transmission) */
#define ETH_MACCR_FES ((uint32_t)0x00004000) /* Fast ethernet speed */
#define ETH_MACCR_ROD ((uint32_t)0x00002000) /* Receive own disable */
@@ -7788,24 +7883,24 @@ typedef struct
#define ETH_MACCR_BL_10 ((uint32_t)0x00000000) /* k = min (n, 10) */
#define ETH_MACCR_BL_8 ((uint32_t)0x00000020) /* k = min (n, 8) */
#define ETH_MACCR_BL_4 ((uint32_t)0x00000040) /* k = min (n, 4) */
- #define ETH_MACCR_BL_1 ((uint32_t)0x00000060) /* k = min (n, 1) */
+ #define ETH_MACCR_BL_1 ((uint32_t)0x00000060) /* k = min (n, 1) */
#define ETH_MACCR_DC ((uint32_t)0x00000010) /* Defferal check */
#define ETH_MACCR_TE ((uint32_t)0x00000008) /* Transmitter enable */
#define ETH_MACCR_RE ((uint32_t)0x00000004) /* Receiver enable */
/* Bit definition for Ethernet MAC Frame Filter Register */
-#define ETH_MACFFR_RA ((uint32_t)0x80000000) /* Receive all */
-#define ETH_MACFFR_HPF ((uint32_t)0x00000400) /* Hash or perfect filter */
-#define ETH_MACFFR_SAF ((uint32_t)0x00000200) /* Source address filter enable */
-#define ETH_MACFFR_SAIF ((uint32_t)0x00000100) /* SA inverse filtering */
+#define ETH_MACFFR_RA ((uint32_t)0x80000000) /* Receive all */
+#define ETH_MACFFR_HPF ((uint32_t)0x00000400) /* Hash or perfect filter */
+#define ETH_MACFFR_SAF ((uint32_t)0x00000200) /* Source address filter enable */
+#define ETH_MACFFR_SAIF ((uint32_t)0x00000100) /* SA inverse filtering */
#define ETH_MACFFR_PCF ((uint32_t)0x000000C0) /* Pass control frames: 3 cases */
#define ETH_MACFFR_PCF_BlockAll ((uint32_t)0x00000040) /* MAC filters all control frames from reaching the application */
#define ETH_MACFFR_PCF_ForwardAll ((uint32_t)0x00000080) /* MAC forwards all control frames to application even if they fail the Address Filter */
- #define ETH_MACFFR_PCF_ForwardPassedAddrFilter ((uint32_t)0x000000C0) /* MAC forwards control frames that pass the Address Filter. */
-#define ETH_MACFFR_BFD ((uint32_t)0x00000020) /* Broadcast frame disable */
-#define ETH_MACFFR_PAM ((uint32_t)0x00000010) /* Pass all mutlicast */
-#define ETH_MACFFR_DAIF ((uint32_t)0x00000008) /* DA Inverse filtering */
-#define ETH_MACFFR_HM ((uint32_t)0x00000004) /* Hash multicast */
+ #define ETH_MACFFR_PCF_ForwardPassedAddrFilter ((uint32_t)0x000000C0) /* MAC forwards control frames that pass the Address Filter. */
+#define ETH_MACFFR_BFD ((uint32_t)0x00000020) /* Broadcast frame disable */
+#define ETH_MACFFR_PAM ((uint32_t)0x00000010) /* Pass all mutlicast */
+#define ETH_MACFFR_DAIF ((uint32_t)0x00000008) /* DA Inverse filtering */
+#define ETH_MACFFR_HM ((uint32_t)0x00000004) /* Hash multicast */
#define ETH_MACFFR_HU ((uint32_t)0x00000002) /* Hash unicast */
#define ETH_MACFFR_PM ((uint32_t)0x00000001) /* Promiscuous mode */
@@ -7816,15 +7911,15 @@ typedef struct
#define ETH_MACHTLR_HTL ((uint32_t)0xFFFFFFFF) /* Hash table low */
/* Bit definition for Ethernet MAC MII Address Register */
-#define ETH_MACMIIAR_PA ((uint32_t)0x0000F800) /* Physical layer address */
-#define ETH_MACMIIAR_MR ((uint32_t)0x000007C0) /* MII register in the selected PHY */
-#define ETH_MACMIIAR_CR ((uint32_t)0x0000001C) /* CR clock range: 6 cases */
+#define ETH_MACMIIAR_PA ((uint32_t)0x0000F800) /* Physical layer address */
+#define ETH_MACMIIAR_MR ((uint32_t)0x000007C0) /* MII register in the selected PHY */
+#define ETH_MACMIIAR_CR ((uint32_t)0x0000001C) /* CR clock range: 6 cases */
#define ETH_MACMIIAR_CR_Div42 ((uint32_t)0x00000000) /* HCLK:60-72 MHz; MDC clock= HCLK/42 */
#define ETH_MACMIIAR_CR_Div16 ((uint32_t)0x00000008) /* HCLK:20-35 MHz; MDC clock= HCLK/16 */
#define ETH_MACMIIAR_CR_Div26 ((uint32_t)0x0000000C) /* HCLK:35-60 MHz; MDC clock= HCLK/26 */
-#define ETH_MACMIIAR_MW ((uint32_t)0x00000002) /* MII write */
-#define ETH_MACMIIAR_MB ((uint32_t)0x00000001) /* MII busy */
-
+#define ETH_MACMIIAR_MW ((uint32_t)0x00000002) /* MII write */
+#define ETH_MACMIIAR_MB ((uint32_t)0x00000001) /* MII busy */
+
/* Bit definition for Ethernet MAC MII Data Register */
#define ETH_MACMIIDR_MD ((uint32_t)0x0000FFFF) /* MII data: read/write data from/to PHY */
@@ -7835,7 +7930,7 @@ typedef struct
#define ETH_MACFCR_PLT_Minus4 ((uint32_t)0x00000000) /* Pause time minus 4 slot times */
#define ETH_MACFCR_PLT_Minus28 ((uint32_t)0x00000010) /* Pause time minus 28 slot times */
#define ETH_MACFCR_PLT_Minus144 ((uint32_t)0x00000020) /* Pause time minus 144 slot times */
- #define ETH_MACFCR_PLT_Minus256 ((uint32_t)0x00000030) /* Pause time minus 256 slot times */
+ #define ETH_MACFCR_PLT_Minus256 ((uint32_t)0x00000030) /* Pause time minus 256 slot times */
#define ETH_MACFCR_UPFD ((uint32_t)0x00000008) /* Unicast pause frame detect */
#define ETH_MACFCR_RFCE ((uint32_t)0x00000004) /* Receive flow control enable */
#define ETH_MACFCR_TFCE ((uint32_t)0x00000002) /* Transmit flow control enable */
@@ -7845,7 +7940,7 @@ typedef struct
#define ETH_MACVLANTR_VLANTC ((uint32_t)0x00010000) /* 12-bit VLAN tag comparison */
#define ETH_MACVLANTR_VLANTI ((uint32_t)0x0000FFFF) /* VLAN tag identifier (for receive frames) */
-/* Bit definition for Ethernet MAC Remote Wake-UpFrame Filter Register */
+/* Bit definition for Ethernet MAC Remote Wake-UpFrame Filter Register */
#define ETH_MACRWUFFR_D ((uint32_t)0xFFFFFFFF) /* Wake-up frame filter register data */
/* Eight sequential Writes to this address (offset 0x28) will write all Wake-UpFrame Filter Registers.
Eight sequential Reads from this address (offset 0x28) will read all Wake-UpFrame Filter Registers. */
@@ -7853,13 +7948,13 @@ typedef struct
Wake-UpFrame Filter Reg1 : Filter 1 Byte Mask
Wake-UpFrame Filter Reg2 : Filter 2 Byte Mask
Wake-UpFrame Filter Reg3 : Filter 3 Byte Mask
- Wake-UpFrame Filter Reg4 : RSVD - Filter3 Command - RSVD - Filter2 Command -
+ Wake-UpFrame Filter Reg4 : RSVD - Filter3 Command - RSVD - Filter2 Command -
RSVD - Filter1 Command - RSVD - Filter0 Command
Wake-UpFrame Filter Re5 : Filter3 Offset - Filter2 Offset - Filter1 Offset - Filter0 Offset
Wake-UpFrame Filter Re6 : Filter1 CRC16 - Filter0 CRC16
Wake-UpFrame Filter Re7 : Filter3 CRC16 - Filter2 CRC16 */
-/* Bit definition for Ethernet MAC PMT Control and Status Register */
+/* Bit definition for Ethernet MAC PMT Control and Status Register */
#define ETH_MACPMTCSR_WFFRPR ((uint32_t)0x80000000) /* Wake-Up Frame Filter Register Pointer Reset */
#define ETH_MACPMTCSR_GU ((uint32_t)0x00000200) /* Global Unicast */
#define ETH_MACPMTCSR_WFR ((uint32_t)0x00000040) /* Wake-Up Frame Received */
@@ -7894,7 +7989,7 @@ typedef struct
#define ETH_MACA1HR_MBC_LBits31_24 ((uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */
#define ETH_MACA1HR_MBC_LBits23_16 ((uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */
#define ETH_MACA1HR_MBC_LBits15_8 ((uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */
- #define ETH_MACA1HR_MBC_LBits7_0 ((uint32_t)0x01000000) /* Mask MAC Address low reg bits [7:0] */
+ #define ETH_MACA1HR_MBC_LBits7_0 ((uint32_t)0x01000000) /* Mask MAC Address low reg bits [7:0] */
#define ETH_MACA1HR_MACA1H ((uint32_t)0x0000FFFF) /* MAC address1 high */
/* Bit definition for Ethernet MAC Address1 Low Register */
@@ -8030,26 +8125,26 @@ typedef struct
#define ETH_DMABMR_RDP_4Beat ((uint32_t)0x00080000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */
#define ETH_DMABMR_RDP_8Beat ((uint32_t)0x00100000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */
#define ETH_DMABMR_RDP_16Beat ((uint32_t)0x00200000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */
- #define ETH_DMABMR_RDP_32Beat ((uint32_t)0x00400000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
+ #define ETH_DMABMR_RDP_32Beat ((uint32_t)0x00400000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
#define ETH_DMABMR_RDP_4xPBL_4Beat ((uint32_t)0x01020000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */
#define ETH_DMABMR_RDP_4xPBL_8Beat ((uint32_t)0x01040000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */
#define ETH_DMABMR_RDP_4xPBL_16Beat ((uint32_t)0x01080000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */
#define ETH_DMABMR_RDP_4xPBL_32Beat ((uint32_t)0x01100000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
#define ETH_DMABMR_RDP_4xPBL_64Beat ((uint32_t)0x01200000) /* maximum number of beats to be transferred in one RxDMA transaction is 64 */
- #define ETH_DMABMR_RDP_4xPBL_128Beat ((uint32_t)0x01400000) /* maximum number of beats to be transferred in one RxDMA transaction is 128 */
+ #define ETH_DMABMR_RDP_4xPBL_128Beat ((uint32_t)0x01400000) /* maximum number of beats to be transferred in one RxDMA transaction is 128 */
#define ETH_DMABMR_FB ((uint32_t)0x00010000) /* Fixed Burst */
#define ETH_DMABMR_RTPR ((uint32_t)0x0000C000) /* Rx Tx priority ratio */
#define ETH_DMABMR_RTPR_1_1 ((uint32_t)0x00000000) /* Rx Tx priority ratio */
#define ETH_DMABMR_RTPR_2_1 ((uint32_t)0x00004000) /* Rx Tx priority ratio */
#define ETH_DMABMR_RTPR_3_1 ((uint32_t)0x00008000) /* Rx Tx priority ratio */
- #define ETH_DMABMR_RTPR_4_1 ((uint32_t)0x0000C000) /* Rx Tx priority ratio */
+ #define ETH_DMABMR_RTPR_4_1 ((uint32_t)0x0000C000) /* Rx Tx priority ratio */
#define ETH_DMABMR_PBL ((uint32_t)0x00003F00) /* Programmable burst length */
#define ETH_DMABMR_PBL_1Beat ((uint32_t)0x00000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */
#define ETH_DMABMR_PBL_2Beat ((uint32_t)0x00000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */
#define ETH_DMABMR_PBL_4Beat ((uint32_t)0x00000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
#define ETH_DMABMR_PBL_8Beat ((uint32_t)0x00000800) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
#define ETH_DMABMR_PBL_16Beat ((uint32_t)0x00001000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
- #define ETH_DMABMR_PBL_32Beat ((uint32_t)0x00002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
+ #define ETH_DMABMR_PBL_32Beat ((uint32_t)0x00002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
#define ETH_DMABMR_PBL_4xPBL_4Beat ((uint32_t)0x01000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
#define ETH_DMABMR_PBL_4xPBL_8Beat ((uint32_t)0x01000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
#define ETH_DMABMR_PBL_4xPBL_16Beat ((uint32_t)0x01000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
@@ -8179,7 +8274,7 @@ typedef struct
/**
* @}
- */
+ */
#ifdef USE_STDPERIPH_DRIVER
#include "stm32f10x_conf.h"
diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c
index 9769aa090..e2f306302 100644
--- a/os/hal/platforms/STM32/uart_lld.c
+++ b/os/hal/platforms/STM32/uart_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -90,13 +91,13 @@ static void set_rx_idle_loop(UARTDriver *uartp) {
/* RX DMA channel preparation, if the char callback is defined then the
TCIE interrupt is enabled too.*/
- if (uartp->ud_config->uc_rxchar == NULL)
+ if (uartp->config->rxchar_cb == NULL)
ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE;
else
ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE | DMA_CCR1_TCIE;
- dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmarx, 1,
- &uartp->ud_rxbuf, uartp->ud_dmaccr | ccr);
- dmaEnableChannel(uartp->ud_dmap, uartp->ud_dmarx);
+ dmaSetupChannel(uartp->dmap, uartp->dmarx, 1,
+ &uartp->rxbuf, uartp->dmaccr | ccr);
+ dmaEnableChannel(uartp->dmap, uartp->dmarx);
}
/**
@@ -108,15 +109,15 @@ static void set_rx_idle_loop(UARTDriver *uartp) {
static void usart_stop(UARTDriver *uartp) {
/* Stops RX and TX DMA channels.*/
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmarx);
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmatx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmarx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmatx);
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ dmaDisableChannel(uartp->dmap, uartp->dmatx);
+ dmaClearChannel(uartp->dmap, uartp->dmarx);
+ dmaClearChannel(uartp->dmap, uartp->dmatx);
/* Stops USART operations.*/
- uartp->ud_usart->CR1 = 0;
- uartp->ud_usart->CR2 = 0;
- uartp->ud_usart->CR3 = 0;
+ uartp->usart->CR1 = 0;
+ uartp->usart->CR2 = 0;
+ uartp->usart->CR3 = 0;
}
/**
@@ -127,16 +128,16 @@ static void usart_stop(UARTDriver *uartp) {
*/
static void usart_start(UARTDriver *uartp) {
uint16_t cr1;
- USART_TypeDef *u = uartp->ud_usart;
+ USART_TypeDef *u = uartp->usart;
/* Defensive programming, starting from a clean state.*/
usart_stop(uartp);
/* Baud rate setting.*/
- if (uartp->ud_usart == USART1)
- u->BRR = STM32_PCLK2 / uartp->ud_config->uc_speed;
+ if (uartp->usart == USART1)
+ u->BRR = STM32_PCLK2 / uartp->config->speed;
else
- u->BRR = STM32_PCLK1 / uartp->ud_config->uc_speed;
+ u->BRR = STM32_PCLK1 / uartp->config->speed;
/* Resetting eventual pending status flags.*/
(void)u->SR; /* SR reset step 1.*/
@@ -145,14 +146,14 @@ static void usart_start(UARTDriver *uartp) {
/* Note that some bits are enforced because required for correct driver
operations.*/
- if (uartp->ud_config->uc_txend2 == NULL)
+ if (uartp->config->txend2_cb == NULL)
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
else
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE |
USART_CR1_TCIE;
- u->CR1 = uartp->ud_config->uc_cr1 | cr1;
- u->CR2 = uartp->ud_config->uc_cr2 | USART_CR2_LBDIE;
- u->CR3 = uartp->ud_config->uc_cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
+ u->CR1 = uartp->config->cr1 | cr1;
+ u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
+ u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
USART_CR3_EIE;
/* Starting the receiver idle loop.*/
@@ -163,17 +164,38 @@ static void usart_start(UARTDriver *uartp) {
* @brief RX DMA common service routine.
*
* @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_rx_end_irq(UARTDriver *uartp) {
+static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
- uartp->ud_rxstate = UART_RX_COMPLETE;
- if (uartp->ud_config->uc_rxend != NULL)
- uartp->ud_config->uc_rxend(uartp);
- /* If the callback didn't explicitly change state then the receiver
- automatically returns to the idle state.*/
- if (uartp->ud_rxstate == UART_RX_COMPLETE) {
- uartp->ud_rxstate = UART_RX_IDLE;
- set_rx_idle_loop(uartp);
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (uartp->rxstate == UART_RX_IDLE) {
+ /* Receiver in idle state, a callback is generated, if enabled, for each
+ received character and then the driver stays in the same state.*/
+ if (uartp->config->rxchar_cb != NULL)
+ uartp->config->rxchar_cb(uartp, uartp->rxbuf);
+ }
+ else {
+ /* Receiver in active state, a callback is generated, if enabled, after
+ a completed transfer.*/
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ uartp->rxstate = UART_RX_COMPLETE;
+ if (uartp->config->rxend_cb != NULL)
+ uartp->config->rxend_cb(uartp);
+ /* If the callback didn't explicitly change state then the receiver
+ automatically returns to the idle state.*/
+ if (uartp->rxstate == UART_RX_COMPLETE) {
+ uartp->rxstate = UART_RX_IDLE;
+ set_rx_idle_loop(uartp);
+ }
}
}
@@ -181,18 +203,30 @@ static void serve_rx_end_irq(UARTDriver *uartp) {
* @brief TX DMA common service routine.
*
* @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_tx_end_irq(UARTDriver *uartp) {
+static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+ dmaDisableChannel(uartp->dmap, uartp->dmatx);
/* A callback is generated, if enabled, after a completed transfer.*/
- uartp->ud_txstate = UART_TX_COMPLETE;
- if (uartp->ud_config->uc_txend1 != NULL)
- uartp->ud_config->uc_txend1(uartp);
+ uartp->txstate = UART_TX_COMPLETE;
+ if (uartp->config->txend1_cb != NULL)
+ uartp->config->txend1_cb(uartp);
/* If the callback didn't explicitly change state then the transmitter
automatically returns to the idle state.*/
- if (uartp->ud_txstate == UART_TX_COMPLETE)
- uartp->ud_txstate = UART_TX_IDLE;
+ if (uartp->txstate == UART_TX_COMPLETE)
+ uartp->txstate = UART_TX_IDLE;
}
+
/**
* @brief USART common service routine.
*
@@ -200,21 +234,21 @@ static void serve_tx_end_irq(UARTDriver *uartp) {
*/
static void serve_usart_irq(UARTDriver *uartp) {
uint16_t sr;
- USART_TypeDef *u = uartp->ud_usart;
+ USART_TypeDef *u = uartp->usart;
sr = u->SR; /* SR reset step 1.*/
(void)u->DR; /* SR reset step 2.*/
if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE |
USART_SR_FE | USART_SR_PE)) {
u->SR = ~USART_SR_LBD;
- if (uartp->ud_config->uc_rxerr != NULL)
- uartp->ud_config->uc_rxerr(uartp, translate_errors(sr));
+ if (uartp->config->rxerr_cb != NULL)
+ uartp->config->rxerr_cb(uartp, translate_errors(sr));
}
if (sr & USART_SR_TC) {
u->SR = ~USART_SR_TC;
/* End of transmission, a callback is generated.*/
- if (uartp->ud_config->uc_txend2 != NULL)
- uartp->ud_config->uc_txend2(uartp);
+ if (uartp->config->txend2_cb != NULL)
+ uartp->config->txend2_cb(uartp);
}
}
@@ -224,58 +258,6 @@ static void serve_usart_irq(UARTDriver *uartp) {
#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
/**
- * @brief USART1 RX DMA interrupt handler (channel 5).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD1;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF5) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- if (uartp->ud_rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->ud_config->uc_rxchar != NULL)
- uartp->ud_config->uc_rxchar(uartp, uartp->ud_rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART1 TX DMA interrupt handler (channel 4).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
- serve_tx_end_irq(&UARTD1);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART1 IRQ handler.
*
* @isr
@@ -292,58 +274,6 @@ CH_IRQ_HANDLER(USART1_IRQHandler) {
#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
/**
- * @brief USART2 RX DMA interrupt handler (channel 6).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD2;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF6) != 0) {
- STM32_UART_USART2_DMA_ERROR_HOOK();
- }
- if (uartp->ud_rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->ud_config->uc_rxchar != NULL)
- uartp->ud_config->uc_rxchar(uartp, uartp->ud_rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART2 TX DMA interrupt handler (channel 7).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF7) != 0) {
- STM32_UART_USART2_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
- serve_tx_end_irq(&UARTD2);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART2 IRQ handler.
*
* @isr
@@ -360,58 +290,6 @@ CH_IRQ_HANDLER(USART2_IRQHandler) {
#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
/**
- * @brief USART3 RX DMA interrupt handler (channel 3).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD3;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF3) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- if (uartp->ud_rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->ud_config->uc_rxchar != NULL)
- uartp->ud_config->uc_rxchar(uartp, uartp->ud_rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART3 TX DMA interrupt handler (channel 2).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
- serve_tx_end_irq(&UARTD3);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART3 IRQ handler.
*
* @isr
@@ -438,36 +316,30 @@ CH_IRQ_HANDLER(USART3_IRQHandler) {
void uart_lld_init(void) {
#if STM32_UART_USE_USART1
- RCC->APB2RSTR = RCC_APB2RSTR_USART1RST;
- RCC->APB2RSTR = 0;
uartObjectInit(&UARTD1);
- UARTD1.ud_usart = USART1;
- UARTD1.ud_dmap = STM32_DMA1;
- UARTD1.ud_dmarx = STM32_DMA_CHANNEL_5;
- UARTD1.ud_dmatx = STM32_DMA_CHANNEL_4;
- UARTD1.ud_dmaccr = 0;
+ UARTD1.usart = USART1;
+ UARTD1.dmap = STM32_DMA1;
+ UARTD1.dmarx = STM32_DMA_CHANNEL_5;
+ UARTD1.dmatx = STM32_DMA_CHANNEL_4;
+ UARTD1.dmaccr = 0;
#endif
#if STM32_UART_USE_USART2
- RCC->APB1RSTR = RCC_APB1RSTR_USART2RST;
- RCC->APB1RSTR = 0;
uartObjectInit(&UARTD2);
- UARTD2.ud_usart = USART2;
- UARTD2.ud_dmap = STM32_DMA1;
- UARTD2.ud_dmarx = STM32_DMA_CHANNEL_6;
- UARTD2.ud_dmatx = STM32_DMA_CHANNEL_7;
- UARTD2.ud_dmaccr = 0;
+ UARTD2.usart = USART2;
+ UARTD2.dmap = STM32_DMA1;
+ UARTD2.dmarx = STM32_DMA_CHANNEL_6;
+ UARTD2.dmatx = STM32_DMA_CHANNEL_7;
+ UARTD2.dmaccr = 0;
#endif
#if STM32_UART_USE_USART3
- RCC->APB1RSTR = RCC_APB1RSTR_USART3RST;
- RCC->APB1RSTR = 0;
uartObjectInit(&UARTD3);
- UARTD3.ud_usart = USART3;
- UARTD3.ud_dmap = STM32_DMA1;
- UARTD3.ud_dmarx = STM32_DMA_CHANNEL_3;
- UARTD3.ud_dmatx = STM32_DMA_CHANNEL_2;
- UARTD3.ud_dmaccr = 0;
+ UARTD3.usart = USART3;
+ UARTD3.dmap = STM32_DMA1;
+ UARTD3.dmarx = STM32_DMA_CHANNEL_3;
+ UARTD3.dmatx = STM32_DMA_CHANNEL_2;
+ UARTD3.dmaccr = 0;
#endif
}
@@ -480,10 +352,14 @@ void uart_lld_init(void) {
*/
void uart_lld_start(UARTDriver *uartp) {
- if (uartp->ud_state == UART_STOP) {
+ if (uartp->state == UART_STOP) {
#if STM32_UART_USE_USART1
if (&UARTD1 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
NVICEnableVector(USART1_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel4_IRQn,
@@ -496,7 +372,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if STM32_UART_USE_USART2
if (&UARTD2 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_6,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_7,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
NVICEnableVector(USART2_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel6_IRQn,
@@ -509,7 +389,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if STM32_UART_USE_USART3
if (&UARTD3 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
NVICEnableVector(USART3_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel2_IRQn,
@@ -522,18 +406,18 @@ void uart_lld_start(UARTDriver *uartp) {
/* Static DMA setup, the transfer size depends on the USART settings,
it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
- uartp->ud_dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12;
- if ((uartp->ud_config->uc_cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M)
- uartp->ud_dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0;
- dmaChannelSetPeripheral(&uartp->ud_dmap->channels[uartp->ud_dmarx],
- &uartp->ud_usart->DR);
- dmaChannelSetPeripheral(&uartp->ud_dmap->channels[uartp->ud_dmatx],
- &uartp->ud_usart->DR);
- uartp->ud_rxbuf = 0;
+ uartp->dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12;
+ if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M)
+ uartp->dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0;
+ dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmarx],
+ &uartp->usart->DR);
+ dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmatx],
+ &uartp->usart->DR);
+ uartp->rxbuf = 0;
}
- uartp->ud_rxstate = UART_RX_IDLE;
- uartp->ud_txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
usart_start(uartp);
}
@@ -546,7 +430,7 @@ void uart_lld_start(UARTDriver *uartp) {
*/
void uart_lld_stop(UARTDriver *uartp) {
- if (uartp->ud_state == UART_READY) {
+ if (uartp->state == UART_READY) {
usart_stop(uartp);
#if STM32_UART_USE_USART1
@@ -554,7 +438,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART1_IRQn);
NVICDisableVector(DMA1_Channel4_IRQn);
NVICDisableVector(DMA1_Channel5_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
return;
}
@@ -565,7 +450,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART2_IRQn);
NVICDisableVector(DMA1_Channel6_IRQn);
NVICDisableVector(DMA1_Channel7_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_6);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_7);
RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
return;
}
@@ -576,7 +462,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART3_IRQn);
NVICDisableVector(DMA1_Channel2_IRQn);
NVICDisableVector(DMA1_Channel3_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN;
return;
}
@@ -598,10 +485,10 @@ void uart_lld_stop(UARTDriver *uartp) {
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
/* TX DMA channel preparation and start.*/
- dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmatx, n, txbuf,
- uartp->ud_dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
+ dmaSetupChannel(uartp->dmap, uartp->dmatx, n, txbuf,
+ uartp->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
DMA_CCR1_TEIE | DMA_CCR1_TCIE);
- dmaEnableChannel(uartp->ud_dmap, uartp->ud_dmatx);
+ dmaEnableChannel(uartp->dmap, uartp->dmatx);
}
/**
@@ -617,9 +504,9 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
*/
size_t uart_lld_stop_send(UARTDriver *uartp) {
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmatx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmatx);
- return (size_t)uartp->ud_dmap->channels[uartp->ud_dmatx].CNDTR;
+ dmaDisableChannel(uartp->dmap, uartp->dmatx);
+ dmaClearChannel(uartp->dmap, uartp->dmatx);
+ return (size_t)uartp->dmap->channels[uartp->dmatx].CNDTR;
}
/**
@@ -636,14 +523,14 @@ size_t uart_lld_stop_send(UARTDriver *uartp) {
void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
/* Stopping previous activity (idle state).*/
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmarx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmarx);
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ dmaClearChannel(uartp->dmap, uartp->dmarx);
/* RX DMA channel preparation and start.*/
- dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmarx, n, rxbuf,
- uartp->ud_dmaccr | DMA_CCR1_MINC |
+ dmaSetupChannel(uartp->dmap, uartp->dmarx, n, rxbuf,
+ uartp->dmaccr | DMA_CCR1_MINC |
DMA_CCR1_TEIE | DMA_CCR1_TCIE);
- dmaEnableChannel(uartp->ud_dmap, uartp->ud_dmarx);
+ dmaEnableChannel(uartp->dmap, uartp->dmarx);
}
/**
@@ -660,9 +547,9 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
size_t uart_lld_stop_receive(UARTDriver *uartp) {
size_t n;
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmarx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmarx);
- n = (size_t)uartp->ud_dmap->channels[uartp->ud_dmarx].CNDTR;
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ dmaClearChannel(uartp->dmap, uartp->dmarx);
+ n = (size_t)uartp->dmap->channels[uartp->dmarx].CNDTR;
set_rx_idle_loop(uartp);
return n;
}
diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h
index 589a274fa..9321df85c 100644
--- a/os/hal/platforms/STM32/uart_lld.h
+++ b/os/hal/platforms/STM32/uart_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -68,21 +69,21 @@
/**
* @brief USART1 interrupt priority level setting.
*/
-#if !defined(STM32_UART_USART1_IRQ_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART1_IRQ_PRIORITY 12
#endif
/**
* @brief USART2 interrupt priority level setting.
*/
-#if !defined(STM32_UART_USART2_IRQ_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART2_IRQ_PRIORITY 12
#endif
/**
* @brief USART3 interrupt priority level setting.
*/
-#if !defined(STM32_UART_USART3_IRQ_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART3_IRQ_PRIORITY 12
#endif
@@ -92,7 +93,7 @@
* because of the channels ordering the RX channel has always priority
* over the TX channel.
*/
-#if !defined(STM32_UART_USART1_DMA_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART1_DMA_PRIORITY 0
#endif
@@ -102,7 +103,7 @@
* because of the channels ordering the RX channel has always priority
* over the TX channel.
*/
-#if !defined(STM32_UART_USART2_DMA_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART2_DMA_PRIORITY 0
#endif
/**
@@ -111,35 +112,17 @@
* because of the channels ordering the RX channel has always priority
* over the TX channel.
*/
-#if !defined(STM32_UART_USART3_DMA_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART3_DMA_PRIORITY 0
#endif
/**
* @brief USART1 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
*/
-#if !defined(STM32_UART_USART1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief USART2 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_UART_USART2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief USART3 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_UART_USART3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
#endif
/*===========================================================================*/
@@ -158,15 +141,15 @@
#error "USART3 not present in the selected device"
#endif
-#if STM32_UART_USE_UART4 && !STM32_HAS_UART4
-#error "UART4 not present in the selected device"
-#endif
-
#if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \
- !STM32_UART_USE_USART3 && !STM32_UART_USE_UART4
+ !STM32_UART_USE_USART3
#error "UART driver activated but no USART/UART peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -212,40 +195,40 @@ typedef struct {
/**
* @brief End of transmission buffer callback.
*/
- uartcb_t uc_txend1;
+ uartcb_t txend1_cb;
/**
* @brief Physical end of transmission callback.
*/
- uartcb_t uc_txend2;
+ uartcb_t txend2_cb;
/**
* @brief Receive buffer filled callback.
*/
- uartcb_t uc_rxend;
+ uartcb_t rxend_cb;
/**
* @brief Character received while out if the @p UART_RECEIVE state.
*/
- uartccb_t uc_rxchar;
+ uartccb_t rxchar_cb;
/**
* @brief Receive error callback.
*/
- uartecb_t uc_rxerr;
+ uartecb_t rxerr_cb;
/* End of the mandatory fields.*/
/**
* @brief Bit rate.
*/
- uint32_t uc_speed;
+ uint32_t speed;
/**
* @brief Initialization value for the CR1 register.
*/
- uint16_t uc_cr1;
+ uint16_t cr1;
/**
* @brief Initialization value for the CR2 register.
*/
- uint16_t uc_cr2;
+ uint16_t cr2;
/**
* @brief Initialization value for the CR3 register.
*/
- uint16_t uc_cr3;
+ uint16_t cr3;
} UARTConfig;
/**
@@ -255,19 +238,19 @@ struct UARTDriver {
/**
* @brief Driver state.
*/
- uartstate_t ud_state;
+ uartstate_t state;
/**
* @brief Transmitter state.
*/
- uarttxstate_t ud_txstate;
+ uarttxstate_t txstate;
/**
* @brief Receiver state.
*/
- uartrxstate_t ud_rxstate;
+ uartrxstate_t rxstate;
/**
* @brief Current configuration data.
*/
- const UARTConfig *ud_config;
+ const UARTConfig *config;
#if defined(UART_DRIVER_EXT_FIELDS)
UART_DRIVER_EXT_FIELDS
#endif
@@ -275,27 +258,27 @@ struct UARTDriver {
/**
* @brief Pointer to the USART registers block.
*/
- USART_TypeDef *ud_usart;
+ USART_TypeDef *usart;
/**
* @brief Pointer to the DMA registers block.
*/
- stm32_dma_t *ud_dmap;
+ stm32_dma_t *dmap;
/**
* @brief DMA priority bit mask.
*/
- uint32_t ud_dmaccr;
+ uint32_t dmaccr;
/**
* @brief Receive DMA channel.
*/
- uint8_t ud_dmarx;
+ uint8_t dmarx;
/**
* @brief Transmit DMA channel.
*/
- uint8_t ud_dmatx;
+ uint8_t dmatx;
/**
* @brief Default receive buffer while into @p UART_RX_IDLE state.
*/
- volatile uint16_t ud_rxbuf;
+ volatile uint16_t rxbuf;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/usb_lld.c b/os/hal/platforms/STM32/usb_lld.c
index 3fe6771ea..331eb38c3 100644
--- a/os/hal/platforms/STM32/usb_lld.c
+++ b/os/hal/platforms/STM32/usb_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -29,7 +30,6 @@
#include "ch.h"
#include "hal.h"
-#include "usb.h"
#if HAL_USE_USB || defined(__DOXYGEN__)
@@ -44,33 +44,123 @@
USBDriver USBD1;
#endif
-
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/**
* @brief EP0 state.
+ * @note It is an union because IN and OUT endpoints are never used at the
+ * same time for EP0.
*/
-static USBEndpointState ep0state;
+static union {
+ /**
+ * @brief IN EP0 state.
+ */
+ USBInEndpointState in;
+ /**
+ * @brief OUT EP0 state.
+ */
+ USBOutEndpointState out;
+} ep0_state;
/**
* @brief EP0 initialization structure.
*/
static const USBEndpointConfig ep0config = {
+ USB_EP_MODE_TYPE_CTRL | USB_EP_MODE_TRANSACTION,
+ _usb_ep0setup,
_usb_ep0in,
_usb_ep0out,
0x40,
0x40,
- EPR_EP_TYPE_CONTROL | EPR_STAT_TX_STALL | EPR_STAT_RX_VALID,
- 0x40,
- 0x80
+ &ep0_state.in,
+ &ep0_state.out
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
+/**
+ * @brief Resets the packet memory allocator.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ */
+static void pm_reset(USBDriver *usbp) {
+
+ /* The first 64 bytes are reserved for the descriptors table. The effective
+ available RAM for endpoint buffers is just 448 bytes.*/
+ usbp->pmnext = 64;
+}
+
+/**
+ * @brief Resets the packet memory allocator.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] size size of the packet buffer to allocate
+ */
+static uint32_t pm_alloc(USBDriver *usbp, size_t size) {
+ uint32_t next;
+
+ next = usbp->pmnext;
+ usbp->pmnext += size;
+ chDbgAssert(usbp->pmnext > USB_PMA_SIZE, "pm_alloc(), #1", "PMA overflow");
+ return next;
+}
+
+/**
+ * @brief Copies a packet from memory into a packet buffer.
+ *
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the endpoint data
+ * @param[in] n maximum number of bytes to copy
+ */
+static void write_packet(usbep_t ep, const uint8_t *buf, size_t n){
+ uint32_t *pmap;
+ stm32_usb_descriptor_t *udp;
+ size_t count;
+
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->TXADDR);
+ udp->TXCOUNT = n;
+ count = (n + 1) / 2;
+ while (count) {
+ *pmap++ = *(uint16_t *)buf;
+ buf += 2;
+ count--;
+ }
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
+}
+
+/**
+ * @brief Copies a packet from a packet buffer into memory.
+ *
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to copy the endpoint data
+ * @param[in] n maximum number of bytes to copy
+ * @return The packet size.
+ * @retval 0 Special case, zero sized packet.
+ */
+static size_t read_packet(usbep_t ep, uint8_t *buf, size_t n){
+ uint32_t *pmap;
+ stm32_usb_descriptor_t *udp;
+ size_t count;
+
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->RXADDR);
+ count = udp->RXCOUNT & RXCOUNT_COUNT_MASK;
+ if (n > count)
+ n = count;
+ count = (n + 1) / 2;
+ while (count) {
+ *(uint16_t *)buf = (uint16_t)*pmap++;
+ buf += 2;
+ count--;
+ }
+ return n;
+}
+
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
@@ -95,6 +185,7 @@ CH_IRQ_HANDLER(USB_HP_IRQHandler) {
*/
CH_IRQ_HANDLER(USB_LP_IRQHandler) {
uint32_t istr;
+ size_t n;
USBDriver *usbp = &USBD1;
CH_IRQ_PROLOGUE();
@@ -104,15 +195,40 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
/* USB bus reset condition handling.*/
if (istr & ISTR_RESET) {
_usb_reset(usbp);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_RESET);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET);
STM32_USB->ISTR = ~ISTR_RESET;
}
+ /* USB bus SUSPEND condition handling.*/
+ if (istr & ISTR_SUSP) {
+ STM32_USB->CNTR |= CNTR_FSUSP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND);
+#if STM32_USB_LOW_POWER_ON_SUSPEND
+ STM32_USB->CNTR |= CNTR_LP_MODE;
+#endif
+ STM32_USB->ISTR = ~ISTR_SUSP;
+ }
+
+ /* USB bus WAKEUP condition handling.*/
+ if (istr & ISTR_WKUP) {
+ uint32_t fnr = STM32_USB->FNR;
+ if (!(fnr & FNR_RXDP)) {
+ STM32_USB->CNTR &= ~CNTR_FSUSP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP);
+ }
+#if STM32_USB_LOW_POWER_ON_SUSPEND
+ else {
+ /* Just noise, going back in SUSPEND mode, reference manual 22.4.5,
+ table 169.*/
+ STM32_USB->CNTR |= CNTR_LP_MODE;
+ }
+#endif
+ STM32_USB->ISTR = ~ISTR_WKUP;
+ }
+
/* SOF handling.*/
if (istr & ISTR_SOF) {
- if (usbp->usb_config->uc_sof_cb)
- usbp->usb_config->uc_sof_cb(usbp);
+ _usb_isr_invoke_sof_cb(usbp);
STM32_USB->ISTR = ~ISTR_SOF;
}
@@ -120,19 +236,63 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
while (istr & ISTR_CTR) {
uint32_t ep;
uint32_t epr = STM32_USB->EPR[ep = istr & ISTR_EP_ID_MASK];
- const USBEndpointConfig *epcp = usbp->usb_ep[ep]->uep_config;
+ const USBEndpointConfig *epcp = usbp->epc[ep];
if (epr & EPR_CTR_TX) {
/* IN endpoint, transmission.*/
EPR_CLEAR_CTR_TX(ep);
- if (epcp->uepc_in_cb)
- epcp->uepc_in_cb(usbp, ep);
+ if (epcp->ep_mode & USB_EP_MODE_PACKET) {
+ /* Packet mode, just invokes the callback.*/
+ _usb_isr_invoke_in_cb(usbp, ep);
+ }
+ else {
+ /* Transaction mode.*/
+ n = USB_GET_DESCRIPTOR(ep)->TXCOUNT;
+ epcp->in_state->txbuf += n;
+ epcp->in_state->txcnt += n;
+ epcp->in_state->txsize -= n;
+ if (epcp->in_state->txsize > 0) {
+ /* Transfer not completed, there are more packets to send.*/
+ if (epcp->in_state->txsize > epcp->in_maxsize)
+ n = epcp->in_maxsize;
+ else
+ n = epcp->in_state->txsize;
+ write_packet(ep, epcp->in_state->txbuf, n);
+ }
+ else {
+ /* Transfer completed, invokes the callback.*/
+ _usb_isr_invoke_in_cb(usbp, ep);
+ }
+ }
}
if (epr & EPR_CTR_RX) {
- /* OUT endpoint, receive.*/
EPR_CLEAR_CTR_RX(ep);
- if (epcp->uepc_out_cb)
- epcp->uepc_out_cb(usbp, ep);
+ /* OUT endpoint, receive.*/
+ if (epr & EPR_SETUP) {
+ /* Setup packets handling, setup packets are handled using a
+ specific callback.*/
+ _usb_isr_invoke_setup_cb(usbp, ep);
+ }
+ else if (epcp->ep_mode & USB_EP_MODE_PACKET) {
+ /* Packet mode, just invokes the callback.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+ else {
+ /* Transaction mode.*/
+ n = read_packet(ep, epcp->out_state->rxbuf, epcp->out_state->rxsize);
+ epcp->out_state->rxbuf += n;
+ epcp->out_state->rxcnt += n;
+ epcp->out_state->rxsize -= n;
+ epcp->out_state->rxpkts -= 1;
+ if (epcp->out_state->rxpkts > 0) {
+ /* Transfer not completed, there are more packets to receive.*/
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
+ }
+ else {
+ /* Transfer completed, invokes the callback.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+ }
}
istr = STM32_USB->ISTR;
}
@@ -152,10 +312,6 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
*/
void usb_lld_init(void) {
- /* USB reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
usbObjectInit(&USBD1);
}
@@ -169,7 +325,7 @@ void usb_lld_init(void) {
*/
void usb_lld_start(USBDriver *usbp) {
- if (usbp->usb_state == USB_STOP) {
+ if (usbp->state == USB_STOP) {
/* Clock activation.*/
#if STM32_USB_USE_USB1
if (&USBD1 == usbp) {
@@ -183,11 +339,12 @@ void usb_lld_start(USBDriver *usbp) {
CORTEX_PRIORITY_MASK(STM32_USB_USB1_HP_IRQ_PRIORITY));
NVICEnableVector(USB_LP_CAN1_RX0_IRQn,
CORTEX_PRIORITY_MASK(STM32_USB_USB1_LP_IRQ_PRIORITY));
-
- /* Reset procedure enforced on driver start.*/
- _usb_reset(&USBD1);
+ /* Releases the USB reset.*/
+ STM32_USB->CNTR = 0;
}
#endif
+ /* Reset procedure enforced on driver start.*/
+ _usb_reset(usbp);
}
/* Configuration.*/
}
@@ -202,11 +359,12 @@ void usb_lld_start(USBDriver *usbp) {
void usb_lld_stop(USBDriver *usbp) {
/* If in ready state then disables the USB clock.*/
- if (usbp->usb_state == USB_STOP) {
+ if (usbp->state == USB_STOP) {
#if STM32_ADC_USE_ADC1
if (&USBD1 == usbp) {
NVICDisableVector(USB_HP_CAN1_TX_IRQn);
NVICDisableVector(USB_LP_CAN1_RX0_IRQn);
+ STM32_USB->CNTR = CNTR_PDWN | CNTR_FRES;
RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
}
#endif
@@ -223,25 +381,23 @@ void usb_lld_stop(USBDriver *usbp) {
void usb_lld_reset(USBDriver *usbp) {
uint32_t cntr;
- /* Powers up the transceiver while holding the USB in reset state.*/
- STM32_USB->CNTR = CNTR_FRES;
-
- /* Releases the USB reset, BTABLE is reset to zero.*/
- STM32_USB->CNTR = 0;
+ /* Post reset initialization.*/
+ STM32_USB->BTABLE = 0;
STM32_USB->ISTR = 0;
STM32_USB->DADDR = DADDR_EF;
- cntr = /*CNTR_ESOFM | */ CNTR_RESETM | /*CNTR_SUSPM |*/
- /*CNTR_WKUPM | CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
+ cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM |
+ CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
/* The SOF interrupt is only enabled if a callback is defined for
this service because it is an high rate source.*/
- if (usbp->usb_config->uc_sof_cb != NULL)
+ if (usbp->config->sof_cb != NULL)
cntr |= CNTR_SOFM;
STM32_USB->CNTR = cntr;
+ /* Resets the packet memory allocator.*/
+ pm_reset(usbp);
+
/* EP0 initialization.*/
- memset(&ep0state, 0, sizeof ep0state);
- ep0state.uep_config = &ep0config;
- usbp->usb_ep[0] = &ep0state;
+ usbp->epc[0] = &ep0config;
usb_lld_init_endpoint(usbp, 0);
}
@@ -249,14 +405,12 @@ void usb_lld_reset(USBDriver *usbp) {
* @brief Sets the USB address.
*
* @param[in] usbp pointer to the @p USBDriver object
- * @param[in] addr the USB address
*
* @notapi
*/
-void usb_lld_set_address(USBDriver *usbp, uint8_t addr) {
+void usb_lld_set_address(USBDriver *usbp) {
- (void)usbp;
- STM32_USB->DADDR = (uint32_t)addr | DADDR_EF;
+ STM32_USB->DADDR = (uint32_t)(usbp->address) | DADDR_EF;
}
/**
@@ -268,25 +422,55 @@ void usb_lld_set_address(USBDriver *usbp, uint8_t addr) {
* @notapi
*/
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
- uint16_t nblocks;
+ uint16_t nblocks, epr;
stm32_usb_descriptor_t *dp;
- const USBEndpointConfig *epcp = usbp->usb_ep[ep]->uep_config;
+ const USBEndpointConfig *epcp = usbp->epc[ep];
+
+ /* Setting the endpoint type.*/
+ switch (epcp->ep_mode & USB_EP_MODE_TYPE) {
+ case USB_EP_MODE_TYPE_ISOC:
+ epr = EPR_EP_TYPE_ISO;
+ break;
+ case USB_EP_MODE_TYPE_BULK:
+ epr = EPR_EP_TYPE_BULK;
+ break;
+ case USB_EP_MODE_TYPE_INTR:
+ epr = EPR_EP_TYPE_INTERRUPT;
+ break;
+ default:
+ epr = EPR_EP_TYPE_CONTROL;
+ }
+
+ /* IN endpoint settings, always in NAK mode initially.*/
+ if (epcp->in_cb != NULL)
+ epr |= EPR_STAT_TX_NAK;
+
+ /* OUT endpoint settings. If the endpoint is in packet mode then it must
+ start ready to accept data else it must start in NAK mode.*/
+ if (epcp->out_cb != NULL) {
+ if (epcp->ep_mode & USB_EP_MODE_PACKET) {
+ usbp->receiving |= (1 << ep);
+ epr |= EPR_STAT_RX_VALID;
+ }
+ else
+ epr |= EPR_STAT_RX_NAK;
+ }
/* EPxR register setup.*/
- EPR_SET(ep, epcp->uepc_epr | ep);
- EPR_TOGGLE(ep, epcp->uepc_epr);
+ EPR_SET(ep, epr | ep);
+ EPR_TOGGLE(ep, epr);
/* Endpoint size and address initialization.*/
- if (epcp->uepc_out_maxsize > 62)
- nblocks = (((((epcp->uepc_out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
+ if (epcp->out_maxsize > 62)
+ nblocks = (((((epcp->out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
0x8000;
else
- nblocks = ((((epcp->uepc_out_maxsize - 1) | 1) + 1) / 2) << 10;
+ nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10;
dp = USB_GET_DESCRIPTOR(ep);
dp->TXCOUNT = 0;
dp->RXCOUNT = nblocks;
- dp->TXADDR = epcp->uepc_inaddr;
- dp->RXADDR = epcp->uepc_outaddr;
+ dp->TXADDR = pm_alloc(usbp, epcp->in_maxsize);
+ dp->RXADDR = pm_alloc(usbp, epcp->out_maxsize);
}
/**
@@ -299,232 +483,275 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
void usb_lld_disable_endpoints(USBDriver *usbp) {
unsigned i;
- (void)usbp;
+ /* Resets the packet memory allocator.*/
+ pm_reset(usbp);
+
+ /* Disabling all endpoints.*/
for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) {
EPR_TOGGLE(i, 0);
EPR_SET(i, 0);
}
+}
+/**
+ * @brief Returns the status of an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+ switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) {
+ case EPR_STAT_RX_DIS:
+ return EP_STATUS_DISABLED;
+ case EPR_STAT_RX_STALL:
+ return EP_STATUS_STALLED;
+ default:
+ return EP_STATUS_ACTIVE;
+ }
}
/**
- * @brief Returns the number of bytes readable from the receive packet
- * buffer.
+ * @brief Returns the status of an IN endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @return The number of bytes that are effectively available.
- * @retval 0 Data not yet available.
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
*
* @notapi
*/
-size_t usb_lld_get_readable(USBDriver *usbp, usbep_t ep) {
+usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
(void)usbp;
- if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_NAK)
- return 0;
- return (size_t)(USB_GET_DESCRIPTOR(ep)->RXCOUNT & RXCOUNT_COUNT_MASK);
+ switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) {
+ case EPR_STAT_TX_DIS:
+ return EP_STATUS_DISABLED;
+ case EPR_STAT_TX_STALL:
+ return EP_STATUS_STALLED;
+ default:
+ return EP_STATUS_ACTIVE;
+ }
}
/**
- * @brief Endpoint read.
- * @details The buffered packet is copied into the user buffer and then
- * the endpoint is brought to the valid state in order to allow
- * reception of more data.
+ * @brief Reads a setup packet from the dedicated packet buffer.
+ * @details This function must be invoked in the context of the @p setup_cb
+ * callback in order to read the received setup packet.
+ * @pre In order to use this function the endpoint must have been
+ * initialized as a control endpoint.
+ * @post The endpoint is ready to accept another packet.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[out] buf buffer where to copy the endpoint data
- * @param[in] n maximum number of bytes to copy
- * @return The number of bytes that were effectively available.
- * @retval 0 Data not yet available.
+ * @param[out] buf buffer where to copy the packet data
*
* @notapi
*/
-size_t usb_lld_read(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
+void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
uint32_t *pmap;
stm32_usb_descriptor_t *udp;
- size_t count;
+ uint32_t n;
(void)usbp;
- if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_NAK)
- return 0;
-
udp = USB_GET_DESCRIPTOR(ep);
pmap = USB_ADDR2PTR(udp->RXADDR);
- count = udp->RXCOUNT & RXCOUNT_COUNT_MASK;
- if (n > count)
- n = count;
- count = (n + 1) / 2;
- while (count) {
+ for (n = 0; n < 4; n++) {
*(uint16_t *)buf = (uint16_t)*pmap++;
buf += 2;
- count--;
}
EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
- return n;
}
+
/**
- * @brief Returns the number of bytes writeable to the transmit packet
- * buffer.
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to accept another packet.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @return The number of bytes that can be written.
- * @retval 0 Endpoint not ready for transmission.
+ * @param[out] buf buffer where to copy the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The received packet size regardless the specified
+ * @p n parameter.
+ * @retval 0 Zero size packet received.
*
- * @iclass
+ * @notapi
*/
-size_t usb_lld_get_writeable(USBDriver *usbp, usbep_t ep) {
+size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+ uint32_t *pmap;
+ stm32_usb_descriptor_t *udp;
+ size_t count;
- if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_NAK)
- return 0;
- return (size_t)usbp->usb_ep[ep]->uep_config->uepc_in_maxsize;
+ (void)usbp;
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->RXADDR);
+ count = udp->RXCOUNT & RXCOUNT_COUNT_MASK;
+ if (n > count)
+ n = count;
+ n = (n + 1) / 2;
+ while (n > 0) {
+ *(uint16_t *)buf = (uint16_t)*pmap++;
+ buf += 2;
+ n--;
+ }
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
+ return count;
}
/**
- * @brief Endpoint write.
- * @details The user data is copied in the packer memory and then
- * the endpoint is brought to the valid state in order to allow
- * transmission.
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[in] buf buffer where to copy the endpoint data
- * @param[in] n maximum number of bytes to copy
- * @return The number of bytes that were effectively written.
- * @retval 0 Endpoint not ready for transmission.
+ * @param[in] buf buffer where to fetch the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
*
* @notapi
*/
-size_t usb_lld_write(USBDriver *usbp, usbep_t ep,
- const uint8_t *buf,
- size_t n) {
+void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
uint32_t *pmap;
stm32_usb_descriptor_t *udp;
- size_t count;
(void)usbp;
- if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_NAK)
- return 0;
-
udp = USB_GET_DESCRIPTOR(ep);
pmap = USB_ADDR2PTR(udp->TXADDR);
udp->TXCOUNT = n;
- count = (n + 1) / 2;
- while (count) {
+ n = (n + 1) / 2;
+ while (n > 0) {
*pmap++ = *(uint16_t *)buf;
buf += 2;
- count--;
+ n--;
}
EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
- return n;
}
/**
- * @brief Returns the status of an IN endpoint.
+ * @brief Starts a receive operation on an OUT endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the endpoint data
+ * @param[in] n maximum number of bytes to copy in the buffer
*
* @notapi
*/
-usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
- switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) {
- case EPR_STAT_TX_DIS:
- return EP_STATUS_DISABLED;
- case EPR_STAT_TX_STALL:
- return EP_STATUS_STALLED;
- default:
- return EP_STATUS_ACTIVE;
- }
+void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+ USBOutEndpointState *osp = usbp->epc[ep]->out_state;
+
+ osp->rxbuf = buf;
+ osp->rxsize = n;
+ osp->rxcnt = 0;
+ if (osp->rxsize == 0) /* Special case for zero sized packets.*/
+ osp->rxpkts = 1;
+ else
+ osp->rxpkts = (uint16_t)((n + usbp->epc[ep]->out_maxsize - 1) /
+ usbp->epc[ep]->out_maxsize);
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
}
/**
- * @brief Returns the status of an OUT endpoint.
+ * @brief Starts a transmit operation on an IN endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the endpoint data
+ * @param[in] n maximum number of bytes to copy
*
* @notapi
*/
-usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
- switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) {
- case EPR_STAT_RX_DIS:
- return EP_STATUS_DISABLED;
- case EPR_STAT_RX_STALL:
- return EP_STATUS_STALLED;
- default:
- return EP_STATUS_ACTIVE;
- }
+void usb_lld_start_in(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+ USBInEndpointState *isp = usbp->epc[ep]->in_state;
+
+ isp->txbuf = buf;
+ isp->txsize = n;
+ isp->txcnt = 0;
+ if (n > (size_t)usbp->epc[ep]->in_maxsize)
+ n = (size_t)usbp->epc[ep]->in_maxsize;
+ write_packet(ep, buf, n);
}
/**
- * @brief Brings an IN endpoint in the stalled state.
+ * @brief Brings an OUT endpoint in the stalled state.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
-void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
+void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
(void)usbp;
- EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL);
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL);
}
/**
- * @brief Brings an OUT endpoint in the stalled state.
+ * @brief Brings an IN endpoint in the stalled state.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
-void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
+void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
(void)usbp;
- EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL);
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL);
}
/**
- * @brief Brings an IN endpoint in the active state.
+ * @brief Brings an OUT endpoint in the active state.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
-void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
+void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
(void)usbp;
/* Makes sure to not put to NAK an endpoint that is already
transferring.*/
- if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID)
- EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK);
+ if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID)
+ EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK);
}
/**
- * @brief Brings an OUT endpoint in the active state.
+ * @brief Brings an IN endpoint in the active state.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
-void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
+void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
(void)usbp;
/* Makes sure to not put to NAK an endpoint that is already
transferring.*/
- if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID)
- EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK);
+ if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID)
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK);
}
#endif /* HAL_USE_USB */
diff --git a/os/hal/platforms/STM32/usb_lld.h b/os/hal/platforms/STM32/usb_lld.h
index e21bbecd2..9b5e9dad2 100644
--- a/os/hal/platforms/STM32/usb_lld.h
+++ b/os/hal/platforms/STM32/usb_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -41,6 +42,11 @@
*/
#define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER
+/**
+ * @brief This device requires the address change after the status packet.
+ */
+#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -55,6 +61,13 @@
#endif
/**
+ * @brief Enables the USB device low power mode on suspend.
+ */
+#if !defined(STM32_USB_LOW_POWER_ON_SUSPEND) || defined(__DOXYGEN__)
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#endif
+
+/**
* @brief USB1 interrupt priority level setting.
*/
#if !defined(STM32_USB_USB1_HP_IRQ_PRIORITY) || defined(__DOXYGEN__)
@@ -89,84 +102,105 @@
/*===========================================================================*/
/**
- * @brief Type of an USB Endpoint configuration structure.
- * @note Platform specific restrictions may apply to endpoints.
+ * @brief Type of an endpoint state structure.
*/
typedef struct {
/**
- * @brief IN endpoint notification callback.
+ * @brief Pointer to the transmission buffer.
*/
- usbepcallback_t uepc_in_cb;
+ const uint8_t *txbuf;
/**
- * @brief OUT endpoint notification callback.
+ * @brief Requested transmit transfer size.
*/
- usbepcallback_t uepc_out_cb;
+ size_t txsize;
/**
- * @brief IN endpoint maximum packet size.
+ * @brief Transmitted bytes so far.
*/
- uint16_t uepc_in_maxsize;
+ size_t txcnt;
+} USBInEndpointState;
+
+/**
+ * @brief Type of an endpoint state structure.
+ */
+typedef struct {
/**
- * @brief OUT endpoint maximum packet size.
+ * @brief Number of packets to receive.
*/
- uint16_t uepc_out_maxsize;
- /* End of the mandatory fields.*/
+ uint16_t rxpkts;
/**
- * @brief EPxR register initialization value.
- * @note Do not specify the EA field, leave it to zero.
+ * @brief Pointer to the receive buffer.
*/
- uint16_t uepc_epr;
+ uint8_t *rxbuf;
/**
- * @brief Endpoint IN buffer address as offset in the PMA.
+ * @brief Requested receive transfer size.
*/
- uint16_t uepc_inaddr;
+ size_t rxsize;
/**
- * @brief Endpoint OUT buffer address as offset in the PMA.
+ * @brief Received bytes so far.
*/
- uint16_t uepc_outaddr;
-} USBEndpointConfig;
-
+ size_t rxcnt;
+} USBOutEndpointState;
/**
- * @brief Type of an endpoint state structure.
+ * @brief Type of an USB endpoint configuration structure.
+ * @note Platform specific restrictions may apply to endpoints.
*/
typedef struct {
/**
- * @brief Configuration associated to the endpoint.
+ * @brief Type and mode of the endpoint.
*/
- const USBEndpointConfig *uep_config;
+ uint32_t ep_mode;
/**
- * @brief Pointer to the transmission buffer.
+ * @brief Setup packet notification callback.
+ * @details This callback is invoked when a setup packet has been
+ * received.
+ * @post The application must immediately call @p usbReadPacket() in
+ * order to access the received packet.
+ * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
+ * endpoints, it should be set to @p NULL for other endpoint
+ * types.
*/
- const uint8_t *uep_txbuf;
+ usbepcallback_t setup_cb;
/**
- * @brief Pointer to the receive buffer.
+ * @brief IN endpoint notification callback.
+ * @details This field must be set to @p NULL if the IN endpoint is not
+ * used.
*/
- uint8_t *uep_rxbuf;
+ usbepcallback_t in_cb;
/**
- * @brief Requested transmit transfer size.
+ * @brief OUT endpoint notification callback.
+ * @details This field must be set to @p NULL if the OUT endpoint is not
+ * used.
*/
- size_t uep_txsize;
- /**
- * @brief Requested receive transfer size.
- */
- size_t uep_rxsize;
+ usbepcallback_t out_cb;
/**
- * @brief Transmitted bytes so far.
+ * @brief IN endpoint maximum packet size.
+ * @details This field must be set to zero if the IN endpoint is not
+ * used.
*/
- size_t uep_txcnt;
+ uint16_t in_maxsize;
/**
- * @brief Received bytes so far.
- */
- size_t uep_rxcnt;
+ * @brief OUT endpoint maximum packet size.
+ * @details This field must be set to zero if the OUT endpoint is not
+ * used.
+ */
+ uint16_t out_maxsize;
/**
- * @brief @p TRUE if transmitting else @p FALSE.
+ * @brief @p USBEndpointState associated to the IN endpoint.
+ * @details This structure maintains the state of the IN endpoint when
+ * the endpoint is not in packet mode. Endpoints configured in
+ * packet mode must set this field to @p NULL.
*/
- uint8_t uep_transmitting;
+ USBInEndpointState *in_state;
/**
- * @brief @p TRUE if receiving else @p FALSE.
+ * @brief @p USBEndpointState associated to the OUT endpoint.
+ * @details This structure maintains the state of the OUT endpoint when
+ * the endpoint is not in packet mode. Endpoints configured in
+ * packet mode must set this field to @p NULL.
*/
- uint8_t uep_receiving;
-} USBEndpointState;
+ USBOutEndpointState *out_state;
+ /* End of the mandatory fields.*/
+} USBEndpointConfig;
/**
* @brief Type of an USB driver configuration structure.
@@ -176,22 +210,22 @@ typedef struct {
* @brief USB events callback.
* @details This callback is invoked when an USB driver event is registered.
*/
- usbeventcb_t uc_event_cb;
+ usbeventcb_t event_cb;
/**
* @brief Device GET_DESCRIPTOR request callback.
* @note This callback is mandatory and cannot be set to @p NULL.
*/
- usbgetdescriptor_t uc_get_descriptor_cb;
+ usbgetdescriptor_t get_descriptor_cb;
/**
* @brief Requests hook callback.
* @details This hook allows to be notified of standard requests or to
* handle non standard requests.
*/
- usbreqhandler_t uc_requests_hook_cb;
+ usbreqhandler_t requests_hook_cb;
/**
* @brief Start Of Frame callback.
*/
- usbcallback_t uc_sof_cb;
+ usbcallback_t sof_cb;
/* End of the mandatory fields.*/
} USBConfig;
@@ -202,61 +236,68 @@ struct USBDriver {
/**
* @brief Driver state.
*/
- usbstate_t usb_state;
+ usbstate_t state;
/**
* @brief Current configuration data.
*/
- const USBConfig *usb_config;
+ const USBConfig *config;
/**
* @brief Field available to user, it can be used to associate an
* application-defined handler to the USB driver.
*/
- void *usb_param;
+ void *param;
/**
- * @brief Active endpoints configurations.
+ * @brief Bit map of the transmitting IN endpoints.
*/
- USBEndpointState *usb_ep[USB_MAX_ENDPOINTS + 1];
+ uint16_t transmitting;
/**
- * @brief Endpoint 0 state.
+ * @brief Bit map of the receiving OUT endpoints.
*/
- usbep0state_t usb_ep0state;
+ uint16_t receiving;
/**
- * @brief Next position in the buffer to be transferred through endpoint 0.
+ * @brief Active endpoints configurations.
*/
- uint8_t *usb_ep0next;
+ const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
/**
- * @brief Maximum number of bytes to be tranferred through endpoint 0.
+ * @brief Endpoint 0 state.
*/
- size_t usb_ep0max;
+ usbep0state_t ep0state;
/**
- * @brief Number of bytes yet to be tranferred through endpoint 0.
+ * @brief Next position in the buffer to be transferred through endpoint 0.
*/
- size_t usb_ep0n;
+ uint8_t *ep0next;
/**
- * @brief Size of the last packet transferred through endpoint 0.
+ * @brief Number of bytes yet to be transferred through endpoint 0.
*/
- size_t usb_ep0lastsize;
+ size_t ep0n;
/**
* @brief Endpoint 0 end transaction callback.
*/
- usbcallback_t usb_ep0endcb;
+ usbcallback_t ep0endcb;
/**
* @brief Setup packet buffer.
*/
- uint8_t usb_setup[8];
+ uint8_t setup[8];
/**
* @brief Current USB device status.
*/
- uint16_t usb_status;
+ uint16_t status;
/**
* @brief Assigned USB address.
*/
- uint8_t usb_address;
+ uint8_t address;
/**
* @brief Current USB device configuration.
*/
- uint8_t usb_configuration;
+ uint8_t configuration;
+#if defined(USB_DRIVER_EXT_FIELDS)
+ USB_DRIVER_EXT_FIELDS
+#endif
/* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the next address in the packet memory.
+ */
+ uint32_t pmnext;
};
/*===========================================================================*/
@@ -270,7 +311,7 @@ struct USBDriver {
*
* @notapi
*/
-#define usb_lld_fetch_word(p) (*(uint16_t *)p)
+#define usb_lld_fetch_word(p) (*(uint16_t *)(p))
/**
* @brief Returns the current frame number.
@@ -282,6 +323,37 @@ struct USBDriver {
*/
#define usb_lld_get_frame_number(usbp) (STM32_USB->FNR & FNR_FN_MASK)
+/**
+ * @brief Returns the exact size of a receive transaction.
+ * @details The received size can be different from the size specified in
+ * @p usbStartReceiveI() because the last packet could have a size
+ * different from the expected one.
+ * @pre The OUT endpoint must have been configured in transaction mode
+ * in order to use this function.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return Received data size.
+ *
+ * @notapi
+ */
+#define usb_lld_get_transaction_size(usbp, ep) \
+ ((usbp)->epc[ep]->out_state->rxcnt)
+
+/**
+ * @brief Returns the exact size of a received packet.
+ * @pre The OUT endpoint must have been configured in packet mode
+ * in order to use this function.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return Received data size.
+ *
+ * @notapi
+ */
+#define usb_lld_get_packet_size(usbp, ep) \
+ ((size_t)USB_GET_DESCRIPTOR(ep)->RXCOUNT & RXCOUNT_COUNT_MASK)
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -290,14 +362,6 @@ struct USBDriver {
extern USBDriver USBD1;
#endif
-#if !defined(__DOXYGEN__)
-extern const USBEndpointConfig usb_lld_ep0config;
-#endif
-
-#if !defined(__DOXYGEN__)
-extern USBEndpointState usb_lld_ep0state;
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -305,20 +369,24 @@ extern "C" {
void usb_lld_start(USBDriver *usbp);
void usb_lld_stop(USBDriver *usbp);
void usb_lld_reset(USBDriver *usbp);
- void usb_lld_set_address(USBDriver *usbp, uint8_t addr);
+ void usb_lld_set_address(USBDriver *usbp);
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
void usb_lld_disable_endpoints(USBDriver *usbp);
- size_t usb_lld_get_readable(USBDriver *usbp, usbep_t ep);
- size_t usb_lld_read(USBDriver *usbp, usbep_t ep,
- uint8_t *buf, size_t n);
- size_t usb_lld_write(USBDriver *usbp, usbep_t ep,
- const uint8_t *buf, size_t n);
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
+ size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_start_in(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/platforms/STM8L/hal_lld.c b/os/hal/platforms/STM8L/hal_lld.c
index 72cb830f3..e2f3c6a7b 100644
--- a/os/hal/platforms/STM8L/hal_lld.c
+++ b/os/hal/platforms/STM8L/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/hal_lld.h b/os/hal/platforms/STM8L/hal_lld.h
index 2e21988e7..159bd0c71 100644
--- a/os/hal/platforms/STM8L/hal_lld.h
+++ b/os/hal/platforms/STM8L/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/hal_lld_stm8l_hd.h b/os/hal/platforms/STM8L/hal_lld_stm8l_hd.h
index 9acad669b..efd3f187e 100644
--- a/os/hal/platforms/STM8L/hal_lld_stm8l_hd.h
+++ b/os/hal/platforms/STM8L/hal_lld_stm8l_hd.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/hal_lld_stm8l_md.h b/os/hal/platforms/STM8L/hal_lld_stm8l_md.h
index f1b1e89b8..e91035e36 100644
--- a/os/hal/platforms/STM8L/hal_lld_stm8l_md.h
+++ b/os/hal/platforms/STM8L/hal_lld_stm8l_md.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h b/os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h
index f01c18af9..e08d62d8d 100644
--- a/os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h
+++ b/os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/pal_lld.c b/os/hal/platforms/STM8L/pal_lld.c
index a91f380a4..e4c3001c6 100644
--- a/os/hal/platforms/STM8L/pal_lld.c
+++ b/os/hal/platforms/STM8L/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/pal_lld.h b/os/hal/platforms/STM8L/pal_lld.h
index 347fed85a..f42973218 100644
--- a/os/hal/platforms/STM8L/pal_lld.h
+++ b/os/hal/platforms/STM8L/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -174,7 +175,7 @@ typedef GPIO_TypeDef *ioportid_t;
*
* @notapi
*/
-#define pal_lld_init(config) *IOPORTS = *(config)
+#define pal_lld_init(config) (*IOPORTS = *(config))
/**
* @brief Reads the physical I/O port states.
@@ -214,7 +215,6 @@ typedef GPIO_TypeDef *ioportid_t;
*/
#define pal_lld_writeport(port, bits) ((port)->ODR = (bits))
-
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
@@ -230,7 +230,7 @@ typedef GPIO_TypeDef *ioportid_t;
* @notapi
*/
#define pal_lld_setgroupmode(port, mask, mode) \
- _pal_lld_setgroupmode(port, mask, mode)
+ _pal_lld_setgroupmode(port, mask, mode)
extern ROMCONST PALConfig pal_default_config;
diff --git a/os/hal/platforms/STM8L/platform.dox b/os/hal/platforms/STM8L/platform.dox
index b1b74251e..0a5f1b614 100644
--- a/os/hal/platforms/STM8L/platform.dox
+++ b/os/hal/platforms/STM8L/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -41,7 +42,7 @@
*/
/**
- * @defgroup STM8L_PAL STM8L GPIO Support
+ * @defgroup STM8L_PAL STM8L PAL Support
* @details The STM8L PAL driver uses the GPIO peripherals.
*
* @section stm8l_pal_1 Supported HW resources
@@ -84,7 +85,7 @@
*/
/**
- * @defgroup STM8L_SERIAL STM8L USART Support (buffered)
+ * @defgroup STM8L_SERIAL STM8L Serial Support
* @details The STM8L Serial driver uses the USART1 peripheral in a
* buffered, interrupt driven, implementation.
*
diff --git a/os/hal/platforms/STM8L/serial_lld.c b/os/hal/platforms/STM8L/serial_lld.c
index 887dd4967..372a48bf4 100644
--- a/os/hal/platforms/STM8L/serial_lld.c
+++ b/os/hal/platforms/STM8L/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/serial_lld.h b/os/hal/platforms/STM8L/serial_lld.h
index c4943433a..ca0de3b6d 100644
--- a/os/hal/platforms/STM8L/serial_lld.h
+++ b/os/hal/platforms/STM8L/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -144,7 +145,7 @@ typedef struct {
#if STM8L_SERIAL_USE_USART1 || defined(__DOXYGEN__)
/**
- * @brief USART1 RX interrupt handler segment.
+ * @brief USART1 RX interrupt handler segment.
*/
#define _USART1_RECEIVE_ISR() { \
uint8_t sr = USART1->SR; \
@@ -159,7 +160,7 @@ typedef struct {
}
/**
- * @brief USART1 TX interrupt handler segment.
+ * @brief USART1 TX interrupt handler segment.
*/
#define _USART1_TRANSMIT_ISR() { \
if (USART1->SR & USART_SR_TXE) { \
@@ -177,7 +178,7 @@ typedef struct {
#if STM8L_SERIAL_USE_USART2 || defined(__DOXYGEN__)
/**
- * @brief USART2 RX interrupt handler segment.
+ * @brief USART2 RX interrupt handler segment.
*/
#define _USART2_RECEIVE_ISR() { \
uint8_t sr = USART2->SR; \
@@ -192,7 +193,7 @@ typedef struct {
}
/**
- * @brief USART2 TX interrupt handler segment.
+ * @brief USART2 TX interrupt handler segment.
*/
#define _USART2_TRANSMIT_ISR() { \
if (USART2->SR & USART_SR_TXE) { \
@@ -210,7 +211,7 @@ typedef struct {
#if STM8L_SERIAL_USE_USART3 || defined(__DOXYGEN__)
/**
- * @brief USART3 RX interrupt handler segment.
+ * @brief USART3 RX interrupt handler segment.
*/
#define _USART3_RECEIVE_ISR() { \
uint8_t sr = USART3->SR; \
@@ -225,7 +226,7 @@ typedef struct {
}
/**
- * @brief USART3 TX interrupt handler segment.
+ * @brief USART3 TX interrupt handler segment.
*/
#define _USART3_TRANSMIT_ISR() { \
if (USART3->SR & USART_SR_TXE) { \
diff --git a/os/hal/platforms/STM8L/shared_isr.c b/os/hal/platforms/STM8L/shared_isr.c
index e89e1f78c..2bbb1a70b 100644
--- a/os/hal/platforms/STM8L/shared_isr.c
+++ b/os/hal/platforms/STM8L/shared_isr.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8S/hal_lld.c b/os/hal/platforms/STM8S/hal_lld.c
index de32cfb44..75772a3af 100644
--- a/os/hal/platforms/STM8S/hal_lld.c
+++ b/os/hal/platforms/STM8S/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8S/hal_lld.h b/os/hal/platforms/STM8S/hal_lld.h
index 1db8a742c..a57da439a 100644
--- a/os/hal/platforms/STM8S/hal_lld.h
+++ b/os/hal/platforms/STM8S/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -202,7 +203,7 @@
/**
* @brief CPU clock.
* @details On the STM8SS the CPU clock can be programmed to be a fraction of
- * the system clock.
+ * the system clock.
*/
#define CPUCLK (SYSCLK / (1 << STM8S_CPU_DIVIDER))
diff --git a/os/hal/platforms/STM8S/pal_lld.c b/os/hal/platforms/STM8S/pal_lld.c
index feb9c33cf..0a9b26657 100644
--- a/os/hal/platforms/STM8S/pal_lld.c
+++ b/os/hal/platforms/STM8S/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8S/pal_lld.h b/os/hal/platforms/STM8S/pal_lld.h
index 65f4584de..ef69d1379 100644
--- a/os/hal/platforms/STM8S/pal_lld.h
+++ b/os/hal/platforms/STM8S/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -159,7 +160,7 @@ typedef GPIO_TypeDef *ioportid_t;
*
* @notapi
*/
-#define pal_lld_init(config) *IOPORTS = *(config)
+#define pal_lld_init(config) (*IOPORTS = *(config))
/**
* @brief Reads the physical I/O port states.
@@ -199,7 +200,6 @@ typedef GPIO_TypeDef *ioportid_t;
*/
#define pal_lld_writeport(port, bits) ((port)->ODR = (bits))
-
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
@@ -215,7 +215,7 @@ typedef GPIO_TypeDef *ioportid_t;
* @notapi
*/
#define pal_lld_setgroupmode(port, mask, mode) \
- _pal_lld_setgroupmode(port, mask, mode)
+ _pal_lld_setgroupmode(port, mask, mode)
extern ROMCONST PALConfig pal_default_config;
diff --git a/os/hal/platforms/STM8S/platform.dox b/os/hal/platforms/STM8S/platform.dox
index d05bb4af6..8ff654170 100644
--- a/os/hal/platforms/STM8S/platform.dox
+++ b/os/hal/platforms/STM8S/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -40,7 +41,7 @@
*/
/**
- * @defgroup STM8S_PAL STM8S GPIO Support
+ * @defgroup STM8S_PAL STM8S PAL Support
* @details The STM8S PAL driver uses the GPIO peripherals.
*
* @section stm8s_pal_1 Supported HW resources
@@ -83,26 +84,7 @@
*/
/**
- * @defgroup STM8S_SPI STM8S SPI Support
- * @details The SPI driver supports the STM8S SPI peripheral in an interrupt
- * driven implementation.
- * @note Being the SPI a fast peripheral, much care must be taken to
- * not saturate the CPU bandwidth with an excessive IRQ rate. The
- * maximum transfer bit rate is likely limited by the IRQ
- * handling.
- *
- * @section stm8s_spi_1 Supported HW resources
- * - SPI.
- * .
- * @section stm8s_spi_2 STM8S SPI driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Fully interrupt driven.
- * .
- * @ingroup STM8S
- */
-
-/**
- * @defgroup STM8S_SERIAL STM8S UART Support (buffered)
+ * @defgroup STM8S_SERIAL STM8S Serial Support
* @details The STM8S Serial driver uses the UART peripherals in a
* buffered, interrupt driven, implementation.
*
@@ -120,3 +102,22 @@
* .
* @ingroup STM8S
*/
+
+/**
+ * @defgroup STM8S_SPI STM8S SPI Support
+ * @details The SPI driver supports the STM8S SPI peripheral in an interrupt
+ * driven implementation.
+ * @note Being the SPI a fast peripheral, much care must be taken to
+ * not saturate the CPU bandwidth with an excessive IRQ rate. The
+ * maximum transfer bit rate is likely limited by the IRQ
+ * handling.
+ *
+ * @section stm8s_spi_1 Supported HW resources
+ * - SPI.
+ * .
+ * @section stm8s_spi_2 STM8S SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Fully interrupt driven.
+ * .
+ * @ingroup STM8S
+ */
diff --git a/os/hal/platforms/STM8S/serial_lld.c b/os/hal/platforms/STM8S/serial_lld.c
index d5bdb96f0..50a389ab4 100644
--- a/os/hal/platforms/STM8S/serial_lld.c
+++ b/os/hal/platforms/STM8S/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -266,7 +267,7 @@ CH_IRQ_HANDLER(18) {
/**
* @brief IRQ 20 service routine.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(20) {
msg_t b;
diff --git a/os/hal/platforms/STM8S/serial_lld.h b/os/hal/platforms/STM8S/serial_lld.h
index 96ac08896..fa8777bd5 100644
--- a/os/hal/platforms/STM8S/serial_lld.h
+++ b/os/hal/platforms/STM8S/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8S/spi_lld.c b/os/hal/platforms/STM8S/spi_lld.c
index c950f0bd4..57e459d80 100644
--- a/os/hal/platforms/STM8S/spi_lld.c
+++ b/os/hal/platforms/STM8S/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -70,12 +71,12 @@ CH_IRQ_HANDLER(10) {
handle the case where a frame arrives immediately after reading the
DR register.*/
while ((SPI->SR & SPI_SR_RXNE) != 0) {
- if (SPID1.spd_rxptr != NULL)
- *SPID1.spd_rxptr++ = SPI->DR;
+ if (SPID1.rxptr != NULL)
+ *SPID1.rxptr++ = SPI->DR;
else
(void)SPI->DR;
- if (--SPID1.spd_rxcnt == 0) {
- chDbgAssert(SPID1.spd_txcnt == 0,
+ if (--SPID1.rxcnt == 0) {
+ chDbgAssert(SPID1.txcnt == 0,
"IRQ10, #1", "counter out of synch");
/* Stops all the IRQ sources.*/
SPI->ICR = 0;
@@ -89,8 +90,8 @@ CH_IRQ_HANDLER(10) {
}
/* Loading the DR register.*/
if ((SPI->SR & SPI_SR_TXE) != 0) {
- if (SPID1.spd_txptr != NULL)
- SPI->DR = *SPID1.spd_txptr++;
+ if (SPID1.txptr != NULL)
+ SPI->DR = *SPID1.txptr++;
else
SPI->DR = 0xFF;
}
@@ -129,8 +130,10 @@ void spi_lld_start(SPIDriver *spip) {
CLK->PCKENR1 |= CLK_PCKENR1_SPI; /* PCKEN11, clock source. */
/* Configuration.*/
- SPI->CR2 = 0;
- SPI->CR1 = spip->spd_config->spc_cr1 | SPI_CR1_MSTR | SPI_CR1_SPE;
+ SPI->CR1 = 0;
+ SPI->CR1 = spip->config->cr1 | SPI_CR1_MSTR;
+ SPI->CR2 = SPI_CR2_SSI | SPI_CR2_SSM;
+ SPI->CR1 |= SPI_CR1_SPE;
}
/**
@@ -162,7 +165,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -175,7 +178,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -191,9 +194,9 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
SPI->ICR = SPI_ICR_TXEI | SPI_ICR_RXEI | SPI_ICR_ERRIE;
}
@@ -215,9 +218,9 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
SPI->ICR = SPI_ICR_TXEI | SPI_ICR_RXEI | SPI_ICR_ERRIE;
}
@@ -236,9 +239,9 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
SPI->ICR = SPI_ICR_TXEI | SPI_ICR_RXEI | SPI_ICR_ERRIE;
}
@@ -257,9 +260,9 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
SPI->ICR = SPI_ICR_TXEI | SPI_ICR_RXEI | SPI_ICR_ERRIE;
}
diff --git a/os/hal/platforms/STM8S/spi_lld.h b/os/hal/platforms/STM8S/spi_lld.h
index 1f665d01a..48af021b0 100644
--- a/os/hal/platforms/STM8S/spi_lld.h
+++ b/os/hal/platforms/STM8S/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -87,20 +88,20 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SPI initialization data.
*/
- uint8_t spc_cr1;
+ uint8_t cr1;
} SPIConfig;
/**
@@ -110,25 +111,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -136,21 +137,21 @@ struct SPIDriver {
#endif
/* End of the mandatory fields.*/
/**
- * @brief Number of bytes yet to be received.
+ * @brief Number of bytes yet to be received.
*/
- uint16_t spd_rxcnt;
+ uint16_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
- uint8_t *spd_rxptr;
+ uint8_t *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
- uint16_t spd_txcnt;
+ uint16_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
- const uint8_t *spd_txptr;
+ const uint8_t *txptr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/Win32/console.c b/os/hal/platforms/Win32/console.c
index 737cf92bf..4f29b7900 100644
--- a/os/hal/platforms/Win32/console.c
+++ b/os/hal/platforms/Win32/console.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/console.h b/os/hal/platforms/Win32/console.h
index 3a30e6295..b803a5de7 100644
--- a/os/hal/platforms/Win32/console.h
+++ b/os/hal/platforms/Win32/console.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/hal_lld.c b/os/hal/platforms/Win32/hal_lld.c
index a03d91998..24a11f51c 100644
--- a/os/hal/platforms/Win32/hal_lld.c
+++ b/os/hal/platforms/Win32/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/hal_lld.h b/os/hal/platforms/Win32/hal_lld.h
index 84696107b..fbeeaa61e 100644
--- a/os/hal/platforms/Win32/hal_lld.h
+++ b/os/hal/platforms/Win32/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/pal_lld.c b/os/hal/platforms/Win32/pal_lld.c
index 54ff76100..b2a83d77f 100644
--- a/os/hal/platforms/Win32/pal_lld.c
+++ b/os/hal/platforms/Win32/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/pal_lld.h b/os/hal/platforms/Win32/pal_lld.h
index b353f2a52..a1c84b13a 100644
--- a/os/hal/platforms/Win32/pal_lld.h
+++ b/os/hal/platforms/Win32/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -128,10 +129,9 @@ typedef sim_vio_port_t *ioportid_t;
*
* @param[in] config architecture-dependent ports configuration
*/
-#define pal_lld_init(config) { \
- vio_port_1 = (config)->VP1Data; \
- vio_port_2 = (config)->VP2Data; \
-}
+#define pal_lld_init(config) \
+ (vio_port_1 = (config)->VP1Data, \
+ vio_port_2 = (config)->VP2Data)
/**
* @brief Reads the physical I/O port states.
@@ -177,7 +177,7 @@ typedef sim_vio_port_t *ioportid_t;
* @param[in] mask group mask
* @param[in] mode group mode
*/
-#define pal_lld_setgroupmode(port, mask, mode) \
+#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
#if !defined(__DOXYGEN__)
diff --git a/os/hal/platforms/Win32/serial_lld.c b/os/hal/platforms/Win32/serial_lld.c
index bbfae160f..6b76ebbc7 100644
--- a/os/hal/platforms/Win32/serial_lld.c
+++ b/os/hal/platforms/Win32/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/serial_lld.h b/os/hal/platforms/Win32/serial_lld.h
index fd6bff34d..a853a507d 100644
--- a/os/hal/platforms/Win32/serial_lld.h
+++ b/os/hal/platforms/Win32/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/platforms.dox b/os/hal/platforms/platforms.dox
index aa25cbca4..fba310bed 100644
--- a/os/hal/platforms/platforms.dox
+++ b/os/hal/platforms/platforms.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c
index 25cbfe750..4843ca90b 100644
--- a/os/hal/src/adc.c
+++ b/os/hal/src/adc.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,19 +68,19 @@ void adcInit(void) {
*/
void adcObjectInit(ADCDriver *adcp) {
- adcp->ad_state = ADC_STOP;
- adcp->ad_config = NULL;
- adcp->ad_samples = NULL;
- adcp->ad_depth = 0;
- adcp->ad_grpp = NULL;
+ adcp->state = ADC_STOP;
+ adcp->config = NULL;
+ adcp->samples = NULL;
+ adcp->depth = 0;
+ adcp->grpp = NULL;
#if ADC_USE_WAIT
- adcp->ad_thread = NULL;
+ adcp->thread = NULL;
#endif /* ADC_USE_WAIT */
#if ADC_USE_MUTUAL_EXCLUSION
#if CH_USE_MUTEXES
- chMtxInit(&adcp->ad_mutex);
+ chMtxInit(&adcp->mutex);
#else
- chSemInit(&adcp->ad_semaphore, 1);
+ chSemInit(&adcp->semaphore, 1);
#endif
#endif /* ADC_USE_MUTUAL_EXCLUSION */
#if defined(ADC_DRIVER_EXT_INIT_HOOK)
@@ -101,11 +102,11 @@ void adcStart(ADCDriver *adcp, const ADCConfig *config) {
chDbgCheck(adcp != NULL, "adcStart");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY),
+ chDbgAssert((adcp->state == ADC_STOP) || (adcp->state == ADC_READY),
"adcStart(), #1", "invalid state");
- adcp->ad_config = config;
+ adcp->config = config;
adc_lld_start(adcp);
- adcp->ad_state = ADC_READY;
+ adcp->state = ADC_READY;
chSysUnlock();
}
@@ -121,10 +122,10 @@ void adcStop(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStop");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY),
+ chDbgAssert((adcp->state == ADC_STOP) || (adcp->state == ADC_READY),
"adcStop(), #1", "invalid state");
adc_lld_stop(adcp);
- adcp->ad_state = ADC_STOP;
+ adcp->state = ADC_STOP;
chSysUnlock();
}
@@ -179,13 +180,13 @@ void adcStartConversionI(ADCDriver *adcp,
((depth == 1) || ((depth & 1) == 0)),
"adcStartConversionI");
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_COMPLETE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_COMPLETE),
"adcStartConversionI(), #1", "not ready");
- adcp->ad_samples = samples;
- adcp->ad_depth = depth;
- adcp->ad_grpp = grpp;
- adcp->ad_state = ADC_ACTIVE;
+ adcp->samples = samples;
+ adcp->depth = depth;
+ adcp->grpp = grpp;
+ adcp->state = ADC_ACTIVE;
adc_lld_start_conversion(adcp);
}
@@ -204,13 +205,13 @@ void adcStopConversion(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStopConversion");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_ACTIVE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_ACTIVE),
"adcStopConversion(), #1", "invalid state");
- if (adcp->ad_state != ADC_READY) {
+ if (adcp->state != ADC_READY) {
adc_lld_stop_conversion(adcp);
- adcp->ad_grpp = NULL;
- adcp->ad_state = ADC_READY;
+ adcp->grpp = NULL;
+ adcp->state = ADC_READY;
_adc_reset_s(adcp);
}
chSysUnlock();
@@ -230,14 +231,14 @@ void adcStopConversionI(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStopConversionI");
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_ACTIVE) ||
- (adcp->ad_state == ADC_COMPLETE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_ACTIVE) ||
+ (adcp->state == ADC_COMPLETE),
"adcStopConversionI(), #1", "invalid state");
- if (adcp->ad_state != ADC_READY) {
+ if (adcp->state != ADC_READY) {
adc_lld_stop_conversion(adcp);
- adcp->ad_grpp = NULL;
- adcp->ad_state = ADC_READY;
+ adcp->grpp = NULL;
+ adcp->state = ADC_READY;
_adc_reset_i(adcp);
}
}
@@ -271,9 +272,9 @@ msg_t adcConvert(ADCDriver *adcp,
msg_t msg;
chSysLock();
- chDbgAssert(grpp->acg_endcb == NULL, "adcConvert(), #1", "has callback");
+ chDbgAssert(adcp->thread == NULL, "adcConvert(), #1", "already waiting");
adcStartConversionI(adcp, grpp, samples, depth);
- (adcp)->ad_thread = chThdSelf();
+ (adcp)->thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
msg = chThdSelf()->p_u.rdymsg;
chSysUnlock();
@@ -286,8 +287,8 @@ msg_t adcConvert(ADCDriver *adcp,
* @brief Gains exclusive access to the ADC peripheral.
* @details This function tries to gain ownership to the ADC bus, if the bus
* is already being used then the invoking thread is queued.
- * @pre In order to use this function the option @p ADC_USE_MUTUAL_EXCLUSION
- * must be enabled.
+ * @pre In order to use this function the option
+ * @p ADC_USE_MUTUAL_EXCLUSION must be enabled.
*
* @param[in] adcp pointer to the @p ADCDriver object
*
@@ -298,16 +299,16 @@ void adcAcquireBus(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcAcquireBus");
#if CH_USE_MUTEXES
- chMtxLock(&adcp->ad_mutex);
+ chMtxLock(&adcp->mutex);
#elif CH_USE_SEMAPHORES
- chSemWait(&adcp->ad_semaphore);
+ chSemWait(&adcp->semaphore);
#endif
}
/**
* @brief Releases exclusive access to the ADC peripheral.
- * @pre In order to use this function the option @p ADC_USE_MUTUAL_EXCLUSION
- * must be enabled.
+ * @pre In order to use this function the option
+ * @p ADC_USE_MUTUAL_EXCLUSION must be enabled.
*
* @param[in] adcp pointer to the @p ADCDriver object
*
@@ -321,7 +322,7 @@ void adcReleaseBus(ADCDriver *adcp) {
(void)adcp;
chMtxUnlock();
#elif CH_USE_SEMAPHORES
- chSemSignal(&adcp->ad_semaphore);
+ chSemSignal(&adcp->semaphore);
#endif
}
#endif /* ADC_USE_MUTUAL_EXCLUSION */
diff --git a/os/hal/src/can.c b/os/hal/src/can.c
index d63cbfd8a..f9a827c4e 100644
--- a/os/hal/src/can.c
+++ b/os/hal/src/can.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,17 +68,17 @@ void canInit(void) {
*/
void canObjectInit(CANDriver *canp) {
- canp->cd_state = CAN_STOP;
- canp->cd_config = NULL;
- chSemInit(&canp->cd_txsem, 0);
- chSemInit(&canp->cd_rxsem, 0);
- chEvtInit(&canp->cd_rxfull_event);
- chEvtInit(&canp->cd_txempty_event);
- chEvtInit(&canp->cd_error_event);
- canp->cd_status = 0;
+ canp->state = CAN_STOP;
+ canp->config = NULL;
+ chSemInit(&canp->txsem, 0);
+ chSemInit(&canp->rxsem, 0);
+ chEvtInit(&canp->rxfull_event);
+ chEvtInit(&canp->txempty_event);
+ chEvtInit(&canp->error_event);
+ canp->status = 0;
#if CAN_USE_SLEEP_MODE
- chEvtInit(&canp->cd_sleep_event);
- chEvtInit(&canp->cd_wakeup_event);
+ chEvtInit(&canp->sleep_event);
+ chEvtInit(&canp->wakeup_event);
#endif /* CAN_USE_SLEEP_MODE */
}
@@ -98,16 +99,16 @@ void canStart(CANDriver *canp, const CANConfig *config) {
chDbgCheck(canp != NULL, "canStart");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_STOP) ||
- (canp->cd_state == CAN_STARTING) ||
- (canp->cd_state == CAN_READY),
+ chDbgAssert((canp->state == CAN_STOP) ||
+ (canp->state == CAN_STARTING) ||
+ (canp->state == CAN_READY),
"canStart(), #1", "invalid state");
- while (canp->cd_state == CAN_STARTING)
+ while (canp->state == CAN_STARTING)
chThdSleepS(1);
- if (canp->cd_state == CAN_STOP) {
- canp->cd_config = config;
+ if (canp->state == CAN_STOP) {
+ canp->config = config;
can_lld_start(canp);
- canp->cd_state = CAN_READY;
+ canp->state = CAN_READY;
}
chSysUnlock();
}
@@ -124,14 +125,14 @@ void canStop(CANDriver *canp) {
chDbgCheck(canp != NULL, "canStop");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_STOP) || (canp->cd_state == CAN_READY),
+ chDbgAssert((canp->state == CAN_STOP) || (canp->state == CAN_READY),
"canStop(), #1", "invalid state");
can_lld_stop(canp);
- chSemResetI(&canp->cd_rxsem, 0);
- chSemResetI(&canp->cd_txsem, 0);
+ chSemResetI(&canp->rxsem, 0);
+ chSemResetI(&canp->txsem, 0);
chSchRescheduleS();
- canp->cd_state = CAN_STOP;
- canp->cd_status = 0;
+ canp->state = CAN_STOP;
+ canp->status = 0;
chSysUnlock();
}
@@ -142,7 +143,7 @@ void canStop(CANDriver *canp) {
* @note Trying to transmit while in sleep mode simply enqueues the thread.
*
* @param[in] canp pointer to the @p CANDriver object
- * @param[in] ctfp pointer to the CAN frame to be transmitted
+ * @param[in] ctfp pointer to the CAN frame to be transmitted
* @param[in] timeout the number of ticks before the operation timeouts,
* the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout.
@@ -160,10 +161,10 @@ msg_t canTransmit(CANDriver *canp, const CANTxFrame *ctfp, systime_t timeout) {
chDbgCheck((canp != NULL) && (ctfp != NULL), "canTransmit");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canTransmit(), #1", "invalid state");
- while ((canp->cd_state == CAN_SLEEP) || !can_lld_can_transmit(canp)) {
- msg_t msg = chSemWaitTimeoutS(&canp->cd_txsem, timeout);
+ while ((canp->state == CAN_SLEEP) || !can_lld_can_transmit(canp)) {
+ msg_t msg = chSemWaitTimeoutS(&canp->txsem, timeout);
if (msg != RDY_OK) {
chSysUnlock();
return msg;
@@ -200,10 +201,10 @@ msg_t canReceive(CANDriver *canp, CANRxFrame *crfp, systime_t timeout) {
chDbgCheck((canp != NULL) && (crfp != NULL), "canReceive");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canReceive(), #1", "invalid state");
- while ((canp->cd_state == CAN_SLEEP) || !can_lld_can_receive(canp)) {
- msg_t msg = chSemWaitTimeoutS(&canp->cd_rxsem, timeout);
+ while ((canp->state == CAN_SLEEP) || !can_lld_can_receive(canp)) {
+ msg_t msg = chSemWaitTimeoutS(&canp->rxsem, timeout);
if (msg != RDY_OK) {
chSysUnlock();
return msg;
@@ -226,8 +227,8 @@ canstatus_t canGetAndClearFlags(CANDriver *canp) {
canstatus_t status;
chSysLock();
- status = canp->cd_status;
- canp->cd_status = 0;
+ status = canp->status;
+ canp->status = 0;
chSysUnlock();
return status;
}
@@ -236,7 +237,7 @@ canstatus_t canGetAndClearFlags(CANDriver *canp) {
/**
* @brief Enters the sleep mode.
* @details This function puts the CAN driver in sleep mode and broadcasts
- * the @p cd_sleep_event event source.
+ * the @p sleep_event event source.
* @pre In order to use this function the option @p CAN_USE_SLEEP_MODE must
* be enabled and the @p CAN_SUPPORTS_SLEEP mode must be supported
* by the low level driver.
@@ -250,12 +251,12 @@ void canSleep(CANDriver *canp) {
chDbgCheck(canp != NULL, "canSleep");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canSleep(), #1", "invalid state");
- if (canp->cd_state == CAN_READY) {
+ if (canp->state == CAN_READY) {
can_lld_sleep(canp);
- canp->cd_state = CAN_SLEEP;
- chEvtBroadcastI(&canp->cd_sleep_event);
+ canp->state = CAN_SLEEP;
+ chEvtBroadcastI(&canp->sleep_event);
chSchRescheduleS();
}
chSysUnlock();
@@ -273,12 +274,12 @@ void canWakeup(CANDriver *canp) {
chDbgCheck(canp != NULL, "canWakeup");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canWakeup(), #1", "invalid state");
- if (canp->cd_state == CAN_SLEEP) {
+ if (canp->state == CAN_SLEEP) {
can_lld_wakeup(canp);
- canp->cd_state = CAN_READY;
- chEvtBroadcastI(&canp->cd_wakeup_event);
+ canp->state = CAN_READY;
+ chEvtBroadcastI(&canp->wakeup_event);
chSchRescheduleS();
}
chSysUnlock();
diff --git a/os/hal/src/gpt.c b/os/hal/src/gpt.c
new file mode 100644
index 000000000..e90a8911a
--- /dev/null
+++ b/os/hal/src/gpt.c
@@ -0,0 +1,229 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file gpt.c
+ * @brief GPT Driver code.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void gptInit(void) {
+
+ gpt_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p GPTDriver structure.
+ *
+ * @param[out] gptp pointer to the @p GPTDriver object
+ *
+ * @init
+ */
+void gptObjectInit(GPTDriver *gptp) {
+
+ gptp->state = GPT_STOP;
+ gptp->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] config pointer to the @p GPTConfig object
+ *
+ * @api
+ */
+void gptStart(GPTDriver *gptp, const GPTConfig *config) {
+
+ chDbgCheck((gptp != NULL) && (config != NULL), "ptStart");
+
+ chSysLock();
+ chDbgAssert((gptp->state == GPT_STOP) || (gptp->state == GPT_READY),
+ "gptStart(), #1", "invalid state");
+ gptp->config = config;
+ gpt_lld_start(gptp);
+ gptp->state = GPT_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStop(GPTDriver *gptp) {
+
+ chDbgCheck(gptp != NULL, "gptStop");
+
+ chSysLock();
+ chDbgAssert((gptp->state == GPT_STOP) || (gptp->state == GPT_READY),
+ "gptStop(), #1", "invalid state");
+ gpt_lld_stop(gptp);
+ gptp->state = GPT_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @api
+ */
+void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval) {
+
+ chSysLock();
+ gptStartContinuousI(gptp, interval);
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @iclass
+ */
+void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptStartContinuousI(), #1", "invalid state");
+ gptp->state = GPT_CONTINUOUS;
+ gpt_lld_start_timer(gptp, interval);
+}
+
+/**
+ * @brief Starts the timer in one shot mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval) {
+
+ chSysLock();
+ gptStartOneShotI(gptp, interval);
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in one shot mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptStartOneShotI(), #1", "invalid state");
+ gptp->state = GPT_ONESHOT;
+ gpt_lld_start_timer(gptp, interval);
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStopTimer(GPTDriver *gptp) {
+
+ chSysLock();
+ gptStopTimerI(gptp);
+ chSysUnlock();
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStopTimerI(GPTDriver *gptp) {
+
+ chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) ||
+ (gptp->state == GPT_ONESHOT),
+ "gptStopTimerI(), #1", "invalid state");
+ gptp->state = GPT_READY;
+ gpt_lld_stop_timer(gptp);
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ * @note The configured callback is not invoked when using this function.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptPolledDelay(), #1", "invalid state");
+ gptp->state = GPT_ONESHOT;
+ gpt_lld_polled_delay(gptp, interval);
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/src/hal.c b/os/hal/src/hal.c
index bfbaa3e84..1a15988f5 100644
--- a/os/hal/src/hal.c
+++ b/os/hal/src/hal.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,9 +67,15 @@ void halInit(void) {
#if HAL_USE_CAN || defined(__DOXYGEN__)
canInit();
#endif
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+ gptInit();
+#endif
#if HAL_USE_I2C || defined(__DOXYGEN__)
i2cInit();
#endif
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+ icuInit();
+#endif
#if HAL_USE_MAC || defined(__DOXYGEN__)
macInit();
#endif
@@ -78,6 +85,9 @@ void halInit(void) {
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
sdInit();
#endif
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+ sdcInit();
+#endif
#if HAL_USE_SPI || defined(__DOXYGEN__)
spiInit();
#endif
diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c
index 84dfcf958..6f99a1afb 100644
--- a/os/hal/src/i2c.c
+++ b/os/hal/src/i2c.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/src/icu.c b/os/hal/src/icu.c
new file mode 100644
index 000000000..3be67448e
--- /dev/null
+++ b/os/hal/src/icu.c
@@ -0,0 +1,151 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file icu.c
+ * @brief ICU Driver code.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief ICU Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void icuInit(void) {
+
+ icu_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p ICUDriver structure.
+ *
+ * @param[out] icup pointer to the @p ICUDriver object
+ *
+ * @init
+ */
+void icuObjectInit(ICUDriver *icup) {
+
+ icup->state = ICU_STOP;
+ icup->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @param[in] config pointer to the @p ICUConfig object
+ *
+ * @api
+ */
+void icuStart(ICUDriver *icup, const ICUConfig *config) {
+
+ chDbgCheck((icup != NULL) && (config != NULL), "icuStart");
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY),
+ "icuStart(), #1", "invalid state");
+ icup->config = config;
+ icu_lld_start(icup);
+ icup->state = ICU_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuStop(ICUDriver *icup) {
+
+ chDbgCheck(icup != NULL, "icuStop");
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY),
+ "icuStop(), #1", "invalid state");
+ icu_lld_stop(icup);
+ icup->state = ICU_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuEnable(ICUDriver *icup) {
+
+ chSysLock();
+ chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state");
+ icu_lld_enable(icup);
+ icup->state = ICU_WAITING;
+ chSysUnlock();
+}
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuDisable(ICUDriver *icup) {
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) ||
+ (icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE),
+ "icuDisable(), #1", "invalid state");
+ icu_lld_disable(icup);
+ icup->state = ICU_READY;
+ chSysUnlock();
+}
+
+#endif /* HAL_USE_ICU */
+
+/** @} */
diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c
index 48656a8a3..4d6a9b2cd 100644
--- a/os/hal/src/mac.c
+++ b/os/hal/src/mac.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -71,10 +72,10 @@ void macInit(void) {
*/
void macObjectInit(MACDriver *macp) {
- chSemInit(&macp->md_tdsem, 0);
- chSemInit(&macp->md_rdsem, 0);
+ chSemInit(&macp->tdsem, 0);
+ chSemInit(&macp->rdsem, 0);
#if CH_USE_EVENTS
- chEvtInit(&macp->md_rdevent);
+ chEvtInit(&macp->rdevent);
#endif
}
@@ -123,8 +124,10 @@ msg_t macWaitTransmitDescriptor(MACDriver *macp,
(time > 0)) {
chSysLock();
systime_t now = chTimeNow();
- if ((msg = chSemWaitTimeoutS(&macp->md_tdsem, time)) == RDY_TIMEOUT)
+ if ((msg = chSemWaitTimeoutS(&macp->tdsem, time)) == RDY_TIMEOUT) {
+ chSysUnlock();
break;
+ }
if (time != TIME_INFINITE)
time -= (chTimeNow() - now);
chSysUnlock();
@@ -173,8 +176,10 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp,
(time > 0)) {
chSysLock();
systime_t now = chTimeNow();
- if ((msg = chSemWaitTimeoutS(&macp->md_rdsem, time)) == RDY_TIMEOUT)
+ if ((msg = chSemWaitTimeoutS(&macp->rdsem, time)) == RDY_TIMEOUT) {
+ chSysUnlock();
break;
+ }
if (time != TIME_INFINITE)
time -= (chTimeNow() - now);
chSysUnlock();
diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c
index 1b2d930c5..e6dcf9287 100644
--- a/os/hal/src/mmc_spi.c
+++ b/os/hal/src/mmc_spi.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,7 +19,7 @@
*/
/**
- * @file mmc_spi.c
+ * @file spi.c
* @brief MMC over SPI driver code.
*
* @addtogroup MMC_SPI
@@ -52,24 +53,24 @@
static void tmrfunc(void *p) {
MMCDriver *mmcp = p;
- if (mmcp->mmc_cnt > 0) {
- if (mmcp->mmc_is_inserted()) {
- if (--mmcp->mmc_cnt == 0) {
- mmcp->mmc_state = MMC_INSERTED;
- chEvtBroadcastI(&mmcp->mmc_inserted_event);
+ if (mmcp->cnt > 0) {
+ if (mmcp->is_inserted()) {
+ if (--mmcp->cnt == 0) {
+ mmcp->state = MMC_INSERTED;
+ chEvtBroadcastI(&mmcp->inserted_event);
}
}
else
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
}
else {
- if (!mmcp->mmc_is_inserted()) {
- mmcp->mmc_state = MMC_WAIT;
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
- chEvtBroadcastI(&mmcp->mmc_removed_event);
+ if (!mmcp->is_inserted()) {
+ mmcp->state = MMC_WAIT;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
+ chEvtBroadcastI(&mmcp->removed_event);
}
}
- chVTSetI(&mmcp->mmc_vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
+ chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
}
/**
@@ -84,13 +85,13 @@ static void wait(MMCDriver *mmcp) {
uint8_t buf[4];
for (i = 0; i < 16; i++) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
}
/* Looks like it is a long wait.*/
while (TRUE) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
#ifdef MMC_NICE_WAITING
@@ -121,7 +122,7 @@ static void send_hdr(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
buf[3] = arg >> 8;
buf[4] = arg;
buf[5] = 0x95; /* Valid for CMD0 ignored by other commands. */
- spiSend(mmcp->mmc_spip, 6, buf);
+ spiSend(mmcp->spip, 6, buf);
}
/**
@@ -138,7 +139,7 @@ static uint8_t recvr1(MMCDriver *mmcp) {
uint8_t r1[1];
for (i = 0; i < 9; i++) {
- spiReceive(mmcp->mmc_spip, 1, r1);
+ spiReceive(mmcp->spip, 1, r1);
if (r1[0] != 0xFF)
return r1[0];
}
@@ -159,10 +160,10 @@ static uint8_t recvr1(MMCDriver *mmcp) {
static uint8_t send_command(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
uint8_t r1;
- spiSelect(mmcp->mmc_spip);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, cmd, arg);
r1 = recvr1(mmcp);
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
return r1;
}
@@ -176,16 +177,16 @@ static uint8_t send_command(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
static void sync(MMCDriver *mmcp) {
uint8_t buf[1];
- spiSelect(mmcp->mmc_spip);
+ spiSelect(mmcp->spip);
while (TRUE) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
#ifdef MMC_NICE_WAITING
chThdSleep(1); /* Trying to be nice with the other threads.*/
#endif
}
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
}
/*===========================================================================*/
@@ -221,15 +222,15 @@ void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip,
const SPIConfig *lscfg, const SPIConfig *hscfg,
mmcquery_t is_protected, mmcquery_t is_inserted) {
- mmcp->mmc_state = MMC_STOP;
- mmcp->mmc_config = NULL;
- mmcp->mmc_spip = spip;
- mmcp->mmc_lscfg = lscfg;
- mmcp->mmc_hscfg = hscfg;
- mmcp->mmc_is_protected = is_protected;
- mmcp->mmc_is_inserted = is_inserted;
- chEvtInit(&mmcp->mmc_inserted_event);
- chEvtInit(&mmcp->mmc_removed_event);
+ mmcp->state = MMC_STOP;
+ mmcp->config = NULL;
+ mmcp->spip = spip;
+ mmcp->lscfg = lscfg;
+ mmcp->hscfg = hscfg;
+ mmcp->is_protected = is_protected;
+ mmcp->is_inserted = is_inserted;
+ chEvtInit(&mmcp->inserted_event);
+ chEvtInit(&mmcp->removed_event);
}
/**
@@ -245,11 +246,11 @@ void mmcStart(MMCDriver *mmcp, const MMCConfig *config) {
chDbgCheck((mmcp != NULL) && (config == NULL), "mmcStart");
chSysLock();
- chDbgAssert(mmcp->mmc_state == MMC_STOP, "mmcStart(), #1", "invalid state");
- mmcp->mmc_config = config;
- mmcp->mmc_state = MMC_WAIT;
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
- chVTSetI(&mmcp->mmc_vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
+ chDbgAssert(mmcp->state == MMC_STOP, "mmcStart(), #1", "invalid state");
+ mmcp->config = config;
+ mmcp->state = MMC_WAIT;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
+ chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
chSysUnlock();
}
@@ -265,17 +266,16 @@ void mmcStop(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStop");
chSysLock();
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_READING) &&
- (mmcp->mmc_state != MMC_WRITING),
- "mmcStop(), #1",
- "invalid state");
- if (mmcp->mmc_state != MMC_STOP) {
- mmcp->mmc_state = MMC_STOP;
- chVTResetI(&mmcp->mmc_vt);
+ chDbgAssert((mmcp->state != MMC_UNINIT) &&
+ (mmcp->state != MMC_READING) &&
+ (mmcp->state != MMC_WRITING),
+ "mmcStop(), #1", "invalid state");
+ if (mmcp->state != MMC_STOP) {
+ mmcp->state = MMC_STOP;
+ chVTResetI(&mmcp->vt);
}
chSysUnlock();
- spiStop(mmcp->mmc_spip);
+ spiStop(mmcp->spip);
}
/**
@@ -300,15 +300,13 @@ bool_t mmcConnect(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcConnect");
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_STOP),
- "mmcConnect(), #1",
- "invalid state");
+ chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_STOP),
+ "mmcConnect(), #1", "invalid state");
- if (mmcp->mmc_state == MMC_INSERTED) {
+ if (mmcp->state == MMC_INSERTED) {
/* Slow clock mode and 128 clock pulses.*/
- spiStart(mmcp->mmc_spip, mmcp->mmc_lscfg);
- spiIgnore(mmcp->mmc_spip, 16);
+ spiStart(mmcp->spip, mmcp->lscfg);
+ spiIgnore(mmcp->spip, 16);
/* SPI mode selection.*/
i = 0;
@@ -334,7 +332,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
}
/* Initialization complete, full speed. */
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
+ spiStart(mmcp->spip, mmcp->hscfg);
/* Setting block size.*/
if (send_command(mmcp, MMC_CMDSETBLOCKLEN, MMC_SECTOR_SIZE) != 0x00)
@@ -342,8 +340,8 @@ bool_t mmcConnect(MMCDriver *mmcp) {
/* Transition to MMC_READY state (if not extracted).*/
chSysLock();
- if (mmcp->mmc_state == MMC_INSERTED) {
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_INSERTED) {
+ mmcp->state = MMC_READY;
result = FALSE;
}
else
@@ -351,7 +349,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
chSysUnlock();
return result;
}
- if (mmcp->mmc_state == MMC_READY)
+ if (mmcp->state == MMC_READY)
return FALSE;
/* Any other state is invalid.*/
return TRUE;
@@ -373,24 +371,22 @@ bool_t mmcDisconnect(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcDisconnect");
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_STOP),
- "mmcDisconnect(), #1",
- "invalid state");
- switch (mmcp->mmc_state) {
+ chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_STOP),
+ "mmcDisconnect(), #1", "invalid state");
+ switch (mmcp->state) {
case MMC_READY:
/* Wait for the pending write operations to complete.*/
sync(mmcp);
chSysLock();
- if (mmcp->mmc_state == MMC_READY)
- mmcp->mmc_state = MMC_INSERTED;
+ if (mmcp->state == MMC_READY)
+ mmcp->state = MMC_INSERTED;
chSysUnlock();
case MMC_INSERTED:
status = FALSE;
default:
status = TRUE;
}
- spiStop(mmcp->mmc_spip);
+ spiStop(mmcp->spip);
return status;
}
@@ -410,21 +406,21 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
chDbgCheck(mmcp != NULL, "mmcStartSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READY) {
+ if (mmcp->state != MMC_READY) {
chSysUnlock();
return TRUE;
}
- mmcp->mmc_state = MMC_READING;
+ mmcp->state = MMC_READING;
chSysUnlock();
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
- spiSelect(mmcp->mmc_spip);
+ spiStart(mmcp->spip, mmcp->hscfg);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, MMC_CMDREADMULTIPLE, startblk * MMC_SECTOR_SIZE);
if (recvr1(mmcp) != 0x00) {
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -448,26 +444,26 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READING) {
+ if (mmcp->state != MMC_READING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
for (i = 0; i < MMC_WAIT_DATA; i++) {
- spiReceive(mmcp->mmc_spip, 1, buffer);
+ spiReceive(mmcp->spip, 1, buffer);
if (buffer[0] == 0xFE) {
- spiReceive(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer);
+ spiReceive(mmcp->spip, MMC_SECTOR_SIZE, buffer);
/* CRC ignored. */
- spiIgnore(mmcp->mmc_spip, 2);
+ spiIgnore(mmcp->spip, 2);
return FALSE;
}
}
/* Timeout.*/
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -489,22 +485,22 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READING) {
+ if (mmcp->state != MMC_READING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(stopcmd), stopcmd);
+ spiSend(mmcp->spip, sizeof(stopcmd), stopcmd);
/* result = recvr1(mmcp) != 0x00;*/
/* Note, ignored r1 response, it can be not zero, unknown issue.*/
recvr1(mmcp);
result = FALSE;
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return result;
}
@@ -525,21 +521,21 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
chDbgCheck(mmcp != NULL, "mmcStartSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_READY) {
+ if (mmcp->state != MMC_READY) {
chSysUnlock();
return TRUE;
}
- mmcp->mmc_state = MMC_WRITING;
+ mmcp->state = MMC_WRITING;
chSysUnlock();
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
- spiSelect(mmcp->mmc_spip);
+ spiStart(mmcp->spip, mmcp->hscfg);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, MMC_CMDWRITEMULTIPLE, startblk * MMC_SECTOR_SIZE);
if (recvr1(mmcp) != 0x00) {
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -564,26 +560,26 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_WRITING) {
+ if (mmcp->state != MMC_WRITING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(start), start); /* Data prologue. */
- spiSend(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer); /* Data. */
- spiIgnore(mmcp->mmc_spip, 2); /* CRC ignored. */
- spiReceive(mmcp->mmc_spip, 1, b);
+ spiSend(mmcp->spip, sizeof(start), start); /* Data prologue. */
+ spiSend(mmcp->spip, MMC_SECTOR_SIZE, buffer); /* Data. */
+ spiIgnore(mmcp->spip, 2); /* CRC ignored. */
+ spiReceive(mmcp->spip, 1, b);
if ((b[0] & 0x1F) == 0x05) {
wait(mmcp);
return FALSE;
}
/* Error.*/
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -604,18 +600,18 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStopSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_WRITING) {
+ if (mmcp->state != MMC_WRITING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(stop), stop);
- spiUnselect(mmcp->mmc_spip);
+ spiSend(mmcp->spip, sizeof(stop), stop);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING) {
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING) {
+ mmcp->state = MMC_READY;
chSysUnlock();
return FALSE;
}
diff --git a/os/hal/src/pal.c b/os/hal/src/pal.c
index ce7c226e9..534935a55 100644
--- a/os/hal/src/pal.c
+++ b/os/hal/src/pal.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -64,9 +65,9 @@
ioportmask_t palReadBus(IOBus *bus) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palReadBus");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palReadBus");
- return palReadGroup(bus->bus_portid, bus->bus_mask, bus->bus_offset);
+ return palReadGroup(bus->portid, bus->mask, bus->offset);
}
/**
@@ -89,9 +90,9 @@ ioportmask_t palReadBus(IOBus *bus) {
void palWriteBus(IOBus *bus, ioportmask_t bits) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palWriteBus");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palWriteBus");
- palWriteGroup(bus->bus_portid, bus->bus_mask, bus->bus_offset, bits);
+ palWriteGroup(bus->portid, bus->mask, bus->offset, bits);
}
/**
@@ -112,9 +113,9 @@ void palWriteBus(IOBus *bus, ioportmask_t bits) {
void palSetBusMode(IOBus *bus, uint_fast8_t mode) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palSetBusMode");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palSetBusMode");
- palSetGroupMode(bus->bus_portid, bus->bus_mask, mode);
+ palSetGroupMode(bus->portid, bus->mask, mode);
}
#endif /* HAL_USE_PAL */
diff --git a/os/hal/src/pwm.c b/os/hal/src/pwm.c
index cf619e508..e7dd6b64c 100644
--- a/os/hal/src/pwm.c
+++ b/os/hal/src/pwm.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,8 +68,8 @@ void pwmInit(void) {
*/
void pwmObjectInit(PWMDriver *pwmp) {
- pwmp->pd_state = PWM_STOP;
- pwmp->pd_config = NULL;
+ pwmp->state = PWM_STOP;
+ pwmp->config = NULL;
#if defined(PWM_DRIVER_EXT_INIT_HOOK)
PWM_DRIVER_EXT_INIT_HOOK(pwmp);
#endif
@@ -76,6 +77,8 @@ void pwmObjectInit(PWMDriver *pwmp) {
/**
* @brief Configures and activates the PWM peripheral.
+ * @note Starting a driver that is already in the @p PWM_READY state
+ * disables all the active channels.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] config pointer to a @p PWMConfig object
@@ -87,11 +90,12 @@ void pwmStart(PWMDriver *pwmp, const PWMConfig *config) {
chDbgCheck((pwmp != NULL) && (config != NULL), "pwmStart");
chSysLock();
- chDbgAssert((pwmp->pd_state == PWM_STOP) || (pwmp->pd_state == PWM_READY),
+ chDbgAssert((pwmp->state == PWM_STOP) || (pwmp->state == PWM_READY),
"pwmStart(), #1", "invalid state");
- pwmp->pd_config = config;
+ pwmp->config = config;
+ pwmp->period = config->period;
pwm_lld_start(pwmp);
- pwmp->pd_state = PWM_READY;
+ pwmp->state = PWM_READY;
chSysUnlock();
}
@@ -107,16 +111,46 @@ void pwmStop(PWMDriver *pwmp) {
chDbgCheck(pwmp != NULL, "pwmStop");
chSysLock();
- chDbgAssert((pwmp->pd_state == PWM_STOP) || (pwmp->pd_state == PWM_READY),
+ chDbgAssert((pwmp->state == PWM_STOP) || (pwmp->state == PWM_READY),
"pwmStop(), #1", "invalid state");
pwm_lld_stop(pwmp);
- pwmp->pd_state = PWM_STOP;
+ pwmp->state = PWM_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] period new cycle time in ticks
+ *
+ * @api
+ */
+void pwmChangePeriod(PWMDriver *pwmp, pwmcnt_t period) {
+
+ chDbgCheck(pwmp != NULL, "pwmChangePeriod");
+
+ chSysLock();
+ chDbgAssert(pwmp->state == PWM_READY,
+ "pwmChangePeriod(), #1", "invalid state");
+ pwmChangePeriodI(pwmp, period);
chSysUnlock();
}
/**
* @brief Enables a PWM channel.
- * @details Programs (or reprograms) a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -132,7 +166,7 @@ void pwmEnableChannel(PWMDriver *pwmp,
"pwmEnableChannel");
chSysLock();
- chDbgAssert(pwmp->pd_state == PWM_READY,
+ chDbgAssert(pwmp->state == PWM_READY,
"pwmEnableChannel(), #1", "not ready");
pwm_lld_enable_channel(pwmp, channel, width);
chSysUnlock();
@@ -140,8 +174,12 @@ void pwmEnableChannel(PWMDriver *pwmp,
/**
* @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -154,7 +192,7 @@ void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel) {
"pwmEnableChannel");
chSysLock();
- chDbgAssert(pwmp->pd_state == PWM_READY,
+ chDbgAssert(pwmp->state == PWM_READY,
"pwmDisableChannel(), #1", "not ready");
pwm_lld_disable_channel(pwmp, channel);
chSysUnlock();
diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c
new file mode 100644
index 000000000..283a0ee75
--- /dev/null
+++ b/os/hal/src/sdc.c
@@ -0,0 +1,392 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file sdc.c
+ * @brief SDC Driver code.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Wait for the card to complete pending operations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE the card is now in transfer state.
+ * @retval TRUE an error occurred while waiting or the card is in an
+ * unexpected state.
+ *
+ * @notapi
+ */
+bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp) {
+ uint32_t resp[1];
+
+ while (TRUE) {
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_STATUS,
+ sdcp->rca, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ return TRUE;
+ switch (SDC_R1_STS(resp[0])) {
+ case SDC_STS_TRAN:
+ return FALSE;
+ case SDC_STS_DATA:
+ case SDC_STS_RCV:
+ case SDC_STS_PRG:
+#if SDC_NICE_WAITING
+ chThdSleepMilliseconds(1);
+#endif
+ continue;
+ default:
+ /* The card should have been initialized so any other state is not
+ valid and is reported as an error.*/
+ return TRUE;
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief SDC Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void sdcInit(void) {
+
+ sdc_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p SDCDriver structure.
+ *
+ * @param[out] sdcp pointer to the @p SDCDriver object
+ *
+ * @init
+ */
+void sdcObjectInit(SDCDriver *sdcp) {
+
+ sdcp->state = SDC_STOP;
+ sdcp->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] config pointer to the @p SDCConfig object, can be @p NULL if
+ * the driver supports a default configuration or
+ * requires no configuration
+ *
+ * @api
+ */
+void sdcStart(SDCDriver *sdcp, const SDCConfig *config) {
+
+ chDbgCheck(sdcp != NULL, "sdcStart");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY),
+ "sdcStart(), #1", "invalid state");
+ sdcp->config = config;
+ sdc_lld_start(sdcp);
+ sdcp->state = SDC_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @api
+ */
+void sdcStop(SDCDriver *sdcp) {
+
+ chDbgCheck(sdcp != NULL, "sdcStop");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY),
+ "sdcStop(), #1", "invalid state");
+ sdc_lld_stop(sdcp);
+ sdcp->state = SDC_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Performs the initialization procedure on the inserted card.
+ * @details This function should be invoked when a card is inserted and
+ * brings the driver in the @p SDC_ACTIVE state where it is possible
+ * to perform read and write operations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the driver is now
+ * in the @p SDC_ACTIVE state.
+ * @retval TRUE operation failed.
+ *
+ * @api
+ */
+bool_t sdcConnect(SDCDriver *sdcp) {
+ uint32_t resp[1];
+
+ chDbgCheck(sdcp != NULL, "sdcConnect");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE),
+ "mmcConnect(), #1", "invalid state");
+ sdcp->state = SDC_CONNECTING;
+ chSysUnlock();
+
+ /* Card clock initialization.*/
+ sdc_lld_start_clk(sdcp);
+
+ /* Enforces the initial card state.*/
+ sdc_lld_send_cmd_none(sdcp, SDC_CMD_GO_IDLE_STATE, 0);
+
+ /* V2.0 cards detection.*/
+ if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND,
+ SDC_CMD8_PATTERN, resp))
+ sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20;
+ /* Voltage verification.*/
+ if (((resp[0] >> 8) & 0xF) != 1)
+ goto failed;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ else {
+#if SDC_MMC_SUPPORT
+ /* MMC or SD V1.1 detection.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ sdcp->cardmode = SDC_MODE_CARDTYPE_MMC;
+ else
+#endif /* SDC_MMC_SUPPORT */
+ sdcp->cardmode = SDC_MODE_CARDTYPE_SDV11;
+ }
+
+#if SDC_MMC_SUPPORT
+ if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
+ /* TODO: MMC initialization.*/
+ return TRUE;
+ }
+ else
+#endif /* SDC_MMC_SUPPORT */
+ {
+ unsigned i;
+ uint32_t ocr;
+
+ /* SD initialization.*/
+ if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_SDV20)
+ ocr = 0xC0100000;
+ else
+ ocr = 0x80100000;
+
+ /* SD-type initialization. */
+ i = 0;
+ while (TRUE) {
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_OP_COND, ocr, resp))
+ goto failed;
+ if ((resp[0] & 0x80000000) != 0) {
+ if (resp[0] & 0x40000000)
+ sdcp->cardmode |= SDC_MODE_HIGH_CAPACITY;
+ break;
+ }
+ if (++i >= SDC_INIT_RETRY)
+ goto failed;
+ chThdSleepMilliseconds(10);
+ }
+ }
+
+ /* Reads CID.*/
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_ALL_SEND_CID, 0, sdcp->cid))
+ goto failed;
+
+ /* Asks for the RCA.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_RELATIVE_ADDR,
+ 0, &sdcp->rca))
+ goto failed;
+
+ /* Reads CSD.*/
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_SEND_CSD, sdcp->rca, sdcp->csd))
+ goto failed;
+
+ /* Switches to high speed.*/
+ sdc_lld_set_data_clk(sdcp);
+
+ /* Selects the card for operations.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEL_DESEL_CARD,
+ sdcp->rca, resp))
+ goto failed;
+
+ /* Block length fixed at 512 bytes.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BLOCKLEN,
+ SDC_BLOCK_SIZE, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+
+ /* Switches to wide bus mode.*/
+ switch (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) {
+ case SDC_MODE_CARDTYPE_SDV11:
+ case SDC_MODE_CARDTYPE_SDV20:
+ sdc_lld_set_bus_mode(sdcp, SDC_MODE_4BIT);
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, sdcp->rca, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BUS_WIDTH, 2, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ }
+
+ sdcp->state = SDC_ACTIVE;
+ return FALSE;
+failed:
+ sdc_lld_stop_clk(sdcp);
+ sdcp->state = SDC_READY;
+ return TRUE;
+}
+
+/**
+ * @brief Brings the driver in a state safe for card removal.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE the operation succeeded and the driver is now
+ * in the @p SDC_READY state.
+ * @retval TRUE the operation failed.
+ *
+ * @api
+ */
+bool_t sdcDisconnect(SDCDriver *sdcp) {
+
+ chDbgCheck(sdcp != NULL, "sdcDisconnect");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE,
+ "sdcDisconnect(), #1", "invalid state");
+ if (sdcp->state == SDC_READY) {
+ chSysUnlock();
+ return FALSE;
+ }
+ sdcp->state = SDC_DISCONNECTING;
+ chSysUnlock();
+
+ /* Waits for eventual pending operations completion.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Card clock stopped.*/
+ sdc_lld_stop_clk(sdcp);
+
+ sdcp->state = SDC_READY;
+ return FALSE;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ * @pre The driver must be in the @p SDC_ACTIVE state after a successful
+ * sdcConnect() invocation.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] n number of blocks to read
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @api
+ */
+bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n) {
+ bool_t err;
+
+ chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcRead(), #1", "invalid state");
+ sdcp->state = SDC_READING;
+ chSysUnlock();
+
+ err = sdc_lld_read(sdcp, startblk, buf, n);
+ sdcp->state = SDC_ACTIVE;
+ return err;
+}
+
+/**
+ * @brief Writes one or more blocks.
+ * @pre The driver must be in the @p SDC_ACTIVE state after a successful
+ * sdcConnect() invocation.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @api
+ */
+bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n) {
+ bool_t err;
+
+ chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcWrite");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcWrite(), #1", "invalid state");
+ sdcp->state = SDC_WRITING;
+ chSysUnlock();
+
+ err = sdc_lld_write(sdcp, startblk, buf, n);
+ sdcp->state = SDC_ACTIVE;
+ return err;
+}
+
+#endif /* HAL_USE_SDC */
+
+/** @} */
diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c
index aafedcc6b..414689aac 100644
--- a/os/hal/src/serial.c
+++ b/os/hal/src/serial.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 62a901162..3f53d7df0 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -58,44 +59,44 @@ static cdc_linecoding_t linecoding = {
static size_t writes(void *ip, const uint8_t *bp, size_t n) {
- return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp,
+ return chOQWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp,
n, TIME_INFINITE);
}
static size_t reads(void *ip, uint8_t *bp, size_t n) {
- return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp,
+ return chIQReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp,
n, TIME_INFINITE);
}
static bool_t putwouldblock(void *ip) {
- return chOQIsFullI(&((SerialDriver *)ip)->oqueue);
+ return chOQIsFullI(&((SerialUSBDriver *)ip)->oqueue);
}
static bool_t getwouldblock(void *ip) {
- return chIQIsEmptyI(&((SerialDriver *)ip)->iqueue);
+ return chIQIsEmptyI(&((SerialUSBDriver *)ip)->iqueue);
}
static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
- return chOQPutTimeout(&((SerialDriver *)ip)->oqueue, b, timeout);
+ return chOQPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, timeout);
}
static msg_t gett(void *ip, systime_t timeout) {
- return chIQGetTimeout(&((SerialDriver *)ip)->iqueue, timeout);
+ return chIQGetTimeout(&((SerialUSBDriver *)ip)->iqueue, timeout);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) {
- return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp, n, time);
+ return chOQWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp, n, time);
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) {
- return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp, n, time);
+ return chIQReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp, n, time);
}
static ioflags_t getflags(void *ip) {
@@ -119,11 +120,14 @@ static void inotify(GenericQueue *qp) {
emptied, then a whole packet is loaded in the queue.*/
if (chIQIsEmptyI(&sdup->iqueue)) {
- n = usbReadI(sdup->config->usbp, sdup->config->data_available_ep,
- sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
- if (n > 0) {
+ n = usbReadPacketI(sdup->config->usbp, DATA_AVAILABLE_EP,
+ sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
+ if (n != USB_ENDPOINT_BUSY) {
+ chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- chSemSetCounterI(&sdup->iqueue.q_sem, n);
+ sdup->iqueue.q_counter = n;
+ while (notempty(&sdup->iqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
}
@@ -133,15 +137,19 @@ static void inotify(GenericQueue *qp) {
*/
static void onotify(GenericQueue *qp) {
SerialUSBDriver *sdup = (SerialUSBDriver *)qp->q_rdptr;
- size_t n;
+ size_t w, n;
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
- n = usbWriteI(sdup->config->usbp, sdup->config->data_request_ep,
- sdup->oqueue.q_buffer, chOQGetFullI(&sdup->oqueue));
- if (n > 0) {
+ n = chOQGetFullI(&sdup->oqueue);
+ w = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP,
+ sdup->oqueue.q_buffer, n);
+ if (w != USB_ENDPOINT_BUSY) {
+ chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
+ sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
+ while (notempty(&sdup->oqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
@@ -165,12 +173,6 @@ void sduInit(void) {
* outside, usually in the hardware initialization code.
*
* @param[out] sdup pointer to a @p SerialUSBDriver structure
- * @param[in] inotify pointer to a callback function that is invoked when
- * some data is read from the Queue. The value can be
- * @p NULL.
- * @param[in] onotify pointer to a callback function that is invoked when
- * some data is written in the Queue. The value can be
- * @p NULL.
*
* @init
*/
@@ -206,7 +208,7 @@ void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) {
"invalid state");
sdup->config = config;
usbStart(config->usbp, &config->usb_config);
- config->usbp->usb_param = sdup;
+ config->usbp->param = sdup;
sdup->state = SDU_READY;
chSysUnlock();
}
@@ -242,11 +244,16 @@ void sduStop(SerialUSBDriver *sdup) {
* - CDC_SET_LINE_CODING.
* - CDC_SET_CONTROL_LINE_STATE.
* .
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @return The hook status.
+ * @retval TRUE Message handled internally.
+ * @retval FALSE Message not handled.
*/
bool_t sduRequestsHook(USBDriver *usbp) {
- if ((usbp->usb_setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
- switch (usbp->usb_setup[1]) {
+ if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
+ switch (usbp->setup[1]) {
case CDC_GET_LINE_CODING:
usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
return TRUE;
@@ -265,36 +272,44 @@ bool_t sduRequestsHook(USBDriver *usbp) {
}
/**
- * @brief Default data request callback.
+ * @brief Default data transmitted callback.
* @details The application must use this function as callback for the IN
* data endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduDataRequest(USBDriver *usbp, usbep_t ep) {
- SerialUSBDriver *sdup = usbp->usb_param;
- size_t n;
+void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
+ SerialUSBDriver *sdup = usbp->param;
+ size_t n, w;
chSysLockFromIsr();
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
n = chOQGetFullI(&sdup->oqueue);
if (n > 0) {
- n = usbWriteI(usbp, ep, sdup->oqueue.q_buffer, n);
- if (n > 0) {
- sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
+ w = usbWritePacketI(usbp, ep, sdup->oqueue.q_buffer, n);
+ if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
+ sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
+ sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
+ while (notempty(&sdup->oqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
chSysUnlockFromIsr();
}
/**
- * @brief Default data available callback.
+ * @brief Default data received callback.
* @details The application must use this function as callback for the OUT
* data endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
- SerialUSBDriver *sdup = usbp->usb_param;
+void sduDataReceived(USBDriver *usbp, usbep_t ep) {
+ SerialUSBDriver *sdup = usbp->param;
chSysLockFromIsr();
/* Writes to the input queue can only happen when the queue has been
@@ -302,11 +317,14 @@ void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
if (chIQIsEmptyI(&sdup->iqueue)) {
size_t n;
- n = usbReadI(usbp, ep, sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
- if (n > 0) {
- sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- chSemSetCounterI(&sdup->iqueue.q_sem, n);
+ n = usbReadPacketI(usbp, ep, sdup->iqueue.q_buffer,
+ SERIAL_USB_BUFFERS_SIZE);
+ if (n != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
+ sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
+ sdup->iqueue.q_counter = n;
+ while (notempty(&sdup->iqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
chSysUnlockFromIsr();
@@ -316,8 +334,11 @@ void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
* @brief Default data received callback.
* @details The application must use this function as callback for the IN
* interrupt endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduInterruptRequest(USBDriver *usbp, usbep_t ep) {
+void sduInterruptTransmitted(USBDriver *usbp, usbep_t ep) {
(void)usbp;
(void)ep;
diff --git a/os/hal/src/spi.c b/os/hal/src/spi.c
index e99126b9e..aaf0115eb 100644
--- a/os/hal/src/spi.c
+++ b/os/hal/src/spi.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,16 +68,16 @@ void spiInit(void) {
*/
void spiObjectInit(SPIDriver *spip) {
- spip->spd_state = SPI_STOP;
- spip->spd_config = NULL;
+ spip->state = SPI_STOP;
+ spip->config = NULL;
#if SPI_USE_WAIT
- spip->spd_thread = NULL;
+ spip->thread = NULL;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION
#if CH_USE_MUTEXES
- chMtxInit(&spip->spd_mutex);
+ chMtxInit(&spip->mutex);
#else
- chSemInit(&spip->spd_semaphore, 1);
+ chSemInit(&spip->semaphore, 1);
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_INIT_HOOK)
@@ -97,11 +98,11 @@ void spiStart(SPIDriver *spip, const SPIConfig *config) {
chDbgCheck((spip != NULL) && (config != NULL), "spiStart");
chSysLock();
- chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY),
+ chDbgAssert((spip->state == SPI_STOP) || (spip->state == SPI_READY),
"spiStart(), #1", "invalid state");
- spip->spd_config = config;
+ spip->config = config;
spi_lld_start(spip);
- spip->spd_state = SPI_READY;
+ spip->state = SPI_READY;
chSysUnlock();
}
@@ -119,11 +120,11 @@ void spiStop(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiStop");
chSysLock();
- chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY),
+ chDbgAssert((spip->state == SPI_STOP) || (spip->state == SPI_READY),
"spiStop(), #1", "invalid state");
spi_lld_unselect(spip);
spi_lld_stop(spip);
- spip->spd_state = SPI_STOP;
+ spip->state = SPI_STOP;
chSysUnlock();
}
@@ -139,8 +140,7 @@ void spiSelect(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiSelect");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiSelect(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiSelect(), #1", "not ready");
spiSelectI(spip);
chSysUnlock();
}
@@ -158,8 +158,7 @@ void spiUnselect(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiUnselect");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiUnselect(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiUnselect(), #1", "not ready");
spiUnselectI(spip);
chSysUnlock();
}
@@ -182,8 +181,7 @@ void spiStartIgnore(SPIDriver *spip, size_t n) {
chDbgCheck((spip != NULL) && (n > 0), "spiStartIgnore");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartIgnore(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartIgnore(), #1", "not ready");
spiStartIgnoreI(spip, n);
chSysUnlock();
}
@@ -212,8 +210,7 @@ void spiStartExchange(SPIDriver *spip, size_t n,
"spiStartExchange");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartExchange(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartExchange(), #1", "not ready");
spiStartExchangeI(spip, n, txbuf, rxbuf);
chSysUnlock();
}
@@ -239,8 +236,7 @@ void spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) {
"spiStartSend");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartSend(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartSend(), #1", "not ready");
spiStartSendI(spip, n, txbuf);
chSysUnlock();
}
@@ -266,8 +262,7 @@ void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
"spiStartReceive");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartReceive(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartReceive(), #1", "not ready");
spiStartReceiveI(spip, n, rxbuf);
chSysUnlock();
}
@@ -280,7 +275,7 @@ void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
@@ -292,10 +287,8 @@ void spiIgnore(SPIDriver *spip, size_t n) {
chDbgCheck((spip != NULL) && (n > 0), "spiIgnoreWait");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiIgnore(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
- "spiIgnore(), #2", "has callback");
+ chDbgAssert(spip->state == SPI_READY, "spiIgnore(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL, "spiIgnore(), #2", "has callback");
spiStartIgnoreI(spip, n);
_spi_wait_s(spip);
chSysUnlock();
@@ -308,7 +301,7 @@ void spiIgnore(SPIDriver *spip, size_t n) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -326,9 +319,8 @@ void spiExchange(SPIDriver *spip, size_t n,
"spiExchange");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiExchange(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
+ chDbgAssert(spip->state == SPI_READY, "spiExchange(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL,
"spiExchange(), #2", "has callback");
spiStartExchangeI(spip, n, txbuf, rxbuf);
_spi_wait_s(spip);
@@ -341,7 +333,7 @@ void spiExchange(SPIDriver *spip, size_t n,
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -353,14 +345,11 @@ void spiExchange(SPIDriver *spip, size_t n,
*/
void spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
- chDbgCheck((spip != NULL) && (n > 0) && (txbuf != NULL),
- "spiSend");
+ chDbgCheck((spip != NULL) && (n > 0) && (txbuf != NULL), "spiSend");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiSend(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
- "spiSend(), #2", "has callback");
+ chDbgAssert(spip->state == SPI_READY, "spiSend(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL, "spiSend(), #2", "has callback");
spiStartSendI(spip, n, txbuf);
_spi_wait_s(spip);
chSysUnlock();
@@ -372,7 +361,7 @@ void spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -388,9 +377,8 @@ void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) {
"spiReceive");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiReceive(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
+ chDbgAssert(spip->state == SPI_READY, "spiReceive(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL,
"spiReceive(), #2", "has callback");
spiStartReceiveI(spip, n, rxbuf);
_spi_wait_s(spip);
@@ -415,9 +403,9 @@ void spiAcquireBus(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiAcquireBus");
#if CH_USE_MUTEXES
- chMtxLock(&spip->spd_mutex);
+ chMtxLock(&spip->mutex);
#elif CH_USE_SEMAPHORES
- chSemWait(&spip->spd_semaphore);
+ chSemWait(&spip->semaphore);
#endif
}
@@ -438,7 +426,7 @@ void spiReleaseBus(SPIDriver *spip) {
(void)spip;
chMtxUnlock();
#elif CH_USE_SEMAPHORES
- chSemSignal(&spip->spd_semaphore);
+ chSemSignal(&spip->semaphore);
#endif
}
#endif /* SPI_USE_MUTUAL_EXCLUSION */
diff --git a/os/hal/src/uart.c b/os/hal/src/uart.c
index 4a21e907f..05fdbb168 100644
--- a/os/hal/src/uart.c
+++ b/os/hal/src/uart.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,10 +68,10 @@ void uartInit(void) {
*/
void uartObjectInit(UARTDriver *uartp) {
- uartp->ud_state = UART_STOP;
- uartp->ud_txstate = UART_TX_IDLE;
- uartp->ud_rxstate = UART_RX_IDLE;
- uartp->ud_config = NULL;
+ uartp->state = UART_STOP;
+ uartp->txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->config = NULL;
/* Optional, user-defined initializer.*/
#if defined(UART_DRIVER_EXT_INIT_HOOK)
UART_DRIVER_EXT_INIT_HOOK(uartp);
@@ -90,14 +91,12 @@ void uartStart(UARTDriver *uartp, const UARTConfig *config) {
chDbgCheck((uartp != NULL) && (config != NULL), "uartStart");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_STOP) ||
- (uartp->ud_state == UART_READY),
- "uartStart(), #1",
- "invalid state");
+ chDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY),
+ "uartStart(), #1", "invalid state");
- uartp->ud_config = config;
+ uartp->config = config;
uart_lld_start(uartp);
- uartp->ud_state = UART_READY;
+ uartp->state = UART_READY;
chSysUnlock();
}
@@ -113,15 +112,13 @@ void uartStop(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStop");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_STOP) ||
- (uartp->ud_state == UART_READY),
- "uartStop(), #1",
- "invalid state");
+ chDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY),
+ "uartStop(), #1", "invalid state");
uart_lld_stop(uartp);
- uartp->ud_state = UART_STOP;
- uartp->ud_txstate = UART_TX_IDLE;
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->state = UART_STOP;
+ uartp->txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
chSysUnlock();
}
@@ -142,13 +139,11 @@ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) {
"uartStartSend");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_txstate == UART_TX_IDLE),
- "uartStartSend(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->txstate == UART_TX_IDLE),
+ "uartStartSend(), #1", "not active");
uart_lld_start_send(uartp, n, txbuf);
- uartp->ud_txstate = UART_TX_ACTIVE;
+ uartp->txstate = UART_TX_ACTIVE;
chSysUnlock();
}
@@ -169,12 +164,11 @@ void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) {
chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL),
"uartStartSendI");
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_txstate != UART_TX_ACTIVE),
- "uartStartSendI(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) &&
+ (uartp->txstate != UART_TX_ACTIVE),
+ "uartStartSendI(), #1", "not active");
uart_lld_start_send(uartp, n, txbuf);
- uartp->ud_txstate = UART_TX_ACTIVE;
+ uartp->txstate = UART_TX_ACTIVE;
}
/**
@@ -195,13 +189,11 @@ size_t uartStopSend(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopSend");
chSysLock();
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopSend(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY, "uartStopSend(), #1", "not active");
- if (uartp->ud_txstate == UART_TX_ACTIVE) {
+ if (uartp->txstate == UART_TX_ACTIVE) {
n = uart_lld_stop_send(uartp);
- uartp->ud_txstate = UART_TX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
}
else
n = 0;
@@ -226,13 +218,11 @@ size_t uartStopSendI(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopSendI");
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopSendI(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active");
- if (uartp->ud_txstate == UART_TX_ACTIVE) {
+ if (uartp->txstate == UART_TX_ACTIVE) {
size_t n = uart_lld_stop_send(uartp);
- uartp->ud_txstate = UART_TX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
return n;
}
return 0;
@@ -255,13 +245,11 @@ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) {
"uartStartReceive");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_rxstate == UART_RX_IDLE),
- "uartStartReceive(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
+ "uartStartReceive(), #1", "not active");
uart_lld_start_receive(uartp, n, rxbuf);
- uartp->ud_rxstate = UART_RX_ACTIVE;
+ uartp->rxstate = UART_RX_ACTIVE;
chSysUnlock();
}
@@ -282,13 +270,11 @@ void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) {
chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL),
"uartStartReceiveI");
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_rxstate == UART_RX_IDLE),
- "uartStartReceiveI(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
+ "uartStartReceiveI(), #1", "not active");
uart_lld_start_receive(uartp, n, rxbuf);
- uartp->ud_rxstate = UART_RX_ACTIVE;
+ uartp->rxstate = UART_RX_ACTIVE;
}
/**
@@ -309,13 +295,12 @@ size_t uartStopReceive(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopReceive");
chSysLock();
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopReceive(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY,
+ "uartStopReceive(), #1", "not active");
- if (uartp->ud_rxstate == UART_RX_ACTIVE) {
+ if (uartp->rxstate == UART_RX_ACTIVE) {
n = uart_lld_stop_receive(uartp);
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
}
else
n = 0;
@@ -339,13 +324,12 @@ size_t uartStopReceive(UARTDriver *uartp) {
size_t uartStopReceiveI(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopReceiveI");
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopReceiveI(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY,
+ "uartStopReceiveI(), #1", "not active");
- if (uartp->ud_rxstate == UART_RX_ACTIVE) {
+ if (uartp->rxstate == UART_RX_ACTIVE) {
size_t n = uart_lld_stop_receive(uartp);
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
return n;
}
return 0;
diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c
index 3cc076443..484590f3b 100644
--- a/os/hal/src/usb.c
+++ b/os/hal/src/usb.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -54,74 +55,19 @@ static const uint8_t halted_status[] = {0x01, 0x00};
*
* @param[in] usbp pointer to the @p USBDriver object
*/
-void set_address(USBDriver *usbp) {
+static void set_address(USBDriver *usbp) {
- usbp->usb_address = usbp->usb_setup[2];
- usb_lld_set_address(usbp, usbp->usb_address);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_ADDRESS);
- usbp->usb_state = USB_SELECTED;
-}
-
-/**
- * @brief Starts a receive phase on the endpoint zero.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- */
-static void start_rx_ep0(USBDriver *usbp) {
-
- if (usbp->usb_ep0n > 0) {
- /* The received data cannot exceed the available amount.*/
- if (usbp->usb_ep0n > usbp->usb_ep0max)
- usbp->usb_ep0n = usbp->usb_ep0max;
-
- /* Determines the maximum amount that can be received using a
- single packet.*/
- if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_out_maxsize)
- usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_out_maxsize;
- else
- usbp->usb_ep0lastsize = usbp->usb_ep0n;
- usbp->usb_ep0state = USB_EP0_RX;
- }
- else {
- /* Sending zero sized status packet.*/
- usb_lld_write(usbp, 0, NULL, 0);
- usbp->usb_ep0state = USB_EP0_SENDING_STS;
- }
-}
-
-/**
- * @brief Starts a transmission phase on the endpoint zero.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- */
-static void start_tx_ep0(USBDriver *usbp) {
-
- if (usbp->usb_ep0n > 0) {
- /* The transmitted data cannot exceed the requested amount.*/
- if (usbp->usb_ep0n > usbp->usb_ep0max)
- usbp->usb_ep0n = usbp->usb_ep0max;
-
- /* Determines the maximum amount that can be transmitted using a
- single packet.*/
- if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize)
- usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_in_maxsize;
- else
- usbp->usb_ep0lastsize = usbp->usb_ep0n;
-
- /* Starts transmission.*/
- usb_lld_write(usbp, 0, usbp->usb_ep0next, usbp->usb_ep0lastsize);
- usbp->usb_ep0state = USB_EP0_TX;
- }
- else
- usbp->usb_ep0state = USB_EP0_WAITING_STS;
+ usbp->address = usbp->setup[2];
+ usb_lld_set_address(usbp);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_ADDRESS);
+ usbp->state = USB_SELECTED;
}
/**
* @brief Standard requests handler.
* @details This is the standard requests default handler, most standard
* requests are handled here, the user can override the standard
- * handling using the @p uc_requests_hook_cb hook in the
+ * handling using the @p requests_hook_cb hook in the
* @p USBConfig structure.
*
* @param[in] usbp pointer to the @p USBDriver object
@@ -133,18 +79,18 @@ static bool_t default_handler(USBDriver *usbp) {
const USBDescriptor *dp;
/* Decoding the request.*/
- switch (((usbp->usb_setup[0] & (USB_RTYPE_RECIPIENT_MASK |
- USB_RTYPE_TYPE_MASK)) |
- (usbp->usb_setup[1] << 8))) {
+ switch (((usbp->setup[0] & (USB_RTYPE_RECIPIENT_MASK |
+ USB_RTYPE_TYPE_MASK)) |
+ (usbp->setup[1] << 8))) {
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_STATUS << 8):
/* Just returns the current status word.*/
- usbSetupTransfer(usbp, (uint8_t *)&usbp->usb_status, 2, NULL);
+ usbSetupTransfer(usbp, (uint8_t *)&usbp->status, 2, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_CLEAR_FEATURE << 8):
/* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature
number is handled as an error.*/
- if (usbp->usb_setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
- usbp->usb_status &= ~2;
+ if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
+ usbp->status &= ~2;
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
}
@@ -152,39 +98,46 @@ static bool_t default_handler(USBDriver *usbp) {
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_FEATURE << 8):
/* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature
number is handled as an error.*/
- if (usbp->usb_setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
- usbp->usb_status |= 2;
+ if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
+ usbp->status |= 2;
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
}
return FALSE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_ADDRESS << 8):
- /* The handling is posponed to after the status phase in order to allow
- the proper completion of the transaction.*/
+ /* The SET_ADDRESS handling can be performed here or postponed after
+ the status packed depending on the USB_SET_ADDRESS_MODE low
+ driver setting.*/
+#if USB_SET_ADDRESS_MODE == USB_EARLY_SET_ADDRESS
+ if ((usbp->setup[0] == USB_RTYPE_RECIPIENT_DEVICE) &&
+ (usbp->setup[1] == USB_REQ_SET_ADDRESS))
+ set_address(usbp);
+ usbSetupTransfer(usbp, NULL, 0, NULL);
+#else
usbSetupTransfer(usbp, NULL, 0, set_address);
+#endif
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_DESCRIPTOR << 8):
/* Handling descriptor requests from the host.*/
- dp = usbp->usb_config->uc_get_descriptor_cb(
- usbp, usbp->usb_setup[3], usbp->usb_setup[2],
- usb_lld_fetch_word(&usbp->usb_setup[4]));
+ dp = usbp->config->get_descriptor_cb(
+ usbp, usbp->setup[3], usbp->setup[2],
+ usb_lld_fetch_word(&usbp->setup[4]));
if (dp == NULL)
return FALSE;
usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_CONFIGURATION << 8):
/* Returning the last selected configuration.*/
- usbSetupTransfer(usbp, &usbp->usb_configuration, 1, NULL);
+ usbSetupTransfer(usbp, &usbp->configuration, 1, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_CONFIGURATION << 8):
/* Handling configuration selection from the host.*/
- usbp->usb_configuration = usbp->usb_setup[2];
- if (usbp->usb_configuration == 0)
- usbp->usb_state = USB_SELECTED;
+ usbp->configuration = usbp->setup[2];
+ if (usbp->configuration == 0)
+ usbp->state = USB_SELECTED;
else
- usbp->usb_state = USB_ACTIVE;
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_CONFIGURED);
+ usbp->state = USB_ACTIVE;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_CONFIGURED);
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_INTERFACE | (USB_REQ_GET_STATUS << 8):
@@ -195,8 +148,8 @@ static bool_t default_handler(USBDriver *usbp) {
return TRUE;
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_GET_STATUS << 8):
/* Sending the EP status.*/
- if (usbp->usb_setup[4] & 0x80) {
- switch (usb_lld_get_status_in(usbp, usbp->usb_setup[4] & 0x0F)) {
+ if (usbp->setup[4] & 0x80) {
+ switch (usb_lld_get_status_in(usbp, usbp->setup[4] & 0x0F)) {
case EP_STATUS_STALLED:
usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL);
return TRUE;
@@ -208,7 +161,7 @@ static bool_t default_handler(USBDriver *usbp) {
}
}
else {
- switch (usb_lld_get_status_out(usbp, usbp->usb_setup[4] & 0x0F)) {
+ switch (usb_lld_get_status_out(usbp, usbp->setup[4] & 0x0F)) {
case EP_STATUS_STALLED:
usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL);
return TRUE;
@@ -221,27 +174,27 @@ static bool_t default_handler(USBDriver *usbp) {
}
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_CLEAR_FEATURE << 8):
/* Only ENDPOINT_HALT is handled as feature.*/
- if (usbp->usb_setup[2] != USB_FEATURE_ENDPOINT_HALT)
+ if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT)
return FALSE;
/* Clearing the EP status, not valid for EP0, it is ignored in that case.*/
- if ((usbp->usb_setup[4] & 0x0F) > 0) {
- if (usbp->usb_setup[4] & 0x80)
- usb_lld_clear_in(usbp, usbp->usb_setup[4] & 0x0F);
+ if ((usbp->setup[4] & 0x0F) > 0) {
+ if (usbp->setup[4] & 0x80)
+ usb_lld_clear_in(usbp, usbp->setup[4] & 0x0F);
else
- usb_lld_clear_out(usbp, usbp->usb_setup[4] & 0x0F);
+ usb_lld_clear_out(usbp, usbp->setup[4] & 0x0F);
}
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_SET_FEATURE << 8):
/* Only ENDPOINT_HALT is handled as feature.*/
- if (usbp->usb_setup[2] != USB_FEATURE_ENDPOINT_HALT)
+ if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT)
return FALSE;
/* Stalling the EP, not valid for EP0, it is ignored in that case.*/
- if ((usbp->usb_setup[4] & 0x0F) > 0) {
- if (usbp->usb_setup[4] & 0x80)
- usb_lld_stall_in(usbp, usbp->usb_setup[4] & 0x0F);
+ if ((usbp->setup[4] & 0x0F) > 0) {
+ if (usbp->setup[4] & 0x80)
+ usb_lld_stall_in(usbp, usbp->setup[4] & 0x0F);
else
- usb_lld_stall_out(usbp, usbp->usb_setup[4] & 0x0F);
+ usb_lld_stall_out(usbp, usbp->setup[4] & 0x0F);
}
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
@@ -282,9 +235,11 @@ void usbInit(void) {
*/
void usbObjectInit(USBDriver *usbp) {
- usbp->usb_state = USB_STOP;
- usbp->usb_config = NULL;
- usbp->usb_param = NULL;
+ usbp->state = USB_STOP;
+ usbp->config = NULL;
+ usbp->param = NULL;
+ usbp->transmitting = 0;
+ usbp->receiving = 0;
}
/**
@@ -301,13 +256,13 @@ void usbStart(USBDriver *usbp, const USBConfig *config) {
chDbgCheck((usbp != NULL) && (config != NULL), "usbStart");
chSysLock();
- chDbgAssert((usbp->usb_state == USB_STOP) || (usbp->usb_state == USB_READY),
+ chDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY),
"usbStart(), #1", "invalid state");
- usbp->usb_config = config;
+ usbp->config = config;
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
usb_lld_start(usbp);
- usbp->usb_state = USB_READY;
+ usbp->state = USB_READY;
chSysUnlock();
}
@@ -323,11 +278,10 @@ void usbStop(USBDriver *usbp) {
chDbgCheck(usbp != NULL, "usbStop");
chSysLock();
- chDbgAssert((usbp->usb_state == USB_STOP) || (usbp->usb_state == USB_READY),
- "usbStop(), #1",
- "invalid state");
+ chDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY),
+ "usbStop(), #1", "invalid state");
usb_lld_stop(usbp);
- usbp->usb_state = USB_STOP;
+ usbp->state = USB_STOP;
chSysUnlock();
}
@@ -340,23 +294,24 @@ void usbStop(USBDriver *usbp) {
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[out] epp pointer to an endpoint state descriptor structure
* @param[in] epcp the endpoint configuration
*
* @iclass
*/
-void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
+void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
const USBEndpointConfig *epcp) {
- chDbgAssert(usbp->usb_state == USB_ACTIVE,
+ chDbgAssert(usbp->state == USB_ACTIVE,
"usbEnableEndpointI(), #1", "invalid state");
- chDbgAssert(usbp->usb_ep[ep] != NULL,
+ chDbgAssert(usbp->epc[ep] != NULL,
"usbEnableEndpointI(), #2", "already initialized");
/* Logically enabling the endpoint in the USBDriver structure.*/
- memset(epp, 0, sizeof(USBEndpointState));
- epp->uep_config = epcp;
- usbp->usb_ep[ep] = epp;
+ if (!(epcp->ep_mode & USB_EP_MODE_PACKET)) {
+ memset(epcp->in_state, 0, sizeof(USBInEndpointState));
+ memset(epcp->out_state, 0, sizeof(USBOutEndpointState));
+ }
+ usbp->epc[ep] = epcp;
/* Low level endpoint activation.*/
usb_lld_init_endpoint(usbp, ep);
@@ -376,18 +331,174 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
void usbDisableEndpointsI(USBDriver *usbp) {
unsigned i;
- chDbgAssert(usbp->usb_state == USB_SELECTED,
+ chDbgAssert(usbp->state == USB_SELECTED,
"usbDisableEndpointsI(), #1", "invalid state");
+ usbp->transmitting &= ~1;
+ usbp->receiving &= ~1;
for (i = 1; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
/* Low level endpoints deactivation.*/
usb_lld_disable_endpoints(usbp);
}
/**
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to accept another packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The received packet size regardless the specified
+ * @p n parameter.
+ * @retval USB_ENDPOINT_BUSY Endpoint busy receiving.
+ * @retval 0 Zero size packet received.
+ *
+ * @iclass
+ */
+size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return USB_ENDPOINT_BUSY;
+
+ usbp->receiving |= (1 << ep);
+ return usb_lld_read_packet(usbp, ep, buf, n);;
+}
+
+/**
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The operation status.
+ * @retval USB_ENDPOINT_BUSY Endpoint busy transmitting.
+ * @retval 0 Operation complete.
+ *
+ * @iclass
+ */
+size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return USB_ENDPOINT_BUSY;
+
+ usbp->transmitting |= (1 << ep);
+ usb_lld_write_packet(usbp, ep, buf, n);
+ return 0;
+}
+
+/**
+ * @brief Starts a receive transaction on an OUT endpoint.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in transaction mode.
+ * @post The endpoint callback is invoked when the transfer has been
+ * completed.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the received data
+ * @param[in] n maximum number of bytes to copy
+ * @return The operation status.
+ * @retval FALSE Operation started successfully.
+ * @retval TRUE Endpoint busy, operation not started.
+ *
+ * @iclass
+ */
+bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return TRUE;
+
+ usbp->receiving |= (1 << ep);
+ usb_lld_start_out(usbp, ep, buf, n);
+ return FALSE;
+}
+
+/**
+ * @brief Starts a transmit transaction on an IN endpoint.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in transaction mode.
+ * @post The endpoint callback is invoked when the transfer has been
+ * completed.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the data to be transmitted
+ * @param[in] n maximum number of bytes to copy
+ * @return The operation status.
+ * @retval FALSE Operation started successfully.
+ * @retval TRUE Endpoint busy, operation not started.
+ *
+ * @iclass
+ */
+bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return TRUE;
+
+ usbp->transmitting |= (1 << ep);
+ usb_lld_start_in(usbp, ep, buf, n);
+ return FALSE;
+}
+
+/**
+ * @brief Stalls an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The operation status.
+ * @retval FALSE Endpoint stalled.
+ * @retval TRUE Endpoint busy, not stalled.
+ *
+ * @iclass
+ */
+bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return TRUE;
+
+ usb_lld_stall_out(usbp, ep);
+ return FALSE;
+}
+
+/**
+ * @brief Stalls an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The operation status.
+ * @retval FALSE Endpoint stalled.
+ * @retval TRUE Endpoint busy, not stalled.
+ *
+ * @iclass
+ */
+bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return TRUE;
+
+ usb_lld_stall_in(usbp, ep);
+ return FALSE;
+}
+
+/**
* @brief USB reset routine.
+ * @details This function must be invoked when an USB bus reset condition is
+ * detected.
*
* @param[in] usbp pointer to the @p USBDriver object
*
@@ -396,24 +507,93 @@ void usbDisableEndpointsI(USBDriver *usbp) {
void _usb_reset(USBDriver *usbp) {
unsigned i;
- usbp->usb_state = USB_READY;
- usbp->usb_status = 0;
- usbp->usb_address = 0;
- usbp->usb_configuration = 0;
+ usbp->state = USB_READY;
+ usbp->status = 0;
+ usbp->address = 0;
+ usbp->configuration = 0;
+ usbp->transmitting = 0;
+ usbp->receiving = 0;
/* Invalidates all endpoints into the USBDriver structure.*/
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
/* EP0 state machine initialization.*/
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
/* Low level reset.*/
usb_lld_reset(usbp);
+}
- /* Endpoint zero initialization.*/
-/* usbp->usb_ep[0].uep_config = &usb_lld_ep0config;
- usb_lld_init_endpoint(usbp, 0, &usb_lld_ep0config);*/
+/**
+ * @brief Default EP0 SETUP callback.
+ * @details This function is used by the low level driver as default handler
+ * for EP0 SETUP events.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number, always zero
+ *
+ * @notapi
+ */
+void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
+ size_t max;
+
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
+ usbReadSetup(usbp, ep, usbp->setup);
+
+ /* First verify if the application has an handler installed for this
+ request.*/
+ if (!(usbp->config->requests_hook_cb) ||
+ !(usbp->config->requests_hook_cb(usbp))) {
+ /* Invoking the default handler, if this fails then stalls the
+ endpoint zero as error.*/
+ if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) ||
+ !default_handler(usbp)) {
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
+ usb_lld_stall_in(usbp, 0);
+ usb_lld_stall_out(usbp, 0);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
+ }
+ }
+
+ /* Transfer preparation. The request handler must have populated
+ correctly the fields ep0next, ep0n and ep0endcb using the macro
+ usbSetupTransfer().*/
+ max = usb_lld_fetch_word(&usbp->setup[6]);
+ /* The transfer size cannot exceed the specified amount.*/
+ if (usbp->ep0n > max)
+ usbp->ep0n = max;
+ if ((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) {
+ /* IN phase.*/
+ if (usbp->ep0n > 0) {
+ /* Starts the transmit phase.*/
+ usbp->ep0state = USB_EP0_TX;
+ usb_lld_start_in(usbp, 0, usbp->ep0next, usbp->ep0n);
+ }
+ else {
+ /* No transmission phase, directly receiving the zero sized status
+ packet.*/
+ usbp->ep0state = USB_EP0_WAITING_STS;
+ usb_lld_start_out(usbp, 0, NULL, 0);
+ }
+ }
+ else {
+ /* OUT phase.*/
+ if (usbp->ep0n > 0) {
+ /* Starts the receive phase.*/
+ usbp->ep0state = USB_EP0_RX;
+ usb_lld_start_out(usbp, 0, usbp->ep0next, usbp->ep0n);
+ }
+ else {
+ /* No receive phase, directly sending the zero sized status
+ packet.*/
+ usbp->ep0state = USB_EP0_SENDING_STS;
+ usb_lld_start_in(usbp, 0, NULL, 0);
+ }
+ }
}
/**
@@ -427,43 +607,41 @@ void _usb_reset(USBDriver *usbp) {
* @notapi
*/
void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
+ size_t max;
(void)ep;
- switch (usbp->usb_ep0state) {
+ switch (usbp->ep0state) {
case USB_EP0_TX:
- usbp->usb_ep0next += usbp->usb_ep0lastsize;
- usbp->usb_ep0max -= usbp->usb_ep0lastsize;
- usbp->usb_ep0n -= usbp->usb_ep0lastsize;
-
- /* The final condition is when the requested size has been transmitted or
- when a packet has been sent with size less than the maximum packet
- size.*/
- if ((usbp->usb_ep0max == 0) ||
- (usbp->usb_ep0lastsize < usbp->usb_ep[0]->uep_config->uepc_in_maxsize))
- usbp->usb_ep0state = USB_EP0_WAITING_STS;
- else {
- usbp->usb_ep0lastsize =
- usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize ?
- usbp->usb_ep[0]->uep_config->uepc_in_maxsize :
- usbp->usb_ep0n;
- usb_lld_write(usbp, 0, usbp->usb_ep0next, usbp->usb_ep0lastsize);
- }
+ max = usb_lld_fetch_word(&usbp->setup[6]);
+ /* If the transmitted size is less than the requested size and it is a
+ multiple of the maximum packet size then a zero size packet must be
+ transmitted.*/
+ if ((usbp->ep0n < max) &&
+ ((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0)) {
+ usb_lld_start_in(usbp, 0, NULL, 0);
+ return;
+ }
+
+ /* Transmit phase over, receiving the zero sized status packet.*/
+ usbp->ep0state = USB_EP0_WAITING_STS;
+ usb_lld_start_out(usbp, 0, NULL, 0);
return;
case USB_EP0_SENDING_STS:
- if (usbp->usb_ep0endcb)
- usbp->usb_ep0endcb(usbp);
-
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ /* Status packet sent, invoking the callback if defined.*/
+ if (usbp->ep0endcb != NULL)
+ usbp->ep0endcb(usbp);
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
return;
default:
;
}
- /* Error response.*/
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
usb_lld_stall_in(usbp, 0);
usb_lld_stall_out(usbp, 0);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_STALLED);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
}
/**
@@ -477,72 +655,33 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
* @notapi
*/
void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
- size_t n, size;
- uint8_t buf[1];
(void)ep;
- switch (usbp->usb_ep0state) {
- case USB_EP0_WAITING_SETUP:
- /* SETUP packet handling.*/
- n = usb_lld_read(usbp, 0, usbp->usb_setup, 8);
- if (n != 8)
- break;
-
- /* First verify if the application has an handler installed for this
- request.*/
- if (!(usbp->usb_config->uc_requests_hook_cb) ||
- !(usbp->usb_config->uc_requests_hook_cb(usbp))) {
- /* Invoking the default handler, if this fails then stalls the
- endpoint zero as error.*/
- if (((usbp->usb_setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) ||
- !default_handler(usbp))
- break;
- }
-
- /* Transfer preparation. The request handler must have populated
- correctly the fields usb_ep0next, usb_ep0n and usb_ep0endcb using
- the macro usbSetupTransfer().*/
- usbp->usb_ep0max = usb_lld_fetch_word(&usbp->usb_setup[6]);
- if ((usbp->usb_setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST)
- start_tx_ep0(usbp);
- else
- start_rx_ep0(usbp);
- return;
+ switch (usbp->ep0state) {
case USB_EP0_RX:
- /* Check for buffer overflow.*/
- n = size = usb_lld_get_readable(usbp, 0);
- if (n > usbp->usb_ep0n)
- n = usbp->usb_ep0n;
- /* Fetching received data packet.*/
- n = usb_lld_read(usbp, 0, usbp->usb_ep0next, n);
- if (n > usbp->usb_ep0max)
- break;
- usbp->usb_ep0max -= size;
- usbp->usb_ep0n -= n;
- usbp->usb_ep0next += n;
- if (usbp->usb_ep0max == 0) {
- usb_lld_write(usbp, 0, NULL, 0);
- usbp->usb_ep0state = USB_EP0_SENDING_STS;
- }
+ /* Receive phase over, sending the zero sized status packet.*/
+ usbp->ep0state = USB_EP0_SENDING_STS;
+ usb_lld_start_in(usbp, 0, NULL, 0);
return;
case USB_EP0_WAITING_STS:
- /* STATUS received packet handling, it must be zero sized.*/
- n = usb_lld_read(usbp, 0, buf, 1);
- if (n != 0)
+ /* Status packet received, it must be zero sized, invoking the callback
+ if defined.*/
+ if (usbGetReceiveTransactionSizeI(usbp, 0) != 0)
break;
- if (usbp->usb_ep0endcb)
- usbp->usb_ep0endcb(usbp);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ if (usbp->ep0endcb != NULL)
+ usbp->ep0endcb(usbp);
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
return;
default:
;
}
- /* Error response.*/
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
usb_lld_stall_in(usbp, 0);
usb_lld_stall_out(usbp, 0);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_STALLED);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
}
#endif /* HAL_USE_USB */
diff --git a/os/hal/templates/adc_lld.c b/os/hal/templates/adc_lld.c
index 54622beb7..eea062160 100644
--- a/os/hal/templates/adc_lld.c
+++ b/os/hal/templates/adc_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -83,6 +84,10 @@ void adc_lld_start(ADCDriver *adcp) {
*/
void adc_lld_stop(ADCDriver *adcp) {
+ if (adcp->state == ADC_READY) {
+ /* Clock de-activation.*/
+
+ }
}
/**
diff --git a/os/hal/templates/adc_lld.h b/os/hal/templates/adc_lld.h
index 54d78fd44..5f04d221b 100644
--- a/os/hal/templates/adc_lld.h
+++ b/os/hal/templates/adc_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -86,15 +87,15 @@ typedef struct {
/**
* @brief Enables the circular buffer mode for the group.
*/
- bool_t acg_circular;
+ bool_t circular;
/**
* @brief Number of the analog channels belonging to the conversion group.
*/
- adc_channels_num_t acg_num_channels;
+ adc_channels_num_t num_channels;
/**
* @brief Callback function associated to the group or @p NULL.
*/
- adccallback_t acg_endcb;
+ adccallback_t end_cb;
/* End of the mandatory fields.*/
} ADCConversionGroup;
@@ -117,37 +118,37 @@ struct ADCDriver {
/**
* @brief Driver state.
*/
- adcstate_t ad_state;
+ adcstate_t state;
/**
* @brief Current configuration data.
*/
- const ADCConfig *ad_config;
+ const ADCConfig *config;
/**
* @brief Current samples buffer pointer or @p NULL.
*/
- adcsample_t *ad_samples;
+ adcsample_t *samples;
/**
* @brief Current samples buffer depth or @p 0.
*/
- size_t ad_depth;
+ size_t depth;
/**
* @brief Current conversion group pointer or @p NULL.
*/
- const ADCConversionGroup *ad_grpp;
+ const ADCConversionGroup *grpp;
#if ADC_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *ad_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the peripheral.
*/
- Mutex ad_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore ad_semaphore;
+ Semaphore semaphore;
#endif
#endif /* ADC_USE_MUTUAL_EXCLUSION */
#if defined(ADC_DRIVER_EXT_FIELDS)
diff --git a/os/hal/templates/can_lld.c b/os/hal/templates/can_lld.c
index 2dc92f169..ae0ca9607 100644
--- a/os/hal/templates/can_lld.c
+++ b/os/hal/templates/can_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -80,7 +81,7 @@ void can_lld_start(CANDriver *canp) {
void can_lld_stop(CANDriver *canp) {
/* If in ready state then disables the CAN peripheral.*/
- if (canp->cd_state == CAN_READY) {
+ if (canp->state == CAN_READY) {
}
}
diff --git a/os/hal/templates/can_lld.h b/os/hal/templates/can_lld.h
index 37ce7f157..d07bd78cc 100644
--- a/os/hal/templates/can_lld.h
+++ b/os/hal/templates/can_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -82,22 +83,22 @@ typedef uint32_t canstatus_t;
*/
typedef struct {
struct {
- uint8_t cf_DLC:4; /**< @brief Data length. */
- uint8_t cf_RTR:1; /**< @brief Frame type. */
- uint8_t cf_IDE:1; /**< @brief Identifier type. */
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
};
union {
struct {
- uint32_t cf_SID:11; /**< @brief Standard identifier.*/
+ uint32_t SID:11; /**< @brief Standard identifier.*/
};
struct {
- uint32_t cf_EID:29; /**< @brief Extended identifier.*/
+ uint32_t EID:29; /**< @brief Extended identifier.*/
};
};
union {
- uint8_t cf_data8[8]; /**< @brief Frame data. */
- uint16_t cf_data16[4]; /**< @brief Frame data. */
- uint32_t cf_data32[2]; /**< @brief Frame data. */
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
};
} CANTxFrame;
@@ -109,22 +110,22 @@ typedef struct {
*/
typedef struct {
struct {
- uint8_t cf_DLC:4; /**< @brief Data length. */
- uint8_t cf_RTR:1; /**< @brief Frame type. */
- uint8_t cf_IDE:1; /**< @brief Identifier type. */
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
};
union {
struct {
- uint32_t cf_SID:11; /**< @brief Standard identifier.*/
+ uint32_t SID:11; /**< @brief Standard identifier.*/
};
struct {
- uint32_t cf_EID:29; /**< @brief Extended identifier.*/
+ uint32_t EID:29; /**< @brief Extended identifier.*/
};
};
union {
- uint8_t cf_data8[8]; /**< @brief Frame data. */
- uint16_t cf_data16[4]; /**< @brief Frame data. */
- uint32_t cf_data32[2]; /**< @brief Frame data. */
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
};
} CANRxFrame;
@@ -155,19 +156,19 @@ typedef struct {
/**
* @brief Driver state.
*/
- canstate_t cd_state;
+ canstate_t state;
/**
* @brief Current configuration data.
*/
- const CANConfig *cd_config;
+ const CANConfig *config;
/**
* @brief Transmission queue semaphore.
*/
- Semaphore cd_txsem;
+ Semaphore txsem;
/**
* @brief Receive queue semaphore.
*/
- Semaphore cd_rxsem;
+ Semaphore rxsem;
/**
* @brief One or more frames become available.
* @note After broadcasting this event it will not be broadcasted again
@@ -177,28 +178,28 @@ typedef struct {
* invoking @p chReceive() when listening to this event. This behavior
* minimizes the interrupt served by the system because CAN traffic.
*/
- EventSource cd_rxfull_event;
+ EventSource rxfull_event;
/**
* @brief One or more transmission slots become available.
*/
- EventSource cd_txempty_event;
+ EventSource txempty_event;
/**
* @brief A CAN bus error happened.
*/
- EventSource cd_error_event;
+ EventSource error_event;
/**
* @brief Error flags set when an error event is broadcasted.
*/
- canstatus_t cd_status;
+ canstatus_t status;
#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
/**
* @brief Entering sleep state event.
*/
- EventSource cd_sleep_event;
+ EventSource sleep_event;
/**
* @brief Exiting sleep state event.
*/
- EventSource cd_wakeup_event;
+ EventSource wakeup_event;
#endif /* CAN_USE_SLEEP_MODE */
/* End of the mandatory fields.*/
} CANDriver;
diff --git a/os/hal/templates/gpt_lld.c b/os/hal/templates/gpt_lld.c
new file mode 100644
index 000000000..1ee010603
--- /dev/null
+++ b/os/hal/templates/gpt_lld.c
@@ -0,0 +1,135 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/gpt_lld.c
+ * @brief GPT Driver subsystem low level driver source template.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint16_t psc;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+
+ }
+ /* Configuration.*/
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ /* Clock de-activation.*/
+
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] period period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period) {
+
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/templates/gpt_lld.h b/os/hal/templates/gpt_lld.h
new file mode 100644
index 000000000..4053c9b7a
--- /dev/null
+++ b/os/hal/templates/gpt_lld.h
@@ -0,0 +1,134 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/gpt_lld.h
+ * @brief GPT Driver subsystem low level driver header template.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint16_t gptcnt_t;
+
+/**
+ * @brief Type of a structure representing a GPT driver.
+ */
+typedef struct GPTDriver GPTDriver;
+
+/**
+ * @brief GPT notification callback type.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+typedef void (*gptcallback_t)(GPTDriver *gptp);
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+#if defined(GPT_DRIVER_EXT_FIELDS)
+ GPT_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/templates/hal_lld.c b/os/hal/templates/hal_lld.c
index c0e561337..aead6dc43 100644
--- a/os/hal/templates/hal_lld.c
+++ b/os/hal/templates/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/hal_lld.h b/os/hal/templates/hal_lld.h
index ad78ba56b..87d150376 100644
--- a/os/hal/templates/hal_lld.h
+++ b/os/hal/templates/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h
index a1840f977..da86f61ed 100644
--- a/os/hal/templates/halconf.h
+++ b/os/hal/templates/halconf.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -55,6 +56,13 @@
#endif
/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
@@ -62,6 +70,13 @@
#endif
/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
@@ -83,6 +98,13 @@
#endif
/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
@@ -90,6 +112,13 @@
#endif
/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB TRUE
+#endif
+
+/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
@@ -103,6 +132,13 @@
#define HAL_USE_UART TRUE
#endif
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB TRUE
+#endif
+
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
@@ -207,6 +243,36 @@
/*===========================================================================*/
/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intevals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
diff --git a/os/hal/templates/i2c_lld.c b/os/hal/templates/i2c_lld.c
index d41f693ab..efd491857 100644
--- a/os/hal/templates/i2c_lld.c
+++ b/os/hal/templates/i2c_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/i2c_lld.h b/os/hal/templates/i2c_lld.h
index ea2b1a61e..a54e99a39 100644
--- a/os/hal/templates/i2c_lld.h
+++ b/os/hal/templates/i2c_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/icu_lld.c b/os/hal/templates/icu_lld.c
new file mode 100644
index 000000000..23596bc97
--- /dev/null
+++ b/os/hal/templates/icu_lld.c
@@ -0,0 +1,145 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/icu_lld.c
+ * @brief ICU Driver subsystem low level driver source template.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ICU driver initialization.
+ *
+ * @notapi
+ */
+void icu_lld_init(void) {
+
+}
+
+/**
+ * @brief Configures and activates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_start(ICUDriver *icup) {
+
+ if (icup->state == ICU_STOP) {
+ /* Clock activation.*/
+ }
+ /* Configuration.*/
+}
+
+/**
+ * @brief Deactivates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_stop(ICUDriver *icup) {
+
+ if (icup->state == ICU_READY) {
+ /* Clock deactivation.*/
+
+ }
+}
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_enable(ICUDriver *icup) {
+
+}
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_disable(ICUDriver *icup) {
+
+}
+
+/**
+ * @brief Returns the width of the latest pulse.
+ * @details The pulse width is defined as number of ticks between the start
+ * edge and the stop edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+icucnt_t icu_lld_get_width(ICUDriver *icup) {
+
+}
+
+/**
+ * @brief Returns the width of the latest cycle.
+ * @details The cycle width is defined as number of ticks between a start
+ * edge and the next start edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+icucnt_t icu_lld_get_period(ICUDriver *icup) {
+
+}
+
+#endif /* HAL_USE_ICU */
+
+/** @} */
diff --git a/os/hal/templates/icu_lld.h b/os/hal/templates/icu_lld.h
new file mode 100644
index 000000000..34549b76e
--- /dev/null
+++ b/os/hal/templates/icu_lld.h
@@ -0,0 +1,138 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/icu_lld.h
+ * @brief ICU Driver subsystem low level driver header template.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#ifndef _ICU_LLD_H_
+#define _ICU_LLD_H_
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ICU driver mode.
+ */
+typedef enum {
+ ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
+ ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
+} icumode_t;
+
+/**
+ * @brief ICU frequency type.
+ */
+typedef uint32_t icufreq_t;
+
+/**
+ * @brief ICU counter type.
+ */
+typedef uint16_t icucnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Driver mode.
+ */
+ icumode_t mode;
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ icufreq_t frequency;
+ /**
+ * @brief Callback for pulse width measurement.
+ */
+ icucallback_t width_cb;
+ /**
+ * @brief Callback for cycle period measurement.
+ */
+ icucallback_t period_cb;
+ /* End of the mandatory fields.*/
+} ICUConfig;
+
+/**
+ * @brief Structure representing an ICU driver.
+ */
+struct ICUDriver {
+ /**
+ * @brief Driver state.
+ */
+ icustate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const ICUConfig *config;
+#if defined(ICU_DRIVER_EXT_FIELDS)
+ ICU_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void icu_lld_init(void);
+ void icu_lld_start(ICUDriver *icup);
+ void icu_lld_stop(ICUDriver *icup);
+ void icu_lld_enable(ICUDriver *icup);
+ void icu_lld_disable(ICUDriver *icup);
+ icucnt_t icu_lld_get_width(ICUDriver *icup);
+ icucnt_t icu_lld_get_period(ICUDriver *icup);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ICU */
+
+#endif /* _ICU_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/templates/mac_lld.c b/os/hal/templates/mac_lld.c
index 8049f29ec..c6cc7825b 100644
--- a/os/hal/templates/mac_lld.c
+++ b/os/hal/templates/mac_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/mac_lld.h b/os/hal/templates/mac_lld.h
index 869fa5db8..e8abe2941 100644
--- a/os/hal/templates/mac_lld.h
+++ b/os/hal/templates/mac_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -73,10 +74,10 @@
* architecture dependent, fields.
*/
typedef struct {
- Semaphore md_tdsem; /**< Transmit semaphore. */
- Semaphore md_rdsem; /**< Receive semaphore. */
+ Semaphore tdsem; /**< Transmit semaphore. */
+ Semaphore rdsem; /**< Receive semaphore. */
#if CH_USE_EVENTS
- EventSource md_rdevent; /**< Receive event source. */
+ EventSource rdevent; /**< Receive event source. */
#endif
/* End of the mandatory fields.*/
} MACDriver;
@@ -87,8 +88,8 @@ typedef struct {
* architecture dependent, fields.
*/
typedef struct {
- size_t td_offset; /**< Current write offset. */
- size_t td_size; /**< Available space size. */
+ size_t offset; /**< Current write offset. */
+ size_t size; /**< Available space size. */
/* End of the mandatory fields.*/
} MACTransmitDescriptor;
@@ -98,8 +99,8 @@ typedef struct {
* architecture dependent, fields.
*/
typedef struct {
- size_t rd_offset; /**< Current read offset. */
- size_t rd_size; /**< Available data size. */
+ size_t offset; /**< Current read offset. */
+ size_t size; /**< Available data size. */
/* End of the mandatory fields.*/
} MACReceiveDescriptor;
diff --git a/os/hal/templates/meta/driver.c b/os/hal/templates/meta/driver.c
index f75c5d380..c12103353 100644
--- a/os/hal/templates/meta/driver.c
+++ b/os/hal/templates/meta/driver.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,8 +68,8 @@ void xxxInit(void) {
*/
void xxxObjectInit(XXXDriver *xxxp) {
- xxxp->xxx_state = XXX_STOP;
- xxxp->xxx_config = NULL;
+ xxxp->state = XXX_STOP;
+ xxxp->config = NULL;
}
/**
@@ -84,12 +85,11 @@ void xxxStart(XXXDriver *xxxp, const XXXConfig *config) {
chDbgCheck((xxxp != NULL) && (config != NULL), "xxxStart");
chSysLock();
- chDbgAssert((xxxp->xxx_state == XXX_STOP) || (xxxp->xxx_state == XXX_READY),
- "xxxStart(), #1",
- "invalid state");
- xxxp->xxx_config = config;
+ chDbgAssert((xxxp->state == XXX_STOP) || (xxxp->state == XXX_READY),
+ "xxxStart(), #1", "invalid state");
+ xxxp->config = config;
xxx_lld_start(xxxp);
- xxxp->xxx_state = XXX_READY;
+ xxxp->state = XXX_READY;
chSysUnlock();
}
@@ -105,11 +105,10 @@ void xxxStop(XXXDriver *xxxp) {
chDbgCheck(xxxp != NULL, "xxxStop");
chSysLock();
- chDbgAssert((xxxp->xxx_state == XXX_STOP) || (xxxp->xxx_state == XXX_READY),
- "xxxStop(), #1",
- "invalid state");
+ chDbgAssert((xxxp->state == XXX_STOP) || (xxxp->state == XXX_READY),
+ "xxxStop(), #1", "invalid state");
xxx_lld_stop(xxxp);
- xxxp->xxx_state = XXX_STOP;
+ xxxp->state = XXX_STOP;
chSysUnlock();
}
diff --git a/os/hal/templates/meta/driver.h b/os/hal/templates/meta/driver.h
index 1014e871c..b4b07170b 100644
--- a/os/hal/templates/meta/driver.h
+++ b/os/hal/templates/meta/driver.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/meta/driver_lld.c b/os/hal/templates/meta/driver_lld.c
index 051dfac03..2cf87bf1f 100644
--- a/os/hal/templates/meta/driver_lld.c
+++ b/os/hal/templates/meta/driver_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -68,7 +69,7 @@ void xxx_lld_init(void) {
*/
void xxx_lld_start(XXXDriver *xxxp) {
- if (xxxp->xxx_state == XXX_STOP) {
+ if (xxxp->state == XXX_STOP) {
/* Clock activation.*/
}
/* Configuration.*/
@@ -83,6 +84,10 @@ void xxx_lld_start(XXXDriver *xxxp) {
*/
void xxx_lld_stop(XXXDriver *xxxp) {
+ if (xxxp->state == XXX_READY) {
+ /* Clock deactivation.*/
+
+ }
}
#endif /* HAL_USE_XXX */
diff --git a/os/hal/templates/meta/driver_lld.h b/os/hal/templates/meta/driver_lld.h
index 7d75bbaea..5af5a4174 100644
--- a/os/hal/templates/meta/driver_lld.h
+++ b/os/hal/templates/meta/driver_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,11 +68,11 @@ struct XXXDriver {
/**
* @brief Driver state.
*/
- xxxstate_t xxx_state;
+ xxxstate_t state;
/**
* @brief Current configuration data.
*/
- const XXXConfig *xxx_config;
+ const XXXConfig *config;
/* End of the mandatory fields.*/
};
diff --git a/os/hal/templates/pal_lld.c b/os/hal/templates/pal_lld.c
index 583b39236..5314ef4b2 100644
--- a/os/hal/templates/pal_lld.c
+++ b/os/hal/templates/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/pal_lld.h b/os/hal/templates/pal_lld.h
index d2e151018..8272b7c30 100644
--- a/os/hal/templates/pal_lld.h
+++ b/os/hal/templates/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/pwm_lld.c b/os/hal/templates/pwm_lld.c
index 7e904765a..67683d120 100644
--- a/os/hal/templates/pwm_lld.c
+++ b/os/hal/templates/pwm_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -68,7 +69,7 @@ void pwm_lld_init(void) {
*/
void pwm_lld_start(PWMDriver *pwmp) {
- if (pwmp->pd_state == PWM_STOP) {
+ if (pwmp->state == PWM_STOP) {
/* Clock activation.*/
}
/* Configuration.*/
@@ -86,23 +87,32 @@ void pwm_lld_stop(PWMDriver *pwmp) {
}
/**
- * @brief Determines whatever the PWM channel is already enabled.
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note The function has effect at the next cycle start.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
*
- * @param[in] pwmp pointer to the @p PWMDriver object
- * @param[in] channel PWM channel identifier
- * @return The PWM channel status.
- * @retval FALSE the channel is not enabled.
- * @retval TRUE the channel is enabled.
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] period new cycle time in ticks
*
* @notapi
*/
-bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel) {
+void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period) {
- return FALSE;
}
/**
* @brief Enables a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -118,11 +128,17 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
/**
* @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
+ *
+ * @notapi
*/
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
diff --git a/os/hal/templates/pwm_lld.h b/os/hal/templates/pwm_lld.h
index 74fb280a7..c34694951 100644
--- a/os/hal/templates/pwm_lld.h
+++ b/os/hal/templates/pwm_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -54,6 +55,11 @@
/*===========================================================================*/
/**
+ * @brief PWM mode type.
+ */
+typedef uint32_t pwmmode_t;
+
+/**
* @brief PWM channel type.
*/
typedef uint8_t pwmchannel_t;
@@ -64,18 +70,6 @@ typedef uint8_t pwmchannel_t;
typedef uint16_t pwmcnt_t;
/**
- * @brief Type of a structure representing an PWM driver.
- */
-typedef struct PWMDriver PWMDriver;
-
-/**
- * @brief PWM notification callback type.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- */
-typedef void (*pwmcallback_t)(PWMDriver *pwmp);
-
-/**
* @brief PWM driver channel configuration structure.
* @note Some architectures may not be able to support the channel mode
* or the callback, in this case the fields are ignored.
@@ -84,13 +78,13 @@ typedef struct {
/**
* @brief Channel active logic level.
*/
- pwmmode_t pcc_mode;
+ pwmmode_t mode;
/**
* @brief Channel callback pointer.
* @note This callback is invoked on the channel compare event. If set to
* @p NULL then the callback is disabled.
*/
- pwmcallback_t pcc_callback;
+ pwmcallback_t callback;
/* End of the mandatory fields.*/
} PWMChannelConfig;
@@ -101,15 +95,27 @@ typedef struct {
*/
typedef struct {
/**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ uint32_t frequency;
+ /**
+ * @brief PWM period in ticks.
+ * @note The low level can use assertions in order to catch invalid
+ * period specifications.
+ */
+ pwmcnt_t period;
+ /**
* @brief Periodic callback pointer.
* @note This callback is invoked on PWM counter reset. If set to
* @p NULL then the callback is disabled.
*/
- pwmcallback_t pc_callback;
+ pwmcallback_t callback;
/**
* @brief Channels configurations.
*/
- PWMChannelConfig pc_channels[PWM_CHANNELS];
+ PWMChannelConfig channels[PWM_CHANNELS];
/* End of the mandatory fields.*/
} PWMConfig;
@@ -122,11 +128,15 @@ struct PWMDriver {
/**
* @brief Driver state.
*/
- pwmstate_t pd_state;
+ pwmstate_t state;
/**
* @brief Current configuration data.
*/
- const PWMConfig *pd_config;
+ const PWMConfig *config;
+ /**
+ * @brief Current PWM period in ticks.
+ */
+ pwmcnt_t period;
#if defined(PWM_DRIVER_EXT_FIELDS)
PWM_DRIVER_EXT_FIELDS
#endif
@@ -137,54 +147,6 @@ struct PWMDriver {
/* Driver macros. */
/*===========================================================================*/
-/**
- * @brief Converts from fraction to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify tenths of thousandth but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] numerator numerator of the fraction
- * @param[in] denominator percentage as an integer between 0 and numerator
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_FRACTION_TO_WIDTH(pwmp, numerator, denominator) 0
-
-/**
- * @brief Converts from degrees to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify hundredths of degrees but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] degrees degrees as an integer between 0 and 36000
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \
- PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees)
-
-/**
- * @brief Converts from percentage to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify tenths of thousandth but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] percentage percentage as an integer between 0 and 10000
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
- PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
-
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -195,7 +157,7 @@ extern "C" {
void pwm_lld_init(void);
void pwm_lld_start(PWMDriver *pwmp);
void pwm_lld_stop(PWMDriver *pwmp);
- bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel);
+ void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period);
void pwm_lld_enable_channel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width);
diff --git a/os/hal/templates/serial_lld.c b/os/hal/templates/serial_lld.c
index 406235767..8fe70f628 100644
--- a/os/hal/templates/serial_lld.c
+++ b/os/hal/templates/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/serial_lld.h b/os/hal/templates/serial_lld.h
index 3c2e8a299..7d570c667 100644
--- a/os/hal/templates/serial_lld.h
+++ b/os/hal/templates/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/spi_lld.c b/os/hal/templates/spi_lld.c
index 5b76e3bdf..c6162d7e0 100644
--- a/os/hal/templates/spi_lld.c
+++ b/os/hal/templates/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -68,7 +69,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
/* Clock activation.*/
}
/* Configuration.*/
diff --git a/os/hal/templates/spi_lld.h b/os/hal/templates/spi_lld.h
index e985aa727..c261bb1d1 100644
--- a/os/hal/templates/spi_lld.h
+++ b/os/hal/templates/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,9 +67,9 @@ typedef void (*spicallback_t)(SPIDriver *spip);
*/
typedef struct {
/**
- * @brief Operation complete callback.
+ * @brief Operation complete callback.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
} SPIConfig;
@@ -81,25 +82,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
- * @brief Waiting thread.
+ * @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
diff --git a/os/hal/templates/uart_lld.c b/os/hal/templates/uart_lld.c
index ab0abeb55..21708858b 100644
--- a/os/hal/templates/uart_lld.c
+++ b/os/hal/templates/uart_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/uart_lld.h b/os/hal/templates/uart_lld.h
index 531e7f3ab..ca55f0108 100644
--- a/os/hal/templates/uart_lld.h
+++ b/os/hal/templates/uart_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -90,23 +91,23 @@ typedef struct {
/**
* @brief End of transmission buffer callback.
*/
- uartcb_t uc_txend1;
+ uartcb_t txend1_cb;
/**
* @brief Physical end of transmission callback.
*/
- uartcb_t uc_txend2;
+ uartcb_t txend2_cb;
/**
* @brief Receive buffer filled callback.
*/
- uartcb_t uc_rxend;
+ uartcb_t rxend_cb;
/**
* @brief Character received while out if the @p UART_RECEIVE state.
*/
- uartccb_t uc_rxchar;
+ uartccb_t rxchar_cb;
/**
* @brief Receive error callback.
*/
- uartecb_t uc_rxerr;
+ uartecb_t rxerr_cb;
/* End of the mandatory fields.*/
} UARTConfig;
@@ -119,19 +120,19 @@ struct UARTDriver {
/**
* @brief Driver state.
*/
- uartstate_t ud_state;
+ uartstate_t state;
/**
* @brief Transmitter state.
*/
- uarttxstate_t ud_txstate;
+ uarttxstate_t txstate;
/**
* @brief Receiver state.
*/
- uartrxstate_t ud_rxstate;
+ uartrxstate_t rxstate;
/**
* @brief Current configuration data.
*/
- const UARTConfig *ud_config;
+ const UARTConfig *config;
#if defined(UART_DRIVER_EXT_FIELDS)
UART_DRIVER_EXT_FIELDS
#endif
diff --git a/os/hal/templates/usb_lld.c b/os/hal/templates/usb_lld.c
new file mode 100644
index 000000000..515fc5443
--- /dev/null
+++ b/os/hal/templates/usb_lld.c
@@ -0,0 +1,346 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/usb_lld.c
+ * @brief USB Driver subsystem low level driver source template.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief EP0 state.
+ * @note It is an union because IN and OUT endpoints are never used at the
+ * same time for EP0.
+ */
+static union {
+ /**
+ * @brief IN EP0 state.
+ */
+ USBInEndpointState in;
+ /**
+ * @brief OUT EP0 state.
+ */
+ USBOutEndpointState out;
+} ep0_state;
+
+/**
+ * @brief EP0 initialization structure.
+ */
+static const USBEndpointConfig ep0config = {
+ USB_EP_MODE_TYPE_CTRL | USB_EP_MODE_TRANSACTION,
+ _usb_ep0in,
+ _usb_ep0out,
+ 0x40,
+ 0x40,
+ &ep0_state.in,
+ &ep0_state.out
+};
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level USB driver initialization.
+ *
+ * @notapi
+ */
+void usb_lld_init(void) {
+
+}
+
+/**
+ * @brief Configures and activates the USB peripheral.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_start(USBDriver *usbp) {
+
+ if (usbp->state == USB_STOP) {
+ /* Clock activation.*/
+
+ /* Reset procedure enforced on driver start.*/
+ _usb_reset(usbp);
+ }
+ /* Configuration.*/
+}
+
+/**
+ * @brief Deactivates the USB peripheral.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_stop(USBDriver *usbp) {
+
+ /* If in ready state then disables the USB clock.*/
+ if (usbp->state == USB_STOP) {
+
+ }
+}
+
+/**
+ * @brief USB low level reset routine.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_reset(USBDriver *usbp) {
+
+ /* Post reset initialization.*/
+
+ /* EP0 initialization.*/
+ usbp->epc[0] = &ep0config;
+ usb_lld_init_endpoint(usbp, 0);
+}
+
+/**
+ * @brief Sets the USB address.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_set_address(USBDriver *usbp) {
+
+}
+
+/**
+ * @brief Enables an endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
+
+}
+
+/**
+ * @brief Disables all the active endpoints except the endpoint zero.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_disable_endpoints(USBDriver *usbp) {
+
+}
+
+/**
+ * @brief Returns the status of an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
+
+}
+
+/**
+ * @brief Returns the status of an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
+
+}
+
+/**
+ * @brief Reads a setup packet from the dedicated packet buffer.
+ * @details This function must be invoked in the context of the @p setup_cb
+ * callback in order to read the received setup packet.
+ * @pre In order to use this function the endpoint must have been
+ * initialized as a control endpoint.
+ * @post The endpoint is ready to accept another packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ *
+ * @notapi
+ */
+void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
+
+}
+
+/**
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to accept another packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The received packet size regardless the specified
+ * @p n parameter.
+ * @retval 0 Zero size packet received.
+ *
+ * @notapi
+ */
+size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+}
+
+/**
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ *
+ * @notapi
+ */
+void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+}
+
+/**
+ * @brief Starts a receive operation on an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the endpoint data
+ * @param[in] n maximum number of bytes to copy in the buffer
+ *
+ * @notapi
+ */
+void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+}
+
+/**
+ * @brief Starts a transmit operation on an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the endpoint data
+ * @param[in] n maximum number of bytes to copy
+ *
+ * @notapi
+ */
+void usb_lld_start_in(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+}
+
+/**
+ * @brief Brings an OUT endpoint in the stalled state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
+
+}
+
+/**
+ * @brief Brings an IN endpoint in the stalled state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
+
+}
+
+/**
+ * @brief Brings an OUT endpoint in the active state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
+
+}
+
+/**
+ * @brief Brings an IN endpoint in the active state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
+
+}
+
+#endif /* HAL_USE_USB */
+
+/** @} */
diff --git a/os/hal/templates/usb_lld.h b/os/hal/templates/usb_lld.h
new file mode 100644
index 000000000..5a41c1c05
--- /dev/null
+++ b/os/hal/templates/usb_lld.h
@@ -0,0 +1,310 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/usb_lld.h
+ * @brief USB Driver subsystem low level driver header template.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#ifndef _USB_LLD_H_
+#define _USB_LLD_H_
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+#include "stm32_usb.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Maximum endpoint address.
+ */
+#define USB_MAX_ENDPOINTS 4
+
+/**
+ * @brief This device requires the address change after the status packet.
+ */
+#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of an IN endpoint state structure.
+ */
+typedef struct {
+
+} USBInEndpointState;
+
+/**
+ * @brief Type of an OUT endpoint state structure.
+ */
+typedef struct {
+
+} USBOutEndpointState;
+
+/**
+ * @brief Type of an USB endpoint configuration structure.
+ * @note Platform specific restrictions may apply to endpoints.
+ */
+typedef struct {
+ /**
+ * @brief Type and mode of the endpoint.
+ */
+ uint32_t ep_mode;
+ /**
+ * @brief IN endpoint notification callback.
+ * @details This field must be set to @p NULL if the IN endpoint is not
+ * used.
+ */
+ usbepcallback_t in_cb;
+ /**
+ * @brief OUT endpoint notification callback.
+ * @details This field must be set to @p NULL if the OUT endpoint is not
+ * used.
+ */
+ usbepcallback_t out_cb;
+ /**
+ * @brief IN endpoint maximum packet size.
+ * @details This field must be set to zero if the IN endpoint is not
+ * used.
+ */
+ uint16_t in_maxsize;
+ /**
+ * @brief OUT endpoint maximum packet size.
+ * @details This field must be set to zero if the OUT endpoint is not
+ * used.
+ */
+ uint16_t out_maxsize;
+ /**
+ * @brief @p USBEndpointState associated to the IN endpoint.
+ * @details This structure maintains the state of the IN endpoint when
+ * the endpoint is not in packet mode. Endpoints configured in
+ * packet mode must set this field to @p NULL.
+ */
+ USBInEndpointState *in_state;
+ /**
+ * @brief @p USBEndpointState associated to the OUT endpoint.
+ * @details This structure maintains the state of the OUT endpoint when
+ * the endpoint is not in packet mode. Endpoints configured in
+ * packet mode must set this field to @p NULL.
+ */
+ USBOutEndpointState *out_state;
+ /* End of the mandatory fields.*/
+} USBEndpointConfig;
+
+/**
+ * @brief Type of an USB driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief USB events callback.
+ * @details This callback is invoked when an USB driver event is registered.
+ */
+ usbeventcb_t event_cb;
+ /**
+ * @brief Device GET_DESCRIPTOR request callback.
+ * @note This callback is mandatory and cannot be set to @p NULL.
+ */
+ usbgetdescriptor_t get_descriptor_cb;
+ /**
+ * @brief Requests hook callback.
+ * @details This hook allows to be notified of standard requests or to
+ * handle non standard requests.
+ */
+ usbreqhandler_t requests_hook_cb;
+ /**
+ * @brief Start Of Frame callback.
+ */
+ usbcallback_t sof_cb;
+ /* End of the mandatory fields.*/
+} USBConfig;
+
+/**
+ * @brief Structure representing an USB driver.
+ */
+struct USBDriver {
+ /**
+ * @brief Driver state.
+ */
+ usbstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const USBConfig *config;
+ /**
+ * @brief Field available to user, it can be used to associate an
+ * application-defined handler to the USB driver.
+ */
+ void *param;
+ /**
+ * @brief Bit map of the transmitting IN endpoints.
+ */
+ uint16_t transmitting;
+ /**
+ * @brief Bit map of the receiving OUT endpoints.
+ */
+ uint16_t receiving;
+ /**
+ * @brief Active endpoints configurations.
+ */
+ const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
+ /**
+ * @brief Endpoint 0 state.
+ */
+ usbep0state_t ep0state;
+ /**
+ * @brief Next position in the buffer to be transferred through endpoint 0.
+ */
+ uint8_t *ep0next;
+ /**
+ * @brief Number of bytes yet to be transferred through endpoint 0.
+ */
+ size_t ep0n;
+ /**
+ * @brief Endpoint 0 end transaction callback.
+ */
+ usbcallback_t ep0endcb;
+ /**
+ * @brief Setup packet buffer.
+ */
+ uint8_t setup[8];
+ /**
+ * @brief Current USB device status.
+ */
+ uint16_t status;
+ /**
+ * @brief Assigned USB address.
+ */
+ uint8_t address;
+ /**
+ * @brief Current USB device configuration.
+ */
+ uint8_t configuration;
+#if defined(USB_DRIVER_EXT_FIELDS)
+ USB_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Fetches a 16 bits word value from an USB message.
+ *
+ * @param[in] p pointer to the 16 bits word
+ *
+ * @notapi
+ */
+#define usb_lld_fetch_word(p) (*(uint16_t *)(p))
+
+/**
+ * @brief Returns the current frame number.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @return The current frame number.
+ *
+ * @notapi
+ */
+#define usb_lld_get_frame_number(usbp)
+
+/**
+ * @brief Returns the exact size of a receive transaction.
+ * @details The received size can be different from the size specified in
+ * @p usbStartReceiveI() because the last packet could have a size
+ * different from the expected one.
+ * @pre The OUT endpoint must have been configured in transaction mode
+ * in order to use this function.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return Received data size.
+ *
+ * @notapi
+ */
+#define usb_lld_get_transaction_size(usbp, ep)
+
+/**
+ * @brief Returns the exact size of a received packet.
+ * @pre The OUT endpoint must have been configured in packet mode
+ * in order to use this function.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return Received data size.
+ *
+ * @notapi
+ */
+#define usb_lld_get_packet_size(usbp, ep)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void usb_lld_init(void);
+ void usb_lld_start(USBDriver *usbp);
+ void usb_lld_stop(USBDriver *usbp);
+ void usb_lld_reset(USBDriver *usbp);
+ void usb_lld_set_address(USBDriver *usbp);
+ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
+ void usb_lld_disable_endpoints(USBDriver *usbp);
+ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
+ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
+ size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_start_in(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
+ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_USB */
+
+#endif /* _USB_LLD_H_ */
+
+/** @} */
diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h
index 3bd81e16b..250f6adbf 100644
--- a/os/kernel/include/ch.h
+++ b/os/kernel/include/ch.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -39,7 +40,7 @@
/**
* @brief Kernel version string.
*/
-#define CH_KERNEL_VERSION "2.3.0unstable"
+#define CH_KERNEL_VERSION "2.3.4unstable"
/**
* @brief Kernel version major number.
@@ -54,7 +55,7 @@
/**
* @brief Kernel version patch number.
*/
-#define CH_KERNEL_PATCH 0
+#define CH_KERNEL_PATCH 4
/*
* Common values.
@@ -94,7 +95,7 @@
#include "chdebug.h"
#if !defined(__DOXYGEN__)
-extern WORKING_AREA(_idle_thread_wa, IDLE_THREAD_STACK_SIZE);
+extern WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE);
#endif
#ifdef __cplusplus
diff --git a/os/kernel/include/chbsem.h b/os/kernel/include/chbsem.h
index e60886bcd..e0e1ca865 100644
--- a/os/kernel/include/chbsem.h
+++ b/os/kernel/include/chbsem.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -70,7 +71,7 @@ typedef struct {
* @param[in] taken the semaphore initial state
*/
#define _BSEMAPHORE_DATA(name, taken) \
- {_SEMAPHORE_DATA(name.bs_sem), ((taken) ? 0 : 1)}
+ {_SEMAPHORE_DATA(name.bs_sem, ((taken) ? 0 : 1))}
/**
* @brief Static semaphore initializer.
diff --git a/os/kernel/include/chcond.h b/os/kernel/include/chcond.h
index 5a03ddd7f..072ae40ab 100644
--- a/os/kernel/include/chcond.h
+++ b/os/kernel/include/chcond.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chdebug.h b/os/kernel/include/chdebug.h
index e29b095e8..471da5532 100644
--- a/os/kernel/include/chdebug.h
+++ b/os/kernel/include/chdebug.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -150,7 +151,7 @@ extern "C" {
#endif
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
extern TraceBuffer trace_buffer;
- void trace_init(void);
+ void _trace_init(void);
void chDbgTrace(Thread *otp);
#endif
#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
diff --git a/os/kernel/include/chdynamic.h b/os/kernel/include/chdynamic.h
index 76de4ae09..790725493 100644
--- a/os/kernel/include/chdynamic.h
+++ b/os/kernel/include/chdynamic.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chevents.h b/os/kernel/include/chevents.h
index 6a1cd6106..e808caec3 100644
--- a/os/kernel/include/chevents.h
+++ b/os/kernel/include/chevents.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -56,6 +57,11 @@ typedef struct EventSource {
} EventSource;
/**
+ * @brief Event Handler callback function.
+ */
+typedef void (*evhandler_t)(eventid_t);
+
+/**
* @brief Data part of a static event source initializer.
* @details This macro should be used when statically initializing an event
* source that is part of a bigger structure.
@@ -119,9 +125,28 @@ typedef struct EventSource {
((void *)(esp) != (void *)(esp)->es_next)
/**
- * @brief Event Handler callback function.
+ * @brief Signals all the Event Listeners registered on the specified Event
+ * Source.
+ *
+ * @param[in] esp pointer to the @p EventSource structure
+ *
+ * @api
*/
-typedef void (*evhandler_t)(eventid_t);
+#define chEvtBroadcast(esp) chEvtBroadcastFlags(esp, 0)
+
+/**
+ * @brief Signals all the Event Listeners registered on the specified Event
+ * Source.
+ * @post This function does not reschedule so a call to a rescheduling
+ * function must be performed before unlocking the kernel. Note that
+ * interrupt handlers always reschedule on exit so an explicit
+ * reschedule must not be performed in ISRs.
+ *
+ * @param[in] esp pointer to the @p EventSource structure
+ *
+ * @iclass
+ */
+#define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0)
#ifdef __cplusplus
extern "C" {
@@ -132,10 +157,10 @@ extern "C" {
void chEvtUnregister(EventSource *esp, EventListener *elp);
eventmask_t chEvtClearFlags(eventmask_t mask);
eventmask_t chEvtAddFlags(eventmask_t mask);
- void chEvtSignal(Thread *tp, eventmask_t mask);
- void chEvtSignalI(Thread *tp, eventmask_t mask);
- void chEvtBroadcast(EventSource *esp);
- void chEvtBroadcastI(EventSource *esp);
+ void chEvtSignalFlags(Thread *tp, eventmask_t mask);
+ void chEvtSignalFlagsI(Thread *tp, eventmask_t mask);
+ void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask);
+ void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask);
void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask);
#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT
eventmask_t chEvtWaitOne(eventmask_t mask);
diff --git a/os/kernel/include/chfiles.h b/os/kernel/include/chfiles.h
index dbe5e0567..ff3f8274e 100644
--- a/os/kernel/include/chfiles.h
+++ b/os/kernel/include/chfiles.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chheap.h b/os/kernel/include/chheap.h
index 1c5ec5419..0db1cbc1d 100644
--- a/os/kernel/include/chheap.h
+++ b/os/kernel/include/chheap.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -74,8 +75,10 @@ struct memory_heap {
#ifdef __cplusplus
extern "C" {
#endif
- void heap_init(void);
+ void _heap_init(void);
+#if !CH_USE_MALLOC_HEAP
void chHeapInit(MemoryHeap *heapp, void *buf, size_t size);
+#endif
void *chHeapAlloc(MemoryHeap *heapp, size_t size);
void chHeapFree(void *p);
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep);
diff --git a/os/kernel/include/chinline.h b/os/kernel/include/chinline.h
index f41c12cc2..d3ae4b7a4 100644
--- a/os/kernel/include/chinline.h
+++ b/os/kernel/include/chinline.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chioch.h b/os/kernel/include/chioch.h
index f5741fcec..02757c7e9 100644
--- a/os/kernel/include/chioch.h
+++ b/os/kernel/include/chioch.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chlists.h b/os/kernel/include/chlists.h
index a93ccedb4..4df139722 100644
--- a/os/kernel/include/chlists.h
+++ b/os/kernel/include/chlists.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chmboxes.h b/os/kernel/include/chmboxes.h
index ce3f238be..4a1706302 100644
--- a/os/kernel/include/chmboxes.h
+++ b/os/kernel/include/chmboxes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -60,10 +61,13 @@ extern "C" {
void chMBReset(Mailbox *mbp);
msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout);
msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t timeout);
+ msg_t chMBPostI(Mailbox *mbp, msg_t msg);
msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout);
msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t timeout);
+ msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg);
msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout);
msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t timeout);
+ msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp);
#ifdef __cplusplus
}
#endif
diff --git a/os/kernel/include/chmemcore.h b/os/kernel/include/chmemcore.h
index f42478125..cf608c4e8 100644
--- a/os/kernel/include/chmemcore.h
+++ b/os/kernel/include/chmemcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -36,14 +37,24 @@
typedef void *(*memgetfunc_t)(size_t size);
/**
+ * @brief Alignment size constant.
+ */
+#define MEM_ALIGN_SIZE sizeof(stkalign_t)
+
+/**
* @brief Alignment mask constant.
*/
-#define MEM_ALIGN_MASK (sizeof(stkalign_t) - 1)
+#define MEM_ALIGN_MASK (MEM_ALIGN_SIZE - 1)
+
+/**
+ * @brief Alignment helper macro.
+ */
+#define MEM_ALIGN_PREV(p) ((size_t)(p) & ~MEM_ALIGN_MASK)
/**
* @brief Alignment helper macro.
*/
-#define MEM_ALIGN_SIZE(p) (((size_t)(p) + MEM_ALIGN_MASK) & ~MEM_ALIGN_MASK)
+#define MEM_ALIGN_NEXT(p) MEM_ALIGN_PREV((size_t)(p) + MEM_ALIGN_MASK)
/**
* @brief Returns whatever a pointer or memory size is aligned to
@@ -56,7 +67,7 @@ typedef void *(*memgetfunc_t)(size_t size);
#ifdef __cplusplus
extern "C" {
#endif
- void core_init(void);
+ void _core_init(void);
void *chCoreAlloc(size_t size);
void *chCoreAllocI(size_t size);
size_t chCoreStatus(void);
diff --git a/os/kernel/include/chmempools.h b/os/kernel/include/chmempools.h
index 1c2e2aa70..c53e17473 100644
--- a/os/kernel/include/chmempools.h
+++ b/os/kernel/include/chmempools.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -59,7 +60,7 @@ typedef struct {
* @param[in] provider memory provider function for the memory pool
*/
#define _MEMORYPOOL_DATA(name, size, provider) \
- {NULL, MEM_ALIGN_SIZE(size), provider}
+ {NULL, MEM_ALIGN_NEXT(size), provider}
/**
* @brief Static memory pool initializer in hungry mode.
diff --git a/os/kernel/include/chmsg.h b/os/kernel/include/chmsg.h
index 438da021f..1803c719d 100644
--- a/os/kernel/include/chmsg.h
+++ b/os/kernel/include/chmsg.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -39,20 +40,47 @@
((tp)->p_msgqueue.p_next != (Thread *)&(tp)->p_msgqueue)
/**
- * @brief Returns the first message in the queue.
+ * @brief Returns the message carried by the specified thread.
+ * @pre This function must be invoked immediately after exiting a call
+ * to @p chMsgWait().
*
- * @iclass
+ * @param[in] tp pointer to the thread
+ * @return The message carried by the sender.
+ *
+ * @api
+ */
+#define chMsgGet(tp) ((tp)->p_msg)
+
+/**
+ * @brief Returns the message carried by the specified thread.
+ * @pre This function must be invoked immediately after exiting a call
+ * to @p chMsgWait().
+ *
+ * @param[in] tp pointer to the thread
+ * @return The message carried by the sender.
+ *
+ * @sclass
+ */
+#define chMsgGetS(tp) ((tp)->p_msg)
+
+/**
+ * @brief Releases the thread waiting on top of the messages queue.
+ * @pre Invoke this function only after a message has been received
+ * using @p chMsgWait().
+ *
+ * @param[in] tp pointer to the thread
+ * @param[in] msg message to be returned to the sender
+ *
+ * @sclass
*/
-#define chMsgGetI(tp) \
- ((tp)->p_msgqueue.p_next->p_msg)
+#define chMsgReleaseS(tp, msg) chSchWakeupS(tp, msg)
#ifdef __cplusplus
extern "C" {
#endif
msg_t chMsgSend(Thread *tp, msg_t msg);
- msg_t chMsgWait(void);
- msg_t chMsgGet(void);
- void chMsgRelease(msg_t msg);
+ Thread * chMsgWait(void);
+ void chMsgRelease(Thread *tp, msg_t msg);
#ifdef __cplusplus
}
#endif
diff --git a/os/kernel/include/chmtx.h b/os/kernel/include/chmtx.h
index cb0e78001..9f2d5a0d3 100644
--- a/os/kernel/include/chmtx.h
+++ b/os/kernel/include/chmtx.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chqueues.h b/os/kernel/include/chqueues.h
index 1913e8bdd..a2df59dad 100644
--- a/os/kernel/include/chqueues.h
+++ b/os/kernel/include/chqueues.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -30,18 +31,11 @@
#if CH_USE_QUEUES || defined(__DOXYGEN__)
-/*
- * Module dependencies check.
- */
-#if !CH_USE_SEMAPHORES
-#error "CH_USE_QUEUES requires CH_USE_SEMAPHORES"
-#endif
-
/** @brief Returned by the queue functions if the operation is successful.*/
#define Q_OK RDY_OK
/** @brief Returned by the queue functions if a timeout occurs.*/
#define Q_TIMEOUT RDY_TIMEOUT
-/** @brief Returned by the queue functions if the queue is reset.*/
+/** @brief Returned by the queue functions if the queue has been reset.*/
#define Q_RESET RDY_RESET
/** @brief Returned by the queue functions if the queue is empty.*/
#define Q_EMPTY -3
@@ -66,12 +60,13 @@ typedef void (*qnotify_t)(GenericQueue *qp);
* @ref system_states) and is non-blocking.
*/
struct GenericQueue {
+ ThreadsQueue q_waiting; /**< @brief Queue of waiting threads. */
+ size_t q_counter; /**< @brief Resources counter. */
uint8_t *q_buffer; /**< @brief Pointer to the queue buffer.*/
uint8_t *q_top; /**< @brief Pointer to the first location
after the buffer. */
uint8_t *q_wrptr; /**< @brief Write pointer. */
uint8_t *q_rdptr; /**< @brief Read pointer. */
- Semaphore q_sem; /**< @brief Counter @p Semaphore. */
qnotify_t q_notify; /**< @brief Data notification callback. */
};
@@ -83,21 +78,19 @@ struct GenericQueue {
*
* @iclass
*/
-#define chQSizeI(qp) ((qp)->q_top - (qp)->q_buffer)
+#define chQSizeI(qp) ((size_t)((qp)->q_top - (qp)->q_buffer))
/**
* @brief Queue space.
* @details Returns the used space if used on an input queue or the empty
* space if used on an output queue.
- * @note The returned value can be less than zero when there are waiting
- * threads on the internal semaphore.
*
* @param[in] qp pointer to a @p GenericQueue structure.
* @return The buffer space.
*
* @iclass
*/
-#define chQSpaceI(qp) chSemGetCounterI(&(qp)->q_sem)
+#define chQSpaceI(qp) ((size_t)((qp)->q_counter))
/**
* @extends GenericQueue
@@ -113,6 +106,28 @@ struct GenericQueue {
typedef GenericQueue InputQueue;
/**
+ * @brief Returns the filled space into an input queue.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @return The number of full bytes in the queue.
+ * @retval 0 if the queue is empty.
+ *
+ * @iclass
+ */
+#define chIQGetFullI(iqp) chQSpaceI(iqp)
+
+/**
+ * @brief Returns the empty space into an input queue.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @return The number of empty bytes in the queue.
+ * @retval 0 if the queue is full.
+ *
+ * @iclass
+ */
+#define chIQGetEmptyI(iqp) (chQSizeI(iqp) - chQSpaceI(iqp))
+
+/**
* @brief Evaluates to @p TRUE if the specified input queue is empty.
*
* @param[in] iqp pointer to an @p InputQueue structure.
@@ -134,7 +149,8 @@ typedef GenericQueue InputQueue;
*
* @iclass
*/
-#define chIQIsFullI(iqp) ((bool_t)(chQSpaceI(iqp) >= chQSizeI(iqp)))
+#define chIQIsFullI(iqp) ((bool_t)(((iqp)->q_wrptr == (iqp)->q_rdptr) && \
+ ((iqp)->q_counter != 0)))
/**
* @brief Input queue read.
@@ -144,7 +160,7 @@ typedef GenericQueue InputQueue;
*
* @param[in] iqp pointer to an @p InputQueue structure
* @return A byte value from the queue.
- * @retval Q_RESET If the queue has been reset.
+ * @retval Q_RESET if the queue has been reset.
*
* @api
*/
@@ -160,13 +176,14 @@ typedef GenericQueue InputQueue;
* @param[in] size size of the queue buffer area
* @param[in] inotify input notification callback pointer
*/
-#define _INPUTQUEUE_DATA(name, buffer, size, inotify) { \
- (uint8_t *)(buffer), \
- (uint8_t *)(buffer) + size, \
- (uint8_t *)(buffer), \
- (uint8_t *)(buffer), \
- _SEMAPHORE_DATA(name.q_sem, 0), \
- inotify \
+#define _INPUTQUEUE_DATA(name, buffer, size, inotify) { \
+ _THREADSQUEUE_DATA(name), \
+ 0, \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer) + (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer), \
+ inotify \
}
/**
@@ -195,6 +212,28 @@ typedef GenericQueue InputQueue;
*/
typedef GenericQueue OutputQueue;
+ /**
+ * @brief Returns the filled space into an output queue.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ * @return The number of full bytes in the queue.
+ * @retval 0 if the queue is empty.
+ *
+ * @iclass
+ */
+#define chOQGetFullI(oqp) (chQSizeI(oqp) - chQSpaceI(oqp))
+
+/**
+ * @brief Returns the empty space into an output queue.
+ *
+ * @param[in] iqp pointer to an @p OutputQueue structure
+ * @return The number of empty bytes in the queue.
+ * @retval 0 if the queue is full.
+ *
+ * @iclass
+ */
+#define chOQGetEmptyI(iqp) chQSpaceI(oqp)
+
/**
* @brief Evaluates to @p TRUE if the specified output queue is empty.
*
@@ -205,7 +244,8 @@ typedef GenericQueue OutputQueue;
*
* @iclass
*/
-#define chOQIsEmptyI(oqp) ((bool_t)(chQSpaceI(oqp) >= chQSizeI(oqp)))
+#define chOQIsEmptyI(oqp) ((bool_t)(((oqp)->q_wrptr == (oqp)->q_rdptr) && \
+ ((oqp)->q_counter != 0)))
/**
* @brief Evaluates to @p TRUE if the specified output queue is full.
@@ -245,13 +285,14 @@ typedef GenericQueue OutputQueue;
* @param[in] size size of the queue buffer area
* @param[in] onotify output notification callback pointer
*/
-#define _OUTPUTQUEUE_DATA(name, buffer, size, onotify) { \
- (uint8_t *)(buffer), \
- (uint8_t *)(buffer) + size, \
- (uint8_t *)(buffer), \
- (uint8_t *)(buffer), \
- _SEMAPHORE_DATA(name.q_sem, size), \
- onotify \
+#define _OUTPUTQUEUE_DATA(name, buffer, size, onotify) { \
+ _THREADSQUEUE_DATA(name), \
+ (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer) + (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer), \
+ onotify \
}
/**
@@ -271,7 +312,6 @@ typedef GenericQueue OutputQueue;
extern "C" {
#endif
void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy);
- size_t chIQGetFullI(InputQueue *iqp);
void chIQResetI(InputQueue *iqp);
msg_t chIQPutI(InputQueue *iqp, uint8_t b);
msg_t chIQGetTimeout(InputQueue *iqp, systime_t time);
@@ -279,7 +319,6 @@ extern "C" {
size_t n, systime_t time);
void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy);
- size_t chOQGetFullI(OutputQueue *oqp);
void chOQResetI(OutputQueue *oqp);
msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time);
msg_t chOQGetI(OutputQueue *oqp);
diff --git a/os/kernel/include/chregistry.h b/os/kernel/include/chregistry.h
index f9185acb7..3e9cc5508 100644
--- a/os/kernel/include/chregistry.h
+++ b/os/kernel/include/chregistry.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chschd.h b/os/kernel/include/chschd.h
index a9283c290..e154da863 100644
--- a/os/kernel/include/chschd.h
+++ b/os/kernel/include/chschd.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -48,13 +49,13 @@
* @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
* see the specific function documentation.
*/
-#define TIME_IMMEDIATE ((systime_t)-1)
+#define TIME_IMMEDIATE ((systime_t)0)
/**
* @brief Infinite time specification for all the syscalls with a timeout
* specification.
*/
-#define TIME_INFINITE ((systime_t)0)
+#define TIME_INFINITE ((systime_t)-1)
/**
* @brief Returns the priority of the first thread on the given ready list.
@@ -83,10 +84,8 @@ typedef struct {
#if CH_TIME_QUANTUM > 0
cnt_t r_preempt; /**< @brief Round robin counter. */
#endif
-#ifndef CH_CURRP_REGISTER_CACHE
Thread *r_current; /**< @brief The currently running
thread. */
-#endif
} ReadyList;
#endif /* !defined(PORT_OPTIMIZED_READYLIST_STRUCT) */
@@ -102,11 +101,7 @@ extern ReadyList rlist;
* (currp = something), use @p setcurrp() instead.
*/
#if !defined(PORT_OPTIMIZED_CURRP) || defined(__DOXYGEN__)
-#if !defined(CH_CURRP_REGISTER_CACHE) || defined(__DOXYGEN__)
#define currp rlist.r_current
-#else /* defined(CH_CURRP_REGISTER_CACHE) */
-register Thread *currp asm(CH_CURRP_REGISTER_CACHE);
-#endif /* defined(CH_CURRP_REGISTER_CACHE) */
#endif /* !defined(PORT_OPTIMIZED_CURRP) */
/**
@@ -126,7 +121,7 @@ register Thread *currp asm(CH_CURRP_REGISTER_CACHE);
#ifdef __cplusplus
extern "C" {
#endif
- void scheduler_init(void);
+ void _scheduler_init(void);
#if !defined(PORT_OPTIMIZED_READYI)
Thread *chSchReadyI(Thread *tp);
#endif
diff --git a/os/kernel/include/chsem.h b/os/kernel/include/chsem.h
index efed15189..04e079466 100644
--- a/os/kernel/include/chsem.h
+++ b/os/kernel/include/chsem.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -51,7 +52,7 @@ extern "C" {
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time);
void chSemSignal(Semaphore *sp);
void chSemSignalI(Semaphore *sp);
- void chSemSetCounterI(Semaphore *sp, cnt_t n);
+ void chSemAddCounterI(Semaphore *sp, cnt_t n);
#if CH_USE_SEMSW
msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw);
#endif
diff --git a/os/kernel/include/chstreams.h b/os/kernel/include/chstreams.h
index 7d85aa186..0bd763366 100644
--- a/os/kernel/include/chstreams.h
+++ b/os/kernel/include/chstreams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/include/chsys.h b/os/kernel/include/chsys.h
index 944aedc02..37d4cd7ce 100644
--- a/os/kernel/include/chsys.h
+++ b/os/kernel/include/chsys.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -28,8 +29,11 @@
#ifndef _CHSYS_H_
#define _CHSYS_H_
+#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
/**
* @brief Returns a pointer to the idle thread.
+ * @pre In order to use this function the option @p CH_NO_IDLE_THREAD
+ * must be disabled.
* @note The reference counter of the idle thread is not incremented but
* it is not strictly required being the idle thread a static
* object.
@@ -39,6 +43,7 @@
* @api
*/
#define chSysGetIdleThread() ((Thread *)_idle_thread_wa)
+#endif
/**
* @brief Halts the system.
diff --git a/os/kernel/include/chthreads.h b/os/kernel/include/chthreads.h
index 677f0be58..215bb9920 100644
--- a/os/kernel/include/chthreads.h
+++ b/os/kernel/include/chthreads.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -176,12 +177,16 @@ struct Thread {
#define THD_STATE_WTOREVT 8
/** @brief Thread state: Waiting in @p chEvtWaitAllTimeout().*/
#define THD_STATE_WTANDEVT 9
-/** @brief Thread state: Waiting in @p chMsgSend().*/
-#define THD_STATE_SNDMSG 10
+/** @brief Thread state: Waiting in @p chMsgSend() (queued).*/
+#define THD_STATE_SNDMSGQ 10
+/** @brief Thread state: Waiting in @p chMsgSend() (not queued).*/
+#define THD_STATE_SNDMSG 11
/** @brief Thread state: Waiting in @p chMsgWait().*/
-#define THD_STATE_WTMSG 11
+#define THD_STATE_WTMSG 12
+/** @brief Thread state: Waiting on an I/O queue.*/
+#define THD_STATE_WTQUEUE 13
/** @brief Thread state: After termination.*/
-#define THD_STATE_FINAL 12
+#define THD_STATE_FINAL 14
/*
* Various flags into the thread p_flags field.
@@ -242,7 +247,7 @@ extern "C" {
* @note This function is only available when the
* @p CH_DBG_THREADS_PROFILING configuration option is enabled.
*
- * @param[in] tp the pointer to the thread
+ * @param[in] tp pointer to the thread
*
* @api
*/
@@ -258,7 +263,7 @@ extern "C" {
/**
* @brief Verifies if the specified thread is in the @p THD_STATE_FINAL state.
*
- * @param[in] tp the pointer to the thread
+ * @param[in] tp pointer to the thread
* @retval TRUE thread terminated.
* @retval FALSE thread not terminated.
*
@@ -279,7 +284,7 @@ extern "C" {
/**
* @brief Resumes a thread created with @p chThdInit().
*
- * @param[in] tp the pointer to the thread
+ * @param[in] tp pointer to the thread
*
* @iclass
*/
@@ -292,9 +297,7 @@ extern "C" {
* handled as follow:
* - @a TIME_INFINITE the thread enters an infinite sleep
* state.
- * - @a TIME_IMMEDIATE this value is accepted but
- * interpreted as a normal time specification not as
- * an immediate timeout specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
* .
*
* @sclass
@@ -307,7 +310,7 @@ extern "C" {
* system clock.
* @note The maximum specified value is implementation dependent.
*
- * @param[in] sec the time in seconds
+ * @param[in] sec time in seconds
*
* @api
*/
@@ -320,7 +323,7 @@ extern "C" {
* system clock.
* @note The maximum specified value is implementation dependent.
*
- * @param[in] msec the time in milliseconds
+ * @param[in] msec time in milliseconds
*
* @api
*/
@@ -333,7 +336,7 @@ extern "C" {
* system clock.
* @note The maximum specified value is implementation dependent.
*
- * @param[in] usec the time in microseconds
+ * @param[in] usec time in microseconds
*
* @api
*/
diff --git a/os/kernel/include/chvt.h b/os/kernel/include/chvt.h
index a7667b92c..e75e966d5 100644
--- a/os/kernel/include/chvt.h
+++ b/os/kernel/include/chvt.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -120,7 +121,7 @@ extern VTList vtlist;
#ifdef __cplusplus
extern "C" {
#endif
- void vt_init(void);
+ void _vt_init(void);
void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par);
void chVTResetI(VirtualTimer *vtp);
bool_t chTimeIsWithin(systime_t start, systime_t end);
diff --git a/os/kernel/kernel.dox b/os/kernel/kernel.dox
index 2a9278620..b1fc4bc29 100644
--- a/os/kernel/kernel.dox
+++ b/os/kernel/kernel.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -174,4 +175,4 @@
* @defgroup internals Internals
* @ingroup kernel
*/
- \ No newline at end of file
+
diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c
index 0ad9d459d..456fc454f 100644
--- a/os/kernel/src/chcond.c
+++ b/os/kernel/src/chcond.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -203,11 +204,11 @@ msg_t chCondWaitS(CondVar *cp) {
* mutex, the mutex ownership is lost.
*
* @param[in] cp pointer to the @p CondVar structure
- * @param[in] time the number of ticks before the operation timeouts,
- * the special value @p TIME_INFINITE is allowed.
- * It is not possible to specify zero @p TIME_IMMEDIATE
- * as timeout specification because it would make no sense
- * in this function.
+ * @param[in] time the number of ticks before the operation timeouts, the
+ * special values are handled as follow:
+ * - @a TIME_INFINITE no timeout.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
* @return A message specifying how the invoking thread has been
* released from the condition variable.
* @retval RDY_OK if the condvar has been signaled using
@@ -240,11 +241,11 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
* mutex, the mutex ownership is lost.
*
* @param[in] cp pointer to the @p CondVar structure
- * @param[in] time the number of ticks before the operation timeouts,
- * the special value @p TIME_INFINITE is allowed.
- * It is not possible to specify zero @p TIME_IMMEDIATE
- * as timeout specification because it would make no sense
- * in this function.
+ * @param[in] time the number of ticks before the operation timeouts, the
+ * special values are handled as follow:
+ * - @a TIME_INFINITE no timeout.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
* @return A message specifying how the invoking thread has been
* released from the condition variable.
* @retval RDY_OK if the condvar has been signaled using
@@ -260,7 +261,7 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) {
Mutex *mp;
msg_t msg;
- chDbgCheck(cp != NULL, "chCondWaitTimeoutS");
+ chDbgCheck((cp != NULL) && (time != TIME_IMMEDIATE), "chCondWaitTimeoutS");
chDbgAssert(currp->p_mtxlist != NULL,
"chCondWaitTimeoutS(), #1",
"not owning a mutex");
diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c
index 80323e183..3c3c34c70 100644
--- a/os/kernel/src/chdebug.c
+++ b/os/kernel/src/chdebug.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -45,7 +46,7 @@ TraceBuffer trace_buffer;
* @brief Trace circular buffer subsystem initialization.
* @note Internal use only.
*/
-void trace_init(void) {
+void _trace_init(void) {
trace_buffer.tb_size = TRACE_BUFFER_SIZE;
trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0];
diff --git a/os/kernel/src/chdynamic.c b/os/kernel/src/chdynamic.c
index 5f1fc3401..acd23c244 100644
--- a/os/kernel/src/chdynamic.c
+++ b/os/kernel/src/chdynamic.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c
index a0ef2d1bb..d74ad2dc4 100644
--- a/os/kernel/src/chevents.c
+++ b/os/kernel/src/chevents.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -160,12 +161,12 @@ eventmask_t chEvtAddFlags(eventmask_t mask) {
*
* @api
*/
-void chEvtSignal(Thread *tp, eventmask_t mask) {
+void chEvtSignalFlags(Thread *tp, eventmask_t mask) {
chDbgCheck(tp != NULL, "chEvtSignal");
chSysLock();
- chEvtSignalI(tp, mask);
+ chEvtSignalFlagsI(tp, mask);
chSchRescheduleS();
chSysUnlock();
}
@@ -182,7 +183,7 @@ void chEvtSignal(Thread *tp, eventmask_t mask) {
*
* @iclass
*/
-void chEvtSignalI(Thread *tp, eventmask_t mask) {
+void chEvtSignalFlagsI(Thread *tp, eventmask_t mask) {
chDbgCheck(tp != NULL, "chEvtSignalI");
@@ -198,15 +199,20 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) {
/**
* @brief Signals all the Event Listeners registered on the specified Event
* Source.
+ * @details This function variants ORs the specified event flags to all the
+ * threads registered on the @p EventSource in addition to the event
+ * flags specified by the threads themselves in the
+ * @p EventListener objects.
*
* @param[in] esp pointer to the @p EventSource structure
+ * @param[in] mask the event flags set to be ORed
*
* @api
*/
-void chEvtBroadcast(EventSource *esp) {
+void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask) {
chSysLock();
- chEvtBroadcastI(esp);
+ chEvtBroadcastFlagsI(esp, mask);
chSchRescheduleS();
chSysUnlock();
}
@@ -214,23 +220,28 @@ void chEvtBroadcast(EventSource *esp) {
/**
* @brief Signals all the Event Listeners registered on the specified Event
* Source.
+ * @details This function variants ORs the specified event flags to all the
+ * threads registered on the @p EventSource in addition to the event
+ * flags specified by the threads themselves in the
+ * @p EventListener objects.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] esp pointer to the @p EventSource structure
+ * @param[in] mask the event flags set to be ORed
*
* @iclass
*/
-void chEvtBroadcastI(EventSource *esp) {
+void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask) {
EventListener *elp;
- chDbgCheck(esp != NULL, "chEvtBroadcastI");
+ chDbgCheck(esp != NULL, "chEvtBroadcastMaskI");
elp = esp->es_next;
while (elp != (EventListener *)esp) {
- chEvtSignalI(elp->el_listener, elp->el_mask);
+ chEvtSignalFlagsI(elp->el_listener, elp->el_mask | mask);
elp = elp->el_next;
}
}
diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c
index 13db7cf6b..b90b21909 100644
--- a/os/kernel/src/chheap.c
+++ b/os/kernel/src/chheap.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -64,7 +65,7 @@ static MemoryHeap default_heap;
*
* @notapi
*/
-void heap_init(void) {
+void _heap_init(void) {
default_heap.h_provider = chCoreAlloc;
default_heap.h_free.h.u.next = (union heap_header *)NULL;
default_heap.h_free.h.size = 0;
@@ -79,6 +80,8 @@ void heap_init(void) {
* @brief Initializes a memory heap from a static memory area.
* @pre Both the heap buffer base and the heap size must be aligned to
* the @p stkalign_t type size.
+ * @pre In order to use this function the option @p CH_USE_MALLOC_HEAP
+ * must be disabled.
*
* @param[out] heapp pointer to the memory heap descriptor to be initialized
* @param[in] buf heap buffer base
@@ -125,7 +128,7 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
if (heapp == NULL)
heapp = &default_heap;
- size = MEM_ALIGN_SIZE(size);
+ size = MEM_ALIGN_NEXT(size);
qp = &heapp->h_free;
H_LOCK(heapp);
@@ -270,7 +273,7 @@ static Mutex hmtx;
static Semaphore hsem;
#endif
-void heap_init(void) {
+void _heap_init(void) {
#if CH_USE_MUTEXES
chMtxInit(&hmtx);
diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c
index 878f1360c..c3168eafe 100644
--- a/os/kernel/src/chlists.c
+++ b/os/kernel/src/chlists.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c
index b2cef2470..af6ee5ea8 100644
--- a/os/kernel/src/chmboxes.c
+++ b/os/kernel/src/chmboxes.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -156,6 +157,34 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
}
/**
+ * @brief Posts a message into a mailbox.
+ * @details This variant is non-blocking, the function returns a timeout
+ * condition if the queue is full.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[in] msg the message to be posted on the mailbox
+ * @return The operation status.
+ * @retval RDY_OK if a message has been correctly posted.
+ * @retval RDY_TIMEOUT if the mailbox is full and the message cannot be
+ * posted.
+ *
+ * @iclass
+ */
+msg_t chMBPostI(Mailbox *mbp, msg_t msg) {
+
+ chDbgCheck(mbp != NULL, "chMBPostI");
+
+ if (chSemGetCounterI(&mbp->mb_emptysem) <= 0)
+ return RDY_TIMEOUT;
+ chSemFastWaitI(&mbp->mb_emptysem);
+ *mbp->mb_wrptr++ = msg;
+ if (mbp->mb_wrptr >= mbp->mb_top)
+ mbp->mb_wrptr = mbp->mb_buffer;
+ chSemSignalI(&mbp->mb_fullsem);
+ return RDY_OK;
+}
+
+/**
* @brief Posts an high priority message into a mailbox.
* @details The invoking thread waits until a empty slot in the mailbox becomes
* available or the specified time runs out.
@@ -219,6 +248,34 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
}
/**
+ * @brief Posts an high priority message into a mailbox.
+ * @details This variant is non-blocking, the function returns a timeout
+ * condition if the queue is full.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[in] msg the message to be posted on the mailbox
+ * @return The operation status.
+ * @retval RDY_OK if a message has been correctly posted.
+ * @retval RDY_TIMEOUT if the mailbox is full and the message cannot be
+ * posted.
+ *
+ * @iclass
+ */
+msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) {
+
+ chDbgCheck(mbp != NULL, "chMBPostAheadI");
+
+ if (chSemGetCounterI(&mbp->mb_emptysem) <= 0)
+ return RDY_TIMEOUT;
+ chSemFastWaitI(&mbp->mb_emptysem);
+ if (--mbp->mb_rdptr < mbp->mb_buffer)
+ mbp->mb_rdptr = mbp->mb_top - 1;
+ *mbp->mb_rdptr = msg;
+ chSemSignalI(&mbp->mb_fullsem);
+ return RDY_OK;
+}
+
+/**
* @brief Retrieves a message from a mailbox.
* @details The invoking thread waits until a message is posted in the mailbox
* or the specified time runs out.
@@ -280,6 +337,33 @@ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) {
}
return rdymsg;
}
+
+/**
+ * @brief Retrieves a message from a mailbox.
+ * @details This variant is non-blocking, the function returns a timeout
+ * condition if the queue is full.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[out] msgp pointer to a message variable for the received message
+ * @return The operation status.
+ * @retval RDY_OK if a message has been correctly fetched.
+ * @retval RDY_TIMEOUT if the mailbox is empty and a message cannot be
+ * fetched.
+ *
+ * @iclass
+ */
+msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp) {
+
+ chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchI");
+
+ if (chSemGetCounterI(&mbp->mb_fullsem) <= 0)
+ return RDY_TIMEOUT;
+ *msgp = *mbp->mb_rdptr++;
+ if (mbp->mb_rdptr >= mbp->mb_top)
+ mbp->mb_rdptr = mbp->mb_buffer;
+ chSemSignalI(&mbp->mb_emptysem);
+ return RDY_OK;
+}
#endif /* CH_USE_MAILBOXES */
/** @} */
diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c
index 69d3014a5..311d170c5 100644
--- a/os/kernel/src/chmemcore.c
+++ b/os/kernel/src/chmemcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -24,18 +25,20 @@
* @addtogroup memcore
* @details Core Memory Manager related APIs and services.
* <h2>Operation mode</h2>
- * The core memory manager is a simplified allocator that only allows
- * to allocate memory blocks without the possibility to free them.<br>
- * This allocator is meant as a memory blocks provider for the other
- * allocators such as:
+ * The core memory manager is a simplified allocator that only
+ * allows to allocate memory blocks without the possibility to
+ * free them.<br>
+ * This allocator is meant as a memory blocks provider for the
+ * other allocators such as:
* - C-Runtime allocator (through a compiler specific adapter module).
* - Heap allocator (see @ref heaps).
* - Memory pools allocator (see @ref pools).
* .
- * By having a centralized memory provider the various allocators can
- * coexist and share the main memory.<br>
- * This allocator, alone, is also useful for very simple applications
- * that just require a simple way to get memory blocks.
+ * By having a centralized memory provider the various allocators
+ * can coexist and share the main memory.<br>
+ * This allocator, alone, is also useful for very simple
+ * applications that just require a simple way to get memory
+ * blocks.
* @pre In order to use the core memory manager APIs the @p CH_USE_MEMCORE
* option must be enabled in @p chconf.h.
* @{
@@ -53,26 +56,24 @@ static uint8_t *endmem;
*
* @notapi
*/
-void core_init(void) {
+void _core_init(void) {
#if CH_MEMCORE_SIZE == 0
- extern uint8_t __heap_base__;
- extern uint8_t __heap_end__;
- nextmem = &__heap_base__;
- endmem = &__heap_end__;
+ extern uint8_t __heap_base__[];
+ extern uint8_t __heap_end__[];
+ nextmem = (uint8_t *)MEM_ALIGN_NEXT(__heap_base__);
+ endmem = (uint8_t *)MEM_ALIGN_PREV(__heap_end__);
#else
- static stkalign_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) /
- sizeof(stkalign_t)];
+ static stkalign_t buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE];
nextmem = (uint8_t *)&buffer[0];
- endmem = (uint8_t *)&buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) /
- sizeof(stkalign_t)];
+ endmem = (uint8_t *)&buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE];
#endif
}
/**
* @brief Allocates a memory block.
* @details The size of the returned block is aligned to the alignment
- * type @p stkalign_t so it is not possible to allocate less
- * than <code>sizeof(stkalign_t)</code>.
+ * type so it is not possible to allocate less
+ * than <code>MEM_ALIGN_SIZE</code>.
*
* @param[in] size the size of the block to be allocated
* @return A pointer to the allocated memory block.
@@ -92,8 +93,8 @@ void *chCoreAlloc(size_t size) {
/**
* @brief Allocates a memory block.
* @details The size of the returned block is aligned to the alignment
- * type @p align_t so it is not possible to allocate less than
- * <code>sizeof(align_t)</code>.
+ * type so it is not possible to allocate less than
+ * <code>MEM_ALIGN_SIZE</code>.
*
* @param[in] size the size of the block to be allocated.
* @return A pointer to the allocated memory block.
@@ -104,7 +105,7 @@ void *chCoreAlloc(size_t size) {
void *chCoreAllocI(size_t size) {
void *p;
- size = MEM_ALIGN_SIZE(size);
+ size = MEM_ALIGN_NEXT(size);
if ((size_t)(endmem - nextmem) < size)
return NULL;
p = nextmem;
diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c
index 092944b59..38adc3d49 100644
--- a/os/kernel/src/chmempools.c
+++ b/os/kernel/src/chmempools.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -55,7 +56,7 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) {
chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit");
mp->mp_next = NULL;
- mp->mp_object_size = MEM_ALIGN_SIZE(size);
+ mp->mp_object_size = MEM_ALIGN_NEXT(size);
mp->mp_provider = provider;
}
@@ -75,10 +76,8 @@ void *chPoolAllocI(MemoryPool *mp) {
if ((objp = mp->mp_next) != NULL)
mp->mp_next = mp->mp_next->ph_next;
-#if CH_USE_MEMCORE
else if (mp->mp_provider != NULL)
objp = mp->mp_provider(mp->mp_object_size);
-#endif
return objp;
}
diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c
index c3b4848b0..5002a892a 100644
--- a/os/kernel/src/chmsg.c
+++ b/os/kernel/src/chmsg.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -75,7 +76,7 @@ msg_t chMsgSend(Thread *tp, msg_t msg) {
msg_insert(ctp, &tp->p_msgqueue);
if (tp->p_state == THD_STATE_WTMSG)
chSchReadyI(tp);
- chSchGoSleepS(THD_STATE_SNDMSG);
+ chSchGoSleepS(THD_STATE_SNDMSGQ);
msg = ctp->p_u.rdymsg;
chSysUnlock();
return msg;
@@ -83,69 +84,46 @@ msg_t chMsgSend(Thread *tp, msg_t msg) {
/**
* @brief Suspends the thread and waits for an incoming message.
- * @post After receiving a message the function @p chMsgRelease() must be
- * invoked in order to acknowledge the reception and send the answer.
+ * @post After receiving a message the function @p chMsgGet() must be
+ * called in order to retrieve the message and then @p chMsgRelease()
+ * must be invoked in order to acknowledge the reception and send
+ * the answer.
* @note If the message is a pointer then you can assume that the data
* pointed by the message is stable until you invoke @p chMsgRelease()
* because the sending thread is suspended until then.
*
- * @return The message.
+ * @return A reference to the thread carrying the message.
*
* @api
*/
-msg_t chMsgWait(void) {
- msg_t msg;
+Thread *chMsgWait(void) {
+ Thread *tp;
chSysLock();
if (!chMsgIsPendingI(currp))
chSchGoSleepS(THD_STATE_WTMSG);
-#if defined(CH_ARCHITECTURE_STM8)
- msg = chMsgGetI((volatile Thread *)currp); /* Temporary hack.*/
-#else
- msg = chMsgGetI(currp);
-#endif
+ tp = fifo_remove(&currp->p_msgqueue);
+ tp->p_state = THD_STATE_SNDMSG;
chSysUnlock();
- return msg;
-}
-
-/**
- * @brief Returns the next message in the queue.
- * @post After receiving a message the function @p chMsgRelease() must be
- * invoked in order to acknowledge the reception and send the answer.
- * @note If the message is a pointer then you can assume that the data
- * pointed by the message is stable until you invoke @p chMsgRelease()
- * because the sending thread is suspended until then.
- *
- * @return The message.
- * @retval 0 if the queue is empty.
- *
- * @api
- */
-msg_t chMsgGet(void) {
- msg_t msg;
-
- chSysLock();
- msg = chMsgIsPendingI(currp) ? chMsgGetI(currp) : (msg_t)NULL;
- chSysUnlock();
- return msg;
+ return tp;
}
/**
* @brief Releases the thread waiting on top of the messages queue.
* @pre Invoke this function only after a message has been received
- * using @p chMsgWait() or @p chMsgGet().
+ * using @p chMsgWait().
*
- * @param[in] msg the message returned to the message sender
+ * @param[in] tp pointer to the thread
+ * @param[in] msg message to be returned to the sender
*
* @api
*/
-void chMsgRelease(msg_t msg) {
+void chMsgRelease(Thread *tp, msg_t msg) {
chSysLock();
- chDbgAssert(chMsgIsPendingI(currp),
- "chMsgRelease(), #1",
- "no message pending");
- chSchWakeupS(fifo_remove(&currp->p_msgqueue), msg);
+ chDbgAssert(tp->p_state == THD_STATE_SNDMSG,
+ "chMsgRelease(), #1", "invalid state");
+ chMsgReleaseS(tp, msg);
chSysUnlock();
}
diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c
index b84c4d57e..df71d1cc6 100644
--- a/os/kernel/src/chmtx.c
+++ b/os/kernel/src/chmtx.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -133,15 +134,17 @@ void chMtxLockS(Mutex *mp) {
prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp);
tp = ((Mutex *)tp->p_u.wtobjp)->m_owner;
continue;
-#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY
+#if CH_USE_CONDVARS | \
+ (CH_USE_SEMAPHORES && CH_USE_SEMAPHORES_PRIORITY) | \
+ (CH_USE_MESSAGES && CH_USE_MESSAGES_PRIORITY)
#if CH_USE_CONDVARS
case THD_STATE_WTCOND:
#endif
-#if CH_USE_SEMAPHORES_PRIORITY
+#if CH_USE_SEMAPHORES && CH_USE_SEMAPHORES_PRIORITY
case THD_STATE_WTSEM:
#endif
-#if CH_USE_MESSAGES_PRIORITY
- case THD_STATE_SNDMSG:
+#if CH_USE_MESSAGES && CH_USE_MESSAGES_PRIORITY
+ case THD_STATE_SNDMSGQ:
#endif
/* Re-enqueues tp with its new priority on the queue.*/
prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp);
diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c
index 8d459a7e8..8532f8307 100644
--- a/os/kernel/src/chqueues.c
+++ b/os/kernel/src/chqueues.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -47,6 +48,30 @@
#if CH_USE_QUEUES || defined(__DOXYGEN__)
/**
+ * @brief Puts the invoking thread into the queue's threads queue.
+ *
+ * @param[out] qp pointer to an @p GenericQueue structure
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return A message specifying how the invoking thread has been
+ * released from threads queue.
+ * @retval Q_OK is the normal exit, thread signaled.
+ * @retval Q_RESET if the queue has been reset.
+ * @retval Q_TIMEOUT if the queue operation timed out.
+ */
+static msg_t qwait(GenericQueue *qp, systime_t time) {
+
+ if (TIME_IMMEDIATE == time)
+ return Q_TIMEOUT;
+ currp->p_u.wtobjp = qp;
+ queue_insert(currp, &qp->q_waiting);
+ return chSchGoSleepTimeoutS(THD_STATE_WTQUEUE, time);
+}
+
+/**
* @brief Initializes an input queue.
* @details A Semaphore is internally initialized and works as a counter of
* the bytes contained in the queue.
@@ -63,28 +88,11 @@
*/
void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) {
+ queue_init(&iqp->q_waiting);
+ iqp->q_counter = 0;
iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = bp;
iqp->q_top = bp + size;
iqp->q_notify = infy;
- chSemInit(&iqp->q_sem, 0);
-}
-
-/**
- * @brief Returns the filled space into an input queue.
- *
- * @param[in] iqp pointer to an @p InputQueue structure
- * @return The number of bytes in the queue.
- * @retval 0 if the queue is empty.
- *
- * @iclass
- */
-size_t chIQGetFullI(InputQueue *iqp) {
- cnt_t cnt;
-
- cnt = chQSpaceI(iqp);
- if (cnt < 0)
- return 0;
- return (size_t)cnt;
}
/**
@@ -101,7 +109,9 @@ size_t chIQGetFullI(InputQueue *iqp) {
void chIQResetI(InputQueue *iqp) {
iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer;
- chSemResetI(&iqp->q_sem, 0);
+ iqp->q_counter = 0;
+ while (notempty(&iqp->q_waiting))
+ chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_RESET;
}
/**
@@ -122,10 +132,14 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
if (chIQIsFullI(iqp))
return Q_FULL;
+ iqp->q_counter++;
*iqp->q_wrptr++ = b;
if (iqp->q_wrptr >= iqp->q_top)
iqp->q_wrptr = iqp->q_buffer;
- chSemSignalI(&iqp->q_sem);
+
+ if (notempty(&iqp->q_waiting))
+ chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK;
+
return Q_OK;
}
@@ -134,6 +148,9 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
* @details This function reads a byte value from an input queue. If the queue
* is empty then the calling thread is suspended until a byte arrives
* in the queue or a timeout occurs.
+ * @note The callback is invoked if the queue is empty before entering the
+ * @p THD_STATE_WTQUEUE state in order to solicit the low level to
+ * start queue filling.
*
* @param[in] iqp pointer to an @p InputQueue structure
* @param[in] time the number of ticks before the operation timeouts,
@@ -143,23 +160,27 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
* .
* @return A byte value from the queue.
* @retval Q_TIMEOUT if the specified time expired.
- * @retval Q_RESET if the queue was reset.
+ * @retval Q_RESET if the queue has been reset.
*
* @api
*/
msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) {
uint8_t b;
- msg_t msg;
chSysLock();
+ while (chIQIsEmptyI(iqp)) {
+ msg_t msg;
- if (iqp->q_notify)
- iqp->q_notify(iqp);
+ if (iqp->q_notify)
+ iqp->q_notify(iqp);
- if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) {
- chSysUnlock();
- return msg;
+ if ((msg = qwait((GenericQueue *)iqp, time)) < Q_OK) {
+ chSysUnlock();
+ return msg;
+ }
}
+
+ iqp->q_counter--;
b = *iqp->q_rdptr++;
if (iqp->q_rdptr >= iqp->q_top)
iqp->q_rdptr = iqp->q_buffer;
@@ -176,8 +197,9 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) {
* been reset.
* @note The function is not atomic, if you need atomicity it is suggested
* to use a semaphore or a mutex for mutual exclusion.
- * @note The queue callback is invoked before entering a sleep state and at
- * the end of the transfer.
+ * @note The callback is invoked if the queue is empty before entering the
+ * @p THD_STATE_WTQUEUE state in order to solicit the low level to
+ * start queue filling.
*
* @param[in] iqp pointer to an @p InputQueue structure
* @param[out] bp pointer to the data buffer
@@ -201,28 +223,26 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
chSysLock();
while (TRUE) {
- if (chIQIsEmptyI(iqp)) {
+ while (chIQIsEmptyI(iqp)) {
if (nfy)
nfy(iqp);
- if ((chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK)) {
+
+ if (qwait((GenericQueue *)iqp, time) != Q_OK) {
chSysUnlock();
return r;
}
}
- else
- chSemFastWaitI(&iqp->q_sem);
+
+ iqp->q_counter--;
*bp++ = *iqp->q_rdptr++;
if (iqp->q_rdptr >= iqp->q_top)
iqp->q_rdptr = iqp->q_buffer;
+
chSysUnlock(); /* Gives a preemption chance in a controlled point.*/
r++;
- if (--n == 0) {
- chSysLock();
- if (nfy)
- nfy(iqp);
- chSysUnlock();
+ if (--n == 0)
return r;
- }
+
chSysLock();
}
}
@@ -244,28 +264,11 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
*/
void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) {
+ queue_init(&oqp->q_waiting);
+ oqp->q_counter = size;
oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = bp;
oqp->q_top = bp + size;
oqp->q_notify = onfy;
- chSemInit(&oqp->q_sem, (cnt_t)size);
-}
-
-/**
- * @brief Returns the filled space into an output queue.
- *
- * @param[in] oqp pointer to an @p OutputQueue structure
- * @return The number of bytes in the queue.
- * @retval 0 if the queue is empty.
- *
- * @iclass
- */
-size_t chOQGetFullI(OutputQueue *oqp) {
- cnt_t cnt;
-
- cnt = chQSpaceI(oqp);
- if (cnt < 0)
- return chQSizeI(oqp);
- return chQSizeI(oqp) - (size_t)cnt;
}
/**
@@ -282,7 +285,9 @@ size_t chOQGetFullI(OutputQueue *oqp) {
void chOQResetI(OutputQueue *oqp) {
oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer;
- chSemResetI(&oqp->q_sem, (cnt_t)(oqp->q_top - oqp->q_buffer));
+ oqp->q_counter = chQSizeI(oqp);
+ while (notempty(&oqp->q_waiting))
+ chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_RESET;
}
/**
@@ -290,6 +295,8 @@ void chOQResetI(OutputQueue *oqp) {
* @details This function writes a byte value to an output queue. If the queue
* is full then the calling thread is suspended until there is space
* in the queue or a timeout occurs.
+ * @note The callback is invoked after writing the character into the
+ * buffer.
*
* @param[in] oqp pointer to an @p OutputQueue structure
* @param[in] b the byte value to be written in the queue
@@ -301,18 +308,23 @@ void chOQResetI(OutputQueue *oqp) {
* @return The operation status.
* @retval Q_OK if the operation succeeded.
* @retval Q_TIMEOUT if the specified time expired.
- * @retval Q_RESET if the queue was reset.
+ * @retval Q_RESET if the queue has been reset.
*
* @api
*/
msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) {
- msg_t msg;
chSysLock();
- if ((msg = chSemWaitTimeoutS(&oqp->q_sem, time)) < RDY_OK) {
- chSysUnlock();
- return msg;
+ while (chOQIsFullI(oqp)) {
+ msg_t msg;
+
+ if ((msg = qwait((GenericQueue *)oqp, time)) < Q_OK) {
+ chSysUnlock();
+ return msg;
+ }
}
+
+ oqp->q_counter--;
*oqp->q_wrptr++ = b;
if (oqp->q_wrptr >= oqp->q_top)
oqp->q_wrptr = oqp->q_buffer;
@@ -340,10 +352,14 @@ msg_t chOQGetI(OutputQueue *oqp) {
if (chOQIsEmptyI(oqp))
return Q_EMPTY;
+ oqp->q_counter++;
b = *oqp->q_rdptr++;
if (oqp->q_rdptr >= oqp->q_top)
oqp->q_rdptr = oqp->q_buffer;
- chSemSignalI(&oqp->q_sem);
+
+ if (notempty(&oqp->q_waiting))
+ chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK;
+
return b;
}
@@ -355,8 +371,8 @@ msg_t chOQGetI(OutputQueue *oqp) {
* been reset.
* @note The function is not atomic, if you need atomicity it is suggested
* to use a semaphore or a mutex for mutual exclusion.
- * @note The queue callback is invoked before entering a sleep state and at
- * the end of the transfer.
+ * @note The callback is invoked after writing each character into the
+ * buffer.
*
* @param[in] oqp pointer to an @p OutputQueue structure
* @param[out] bp pointer to the data buffer
@@ -380,28 +396,24 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
chSysLock();
while (TRUE) {
- if (chOQIsFullI(oqp)) {
- if (nfy)
- nfy(oqp);
- if ((chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK)) {
+ while (chOQIsFullI(oqp)) {
+ if (qwait((GenericQueue *)oqp, time) != Q_OK) {
chSysUnlock();
return w;
}
}
- else
- chSemFastWaitI(&oqp->q_sem);
+ oqp->q_counter--;
*oqp->q_wrptr++ = *bp++;
if (oqp->q_wrptr >= oqp->q_top)
oqp->q_wrptr = oqp->q_buffer;
+
+ if (nfy)
+ nfy(oqp);
+
chSysUnlock(); /* Gives a preemption chance in a controlled point.*/
w++;
- if (--n == 0) {
- chSysLock();
- if (nfy)
- nfy(oqp);
- chSysUnlock();
+ if (--n == 0)
return w;
- }
chSysLock();
}
}
diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c
index e95ad21a8..9eabe71c0 100644
--- a/os/kernel/src/chregistry.c
+++ b/os/kernel/src/chregistry.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c
index 5b04c1f3d..d41649b4c 100644
--- a/os/kernel/src/chschd.c
+++ b/os/kernel/src/chschd.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -44,7 +45,7 @@ ReadyList rlist;
*
* @notapi
*/
-void scheduler_init(void) {
+void _scheduler_init(void) {
queue_init(&rlist.r_queue);
rlist.r_prio = NOPRIO;
@@ -129,12 +130,16 @@ static void wakeup(void *p) {
/* Handling the special case where the thread has been made ready by
another thread with higher priority.*/
return;
-#if CH_USE_SEMAPHORES || (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT)
+#if CH_USE_SEMAPHORES || CH_USE_QUEUES || \
+ (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT)
#if CH_USE_SEMAPHORES
case THD_STATE_WTSEM:
chSemFastSignalI((Semaphore *)tp->p_u.wtobjp);
/* Falls into, intentional. */
#endif
+#if CH_USE_QUEUES
+ case THD_STATE_WTQUEUE:
+#endif
#if CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT
case THD_STATE_WTCOND:
#endif
@@ -160,9 +165,7 @@ static void wakeup(void *p) {
* - @a TIME_INFINITE the thread enters an infinite sleep
* state, this is equivalent to invoking
* @p chSchGoSleepS() but, of course, less efficient.
- * - @a TIME_IMMEDIATE this value is accepted but
- * interpreted as a normal time specification not as an
- * immediate timeout specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
* .
* @return The wakeup message.
* @retval RDY_TIMEOUT if a timeout occurs.
diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c
index 18ea9e996..c22a568ea 100644
--- a/os/kernel/src/chsem.c
+++ b/os/kernel/src/chsem.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -312,35 +313,32 @@ void chSemSignalI(Semaphore *sp) {
}
/**
- * @brief Sets the semaphore counter to the specified value.
- * @post After invoking this function all the threads waiting on the
- * semaphore, if any, are released and the semaphore counter is set
- * to the specified, non negative, value.
+ * @brief Adds the specified value to the semaphore counter.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] sp pointer to a @p Semaphore structure
- * @param[in] n the new value of the semaphore counter. The value must
- * be non-negative.
+ * @param[in] n value to be added to the semaphore counter. The value
+ * must be positive.
*
* @iclass
*/
-void chSemSetCounterI(Semaphore *sp, cnt_t n) {
- cnt_t cnt;
+void chSemAddCounterI(Semaphore *sp, cnt_t n) {
- chDbgCheck((sp != NULL) && (n >= 0), "chSemSetCounterI");
+ chDbgCheck((sp != NULL) && (n > 0), "chSemAddCounterI");
chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) ||
((sp->s_cnt < 0) && notempty(&sp->s_queue)),
- "chSemSetCounterI(), #1",
+ "chSemAddCounterI(), #1",
"inconsistent semaphore");
- cnt = sp->s_cnt;
- sp->s_cnt = n;
- while (++cnt <= 0)
- chSchReadyI(lifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK;
+ while (n > 0) {
+ if (++sp->s_cnt <= 0)
+ chSchReadyI(fifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK;
+ n--;
+ }
}
#if CH_USE_SEMSW
diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c
index 0051985ba..6892ec73a 100644
--- a/os/kernel/src/chsys.c
+++ b/os/kernel/src/chsys.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -34,11 +35,12 @@
#include "ch.h"
+#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
/**
* @brief Idle thread working area.
- * @see IDLE_THREAD_STACK_SIZE
+ * @see PORT_IDLE_THREAD_STACK_SIZE
*/
-WORKING_AREA(_idle_thread_wa, IDLE_THREAD_STACK_SIZE);
+WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE);
/**
* @brief This function implements the idle thread infinite loop.
@@ -58,6 +60,7 @@ void _idle_thread(void *p) {
IDLE_LOOP_HOOK();
}
}
+#endif /* CH_NO_IDLE_THREAD */
/**
* @brief ChibiOS/RT initialization.
@@ -75,16 +78,16 @@ void chSysInit(void) {
static Thread mainthread;
port_init();
- scheduler_init();
- vt_init();
+ _scheduler_init();
+ _vt_init();
#if CH_USE_MEMCORE
- core_init();
+ _core_init();
#endif
#if CH_USE_HEAP
- heap_init();
+ _heap_init();
#endif
#if CH_DBG_ENABLE_TRACE
- trace_init();
+ _trace_init();
#endif
/* Now this instructions flow becomes the main thread.*/
@@ -92,11 +95,13 @@ void chSysInit(void) {
currp->p_state = THD_STATE_CURRENT;
chSysEnable();
+#if !CH_NO_IDLE_THREAD
/* This thread has the lowest priority in the system, its role is just to
serve interrupts in its context while keeping the lowest energy saving
mode compatible with the system status.*/
chThdCreateStatic(_idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO,
(tfunc_t)_idle_thread, NULL);
+#endif
}
/**
diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c
index 51efc20d1..7df276bea 100644
--- a/os/kernel/src/chthreads.c
+++ b/os/kernel/src/chthreads.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -205,8 +206,7 @@ Thread *chThdCreateStatic(void *wsp, size_t size,
tprio_t chThdSetPriority(tprio_t newprio) {
tprio_t oldprio;
- chDbgCheck((newprio >= LOWPRIO) && (newprio <= HIGHPRIO),
- "chThdSetPriority");
+ chDbgCheck(newprio <= HIGHPRIO, "chThdSetPriority");
chSysLock();
#if CH_USE_MUTEXES
@@ -273,16 +273,14 @@ void chThdTerminate(Thread *tp) {
* handled as follow:
* - @a TIME_INFINITE the thread enters an infinite sleep
* state.
- * - @a TIME_IMMEDIATE this value is accepted but
- * interpreted as a normal time specification not as an
- * immediate timeout specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
* .
*
* @api
*/
void chThdSleep(systime_t time) {
- chDbgCheck(time != TIME_INFINITE, "chThdSleep");
+ chDbgCheck(time != TIME_IMMEDIATE, "chThdSleep");
chSysLock();
chThdSleepS(time);
diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c
index b622bb493..4674c728e 100644
--- a/os/kernel/src/chvt.c
+++ b/os/kernel/src/chvt.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -39,7 +40,7 @@ VTList vtlist;
*
* @notapi
*/
-void vt_init(void) {
+void _vt_init(void) {
vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist;
vtlist.vt_time = (systime_t)-1;
@@ -52,10 +53,12 @@ void vt_init(void) {
* the I-Locked state, see @ref system_states.
*
* @param[out] vtp the @p VirtualTimer structure pointer
- * @param[in] time the number of time ticks, the value @p TIME_INFINITE
- * is notallowed. The value @p TIME_IMMEDIATE is allowed
- * but interpreted as a normal time specification not as
- * an immediate timeout specification.
+ * @param[in] time the number of ticks before the operation timeouts, the
+ * special values are handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
* @param[in] vtfunc the timer callback function. After invoking the
* callback the timer is disabled and the structure can
* be disposed or reused.
@@ -67,7 +70,7 @@ void vt_init(void) {
void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
VirtualTimer *p;
- chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_INFINITE),
+ chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_IMMEDIATE),
"chVTSetI");
vtp->vt_par = par;
diff --git a/os/kernel/templates/chconf.h b/os/kernel/templates/chconf.h
index 3353391ca..c9c4c286a 100644
--- a/os/kernel/templates/chconf.h
+++ b/os/kernel/templates/chconf.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -83,12 +84,29 @@
*
* @note In order to let the OS manage the whole RAM the linker script must
* provide the @p __heap_base__ and @p __heap_end__ symbols.
- * @note Requires @p CH_USE_COREMEM.
+ * @note Requires @p CH_USE_MEMCORE.
*/
#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
#define CH_MEMCORE_SIZE 0
#endif
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread automatically. The application has
+ * then the responsibility to do one of the following:
+ * - Spawn a custom idle thread at priority @p IDLEPRIO.
+ * - Change the main() thread priority to @p IDLEPRIO then enter
+ * an endless loop. In this scenario the @p main() thread acts as
+ * the idle thread.
+ * .
+ * @note Unless an idle thread is spawned the @p main() thread must not
+ * enter a sleep state.
+ */
+#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
+#define CH_NO_IDLE_THREAD FALSE
+#endif
+
/*===========================================================================*/
/* Performance options. */
/*===========================================================================*/
@@ -105,26 +123,6 @@
#define CH_OPTIMIZE_SPEED TRUE
#endif
-/**
- * @brief Exotic optimization.
- * @details If defined then a CPU register is used as storage for the global
- * @p currp variable. Caching this variable in a register greatly
- * improves both space and time OS efficiency. A side effect is that
- * one less register has to be saved during the context switch
- * resulting in lower RAM usage and faster context switch.
- *
- * @note This option is only usable with the GCC compiler and is only useful
- * on processors with many registers like ARM cores.
- * @note If this option is enabled then ALL the libraries linked to the
- * ChibiOS/RT code <b>must</b> be recompiled with the GCC option @p
- * -ffixed-@<reg@>.
- * @note This option must be enabled in the Makefile, it is listed here for
- * documentation only.
- */
-#if defined(__DOXYGEN__)
-#define CH_CURRP_REGISTER_CACHE "reg"
-#endif
-
/*===========================================================================*/
/* Subsystem options. */
/*===========================================================================*/
@@ -280,7 +278,6 @@
* @details If enabled then the I/O queues APIs are included in the kernel.
*
* @note The default is @p TRUE.
- * @note Requires @p CH_USE_SEMAPHORES.
*/
#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
#define CH_USE_QUEUES TRUE
@@ -303,7 +300,7 @@
* in the kernel.
*
* @note The default is @p TRUE.
- * @note Requires @p CH_USE_COREMEM and either @p CH_USE_MUTEXES or
+ * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or
* @p CH_USE_SEMAPHORES.
* @note Mutexes are recommended.
*/
@@ -318,7 +315,7 @@
*
* @note The default is @p FALSE.
* @note Requires @p CH_USE_HEAP.
- * @note The C-runtime may or may not require @p CH_USE_COREMEM, see the
+ * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
* appropriate documentation.
*/
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
diff --git a/os/kernel/templates/chcore.c b/os/kernel/templates/chcore.c
index c2737b04a..74281f759 100644
--- a/os/kernel/templates/chcore.c
+++ b/os/kernel/templates/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/kernel/templates/chcore.h b/os/kernel/templates/chcore.h
index 69c37b24d..5c8236c7b 100644
--- a/os/kernel/templates/chcore.h
+++ b/os/kernel/templates/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -30,6 +31,48 @@
#ifndef _CHCORE_H_
#define _CHCORE_H_
+/*===========================================================================*/
+/* Port constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port configurable parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief Stack size for the system idle thread.
+ * @details This size depends on the idle thread implementation, usually
+ * the idle thread should take no more space than those reserved
+ * by @p PORT_INT_REQUIRED_STACK.
+ */
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 0
+#endif
+
+/**
+ * @brief Per-thread stack overhead for interrupts servicing.
+ * @details This constant is used in the calculation of the correct working
+ * area size.
+ * This value can be zero on those architecture where there is a
+ * separate interrupt stack and the stack space between @p intctx and
+ * @p extctx is known to be zero.
+ */
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 0
+#endif
+
+/*===========================================================================*/
+/* Port derived parameters. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port exported info. */
+/*===========================================================================*/
+
/**
* @brief Unique macro for the implemented architecture.
*/
@@ -38,12 +81,26 @@
/**
* @brief Name of the implemented architecture.
*/
-#define CH_ARCHITECTURE_NAME ""
+#define CH_ARCHITECTURE_NAME ""
/**
* @brief Name of the architecture variant (optional).
*/
-#define CH_ARCHITECTURE_VARIANT_NAME ""
+#define CH_ARCHITECTURE_VARIANT_NAME ""
+
+/**
+ * @brief Name of the compiler supported by this port.
+ */
+#define CH_COMPILER_NAME "GCC"
+
+/**
+ * @brief Port-specific information string.
+ */
+#define CH_PORT_INFO ""
+
+/*===========================================================================*/
+/* Port implementation part. */
+/*===========================================================================*/
/**
* @brief Base type for stack and memory alignment.
@@ -84,28 +141,6 @@ struct context {
}
/**
- * @brief Stack size for the system idle thread.
- * @details This size depends on the idle thread implementation, usually
- * the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
- */
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 0
-#endif
-
-/**
- * @brief Per-thread stack overhead for interrupts servicing.
- * @details This constant is used in the calculation of the correct working
- * area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- */
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 0
-#endif
-
-/**
* @brief Enforces a correct alignment for a stack area size value.
*/
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
@@ -116,7 +151,7 @@ struct context {
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/kernel/templates/chtypes.h b/os/kernel/templates/chtypes.h
index 9be581d33..8b25e598c 100644
--- a/os/kernel/templates/chtypes.h
+++ b/os/kernel/templates/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -105,7 +106,7 @@ typedef int32_t cnt_t;
* a pointer to a ROMCONST constant is compatible with a pointer
* to a normal variable. It is just like the "const" keyword but
* requires that the constant is placed in ROM if the architecture
- * supports it.
+ * supports it.
*/
#define ROMCONST const
diff --git a/os/ports/GCC/ARM/AT91SAM7/armparams.h b/os/ports/GCC/ARM/AT91SAM7/armparams.h
index 8b53605ea..a40278032 100644
--- a/os/ports/GCC/ARM/AT91SAM7/armparams.h
+++ b/os/ports/GCC/ARM/AT91SAM7/armparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/AT91SAM7/vectors.s b/os/ports/GCC/ARM/AT91SAM7/vectors.s
index f27ecd0dd..f56f7df3b 100644
--- a/os/ports/GCC/ARM/AT91SAM7/vectors.s
+++ b/os/ports/GCC/ARM/AT91SAM7/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/AT91SAM7/wfi.h b/os/ports/GCC/ARM/AT91SAM7/wfi.h
index 76390d407..7a43ded99 100644
--- a/os/ports/GCC/ARM/AT91SAM7/wfi.h
+++ b/os/ports/GCC/ARM/AT91SAM7/wfi.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/LPC214x/armparams.h b/os/ports/GCC/ARM/LPC214x/armparams.h
index 5688fbab4..2b8e4cd50 100644
--- a/os/ports/GCC/ARM/LPC214x/armparams.h
+++ b/os/ports/GCC/ARM/LPC214x/armparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/LPC214x/vectors.s b/os/ports/GCC/ARM/LPC214x/vectors.s
index 6b0235c62..1d8711e72 100644
--- a/os/ports/GCC/ARM/LPC214x/vectors.s
+++ b/os/ports/GCC/ARM/LPC214x/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/LPC214x/wfi.h b/os/ports/GCC/ARM/LPC214x/wfi.h
index 1688c33f8..8b9a80889 100644
--- a/os/ports/GCC/ARM/LPC214x/wfi.h
+++ b/os/ports/GCC/ARM/LPC214x/wfi.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/chcore.c b/os/ports/GCC/ARM/chcore.c
index db4793f0e..d97ee2fa5 100644
--- a/os/ports/GCC/ARM/chcore.c
+++ b/os/ports/GCC/ARM/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/chcore.h b/os/ports/GCC/ARM/chcore.h
index 7e0e1e003..20727ce23 100644
--- a/os/ports/GCC/ARM/chcore.h
+++ b/os/ports/GCC/ARM/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -61,7 +62,7 @@
* @brief If enabled allows the idle thread to enter a low power mode.
*/
#ifndef ARM_ENABLE_WFI_IDLE
-#define ARM_ENABLE_WFI_IDLE FALSE
+#define ARM_ENABLE_WFI_IDLE FALSE
#endif
/*===========================================================================*/
@@ -92,7 +93,7 @@
* - "ARM9".
* .
*/
-#define CH_ARCHITECTURE_NAME "ARMx"
+#define CH_ARCHITECTURE_NAME "ARMx"
/**
* @brief Name of the architecture variant (optional).
@@ -102,19 +103,45 @@
* - "ARM9"
* .
*/
-#define CH_CORE_VARIANT_NAME "ARMxy"
+#define CH_CORE_VARIANT_NAME "ARMxy"
+
+/**
+ * @brief Port-specific information string.
+ * @note The value is for documentation only, the real value changes
+ * depending on the selected options, the possible values are:
+ * - "Pure ARM"
+ * - "Pure THUMB"
+ * - "Interworking"
+ * .
+ */
+#define CH_PORT_INFO "ARM|THUMB|Interworking"
#elif ARM_CORE == ARM_CORE_ARM7TDMI
#define CH_ARCHITECTURE_ARM7TDMI
-#define CH_ARCHITECTURE_NAME "ARM7"
-#define CH_CORE_VARIANT_NAME "ARM7TDMI"
+#define CH_ARCHITECTURE_NAME "ARM7"
+#define CH_CORE_VARIANT_NAME "ARM7TDMI"
#elif ARM_MODEL == ARM_VARIANT_ARM9
#define CH_ARCHITECTURE_ARM9
-#define CH_ARCHITECTURE_NAME "ARM9"
-#define CH_CORE_VARIANT_NAME "ARM9"
+#define CH_ARCHITECTURE_NAME "ARM9"
+#define CH_CORE_VARIANT_NAME "ARM9"
#endif
+#if THUMB_PRESENT
+#if THUMB_NO_INTERWORKING
+#define CH_PORT_INFO "Pure THUMB mode"
+#else /* !THUMB_NO_INTERWORKING */
+#define CH_PORT_INFO "Interworking mode"
+#endif /* !THUMB_NO_INTERWORKING */
+#else /* !THUMB_PRESENT */
+#define CH_PORT_INFO "Pure ARM mode"
+#endif /* !THUMB_PRESENT */
+
+/**
+ * @brief Name of the compiler supported by this port.
+ */
+#define CH_COMPILER_NAME "GCC "__VERSION__
+
/*===========================================================================*/
/* Port implementation part (common). */
/*===========================================================================*/
@@ -154,9 +181,7 @@ struct intctx {
regarm_t r4;
regarm_t r5;
regarm_t r6;
-#ifndef CH_CURRP_REGISTER_CACHE
regarm_t r7;
-#endif
regarm_t r8;
regarm_t r9;
regarm_t r10;
@@ -191,12 +216,12 @@ struct context {
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
+ * by @p PORT_INT_REQUIRED_STACK.
* @note In this port it is set to 4 because the idle thread does have
* a stack frame when compiling without optimizations.
*/
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 4
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 4
#endif
/**
@@ -209,8 +234,8 @@ struct context {
* @note In this port 0x10 is a safe value, it can be reduced after careful
* analysis of the generated code.
*/
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 0x10
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 0x10
#endif
/**
@@ -224,7 +249,7 @@ struct context {
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/ports/GCC/ARM/chcoreasm.s b/os/ports/GCC/ARM/chcoreasm.s
index 22ffa2c40..41bd29a90 100644
--- a/os/ports/GCC/ARM/chcoreasm.s
+++ b/os/ports/GCC/ARM/chcoreasm.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/chtypes.h b/os/ports/GCC/ARM/chtypes.h
index ba906f4f1..0a3bf1fe3 100644
--- a/os/ports/GCC/ARM/chtypes.h
+++ b/os/ports/GCC/ARM/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/crt0.s b/os/ports/GCC/ARM/crt0.s
index b3a6aa392..fb410af52 100644
--- a/os/ports/GCC/ARM/crt0.s
+++ b/os/ports/GCC/ARM/crt0.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARM/port.dox b/os/ports/GCC/ARM/port.dox
index 2fe0f19c2..f264591f7 100644
--- a/os/ports/GCC/ARM/port.dox
+++ b/os/ports/GCC/ARM/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/LPC11xx/cmparams.h b/os/ports/GCC/ARMCMx/LPC11xx/cmparams.h
index 927a729e0..4016e6aa1 100644
--- a/os/ports/GCC/ARMCMx/LPC11xx/cmparams.h
+++ b/os/ports/GCC/ARMCMx/LPC11xx/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/LPC11xx/port.mk b/os/ports/GCC/ARMCMx/LPC11xx/port.mk
index 886add45d..a38729958 100644
--- a/os/ports/GCC/ARMCMx/LPC11xx/port.mk
+++ b/os/ports/GCC/ARMCMx/LPC11xx/port.mk
@@ -1,10 +1,11 @@
# List of the ChibiOS/RT Cortex-M0 LPC11xx port files.
-PORTSRC = $(CHIBIOS)/os/ports/GCC/ARMCMx/LPC11xx/vectors.c \
+PORTSRC = $(CHIBIOS)/os/ports/GCC/ARMCMx/crt0.c \
+ $(CHIBIOS)/os/ports/GCC/ARMCMx/LPC11xx/vectors.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v6m.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/nvic.c
-PORTASM = ${CHIBIOS}/os/ports/GCC/ARMCMx/crt0_v6m.s
+PORTASM =
PORTINC = ${CHIBIOS}/os/ports/GCC/ARMCMx \
${CHIBIOS}/os/ports/GCC/ARMCMx/LPC11xx
diff --git a/os/ports/GCC/ARMCMx/LPC11xx/vectors.c b/os/ports/GCC/ARMCMx/LPC11xx/vectors.c
index 34b220807..63b343ea2 100644
--- a/os/ports/GCC/ARMCMx/LPC11xx/vectors.c
+++ b/os/ports/GCC/ARMCMx/LPC11xx/vectors.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -81,7 +82,7 @@ extern void VectorBC(void);
#endif
/**
- * @brief LPC11xx vectors table.
+ * @brief LPC11xx vectors table.
*/
#if !defined(__DOXYGEN__)
__attribute__ ((section("vectors")))
@@ -106,7 +107,7 @@ void (*_vectors[])(void) = {
* @details Any undefined exception vector points to this function by default.
* This function simply stops the system into an infinite loop.
*
- * @notapi
+ * @notapi
*/
#if !defined(__DOXYGEN__)
__attribute__ ((naked))
diff --git a/os/ports/GCC/ARMCMx/LPC13xx/cmparams.h b/os/ports/GCC/ARMCMx/LPC13xx/cmparams.h
index fb08f181f..ee49e5de9 100644
--- a/os/ports/GCC/ARMCMx/LPC13xx/cmparams.h
+++ b/os/ports/GCC/ARMCMx/LPC13xx/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/LPC13xx/port.mk b/os/ports/GCC/ARMCMx/LPC13xx/port.mk
index 3ab940082..d87487e54 100644
--- a/os/ports/GCC/ARMCMx/LPC13xx/port.mk
+++ b/os/ports/GCC/ARMCMx/LPC13xx/port.mk
@@ -1,10 +1,11 @@
# List of the ChibiOS/RT Cortex-M0 LPC13xx port files.
-PORTSRC = $(CHIBIOS)/os/ports/GCC/ARMCMx/LPC13xx/vectors.c \
+PORTSRC = $(CHIBIOS)/os/ports/GCC/ARMCMx/crt0.c \
+ $(CHIBIOS)/os/ports/GCC/ARMCMx/LPC13xx/vectors.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v7m.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/nvic.c
-PORTASM = ${CHIBIOS}/os/ports/GCC/ARMCMx/crt0_v7m.s
+PORTASM =
PORTINC = ${CHIBIOS}/os/ports/GCC/ARMCMx \
${CHIBIOS}/os/ports/GCC/ARMCMx/LPC13xx
diff --git a/os/ports/GCC/ARMCMx/LPC13xx/vectors.c b/os/ports/GCC/ARMCMx/LPC13xx/vectors.c
index 4602f3c1b..1e27c4fc8 100644
--- a/os/ports/GCC/ARMCMx/LPC13xx/vectors.c
+++ b/os/ports/GCC/ARMCMx/LPC13xx/vectors.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -105,7 +106,7 @@ extern void Vector11C(void);
#endif
/**
- * @brief LPC13xx vectors table.
+ * @brief LPC13xx vectors table.
*/
#if !defined(__DOXYGEN__)
__attribute__ ((section("vectors")))
@@ -136,7 +137,7 @@ void (*_vectors[])(void) = {
* @details Any undefined exception vector points to this function by default.
* This function simply stops the system into an infinite loop.
*
- * @notapi
+ * @notapi
*/
#if !defined(__DOXYGEN__)
__attribute__ ((naked))
diff --git a/os/ports/GCC/ARMCMx/STM32/cmparams.h b/os/ports/GCC/ARMCMx/STM32/cmparams.h
index fe9f219e5..5b630dbb8 100644
--- a/os/ports/GCC/ARMCMx/STM32/cmparams.h
+++ b/os/ports/GCC/ARMCMx/STM32/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/STM32/port.mk b/os/ports/GCC/ARMCMx/STM32/port.mk
index 80764b3d9..104b22e42 100644
--- a/os/ports/GCC/ARMCMx/STM32/port.mk
+++ b/os/ports/GCC/ARMCMx/STM32/port.mk
@@ -1,10 +1,11 @@
# List of the ChibiOS/RT Cortex-M3 STM32 port files.
-PORTSRC = $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32/vectors.c \
+PORTSRC = $(CHIBIOS)/os/ports/GCC/ARMCMx/crt0.c \
+ $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32/vectors.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v7m.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/nvic.c
-PORTASM = ${CHIBIOS}/os/ports/GCC/ARMCMx/crt0_v7m.s
+PORTASM =
PORTINC = ${CHIBIOS}/os/ports/GCC/ARMCMx \
${CHIBIOS}/os/ports/GCC/ARMCMx/STM32
diff --git a/os/ports/GCC/ARMCMx/STM32/vectors.c b/os/ports/GCC/ARMCMx/STM32/vectors.c
index 1ecbae7e4..f12e2e867 100644
--- a/os/ports/GCC/ARMCMx/STM32/vectors.c
+++ b/os/ports/GCC/ARMCMx/STM32/vectors.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -96,12 +97,13 @@ extern void VectorDC(void);
extern void VectorE0(void);
extern void VectorE4(void);
extern void VectorE8(void);
-#if defined(STM32F10X_MD_VL) || defined(STM32F10X_HD) || defined(STM32F10X_CL)
+#if defined(STM32F10X_MD_VL) || defined(STM32F10X_HD) || \
+ defined(STM32F10X_XL) || defined(STM32F10X_CL)
extern void VectorEC(void);
extern void VectorF0(void);
extern void VectorF4(void);
#endif
-#if defined(STM32F10X_HD) || defined(STM32F10X_CL)
+#if defined(STM32F10X_HD) || defined(STM32F10X_XL) || defined(STM32F10X_CL)
extern void VectorF8(void);
extern void VectorFC(void);
extern void Vector100(void);
@@ -130,7 +132,7 @@ extern void Vector14C(void);
#endif
/**
- * @brief STM32 vectors table.
+ * @brief STM32 vectors table.
*/
#if !defined(__DOXYGEN__)
__attribute__ ((section("vectors")))
@@ -172,7 +174,7 @@ void (*_vectors[])(void) = {
* @details Any undefined exception vector points to this function by default.
* This function simply stops the system into an infinite loop.
*
- * @notapi
+ * @notapi
*/
#if !defined(__DOXYGEN__)
__attribute__ ((naked))
diff --git a/os/ports/GCC/ARMCMx/chcore.c b/os/ports/GCC/ARMCMx/chcore.c
index 4bb0436cd..5b210b8fa 100644
--- a/os/ports/GCC/ARMCMx/chcore.c
+++ b/os/ports/GCC/ARMCMx/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/chcore.h b/os/ports/GCC/ARMCMx/chcore.h
index 3fe046a95..5d47a6699 100644
--- a/os/ports/GCC/ARMCMx/chcore.h
+++ b/os/ports/GCC/ARMCMx/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -28,16 +29,22 @@
#ifndef _CHCORE_H_
#define _CHCORE_H_
-#include "nvic.h"
-
/*===========================================================================*/
-/* Port constants. */
+/* Port constants (common). */
/*===========================================================================*/
-#define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */
-#define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */
-#define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */
-#define CORTEX_M4 4 /**< @brief Cortex-M4 variant. */
+/* Added to make the header stand-alone when included from asm.*/
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */
+#define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */
+#define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */
+#define CORTEX_M4 4 /**< @brief Cortex-M4 variant. */
/* Inclusion of the Cortex-Mx implementation specific parameters.*/
#include "cmparams.h"
@@ -50,36 +57,26 @@
#error "unknown or unsupported Cortex-M model"
#endif
-/*===========================================================================*/
-/* Port statically derived parameters. */
-/*===========================================================================*/
-
/**
* @brief Total priority levels.
*/
-#define CORTEX_PRIORITY_LEVELS (1 << CORTEX_PRIORITY_BITS)
+#define CORTEX_PRIORITY_LEVELS (1 << CORTEX_PRIORITY_BITS)
/**
* @brief Minimum priority level.
* @details This minimum priority level is calculated from the number of
* priority bits supported by the specific Cortex-Mx implementation.
*/
-#define CORTEX_MINIMUM_PRIORITY (CORTEX_PRIORITY_LEVELS - 1)
+#define CORTEX_MINIMUM_PRIORITY (CORTEX_PRIORITY_LEVELS - 1)
/**
* @brief Maximum priority level.
* @details The maximum allowed priority level is always zero.
*/
-#define CORTEX_MAXIMUM_PRIORITY 0
-
-/**
- * @brief Disabled value for BASEPRI register.
- * @note ARMv7-M architecture only.
- */
-#define CORTEX_BASEPRI_DISABLED 0
+#define CORTEX_MAXIMUM_PRIORITY 0
/*===========================================================================*/
-/* Port macros. */
+/* Port macros (common). */
/*===========================================================================*/
/**
@@ -95,75 +92,56 @@
((n) << (8 - CORTEX_PRIORITY_BITS))
/*===========================================================================*/
-/* Port configurable parameters. */
+/* Port configurable parameters (common). */
/*===========================================================================*/
/**
- * @brief Enables the use of the WFI instruction in the idle thread loop.
+ * @brief Stack size for the system idle thread.
+ * @details This size depends on the idle thread implementation, usually
+ * the idle thread should take no more space than those reserved
+ * by @p PORT_INT_REQUIRED_STACK.
+ * @note In this port it is set to 16 because the idle thread does have
+ * a stack frame when compiling without optimizations. You may
+ * reduce this value to zero when compiling with optimizations.
*/
-#ifndef CORTEX_ENABLE_WFI_IDLE
-#define CORTEX_ENABLE_WFI_IDLE FALSE
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 16
#endif
/**
- * @brief SYSTICK handler priority.
- * @note The default SYSTICK handler priority is calculated as the priority
- * level in the middle of the numeric priorities range.
+ * @brief Per-thread stack overhead for interrupts servicing.
+ * @details This constant is used in the calculation of the correct working
+ * area size.
+ * This value can be zero on those architecture where there is a
+ * separate interrupt stack and the stack space between @p intctx and
+ * @p extctx is known to be zero.
+ * @note In this port it is conservatively set to 16 because the function
+ * @p chSchDoRescheduleI() can have a stack frame, expecially with
+ * compiler optimizations disabled.
*/
-#ifndef CORTEX_PRIORITY_SYSTICK
-#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
-#else
-/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
-#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
-#endif
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 16
#endif
/**
- * @brief SVCALL handler priority.
- * @note The default SVCALL handler priority is calculated as
- * @p CORTEX_MAXIMUM_PRIORITY+1, in the ARMv7-M port this reserves
- * the @p CORTEX_MAXIMUM_PRIORITY priority level as fast interrupts
- * priority level.
- * @note The SVCALL vector is only used in the ARMv7-M port, it is available
- * to user in the ARMv6-M port.
+ * @brief Enables the use of the WFI instruction in the idle thread loop.
*/
-#ifndef CORTEX_PRIORITY_SVCALL
-#define CORTEX_PRIORITY_SVCALL (CORTEX_MAXIMUM_PRIORITY + 1)
-#else
-/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL)
-#error "invalid priority level specified for CORTEX_PRIORITY_SVCALL"
-#endif
+#ifndef CORTEX_ENABLE_WFI_IDLE
+#define CORTEX_ENABLE_WFI_IDLE FALSE
#endif
/**
- * @brief PENDSV handler priority.
- * @note The default PENDSV handler priority is set at the
- * @p CORTEX_MINIMUM_PRIORITY priority level.
- * @note The PENDSV vector is only used in the ARMv7-M legacy port, it is
- * available to user in the ARMv6-M and ARMv7-M ports.
- * @note In the ARMv7-M legacy port this value should be not changed from
- * the minimum priority level.
+ * @brief SYSTICK handler priority.
+ * @note The default SYSTICK handler priority is calculated as the priority
+ * level in the middle of the numeric priorities range.
*/
-#ifndef CORTEX_PRIORITY_PENDSV
-#define CORTEX_PRIORITY_PENDSV CORTEX_MINIMUM_PRIORITY
+#ifndef CORTEX_PRIORITY_SYSTICK
+#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
#else
/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_PENDSV)
-#error "invalid priority level specified for CORTEX_PRIORITY_PENDSV"
-#endif
+#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
+#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
#endif
-
-/**
- * @brief BASEPRI level within kernel lock.
- * @note This value must not mask the SVCALL priority level or the
- * kernel would hard fault.
- * @note ARMv7-M architecture only.
- */
-#ifndef CORTEX_BASEPRI_KERNEL
-#define CORTEX_BASEPRI_KERNEL \
- CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1)
#endif
/**
@@ -171,14 +149,18 @@
* @note The default value is 64 in order to comply with EABI, reducing
* the value to 32 can save some RAM space if you don't care about
* binary compatibility with EABI compiled libraries.
- * @note Allowed values are 32 or 64.
+ * @note Allowed values are 32 or 64.
*/
#ifndef CORTEX_STACK_ALIGNMENT
-#define CORTEX_STACK_ALIGNMENT 64
+#define CORTEX_STACK_ALIGNMENT 64
#endif
/*===========================================================================*/
-/* Port exported info. */
+/* Port derived parameters (common). */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port exported info (common). */
/*===========================================================================*/
/**
@@ -186,62 +168,26 @@
*/
#define CH_ARCHITECTURE_ARM
-#if defined(__DOXYGEN__)
-/**
- * @brief Macro defining the specific ARM architecture.
- * @note This macro is for documentation only, the real name changes
- * depending on the selected architecture, the possible names are:
- * - CH_ARCHITECTURE_ARM_v6M.
- * - CH_ARCHITECTURE_ARM_v7M.
- * .
- */
-#define CH_ARCHITECTURE_ARM_vxm
-
/**
- * @brief Name of the implemented architecture.
- * @note The value is for documentation only, the real value changes
- * depending on the selected architecture, the possible values are:
- * - "ARMv6-M".
- * - "ARMv7-M".
- * - "ARMv7-ME".
- * .
+ * @brief Name of the compiler supported by this port.
*/
-#define CH_ARCHITECTURE_NAME "ARMvx-M"
-
-/**
- * @brief Name of the architecture variant (optional).
- * @note The value is for documentation only, the real value changes
- * depending on the selected architecture, the possible values are:
- * - "Cortex-M0"
- * - "Cortex-M1"
- * - "Cortex-M3"
- * - "Cortex-M4"
- * .
- */
-#define CH_CORE_VARIANT_NAME "Cortex-Mx"
-
-#elif CORTEX_MODEL == CORTEX_M4
-#define CH_ARCHITECTURE_ARM_v7M
-#define CH_ARCHITECTURE_NAME "ARMv7-ME"
-#define CH_CORE_VARIANT_NAME "Cortex-M4"
-#elif CORTEX_MODEL == CORTEX_M3
-#define CH_ARCHITECTURE_ARM_v7M
-#define CH_ARCHITECTURE_NAME "ARMv7-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M3"
-#elif CORTEX_MODEL == CORTEX_M1
-#define CH_ARCHITECTURE_ARM_v6M
-#define CH_ARCHITECTURE_NAME "ARMv6-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M1"
-#elif CORTEX_MODEL == CORTEX_M0
-#define CH_ARCHITECTURE_ARM_v6M
-#define CH_ARCHITECTURE_NAME "ARMv6-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M0"
-#endif
+#define CH_COMPILER_NAME "GCC "__VERSION__
/*===========================================================================*/
/* Port implementation part (common). */
/*===========================================================================*/
+/* Includes the sub-architecture-specific part.*/
+#if (CORTEX_MODEL == CORTEX_M0) || (CORTEX_MODEL == CORTEX_M1)
+#include "chcore_v6m.h"
+#elif (CORTEX_MODEL == CORTEX_M3) || (CORTEX_MODEL == CORTEX_M4)
+#include "chcore_v7m.h"
+#endif
+
+#if !defined(_FROM_ASM_)
+
+#include "nvic.h"
+
/**
* @brief Stack and memory alignment enforcement.
*/
@@ -258,11 +204,6 @@ typedef uint32_t stkalign_t __attribute__ ((aligned (4)));
#error "invalid stack alignment selected"
#endif
-/**
- * @brief Generic ARM register.
- */
-typedef void *regarm_t;
-
#if defined(__DOXYGEN__)
/**
* @brief Interrupt saved context.
@@ -294,6 +235,20 @@ struct context {
};
/**
+ * @brief Platform dependent part of the @p chThdCreateI() API.
+ * @details This code usually setup the context switching frame represented
+ * by an @p intctx structure.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
+ wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.r13->r4 = pf; \
+ tp->p_ctx.r13->r5 = arg; \
+ tp->p_ctx.r13->lr = _port_thread_start; \
+}
+
+/**
* @brief Enforces a correct alignment for a stack area size value.
*/
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
@@ -301,10 +256,10 @@ struct context {
/**
* @brief Computes the thread working area global size.
*/
-#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
- sizeof(struct intctx) + \
- sizeof(struct extctx) + \
- (n) + (INT_REQUIRED_STACK))
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
@@ -313,12 +268,7 @@ struct context {
*/
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
-/* Includes the architecture-specific implementation part.*/
-#if defined(CH_ARCHITECTURE_ARM_v6M)
-#include "chcore_v6m.h"
-#elif defined(CH_ARCHITECTURE_ARM_v7M)
-#include "chcore_v7m.h"
-#endif
+#endif /* _FROM_ASM_ */
#endif /* _CHCORE_H_ */
diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c
index dbff1d07c..18082e86f 100644
--- a/os/ports/GCC/ARMCMx/chcore_v6m.c
+++ b/os/ports/GCC/ARMCMx/chcore_v6m.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -28,16 +29,6 @@
#include "ch.h"
/**
- * @brief PC register temporary storage.
- */
-regarm_t _port_saved_pc;
-
-/**
- * @brief IRQ nesting counter.
- */
-unsigned _port_irq_nesting;
-
-/**
* @brief System Timer vector.
* @details This interrupt is used as system tick.
* @note The timer must be initialized in the startup code.
@@ -53,39 +44,63 @@ CH_IRQ_HANDLER(SysTickVector) {
CH_IRQ_EPILOGUE();
}
+#if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__)
+/**
+ * @brief NMI vector.
+ * @details The NMI vector is used for exception mode re-entering after a
+ * context switch.
+ */
+void NMIVector(void) {
+ register struct extctx *ctxp;
+
+ /* Discarding the current exception context and positioning the stack to
+ point to the real one.*/
+ asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory");
+ ctxp++;
+ asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory");
+ port_unlock_from_isr();
+}
+#endif /* !CORTEX_ALTERNATE_SWITCH */
+
+#if CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__)
+/**
+ * @brief PendSV vector.
+ * @details The PendSV vector is used for exception mode re-entering after a
+ * context switch.
+ */
+void PendSVVector(void) {
+ register struct extctx *ctxp;
+
+ /* Discarding the current exception context and positioning the stack to
+ point to the real one.*/
+ asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory");
+ ctxp++;
+ asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory");
+}
+#endif /* CORTEX_ALTERNATE_SWITCH */
+
/**
* @brief Post-IRQ switch code.
- * @details On entry the stack and the registers are restored by the exception
- * return, the PC value is stored in @p _port_saved_pc, the interrupts
- * are disabled.
+ * @details The switch is performed in thread context then an NMI exception
+ * is enforced in order to return to the exact point before the
+ * preemption.
*/
#if !defined(__DOXYGEN__)
__attribute__((naked))
#endif
void _port_switch_from_isr(void) {
- /* Note, saves r4 to make space for the PC.*/
- asm volatile ("push {r0, r1, r2, r3, r4} \n\t"
- "mrs r0, APSR \n\t"
- "mov r1, r12 \n\t"
- "push {r0, r1, lr} \n\t"
- "ldr r0, =_port_saved_pc \n\t"
- "ldr r0, [r0] \n\t"
- "add r0, r0, #1 \n\t"
- "str r0, [sp, #28]" : : : "memory");
chSchDoRescheduleI();
-
- /* Note, the last registers are restored alone after re-enabling the
- interrupts in order to minimize the (very remote and unlikely)
- possibility that the stack is filled by continuous and saturating
- interrupts that would not allow that last words to be pulled out of
- the stack.*/
- asm volatile ("pop {r0, r1, r2} \n\t"
- "mov r12, r1 \n\t"
- "msr APSR, r0 \n\t"
- "mov lr, r2 \n\t"
- "cpsie i \n\t"
- "pop {r0, r1, r2, r3, pc}" : : : "memory");
+#if CORTEX_ALTERNATE_SWITCH
+ SCB_ICSR = ICSR_PENDSVSET;
+ port_unlock();
+#else
+ SCB_ICSR = ICSR_NMIPENDSET;
+#endif
+ /* The following loop should never be executed, the exception will kick in
+ immediately.*/
+ while (TRUE)
+ ;
}
#define PUSH_CONTEXT(sp) { \
@@ -119,16 +134,9 @@ void _port_switch_from_isr(void) {
#if !defined(__DOXYGEN__)
__attribute__((naked))
#endif
-void port_switch(Thread *ntp, Thread *otp) {
+void _port_switch(Thread *ntp, Thread *otp) {
register struct intctx *r13 asm ("r13");
- /* Stack overflow check, if enabled.*/
-#if CH_DBG_ENABLE_STACK_CHECK
- if ((void *)(r13 - 1) < (void *)(otp + 1))
- asm volatile ("movs r0, #0 \n\t"
- "b chDbgPanic");
-#endif /* CH_DBG_ENABLE_STACK_CHECK */
-
PUSH_CONTEXT(r13);
otp->p_ctx.r13 = r13;
@@ -138,6 +146,33 @@ void port_switch(Thread *ntp, Thread *otp) {
}
/**
+ * @brief IRQ epilogue code.
+ *
+ * @param[in] lr value of the @p LR register on ISR entry
+ */
+void _port_irq_epilogue(regarm_t lr) {
+
+ if (lr != (regarm_t)0xFFFFFFF1) {
+ port_lock_from_isr();
+ if (chSchIsRescRequiredExI()) {
+ register struct extctx *ctxp;
+
+ /* Adding an artificial exception return context, there is no need to
+ populate it fully.*/
+ asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory");
+ ctxp--;
+ asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory");
+ ctxp->pc = _port_switch_from_isr;
+ ctxp->xpsr = (regarm_t)0x01000000;
+ /* Note, returning without unlocking is intentional, this is done in
+ order to keep the rest of the context switching atomic.*/
+ return;
+ }
+ port_unlock_from_isr();
+ }
+}
+
+/**
* @brief Start a thread by invoking its work function.
* @details If the work function returns @p chThdExit() is automatically
* invoked.
diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h
index 1bd2f777e..2141ee468 100644
--- a/os/ports/GCC/ARMCMx/chcore_v6m.h
+++ b/os/ports/GCC/ARMCMx/chcore_v6m.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -29,33 +30,87 @@
#define _CHCORE_V6M_H_
/*===========================================================================*/
+/* Port constants. */
+/*===========================================================================*/
+
+/**
+ * @brief PendSV priority level.
+ * @note This priority is enforced to be equal to @p 0,
+ * this handler always have the highest priority that cannot preempt
+ * the kernel.
+ */
+#define CORTEX_PRIORITY_PENDSV 0
+
+/*===========================================================================*/
+/* Port configurable parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief Alternate preemption method.
+ * @details Activating this option will make the Kernel use the PendSV
+ * handler for preemption instead of the NMI handler.
+ */
+#ifndef CORTEX_ALTERNATE_SWITCH
+#define CORTEX_ALTERNATE_SWITCH FALSE
+#endif
+
+/*===========================================================================*/
+/* Port derived parameters. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port exported info. */
+/*===========================================================================*/
+
+/**
+ * @brief Macro defining the specific ARM architecture.
+ */
+#define CH_ARCHITECTURE_ARM_v6M
+
+/**
+ * @brief Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARMv6-M"
+
+/**
+ * @brief Name of the architecture variant.
+ */
+#if (CORTEX_MODEL == CORTEX_M0) || defined(__DOXYGEN__)
+#define CH_CORE_VARIANT_NAME "Cortex-M0"
+#elif (CORTEX_MODEL == CORTEX_M1)
+#define CH_CORE_VARIANT_NAME "Cortex-M1"
+#endif
+
+/**
+ * @brief Port-specific information string.
+ */
+#if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__)
+#define CH_PORT_INFO "Preemption through NMI"
+#else
+#define CH_PORT_INFO "Preemption through PendSV"
+#endif
+
+/*===========================================================================*/
/* Port implementation part. */
/*===========================================================================*/
+#if !defined(_FROM_ASM_)
+
/**
- * @brief Cortex-Mx exception context.
+ * @brief Generic ARM register.
*/
-struct cmxctx {
- regarm_t r0;
- regarm_t r1;
- regarm_t r2;
- regarm_t r3;
- regarm_t r12;
- regarm_t lr_thd;
- regarm_t pc;
- regarm_t xpsr;
-};
+typedef void *regarm_t;
#if !defined(__DOXYGEN__)
struct extctx {
- regarm_t xpsr;
- regarm_t r12;
- regarm_t lr;
regarm_t r0;
regarm_t r1;
regarm_t r2;
regarm_t r3;
+ regarm_t r12;
+ regarm_t lr_thd;
regarm_t pc;
+ regarm_t xpsr;
};
struct intctx {
@@ -72,75 +127,20 @@ struct intctx {
#endif
/**
- * @brief Platform dependent part of the @p chThdCreateI() API.
- * @details This code usually setup the context switching frame represented
- * by an @p intctx structure.
- */
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
- wsize - \
- sizeof(struct intctx)); \
- tp->p_ctx.r13->r4 = pf; \
- tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->lr = _port_thread_start; \
-}
-
-/**
- * @brief Stack size for the system idle thread.
- * @details This size depends on the idle thread implementation, usually
- * the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
- * @note In this port it is set to 8 because the idle thread does have
- * a stack frame when compiling without optimizations. You may
- * reduce this value to zero when compiling with optimizations.
- */
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 8
-#endif
-
-/**
- * @brief Per-thread stack overhead for interrupts servicing.
- * @details This constant is used in the calculation of the correct working
- * area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
- * compiler optimizations disabled.
- */
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 16
-#endif
-
-/**
* @brief IRQ prologue code.
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_PROLOGUE() { \
- port_lock_from_isr(); \
- _port_irq_nesting++; \
- port_unlock_from_isr(); \
-}
+#define PORT_IRQ_PROLOGUE() \
+ regarm_t _saved_lr; \
+ asm volatile ("mov %0, lr" : "=r" (_saved_lr) : : "memory")
/**
* @brief IRQ epilogue code.
* @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_EPILOGUE() { \
- port_lock_from_isr(); \
- if ((--_port_irq_nesting == 0) && chSchIsRescRequiredExI()) { \
- register struct cmxctx *ctxp; \
- \
- asm volatile ("mrs %0, PSP" : "=r" (ctxp) : ); \
- _port_saved_pc = ctxp->pc; \
- ctxp->pc = _port_switch_from_isr; \
- return; \
- } \
- port_unlock_from_isr(); \
-}
+#define PORT_IRQ_EPILOGUE() _port_irq_epilogue(_saved_lr)
/**
* @brief IRQ handler function declaration.
@@ -160,8 +160,9 @@ struct intctx {
* @brief Port-related initialization code.
*/
#define port_init() { \
- _port_irq_nesting = 0; \
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \
+ NVICSetSystemHandlerPriority(HANDLER_PENDSV, \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \
NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \
}
@@ -227,22 +228,41 @@ struct intctx {
#define port_wait_for_interrupt()
#endif
-#if !defined(__DOXYGEN__)
-extern regarm_t _port_saved_pc;
-extern unsigned _port_irq_nesting;
+/**
+ * @brief Performs a context switch between two threads.
+ * @details This is the most critical code in any port, this function
+ * is responsible for the context switch between 2 threads.
+ * @note The implementation of this code affects <b>directly</b> the context
+ * switch performance so optimize here as much as you can.
+ *
+ * @param[in] ntp the thread to be switched in
+ * @param[in] otp the thread to be switched out
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
+#define port_switch(ntp, otp) _port_switch(ntp, otp)
+#else
+#define port_switch(ntp, otp) { \
+ register struct intctx *r13 asm ("r13"); \
+ if ((void *)(r13 - 1) < (void *)(otp + 1)) \
+ chDbgPanic("stack overflow"); \
+ _port_switch(ntp, otp); \
+}
#endif
#ifdef __cplusplus
extern "C" {
#endif
void port_halt(void);
- void port_switch(Thread *ntp, Thread *otp);
+ void _port_switch(Thread *ntp, Thread *otp);
+ void _port_irq_epilogue(regarm_t lr);
void _port_switch_from_isr(void);
void _port_thread_start(void);
#ifdef __cplusplus
}
#endif
+#endif /* _FROM_ASM_ */
+
#endif /* _CHCORE_V6M_H_ */
/** @} */
diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c
index 6e3732a8d..2cf5cfe6b 100644
--- a/os/ports/GCC/ARMCMx/chcore_v7m.c
+++ b/os/ports/GCC/ARMCMx/chcore_v7m.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -27,9 +28,8 @@
#include "ch.h"
-#if !defined(CH_CURRP_REGISTER_CACHE) || defined(__DOXXYGEN__)
/**
- * @brief Internal context stacking.
+ * @brief Internal context stacking.
*/
#define PUSH_CONTEXT() { \
asm volatile ("push {r4, r5, r6, r7, r8, r9, r10, r11, lr}" \
@@ -43,17 +43,6 @@
asm volatile ("pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}" \
: : : "memory"); \
}
-#else /* defined(CH_CURRP_REGISTER_CACHE) */
-#define PUSH_CONTEXT() { \
- asm volatile ("push {r4, r5, r6, r8, r9, r10, r11, lr}" \
- : : : "memory"); \
-}
-
-#define POP_CONTEXT() { \
- asm volatile ("pop {r4, r5, r6, r8, r9, r10, r11, pc}" \
- : : : "memory"); \
-}
-#endif /* defined(CH_CURRP_REGISTER_CACHE) */
#if !CH_OPTIMIZE_SPEED
void _port_lock(void) {
@@ -83,10 +72,12 @@ CH_IRQ_HANDLER(SysTickVector) {
CH_IRQ_EPILOGUE();
}
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
/**
* @brief SVC vector.
* @details The SVC vector is used for exception mode re-entering after a
* context switch.
+ * @note The PendSV vector is only used in advanced kernel mode.
*/
void SVCallVector(void) {
register struct extctx *ctxp;
@@ -98,9 +89,28 @@ void SVCallVector(void) {
asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory");
port_unlock_from_isr();
}
+#endif /* !CORTEX_SIMPLIFIED_PRIORITY */
+#if CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
/**
- * @brief Reschedule verification and setup after an IRQ.
+ * @brief PendSV vector.
+ * @details The PendSV vector is used for exception mode re-entering after a
+ * context switch.
+ * @note The PendSV vector is only used in compact kernel mode.
+ */
+void PendSVVector(void) {
+ register struct extctx *ctxp;
+
+ /* Discarding the current exception context and positioning the stack to
+ point to the real one.*/
+ asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory");
+ ctxp++;
+ asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory");
+}
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
+
+/**
+ * @brief Reschedule verification and setup after an IRQ.
*/
void _port_irq_epilogue(void) {
@@ -133,7 +143,14 @@ __attribute__((naked))
void _port_switch_from_isr(void) {
chSchDoRescheduleI();
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
asm volatile ("svc #0");
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+ SCB_ICSR = ICSR_PENDSVSET;
+ port_unlock();
+ while (TRUE)
+ ;
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
}
/**
diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h
index 2a4838669..297bd4e54 100644
--- a/os/ports/GCC/ARMCMx/chcore_v7m.h
+++ b/os/ports/GCC/ARMCMx/chcore_v7m.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -29,9 +30,111 @@
#define _CHCORE_V7M_H_
/*===========================================================================*/
+/* Port constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Disabled value for BASEPRI register.
+ */
+#define CORTEX_BASEPRI_DISABLED 0
+
+/*===========================================================================*/
+/* Port configurable parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief Simplified priority handling flag.
+ * @details Activating this option will make the Kernel work in compact mode.
+ */
+#ifndef CORTEX_SIMPLIFIED_PRIORITY
+#define CORTEX_SIMPLIFIED_PRIORITY FALSE
+#endif
+
+/**
+ * @brief SVCALL handler priority.
+ * @note The default SVCALL handler priority is defaulted to
+ * @p CORTEX_MAXIMUM_PRIORITY+1, this reserves the
+ * @p CORTEX_MAXIMUM_PRIORITY priority level as fast interrupts
+ * priority level.
+ */
+#ifndef CORTEX_PRIORITY_SVCALL
+#define CORTEX_PRIORITY_SVCALL (CORTEX_MAXIMUM_PRIORITY + 1)
+#else
+/* If it is externally redefined then better perform a validity check on it.*/
+#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL)
+#error "invalid priority level specified for CORTEX_PRIORITY_SVCALL"
+#endif
+#endif
+
+/*===========================================================================*/
+/* Port derived parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief BASEPRI level within kernel lock.
+ * @note In compact kernel mode this constant value is enforced to zero.
+ */
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
+#define CORTEX_BASEPRI_KERNEL \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1)
+#else
+#define CORTEX_BASEPRI_KERNEL 0
+#endif
+
+/**
+ * @brief PendSV priority level.
+ * @note This priority is enforced to be equal to @p CORTEX_BASEPRI_KERNEL,
+ * this handler always have the highest priority that cannot preempt
+ * the kernel.
+ */
+#define CORTEX_PRIORITY_PENDSV CORTEX_BASEPRI_KERNEL
+
+/*===========================================================================*/
+/* Port exported info. */
+/*===========================================================================*/
+
+#if (CORTEX_MODEL == CORTEX_M3) || defined(__DOXYGEN__)
+/**
+ * @brief Macro defining the specific ARM architecture.
+ */
+#define CH_ARCHITECTURE_ARM_v7M
+
+/**
+ * @brief Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARMv7-M"
+
+/**
+ * @brief Name of the architecture variant.
+ */
+#define CH_CORE_VARIANT_NAME "Cortex-M3"
+
+#elif (CORTEX_MODEL == CORTEX_M4)
+#define CH_ARCHITECTURE_ARM_v7ME
+#define CH_ARCHITECTURE_NAME "ARMv7-ME"
+#define CH_CORE_VARIANT_NAME "Cortex-M4"
+#endif
+
+/**
+ * @brief Port-specific information string.
+ */
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
+#define CH_PORT_INFO "Advanced kernel mode"
+#else
+#define CH_PORT_INFO "Compact kernel mode"
+#endif
+
+/*===========================================================================*/
/* Port implementation part. */
/*===========================================================================*/
+#if !defined(_FROM_ASM_)
+
+/**
+ * @brief Generic ARM register.
+ */
+typedef void *regarm_t;
+
#if !defined(__DOXYGEN__)
struct extctx {
regarm_t r0;
@@ -48,9 +151,7 @@ struct intctx {
regarm_t r4;
regarm_t r5;
regarm_t r6;
-#ifndef CH_CURRP_REGISTER_CACHE
regarm_t r7;
-#endif
regarm_t r8;
regarm_t r9;
regarm_t r10;
@@ -60,48 +161,6 @@ struct intctx {
#endif
/**
- * @brief Platform dependent part of the @p chThdCreateI() API.
- * @details This code usually setup the context switching frame represented
- * by an @p intctx structure.
- */
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
- wsize - \
- sizeof(struct intctx)); \
- tp->p_ctx.r13->r4 = pf; \
- tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->lr = _port_thread_start; \
-}
-
-/**
- * @brief Stack size for the system idle thread.
- * @details This size depends on the idle thread implementation, usually
- * the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
- * @note In this port it is set to 8 because the idle thread does have
- * a stack frame when compiling without optimizations. You may
- * reduce this value to zero when compiling with optimizations.
- */
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 8
-#endif
-
-/**
- * @brief Per-thread stack overhead for interrupts servicing.
- * @details This constant is used in the calculation of the correct working
- * area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
- * compiler optimizations disabled.
- */
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 16
-#endif
-
-/**
* @brief IRQ prologue code.
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
@@ -136,6 +195,8 @@ struct intctx {
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \
NVICSetSystemHandlerPriority(HANDLER_SVCALL, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL)); \
+ NVICSetSystemHandlerPriority(HANDLER_PENDSV, \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \
NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \
}
@@ -146,16 +207,20 @@ struct intctx {
* more actions.
* @note In this port this it raises the base priority to kernel level.
*/
-#if CH_OPTIMIZE_SPEED
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
+#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
#define port_lock() { \
register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \
asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); \
}
-#else
+#else /* !CH_OPTIMIZE_SPEED */
#define port_lock() { \
asm volatile ("bl _port_lock" : : : "r3", "lr", "memory"); \
}
-#endif
+#endif /* !CH_OPTIMIZE_SPEED */
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_lock() asm volatile ("cpsid i" : : : "memory")
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Kernel-unlock action.
@@ -163,16 +228,20 @@ struct intctx {
* more actions.
* @note In this port this it lowers the base priority to user level.
*/
-#if CH_OPTIMIZE_SPEED
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
+#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
#define port_unlock() { \
register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; \
asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); \
}
-#else
+#else /* !CH_OPTIMIZE_SPEED */
#define port_unlock() { \
asm volatile ("bl _port_unlock" : : : "r3", "lr", "memory"); \
}
-#endif
+#endif /* !CH_OPTIMIZE_SPEED */
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_unlock() asm volatile ("cpsie i" : : : "memory")
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Kernel-lock action from an interrupt handler.
@@ -205,21 +274,29 @@ struct intctx {
* @note Interrupt sources above kernel level remains enabled.
* @note In this port it raises/lowers the base priority to kernel level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_suspend() { \
register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \
asm volatile ("msr BASEPRI, %0 \n\t" \
"cpsie i" : : "r" (tmp) : "memory"); \
}
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_suspend() asm volatile ("cpsid i" : : : "memory")
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Enables all the interrupt sources.
* @note In this port it lowers the base priority to user level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_enable() { \
register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; \
asm volatile ("msr BASEPRI, %0 \n\t" \
"cpsie i" : : "r" (tmp) : "memory"); \
}
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_enable() asm volatile ("cpsie i" : : : "memory")
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Enters an architecture-dependent IRQ-waiting mode.
@@ -253,6 +330,8 @@ extern "C" {
}
#endif
+#endif /* _FROM_ASM_ */
+
#endif /* _CHCORE_V7M_H_ */
/** @} */
diff --git a/os/ports/GCC/ARMCMx/chtypes.h b/os/ports/GCC/ARMCMx/chtypes.h
index f4bf93c1c..938a736d0 100644
--- a/os/ports/GCC/ARMCMx/chtypes.h
+++ b/os/ports/GCC/ARMCMx/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/crt0.c b/os/ports/GCC/ARMCMx/crt0.c
new file mode 100644
index 000000000..0bb88dd83
--- /dev/null
+++ b/os/ports/GCC/ARMCMx/crt0.c
@@ -0,0 +1,274 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ARMCMx/crt0.c
+ * @brief Generic ARMvx-M (Cortex-M0/M1/M3/M4) startup file for ChibiOS/RT.
+ *
+ * @addtogroup ARMCMx_STARTUP
+ * @{
+ */
+
+#include "chtypes.h"
+
+#define FALSE 0
+#define TRUE (!FALSE)
+
+typedef void (*funcp_t)(void);
+typedef funcp_t * funcpp_t;
+
+/**
+ * @brief Control special register initialization value.
+ * @details The system is setup to run in privileged mode using the PSP
+ * stack (dual stack mode).
+ */
+#if !defined(CRT0_CONTROL_INIT) || defined(__DOXYGEN__)
+#define CRT0_CONTROL_INIT 0x00000002
+#endif
+
+/**
+ * @brief DATA segment initialization switch.
+ */
+#if !defined(CRT0_INIT_DATA) || defined(__DOXYGEN__)
+#define CRT0_INIT_DATA TRUE
+#endif
+
+/**
+ * @brief BSS segment initialization switch.
+ */
+#if !defined(CRT0_INIT_BSS) || defined(__DOXYGEN__)
+#define CRT0_INIT_BSS TRUE
+#endif
+
+/**
+ * @brief Constructors invocation switch.
+ */
+#if !defined(CRT0_CALL_CONSTRUCTORS) || defined(__DOXYGEN__)
+#define CRT0_CALL_CONSTRUCTORS TRUE
+#endif
+
+/**
+ * @brief Destructors invocation switch.
+ */
+#if !defined(CRT0_CALL_DESTRUCTORS) || defined(__DOXYGEN__)
+#define CRT0_CALL_DESTRUCTORS TRUE
+#endif
+
+#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
+
+/**
+ * @brief Ram end.
+ * @details This symbol must be exported by the linker script and represents
+ * the location after the last RAM location.
+ */
+extern uint8_t __ram_end__;
+
+/**
+ * @brief Main stack size.
+ * @details This symbol must be exported by the linker script and represents
+ * the main stack size.
+ * @note The main stack is the stack where interrupts and exceptions are
+ * processed.
+ */
+extern uint8_t __main_stack_size__;
+
+/**
+ * @brief Process stack size.
+ * @details This symbol must be exported by the linker script and represents
+ * the process stack size.
+ * @note The process stack is the stack used by the @p main() function.
+ */
+extern uint8_t __process_stack_size__;
+
+/**
+ * @brief ROM image of the data segment start.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern uint32_t _textdata;
+
+/**
+ * @brief Data segment start.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern uint32_t _data;
+
+/**
+ * @brief Data segment end.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern uint32_t _edata;
+
+/**
+ * @brief BSS segment start.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern uint32_t _bss_start;
+
+/**
+ * @brief BSS segment end.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern uint32_t _bss_end;
+
+/**
+ * @brief Constructors table start.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern funcp_t __init_array_start;
+
+/**
+ * @brief Constructors table end.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern funcp_t __init_array_end;
+
+/**
+ * @brief Destructors table start.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern funcp_t __fini_array_start;
+
+/**
+ * @brief Destructors table end.
+ * @pre The symbol must be aligned to a 32 bits boundary.
+ */
+extern funcp_t __fini_array_end;
+
+/**
+ * @brief Application @p main() function.
+ */
+extern void main(void);
+
+/**
+ * @brief Early initialization.
+ * @details This hook is invoked immediately after the stack initialization
+ * and before the DATA and BSS segments initialization. The
+ * default behavior is to do nothing.
+ * @note This function is a weak symbol.
+ */
+#if !defined(__DOXYGEN__)
+__attribute__((weak))
+#endif
+void __early_init(void) {}
+
+/**
+ * @brief Late initialization.
+ * @details This hook is invoked after the DATA and BSS segments
+ * initialization and before any static constructor. The
+ * default behavior is to do nothing.
+ * @note This function is a weak symbol.
+ */
+#if !defined(__DOXYGEN__)
+__attribute__((weak))
+#endif
+void __late_init(void) {}
+
+/**
+ * @brief Default @p main() function exit handler.
+ * @details This handler is invoked or the @p main() function exit. The
+ * default behavior is to enter an infinite loop.
+ * @note This function is a weak symbol.
+ */
+#if !defined(__DOXYGEN__)
+__attribute__((weak, naked))
+#endif
+void _default_exit(void) {
+ while (1)
+ ;
+}
+
+/**
+ * @brief Reset vector.
+ */
+#if !defined(__DOXYGEN__)
+__attribute__((naked))
+#endif
+void ResetHandler(void) {
+ uint32_t psp, ctl;
+
+ /* Process Stack initialization, it is allocated below the main stack. The
+ main stack is assumed to be allocated starting from @p __ram_end__
+ extending downward.*/
+ asm volatile ("cpsid i");
+ psp = SYMVAL(__ram_end__) - SYMVAL(__main_stack_size__);
+ asm volatile ("msr PSP, %0" : : "r" (psp));
+
+ ctl = CRT0_CONTROL_INIT;
+ asm volatile ("msr CONTROL, %0" : : "r" (ctl));
+ asm volatile ("isb");
+
+ /* Early initialization hook invocation.*/
+ __early_init();
+
+#if CRT0_INIT_DATA
+ /* DATA segment initialization.*/
+ {
+ uint32_t *tp, *dp;
+
+ tp = &_textdata;
+ dp = &_data;
+ while (dp < &_edata)
+ *dp++ = *tp++;
+ }
+#endif
+
+#if CRT0_INIT_BSS
+ /* BSS segment initialization.*/
+ {
+ uint32_t *bp;
+
+ bp = &_bss_start;
+ while (bp < &_bss_end)
+ *bp++ = 0;
+ }
+#endif
+
+ /* Late initialization hook invocation.*/
+ __late_init();
+
+#if CRT0_CALL_CONSTRUCTORS
+ /* Constructors invocation.*/
+ {
+ funcpp_t fpp = &__init_array_start;
+ while (fpp < &__init_array_end) {
+ (*fpp)();
+ fpp++;
+ }
+ }
+#endif
+
+ /* Invoking application main() function.*/
+ main();
+
+#if CRT0_CALL_DESTRUCTORS
+ /* Destructors invocation.*/
+ {
+ funcpp_t fpp = &__fini_array_start;
+ while (fpp < &__fini_array_end) {
+ (*fpp)();
+ fpp++;
+ }
+ }
+#endif
+
+ /* Invoking the exit handler.*/
+ _default_exit();
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARMCMx/crt0_v6m.s b/os/ports/GCC/ARMCMx/crt0_v6m.s
index baaf6f32d..478625d42 100644
--- a/os/ports/GCC/ARMCMx/crt0_v6m.s
+++ b/os/ports/GCC/ARMCMx/crt0_v6m.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/crt0_v7m.s b/os/ports/GCC/ARMCMx/crt0_v7m.s
index 4e4a40631..c5f714a26 100644
--- a/os/ports/GCC/ARMCMx/crt0_v7m.s
+++ b/os/ports/GCC/ARMCMx/crt0_v7m.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/nvic.c b/os/ports/GCC/ARMCMx/nvic.c
index fb470c2e1..51e4280f2 100644
--- a/os/ports/GCC/ARMCMx/nvic.c
+++ b/os/ports/GCC/ARMCMx/nvic.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/nvic.h b/os/ports/GCC/ARMCMx/nvic.h
index bd5d0f31b..02f010c4a 100644
--- a/os/ports/GCC/ARMCMx/nvic.h
+++ b/os/ports/GCC/ARMCMx/nvic.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/ARMCMx/old/chcore_v7m.c b/os/ports/GCC/ARMCMx/old/chcore_v7m.c
index c8b2f3af6..244ff396e 100644
--- a/os/ports/GCC/ARMCMx/old/chcore_v7m.c
+++ b/os/ports/GCC/ARMCMx/old/chcore_v7m.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -53,7 +54,6 @@ void SysTickVector(void) {
chSysUnlockFromIsr();
}
-#if !defined(CH_CURRP_REGISTER_CACHE)
#define PUSH_CONTEXT(sp, prio) { \
asm volatile ("mrs %0, PSP \n\t" \
"stmdb %0!, {r3-r11,lr}" : \
@@ -66,20 +66,6 @@ void SysTickVector(void) {
"msr BASEPRI, r3 \n\t" \
"bx lr" : "=r" (sp) : "r" (sp)); \
}
-#else /* defined(CH_CURRP_REGISTER_CACHE) */
-#define PUSH_CONTEXT(sp, prio) { \
- asm volatile ("mrs %0, PSP \n\t" \
- "stmdb %0!, {r3-r6,r8-r11, lr}" : \
- "=r" (sp) : "r" (sp), "r" (prio)); \
-}
-
-#define POP_CONTEXT(sp) { \
- asm volatile ("ldmia %0!, {r3-r6,r8-r11, lr} \n\t" \
- "msr PSP, %0 \n\t" \
- "msr BASEPRI, r3 \n\t" \
- "bx lr" : "=r" (sp) : "r" (sp)); \
-}
-#endif /* defined(CH_CURRP_REGISTER_CACHE) */
/**
* @brief SVC vector.
diff --git a/os/ports/GCC/ARMCMx/old/chcore_v7m.h b/os/ports/GCC/ARMCMx/old/chcore_v7m.h
index 480542db1..b94afdca3 100644
--- a/os/ports/GCC/ARMCMx/old/chcore_v7m.h
+++ b/os/ports/GCC/ARMCMx/old/chcore_v7m.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -95,12 +96,12 @@ struct intctx {
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
+ * by @p PORT_INT_REQUIRED_STACK.
* @note In this port it is set to 4 because the idle thread does have
* a stack frame when compiling without optimizations.
*/
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 4
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 4
#endif
/**
@@ -112,8 +113,8 @@ struct intctx {
* @p extctx is known to be zero.
* @note This port requires no extra stack space for interrupt handling.
*/
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 0
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 0
#endif
/**
diff --git a/os/ports/GCC/ARMCMx/port.dox b/os/ports/GCC/ARMCMx/port.dox
index 32b736434..8f5efc9aa 100644
--- a/os/ports/GCC/ARMCMx/port.dox
+++ b/os/ports/GCC/ARMCMx/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -25,9 +26,28 @@
* This port supports all the cores implementing the ARMv6-M and ARMv7-M
* architectures.
*
- * @section ARMCMx_STATES_A System logical states in ARMv6-M mode
- * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
- * Cortex-M0 port:
+ * @section ARMCMx_MODES Kernel Modes
+ * The Cortex-Mx port supports two distinct kernel modes:
+ * - <b>Advanced Kernel</b> mode. In this mode the kernel only masks
+ * interrupt sources with priorities below or equal to the
+ * @p CORTEX_BASEPRI_KERNEL level. Higher priorities are not affected by
+ * the kernel critical sections and can be used for fast interrupts.
+ * This mode is not available in the ARMv6-M architecture which does not
+ * support priority masking.
+ * - <b>Compact Kernel</b> mode. In this mode the kernel handles IRQ priorities
+ * in a simplified way, all interrupt sources are disabled when the kernel
+ * enters into a critical zone and re-enabled on exit. This is simple and
+ * adequate for most applications, this mode results in a more compact and
+ * faster kernel.
+ * .
+ * The selection of the mode is performed using the port configuration option
+ * @p CORTEX_SIMPLIFIED_PRIORITY. Apart from the different handling of
+ * interrupts there are no other differences between the two modes. The
+ * kernel API is exactly the same.
+ *
+ * @section ARMCMx_STATES_A System logical states in Compact Kernel mode
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in Compact
+ * Kernel mode:
* - <b>Init</b>. This state is represented by the startup code and the
* initialization code before @p chSysInit() is executed. It has not a
* special hardware state associated.
@@ -52,21 +72,21 @@
* mode.
* - <b>Serving Fast Interrupt</b>. This state is not implemented in the
* ARMv6-M implementation.
- * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-M3 has a specific
+ * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-Mx has a specific
* asynchronous NMI vector and several synchronous fault vectors that can
* be considered belonging to this category.
* - <b>Halted</b>. Implemented as an infinite loop after globally masking all
* the maskable interrupt sources. The ARM state is whatever the processor
* was running when @p chSysHalt() was invoked.
*
- * @section ARMCMx_STATES_B System logical states in ARMv7-M mode
- * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
- * Cortex-M3 port:
+ * @section ARMCMx_STATES_B System logical states in Advanced Kernel mode
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in the
+ * Advanced Kernel mode:
* - <b>Init</b>. This state is represented by the startup code and the
* initialization code before @p chSysInit() is executed. It has not a
* special hardware state associated.
* - <b>Normal</b>. This is the state the system has after executing
- * @p chSysInit(). In this state the ARM Cortex-M3 has the BASEPRI register
+ * @p chSysInit(). In this state the ARM Cortex-Mx has the BASEPRI register
* set at @p CORTEX_BASEPRI_USER level, interrupts are not masked. The
* processor is running in thread-privileged mode.
* - <b>Suspended</b>. In this state the interrupt sources are not globally
@@ -92,7 +112,7 @@
* - <b>Serving Fast Interrupt</b>. It is basically the same of the SRI state
* but it is not possible to switch to the I-Locked state because fast
* interrupts can preempt the kernel critical zone.
- * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-M3 has a specific
+ * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-Mx has a specific
* asynchronous NMI vector and several synchronous fault vectors that can
* be considered belonging to this category.
* - <b>Halted</b>. Implemented as an infinite loop after globally masking all
@@ -139,17 +159,24 @@
* - @p IDLE_THREAD_STACK_SIZE, stack area size to be assigned to the IDLE
* thread. Usually there is no need to change this value unless inserting
* code in the IDLE thread using the @p IDLE_LOOP_HOOK hook macro.
- * - @p CORTEX_BASEPRI_KERNEL, this is the @p BASEPRI value for the kernel lock
- * code. Code running at higher priority levels must not invoke any OS API.
- * This setting is specific to the ARMv7-M architecture.
* - @p CORTEX_PRIORITY_SYSTICK, priority of the SYSTICK handler.
- * - @p CORTEX_PRIORITY_SVCALL, priority of the SVCALL handler.
* - @p CORTEX_PRIORITY_PENDSV, priority of the PENDSV handler.
* - @p CORTEX_ENABLE_WFI_IDLE, if set to @p TRUE enables the use of the
* @p <b>wfi</b> instruction from within the idle loop. This option is
* defaulted to FALSE because it can create problems with some debuggers.
* Setting this option to TRUE reduces the system power requirements.
* .
+ * @section ARMCMx_CONF_1 ARMv6-M specific options
+ * The following options are specific for the ARMv6-M architecture:
+ * - @p CORTEX_ALTERNATE_SWITCH, when activated makes the OS use the PendSV
+ * exception instead of NMI as preemption handler.
+ * .
+ * @section ARMCMx_CONF_2 ARMv7-M specific options
+ * The following options are specific for the ARMv6-M architecture:
+ * - @p CORTEX_PRIORITY_SVCALL, priority of the SVCALL handler.
+ * - @p CORTEX_SIMPLIFIED_PRIORITY, when enabled activates the Compact kernel
+ * mode.
+ * .
* @ingroup ARMCMx
*/
@@ -199,15 +226,19 @@
* @section ARMCMx_STARTUP_2 Expected linker symbols
* The startup code starts at the symbol @p ResetHandler and expects the
* following symbols to be defined in the linker script:
- * - @p __ram_end__ RAM end location +1.
+ * - @p __ram_end__ End of RAM.
* - @p __main_stack_size__ Exception stack size.
* - @p __process_stack_size__ Process stack size. This is the stack area used
* by the @p main() function.
- * - @p _textdata address of the data segment source read only data.
- * - @p _data data segment start location.
- * - @p _edata data segment end location +1.
- * - @p _bss_start BSS start location.
- * - @p _bss_end BSS end location +1.
+ * - @p _textdata Address of the data segment source read only data.
+ * - @p _data Start of the data segment.
+ * - @p _edata End of the data segment end location.
+ * - @p _bss_start Start of the BSS.
+ * - @p _bss_end End of the BSS segment.
+ * - @p __init_array_start Start of the constructors array.
+ * - @p __init_array_end End of the constructors array.
+ * - @p __fini_array_start Start of the destructors array.
+ * - @p __fini_array_end End of the destructors array.
* .
* @ingroup ARMCMx
*/
diff --git a/os/ports/GCC/AVR/chcore.c b/os/ports/GCC/AVR/chcore.c
index 082b5fd79..7cb0dda07 100644
--- a/os/ports/GCC/AVR/chcore.c
+++ b/os/ports/GCC/AVR/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -50,10 +51,8 @@ void port_switch(Thread *ntp, Thread *otp) {
asm volatile ("push r5");
asm volatile ("push r6");
asm volatile ("push r7");
-#ifndef CH_CURRP_REGISTER_CACHE
asm volatile ("push r8");
asm volatile ("push r9");
-#endif
asm volatile ("push r10");
asm volatile ("push r11");
asm volatile ("push r12");
@@ -87,10 +86,8 @@ void port_switch(Thread *ntp, Thread *otp) {
asm volatile ("pop r12");
asm volatile ("pop r11");
asm volatile ("pop r10");
-#ifndef CH_CURRP_REGISTER_CACHE
asm volatile ("pop r9");
asm volatile ("pop r8");
-#endif
asm volatile ("pop r7");
asm volatile ("pop r6");
asm volatile ("pop r5");
diff --git a/os/ports/GCC/AVR/chcore.h b/os/ports/GCC/AVR/chcore.h
index 7f15ba50e..2d33b205d 100644
--- a/os/ports/GCC/AVR/chcore.h
+++ b/os/ports/GCC/AVR/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -35,7 +36,7 @@
* @brief If enabled allows the idle thread to enter a low power mode.
*/
#ifndef ENABLE_WFI_IDLE
-#define ENABLE_WFI_IDLE 0
+#define ENABLE_WFI_IDLE 0
#endif
/**
@@ -46,12 +47,22 @@
/**
* @brief Name of the implemented architecture.
*/
-#define CH_ARCHITECTURE_NAME "AVR"
+#define CH_ARCHITECTURE_NAME "AVR"
/**
* @brief Name of the architecture variant (optional).
*/
-#define CH_CORE_VARIANT_NAME "MegaAVR"
+#define CH_CORE_VARIANT_NAME "MegaAVR"
+
+/**
+ * @brief Name of the compiler supported by this port.
+ */
+#define CH_COMPILER_NAME "GCC "__VERSION__
+
+/**
+ * @brief Port-specific information string.
+ */
+#define CH_PORT_INFO "None"
/**
* @brief 8 bits stack and memory alignment enforcement.
@@ -104,10 +115,8 @@ struct intctx {
uint8_t r12;
uint8_t r11;
uint8_t r10;
-#ifndef CH_CURRP_REGISTER_CACHE
uint8_t r9;
uint8_t r8;
-#endif
uint8_t r7;
uint8_t r6;
uint8_t r5;
@@ -148,11 +157,11 @@ struct context {
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
+ * by @p PORT_INT_REQUIRED_STACK.
* @note In this port it is set to 8.
*/
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 8
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 8
#endif
/**
@@ -164,8 +173,8 @@ struct context {
* @p extctx is known to be zero.
* @note In this port the default is 32 bytes per thread.
*/
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 32
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 32
#endif
/**
@@ -179,7 +188,7 @@ struct context {
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
(sizeof(struct intctx) - 1) + \
(sizeof(struct extctx) - 1) + \
- (n) + (INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/ports/GCC/AVR/chtypes.h b/os/ports/GCC/AVR/chtypes.h
index f180dfd4b..ceda147d5 100644
--- a/os/ports/GCC/AVR/chtypes.h
+++ b/os/ports/GCC/AVR/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/AVR/port.dox b/os/ports/GCC/AVR/port.dox
index 6187f399e..c8a506b70 100644
--- a/os/ports/GCC/AVR/port.dox
+++ b/os/ports/GCC/AVR/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/MSP430/chcore.c b/os/ports/GCC/MSP430/chcore.c
index d8b1a63de..d9192177d 100644
--- a/os/ports/GCC/MSP430/chcore.c
+++ b/os/ports/GCC/MSP430/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/MSP430/chcore.h b/os/ports/GCC/MSP430/chcore.h
index 35d9f71ef..3e3d5b5d1 100644
--- a/os/ports/GCC/MSP430/chcore.h
+++ b/os/ports/GCC/MSP430/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -35,7 +36,7 @@
* @brief Enables the use of a wait state in the idle thread loop.
*/
#ifndef ENABLE_WFI_IDLE
-#define ENABLE_WFI_IDLE 0
+#define ENABLE_WFI_IDLE 0
#endif
/**
@@ -46,12 +47,22 @@
/**
* @brief Name of the implemented architecture.
*/
-#define CH_ARCHITECTURE_NAME "MSP430"
+#define CH_ARCHITECTURE_NAME "MSP430"
/**
* @brief Name of the architecture variant (optional).
*/
-#define CH_CORE_VARIANT_NAME "MSP430"
+#define CH_CORE_VARIANT_NAME "MSP430"
+
+/**
+ * @brief Name of the compiler supported by this port.
+ */
+#define CH_COMPILER_NAME "GCC "__VERSION__
+
+/**
+ * @brief Port-specific information string.
+ */
+#define CH_PORT_INFO "None"
/**
* @brief 16 bits stack and memory alignment enforcement.
@@ -121,10 +132,10 @@ struct context {
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
+ * by @p PORT_INT_REQUIRED_STACK.
*/
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 0
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 0
#endif
/**
@@ -136,8 +147,8 @@ struct context {
* @p extctx is known to be zero.
* @note In this port the default is 32 bytes per thread.
*/
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 32
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 32
#endif
/**
@@ -151,7 +162,7 @@ struct context {
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/ports/GCC/MSP430/chtypes.h b/os/ports/GCC/MSP430/chtypes.h
index 3798a14dc..acc55c418 100644
--- a/os/ports/GCC/MSP430/chtypes.h
+++ b/os/ports/GCC/MSP430/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/MSP430/port.dox b/os/ports/GCC/MSP430/port.dox
index fad67b3e5..502e8295a 100644
--- a/os/ports/GCC/MSP430/port.dox
+++ b/os/ports/GCC/MSP430/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/PPC/SPC56x/ivor.s b/os/ports/GCC/PPC/SPC56x/ivor.s
index 725098e09..7f470d26a 100644
--- a/os/ports/GCC/PPC/SPC56x/ivor.s
+++ b/os/ports/GCC/PPC/SPC56x/ivor.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/PPC/SPC56x/vectors.s b/os/ports/GCC/PPC/SPC56x/vectors.s
index f1d43796e..820c5a7f6 100644
--- a/os/ports/GCC/PPC/SPC56x/vectors.s
+++ b/os/ports/GCC/PPC/SPC56x/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/PPC/chcore.c b/os/ports/GCC/PPC/chcore.c
index 907652e6c..c68d5e07c 100644
--- a/os/ports/GCC/PPC/chcore.c
+++ b/os/ports/GCC/PPC/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/PPC/chcore.h b/os/ports/GCC/PPC/chcore.h
index 6f45d5a82..6504532ac 100644
--- a/os/ports/GCC/PPC/chcore.h
+++ b/os/ports/GCC/PPC/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -36,12 +37,12 @@
* @brief Enables the use of the @p WFI instruction.
*/
#ifndef ENABLE_WFI_IDLE
-#define ENABLE_WFI_IDLE 0
+#define ENABLE_WFI_IDLE 0
#endif
/* Core variants identifiers.*/
-#define PPC_VARIANT_e200z3 3 /**< e200z3 core identifier. */
-#define PPC_VARIANT_e200z4 4 /**< e200z4 core identifier. */
+#define PPC_VARIANT_e200z3 3 /**< e200z3 core identifier. */
+#define PPC_VARIANT_e200z4 4 /**< e200z4 core identifier. */
/**
* @brief Core variant selector.
@@ -49,7 +50,7 @@
* possibly code paths and structures into the port layer.
*/
#if !defined(PPC_VARIANT) || defined(__DOXYGEN__)
-#define PPC_VARIANT PPC_VARIANT_e200z3
+#define PPC_VARIANT PPC_VARIANT_e200z3
#endif
/**
@@ -60,20 +61,30 @@
/**
* @brief Name of the implemented architecture.
*/
-#define CH_ARCHITECTURE_NAME "PowerPC"
+#define CH_ARCHITECTURE_NAME "Power Architecture"
/**
* @brief Name of the architecture variant.
*/
#if (PPC_VARIANT == PPC_VARIANT_e200z3) || defined(__DOXYGEN__)
-#define CH_CORE_VARIANT_NAME "e200z3"
+#define CH_CORE_VARIANT_NAME "e200z3"
#elif PPC_VARIANT == PPC_VARIANT_e200z4
-#define CH_CORE_VARIANT_NAME "e200z4"
+#define CH_CORE_VARIANT_NAME "e200z4"
#else
#error "unknown or unsupported PowerPC variant specified"
#endif
/**
+ * @brief Name of the compiler supported by this port.
+ */
+#define CH_COMPILER_NAME "GCC "__VERSION__
+
+/**
+ * @brief Port-specific information string.
+ */
+#define CH_PORT_INFO "None"
+
+/**
* @brief Base type for stack and memory alignment.
*/
typedef struct {
@@ -184,10 +195,10 @@ struct context {
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
+ * by @p PORT_INT_REQUIRED_STACK.
*/
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 0
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 0
#endif
/**
@@ -198,8 +209,8 @@ struct context {
* separate interrupt stack and the stack space between @p intctx and
* @p extctx is known to be zero.
*/
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 128
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 128
#endif
/**
@@ -213,7 +224,7 @@ struct context {
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/ports/GCC/PPC/chtypes.h b/os/ports/GCC/PPC/chtypes.h
index f0be524b6..5b5de7e1a 100644
--- a/os/ports/GCC/PPC/chtypes.h
+++ b/os/ports/GCC/PPC/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/PPC/crt0.s b/os/ports/GCC/PPC/crt0.s
index 0a2697be8..fba20e4b0 100644
--- a/os/ports/GCC/PPC/crt0.s
+++ b/os/ports/GCC/PPC/crt0.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/PPC/port.dox b/os/ports/GCC/PPC/port.dox
index 70ba4784a..e5f9e3deb 100644
--- a/os/ports/GCC/PPC/port.dox
+++ b/os/ports/GCC/PPC/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/SIMIA32/chcore.c b/os/ports/GCC/SIMIA32/chcore.c
index e2531cd4e..58f079ef5 100644
--- a/os/ports/GCC/SIMIA32/chcore.c
+++ b/os/ports/GCC/SIMIA32/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/GCC/SIMIA32/chcore.h b/os/ports/GCC/SIMIA32/chcore.h
index 87403d90e..3d5c62b23 100644
--- a/os/ports/GCC/SIMIA32/chcore.h
+++ b/os/ports/GCC/SIMIA32/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -33,12 +34,22 @@
/**
* Name of the implemented architecture.
*/
-#define CH_ARCHITECTURE_NAME "Simulator"
+#define CH_ARCHITECTURE_NAME "Simulator"
/**
* @brief Name of the architecture variant (optional).
*/
-#define CH_CORE_VARIANT_NAME "x86 (integer only)"
+#define CH_CORE_VARIANT_NAME "x86 (integer only)"
+
+/**
+ * @brief Name of the compiler supported by this port.
+ */
+#define CH_COMPILER_NAME "GCC "__VERSION__
+
+/**
+ * @brief Port-specific information string.
+ */
+#define CH_PORT_INFO "No preemption"
/**
* 16 bytes stack alignment.
@@ -107,8 +118,8 @@ struct context {
/**
* Stack size for the system idle thread.
*/
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 256
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 256
#endif
/**
@@ -117,8 +128,8 @@ struct context {
* It requires stack space because the simulated "interrupt handlers" can
* invoke host library functions inside so it better have a lot of space.
*/
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 16384
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 16384
#endif
/**
@@ -133,7 +144,7 @@ struct context {
sizeof(void *) * 4 + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* Macro used to allocate a thread working area aligned as both position and
diff --git a/os/ports/GCC/SIMIA32/chtypes.h b/os/ports/GCC/SIMIA32/chtypes.h
index 327de745a..b6e73fb96 100644
--- a/os/ports/GCC/SIMIA32/chtypes.h
+++ b/os/ports/GCC/SIMIA32/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/LPC11xx/cmparams.h b/os/ports/IAR/ARMCMx/LPC11xx/cmparams.h
index 644b8050d..2b66fbf4a 100644
--- a/os/ports/IAR/ARMCMx/LPC11xx/cmparams.h
+++ b/os/ports/IAR/ARMCMx/LPC11xx/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/LPC11xx/vectors.s b/os/ports/IAR/ARMCMx/LPC11xx/vectors.s
index 13e0eafb9..f57b2b5e4 100644
--- a/os/ports/IAR/ARMCMx/LPC11xx/vectors.s
+++ b/os/ports/IAR/ARMCMx/LPC11xx/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/LPC13xx/cmparams.h b/os/ports/IAR/ARMCMx/LPC13xx/cmparams.h
index 34177a6a9..1e970e72a 100644
--- a/os/ports/IAR/ARMCMx/LPC13xx/cmparams.h
+++ b/os/ports/IAR/ARMCMx/LPC13xx/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/LPC13xx/vectors.s b/os/ports/IAR/ARMCMx/LPC13xx/vectors.s
index 69e0c8add..8ad48d0dd 100644
--- a/os/ports/IAR/ARMCMx/LPC13xx/vectors.s
+++ b/os/ports/IAR/ARMCMx/LPC13xx/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/STM32/cmparams.h b/os/ports/IAR/ARMCMx/STM32/cmparams.h
index d75c3ca2c..3e18146c0 100644
--- a/os/ports/IAR/ARMCMx/STM32/cmparams.h
+++ b/os/ports/IAR/ARMCMx/STM32/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/STM32/vectors.s b/os/ports/IAR/ARMCMx/STM32/vectors.s
index 868741f4f..85c889267 100644
--- a/os/ports/IAR/ARMCMx/STM32/vectors.s
+++ b/os/ports/IAR/ARMCMx/STM32/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/chcore.c b/os/ports/IAR/ARMCMx/chcore.c
index 2f2122ae4..4c9cc08f9 100644
--- a/os/ports/IAR/ARMCMx/chcore.c
+++ b/os/ports/IAR/ARMCMx/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/chcore.h b/os/ports/IAR/ARMCMx/chcore.h
index 7644368be..5eff85f51 100644
--- a/os/ports/IAR/ARMCMx/chcore.h
+++ b/os/ports/IAR/ARMCMx/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -28,18 +29,22 @@
#ifndef _CHCORE_H_
#define _CHCORE_H_
-#include <intrinsics.h>
-
-#include "nvic.h"
-
/*===========================================================================*/
-/* Port constants. */
+/* Port constants (common). */
/*===========================================================================*/
-#define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */
-#define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */
-#define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */
-#define CORTEX_M4 4 /**< @brief Cortex-M4 variant. */
+/* Added to make the header stand-alone when included from asm.*/
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */
+#define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */
+#define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */
+#define CORTEX_M4 4 /**< @brief Cortex-M4 variant. */
/* Inclusion of the Cortex-Mx implementation specific parameters.*/
#include "cmparams.h"
@@ -47,41 +52,31 @@
/* Cortex model check, only M0 and M3 supported right now.*/
#if (CORTEX_MODEL == CORTEX_M0) || (CORTEX_MODEL == CORTEX_M3)
#elif (CORTEX_MODEL == CORTEX_M1) || (CORTEX_MODEL == CORTEX_M4)
-#warning "untested Cortex-M model"
+#error "untested Cortex-M model, manually remove this check in chcore.h"
#else
#error "unknown or unsupported Cortex-M model"
#endif
-/*===========================================================================*/
-/* Port statically derived parameters. */
-/*===========================================================================*/
-
/**
* @brief Total priority levels.
*/
-#define CORTEX_PRIORITY_LEVELS (1 << CORTEX_PRIORITY_BITS)
+#define CORTEX_PRIORITY_LEVELS (1 << CORTEX_PRIORITY_BITS)
/**
* @brief Minimum priority level.
* @details This minimum priority level is calculated from the number of
* priority bits supported by the specific Cortex-Mx implementation.
*/
-#define CORTEX_MINIMUM_PRIORITY (CORTEX_PRIORITY_LEVELS - 1)
+#define CORTEX_MINIMUM_PRIORITY (CORTEX_PRIORITY_LEVELS - 1)
/**
* @brief Maximum priority level.
* @details The maximum allowed priority level is always zero.
*/
-#define CORTEX_MAXIMUM_PRIORITY 0
-
-/**
- * @brief Disabled value for BASEPRI register.
- * @note ARMv7-M architecture only.
- */
-#define CORTEX_BASEPRI_DISABLED 0
+#define CORTEX_MAXIMUM_PRIORITY 0
/*===========================================================================*/
-/* Port macros. */
+/* Port macros (common). */
/*===========================================================================*/
/**
@@ -97,75 +92,56 @@
((n) << (8 - CORTEX_PRIORITY_BITS))
/*===========================================================================*/
-/* Port configurable parameters. */
+/* Port configurable parameters (common). */
/*===========================================================================*/
/**
- * @brief Enables the use of the WFI instruction in the idle thread loop.
+ * @brief Stack size for the system idle thread.
+ * @details This size depends on the idle thread implementation, usually
+ * the idle thread should take no more space than those reserved
+ * by @p PORT_INT_REQUIRED_STACK.
+ * @note In this port it is set to 16 because the idle thread does have
+ * a stack frame when compiling without optimizations. You may
+ * reduce this value to zero when compiling with optimizations.
*/
-#ifndef CORTEX_ENABLE_WFI_IDLE
-#define CORTEX_ENABLE_WFI_IDLE FALSE
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 16
#endif
/**
- * @brief SYSTICK handler priority.
- * @note The default SYSTICK handler priority is calculated as the priority
- * level in the middle of the numeric priorities range.
+ * @brief Per-thread stack overhead for interrupts servicing.
+ * @details This constant is used in the calculation of the correct working
+ * area size.
+ * This value can be zero on those architecture where there is a
+ * separate interrupt stack and the stack space between @p intctx and
+ * @p extctx is known to be zero.
+ * @note In this port it is conservatively set to 16 because the function
+ * @p chSchDoRescheduleI() can have a stack frame, expecially with
+ * compiler optimizations disabled.
*/
-#ifndef CORTEX_PRIORITY_SYSTICK
-#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
-#else
-/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
-#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
-#endif
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 16
#endif
/**
- * @brief SVCALL handler priority.
- * @note The default SVCALL handler priority is calculated as
- * @p CORTEX_MAXIMUM_PRIORITY+1, in the ARMv7-M port this reserves
- * the @p CORTEX_MAXIMUM_PRIORITY priority level as fast interrupts
- * priority level.
- * @note The SVCALL vector is only used in the ARMv7-M port, it is available
- * to user in the ARMv6-M port.
+ * @brief Enables the use of the WFI instruction in the idle thread loop.
*/
-#ifndef CORTEX_PRIORITY_SVCALL
-#define CORTEX_PRIORITY_SVCALL (CORTEX_MAXIMUM_PRIORITY + 1)
-#else
-/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL)
-#error "invalid priority level specified for CORTEX_PRIORITY_SVCALL"
-#endif
+#ifndef CORTEX_ENABLE_WFI_IDLE
+#define CORTEX_ENABLE_WFI_IDLE FALSE
#endif
/**
- * @brief PENDSV handler priority.
- * @note The default PENDSV handler priority is set at the
- * @p CORTEX_MINIMUM_PRIORITY priority level.
- * @note The PENDSV vector is only used in the ARMv7-M legacy port, it is
- * available to user in the ARMv6-M and ARMv7-M ports.
- * @note In the ARMv7-M legacy port this value should be not changed from
- * the minimum priority level.
+ * @brief SYSTICK handler priority.
+ * @note The default SYSTICK handler priority is calculated as the priority
+ * level in the middle of the numeric priorities range.
*/
-#ifndef CORTEX_PRIORITY_PENDSV
-#define CORTEX_PRIORITY_PENDSV CORTEX_MINIMUM_PRIORITY
+#ifndef CORTEX_PRIORITY_SYSTICK
+#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
#else
/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_PENDSV)
-#error "invalid priority level specified for CORTEX_PRIORITY_PENDSV"
-#endif
+#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
+#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
#endif
-
-/**
- * @brief BASEPRI level within kernel lock.
- * @note This value must not mask the SVCALL priority level or the
- * kernel would hard fault.
- * @note ARMv7-M architecture only.
- */
-#ifndef CORTEX_BASEPRI_KERNEL
-#define CORTEX_BASEPRI_KERNEL \
- CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1)
#endif
/**
@@ -176,11 +152,15 @@
* @note Allowed values are 32 or 64.
*/
#ifndef CORTEX_STACK_ALIGNMENT
-#define CORTEX_STACK_ALIGNMENT 64
+#define CORTEX_STACK_ALIGNMENT 64
#endif
/*===========================================================================*/
-/* Port exported info. */
+/* Port derived parameters (common). */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port exported info (common). */
/*===========================================================================*/
/**
@@ -188,62 +168,27 @@
*/
#define CH_ARCHITECTURE_ARM
-#if defined(__DOXYGEN__)
/**
- * @brief Macro defining the specific ARM architecture.
- * @note This macro is for documentation only, the real name changes
- * depending on the selected architecture, the possible names are:
- * - CH_ARCHITECTURE_ARM_v6M.
- * - CH_ARCHITECTURE_ARM_v7M.
- * .
+ * @brief Name of the compiler supported by this port.
*/
-#define CH_ARCHITECTURE_ARM_vxm
-
-/**
- * @brief Name of the implemented architecture.
- * @note The value is for documentation only, the real value changes
- * depending on the selected architecture, the possible values are:
- * - "ARMv6-M".
- * - "ARMv7-M".
- * - "ARMv7-ME".
- * .
- */
-#define CH_ARCHITECTURE_NAME "ARMvx-M"
-
-/**
- * @brief Name of the architecture variant (optional).
- * @note The value is for documentation only, the real value changes
- * depending on the selected architecture, the possible values are:
- * - "Cortex-M0"
- * - "Cortex-M1"
- * - "Cortex-M3"
- * - "Cortex-M4"
- * .
- */
-#define CH_CORE_VARIANT_NAME "Cortex-Mx"
-
-#elif CORTEX_MODEL == CORTEX_M4
-#define CH_ARCHITECTURE_ARM_v7M
-#define CH_ARCHITECTURE_NAME "ARMv7-ME"
-#define CH_CORE_VARIANT_NAME "Cortex-M4"
-#elif CORTEX_MODEL == CORTEX_M3
-#define CH_ARCHITECTURE_ARM_v7M
-#define CH_ARCHITECTURE_NAME "ARMv7-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M3"
-#elif CORTEX_MODEL == CORTEX_M1
-#define CH_ARCHITECTURE_ARM_v6M
-#define CH_ARCHITECTURE_NAME "ARMv6-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M1"
-#elif CORTEX_MODEL == CORTEX_M0
-#define CH_ARCHITECTURE_ARM_v6M
-#define CH_ARCHITECTURE_NAME "ARMv6-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M0"
-#endif
+#define CH_COMPILER_NAME "IAR"
/*===========================================================================*/
/* Port implementation part (common). */
/*===========================================================================*/
+/* Includes the sub-architecture-specific part.*/
+#if (CORTEX_MODEL == CORTEX_M0) || (CORTEX_MODEL == CORTEX_M1)
+#include "chcore_v6m.h"
+#elif (CORTEX_MODEL == CORTEX_M3) || (CORTEX_MODEL == CORTEX_M4)
+#include "chcore_v7m.h"
+#endif
+
+#if !defined(_FROM_ASM_)
+
+#include <intrinsics.h>
+#include "nvic.h"
+
/**
* @brief Stack and memory alignment enforcement.
*/
@@ -255,11 +200,6 @@ typedef uint32_t stkalign_t;
#error "invalid stack alignment selected"
#endif
-/**
- * @brief Generic ARM register.
- */
-typedef void *regarm_t;
-
#if defined(__DOXYGEN__)
/**
* @brief Interrupt saved context.
@@ -291,6 +231,20 @@ struct context {
};
/**
+ * @brief Platform dependent part of the @p chThdCreateI() API.
+ * @details This code usually setup the context switching frame represented
+ * by an @p intctx structure.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
+ wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.r13->r4 = (void *)pf; \
+ tp->p_ctx.r13->r5 = (void *)arg; \
+ tp->p_ctx.r13->lr = (void *)_port_thread_start; \
+}
+
+/**
* @brief Enforces a correct alignment for a stack area size value.
*/
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
@@ -298,10 +252,10 @@ struct context {
/**
* @brief Computes the thread working area global size.
*/
-#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
- sizeof(struct intctx) + \
- sizeof(struct extctx) + \
- (n) + (INT_REQUIRED_STACK))
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
@@ -310,12 +264,7 @@ struct context {
*/
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
-/* Includes the architecture-specific implementation part.*/
-#if defined(CH_ARCHITECTURE_ARM_v6M)
-#include "chcore_v6m.h"
-#elif defined(CH_ARCHITECTURE_ARM_v7M)
-#include "chcore_v7m.h"
-#endif
+#endif /* _FROM_ASM_ */
#endif /* _CHCORE_H_ */
diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.c b/os/ports/IAR/ARMCMx/chcore_v6m.c
index 25b360809..f04ff96d1 100644
--- a/os/ports/IAR/ARMCMx/chcore_v6m.c
+++ b/os/ports/IAR/ARMCMx/chcore_v6m.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -28,16 +29,6 @@
#include "ch.h"
/**
- * @brief PC register temporary storage.
- */
-regarm_t _port_saved_pc;
-
-/**
- * @brief IRQ nesting counter.
- */
-unsigned _port_irq_nesting;
-
-/**
* @brief System Timer vector.
* @details This interrupt is used as system tick.
* @note The timer must be initialized in the startup code.
diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.h b/os/ports/IAR/ARMCMx/chcore_v6m.h
index a2d1a40d3..3eed8bf43 100644
--- a/os/ports/IAR/ARMCMx/chcore_v6m.h
+++ b/os/ports/IAR/ARMCMx/chcore_v6m.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -29,33 +30,87 @@
#define _CHCORE_V6M_H_
/*===========================================================================*/
+/* Port constants. */
+/*===========================================================================*/
+
+/**
+ * @brief PendSV priority level.
+ * @note This priority is enforced to be equal to @p 0,
+ * this handler always have the highest priority that cannot preempt
+ * the kernel.
+ */
+#define CORTEX_PRIORITY_PENDSV 0
+
+/*===========================================================================*/
+/* Port configurable parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief Alternate preemption method.
+ * @details Activating this option will make the Kernel use the PendSV
+ * handler for preemption instead of the NMI handler.
+ */
+#ifndef CORTEX_ALTERNATE_SWITCH
+#define CORTEX_ALTERNATE_SWITCH FALSE
+#endif
+
+/*===========================================================================*/
+/* Port derived parameters. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port exported info. */
+/*===========================================================================*/
+
+/**
+ * @brief Macro defining the specific ARM architecture.
+ */
+#define CH_ARCHITECTURE_ARM_v6M
+
+/**
+ * @brief Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARMv6-M"
+
+/**
+ * @brief Name of the architecture variant.
+ */
+#if (CORTEX_MODEL == CORTEX_M0) || defined(__DOXYGEN__)
+#define CH_CORE_VARIANT_NAME "Cortex-M0"
+#elif (CORTEX_MODEL == CORTEX_M1)
+#define CH_CORE_VARIANT_NAME "Cortex-M1"
+#endif
+
+/**
+ * @brief Port-specific information string.
+ */
+#if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__)
+#define CH_PORT_INFO "Preemption through NMI"
+#else
+#define CH_PORT_INFO "Preemption through PendSV"
+#endif
+
+/*===========================================================================*/
/* Port implementation part. */
/*===========================================================================*/
+#if !defined(_FROM_ASM_)
+
/**
- * @brief Cortex-Mx exception context.
+ * @brief Generic ARM register.
*/
-struct cmxctx {
- regarm_t r0;
- regarm_t r1;
- regarm_t r2;
- regarm_t r3;
- regarm_t r12;
- regarm_t lr_thd;
- regarm_t pc;
- regarm_t xpsr;
-};
+typedef void *regarm_t;
#if !defined(__DOXYGEN__)
struct extctx {
- regarm_t xpsr;
- regarm_t r12;
- regarm_t lr;
regarm_t r0;
regarm_t r1;
regarm_t r2;
regarm_t r3;
+ regarm_t r12;
+ regarm_t lr_thd;
regarm_t pc;
+ regarm_t xpsr;
};
struct intctx {
@@ -72,64 +127,18 @@ struct intctx {
#endif
/**
- * @brief Platform dependent part of the @p chThdInit() API.
- * @details This code usually setup the context switching frame represented
- * by an @p intctx structure.
- */
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
- wsize - \
- sizeof(struct intctx)); \
- tp->p_ctx.r13->r4 = (void *)pf; \
- tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->lr = (void *)_port_thread_start; \
-}
-
-/**
- * @brief Stack size for the system idle thread.
- * @details This size depends on the idle thread implementation, usually
- * the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
- * @note In this port it is set to 8 because the idle thread does have
- * a stack frame when compiling without optimizations. You may
- * reduce this value to zero when compiling with optimizations.
- */
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 8
-#endif
-
-/**
- * @brief Per-thread stack overhead for interrupts servicing.
- * @details This constant is used in the calculation of the correct working
- * area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
- * compiler optimizations disabled.
- */
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 16
-#endif
-
-/**
* @brief IRQ prologue code.
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_PROLOGUE() { \
- port_lock_from_isr(); \
- _port_irq_nesting++; \
- port_unlock_from_isr(); \
-}
+#define PORT_IRQ_PROLOGUE() regarm_t _saved_lr = (regarm_t)__get_LR()
/**
* @brief IRQ epilogue code.
* @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_EPILOGUE() _port_irq_epilogue()
+#define PORT_IRQ_EPILOGUE() _port_irq_epilogue(_saved_lr)
/**
* @brief IRQ handler function declaration.
@@ -149,8 +158,9 @@ struct intctx {
* @brief Port-related initialization code.
*/
#define port_init() { \
- _port_irq_nesting = 0; \
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \
+ NVICSetSystemHandlerPriority(HANDLER_PENDSV, \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \
NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \
}
@@ -236,23 +246,20 @@ struct intctx {
}
#endif
-#if !defined(__DOXYGEN__)
-extern regarm_t _port_saved_pc;
-extern unsigned _port_irq_nesting;
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
void port_halt(void);
void _port_switch(Thread *ntp, Thread *otp);
- void _port_irq_epilogue(void);
+ void _port_irq_epilogue(regarm_t lr);
void _port_switch_from_isr(void);
void _port_thread_start(void);
#ifdef __cplusplus
}
#endif
+#endif /* _FROM_ASM_ */
+
#endif /* _CHCORE_V6M_H_ */
/** @} */
diff --git a/os/ports/IAR/ARMCMx/chcore_v7m.c b/os/ports/IAR/ARMCMx/chcore_v7m.c
index fe267b9e9..cef8b59a0 100644
--- a/os/ports/IAR/ARMCMx/chcore_v7m.c
+++ b/os/ports/IAR/ARMCMx/chcore_v7m.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/chcore_v7m.h b/os/ports/IAR/ARMCMx/chcore_v7m.h
index ad4abf25b..ac757a563 100644
--- a/os/ports/IAR/ARMCMx/chcore_v7m.h
+++ b/os/ports/IAR/ARMCMx/chcore_v7m.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -29,9 +30,111 @@
#define _CHCORE_V7M_H_
/*===========================================================================*/
+/* Port constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Disabled value for BASEPRI register.
+ */
+#define CORTEX_BASEPRI_DISABLED 0
+
+/*===========================================================================*/
+/* Port configurable parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief Simplified priority handling flag.
+ * @details Activating this option will make the Kernel work in compact mode.
+ */
+#ifndef CORTEX_SIMPLIFIED_PRIORITY
+#define CORTEX_SIMPLIFIED_PRIORITY FALSE
+#endif
+
+/**
+ * @brief SVCALL handler priority.
+ * @note The default SVCALL handler priority is defaulted to
+ * @p CORTEX_MAXIMUM_PRIORITY+1, this reserves the
+ * @p CORTEX_MAXIMUM_PRIORITY priority level as fast interrupts
+ * priority level.
+ */
+#ifndef CORTEX_PRIORITY_SVCALL
+#define CORTEX_PRIORITY_SVCALL (CORTEX_MAXIMUM_PRIORITY + 1)
+#else
+/* If it is externally redefined then better perform a validity check on it.*/
+#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL)
+#error "invalid priority level specified for CORTEX_PRIORITY_SVCALL"
+#endif
+#endif
+
+/*===========================================================================*/
+/* Port derived parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief BASEPRI level within kernel lock.
+ * @note In compact kernel mode this constant value is enforced to zero.
+ */
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
+#define CORTEX_BASEPRI_KERNEL \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1)
+#else
+#define CORTEX_BASEPRI_KERNEL 0
+#endif
+
+/**
+ * @brief PendSV priority level.
+ * @note This priority is enforced to be equal to @p CORTEX_BASEPRI_KERNEL,
+ * this handler always have the highest priority that cannot preempt
+ * the kernel.
+ */
+#define CORTEX_PRIORITY_PENDSV CORTEX_BASEPRI_KERNEL
+
+/*===========================================================================*/
+/* Port exported info. */
+/*===========================================================================*/
+
+#if (CORTEX_MODEL == CORTEX_M3) || defined(__DOXYGEN__)
+/**
+ * @brief Macro defining the specific ARM architecture.
+ */
+#define CH_ARCHITECTURE_ARM_v7M
+
+/**
+ * @brief Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARMv7-M"
+
+/**
+ * @brief Name of the architecture variant.
+ */
+#define CH_CORE_VARIANT_NAME "Cortex-M3"
+
+#elif (CORTEX_MODEL == CORTEX_M4)
+#define CH_ARCHITECTURE_ARM_v7ME
+#define CH_ARCHITECTURE_NAME "ARMv7-ME"
+#define CH_CORE_VARIANT_NAME "Cortex-M4"
+#endif
+
+/**
+ * @brief Port-specific information string.
+ */
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
+#define CH_PORT_INFO "Advanced kernel mode"
+#else
+#define CH_PORT_INFO "Compact kernel mode"
+#endif
+
+/*===========================================================================*/
/* Port implementation part. */
/*===========================================================================*/
+#if !defined(_FROM_ASM_)
+
+/**
+ * @brief Generic ARM register.
+ */
+typedef void *regarm_t;
+
#if !defined(__DOXYGEN__)
struct extctx {
regarm_t r0;
@@ -48,9 +151,7 @@ struct intctx {
regarm_t r4;
regarm_t r5;
regarm_t r6;
-#ifndef CH_CURRP_REGISTER_CACHE
regarm_t r7;
-#endif
regarm_t r8;
regarm_t r9;
regarm_t r10;
@@ -60,48 +161,6 @@ struct intctx {
#endif
/**
- * @brief Platform dependent part of the @p chThdCreateI() API.
- * @details This code usually setup the context switching frame represented
- * by an @p intctx structure.
- */
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
- wsize - \
- sizeof(struct intctx)); \
- tp->p_ctx.r13->r4 = (void *)pf; \
- tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->lr = (void *)_port_thread_start; \
-}
-
-/**
- * @brief Stack size for the system idle thread.
- * @details This size depends on the idle thread implementation, usually
- * the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
- * @note In this port it is set to 8 because the idle thread does have
- * a stack frame when compiling without optimizations. You may
- * reduce this value to zero when compiling with optimizations.
- */
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 8
-#endif
-
-/**
- * @brief Per-thread stack overhead for interrupts servicing.
- * @details This constant is used in the calculation of the correct working
- * area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
- * compiler optimizations disabled.
- */
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 16
-#endif
-
-/**
* @brief IRQ prologue code.
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
@@ -136,6 +195,8 @@ struct intctx {
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \
NVICSetSystemHandlerPriority(HANDLER_SVCALL, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL)); \
+ NVICSetSystemHandlerPriority(HANDLER_PENDSV, \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \
NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \
}
@@ -146,7 +207,11 @@ struct intctx {
* more actions.
* @note In this port this it raises the base priority to kernel level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_lock() __set_BASEPRI(CORTEX_BASEPRI_KERNEL)
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_lock() __disable_interrupt()
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Kernel-unlock action.
@@ -154,7 +219,11 @@ struct intctx {
* more actions.
* @note In this port this it lowers the base priority to user level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_unlock() __set_BASEPRI(CORTEX_BASEPRI_DISABLED)
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_unlock() __enable_interrupt()
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Kernel-lock action from an interrupt handler.
@@ -187,19 +256,27 @@ struct intctx {
* @note Interrupt sources above kernel level remains enabled.
* @note In this port it raises/lowers the base priority to kernel level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_suspend() { \
__set_BASEPRI(CORTEX_BASEPRI_KERNEL); \
__enable_interrupt(); \
}
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_suspend() __disable_interrupt()
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Enables all the interrupt sources.
* @note In this port it lowers the base priority to user level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_enable() { \
__set_BASEPRI(CORTEX_BASEPRI_DISABLED); \
__enable_interrupt(); \
}
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_enable() __enable_interrupt()
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Enters an architecture-dependent IRQ-waiting mode.
@@ -247,6 +324,8 @@ extern "C" {
}
#endif
+#endif /* _FROM_ASM_ */
+
#endif /* _CHCORE_V7M_H_ */
/** @} */
diff --git a/os/ports/IAR/ARMCMx/chcoreasm_v6m.s b/os/ports/IAR/ARMCMx/chcoreasm_v6m.s
index 07d89e6b5..ef72de53c 100644
--- a/os/ports/IAR/ARMCMx/chcoreasm_v6m.s
+++ b/os/ports/IAR/ARMCMx/chcoreasm_v6m.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -23,23 +24,21 @@
PRESERVE8
/*
- * Imports the Cortex-Mx parameters header and performs the same calculations
- * done in chcore.h.
+ * Imports the Cortex-Mx configuration headers.
*/
-#include "cmparams.h"
+#define _FROM_ASM_
+#include "chconf.h"
+#include "chcore.h"
-#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
-
-EXTCTX_SIZE SET 32
-CONTEXT_OFFSET SET 12
+EXTCTX_SIZE SET 32
+CONTEXT_OFFSET SET 12
+SCB_ICSR SET 0xE000ED04
SECTION .text:CODE:NOROOT(2)
EXTERN chThdExit
EXTERN chSchIsRescRequiredExI
EXTERN chSchDoRescheduleI
- EXTERN _port_saved_pc
- EXTERN _port_irq_nesting
THUMB
@@ -77,54 +76,78 @@ _port_thread_start:
bl chThdExit
/*
+ * NMI vector.
+ * The NMI vector is used for exception mode re-entering after a context
+ * switch.
+ */
+#if !CORTEX_ALTERNATE_SWITCH
+ PUBLIC NMIVector
+NMIVector:
+ mrs r3, PSP
+ adds r3, r3, #32
+ msr PSP, r3
+ cpsie i
+ bx lr
+#endif
+
+/*
+ * PendSV vector.
+ * The PendSV vector is used for exception mode re-entering after a context
+ * switch.
+ */
+#if CORTEX_ALTERNATE_SWITCH
+ PUBLIC PendSVVector
+PendSVVector:
+ mrs r3, PSP
+ adds r3, r3, #32
+ msr PSP, r3
+ bx lr
+#endif
+
+/*
* Post-IRQ switch code.
* Exception handlers return here for context switching.
*/
PUBLIC _port_switch_from_isr
_port_switch_from_isr:
- /* Note, saves r4 to make space for the PC.*/
- push {r0, r1, r2, r3, r4}
- mrs r0, APSR
- mov r1, r12
- push {r0, r1, lr}
- ldr r0, =_port_saved_pc
- ldr r0, [r0]
- adds r0, r0, #1
- str r0, [sp, #28]
bl chSchDoRescheduleI
- pop {r0, r1, r2}
- mov r12, r1
- msr APSR, r0
- mov lr, r2
+ ldr r2, =SCB_ICSR
+ movs r3, #128
+#if CORTEX_ALTERNATE_SWITCH
+ lsls r3, r3, #21
+ str r3, [r2, #0]
cpsie i
- pop {r0, r1, r2, r3, pc}
+#else
+ lsls r3, r3, #24
+ str r3, [r2, #0]
+#endif
+waithere:
+ b waithere
/*
* Reschedule verification and setup after an IRQ.
*/
PUBLIC _port_irq_epilogue
_port_irq_epilogue:
- push {r4, lr}
+ push {r3, lr}
+ adds r0, r0, #15
+ beq stillnested
cpsid i
- ldr r2, =_port_irq_nesting
- ldr r3, [r2]
- subs r3, r3, #1
- str r3, [r2]
- cmp r3, #0
- beq skipexit
-notrequired
- cpsie i
- pop {r4, pc}
-skipexit
bl chSchIsRescRequiredExI
cmp r0, #0
- beq notrequired
- mrs r1, PSP
- ldr r2, =_port_saved_pc
- ldr r3, [r1, #24]
- str r3, [r2]
- ldr r3, =_port_switch_from_isr
- str r3, [r1, #24]
- pop {r4, pc}
+ bne doresch
+ cpsie i
+stillnested
+ pop {r3, pc}
+doresch
+ mrs r3, PSP
+ subs r3, r3, #32
+ msr PSP, r3
+ ldr r2, =_port_switch_from_isr
+ str r2, [r3, #24]
+ movs r2, #128
+ lsls r2, r2, #17
+ str r2, [r3, #28]
+ pop {r3, pc}
END
diff --git a/os/ports/IAR/ARMCMx/chcoreasm_v7m.s b/os/ports/IAR/ARMCMx/chcoreasm_v7m.s
index 9273ce9f4..65531ff8c 100644
--- a/os/ports/IAR/ARMCMx/chcoreasm_v7m.s
+++ b/os/ports/IAR/ARMCMx/chcoreasm_v7m.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -23,27 +24,17 @@
PRESERVE8
/*
- * Imports the Cortex-Mx parameters header and performs the same calculations
- * done in chcore.h.
+ * Imports the Cortex-Mx configuration headers.
*/
-#include "cmparams.h"
-
-#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
-
-#ifndef CORTEX_PRIORITY_SVCALL
-#define CORTEX_PRIORITY_SVCALL 1
-#endif
-
-#ifndef CORTEX_BASEPRI_KERNEL
-#define CORTEX_BASEPRI_KERNEL CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1)
-#endif
-
-#define CORTEX_BASEPRI_DISABLED 0
+#define _FROM_ASM_
+#include "chconf.h"
+#include "chcore.h"
EXTCTX_SIZE SET 32
CONTEXT_OFFSET SET 12
SCB_ICSR SET 0xE000ED04
ICSR_RETTOBASE SET 0x00000800
+ICSR_PENDSVSET SET 0x10000000
SECTION .text:CODE:NOROOT(2)
@@ -59,7 +50,7 @@ ICSR_RETTOBASE SET 0x00000800
PUBLIC _port_switch
_port_switch:
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
- str sp, [r1, #CONTEXT_OFFSET]
+ str sp, [r1, #CONTEXT_OFFSET]
ldr sp, [r0, #CONTEXT_OFFSET]
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
@@ -69,8 +60,12 @@ _port_switch:
*/
PUBLIC _port_thread_start
_port_thread_start:
+#if CORTEX_SIMPLIFIED_PRIORITY
+ cpsie i
+#else
movs r3, #CORTEX_BASEPRI_DISABLED
msr BASEPRI, r3
+#endif
mov r0, r5
blx r4
bl chThdExit
@@ -82,22 +77,39 @@ _port_thread_start:
PUBLIC _port_switch_from_isr
_port_switch_from_isr:
bl chSchDoRescheduleI
+#if CORTEX_SIMPLIFIED_PRIORITY
+ mov r3, #LWRD SCB_ICSR
+ movt r3, #HWRD SCB_ICSR
+ mov r2, #ICSR_PENDSVSET
+ str r2, [r3]
+ cpsie i
+.L3: b .L3
+#else
svc #0
+#endif
/*
* Reschedule verification and setup after an IRQ.
*/
PUBLIC _port_irq_epilogue
_port_irq_epilogue:
+#if CORTEX_SIMPLIFIED_PRIORITY
+ cpsid i
+#else
movs r3, #CORTEX_BASEPRI_KERNEL
msr BASEPRI, r3
+#endif
mov r3, #LWRD SCB_ICSR
movt r3, #HWRD SCB_ICSR
ldr r3, [r3, #0]
tst r3, #ICSR_RETTOBASE
bne .L7
+#if CORTEX_SIMPLIFIED_PRIORITY
+ cpsie i
+#else
movs r3, #CORTEX_BASEPRI_DISABLED
msr BASEPRI, r3
+#endif
bx lr
.L7:
push {r3, lr}
@@ -113,8 +125,12 @@ _port_irq_epilogue:
str r2, [r3, #28]
pop {r3, pc}
.L4:
+#if CORTEX_SIMPLIFIED_PRIORITY
+ cpsie i
+#else
movs r3, #CORTEX_BASEPRI_DISABLED
msr BASEPRI, r3
+#endif
pop {r3, pc}
/*
@@ -122,6 +138,7 @@ _port_irq_epilogue:
* Discarding the current exception context and positioning the stack to
* point to the real one.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY
PUBLIC SVCallVector
SVCallVector:
mrs r3, PSP
@@ -130,5 +147,20 @@ SVCallVector:
movs r3, #CORTEX_BASEPRI_DISABLED
msr BASEPRI, r3
bx lr
+#endif
+
+/*
+ * PendSV vector.
+ * Discarding the current exception context and positioning the stack to
+ * point to the real one.
+ */
+#if CORTEX_SIMPLIFIED_PRIORITY
+ PUBLIC PendSVVector
+PendSVVector:
+ mrs r3, PSP
+ adds r3, r3, #EXTCTX_SIZE
+ msr PSP, r3
+ bx lr
+#endif
END
diff --git a/os/ports/IAR/ARMCMx/chtypes.h b/os/ports/IAR/ARMCMx/chtypes.h
index 4020b95b5..f24bb6ffc 100644
--- a/os/ports/IAR/ARMCMx/chtypes.h
+++ b/os/ports/IAR/ARMCMx/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/cstartup.s b/os/ports/IAR/ARMCMx/cstartup.s
index 1421ea86e..677cd5248 100644
--- a/os/ports/IAR/ARMCMx/cstartup.s
+++ b/os/ports/IAR/ARMCMx/cstartup.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/nvic.c b/os/ports/IAR/ARMCMx/nvic.c
index 93dbd6ba4..690c4e488 100644
--- a/os/ports/IAR/ARMCMx/nvic.c
+++ b/os/ports/IAR/ARMCMx/nvic.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/nvic.h b/os/ports/IAR/ARMCMx/nvic.h
index 321a0ed7b..f424a854d 100644
--- a/os/ports/IAR/ARMCMx/nvic.h
+++ b/os/ports/IAR/ARMCMx/nvic.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/IAR/ARMCMx/port.dox b/os/ports/IAR/ARMCMx/port.dox
index 00d669726..3e10318ce 100644
--- a/os/ports/IAR/ARMCMx/port.dox
+++ b/os/ports/IAR/ARMCMx/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -25,9 +26,28 @@
* This port supports all the cores implementing the ARMv6-M and ARMv7-M
* architectures.
*
- * @section IAR_ARMCMx_STATES_A System logical states in ARMv6-M mode
- * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
- * Cortex-M0 port:
+ * @section IAR_ARMCMx_MODES Kernel Modes
+ * The Cortex-Mx port supports two distinct kernel modes:
+ * - <b>Advanced Kernel</b> mode. In this mode the kernel only masks
+ * interrupt sources with priorities below or equal to the
+ * @p CORTEX_BASEPRI_KERNEL level. Higher priorities are not affected by
+ * the kernel critical sections and can be used for fast interrupts.
+ * This mode is not available in the ARMv6-M architecture which does not
+ * support priority masking.
+ * - <b>Compact Kernel</b> mode. In this mode the kernel handles IRQ priorities
+ * in a simplified way, all interrupt sources are disabled when the kernel
+ * enters into a critical zone and re-enabled on exit. This is simple and
+ * adequate for most applications, this mode results in a more compact and
+ * faster kernel.
+ * .
+ * The selection of the mode is performed using the port configuration option
+ * @p CORTEX_SIMPLIFIED_PRIORITY. Apart from the different handling of
+ * interrupts there are no other differences between the two modes. The
+ * kernel API is exactly the same.
+ *
+ * @section IAR_ARMCMx_STATES_A System logical states in Compact Kernel mode
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in Compact
+ * Kernel mode:
* - <b>Init</b>. This state is represented by the startup code and the
* initialization code before @p chSysInit() is executed. It has not a
* special hardware state associated.
@@ -52,21 +72,21 @@
* mode.
* - <b>Serving Fast Interrupt</b>. This state is not implemented in the
* ARMv6-M implementation.
- * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-M3 has a specific
+ * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-Mx has a specific
* asynchronous NMI vector and several synchronous fault vectors that can
* be considered belonging to this category.
* - <b>Halted</b>. Implemented as an infinite loop after globally masking all
* the maskable interrupt sources. The ARM state is whatever the processor
* was running when @p chSysHalt() was invoked.
*
- * @section IAR_ARMCMx_STATES_B System logical states in ARMv7-M mode
- * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
- * Cortex-M3 port:
+ * @section IAR_ARMCMx_STATES_B System logical states in Advanced Kernel mode
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in the
+ * Advanced Kernel mode:
* - <b>Init</b>. This state is represented by the startup code and the
* initialization code before @p chSysInit() is executed. It has not a
* special hardware state associated.
* - <b>Normal</b>. This is the state the system has after executing
- * @p chSysInit(). In this state the ARM Cortex-M3 has the BASEPRI register
+ * @p chSysInit(). In this state the ARM Cortex-Mx has the BASEPRI register
* set at @p CORTEX_BASEPRI_USER level, interrupts are not masked. The
* processor is running in thread-privileged mode.
* - <b>Suspended</b>. In this state the interrupt sources are not globally
@@ -92,7 +112,7 @@
* - <b>Serving Fast Interrupt</b>. It is basically the same of the SRI state
* but it is not possible to switch to the I-Locked state because fast
* interrupts can preempt the kernel critical zone.
- * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-M3 has a specific
+ * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-Mx has a specific
* asynchronous NMI vector and several synchronous fault vectors that can
* be considered belonging to this category.
* - <b>Halted</b>. Implemented as an infinite loop after globally masking all
@@ -139,17 +159,24 @@
* - @p IDLE_THREAD_STACK_SIZE, stack area size to be assigned to the IDLE
* thread. Usually there is no need to change this value unless inserting
* code in the IDLE thread using the @p IDLE_LOOP_HOOK hook macro.
- * - @p CORTEX_BASEPRI_KERNEL, this is the @p BASEPRI value for the kernel lock
- * code. Code running at higher priority levels must not invoke any OS API.
- * This setting is specific to the ARMv7-M architecture.
* - @p CORTEX_PRIORITY_SYSTICK, priority of the SYSTICK handler.
- * - @p CORTEX_PRIORITY_SVCALL, priority of the SVCALL handler.
* - @p CORTEX_PRIORITY_PENDSV, priority of the PENDSV handler.
* - @p CORTEX_ENABLE_WFI_IDLE, if set to @p TRUE enables the use of the
* @p <b>wfi</b> instruction from within the idle loop. This option is
* defaulted to FALSE because it can create problems with some debuggers.
* Setting this option to TRUE reduces the system power requirements.
* .
+ * @section IAR_ARMCMx_CONF_1 ARMv6-M specific options
+ * The following options are specific for the ARMv6-M architecture:
+ * - @p CORTEX_ALTERNATE_SWITCH, when activated makes the OS use the PendSV
+ * exception instead of NMI as preemption handler.
+ * .
+ * @section IAR_ARMCMx_CONF_2 ARMv7-M specific options
+ * The following options are specific for the ARMv6-M architecture:
+ * - @p CORTEX_PRIORITY_SVCALL, priority of the SVCALL handler.
+ * - @p CORTEX_SIMPLIFIED_PRIORITY, when enabled activates the Compact kernel
+ * mode.
+ * .
* @ingroup IAR_ARMCMx
*/
diff --git a/os/ports/RC/STM8/chcore.c b/os/ports/RC/STM8/chcore.c
index ed0103049..d7034e38a 100644
--- a/os/ports/RC/STM8/chcore.c
+++ b/os/ports/RC/STM8/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RC/STM8/chcore.h b/os/ports/RC/STM8/chcore.h
index 55c5d3ac0..07b7fa0b6 100644
--- a/os/ports/RC/STM8/chcore.h
+++ b/os/ports/RC/STM8/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -38,7 +39,7 @@
* @brief Enables the use of the WFI instruction in the idle thread loop.
*/
#ifndef STM8_ENABLE_WFI_IDLE
-#define STM8_ENABLE_WFI_IDLE FALSE
+#define STM8_ENABLE_WFI_IDLE FALSE
#endif
/*===========================================================================*/
@@ -53,7 +54,17 @@
/**
* @brief Name of the implemented architecture.
*/
-#define CH_ARCHITECTURE_NAME "STM8"
+#define CH_ARCHITECTURE_NAME "STM8"
+
+/**
+ * @brief Name of the compiler supported by this port.
+ */
+#define CH_COMPILER_NAME "Raisonance"
+
+/**
+ * @brief Port-specific information string.
+ */
+#define CH_PORT_INFO "None"
/*===========================================================================*/
/* Port implementation part. */
@@ -146,10 +157,10 @@ struct stm8_startctx {
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
+ * by @p PORT_INT_REQUIRED_STACK.
*/
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 0
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 0
#endif
/**
@@ -157,8 +168,8 @@ struct stm8_startctx {
* @details This is a safe value, you may trim it down after reading the
* right size in the map file.
*/
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 48
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 48
#endif
/**
@@ -172,7 +183,7 @@ struct stm8_startctx {
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
(sizeof(struct intctx) - 1) + \
(sizeof(struct extctx) - 1) + \
- (n) + (INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/ports/RC/STM8/chtypes.h b/os/ports/RC/STM8/chtypes.h
index 4f2241b1f..74bd3ed9e 100644
--- a/os/ports/RC/STM8/chtypes.h
+++ b/os/ports/RC/STM8/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RC/STM8/port.dox b/os/ports/RC/STM8/port.dox
index 7a7d10788..dbcd69ee7 100644
--- a/os/ports/RC/STM8/port.dox
+++ b/os/ports/RC/STM8/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/LPC11xx/cmparams.h b/os/ports/RVCT/ARMCMx/LPC11xx/cmparams.h
index fec1ea3a2..7289af9e7 100644
--- a/os/ports/RVCT/ARMCMx/LPC11xx/cmparams.h
+++ b/os/ports/RVCT/ARMCMx/LPC11xx/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/LPC11xx/vectors.s b/os/ports/RVCT/ARMCMx/LPC11xx/vectors.s
index 91ee5ee18..798003e49 100644
--- a/os/ports/RVCT/ARMCMx/LPC11xx/vectors.s
+++ b/os/ports/RVCT/ARMCMx/LPC11xx/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/LPC13xx/cmparams.h b/os/ports/RVCT/ARMCMx/LPC13xx/cmparams.h
index d45565bbb..e484d7aad 100644
--- a/os/ports/RVCT/ARMCMx/LPC13xx/cmparams.h
+++ b/os/ports/RVCT/ARMCMx/LPC13xx/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/LPC13xx/vectors.s b/os/ports/RVCT/ARMCMx/LPC13xx/vectors.s
index f8a4d7f74..5290f1cd4 100644
--- a/os/ports/RVCT/ARMCMx/LPC13xx/vectors.s
+++ b/os/ports/RVCT/ARMCMx/LPC13xx/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/STM32/cmparams.h b/os/ports/RVCT/ARMCMx/STM32/cmparams.h
index 2c7a06d4a..73a3f2357 100644
--- a/os/ports/RVCT/ARMCMx/STM32/cmparams.h
+++ b/os/ports/RVCT/ARMCMx/STM32/cmparams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/STM32/vectors.s b/os/ports/RVCT/ARMCMx/STM32/vectors.s
index 1abf3cc1e..330f34bf8 100644
--- a/os/ports/RVCT/ARMCMx/STM32/vectors.s
+++ b/os/ports/RVCT/ARMCMx/STM32/vectors.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/chcore.c b/os/ports/RVCT/ARMCMx/chcore.c
index 627b4c812..fec6b2e1d 100644
--- a/os/ports/RVCT/ARMCMx/chcore.c
+++ b/os/ports/RVCT/ARMCMx/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/chcore.h b/os/ports/RVCT/ARMCMx/chcore.h
index a8c8d7496..42b397e93 100644
--- a/os/ports/RVCT/ARMCMx/chcore.h
+++ b/os/ports/RVCT/ARMCMx/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -28,16 +29,22 @@
#ifndef _CHCORE_H_
#define _CHCORE_H_
-#include "nvic.h"
-
/*===========================================================================*/
-/* Port constants. */
+/* Port constants (common). */
/*===========================================================================*/
-#define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */
-#define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */
-#define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */
-#define CORTEX_M4 4 /**< @brief Cortex-M4 variant. */
+/* Added to make the header stand-alone when included from asm.*/
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */
+#define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */
+#define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */
+#define CORTEX_M4 4 /**< @brief Cortex-M4 variant. */
/* Inclusion of the Cortex-Mx implementation specific parameters.*/
#include "cmparams.h"
@@ -50,36 +57,26 @@
#error "unknown or unsupported Cortex-M model"
#endif
-/*===========================================================================*/
-/* Port statically derived parameters. */
-/*===========================================================================*/
-
/**
* @brief Total priority levels.
*/
-#define CORTEX_PRIORITY_LEVELS (1 << CORTEX_PRIORITY_BITS)
+#define CORTEX_PRIORITY_LEVELS (1 << CORTEX_PRIORITY_BITS)
/**
* @brief Minimum priority level.
* @details This minimum priority level is calculated from the number of
* priority bits supported by the specific Cortex-Mx implementation.
*/
-#define CORTEX_MINIMUM_PRIORITY (CORTEX_PRIORITY_LEVELS - 1)
+#define CORTEX_MINIMUM_PRIORITY (CORTEX_PRIORITY_LEVELS - 1)
/**
* @brief Maximum priority level.
* @details The maximum allowed priority level is always zero.
*/
-#define CORTEX_MAXIMUM_PRIORITY 0
-
-/**
- * @brief Disabled value for BASEPRI register.
- * @note ARMv7-M architecture only.
- */
-#define CORTEX_BASEPRI_DISABLED 0
+#define CORTEX_MAXIMUM_PRIORITY 0
/*===========================================================================*/
-/* Port macros. */
+/* Port macros (common). */
/*===========================================================================*/
/**
@@ -95,75 +92,56 @@
((n) << (8 - CORTEX_PRIORITY_BITS))
/*===========================================================================*/
-/* Port configurable parameters. */
+/* Port configurable parameters (common). */
/*===========================================================================*/
/**
- * @brief Enables the use of the WFI instruction in the idle thread loop.
+ * @brief Stack size for the system idle thread.
+ * @details This size depends on the idle thread implementation, usually
+ * the idle thread should take no more space than those reserved
+ * by @p PORT_INT_REQUIRED_STACK.
+ * @note In this port it is set to 16 because the idle thread does have
+ * a stack frame when compiling without optimizations. You may
+ * reduce this value to zero when compiling with optimizations.
*/
-#ifndef CORTEX_ENABLE_WFI_IDLE
-#define CORTEX_ENABLE_WFI_IDLE FALSE
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 16
#endif
/**
- * @brief SYSTICK handler priority.
- * @note The default SYSTICK handler priority is calculated as the priority
- * level in the middle of the numeric priorities range.
+ * @brief Per-thread stack overhead for interrupts servicing.
+ * @details This constant is used in the calculation of the correct working
+ * area size.
+ * This value can be zero on those architecture where there is a
+ * separate interrupt stack and the stack space between @p intctx and
+ * @p extctx is known to be zero.
+ * @note In this port it is conservatively set to 16 because the function
+ * @p chSchDoRescheduleI() can have a stack frame, expecially with
+ * compiler optimizations disabled.
*/
-#ifndef CORTEX_PRIORITY_SYSTICK
-#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
-#else
-/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
-#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
-#endif
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 16
#endif
/**
- * @brief SVCALL handler priority.
- * @note The default SVCALL handler priority is calculated as
- * @p CORTEX_MAXIMUM_PRIORITY+1, in the ARMv7-M port this reserves
- * the @p CORTEX_MAXIMUM_PRIORITY priority level as fast interrupts
- * priority level.
- * @note The SVCALL vector is only used in the ARMv7-M port, it is available
- * to user in the ARMv6-M port.
+ * @brief Enables the use of the WFI instruction in the idle thread loop.
*/
-#ifndef CORTEX_PRIORITY_SVCALL
-#define CORTEX_PRIORITY_SVCALL (CORTEX_MAXIMUM_PRIORITY + 1)
-#else
-/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL)
-#error "invalid priority level specified for CORTEX_PRIORITY_SVCALL"
-#endif
+#ifndef CORTEX_ENABLE_WFI_IDLE
+#define CORTEX_ENABLE_WFI_IDLE FALSE
#endif
/**
- * @brief PENDSV handler priority.
- * @note The default PENDSV handler priority is set at the
- * @p CORTEX_MINIMUM_PRIORITY priority level.
- * @note The PENDSV vector is only used in the ARMv7-M legacy port, it is
- * available to user in the ARMv6-M and ARMv7-M ports.
- * @note In the ARMv7-M legacy port this value should be not changed from
- * the minimum priority level.
+ * @brief SYSTICK handler priority.
+ * @note The default SYSTICK handler priority is calculated as the priority
+ * level in the middle of the numeric priorities range.
*/
-#ifndef CORTEX_PRIORITY_PENDSV
-#define CORTEX_PRIORITY_PENDSV CORTEX_MINIMUM_PRIORITY
+#ifndef CORTEX_PRIORITY_SYSTICK
+#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
#else
/* If it is externally redefined then better perform a validity check on it.*/
-#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_PENDSV)
-#error "invalid priority level specified for CORTEX_PRIORITY_PENDSV"
-#endif
+#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
+#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
#endif
-
-/**
- * @brief BASEPRI level within kernel lock.
- * @note This value must not mask the SVCALL priority level or the
- * kernel would hard fault.
- * @note ARMv7-M architecture only.
- */
-#ifndef CORTEX_BASEPRI_KERNEL
-#define CORTEX_BASEPRI_KERNEL \
- CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1)
#endif
/**
@@ -174,11 +152,15 @@
* @note Allowed values are 32 or 64.
*/
#ifndef CORTEX_STACK_ALIGNMENT
-#define CORTEX_STACK_ALIGNMENT 64
+#define CORTEX_STACK_ALIGNMENT 64
#endif
/*===========================================================================*/
-/* Port exported info. */
+/* Port derived parameters (common). */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port exported info (common). */
/*===========================================================================*/
/**
@@ -186,62 +168,26 @@
*/
#define CH_ARCHITECTURE_ARM
-#if defined(__DOXYGEN__)
-/**
- * @brief Macro defining the specific ARM architecture.
- * @note This macro is for documentation only, the real name changes
- * depending on the selected architecture, the possible names are:
- * - CH_ARCHITECTURE_ARM_v6M.
- * - CH_ARCHITECTURE_ARM_v7M.
- * .
- */
-#define CH_ARCHITECTURE_ARM_vxm
-
/**
- * @brief Name of the implemented architecture.
- * @note The value is for documentation only, the real value changes
- * depending on the selected architecture, the possible values are:
- * - "ARMv6-M".
- * - "ARMv7-M".
- * - "ARMv7-ME".
- * .
+ * @brief Name of the compiler supported by this port.
*/
-#define CH_ARCHITECTURE_NAME "ARMvx-M"
-
-/**
- * @brief Name of the architecture variant (optional).
- * @note The value is for documentation only, the real value changes
- * depending on the selected architecture, the possible values are:
- * - "Cortex-M0"
- * - "Cortex-M1"
- * - "Cortex-M3"
- * - "Cortex-M4"
- * .
- */
-#define CH_CORE_VARIANT_NAME "Cortex-Mx"
-
-#elif CORTEX_MODEL == CORTEX_M4
-#define CH_ARCHITECTURE_ARM_v7M
-#define CH_ARCHITECTURE_NAME "ARMv7-ME"
-#define CH_CORE_VARIANT_NAME "Cortex-M4"
-#elif CORTEX_MODEL == CORTEX_M3
-#define CH_ARCHITECTURE_ARM_v7M
-#define CH_ARCHITECTURE_NAME "ARMv7-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M3"
-#elif CORTEX_MODEL == CORTEX_M1
-#define CH_ARCHITECTURE_ARM_v6M
-#define CH_ARCHITECTURE_NAME "ARMv6-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M1"
-#elif CORTEX_MODEL == CORTEX_M0
-#define CH_ARCHITECTURE_ARM_v6M
-#define CH_ARCHITECTURE_NAME "ARMv6-M"
-#define CH_CORE_VARIANT_NAME "Cortex-M0"
-#endif
+#define CH_COMPILER_NAME "RVCT"
/*===========================================================================*/
/* Port implementation part (common). */
/*===========================================================================*/
+/* Includes the sub-architecture-specific part.*/
+#if (CORTEX_MODEL == CORTEX_M0) || (CORTEX_MODEL == CORTEX_M1)
+#include "chcore_v6m.h"
+#elif (CORTEX_MODEL == CORTEX_M3) || (CORTEX_MODEL == CORTEX_M4)
+#include "chcore_v7m.h"
+#endif
+
+#if !defined(_FROM_ASM_)
+
+#include "nvic.h"
+
/**
* @brief Stack and memory alignment enforcement.
*/
@@ -258,11 +204,6 @@ typedef uint32_t stkalign_t __attribute__ ((aligned (4)));
#error "invalid stack alignment selected"
#endif
-/**
- * @brief Generic ARM register.
- */
-typedef void *regarm_t;
-
#if defined(__DOXYGEN__)
/**
* @brief Interrupt saved context.
@@ -294,6 +235,20 @@ struct context {
};
/**
+ * @brief Platform dependent part of the @p chThdCreateI() API.
+ * @details This code usually setup the context switching frame represented
+ * by an @p intctx structure.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
+ wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.r13->r4 = (void *)pf; \
+ tp->p_ctx.r13->r5 = (void *)arg; \
+ tp->p_ctx.r13->lr = (void *)_port_thread_start; \
+}
+
+/**
* @brief Enforces a correct alignment for a stack area size value.
*/
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
@@ -301,10 +256,10 @@ struct context {
/**
* @brief Computes the thread working area global size.
*/
-#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
- sizeof(struct intctx) + \
- sizeof(struct extctx) + \
- (n) + (INT_REQUIRED_STACK))
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
@@ -313,12 +268,7 @@ struct context {
*/
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
-/* Includes the architecture-specific implementation part.*/
-#if defined(CH_ARCHITECTURE_ARM_v6M)
-#include "chcore_v6m.h"
-#elif defined(CH_ARCHITECTURE_ARM_v7M)
-#include "chcore_v7m.h"
-#endif
+#endif /* _FROM_ASM_ */
#endif /* _CHCORE_H_ */
diff --git a/os/ports/RVCT/ARMCMx/chcore_v6m.c b/os/ports/RVCT/ARMCMx/chcore_v6m.c
index 6340df81c..c0b2922d9 100644
--- a/os/ports/RVCT/ARMCMx/chcore_v6m.c
+++ b/os/ports/RVCT/ARMCMx/chcore_v6m.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -28,16 +29,6 @@
#include "ch.h"
/**
- * @brief PC register temporary storage.
- */
-regarm_t _port_saved_pc;
-
-/**
- * @brief IRQ nesting counter.
- */
-unsigned _port_irq_nesting;
-
-/**
* @brief System Timer vector.
* @details This interrupt is used as system tick.
* @note The timer must be initialized in the startup code.
diff --git a/os/ports/RVCT/ARMCMx/chcore_v6m.h b/os/ports/RVCT/ARMCMx/chcore_v6m.h
index 796b7f22e..347588bbb 100644
--- a/os/ports/RVCT/ARMCMx/chcore_v6m.h
+++ b/os/ports/RVCT/ARMCMx/chcore_v6m.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -29,33 +30,87 @@
#define _CHCORE_V6M_H_
/*===========================================================================*/
+/* Port constants. */
+/*===========================================================================*/
+
+/**
+ * @brief PendSV priority level.
+ * @note This priority is enforced to be equal to @p 0,
+ * this handler always have the highest priority that cannot preempt
+ * the kernel.
+ */
+#define CORTEX_PRIORITY_PENDSV 0
+
+/*===========================================================================*/
+/* Port configurable parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief Alternate preemption method.
+ * @details Activating this option will make the Kernel use the PendSV
+ * handler for preemption instead of the NMI handler.
+ */
+#ifndef CORTEX_ALTERNATE_SWITCH
+#define CORTEX_ALTERNATE_SWITCH FALSE
+#endif
+
+/*===========================================================================*/
+/* Port derived parameters. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Port exported info. */
+/*===========================================================================*/
+
+/**
+ * @brief Macro defining the specific ARM architecture.
+ */
+#define CH_ARCHITECTURE_ARM_v6M
+
+/**
+ * @brief Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARMv6-M"
+
+/**
+ * @brief Name of the architecture variant.
+ */
+#if (CORTEX_MODEL == CORTEX_M0) || defined(__DOXYGEN__)
+#define CH_CORE_VARIANT_NAME "Cortex-M0"
+#elif (CORTEX_MODEL == CORTEX_M1)
+#define CH_CORE_VARIANT_NAME "Cortex-M1"
+#endif
+
+/**
+ * @brief Port-specific information string.
+ */
+#if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__)
+#define CH_PORT_INFO "Preemption through NMI"
+#else
+#define CH_PORT_INFO "Preemption through PendSV"
+#endif
+
+/*===========================================================================*/
/* Port implementation part. */
/*===========================================================================*/
+#if !defined(_FROM_ASM_)
+
/**
- * @brief Cortex-Mx exception context.
+ * @brief Generic ARM register.
*/
-struct cmxctx {
- regarm_t r0;
- regarm_t r1;
- regarm_t r2;
- regarm_t r3;
- regarm_t r12;
- regarm_t lr_thd;
- regarm_t pc;
- regarm_t xpsr;
-};
+typedef void *regarm_t;
#if !defined(__DOXYGEN__)
struct extctx {
- regarm_t xpsr;
- regarm_t r12;
- regarm_t lr;
regarm_t r0;
regarm_t r1;
regarm_t r2;
regarm_t r3;
+ regarm_t r12;
+ regarm_t lr_thd;
regarm_t pc;
+ regarm_t xpsr;
};
struct intctx {
@@ -72,64 +127,18 @@ struct intctx {
#endif
/**
- * @brief Platform dependent part of the @p chThdInit() API.
- * @details This code usually setup the context switching frame represented
- * by an @p intctx structure.
- */
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
- wsize - \
- sizeof(struct intctx)); \
- tp->p_ctx.r13->r4 = (void *)pf; \
- tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->lr = (void *)_port_thread_start; \
-}
-
-/**
- * @brief Stack size for the system idle thread.
- * @details This size depends on the idle thread implementation, usually
- * the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
- * @note In this port it is set to 8 because the idle thread does have
- * a stack frame when compiling without optimizations. You may
- * reduce this value to zero when compiling with optimizations.
- */
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 8
-#endif
-
-/**
- * @brief Per-thread stack overhead for interrupts servicing.
- * @details This constant is used in the calculation of the correct working
- * area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
- * compiler optimizations disabled.
- */
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 16
-#endif
-
-/**
* @brief IRQ prologue code.
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_PROLOGUE() { \
- port_lock_from_isr(); \
- _port_irq_nesting++; \
- port_unlock_from_isr(); \
-}
+#define PORT_IRQ_PROLOGUE() regarm_t _saved_lr = (regarm_t)__return_address()
/**
* @brief IRQ epilogue code.
* @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_EPILOGUE() _port_irq_epilogue()
+#define PORT_IRQ_EPILOGUE() _port_irq_epilogue(_saved_lr)
/**
* @brief IRQ handler function declaration.
@@ -149,8 +158,9 @@ struct intctx {
* @brief Port-related initialization code.
*/
#define port_init() { \
- _port_irq_nesting = 0; \
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \
+ NVICSetSystemHandlerPriority(HANDLER_PENDSV, \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \
NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \
}
@@ -226,11 +236,15 @@ struct intctx {
* @param[in] ntp the thread to be switched in
* @param[in] otp the thread to be switched out
*/
+#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define port_switch(ntp, otp) _port_switch(ntp, otp)
-
-#if !defined(__DOXYGEN__)
-extern regarm_t _port_saved_pc;
-extern unsigned _port_irq_nesting;
+#else
+#define port_switch(ntp, otp) { \
+ struct intctx *r13 = (struct intctx *)__current_sp(); \
+ if ((void *)(r13 - 1) < (void *)(otp + 1)) \
+ chDbgPanic("stack overflow"); \
+ _port_switch(ntp, otp); \
+}
#endif
#ifdef __cplusplus
@@ -238,13 +252,15 @@ extern "C" {
#endif
void port_halt(void);
void _port_switch(Thread *ntp, Thread *otp);
- void _port_irq_epilogue(void);
+ void _port_irq_epilogue(regarm_t lr);
void _port_switch_from_isr(void);
void _port_thread_start(void);
#ifdef __cplusplus
}
#endif
+#endif /* _FROM_ASM_ */
+
#endif /* _CHCORE_V6M_H_ */
/** @} */
diff --git a/os/ports/RVCT/ARMCMx/chcore_v7m.c b/os/ports/RVCT/ARMCMx/chcore_v7m.c
index 84d1c97a1..7ed226255 100644
--- a/os/ports/RVCT/ARMCMx/chcore_v7m.c
+++ b/os/ports/RVCT/ARMCMx/chcore_v7m.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/chcore_v7m.h b/os/ports/RVCT/ARMCMx/chcore_v7m.h
index 528144173..14b25fd8c 100644
--- a/os/ports/RVCT/ARMCMx/chcore_v7m.h
+++ b/os/ports/RVCT/ARMCMx/chcore_v7m.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -29,9 +30,111 @@
#define _CHCORE_V7M_H_
/*===========================================================================*/
+/* Port constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Disabled value for BASEPRI register.
+ */
+#define CORTEX_BASEPRI_DISABLED 0
+
+/*===========================================================================*/
+/* Port configurable parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief Simplified priority handling flag.
+ * @details Activating this option will make the Kernel work in compact mode.
+ */
+#ifndef CORTEX_SIMPLIFIED_PRIORITY
+#define CORTEX_SIMPLIFIED_PRIORITY FALSE
+#endif
+
+/**
+ * @brief SVCALL handler priority.
+ * @note The default SVCALL handler priority is defaulted to
+ * @p CORTEX_MAXIMUM_PRIORITY+1, this reserves the
+ * @p CORTEX_MAXIMUM_PRIORITY priority level as fast interrupts
+ * priority level.
+ */
+#ifndef CORTEX_PRIORITY_SVCALL
+#define CORTEX_PRIORITY_SVCALL (CORTEX_MAXIMUM_PRIORITY + 1)
+#else
+/* If it is externally redefined then better perform a validity check on it.*/
+#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL)
+#error "invalid priority level specified for CORTEX_PRIORITY_SVCALL"
+#endif
+#endif
+
+/*===========================================================================*/
+/* Port derived parameters. */
+/*===========================================================================*/
+
+/**
+ * @brief BASEPRI level within kernel lock.
+ * @note In compact kernel mode this constant value is enforced to zero.
+ */
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
+#define CORTEX_BASEPRI_KERNEL \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1)
+#else
+#define CORTEX_BASEPRI_KERNEL 0
+#endif
+
+/**
+ * @brief PendSV priority level.
+ * @note This priority is enforced to be equal to @p CORTEX_BASEPRI_KERNEL,
+ * this handler always have the highest priority that cannot preempt
+ * the kernel.
+ */
+#define CORTEX_PRIORITY_PENDSV CORTEX_BASEPRI_KERNEL
+
+/*===========================================================================*/
+/* Port exported info. */
+/*===========================================================================*/
+
+#if (CORTEX_MODEL == CORTEX_M3) || defined(__DOXYGEN__)
+/**
+ * @brief Macro defining the specific ARM architecture.
+ */
+#define CH_ARCHITECTURE_ARM_v7M
+
+/**
+ * @brief Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARMv7-M"
+
+/**
+ * @brief Name of the architecture variant.
+ */
+#define CH_CORE_VARIANT_NAME "Cortex-M3"
+
+#elif (CORTEX_MODEL == CORTEX_M4)
+#define CH_ARCHITECTURE_ARM_v7ME
+#define CH_ARCHITECTURE_NAME "ARMv7-ME"
+#define CH_CORE_VARIANT_NAME "Cortex-M4"
+#endif
+
+/**
+ * @brief Port-specific information string.
+ */
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
+#define CH_PORT_INFO "Advanced kernel mode"
+#else
+#define CH_PORT_INFO "Compact kernel mode"
+#endif
+
+/*===========================================================================*/
/* Port implementation part. */
/*===========================================================================*/
+#if !defined(_FROM_ASM_)
+
+/**
+ * @brief Generic ARM register.
+ */
+typedef void *regarm_t;
+
#if !defined(__DOXYGEN__)
struct extctx {
regarm_t r0;
@@ -48,9 +151,7 @@ struct intctx {
regarm_t r4;
regarm_t r5;
regarm_t r6;
-#ifndef CH_CURRP_REGISTER_CACHE
regarm_t r7;
-#endif
regarm_t r8;
regarm_t r9;
regarm_t r10;
@@ -60,48 +161,6 @@ struct intctx {
#endif
/**
- * @brief Platform dependent part of the @p chThdCreateI() API.
- * @details This code usually setup the context switching frame represented
- * by an @p intctx structure.
- */
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
- wsize - \
- sizeof(struct intctx)); \
- tp->p_ctx.r13->r4 = (void *)pf; \
- tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->lr = (void *)_port_thread_start; \
-}
-
-/**
- * @brief Stack size for the system idle thread.
- * @details This size depends on the idle thread implementation, usually
- * the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
- * @note In this port it is set to 8 because the idle thread does have
- * a stack frame when compiling without optimizations. You may
- * reduce this value to zero when compiling with optimizations.
- */
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 8
-#endif
-
-/**
- * @brief Per-thread stack overhead for interrupts servicing.
- * @details This constant is used in the calculation of the correct working
- * area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoRescheduleI() can have a stack frame, expecially with
- * compiler optimizations disabled.
- */
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 16
-#endif
-
-/**
* @brief IRQ prologue code.
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
@@ -136,6 +195,8 @@ struct intctx {
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \
NVICSetSystemHandlerPriority(HANDLER_SVCALL, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL)); \
+ NVICSetSystemHandlerPriority(HANDLER_PENDSV, \
+ CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \
NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \
}
@@ -146,10 +207,14 @@ struct intctx {
* more actions.
* @note In this port this it raises the base priority to kernel level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_lock() { \
register uint32_t basepri __asm("basepri"); \
basepri = CORTEX_BASEPRI_KERNEL; \
}
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_lock() __disable_irq()
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Kernel-unlock action.
@@ -157,10 +222,14 @@ struct intctx {
* more actions.
* @note In this port this it lowers the base priority to user level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_unlock() { \
register uint32_t basepri __asm("basepri"); \
basepri = CORTEX_BASEPRI_DISABLED; \
}
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_unlock() __enable_irq()
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Kernel-lock action from an interrupt handler.
@@ -193,21 +262,28 @@ struct intctx {
* @note Interrupt sources above kernel level remains enabled.
* @note In this port it raises/lowers the base priority to kernel level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_suspend() { \
register uint32_t basepri __asm("basepri"); \
basepri = CORTEX_BASEPRI_KERNEL; \
- __enable_irq(); \
}
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_suspend() __disable_irq()
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Enables all the interrupt sources.
* @note In this port it lowers the base priority to user level.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
#define port_enable() { \
register uint32_t basepri __asm("basepri"); \
basepri = CORTEX_BASEPRI_DISABLED; \
__enable_irq(); \
}
+#else /* CORTEX_SIMPLIFIED_PRIORITY */
+#define port_enable() __enable_irq()
+#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/**
* @brief Enters an architecture-dependent IRQ-waiting mode.
@@ -233,7 +309,16 @@ struct intctx {
* @param[in] ntp the thread to be switched in
* @param[in] otp the thread to be switched out
*/
-#define port_switch(ntp, otp) _port_switch(ntp, otp)
+#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
+#define port_switch(ntp, otp) _port_switch(ntp, otp)
+#else
+#define port_switch(ntp, otp) { \
+ struct intctx *r13 = (struct intctx *)__current_sp(); \
+ if ((void *)(r13 - 1) < (void *)(otp + 1)) \
+ chDbgPanic("stack overflow"); \
+ _port_switch(ntp, otp); \
+}
+#endif
#ifdef __cplusplus
extern "C" {
@@ -247,6 +332,8 @@ extern "C" {
}
#endif
+#endif /* _FROM_ASM_ */
+
#endif /* _CHCORE_V7M_H_ */
/** @} */
diff --git a/os/ports/RVCT/ARMCMx/chcoreasm_v6m.s b/os/ports/RVCT/ARMCMx/chcoreasm_v6m.s
index 8f348f099..6cfc89410 100644
--- a/os/ports/RVCT/ARMCMx/chcoreasm_v6m.s
+++ b/os/ports/RVCT/ARMCMx/chcoreasm_v6m.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,15 +19,15 @@
*/
/*
- * Imports the Cortex-Mx parameters header and performs the same calculations
- * done in chcore.h.
+ * Imports the Cortex-Mx configuration headers.
*/
-#include "cmparams.h"
-
-#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
+#define _FROM_ASM_
+#include "chconf.h"
+#include "chcore.h"
EXTCTX_SIZE EQU 32
CONTEXT_OFFSET EQU 12
+SCB_ICSR EQU 0xE000ED04
PRESERVE8
THUMB
@@ -35,8 +36,6 @@ CONTEXT_OFFSET EQU 12
IMPORT chThdExit
IMPORT chSchIsRescRequiredExI
IMPORT chSchDoRescheduleI
- IMPORT _port_saved_pc
- IMPORT _port_irq_nesting
/*
* Performs a context switch between two threads.
@@ -74,27 +73,54 @@ _port_thread_start PROC
ENDP
/*
+ * NMI vector.
+ * The NMI vector is used for exception mode re-entering after a context
+ * switch.
+ */
+#if !CORTEX_ALTERNATE_SWITCH
+ EXPORT NMIVector
+NMIVector PROC
+ mrs r3, PSP
+ adds r3, r3, #32
+ msr PSP, r3
+ cpsie i
+ bx lr
+ ENDP
+#endif
+
+/*
+ * PendSV vector.
+ * The PendSV vector is used for exception mode re-entering after a context
+ * switch.
+ */
+#if CORTEX_ALTERNATE_SWITCH
+ EXPORT PendSVVector
+PendSVVector PROC
+ mrs r3, PSP
+ adds r3, r3, #32
+ msr PSP, r3
+ bx lr
+ ENDP
+#endif
+
+/*
* Post-IRQ switch code.
* Exception handlers return here for context switching.
*/
EXPORT _port_switch_from_isr
_port_switch_from_isr PROC
- /* Note, saves r4 to make space for the PC.*/
- push {r0, r1, r2, r3, r4}
- mrs r0, APSR
- mov r1, r12
- push {r0, r1, lr}
- ldr r0, =_port_saved_pc
- ldr r0, [r0]
- adds r0, r0, #1
- str r0, [sp, #28]
bl chSchDoRescheduleI
- pop {r0, r1, r2}
- mov r12, r1
- msr APSR, r0
- mov lr, r2
+ ldr r2, =SCB_ICSR
+ movs r3, #128
+#if CORTEX_ALTERNATE_SWITCH
+ lsls r3, r3, #21
+ str r3, [r2, #0]
cpsie i
- pop {r0, r1, r2, r3, pc}
+#else
+ lsls r3, r3, #24
+ str r3, [r2, #0]
+#endif
+waithere b waithere
ENDP
/*
@@ -102,29 +128,26 @@ _port_switch_from_isr PROC
*/
EXPORT _port_irq_epilogue
_port_irq_epilogue PROC
- push {r4, lr}
+ push {r3, lr}
+ adds r0, r0, #15
+ beq stillnested
cpsid i
- ldr r2, =_port_irq_nesting
- ldr r3, [r2]
- subs r3, r3, #1
- str r3, [r2]
- cmp r3, #0
- beq skipexit
-notrequired
- cpsie i
- pop {r4, pc}
-skipexit
bl chSchIsRescRequiredExI
cmp r0, #0
- beq notrequired
- mrs r1, PSP
- ldr r2, =_port_saved_pc
- ldr r3, [r1, #24]
- str r3, [r2]
- ldr r3, =_port_switch_from_isr
- str r3, [r1, #24]
- pop {r4, pc}
- nop
+ bne doresch
+ cpsie i
+stillnested
+ pop {r3, pc}
+doresch
+ mrs r3, PSP
+ subs r3, r3, #32
+ msr PSP, r3
+ ldr r2, =_port_switch_from_isr
+ str r2, [r3, #24]
+ movs r2, #128
+ lsls r2, r2, #17
+ str r2, [r3, #28]
+ pop {r3, pc}
ENDP
END
diff --git a/os/ports/RVCT/ARMCMx/chcoreasm_v7m.s b/os/ports/RVCT/ARMCMx/chcoreasm_v7m.s
index 1e00ccea3..6c7efeb3c 100644
--- a/os/ports/RVCT/ARMCMx/chcoreasm_v7m.s
+++ b/os/ports/RVCT/ARMCMx/chcoreasm_v7m.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,27 +19,17 @@
*/
/*
- * Imports the Cortex-Mx parameters header and performs the same calculations
- * done in chcore.h.
+ * Imports the Cortex-Mx configuration headers.
*/
-#include "cmparams.h"
-
-#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
-
-#ifndef CORTEX_PRIORITY_SVCALL
-#define CORTEX_PRIORITY_SVCALL 1
-#endif
-
-#ifndef CORTEX_BASEPRI_KERNEL
-#define CORTEX_BASEPRI_KERNEL CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1)
-#endif
-
-#define CORTEX_BASEPRI_DISABLED 0
+#define _FROM_ASM_
+#include "chconf.h"
+#include "chcore.h"
EXTCTX_SIZE EQU 32
CONTEXT_OFFSET EQU 12
SCB_ICSR EQU 0xE000ED04
ICSR_RETTOBASE EQU 0x00000800
+ICSR_PENDSVSET EQU 0x10000000
PRESERVE8
THUMB
@@ -65,8 +56,12 @@ _port_switch PROC
*/
EXPORT _port_thread_start
_port_thread_start PROC
+#if CORTEX_SIMPLIFIED_PRIORITY
+ cpsie i
+#else
movs r3, #CORTEX_BASEPRI_DISABLED
msr BASEPRI, r3
+#endif
mov r0, r5
blx r4
bl chThdExit
@@ -79,7 +74,16 @@ _port_thread_start PROC
EXPORT _port_switch_from_isr
_port_switch_from_isr PROC
bl chSchDoRescheduleI
+#if CORTEX_SIMPLIFIED_PRIORITY
+ mov r3, #SCB_ICSR :AND: 0xFFFF
+ movt r3, #SCB_ICSR :SHR: 16
+ mov r2, #ICSR_PENDSVSET
+ str r2, [r3, #0]
+ cpsie i
+waithere b waithere
+#else
svc #0
+#endif
ENDP
/*
@@ -87,15 +91,23 @@ _port_switch_from_isr PROC
*/
EXPORT _port_irq_epilogue
_port_irq_epilogue PROC
+#if CORTEX_SIMPLIFIED_PRIORITY
+ cpsid i
+#else
movs r3, #CORTEX_BASEPRI_KERNEL
msr BASEPRI, r3
+#endif
mov r3, #SCB_ICSR :AND: 0xFFFF
movt r3, #SCB_ICSR :SHR: 16
ldr r3, [r3, #0]
tst r3, #ICSR_RETTOBASE
bne skipexit
+#if CORTEX_SIMPLIFIED_PRIORITY
+ cpsie i
+#else
movs r3, #CORTEX_BASEPRI_DISABLED
msr BASEPRI, r3
+#endif
bx lr
skipexit
push {r3, lr}
@@ -111,8 +123,12 @@ skipexit
str r2, [r3, #28]
pop {r3, pc}
noreschedule
+#if CORTEX_SIMPLIFIED_PRIORITY
+ cpsie i
+#else
movs r3, #CORTEX_BASEPRI_DISABLED
msr BASEPRI, r3
+#endif
pop {r3, pc}
ENDP
@@ -121,6 +137,7 @@ noreschedule
* Discarding the current exception context and positioning the stack to
* point to the real one.
*/
+#if !CORTEX_SIMPLIFIED_PRIORITY
EXPORT SVCallVector
SVCallVector PROC
mrs r3, PSP
@@ -130,5 +147,22 @@ SVCallVector PROC
msr BASEPRI, r3
bx lr
ENDP
+#endif
+
+/*
+ * PendSV vector.
+ * Discarding the current exception context and positioning the stack to
+ * point to the real one.
+ */
+#if CORTEX_SIMPLIFIED_PRIORITY
+ EXPORT PendSVVector
+PendSVVector PROC
+ mrs r3, PSP
+ adds r3, r3, #EXTCTX_SIZE
+ msr PSP, r3
+ bx lr
+ nop
+ ENDP
+#endif
END
diff --git a/os/ports/RVCT/ARMCMx/chtypes.h b/os/ports/RVCT/ARMCMx/chtypes.h
index af8d64eb8..8f681d7c2 100644
--- a/os/ports/RVCT/ARMCMx/chtypes.h
+++ b/os/ports/RVCT/ARMCMx/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/cstartup.s b/os/ports/RVCT/ARMCMx/cstartup.s
index d0a8104a8..95f2f0f48 100644
--- a/os/ports/RVCT/ARMCMx/cstartup.s
+++ b/os/ports/RVCT/ARMCMx/cstartup.s
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/nvic.c b/os/ports/RVCT/ARMCMx/nvic.c
index 568c4a23e..8656a288c 100644
--- a/os/ports/RVCT/ARMCMx/nvic.c
+++ b/os/ports/RVCT/ARMCMx/nvic.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/nvic.h b/os/ports/RVCT/ARMCMx/nvic.h
index 590deae24..a1fbe4ea5 100644
--- a/os/ports/RVCT/ARMCMx/nvic.h
+++ b/os/ports/RVCT/ARMCMx/nvic.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/RVCT/ARMCMx/port.dox b/os/ports/RVCT/ARMCMx/port.dox
index 0e65f8c2b..c69fcdd27 100644
--- a/os/ports/RVCT/ARMCMx/port.dox
+++ b/os/ports/RVCT/ARMCMx/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -25,9 +26,28 @@
* This port supports all the cores implementing the ARMv6-M and ARMv7-M
* architectures.
*
- * @section RVCT_ARMCMx_STATES_A System logical states in ARMv6-M mode
- * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
- * Cortex-M0 port:
+ * @section RVCT_ARMCMx_MODES Kernel Modes
+ * The Cortex-Mx port supports two distinct kernel modes:
+ * - <b>Advanced Kernel</b> mode. In this mode the kernel only masks
+ * interrupt sources with priorities below or equal to the
+ * @p CORTEX_BASEPRI_KERNEL level. Higher priorities are not affected by
+ * the kernel critical sections and can be used for fast interrupts.
+ * This mode is not available in the ARMv6-M architecture which does not
+ * support priority masking.
+ * - <b>Compact Kernel</b> mode. In this mode the kernel handles IRQ priorities
+ * in a simplified way, all interrupt sources are disabled when the kernel
+ * enters into a critical zone and re-enabled on exit. This is simple and
+ * adequate for most applications, this mode results in a more compact and
+ * faster kernel.
+ * .
+ * The selection of the mode is performed using the port configuration option
+ * @p CORTEX_SIMPLIFIED_PRIORITY. Apart from the different handling of
+ * interrupts there are no other differences between the two modes. The
+ * kernel API is exactly the same.
+ *
+ * @section RVCT_ARMCMx_STATES_A System logical states in Compact Kernel mode
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in Compact
+ * Kernel mode:
* - <b>Init</b>. This state is represented by the startup code and the
* initialization code before @p chSysInit() is executed. It has not a
* special hardware state associated.
@@ -52,21 +72,21 @@
* mode.
* - <b>Serving Fast Interrupt</b>. This state is not implemented in the
* ARMv6-M implementation.
- * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-M3 has a specific
+ * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-Mx has a specific
* asynchronous NMI vector and several synchronous fault vectors that can
* be considered belonging to this category.
* - <b>Halted</b>. Implemented as an infinite loop after globally masking all
* the maskable interrupt sources. The ARM state is whatever the processor
* was running when @p chSysHalt() was invoked.
*
- * @section RVCT_ARMCMx_STATES_B System logical states in ARMv7-M mode
- * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
- * Cortex-M3 port:
+ * @section RVCT_ARMCMx_STATES_B System logical states in Advanced Kernel mode
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in the
+ * Advanced Kernel mode:
* - <b>Init</b>. This state is represented by the startup code and the
* initialization code before @p chSysInit() is executed. It has not a
* special hardware state associated.
* - <b>Normal</b>. This is the state the system has after executing
- * @p chSysInit(). In this state the ARM Cortex-M3 has the BASEPRI register
+ * @p chSysInit(). In this state the ARM Cortex-Mx has the BASEPRI register
* set at @p CORTEX_BASEPRI_USER level, interrupts are not masked. The
* processor is running in thread-privileged mode.
* - <b>Suspended</b>. In this state the interrupt sources are not globally
@@ -92,7 +112,7 @@
* - <b>Serving Fast Interrupt</b>. It is basically the same of the SRI state
* but it is not possible to switch to the I-Locked state because fast
* interrupts can preempt the kernel critical zone.
- * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-M3 has a specific
+ * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-Mx has a specific
* asynchronous NMI vector and several synchronous fault vectors that can
* be considered belonging to this category.
* - <b>Halted</b>. Implemented as an infinite loop after globally masking all
@@ -139,17 +159,24 @@
* - @p IDLE_THREAD_STACK_SIZE, stack area size to be assigned to the IDLE
* thread. Usually there is no need to change this value unless inserting
* code in the IDLE thread using the @p IDLE_LOOP_HOOK hook macro.
- * - @p CORTEX_BASEPRI_KERNEL, this is the @p BASEPRI value for the kernel lock
- * code. Code running at higher priority levels must not invoke any OS API.
- * This setting is specific to the ARMv7-M architecture.
* - @p CORTEX_PRIORITY_SYSTICK, priority of the SYSTICK handler.
- * - @p CORTEX_PRIORITY_SVCALL, priority of the SVCALL handler.
* - @p CORTEX_PRIORITY_PENDSV, priority of the PENDSV handler.
* - @p CORTEX_ENABLE_WFI_IDLE, if set to @p TRUE enables the use of the
* @p <b>wfi</b> instruction from within the idle loop. This option is
* defaulted to FALSE because it can create problems with some debuggers.
* Setting this option to TRUE reduces the system power requirements.
* .
+ * @section RVCT_ARMCMx_CONF_1 ARMv6-M specific options
+ * The following options are specific for the ARMv6-M architecture:
+ * - @p CORTEX_ALTERNATE_SWITCH, when activated makes the OS use the PendSV
+ * exception instead of NMI as preemption handler.
+ * .
+ * @section RVCT_ARMCMx_CONF_2 ARMv7-M specific options
+ * The following options are specific for the ARMv6-M architecture:
+ * - @p CORTEX_PRIORITY_SVCALL, priority of the SVCALL handler.
+ * - @p CORTEX_SIMPLIFIED_PRIORITY, when enabled activates the Compact kernel
+ * mode.
+ * .
* @ingroup RVCT_ARMCMx
*/
diff --git a/os/ports/cosmic/STM8/chcore.c b/os/ports/cosmic/STM8/chcore.c
index 1c382cde6..c5f1de2d6 100644
--- a/os/ports/cosmic/STM8/chcore.c
+++ b/os/ports/cosmic/STM8/chcore.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/cosmic/STM8/chcore.h b/os/ports/cosmic/STM8/chcore.h
index f5fde8fb1..93a4c24f0 100644
--- a/os/ports/cosmic/STM8/chcore.h
+++ b/os/ports/cosmic/STM8/chcore.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -36,7 +37,7 @@
* @brief Enables the use of the WFI instruction in the idle thread loop.
*/
#ifndef STM8_ENABLE_WFI_IDLE
-#define STM8_ENABLE_WFI_IDLE FALSE
+#define STM8_ENABLE_WFI_IDLE FALSE
#endif
/*===========================================================================*/
@@ -51,7 +52,17 @@
/**
* @brief Name of the implemented architecture.
*/
-#define CH_ARCHITECTURE_NAME "STM8"
+#define CH_ARCHITECTURE_NAME "STM8"
+
+/**
+ * @brief Name of the compiler supported by this port.
+ */
+#define CH_COMPILER_NAME "Cosmic"
+
+/**
+ * @brief Port-specific information string.
+ */
+#define CH_PORT_INFO "None"
/*===========================================================================*/
/* Port implementation part. */
@@ -144,10 +155,10 @@ struct stm8_startctx {
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
- * by @p INT_REQUIRED_STACK.
+ * by @p PORT_INT_REQUIRED_STACK.
*/
-#ifndef IDLE_THREAD_STACK_SIZE
-#define IDLE_THREAD_STACK_SIZE 0
+#ifndef PORT_IDLE_THREAD_STACK_SIZE
+#define PORT_IDLE_THREAD_STACK_SIZE 0
#endif
/**
@@ -155,8 +166,8 @@ struct stm8_startctx {
* @details This is a safe value, you may trim it down after reading the
* right size in the map file.
*/
-#ifndef INT_REQUIRED_STACK
-#define INT_REQUIRED_STACK 48
+#ifndef PORT_INT_REQUIRED_STACK
+#define PORT_INT_REQUIRED_STACK 48
#endif
/**
@@ -170,7 +181,7 @@ struct stm8_startctx {
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
(sizeof(struct intctx) - 1) + \
(sizeof(struct extctx) - 1) + \
- (n) + (INT_REQUIRED_STACK))
+ (n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
diff --git a/os/ports/cosmic/STM8/chtypes.h b/os/ports/cosmic/STM8/chtypes.h
index 3fe35570d..440b2ed0f 100644
--- a/os/ports/cosmic/STM8/chtypes.h
+++ b/os/ports/cosmic/STM8/chtypes.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/cosmic/STM8/port.dox b/os/ports/cosmic/STM8/port.dox
index ec57658ae..80ae3fda5 100644
--- a/os/ports/cosmic/STM8/port.dox
+++ b/os/ports/cosmic/STM8/port.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/ports/ports.dox b/os/ports/ports.dox
index 8168fdbce..df9828ce6 100644
--- a/os/ports/ports.dox
+++ b/os/ports/ports.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/various/ch.cpp b/os/various/ch.cpp
index a3507868d..2b23768d7 100644
--- a/os/various/ch.cpp
+++ b/os/various/ch.cpp
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -130,19 +131,19 @@ namespace chibios_rt {
return chMsgSend(thread_ref, msg);
}
- msg_t BaseThread::WaitMessage(void) {
+ Thread *BaseThread::WaitMessage(void) {
return chMsgWait();
}
- msg_t BaseThread::GetMessage(void) {
+ msg_t BaseThread::GetMessage(Thread* tp) {
- return chMsgGet();
+ return chMsgGet(tp);
}
- void BaseThread::ReleaseMessage(msg_t msg) {
+ void BaseThread::ReleaseMessage(Thread* tp, msg_t msg) {
- chMsgRelease(msg);
+ chMsgRelease(tp, msg);
}
bool BaseThread::IsPendingMessage(void) {
diff --git a/os/various/ch.hpp b/os/various/ch.hpp
index 7bbd43c9f..d48dc30fe 100644
--- a/os/various/ch.hpp
+++ b/os/various/ch.hpp
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -197,26 +198,27 @@ namespace chibios_rt {
msg_t SendMessage(msg_t msg);
/**
- * @brief Waits for a message and returns it.
+ * @brief Waits for a message.
*
- * @return The incoming message.
+ * @return The sebder thread.
*/
- static msg_t WaitMessage(void);
+ static Thread *WaitMessage(void);
/**
* @brief Returns an enqueued message or @p NULL.
*
+ * @param[in] tp the sender thread
* @return The incoming message.
- * @retval NULL No incoming message.
*/
- static msg_t GetMessage(void);
+ static msg_t GetMessage(Thread* tp);
/**
* @brief Releases the next message in queue with a reply.
*
+ * @param[in] tp the sender thread
* @param[in] msg the answer message
*/
- static void ReleaseMessage(msg_t msg);
+ static void ReleaseMessage(Thread* tp, msg_t msg);
/**
* @brief Returns true if there is at least one message in queue.
diff --git a/os/various/evtimer.c b/os/various/evtimer.c
index 140d90ed0..6a7226b27 100644
--- a/os/various/evtimer.c
+++ b/os/various/evtimer.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/various/evtimer.h b/os/various/evtimer.h
index 3f675fffc..a753e8984 100644
--- a/os/various/evtimer.h
+++ b/os/various/evtimer.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/various/memstreams.c b/os/various/memstreams.c
index 9e6bd1e3a..b1edf1a45 100644
--- a/os/various/memstreams.c
+++ b/os/various/memstreams.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/various/memstreams.h b/os/various/memstreams.h
index 438b8ce00..53d8c567d 100644
--- a/os/various/memstreams.h
+++ b/os/various/memstreams.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/various/shell.c b/os/various/shell.c
index 8a0fd4d45..e3686c6cb 100644
--- a/os/various/shell.c
+++ b/os/various/shell.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/various/shell.h b/os/various/shell.h
index 821a2c985..9b3b70513 100644
--- a/os/various/shell.h
+++ b/os/various/shell.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/various/syscalls.c b/os/various/syscalls.c
index 2abe6dfde..b22765b80 100644
--- a/os/various/syscalls.c
+++ b/os/various/syscalls.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/various/usb_msc.c b/os/various/usb_msc.c
new file mode 100644
index 000000000..43a5ec23c
--- /dev/null
+++ b/os/various/usb_msc.c
@@ -0,0 +1,303 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*-*
+ * @file usb_msc.c
+ * @brief USB Mass Storage Class code.
+ *
+ * @addtogroup USB_MSC
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#include "usb_msc.h"
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/**
+ * @brief Zero-filled constant buffer.
+ */
+static const uint8_t zerobuf[4] = {0, 0, 0, 0};
+
+/**
+ * @brief Answer to the INQUIRY command.
+ */
+static const uint8_t scsi_inquiry_data[] = {
+ 0x00, /* Direct Access Device. */
+ 0x80, /* RMB = 1: Removable Medium. */
+ 0x02, /* ISO, ECMA, ANSI = 2. */
+ 0x00, /* UFI response format. */
+
+ 36 - 4, /* Additional Length. */
+ 0x00,
+ 0x00,
+ 0x00,
+ /* Vendor Identification */
+ 'C', 'h', 'i', 'b', 'i', 'O', 'S', ' ',
+ /* Product Identification */
+ 'S', 'D', ' ', 'F', 'l', 'a', 's', 'h',
+ ' ', 'D', 'i', 's', 'k', ' ', ' ', ' ',
+ /* Product Revision Level */
+ '1', '.', '0', ' '
+};
+
+/**
+ * @brief Generic buffer.
+ */
+uint8_t buf[16];
+
+/*===========================================================================*/
+/* MMC interface code. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* SCSI emulation code. */
+/*===========================================================================*/
+
+static uint8_t scsi_read_format_capacities(uint32_t *nblocks,
+ uint32_t *secsize) {
+
+ *nblocks = 1024;
+ *secsize = 512;
+ return 3; /* No Media.*/
+}
+
+/*===========================================================================*/
+/* Mass Storage Class related code. */
+/*===========================================================================*/
+
+/**
+ * @brief MSC state machine current state.
+ */
+static mscstate_t msc_state;
+
+/**
+ * @brief Received CBW.
+ */
+static msccbw_t CBW;
+
+/**
+ * @brief CSW to be transmitted.
+ */
+static msccsw_t CSW;
+
+/**
+ * @brief MSC state machine initialization.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ */
+static void msc_reset(USBDriver *usbp) {
+
+ msc_state = MSC_IDLE;
+ chSysLockFromIsr();
+ usbStartReceiveI(usbp, MSC_DATA_OUT_EP, (uint8_t *)&CBW, sizeof CBW);
+ chSysUnlockFromIsr();
+}
+
+static void msc_transmit(USBDriver *usbp, const uint8_t *p, size_t n) {
+
+ if (n > CBW.dCBWDataTransferLength)
+ n = CBW.dCBWDataTransferLength;
+ CSW.dCSWDataResidue = CBW.dCBWDataTransferLength - (uint32_t)n;
+ chSysLockFromIsr();
+ usbStartTransmitI(usbp, MSC_DATA_IN_EP, p, n);
+ chSysUnlockFromIsr();
+}
+
+static void msc_sendstatus(USBDriver *usbp) {
+
+ msc_state = MSC_SENDING_CSW;
+ chSysLockFromIsr();
+ usbStartTransmitI(usbp, MSC_DATA_IN_EP, (uint8_t *)&CSW, sizeof CSW);
+ chSysUnlockFromIsr();
+}
+
+static bool_t msc_decode(USBDriver *usbp) {
+ uint32_t nblocks, secsize;
+
+ switch (CBW.CBWCB[0]) {
+ case SCSI_REQUEST_SENSE:
+ break;
+ case SCSI_INQUIRY:
+ msc_transmit(usbp, (uint8_t *)&scsi_inquiry_data,
+ sizeof scsi_inquiry_data);
+ CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
+ break;
+ case SCSI_READ_FORMAT_CAPACITIES:
+ buf[8] = scsi_read_format_capacities(&nblocks, &secsize);
+ buf[0] = buf[1] = buf[2] = 0;
+ buf[3] = 8;
+ buf[4] = (uint8_t)(nblocks >> 24);
+ buf[5] = (uint8_t)(nblocks >> 16);
+ buf[6] = (uint8_t)(nblocks >> 8);
+ buf[7] = (uint8_t)(nblocks >> 0);
+ buf[9] = (uint8_t)(secsize >> 16);
+ buf[10] = (uint8_t)(secsize >> 8);
+ buf[11] = (uint8_t)(secsize >> 0);
+ msc_transmit(usbp, buf, 12);
+ CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
+ break;
+ default:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Default requests hook.
+ * @details The application must use this function as callback for the
+ * messages hook.
+ * The following requests are emulated:
+ * - MSC_GET_MAX_LUN_COMMAND.
+ * - MSC_MASS_STORAGE_RESET_COMMAND.
+ * .
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @return The hook status.
+ * @retval TRUE Message handled internally.
+ * @retval FALSE Message not handled.
+ */
+bool_t mscRequestsHook(USBDriver *usbp) {
+
+ if ((usbp->setup[0] & (USB_RTYPE_TYPE_MASK | USB_RTYPE_RECIPIENT_MASK)) ==
+ (USB_RTYPE_TYPE_CLASS | USB_RTYPE_RECIPIENT_INTERFACE)) {
+ switch (usbp->setup[1]) {
+ case MSC_GET_MAX_LUN_COMMAND:
+ usbSetupTransfer(usbp, (uint8_t *)zerobuf, 1, NULL);
+ return TRUE;
+ case MSC_MASS_STORAGE_RESET_COMMAND:
+ msc_reset(usbp);
+ usbSetupTransfer(usbp, NULL, 0, NULL);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * @brief Default data transmitted callback.
+ * @details The application must use this function as callback for the IN
+ * data endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ */
+void mscDataTransmitted(USBDriver *usbp, usbep_t ep) {
+
+ switch (msc_state) {
+ case MSC_DATA_IN:
+ CSW.dCSWSignature = MSC_CSW_SIGNATURE;
+ CSW.dCSWTag = CBW.dCBWTag;
+ chSysLockFromIsr();
+ usbStartTransmitI(usbp, ep, (uint8_t *)&CSW, sizeof CSW);
+ chSysUnlockFromIsr();
+ msc_state = MSC_SENDING_CSW;
+ break;
+ case MSC_SENDING_CSW:
+ chSysLockFromIsr();
+ usbStartReceiveI(usbp, MSC_DATA_OUT_EP, (uint8_t *)&CBW, sizeof CBW);
+ chSysUnlockFromIsr();
+ msc_state = MSC_IDLE;
+ break;
+ default:
+ ;
+ }
+}
+
+/**
+ * @brief Default data received callback.
+ * @details The application must use this function as callback for the OUT
+ * data endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ */
+void mscDataReceived(USBDriver *usbp, usbep_t ep) {
+ size_t n;
+
+ n = usbGetReceiveTransactionSizeI(usbp, ep);
+ switch (msc_state) {
+ case MSC_IDLE:
+ if ((n != sizeof(msccbw_t)) || (CBW.dCBWSignature != MSC_CBW_SIGNATURE))
+ goto stall_out; /* 6.6.1 */
+
+ /* Decoding SCSI command.*/
+ if (msc_decode(usbp)) {
+ if (CBW.dCBWDataTransferLength == 0) {
+ CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
+ CSW.dCSWDataResidue = 0;
+ msc_sendstatus(usbp);
+ return;
+ }
+ goto stall_both;
+ }
+
+ /* Commands with zero transfer length, 5.1.*/
+ if (CBW.dCBWDataTransferLength == 0) {
+ msc_sendstatus(usbp);
+ return;
+ }
+
+ /* Transfer direction.*/
+ if (CBW.bmCBWFlags & 0x80) {
+ /* IN, Device to Host.*/
+ msc_state = MSC_DATA_IN;
+ }
+ else {
+ /* OUT, Host to Device.*/
+ msc_state = MSC_DATA_OUT;
+ }
+ break;
+ case MSC_DATA_OUT:
+ break;
+ default:
+ ;
+ }
+ return;
+stall_out:
+ msc_state = MSC_ERROR;
+ chSysLockFromIsr();
+ usbStallReceiveI(usbp, ep);
+ chSysUnlockFromIsr();
+ return;
+stall_both:
+ msc_state = MSC_ERROR;
+ chSysLockFromIsr();
+ usbStallTransmitI(usbp, ep);
+ usbStallReceiveI(usbp, ep);
+ chSysUnlockFromIsr();
+ return;
+}
+
+/** @} */
diff --git a/os/various/usb_msc.h b/os/various/usb_msc.h
new file mode 100644
index 000000000..27ecc8af3
--- /dev/null
+++ b/os/various/usb_msc.h
@@ -0,0 +1,167 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*-*
+ * @file usb_msc.h
+ * @brief USB Mass Storage Class header.
+ *
+ * @addtogroup USB_MSC
+ * @{
+ */
+
+#ifndef _USB_MSC_H_
+#define _USB_MSC_H_
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define MSC_CBW_SIGNATURE 0x43425355
+#define MSC_CSW_SIGNATURE 0x53425355
+
+#define MSC_GET_MAX_LUN_COMMAND 0xFE
+#define MSC_MASS_STORAGE_RESET_COMMAND 0xFF
+
+#define MSC_CSW_STATUS_PASSED 0
+#define MSC_CSW_STATUS_FAILED 1
+#define MSC_CSW_STATUS_PHASE_ERROR 2
+
+
+#define SCSI_FORMAT_UNIT 0x04
+#define SCSI_INQUIRY 0x12
+#define SCSI_MODE_SELECT6 0x15
+#define SCSI_MODE_SELECT10 0x55
+#define SCSI_MODE_SENSE6 0x1A
+#define SCSI_MODE_SENSE10 0x5A
+#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
+#define SCSI_READ6 0x08
+#define SCSI_READ10 0x28
+#define SCSI_READ12 0xA8
+#define SCSI_READ16 0x88
+
+#define SCSI_READ_CAPACITY10 0x25
+#define SCSI_READ_CAPACITY16 0x9E
+
+#define SCSI_REQUEST_SENSE 0x03
+#define SCSI_START_STOP_UNIT 0x1B
+#define SCSI_TEST_UNIT_READY 0x00
+#define SCSI_WRITE6 0x0A
+#define SCSI_WRITE10 0x2A
+#define SCSI_WRITE12 0xAA
+#define SCSI_WRITE16 0x8A
+
+#define SCSI_VERIFY10 0x2F
+#define SCSI_VERIFY12 0xAF
+#define SCSI_VERIFY16 0x8F
+
+#define SCSI_SEND_DIAGNOSTIC 0x1D
+#define SCSI_READ_FORMAT_CAPACITIES 0x23
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Endpoint number for bulk IN.
+ */
+#if !defined(MSC_DATA_IN_EP) || defined(__DOXYGEN__)
+#define MSC_DATA_IN_EP 1
+#endif
+
+/**
+ * @brief Endpoint number for bulk OUT.
+ */
+#if !defined(MSC_DATA_OUT_EP) || defined(__DOXYGEN__)
+#define MSC_DATA_OUT_EP 2
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of the MSC possible states.
+ */
+typedef enum {
+ MSC_IDLE = 0,
+ MSC_DATA_OUT,
+ MSC_DATA_IN,
+ MSC_SENDING_CSW,
+ MSC_ERROR
+} mscstate_t;
+
+/**
+ * @brief CBW structure.
+ */
+struct CBW {
+ uint32_t dCBWSignature;
+ uint32_t dCBWTag;
+ uint32_t dCBWDataTransferLength;
+ uint8_t bmCBWFlags;
+ uint8_t bCBWLUN;
+ uint8_t bCBWCBLength;
+ uint8_t CBWCB[16];
+};
+
+/**
+ * @brief CSW structure.
+ */
+struct CSW {
+ uint32_t dCSWSignature;
+ uint32_t dCSWTag;
+ uint32_t dCSWDataResidue;
+ uint8_t bCSWStatus;
+};
+
+/**
+ * @brief Type of a CBW structure.
+ */
+typedef struct CBW msccbw_t;
+
+/**
+ * @brief Type of a CSW structure.
+ */
+typedef struct CSW msccsw_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ bool_t mscRequestsHook(USBDriver *usbp);
+ void mscDataTransmitted(USBDriver *usbp, usbep_t ep);
+ void mscDataReceived(USBDriver *usbp, usbep_t ep);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _USB_MSC_H_ */
+
+/** @} */
diff --git a/os/various/various.dox b/os/various/various.dox
index 1a8130f4d..9ae895af4 100644
--- a/os/various/various.dox
+++ b/os/various/various.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.