STM8 port: Add UART support. Make use of full 1KB on Discovery. Improve documentation.

This commit is contained in:
Kelvin Lawson
2010-03-09 00:37:46 +00:00
parent 097c32bf10
commit 7d56170c40
41 changed files with 2411 additions and 121 deletions

View File

@@ -31,8 +31,8 @@ interrupt lockouts / critical sections:
A couple of additional source files are also included here:
* uart.c: Simple driver for the ATmega UART
* tests-main.c: Main application file (used for launching automated tests)
* uart.c: Simple driver for the ATmega UART
Atomthreads includes a suite of automated tests which prove the key OS
functionality, and can be used with any architecture ports. This port
@@ -113,10 +113,19 @@ STK500 SPECIFICS
If the STK500 is used, you should connect your serial programming cable to
the "RS232 CTRL" connector.
The test applications also make use of the UART to print out Pass/Fail
The test applications make use of a LED to indicate test pass/fail status.
This is currently configured to use a bit in PORTB, which on the STK500
maps to a LED on the carrier board. You may change the port and register
bit in tests-main.c to utilise a different pin on other hardware platforms.
You may also completely omit the LED flashing in the test application if
you prefer to use the UART for monitoring test status.
The test applications also make use of the UART to print out pass/fail
indications and other information. For this you should connect a serial
debug cable to the STK500 "RS232 SPARE" connector. You should also connect
PD0/1 to "RS232 SPARE RXD/TXD" respectively using a two-wire link.
PD0/1 to "RS232 SPARE RXD/TXD" respectively using a two-wire link. Use of
a UART is not required if you prefer to use the LED or some other method
of notifying test pass/fail status.
---------------------------------------------------------------------------
@@ -145,11 +154,12 @@ out on the terminal. You can use this to verify that your platform has
enough program and data space to run the application.
To view the test results, connect a serial debug cable to your target
platform. On starting, the test applications print out "Go" on the UART.
Once the test is complete they will print out "Pass" or "Fail", along
with other information if the test failed. Most of the tests complete
within a few seconds, but some (particularly the stress tests) can take
minutes, so be patient.
platform (defaults to 9600bps 8N1). On starting, the test applications
print out "Go" on the UART. Once the test is complete they will print
out "Pass" or "Fail", along with other information if the test failed.
Most of the tests complete within a few seconds, but some (particularly
the stress tests) can take minutes, so be patient.
Note that some tests utilise four test threads, which together with the
idle thread and main test thread can consume significant RAM resource.

View File

@@ -29,14 +29,12 @@
#include <stdio.h>
#include <avr/pgmspace.h>
#include "atom.h"
#include "atomport-private.h"
#include "atomtests.h"
#include "atomtimer.h"
#include "uart.h"
#include <avr/pgmspace.h>
/* Constants */
@@ -228,7 +226,7 @@ int main ( void )
static void main_thread_func (uint32_t data)
{
uint32_t test_status;
int sleep_ticks;
int sleep_ticks;
/* Enable all LEDs (STK500-specific) */
DDRB = 0xFF;

View File

@@ -52,7 +52,7 @@ static ATOM_MUTEX uart_mutex;
/*
* Initialize the UART to 9600 Bd, tx/rx, 8N1.
* Initialize the UART to requested baudrate, tx/rx, 8N1.
*/
int
uart_init(uint32_t baudrate)

View File

@@ -14,6 +14,7 @@ CC=cxstm8
ASM=castm8
LINK=clnk
CHEX=chex
PART=STM8S105
# Enable stack-checking
STACK_CHECK=true
@@ -22,11 +23,11 @@ STACK_CHECK=true
BUILD_DIR=build
# Port/application object files
APP_OBJECTS = atomport.o tests-main.o stm8_interrupt_vector.o
APP_OBJECTS = atomport.o tests-main.o stm8_interrupt_vector.o uart.o
APP_ASM_OBJECTS = atomport-asm.o
# STM8S Peripheral driver object files
PERIPH_OBJECTS = stm8s_gpio.o stm8s_tim1.o
PERIPH_OBJECTS = stm8s_gpio.o stm8s_tim1.o stm8s_clk.o stm8s_uart2.o
# Kernel object files
KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o
@@ -48,8 +49,8 @@ vpath %.elf .\$(BUILD_DIR)
vpath %.hex .\$(BUILD_DIR)
# Compiler/Assembler flags
CFLAGS=+modsl0 -pp
DBG_CFLAGS=+modsl0 +debug -pxp -no -pp -l
CFLAGS=+modsl0 -pp -d$(PART)
DBG_CFLAGS=+modsl0 +debug -pxp -no -pp -l -d$(PART)
ASMFLAGS=
DBG_ASMFLAGS=-xx -u

View File

@@ -31,8 +31,9 @@ interrupt lockouts / critical sections:
A few additional source files are also included here:
* stm8_interrupt_vector.c: List of interrupt handlers for vector table
* tests-main.c: Main application file (used for launching automated tests)
* stm8_interrupt_vector.c: List of interrupt handlers for vector table
* uart.c: UART wrapper to allow use of stdio/printf()
* stm8s-periphs/*.*: Peripheral drivers as delivered by ST (no changes
to distributed code).
@@ -123,9 +124,9 @@ This is also a good starting point for building your own applications:
simply modify the file tests-main.c which starts the test application.
You can run any of the other automated tests by replacing the file sem1.c
within the project by another of the tests within the atomthreads tests
folder. This is rather painful using a GUI interface, and you may prefer
to use the Makefile-based system instead which builds all automated
tests in one command.
folder. This is rather painful using a GUI interface due to the large
number of test files, and you may prefer to use the Makefile-based system
instead which builds all automated tests in one command.
---------------------------------------------------------------------------
@@ -179,37 +180,31 @@ PROGRAMMING MAKEFILE-BUILT APPLICATIONS TO THE TARGET DEVICE
When developing within STVD, programs can be downloaded directly to the
target. If, however, you are building applications separately using a
Makefile or similar, then you are not able to program the application
using STVD. The tools delivered by ST do not appear to offer any easy way
of downloading and running applications built externally. For the time
being the following (slow) development workflow is possible (note that
these settings apply to the STM8S-Discovery):
using STVD. None of the tools delivered by ST appear to be designed to
cater for those who build applications externally, but it is possible using
STVP.
The following development workflow can be used (note that these settings
apply to the STM8S-Discovery):
* Build app using Makefile.
* Open STVP and configure to use Swim ST-Link for CPU STM8105C6.
* Program using STVP.
* Open application .s19 file and program using "Program All Tabs".
Unfortunately STVP does not reset and start the CPU running. The
following can be used to do this:
Unfortunately STVP does not have a command to reset and start the CPU
running, but it can be forced into doing so by reconfiguring the
programmer:
* cd \Program Files\STMicroelectronics\st_toolset\stvd\swim
* ..\gdb7.exe --command=gdbswim_stlink.ini
* emulator-reset-port-mcu usb://usb stm8s105c6
* run
* Select "Configure ST Visual Programmer" from the Configure menu.
Your application should now be programmed and running.
If you wish to run another application, you must stop GDB using Ctrl-C
and request STVP to communicate with the USB debugger again (either by
selecting "Configure ST Visual Programmer" or just closing and reopening
the STVP application). You can then download a new application and repeat
the GDB steps. You must force a USB reconnect within STVP because it loses
communication with the debugger while GDB is in use.
If you wish to program and run another application then you can open and
program it in STVP, then use the Configure menu again to reset the
device and start it running.
This is clearly not a very efficient workflow but it appears that at
this time there are no applications for simple programming and running
of applications to the STM8S-Discovery hardware. Other development
platforms and debugger hardware may have better tools available, this
only applies to the Discovery.
Other programming tools may exist but are not apparent in the toolset
delivered for use the STM8S Discovery platform.
---------------------------------------------------------------------------
@@ -219,14 +214,38 @@ STM8S-DISCOVERY SPECIFICS
There are very minimal board-specific aspects to the STM8 port so it is
trivial to run Atomthreads on other STM8 platforms.
The test application makes use of an LED on one of the GPIO ports of the
Discovery board to indicate whether the automated tests passed or failed.
This is not a core port feature and would not be required in user
applications.
The test applications make use of a LED to indicate test pass/fail status.
This is currently configured to use a bit in GPIOD, which on the Discovery
board maps to the board's only LED. You may change the port and register
bit in tests-main.c to utilise a different pin on other hardware platforms.
You may also completely omit the LED flashing in the test application if
you prefer to use the UART for monitoring test status.
The test applications also make use of the UART to print out pass/fail
indications and other information. For this you should connect a serial
cable to the Discovery board via the external pin connectors. Use of
a UART is not required if you prefer to use the LED or some other method
of notifying test pass/fail status.
To connect a serial cable to the Discovery you will need to connect to
the following pins on the external connectors:
Vcc: CN2 pin 8
GND: CN2 pin 7
UART TX: CN4 pin 10 (connect to RX at the PC end)
UART RX: CN4 pin 9 (connect to TX at the PC end)
Note that the board uses TTL levels so you may need to use a level
converter. External level converters may need to be powered using
a Vdd of 5v, which can be achieved by positioning JP1 on the Discovery.
The STM8 device on the Discovery only offers UART2. If you are using a
different device or wish to use an alternative UART then you must change
the stm8s_conf.h file.
If you are using a CPU other than the STM8S105C6 you should modify
stm8s_conf.h to specify your CPU. You may also wish to enable in that file
any CPU peripherals which you wish to use.
PART in the Makefile (or the preprocessor settings for both Debug and
Release projects if using the STVD project) to specify your CPU. You may
also wish to enable any CPU peripherals which you wish to use in the
stm8s_conf.h file.
---------------------------------------------------------------------------
@@ -239,13 +258,17 @@ port to prove that all core functionality is working on your target.
The full set of tests can be found in the top-level 'tests' folder. Each of
these tests is built as an independent application in the 'build' folder.
Run them individually using the STVP process described above. For example
to run the 'kern1.c' test usr STVP to program it, and GDB to start the
application running.
to run the 'kern1.c' test use STVP to program and run it.
To view the test results, watch the LED on the STM8S-Discovery. This will
flash once per second if the test passed, and once every 1/8 second if the
test failed.
If you wish to use the UART, connect a serial debug cable to your target
platform (defaults to 9600bps 8N1). On starting, the test applications
print out "Go" on the UART. Once the test is complete they will print
out "Pass" or "Fail", along with other information if the test failed.
Most of the tests complete within a few seconds, but some (particularly
the stress tests) can take several seconds, so be patient.
@@ -254,7 +277,8 @@ as possible, and can be used for quick confirmation of core OS
functionality if you ever need to make a change to the kernel or port.
The test application main() is contained in tests-main.c. This initialises
the OS, creates a main thread, and calls out to the test modules.
the OS, creates a main thread, and calls out to the test modules. It also
initialises the UART driver for use by stdout.
---------------------------------------------------------------------------
@@ -263,9 +287,9 @@ WRITING APPLICATIONS
The easiest way to start a new application which utilises the Atomthreads
scheduler is to base your main application startup on tests-main.c. This
initialises the OS and calls out to the test module entry functions. You
can generally simply replace the call to the test modules by a call to your
own application startup code.
initialises the OS, sets up a UART and calls out to the test module entry
functions. You can generally simply replace the call to the test modules by
a call to your own application startup code.
---------------------------------------------------------------------------
@@ -304,10 +328,13 @@ interrupt handlers interrupting while the thread is deep within a kernel
or application call stack. You will need to increase this depending on
what level of stack the application code in question requires.
While 128 bytes has so far been found to be sufficient for the stack
needs of all of the automated test module threads, the main test thread
does typically require more due to the additional variables and
subroutines called.
At this time the maximum stack consumed by the test threads within the
automated test modules is 95 bytes of stack, and the main test thread has
been seen to consume 161 bytes of stack. At this time the timer2 test is
the largest consumer of test thread stack (95 bytes) and the sem4 test
consumes the largest main thread stack (161 bytes). If your applications
have large amounts of local data or call several subroutines then you may
find that you need larger than 128 bytes.
You may monitor the stack usage of your application threads during runtime
by defining the macro ATOM_STACK_CHECKING and calling

View File

@@ -33,8 +33,11 @@
/* Include Atomthreads kernel API */
#include "atom.h"
/* Logger macro for viewing test results (UART not used on this platform) */
#define ATOMLOG
/* Prerequisite include for ATOMLOG() macro (via printf) */
#include <stdio.h>
/* Logger macro for viewing test results */
#define ATOMLOG printf
/*
* String location macro: for platforms which need to place strings in

View File

@@ -83,10 +83,10 @@ String.100.0=STM8S105C6
[Root.Config.0.Settings.3]
String.2.0=Compiling $(InputFile)...
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).ls
String.6.0=2010,2,15,19,3,34
String.6.0=2010,3,6,17,19,51
[Root.Config.0.Settings.4]
String.2.0=Assembling $(InputFile)...
@@ -106,7 +106,7 @@ String.3.0=clnk $(ToolsetLibOpts) -o $(OutputPath)$(TargetSName).sm8 -fakeIntege
String.3.1=cvdwarf $(OutputPath)$(TargetSName).sm8
String.4.0=$(OutputPath)$(TargetFName)
String.5.0=$(OutputPath)$(ProjectSFile).elf $(OutputPath)$(TargetSName).map
String.6.0=2010,2,14,20,36,55
String.6.0=2010,3,9,0,24,9
String.100.0=
String.101.0=crtsi.st7
String.102.0=+seg .const -b 0x8080 -m 0x7f80 -n .const -it
@@ -116,14 +116,14 @@ String.102.3=+seg .bsct -b 0x2 -m 0xfe -n .bsct
String.102.4=+seg .ubsct -a .bsct -n .ubsct
String.102.5=+seg .bit -a .ubsct -n .bit -id
String.102.6=+seg .share -a .bit -n .share -is
String.102.7=+seg .data -b 0x100 -m 0x500 -n .data
String.102.7=+seg .data -b 0x100 -m 0x6c0 -n .data
String.102.8=+seg .bss -a .data -n .bss
String.103.0=Code,Constants[0x8080-0xffff]=.const,.text
String.103.1=Eeprom[0x4000-0x43ff]=.eeprom
String.103.2=Zero Page[0x2-0xff]=.bsct,.ubsct,.bit,.share
String.103.3=Ram[0x100-0x5ff]=.data,.bss
String.103.3=Ram[0x100-0x7bf]=.data,.bss
String.104.0=0x7ff
String.105.0=libis0.sm8;libm0.sm8
String.105.0=libisl0.sm8;libm0.sm8
Int.0=0
Int.1=0
@@ -166,10 +166,10 @@ String.100.0=STM8S105C6
[Root.Config.1.Settings.3]
String.2.0=Compiling $(InputFile)...
String.3.0=cxstm8 +modsl0 -customC-pp -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.3.0=cxstm8 +modsl0 -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).ls
String.6.0=2010,2,15,19,3,34
String.6.0=2010,3,6,17,19,51
[Root.Config.1.Settings.4]
String.2.0=Assembling $(InputFile)...
@@ -188,8 +188,8 @@ String.2.0=Running Linker
String.3.0=clnk $(ToolsetLibOpts) -o $(OutputPath)$(TargetSName).sm8 -fakeInteger -fakeOutFile$(ProjectSFile).elf -fakeRunConv -fakeStartupcrtsi0.sm8 -fakeAutoGen -fakeVectFilestm8_interrupt_vector.c -fakeVectAddr0x8000 -customMapAddress -customCfgFile $(OutputPath)$(TargetSName).lkf
String.3.1=cvdwarf $(OutputPath)$(TargetSName).sm8
String.4.0=$(OutputPath)$(TargetFName)
String.5.0=
String.6.0=2010,2,15,19,3,34
String.5.0=$(OutputPath)$(ProjectSFile).elf
String.6.0=2010,3,9,0,24,9
String.100.0=
String.101.0=crtsi.st7
String.102.0=+seg .const -b 0x8080 -m 0x7f80 -n .const -it
@@ -199,12 +199,12 @@ String.102.3=+seg .bsct -b 0x2 -m 0xfe -n .bsct
String.102.4=+seg .ubsct -a .bsct -n .ubsct
String.102.5=+seg .bit -a .ubsct -n .bit -id
String.102.6=+seg .share -a .bit -n .share -is
String.102.7=+seg .data -b 0x100 -m 0x500 -n .data
String.102.7=+seg .data -b 0x100 -m 0x6c0 -n .data
String.102.8=+seg .bss -a .data -n .bss
String.103.0=Code,Constants[0x8080-0xffff]=.const,.text
String.103.1=Eeprom[0x4000-0x43ff]=.eeprom
String.103.2=Zero Page[0x2-0xff]=.bsct,.ubsct,.bit,.share
String.103.3=Ram[0x100-0x5ff]=.data,.bss
String.103.3=Ram[0x100-0x7bf]=.data,.bss
String.104.0=0x7ff
String.105.0=libis0.sm8;libm0.sm8
Int.0=0
@@ -247,10 +247,10 @@ Int.1=0
[Root.Kernel.Config.0.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).ls
String.6.0=2010,2,15,19,3,34
String.6.0=2010,3,6,17,19,51
[Root.Kernel.Config.0.Settings.2]
String.2.0=Assembling $(InputFile)...
@@ -271,10 +271,10 @@ Int.1=0
[Root.Kernel.Config.1.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=cxstm8 +modsl0 -customC-pp -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.3.0=cxstm8 +modsl0 -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).ls
String.6.0=2010,2,15,19,3,34
String.6.0=2010,3,6,17,19,51
[Root.Kernel.Config.1.Settings.2]
String.2.0=Assembling $(InputFile)...
@@ -339,7 +339,7 @@ PathName=..\..\kernel\atomtimer.h
[Root.Peripherals]
ElemType=Folder
PathName=Peripherals
Child=Root.Peripherals.stm8s-periphs\stm8s_gpio.c
Child=Root.Peripherals.stm8s-periphs\stm8s_clk.c
Next=Root.Port
Config.0=Root.Peripherals.Config.0
Config.1=Root.Peripherals.Config.1
@@ -364,10 +364,10 @@ Int.1=0
[Root.Peripherals.Config.0.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).ls
String.6.0=2010,2,15,19,3,34
String.6.0=2010,3,6,17,19,51
[Root.Peripherals.Config.0.Settings.2]
String.2.0=Assembling $(InputFile)...
@@ -391,10 +391,10 @@ Int.1=0
[Root.Peripherals.Config.1.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=cxstm8 +modsl0 -customC-pp -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.3.0=cxstm8 +modsl0 -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).ls
String.6.0=2010,2,15,19,3,34
String.6.0=2010,3,6,17,19,51
[Root.Peripherals.Config.1.Settings.2]
String.2.0=Assembling $(InputFile)...
@@ -410,6 +410,21 @@ String.4.0=
String.5.0=
String.6.0=2010,2,9,1,12,48
[Root.Peripherals.stm8s-periphs\stm8s_clk.c]
ElemType=File
PathName=stm8s-periphs\stm8s_clk.c
Next=Root.Peripherals.stm8s-periphs\stm8s_uart2.h
[Root.Peripherals.stm8s-periphs\stm8s_uart2.h]
ElemType=File
PathName=stm8s-periphs\stm8s_uart2.h
Next=Root.Peripherals.stm8s-periphs\stm8s_uart2.c
[Root.Peripherals.stm8s-periphs\stm8s_uart2.c]
ElemType=File
PathName=stm8s-periphs\stm8s_uart2.c
Next=Root.Peripherals.stm8s-periphs\stm8s_gpio.c
[Root.Peripherals.stm8s-periphs\stm8s_gpio.c]
ElemType=File
PathName=stm8s-periphs\stm8s_gpio.c
@@ -476,10 +491,10 @@ Int.1=0
[Root.Port.Config.0.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).ls
String.6.0=2010,2,15,19,3,34
String.6.0=2010,3,6,17,19,51
[Root.Port.Config.0.Settings.2]
String.2.0=Assembling $(InputFile)...
@@ -503,10 +518,10 @@ Int.1=0
[Root.Port.Config.1.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=cxstm8 +modsl0 -customC-pp -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.3.0=cxstm8 +modsl0 -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).ls
String.6.0=2010,2,15,19,3,34
String.6.0=2010,3,6,17,19,51
[Root.Port.Config.1.Settings.2]
String.2.0=Assembling $(InputFile)...
@@ -525,6 +540,16 @@ String.6.0=2010,2,9,1,12,48
[Root.Port...\..\tests\sem1.c]
ElemType=File
PathName=..\..\tests\sem1.c
Next=Root.Port.uart.h
[Root.Port.uart.h]
ElemType=File
PathName=uart.h
Next=Root.Port.uart.c
[Root.Port.uart.c]
ElemType=File
PathName=uart.c
Next=Root.Port.atomport-tests.h
[Root.Port.atomport-tests.h]

View File

@@ -11,8 +11,9 @@
+seg .ubsct -a .bsct -n .ubsct
+seg .bit -a .ubsct -n .bit -id
+seg .share -a .bit -n .share -is
# Segment Ram:
+seg .data -b 0x100 -m 0x500 -n .data
# Segment Ram (allow up to RAMTOP-64 to be used for data
# sections, leaving 64 bytes for the startup stack):
+seg .data -b 0x100 -m 0x6c0 -n .data
+seg .bss -a .data -n .bss
#<END SEGMENT_CONF>
@@ -30,10 +31,13 @@ build\atommutex.o
build\atomqueue.o
build\atomsem.o
build\atomtimer.o
build\stm8s_clk.o
build\stm8s_gpio.o
build\stm8s_tim1.o
build\stm8s_uart2.o
build\tests-main.o
build\atomport.o
build\uart.o
build\atomport-asm.o
# Caller passes in test application object name as param1
@1
@@ -58,6 +62,6 @@ build/stm8_interrupt_vector.o
+def __endzp=@.ubsct # end of uninitialized zpage
+def __memory=@.bss # end of bss segment
+def __startmem=@.bss
+def __endmem=0x5ff
+def __endmem=0x7bf
+def __stack=0x7ff
#<END DEFINED_VARIABLES>

View File

@@ -0,0 +1,793 @@
/**
******************************************************************************
* @file stm8s_clk.c
* @brief This file contains all the functions for the CLK peripheral.
* @author STMicroelectronics - MCD Application Team
* @version V1.1.1
* @date 06/05/2009
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
* @image html logo.bmp
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm8s_clk.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private Constants ---------------------------------------------------------*/
/**
* @addtogroup CLK_Private_Constants
* @{
*/
uc8 HSIDivFactor[4] = {1, 2, 4, 8}; /*!< Holds the different HSI Dividor factors */
uc8 CLKPrescTable[8] = {1, 2, 4, 8, 10, 16, 20, 40}; /*!< Holds the different CLK prescaler values */
/**
* @}
*/
/* Public functions ----------------------------------------------------------*/
/**
* @addtogroup CLK_Public_Functions
* @{
*/
/**
* @brief Deinitializes the CLK peripheral registers to their default reset
* values.
* @par Parameters:
* None
* @retval None
* @par Warning:
* Resetting the CCOR register: \n
* When the CCOEN bit is set, the reset of the CCOR register require
* two consecutive write instructions in order to reset first the CCOEN bit
* and the second one is to reset the CCOSEL bits.
*/
void CLK_DeInit(void)
{
CLK->ICKR = CLK_ICKR_RESET_VALUE;
CLK->ECKR = CLK_ECKR_RESET_VALUE;
CLK->SWR = CLK_SWR_RESET_VALUE;
CLK->SWCR = CLK_SWCR_RESET_VALUE;
CLK->CKDIVR = CLK_CKDIVR_RESET_VALUE;
CLK->PCKENR1 = CLK_PCKENR1_RESET_VALUE;
CLK->PCKENR2 = CLK_PCKENR2_RESET_VALUE;
CLK->CSSR = CLK_CSSR_RESET_VALUE;
CLK->CCOR = CLK_CCOR_RESET_VALUE;
while (CLK->CCOR & CLK_CCOR_CCOEN)
{}
CLK->CCOR = CLK_CCOR_RESET_VALUE;
CLK->CANCCR = CLK_CANCCR_RESET_VALUE;
CLK->HSITRIMR = CLK_HSITRIMR_RESET_VALUE;
CLK->SWIMCCR = CLK_SWIMCCR_RESET_VALUE;
}
/**
* @brief Configures the High Speed Internal oscillator (HSI).
* @par Full description:
* If CLK_FastHaltWakeup is enabled, HSI oscillator is automatically
* switched-on (HSIEN=1) and selected as next clock master
* (CKM=SWI=HSI) when resuming from HALT/ActiveHalt modes.\n
* @param[in] NewState this parameter is the Wake-up Mode state.
* @retval None
*/
void CLK_FastHaltWakeUpCmd(FunctionalState NewState)
{
/* check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Set FHWU bit (HSI oscillator is automatically switched-on) */
CLK->ICKR |= CLK_ICKR_FHWU;
}
else /* FastHaltWakeup = DISABLE */
{
/* Reset FHWU bit */
CLK->ICKR &= (u8)(~CLK_ICKR_FHWU);
}
}
/**
* @brief Enable or Disable the External High Speed oscillator (HSE).
* @param[in] NewState new state of HSEEN, value accepted ENABLE, DISABLE.
* @retval None
*/
void CLK_HSECmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Set HSEEN bit */
CLK->ECKR |= CLK_ECKR_HSEEN;
}
else
{
/* Reset HSEEN bit */
CLK->ECKR &= (u8)(~CLK_ECKR_HSEEN);
}
}
/**
* @brief Enables or disables the Internal High Speed oscillator (HSI).
* @param[in] NewState new state of HSIEN, value accepted ENABLE, DISABLE.
* @retval None
*/
void CLK_HSICmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Set HSIEN bit */
CLK->ICKR |= CLK_ICKR_HSIEN;
}
else
{
/* Reset HSIEN bit */
CLK->ICKR &= (u8)(~CLK_ICKR_HSIEN);
}
}
/**
* @brief Enables or disables the Internal Low Speed oscillator (LSI).
* @param[in] NewState new state of LSIEN, value accepted ENABLE, DISABLE.
* @retval None
*/
void CLK_LSICmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Set LSIEN bit */
CLK->ICKR |= CLK_ICKR_LSIEN;
}
else
{
/* Reset LSIEN bit */
CLK->ICKR &= (u8)(~CLK_ICKR_LSIEN);
}
}
/**
* @brief Enables or disablle the Configurable Clock Output (CCO).
* @param[in] NewState : New state of CCEN bit (CCO register).
* This parameter can be any of the @ref FunctionalState enumeration.
* @retval None
*/
void CLK_CCOCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Set CCOEN bit */
CLK->CCOR |= CLK_CCOR_CCOEN;
}
else
{
/* Reset CCOEN bit */
CLK->CCOR &= (u8)(~CLK_CCOR_CCOEN);
}
}
/**
* @brief Starts or Stops manually the clock switch execution.
* @par Full description:
* NewState parameter set the SWEN.
* @param[in] NewState new state of SWEN, value accepted ENABLE, DISABLE.
* @retval None
*/
void CLK_ClockSwitchCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE )
{
/* Enable the Clock Switch */
CLK->SWCR |= CLK_SWCR_SWEN;
}
else
{
/* Disable the Clock Switch */
CLK->SWCR &= (u8)(~CLK_SWCR_SWEN);
}
}
/**
* @brief Configures the slow active halt wake up
* @param[in] NewState: specifies the Slow Active Halt wake up state.
* can be set of the following values:
* - DISABLE: Slow Active Halt mode disabled;
* - ENABLE: Slow Active Halt mode enabled.
* @retval None
*/
void CLK_SlowActiveHaltWakeUpCmd(FunctionalState NewState)
{
/* check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Set S_ACTHALT bit */
CLK->ICKR |= CLK_ICKR_SWUAH;
}
else
{
/* Reset S_ACTHALT bit */
CLK->ICKR &= (u8)(~CLK_ICKR_SWUAH);
}
}
/**
* @brief Enables or disables the specified peripheral CLK.
* @param[in] CLK_Peripheral : This parameter specifies the peripheral clock to gate.
* This parameter can be any of the @ref CLK_Peripheral_TypeDef enumeration.
* @param[in] NewState : New state of specified peripheral clock.
* This parameter can be any of the @ref FunctionalState enumeration.
* @retval None
*/
void CLK_PeripheralClockConfig(CLK_Peripheral_TypeDef CLK_Peripheral, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
assert_param(IS_CLK_PERIPHERAL_OK(CLK_Peripheral));
if (((u8)CLK_Peripheral & (u8)0x10) == 0x00)
{
if (NewState != DISABLE)
{
/* Enable the peripheral Clock */
CLK->PCKENR1 |= (u8)((u8)1 << ((u8)CLK_Peripheral & (u8)0x0F));
}
else
{
/* Disable the peripheral Clock */
CLK->PCKENR1 &= (u8)(~(u8)(((u8)1 << ((u8)CLK_Peripheral & (u8)0x0F))));
}
}
else
{
if (NewState != DISABLE)
{
/* Enable the peripheral Clock */
CLK->PCKENR2 |= (u8)((u8)1 << ((u8)CLK_Peripheral & (u8)0x0F));
}
else
{
/* Disable the peripheral Clock */
CLK->PCKENR2 &= (u8)(~(u8)(((u8)1 << ((u8)CLK_Peripheral & (u8)0x0F))));
}
}
}
/**
* @brief configures the Switch from one clock to another
* @param[in] CLK_SwitchMode select the clock switch mode.
* It can be set of the values of @ref CLK_SwitchMode_TypeDef
* @param[in] CLK_NewClock choice of the future clock.
* It can be set of the values of @ref CLK_Source_TypeDef
* @param[in] NewState Enable or Disable the Clock Switch interrupt.
* @param[in] CLK_CurrentClockState current clock to switch OFF or to keep ON.
* It can be set of the values of @ref CLK_CurrentClockState_TypeDef
* @retval ErrorStatus this shows the clock switch status (ERROR/SUCCESS).
*/
ErrorStatus CLK_ClockSwitchConfig(CLK_SwitchMode_TypeDef CLK_SwitchMode, CLK_Source_TypeDef CLK_NewClock, FunctionalState ITState, CLK_CurrentClockState_TypeDef CLK_CurrentClockState)
{
CLK_Source_TypeDef clock_master;
u16 DownCounter = CLK_TIMEOUT;
ErrorStatus Swif = ERROR;
/* Check the parameters */
assert_param(IS_CLK_SOURCE_OK(CLK_NewClock));
assert_param(IS_CLK_SWITCHMODE_OK(CLK_SwitchMode));
assert_param(IS_FUNCTIONALSTATE_OK(ITState));
assert_param(IS_CLK_CURRENTCLOCKSTATE_OK(CLK_CurrentClockState));
/* Current clock master saving */
clock_master = (CLK_Source_TypeDef)CLK->CMSR;
/* Automatic switch mode management */
if (CLK_SwitchMode == CLK_SWITCHMODE_AUTO)
{
/* Enables Clock switch */
CLK->SWCR |= CLK_SWCR_SWEN;
/* Enables or Disables Switch interrupt */
if (ITState != DISABLE)
{
CLK->SWCR |= CLK_SWCR_SWIEN;
}
else
{
CLK->SWCR &= (u8)(~CLK_SWCR_SWIEN);
}
/* Selection of the target clock source */
CLK->SWR = (u8)CLK_NewClock;
while (((CLK->SWCR & CLK_SWCR_SWBSY) && (DownCounter != 0)))
{
DownCounter--;
}
if (DownCounter != 0)
{
Swif = SUCCESS;
}
else
{
Swif = ERROR;
}
}
else /* CLK_SwitchMode == CLK_SWITCHMODE_MANUAL */
{
/* Enables or Disables Switch interrupt if required */
if (ITState != DISABLE)
{
CLK->SWCR |= CLK_SWCR_SWIEN;
}
else
{
CLK->SWCR &= (u8)(~CLK_SWCR_SWIEN);
}
/* Selection of the target clock source */
CLK->SWR = (u8)CLK_NewClock;
/* In manual mode, there is no risk to be stucked in a loop, value returned
is then always SUCCESS */
Swif = SUCCESS;
}
/* Switch OFF current clock if required */
if ((CLK_CurrentClockState == CLK_CURRENTCLOCKSTATE_DISABLE) && ( clock_master == CLK_SOURCE_HSI))
{
CLK->ICKR &= (u8)(~CLK_ICKR_HSIEN);
}
else if ((CLK_CurrentClockState == CLK_CURRENTCLOCKSTATE_DISABLE) && ( clock_master == CLK_SOURCE_LSI))
{
CLK->ICKR &= (u8)(~CLK_ICKR_LSIEN);
}
else if ((CLK_CurrentClockState == CLK_CURRENTCLOCKSTATE_DISABLE) && ( clock_master == CLK_SOURCE_HSE))
{
CLK->ECKR &= (u8)(~CLK_ECKR_HSEEN);
}
return(Swif);
}
/**
* @brief Configures the HSI clock dividers.
* @param[in] HSIPrescaler : Specifies the HSI clock divider to apply.
* This parameter can be any of the @ref CLK_Prescaler_TypeDef enumeration.
* @retval None
*/
void CLK_HSIPrescalerConfig(CLK_Prescaler_TypeDef HSIPrescaler)
{
/* check the parameters */
assert_param(IS_CLK_HSIPRESCALER_OK(HSIPrescaler));
/* Clear High speed internal clock prescaler */
CLK->CKDIVR &= (u8)(~CLK_CKDIVR_HSIDIV);
/* Set High speed internal clock prescaler */
CLK->CKDIVR |= (u8)HSIPrescaler;
}
/**
* @brief Output the selected clock on a dedicated I/O pin.
* @param[in] CLK_CCO : Specifies the clock source.
* This parameter can be any of the @ref CLK_Output_TypeDef enumeration.
* @retval None
* @par Required preconditions:
* The dedicated I/O pin must be set at 1 in the corresponding Px_CR1 register \n
* to be set as input with pull-up or push-pull output.
*/
void CLK_CCOConfig(CLK_Output_TypeDef CLK_CCO)
{
/* check the parameters */
assert_param(IS_CLK_OUTPUT_OK(CLK_CCO));
/* Clears of the CCO type bits part */
CLK->CCOR &= (u8)(~CLK_CCOR_CCOSEL);
/* Selects the source provided on cco_ck output */
CLK->CCOR |= (u8)CLK_CCO;
/* Enable the clock output */
CLK->CCOR |= CLK_CCOR_CCOEN;
}
/**
* @brief Enables or disables the specified CLK interrupts.
* @param[in] CLK_IT This parameter specifies the interrupt sources.
* It can be one of the values of @ref CLK_IT_TypeDef.
* @param[in] NewState New state of the Interrupt.
* Value accepted ENABLE, DISABLE.
* @retval None
*/
void CLK_ITConfig(CLK_IT_TypeDef CLK_IT, FunctionalState NewState)
{
/* check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
assert_param(IS_CLK_IT_OK(CLK_IT));
if (NewState != DISABLE)
{
switch (CLK_IT)
{
case CLK_IT_SWIF: /* Enable the clock switch interrupt */
CLK->SWCR |= CLK_SWCR_SWIEN;
break;
case CLK_IT_CSSD: /* Enable the clock security system detection interrupt */
CLK->CSSR |= CLK_CSSR_CSSDIE;
break;
default:
break;
}
}
else /*(NewState == DISABLE)*/
{
switch (CLK_IT)
{
case CLK_IT_SWIF: /* Disable the clock switch interrupt */
CLK->SWCR &= (u8)(~CLK_SWCR_SWIEN);
break;
case CLK_IT_CSSD: /* Disable the clock security system detection interrupt */
CLK->CSSR &= (u8)(~CLK_CSSR_CSSDIE);
break;
default:
break;
}
}
}
/**
* @brief Configures the HSI and CPU clock dividers.
* @param[in] ClockPrescaler Specifies the HSI or CPU clock divider to apply.
* @retval None
*/
void CLK_SYSCLKConfig(CLK_Prescaler_TypeDef ClockPrescaler)
{
/* check the parameters */
assert_param(IS_CLK_PRESCALER_OK(ClockPrescaler));
if (((u8)ClockPrescaler & (u8)0x80) == 0x00) /* Bit7 = 0 means HSI divider */
{
CLK->CKDIVR &= (u8)(~CLK_CKDIVR_HSIDIV);
CLK->CKDIVR |= (u8)((u8)ClockPrescaler & (u8)CLK_CKDIVR_HSIDIV);
}
else /* Bit7 = 1 means CPU divider */
{
CLK->CKDIVR &= (u8)(~CLK_CKDIVR_CPUDIV);
CLK->CKDIVR |= (u8)((u8)ClockPrescaler & (u8)CLK_CKDIVR_CPUDIV);
}
}
/**
* @brief Configures the SWIM clock frequency on the fly.
* @param[in] CLK_SWIMDivider Specifies the SWIM clock divider to apply.
* can be one of the value of @ref CLK_SWIMDivider_TypeDef
* @retval None
*/
void CLK_SWIMConfig(CLK_SWIMDivider_TypeDef CLK_SWIMDivider)
{
/* check the parameters */
assert_param(IS_CLK_SWIMDIVIDER_OK(CLK_SWIMDivider));
if (CLK_SWIMDivider != CLK_SWIMDIVIDER_2)
{
/* SWIM clock is not divided by 2 */
CLK->SWIMCCR |= CLK_SWIMCCR_SWIMDIV;
}
else /* CLK_SWIMDivider == CLK_SWIMDIVIDER_2 */
{
/* SWIM clock is divided by 2 */
CLK->SWIMCCR &= (u8)(~CLK_SWIMCCR_SWIMDIV);
}
}
/**
* @brief Configure the divider for the external CAN clock.
* @param[in] CLK_CANDivider Specifies the CAN clock divider to apply.
* can be one of the value of @ref CLK_CANDivider_TypeDef
* @retval None
*/
void CLK_CANConfig(CLK_CANDivider_TypeDef CLK_CANDivider)
{
/* check the parameters */
assert_param(IS_CLK_CANDIVIDER_OK(CLK_CANDivider));
/* Clear the CANDIV bits */
CLK->CANCCR &= (u8)(~CLK_CANCCR_CANDIV);
/* Select divider */
CLK->CANCCR |= (u8)CLK_CANDivider;
}
/**
* @brief Enables the Clock Security System.
* @par Full description:
* once CSS is enabled it cannot be disabled until the next reset.
* @par Parameters:
* None
* @retval None
*/
void CLK_ClockSecuritySystemEnable(void)
{
/* Set CSSEN bit */
CLK->CSSR |= CLK_CSSR_CSSEN;
}
/**
* @brief Returns the clock source used as system clock.
* @par Parameters:
* None
* @retval Clock source used.
* can be one of the values of @ref CLK_Source_TypeDef
*/
CLK_Source_TypeDef CLK_GetSYSCLKSource(void)
{
return((CLK_Source_TypeDef)CLK->CMSR);
}
/**
* @brief This function returns the frequencies of different on chip clocks.
* @par Parameters:
* None
* @retval the master clock frequency
*/
u32 CLK_GetClockFreq(void)
{
u32 clockfrequency = 0;
CLK_Source_TypeDef clocksource = CLK_SOURCE_HSI;
u8 tmp = 0, presc = 0;
/* Get CLK source. */
clocksource = (CLK_Source_TypeDef)CLK->CMSR;
if (clocksource == CLK_SOURCE_HSI)
{
tmp = (u8)(CLK->CKDIVR & CLK_CKDIVR_HSIDIV);
tmp = (u8)(tmp >> 3);
presc = HSIDivFactor[tmp];
clockfrequency = HSI_VALUE / presc;
}
else if ( clocksource == CLK_SOURCE_LSI)
{
clockfrequency = LSI_VALUE;
}
else
{
clockfrequency = HSE_VALUE;
}
return((u32)clockfrequency);
}
/**
* @brief Adjusts the Internal High Speed oscillator (HSI) calibration value.
* @par Full description:
* @param[in] CLK_HSICalibrationValue calibration trimming value.
* can be one of the values of @ref CLK_HSITrimValue_TypeDef
* @retval None
*/
void CLK_AdjustHSICalibrationValue(CLK_HSITrimValue_TypeDef CLK_HSICalibrationValue)
{
/* check the parameters */
assert_param(IS_CLK_HSITRIMVALUE_OK(CLK_HSICalibrationValue));
/* Store the new value */
CLK->HSITRIMR = (u8)((CLK->HSITRIMR & (u8)(~CLK_HSITRIMR_HSITRIM))|((u8)CLK_HSICalibrationValue));
}
/**
* @brief Reset the SWBSY flag (SWICR Reister)
* @par Full description:
* This function reset SWBSY flag in order to reset clock switch operations (target
* oscillator is broken, stabilization is longing too much, etc.). If at the same time \n
* software attempts to set SWEN and clear SWBSY, SWBSY action takes precedence.
* @par Parameters:
* None
* @retval None
*/
void CLK_SYSCLKEmergencyClear(void)
{
CLK->SWCR &= (u8)(~CLK_SWCR_SWBSY);
}
/**
* @brief Checks whether the specified CLK flag is set or not.
* @par Full description:
* @param[in] CLK_FLAG Flag to check.
* can be one of the values of @ref CLK_Flag_TypeDef
* @retval FlagStatus, status of the checked flag
*/
FlagStatus CLK_GetFlagStatus(CLK_Flag_TypeDef CLK_FLAG)
{
u16 statusreg = 0;
u8 tmpreg = 0;
FlagStatus bitstatus = RESET;
/* check the parameters */
assert_param(IS_CLK_FLAG_OK(CLK_FLAG));
/* Get the CLK register index */
statusreg = (u16)((u16)CLK_FLAG & (u16)0xFF00);
if (statusreg == 0x0100) /* The flag to check is in ICKRregister */
{
tmpreg = CLK->ICKR;
}
else if (statusreg == 0x0200) /* The flag to check is in ECKRregister */
{
tmpreg = CLK->ECKR;
}
else if (statusreg == 0x0300) /* The flag to check is in SWIC register */
{
tmpreg = CLK->SWCR;
}
else if (statusreg == 0x0400) /* The flag to check is in CSS register */
{
tmpreg = CLK->CSSR;
}
else /* The flag to check is in CCO register */
{
tmpreg = CLK->CCOR;
}
if ((tmpreg & (u8)CLK_FLAG) != (u8)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
/* Return the flag status */
return((FlagStatus)bitstatus);
}
/**
* @brief Checks whether the specified CLK interrupt has is enabled or not.
* @param[in] CLK_IT specifies the CLK interrupt.
* can be one of the values of @ref CLK_IT_TypeDef
* @retval ITStatus, new state of CLK_IT (SET or RESET).
*/
ITStatus CLK_GetITStatus(CLK_IT_TypeDef CLK_IT)
{
ITStatus bitstatus = RESET;
/* check the parameters */
assert_param(IS_CLK_IT_OK(CLK_IT));
if (CLK_IT == CLK_IT_SWIF)
{
/* Check the status of the clock switch interrupt */
if ((CLK->SWCR & (u8)CLK_IT) == (u8)0x0C)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
else /* CLK_IT == CLK_IT_CSSDIE */
{
/* Check the status of the security system detection interrupt */
if ((CLK->CSSR & (u8)CLK_IT) == (u8)0x0C)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
/* Return the CLK_IT status */
return bitstatus;
}
/**
* @brief Clears the CLKs interrupt pending bits.
* @param[in] CLK_IT specifies the interrupt pending bits.
* can be one of the values of @ref CLK_IT_TypeDef
* @retval None
*/
void CLK_ClearITPendingBit(CLK_IT_TypeDef CLK_IT)
{
/* check the parameters */
assert_param(IS_CLK_IT_OK(CLK_IT));
if (CLK_IT == (u8)CLK_IT_CSSD)
{
/* Clear the status of the security system detection interrupt */
CLK->CSSR &= (u8)(~CLK_CSSR_CSSD);
}
else /* CLK_PendingBit == (u8)CLK_IT_SWIF */
{
/* Clear the status of the clock switch interrupt */
CLK->SWCR &= (u8)(~CLK_SWCR_SWIF);
}
}
/**
* @}
*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,898 @@
/**
********************************************************************************
* @file stm8s_uart2.c
* @brief This file contains all the functions for the UART2 peripheral.
* @author STMicroelectronics - MCD Application Team
* @version V1.1.1
* @date 06/05/2009
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
* @image html logo.bmp
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm8s_uart2.h"
#include "stm8s_clk.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/
/** @}
* @addtogroup UART2_Public_Functions
* @{
*/
/**
* @brief Deinitializes the UART2 peripheral.
* @par Full description:
* Set the UART2 peripheral registers to their default reset values.
* @retval None
*/
void UART2_DeInit(void)
{
u8 dummy = 0;
/*< Clear the Idle Line Detected bit in the status rerister by a read
to the UART2_SR register followed by a Read to the UART2_DR register */
dummy = UART2->SR;
dummy = UART2->DR;
UART2->BRR2 = UART2_BRR2_RESET_VALUE; /*< Set UART2_BRR2 to reset value 0x00 */
UART2->BRR1 = UART2_BRR1_RESET_VALUE; /*< Set UART2_BRR1 to reset value 0x00 */
UART2->CR1 = UART2_CR1_RESET_VALUE; /*< Set UART2_CR1 to reset value 0x00 */
UART2->CR2 = UART2_CR2_RESET_VALUE; /*< Set UART2_CR2 to reset value 0x00 */
UART2->CR3 = UART2_CR3_RESET_VALUE; /*< Set UART2_CR3 to reset value 0x00 */
UART2->CR4 = UART2_CR4_RESET_VALUE; /*< Set UART2_CR4 to reset value 0x00 */
UART2->CR5 = UART2_CR5_RESET_VALUE; /*< Set UART2_CR5 to reset value 0x00 */
UART2->CR6 = UART2_CR6_RESET_VALUE; /*< Set UART2_CR6 to reset value 0x00 */
}
/**
* @brief Initializes the UART2 according to the specified parameters.
* @param[in] BaudRate: The baudrate.
* @param[in] WordLength : This parameter can be any of the @ref UART2_WordLength_TypeDef enumeration.
* @param[in] StopBits: This parameter can be any of the @ref UART2_StopBits_TypeDef enumeration.
* @param[in] Parity: This parameter can be any of the @ref UART2_Parity_TypeDef enumeration.
* @param[in] SyncMode: This parameter can be any of the @ref UART2_SyncMode_TypeDef values.
* @param[in] Mode: This parameter can be any of the @ref UART2_Mode_TypeDef values
* @retval None
*/
void UART2_Init(u32 BaudRate, UART2_WordLength_TypeDef WordLength, UART2_StopBits_TypeDef StopBits, UART2_Parity_TypeDef Parity, UART2_SyncMode_TypeDef SyncMode, UART2_Mode_TypeDef Mode)
{
u8 BRR2_1, BRR2_2 = 0;
u32 BaudRate_Mantissa, BaudRate_Mantissa100 = 0;
/* assert_param: BaudRate value should be <= 625000 bps */
assert_param(IS_UART2_BAUDRATE_OK(BaudRate));
assert_param(IS_UART2_WORDLENGTH_OK(WordLength));
assert_param(IS_UART2_STOPBITS_OK(StopBits));
assert_param(IS_UART2_PARITY_OK(Parity));
/* assert_param: UART2_Mode value should exclude values such as UART2_ModeTx_Enable|UART2_ModeTx_Disable */
assert_param(IS_UART2_MODE_OK((u8)Mode));
/* assert_param: UART2_SyncMode value should exclude values such as
UART2_CLOCK_ENABLE|UART2_CLOCK_DISABLE */
assert_param(IS_UART2_SYNCMODE_OK((u8)SyncMode));
UART2->CR1 &= (u8)(~UART2_CR1_M); /**< Clear the word length bit */
UART2->CR1 |= (u8)WordLength; /**< Set the word length bit according to UART2_WordLength value */
UART2->CR3 &= (u8)(~UART2_CR3_STOP); /**< Clear the STOP bits */
UART2->CR3 |= (u8)StopBits; /**< Set the STOP bits number according to UART2_StopBits value */
UART2->CR1 &= (u8)(~(UART2_CR1_PCEN | UART2_CR1_PS )); /**< Clear the Parity Control bit */
UART2->CR1 |= (u8)Parity; /**< Set the Parity Control bit to UART2_Parity value */
UART2->BRR1 &= (u8)(~UART2_BRR1_DIVM); /**< Clear the LSB mantissa of UARTDIV */
UART2->BRR2 &= (u8)(~UART2_BRR2_DIVM); /**< Clear the MSB mantissa of UARTDIV */
UART2->BRR2 &= (u8)(~UART2_BRR2_DIVF); /**< Clear the Fraction bits of UARTDIV */
/**< Set the UART2 BaudRates in BRR1 and BRR2 registers according to UART2_BaudRate value */
BaudRate_Mantissa = ((u32)CLK_GetClockFreq() / (BaudRate << 4));
BaudRate_Mantissa100 = (((u32)CLK_GetClockFreq() * 100) / (BaudRate << 4));
/**< The fraction and MSB mantissa should be loaded in one step in the BRR2 register*/
BRR2_1 = (u8)((u8)(((BaudRate_Mantissa100 - (BaudRate_Mantissa * 100))
<< 4) / 100) & (u8)0x0F); /**< Set the fraction of UARTDIV */
BRR2_2 = (u8)((BaudRate_Mantissa >> 4) & (u8)0xF0);
UART2->BRR2 = (u8)(BRR2_1 | BRR2_2);
UART2->BRR1 = (u8)BaudRate_Mantissa; /**< Set the LSB mantissa of UARTDIV */
UART2->CR2 &= (u8)~(UART2_CR2_TEN | UART2_CR2_REN); /**< Disable the Transmitter and Receiver before seting the LBCL, CPOL and CPHA bits */
UART2->CR3 &= (u8)~(UART2_CR3_CPOL | UART2_CR3_CPHA | UART2_CR3_LBCL); /**< Clear the Clock Polarity, lock Phase, Last Bit Clock pulse */
UART2->CR3 |= (u8)((u8)SyncMode & (u8)(UART2_CR3_CPOL | UART2_CR3_CPHA | UART2_CR3_LBCL)); /**< Set the Clock Polarity, lock Phase, Last Bit Clock pulse */
if ((u8)Mode & (u8)UART2_MODE_TX_ENABLE)
{
UART2->CR2 |= (u8)UART2_CR2_TEN; /**< Set the Transmitter Enable bit */
}
else
{
UART2->CR2 &= (u8)(~UART2_CR2_TEN); /**< Clear the Transmitter Disable bit */
}
if ((u8)Mode & (u8)UART2_MODE_RX_ENABLE)
{
UART2->CR2 |= (u8)UART2_CR2_REN; /**< Set the Receiver Enable bit */
}
else
{
UART2->CR2 &= (u8)(~UART2_CR2_REN); /**< Clear the Receiver Disable bit */
}
/**< Set the Clock Enable bit, lock Polarity, lock Phase and Last Bit Clock pulse bits according to UART2_Mode value */
if ((u8)SyncMode&(u8)UART2_SYNCMODE_CLOCK_DISABLE)
{
UART2->CR3 &= (u8)(~UART2_CR3_CKEN); /**< Clear the Clock Enable bit */
/**< configure in Push Pull or Open Drain mode the Tx I/O line by setting the correct I/O Port register according the product package and line configuration*/
}
else
{
UART2->CR3 |= (u8)((u8)SyncMode & UART2_CR3_CKEN);
}
}
/**
* @brief Enable the UART2 peripheral.
* @par Full description:
* Enable the UART2 peripheral.
* @param[in] NewState new state of the UART2 Communication.
* This parameter can be:
* - ENABLE
* - DISABLE
* @retval None
*/
void UART2_Cmd(FunctionalState NewState)
{
if (NewState != DISABLE)
{
UART2->CR1 &= (u8)(~UART2_CR1_UARTD); /**< UART2 Enable */
}
else
{
UART2->CR1 |= UART2_CR1_UARTD; /**< UART2 Disable (for low power consumption) */
}
}
/**
* @brief Enables or disables the specified UART2 interrupts.
* @par Full description:
* Enables or disables the specified UART2 interrupts.
* @param[in] UART2_IT specifies the UART2 interrupt sources to be enabled or disabled.
* This parameter can be one of the following values:
* - UART2_IT_LBDF: LIN Break detection interrupt
* - UART2_IT_LHDF: LIN Break detection interrupt
* - UART2_IT_TXE: Tansmit Data Register empty interrupt
* - UART2_IT_TC: Transmission complete interrupt
* - UART2_IT_RXNE_OR: Receive Data register not empty/Over run error interrupt
* - UART2_IT_IDLE: Idle line detection interrupt
* - UART2_IT_PE: Parity Error interrupt
* @param[in] NewState new state of the specified UART2 interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void UART2_ITConfig(UART2_IT_TypeDef UART2_IT, FunctionalState NewState)
{
u8 uartreg, itpos = 0x00;
assert_param(IS_UART2_CONFIG_IT_OK(UART2_IT));
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
/* Get the UART2 register index */
uartreg = (u8)(UART2_IT >> 0x08);
/* Get the UART2 IT index */
itpos = (u8)((u8)1 << (u8)((u8)UART2_IT & (u8)0x0F));
if (NewState != DISABLE)
{
/**< Enable the Interrupt bits according to UART2_IT mask */
if (uartreg == 0x01)
{
UART2->CR1 |= itpos;
}
else if (uartreg == 0x02)
{
UART2->CR2 |= itpos;
}
else if (uartreg == 0x03)
{
UART2->CR4 |= itpos;
}
else
{
UART2->CR6 |= itpos;
}
}
else
{
/**< Disable the interrupt bits according to UART2_IT mask */
if (uartreg == 0x01)
{
UART2->CR1 &= (u8)(~itpos);
}
else if (uartreg == 0x02)
{
UART2->CR2 &= (u8)(~itpos);
}
else if (uartreg == 0x03)
{
UART2->CR4 &= (u8)(~itpos);
}
else
{
UART2->CR6 &= (u8)(~itpos);
}
}
}
/**
* @brief Configures the UART2s IrDA interface.
* @par Full description:
* Configures the UART2s IrDA interface.
* @par This function is valid only for UART2.
* @param[in] UART2_IrDAMode specifies the IrDA mode.
* This parameter can be any of the @ref UART2_IrDAMode_TypeDef values.
* @retval None
*/
void UART2_IrDAConfig(UART2_IrDAMode_TypeDef UART2_IrDAMode)
{
assert_param(IS_UART2_IRDAMODE_OK(UART2_IrDAMode));
if (UART2_IrDAMode != UART2_IRDAMODE_NORMAL)
{
UART2->CR5 |= UART2_CR5_IRLP;
}
else
{
UART2->CR5 &= ((u8)~UART2_CR5_IRLP);
}
}
/**
* @brief Enables or disables the UART2s IrDA interface.
* @par Full description:
* Enables or disables the UART2s IrDA interface.
* @par This function is related to IrDA mode.
* @param[in] NewState new state of the IrDA mode.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void UART2_IrDACmd(FunctionalState NewState)
{
/* Check parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Enable the IrDA mode by setting the IREN bit in the CR3 register */
UART2->CR5 |= UART2_CR5_IREN;
}
else
{
/* Disable the IrDA mode by clearing the IREN bit in the CR3 register */
UART2->CR5 &= ((u8)~UART2_CR5_IREN);
}
}
/**
* @brief Sets the UART2 LIN Break detection length.
* @par Full description:
* Sets the UART2 LIN Break detection length.
* @param[in] UART2_LINBreakDetectionLength specifies the LIN break detection length.
* This parameter can be any of the @ref UART2_LINBreakDetectionLength_TypeDef values.
* @retval None
*/
void UART2_LINBreakDetectionConfig(UART2_LINBreakDetectionLength_TypeDef UART2_LINBreakDetectionLength)
{
assert_param(IS_UART2_LINBREAKDETECTIONLENGTH_OK(UART2_LINBreakDetectionLength));
if (UART2_LINBreakDetectionLength != UART2_LINBREAKDETECTIONLENGTH_10BITS)
{
UART2->CR4 |= UART2_CR4_LBDL;
}
else
{
UART2->CR4 &= ((u8)~UART2_CR4_LBDL);
}
}
/**
* @brief Configue the UART2 peripheral.
* @par Full description:
* Configue the UART2 peripheral.
* @param[in] UART2_Mode specifies the LIN mode.
* This parameter can be any of the @ref UART2_LinMode_TypeDef values.
* @param[in] UART2_Autosync specifies the LIN automatic resynchronization mode.
* This parameter can be any of the @ref UART2_LinAutosync_TypeDef values.
* @param[in] UART2_DivUp specifies the LIN divider update method.
* This parameter can be any of the @ref UART2_LinDivUp_TypeDef values.
* @retval None
*/
void UART2_LINConfig(UART2_LinMode_TypeDef UART2_Mode, UART2_LinAutosync_TypeDef UART2_Autosync, UART2_LinDivUp_TypeDef UART2_DivUp)
{
assert_param(IS_UART2_SLAVE_OK(UART2_Mode));
assert_param(IS_UART2_AUTOSYNC_OK(UART2_Autosync));
assert_param(IS_UART2_DIVUP_OK(UART2_DivUp));
if (UART2_Mode != UART2_LIN_MODE_MASTER)
{
UART2->CR6 |= UART2_CR6_LSLV;
}
else
{
UART2->CR6 &= ((u8)~UART2_CR6_LSLV);
}
if (UART2_Autosync != UART2_LIN_AUTOSYNC_DISABLE)
{
UART2->CR6 |= UART2_CR6_LASE ;
}
else
{
UART2->CR6 &= ((u8)~ UART2_CR6_LASE );
}
if (UART2_DivUp != UART2_LIN_DIVUP_LBRR1)
{
UART2->CR6 |= UART2_CR6_LDUM;
}
else
{
UART2->CR6 &= ((u8)~ UART2_CR6_LDUM);
}
}
/**
* @brief Enables or disables the UART2 LIN mode.
* @par Full description:
* Enables or disables the UART2s LIN mode.
* @param[in] NewState is new state of the UART2 LIN mode.
* This parameter can be:
* - ENABLE
* - DISABLE
* @retval None
*/
void UART2_LINCmd(FunctionalState NewState)
{
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Enable the LIN mode by setting the LINE bit in the CR2 register */
UART2->CR3 |= UART2_CR3_LINEN;
}
else
{
/* Disable the LIN mode by clearing the LINE bit in the CR2 register */
UART2->CR3 &= ((u8)~UART2_CR3_LINEN);
}
}
/**
* @brief Enables or disables the UART2 Smart Card mode.
* @par Full description:
* Enables or disables the UART2 Smart Card mode.
* @par This function is related to SmartCard mode.
* @param[in] NewState: new state of the Smart Card mode.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void UART2_SmartCardCmd(FunctionalState NewState)
{
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Enable the SC mode by setting the SCEN bit in the CR5 register */
UART2->CR5 |= UART2_CR5_SCEN;
}
else
{
/* Disable the SC mode by clearing the SCEN bit in the CR5 register */
UART2->CR5 &= ((u8)(~UART2_CR5_SCEN));
}
}
/**
* @brief Enables or disables NACK transmission.
* @par Full description:
* Enables or disables NACK transmission.
* @par This function is valid only for UART2 because is related to SmartCard mode.
* @param[in] NewState: new state of the Smart Card mode.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void UART2_SmartCardNACKCmd(FunctionalState NewState)
{
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Enable the NACK transmission by setting the NACK bit in the CR5 register */
UART2->CR5 |= UART2_CR5_NACK;
}
else
{
/* Disable the NACK transmission by clearing the NACK bit in the CR5 register */
UART2->CR5 &= ((u8)~(UART2_CR5_NACK));
}
}
/**
* @brief Selects the UART2 WakeUp method.
* @par Full description:
* Selects the UART2 WakeUp method.
* @param[in] UART2_WakeUp: specifies the UART2 wakeup method.
* This parameter can be any of the @ref UART2_WakeUp_TypeDef values.
* @retval None
*/
void UART2_WakeUpConfig(UART2_WakeUp_TypeDef UART2_WakeUp)
{
assert_param(IS_UART2_WAKEUP_OK(UART2_WakeUp));
UART2->CR1 &= ((u8)~UART2_CR1_WAKE);
UART2->CR1 |= (u8)UART2_WakeUp;
}
/**
* @brief Determines if the UART2 is in mute mode or not.
* @par Full description:
* Determines if the UART2 is in mute mode or not.
* @param[in] NewState: new state of the UART2 mode.
* This parameter can be:
* - ENABLE
* - DISABLE
* @retval None
*/
void UART2_ReceiverWakeUpCmd(FunctionalState NewState)
{
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/* Enable the mute mode UART2 by setting the RWU bit in the CR2 register */
UART2->CR2 |= UART2_CR2_RWU;
}
else
{
/* Disable the mute mode UART2 by clearing the RWU bit in the CR1 register */
UART2->CR2 &= ((u8)~UART2_CR2_RWU);
}
}
/**
* @brief Returns the most recent received data by the UART2 peripheral.
* @par Full description:
* Returns the most recent received data by the UART2 peripheral.
* @retval u16 Received Data
* @par Required preconditions:
* UART2_Cmd(ENABLE);
*/
u8 UART2_ReceiveData8(void)
{
return ((u8)UART2->DR);
}
/**
* @brief Returns the most recent received data by the UART2 peripheral.
* @par Full description:
* Returns the most recent received data by the UART2 peripheral.
* @retval u16 Received Data
* @par Required preconditions:
* UART2_Cmd(ENABLE);
*/
u16 UART2_ReceiveData9(void)
{
return (u16)((((u16)UART2->DR) | ((u16)(((u16)((u16)UART2->CR1 & (u16)UART2_CR1_R8)) << 1))) & ((u16)0x01FF));
}
/**
* @brief Transmits 8 bit data through the UART2 peripheral.
* @par Full description:
* Transmits 8 bit data through the UART2 peripheral.
* @param[in] Data: the data to transmit.
* @retval None
* @par Required preconditions:
* UART2_Cmd(ENABLE);
*/
void UART2_SendData8(u8 Data)
{
/* Transmit Data */
UART2->DR = Data;
}
/**
* @brief Transmits 9 bit data through the UART2 peripheral.
* @par Full description:
* Transmits 9 bit data through the UART2 peripheral.
* @param[in] Data: the data to transmit.
* @retval None
* @par Required preconditions:
* UART2_Cmd(ENABLE);
*/
void UART2_SendData9(u16 Data)
{
UART2->CR1 &= ((u8)~UART2_CR1_T8); /* Clear the transmit data bit 8 */
UART2->CR1 |= (u8)(((u8)(Data >> 2)) & UART2_CR1_T8); /* Write the transmit data bit [8] */
UART2->DR = (u8)(Data); /* Write the transmit data bit [0:7] */
}
/**
* @brief Transmits break characters.
* @par Full description:
* Transmits break characters on the UART2 peripheral.
* @retval None
*/
void UART2_SendBreak(void)
{
UART2->CR2 |= UART2_CR2_SBK;
}
/**
* @brief Sets the address of the UART2 node.
* @par Full description:
* Sets the address of the UART2 node.
* @param[in] UART2_Address: Indicates the address of the UART2 node.
* @retval None
*/
void UART2_SetAddress(u8 UART2_Address)
{
/*assert_param for x UART2_Address*/
assert_param(IS_UART2_ADDRESS_OK(UART2_Address));
/* Clear the UART2 address */
UART2->CR4 &= ((u8)~UART2_CR4_ADD);
/* Set the UART2 address node */
UART2->CR4 |= UART2_Address;
}
/**
* @brief Sets the specified UART2 guard time.
* @par Full description:
* Sets the address of the UART2 node.
* @par This function is related to SmartCard mode.
* @param[in] UART2_GuardTime: specifies the guard time.
* @retval None
* @par Required preconditions:
* SmartCard Mode Enabled
*/
void UART2_SetGuardTime(u8 UART2_GuardTime)
{
/* Set the UART2 guard time */
UART2->GTR = UART2_GuardTime;
}
/**
* @brief Sets the system clock prescaler.
* @par Full description:
* Sets the system clock prescaler.
* @par This function is related to SmartCard and IrDa mode.
* @param[in] UART2_Prescaler: specifies the prescaler clock.
* This parameter can be one of the following values:
* @par IrDA Low Power Mode
* The clock source is diveded by the value given in the register (8 bits)
* - 0000 0000 Reserved
* - 0000 0001 divides the clock source by 1
* - 0000 0010 divides the clock source by 2
* - ...........................................................
* @par Smart Card Mode
* The clock source is diveded by the value given in the register (5 significant bits) multipied by 2
* - 0 0000 Reserved
* - 0 0001 divides the clock source by 2
* - 0 0010 divides the clock source by 4
* - 0 0011 divides the clock source by 6
* - ...........................................................
* @retval None
* @par Required preconditions:
* IrDA Low Power mode or smartcard mode enabled
*/
void UART2_SetPrescaler(u8 UART2_Prescaler)
{
/* Load the UART2 prescaler value*/
UART2->PSCR = UART2_Prescaler;
}
/**
* @brief Checks whether the specified UART2 flag is set or not.
* @par Full description:
* Checks whether the specified UART2 flag is set or not.
* @param[in] UART2_FLAG specifies the flag to check.
* This parameter can be any of the @ref UART2_Flag_TypeDef enumeration.
* @retval FlagStatus (SET or RESET)
*/
FlagStatus UART2_GetFlagStatus(UART2_Flag_TypeDef UART2_FLAG)
{
FlagStatus status = RESET;
/* Check parameters */
assert_param(IS_UART2_FLAG_OK(UART2_FLAG));
/* Check the status of the specified UART2 flag*/
if (UART2_FLAG == UART2_FLAG_LBDF)
{
if ((UART2->CR4 & (u8)UART2_FLAG) != (u8)0x00)
{
/* UART2_FLAG is set*/
status = SET;
}
else
{
/* UART2_FLAG is reset*/
status = RESET;
}
}
else if (UART2_FLAG == UART2_FLAG_SBK)
{
if ((UART2->CR2 & (u8)UART2_FLAG) != (u8)0x00)
{
/* UART2_FLAG is set*/
status = SET;
}
else
{
/* UART2_FLAG is reset*/
status = RESET;
}
}
else if ((UART2_FLAG == UART2_FLAG_LHDF) || (UART2_FLAG == UART2_FLAG_LSF))
{
if ((UART2->CR6 & (u8)UART2_FLAG) != (u8)0x00)
{
/* UART2_FLAG is set*/
status = SET;
}
else
{
/* UART2_FLAG is reset*/
status = RESET;
}
}
else
{
if ((UART2->SR & (u8)UART2_FLAG) != (u8)0x00)
{
/* UART2_FLAG is set*/
status = SET;
}
else
{
/* UART2_FLAG is reset*/
status = RESET;
}
}
/* Return the UART2_FLAG status*/
return status;
}
/**
* @brief Clears the UART2 flags.
* @par Full description:
* Clears the UART2 flags.
* @param[in] UART2_FLAG specifies the flag to clear
* This parameter can be any combination of the following values:
* - UART2_FLAG_LBDF: LIN Break detection flag.
* - UART2_FLAG_LHDF: LIN Header detection flag.
* - UART2_FLAG_LSF: LIN synchrone field flag.
* - UART2_FLAG_RXNE: Receive data register not empty flag.
* @par Notes:
* - PE (Parity error), FE (Framing error), NE (Noise error), OR (OverRun error)
* and IDLE (Idle line detected) flags are cleared by software sequence: a read
* operation to UART2_SR register (UART2_GetFlagStatus())followed by a read operation
* to UART2_DR register(UART2_ReceiveData8() or UART2_ReceiveData9()).
* - RXNE flag can be also cleared by a read to the UART2_DR register
* (UART2_ReceiveData8()or UART2_ReceiveData9()).
* - TC flag can be also cleared by software sequence: a read operation to UART2_SR
* register (UART2_GetFlagStatus()) followed by a write operation to UART2_DR register
* (UART2_SendData8() or UART2_SendData9()).
* - TXE flag is cleared only by a write to the UART2_DR register (UART2_SendData8() or
* UART2_SendData9()).
* - SBK flag is cleared during the stop bit of break.
* @retval None
*/
void UART2_ClearFlag(UART2_Flag_TypeDef UART2_FLAG)
{
assert_param(IS_UART2_CLEAR_FLAG_OK(UART2_FLAG));
/*< Clear the Receive Register Not Empty flag */
if (UART2_FLAG == UART2_FLAG_RXNE)
{
UART2->SR = (u8)~(UART2_SR_RXNE);
}
/*< Clear the LIN Break Detection flag */
else if (UART2_FLAG == UART2_FLAG_LBDF)
{
UART2->CR4 &= (u8)(~UART2_CR4_LBDF);
}
/*< Clear the LIN Header Detection Flag */
else if (UART2_FLAG == UART2_FLAG_LHDF)
{
UART2->CR6 &= (u8)(~UART2_CR6_LHDF);
}
/*< Clear the LIN Synch Field flag */
else
{
UART2->CR6 &= (u8)(~UART2_CR6_LSF);
}
}
/**
* @brief Checks whether the specified UART2 interrupt has occurred or not.
* @par Full description:
* Checks whether the specified UART2 interrupt has occurred or not.
* @param[in] UART2_IT: Specifies the UART2 interrupt pending bit to check.
* This parameter can be one of the following values:
* - UART2_IT_LBDF: LIN Break detection interrupt
* - UART2_IT_TXE: Tansmit Data Register empty interrupt
* - UART2_IT_TC: Transmission complete interrupt
* - UART2_IT_RXNE: Receive Data register not empty interrupt
* - UART2_IT_IDLE: Idle line detection interrupt
* - UART2_IT_OR: OverRun Error interrupt
* - UART2_IT_PE: Parity Error interrupt
* @retval
* ITStatus The new state of UART2_IT (SET or RESET).
*/
ITStatus UART2_GetITStatus(UART2_IT_TypeDef UART2_IT)
{
ITStatus pendingbitstatus = RESET;
u8 itpos = 0;
u8 itmask1 = 0;
u8 itmask2 = 0;
u8 enablestatus = 0;
/* Check parameters */
assert_param(IS_UART2_GET_IT_OK(UART2_IT));
/* Get the UART2 IT index*/
itpos = (u8)((u8)1 << (u8)((u8)UART2_IT & (u8)0x0F));
/* Get the UART2 IT index*/
itmask1 = (u8)((u8)UART2_IT >> (u8)4);
/* Set the IT mask*/
itmask2 = (u8)((u8)1 << itmask1);
/* Check the status of the specified UART2 pending bit*/
if (UART2_IT == UART2_IT_PE)
{
/* Get the UART2_ITPENDINGBIT enable bit status*/
enablestatus = (u8)((u8)UART2->CR1 & itmask2);
/* Check the status of the specified UART2 interrupt*/
if (((UART2->SR & itpos) != (u8)0x00) && enablestatus)
{
/* Interrupt occurred*/
pendingbitstatus = SET;
}
else
{
/* Interrupt not occurred*/
pendingbitstatus = RESET;
}
}
else if (UART2_IT == UART2_IT_LBDF)
{
/* Get the UART2_IT enable bit status*/
enablestatus = (u8)((u8)UART2->CR4 & itmask2);
/* Check the status of the specified UART2 interrupt*/
if (((UART2->CR4 & itpos) != (u8)0x00) && enablestatus)
{
/* Interrupt occurred*/
pendingbitstatus = SET;
}
else
{
/* Interrupt not occurred*/
pendingbitstatus = RESET;
}
}
else if (UART2_IT == UART2_IT_LHDF)
{
/* Get the UART2_IT enable bit status*/
enablestatus = (u8)((u8)UART2->CR6 & itmask2);
/* Check the status of the specified UART2 interrupt*/
if (((UART2->CR6 & itpos) != (u8)0x00) && enablestatus)
{
/* Interrupt occurred*/
pendingbitstatus = SET;
}
else
{
/* Interrupt not occurred*/
pendingbitstatus = RESET;
}
}
else
{
/* Get the UART2_IT enable bit status*/
enablestatus = (u8)((u8)UART2->CR2 & itmask2);
/* Check the status of the specified UART2 interrupt*/
if (((UART2->SR & itpos) != (u8)0x00) && enablestatus)
{
/* Interrupt occurred*/
pendingbitstatus = SET;
}
else
{
/* Interrupt not occurred*/
pendingbitstatus = RESET;
}
}
/* Return the UART2_IT status*/
return pendingbitstatus;
}
/**
* @brief Clears the UART2 pending flags.
* @par Full description:
* Clears the UART2 pending bit.
* @param[in] UART2_IT specifies the pending bit to clear
* This parameter can be one of the following values:
* - UART2_IT_LBDF: LIN Break detection interrupt
* - UART2_IT_LHDF: LIN Header detection interrupt
* - UART2_IT_RXNE: Receive Data register not empty interrupt.
*
* @par Notes:
* - PE (Parity error), FE (Framing error), NE (Noise error), OR (OverRun error) and
* IDLE (Idle line detected) pending bits are cleared by software sequence: a read
* operation to UART2_SR register (UART2_GetITStatus()) followed by a read operation
* to UART2_DR register (UART2_ReceiveData8() or UART2_ReceiveData9() ).
* - RXNE pending bit can be also cleared by a read to the UART2_DR register
* (UART2_ReceiveData8() or UART2_ReceiveData9() ).
* - TC (Transmit complet) pending bit can be cleared by software sequence: a read
* operation to UART2_SR register (UART2_GetITStatus()) followed by a write operation
* to UART2_DR register (UART2_SendData8()or UART2_SendData9()).
* - TXE pending bit is cleared only by a write to the UART2_DR register
* (UART2_SendData8() or UART2_SendData9()).
* @retval None
*/
void UART2_ClearITPendingBit(UART2_IT_TypeDef UART2_IT)
{
assert_param(IS_UART2_CLEAR_IT_OK(UART2_IT));
/*< Clear the Receive Register Not Empty pending bit */
if (UART2_IT == UART2_IT_RXNE)
{
UART2->SR = (u8)~(UART2_SR_RXNE);
}
/*< Clear the LIN Break Detection pending bit */
else if (UART2_IT == UART2_IT_LBDF)
{
UART2->CR4 &= (u8)~(UART2_CR4_LBDF);
}
/*< Clear the LIN Header Detection pending bit */
else
{
UART2->CR6 &= (u8)(~UART2_CR6_LHDF);
}
}
/**
* @}
*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,412 @@
/**
********************************************************************************
* @file stm8s_uart2.h
* @brief This file contains all functions prototypes and macros for the UART2 peripheral.
* @author STMicroelectronics - MCD Application Team
* @version V1.1.1
* @date 06/05/2009
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
* @image html logo.bmp
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM8S_UART2_H
#define __STM8S_UART2_H
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
/* Exported types ------------------------------------------------------------*/
/** @addtogroup UART2_Exported_Types
* @{
*/
/**
* @brief UART2 Irda Modes
*/
typedef enum { UART2_IRDAMODE_NORMAL = (u8)0x00, /**< 0x00 Irda Normal Mode */
UART2_IRDAMODE_LOWPOWER = (u8)0x01 /**< 0x01 Irda Low Power Mode */
} UART2_IrDAMode_TypeDef;
/**
* @brief UART2 WakeUP Modes
*/
typedef enum { UART2_WAKEUP_IDLELINE = (u8)0x00, /**< 0x01 Idle Line wake up */
UART2_WAKEUP_ADDRESSMARK = (u8)0x08 /**< 0x02 Address Mark wake up */
} UART2_WakeUp_TypeDef;
/**
* @brief UART2 LIN Break detection length possible values
*/
typedef enum { UART2_LINBREAKDETECTIONLENGTH_10BITS = (u8)0x00, /**< 0x01 10 bits Lin Break detection */
UART2_LINBREAKDETECTIONLENGTH_11BITS = (u8)0x01 /**< 0x02 11 bits Lin Break detection */
} UART2_LINBreakDetectionLength_TypeDef;
/**
* @brief UART2 stop bits possible values
*/
typedef enum { UART2_STOPBITS_1 = (u8)0x00, /**< One stop bit is transmitted at the end of frame*/
UART2_STOPBITS_0_5 = (u8)0x10, /**< Half stop bits is transmitted at the end of frame*/
UART2_STOPBITS_2 = (u8)0x20, /**< Two stop bits are transmitted at the end of frame*/
UART2_STOPBITS_1_5 = (u8)0x30 /**< One and half stop bits*/
} UART2_StopBits_TypeDef;
/**
* @brief UART2 parity possible values
*/
typedef enum { UART2_PARITY_NO = (u8)0x00, /**< No Parity*/
UART2_PARITY_EVEN = (u8)0x04, /**< Even Parity*/
UART2_PARITY_ODD = (u8)0x06 /**< Odd Parity*/
} UART2_Parity_TypeDef;
/**
* @brief UART2 Mode possible values
*/
typedef enum { UART2_LIN_MODE_MASTER = (u8)0x00, /**< LIN Master Mode*/
UART2_LIN_MODE_SLAVE = (u8)0x01 /**< LIN Slave Mode*/
} UART2_LinMode_TypeDef;
/**
* @brief UART2 automatic resynchronisation possible values
*/
typedef enum { UART2_LIN_AUTOSYNC_DISABLE = (u8)0x00, /**< LIN Autosynchronization Disable*/
UART2_LIN_AUTOSYNC_ENABLE = (u8)0x01 /**< LIN Autosynchronization Enable*/
} UART2_LinAutosync_TypeDef;
/**
* @brief UART2 Divider Update Method possible values
*/
typedef enum { UART2_LIN_DIVUP_LBRR1 = (u8)0x00, /**< LIN LDIV is updated as soon as LBRR1 is written*/
UART2_LIN_DIVUP_NEXTRXNE = (u8)0x01 /**< LIN LDIV is updated at the next received character*/
} UART2_LinDivUp_TypeDef;
/**
* @brief UART2 Synchrone modes
*/
typedef enum { UART2_SYNCMODE_CLOCK_DISABLE = (u8)0x80, /**< 0x80 Sync mode Disable, SLK pin Disable */
UART2_SYNCMODE_CLOCK_ENABLE = (u8)0x08, /**< 0x08 Sync mode Enable, SLK pin Enable */
UART2_SYNCMODE_CPOL_LOW = (u8)0x40, /**< 0x40 Steady low value on SCLK pin outside transmission window */
UART2_SYNCMODE_CPOL_HIGH = (u8)0x04, /**< 0x04 Steady high value on SCLK pin outside transmission window */
UART2_SYNCMODE_CPHA_MIDDLE = (u8)0x20, /**< 0x20 SCLK clock line activated in middle of data bit */
UART2_SYNCMODE_CPHA_BEGINING = (u8)0x02, /**< 0x02 SCLK clock line activated at beginning of data bit */
UART2_SYNCMODE_LASTBIT_DISABLE = (u8)0x10, /**< 0x10 The clock pulse of the last data bit is not output to the SCLK pin */
UART2_SYNCMODE_LASTBIT_ENABLE = (u8)0x01 /**< 0x01 The clock pulse of the last data bit is output to the SCLK pin */
} UART2_SyncMode_TypeDef;
/**
* @brief UART2 Word length possible values
*/
typedef enum { UART2_WORDLENGTH_8D = (u8)0x00,/**< 0x00 8 bits Data */
UART2_WORDLENGTH_9D = (u8)0x10 /**< 0x10 9 bits Data */
} UART2_WordLength_TypeDef;
/**
* @brief UART2 Mode possible values
*/
typedef enum { UART2_MODE_RX_ENABLE = (u8)0x08, /**< 0x08 Receive Enable */
UART2_MODE_TX_ENABLE = (u8)0x04, /**< 0x04 Transmit Enable */
UART2_MODE_TX_DISABLE = (u8)0x80, /**< 0x80 Transmit Disable */
UART2_MODE_RX_DISABLE = (u8)0x40, /**< 0x40 Single-wire Half-duplex mode */
UART2_MODE_TXRX_ENABLE = (u8)0x0C /**< 0x0C Transmit Enable and Receive Enable */
} UART2_Mode_TypeDef;
/**
* @brief UART2 Flag possible values
*/
typedef enum
{
UART2_FLAG_TXE = (u16)0x0080, /*!< Transmit Data Register Empty flag */
UART2_FLAG_TC = (u16)0x0040, /*!< Transmission Complete flag */
UART2_FLAG_RXNE = (u16)0x0020, /*!< Read Data Register Not Empty flag */
UART2_FLAG_IDLE = (u16)0x0010, /*!< Idle line detected flag */
UART2_FLAG_OR_LHE = (u16)0x0008, /*!< OverRun error flag */
UART2_FLAG_NF = (u16)0x0004, /*!< Noise error flag */
UART2_FLAG_FE = (u16)0x0002, /*!< Framing Error flag */
UART2_FLAG_PE = (u16)0x0001, /*!< Parity Error flag */
UART2_FLAG_SBK = (u16)0x0101, /**< Send Break Complete interrupt flag */
UART2_FLAG_LBDF = (u16)0x0210, /**< LIN Break Detection Flag */
UART2_FLAG_LHDF = (u16)0x0302, /**< LIN Header Detection Flag*/
UART2_FLAG_LSF = (u16)0x0301 /**< LIN Sync Field Flag*/
} UART2_Flag_TypeDef;
/**
* @brief UART2 Interrupt definition
* UART2_IT possible values
* Elements values convention: 0xZYX
* X: Position of the corresponding Interrupt
* - For the following values, X means the interrupt position in the CR2 register.
* UART2_IT_TXE
* UART2_IT_TC
* UART2_IT_RXNE
* UART2_IT_IDLE
* UART2_IT_OR
* - For the UART2_IT_PE value, X means the flag position in the CR1 register.
* - For the UART2_IT_LBDF value, X means the flag position in the CR4 register.
* - For the UART2_IT_LHDF value, X means the flag position in the CR6 register.
* Y: Flag position
* - For the following values, Y means the flag (pending bit) position in the SR register.
* UART2_IT_TXE
* UART2_IT_TC
* UART2_IT_RXNE
* UART2_IT_IDLE
* UART2_IT_OR
* UART2_IT_PE
* - For the UART2_IT_LBDF value, Y means the flag position in the CR4 register.
* - For the UART2_IT_LHDF value, Y means the flag position in the CR6 register.
* Z: Register index: indicate in which register the dedicated interrupt source is:
* - 1==> CR1 register
* - 2==> CR2 register
* - 3==> CR4 register
* - 4==> CR6 register
*/
typedef enum { UART2_IT_TXE = (u16)0x0277, /**< Transmit interrupt */
UART2_IT_TC = (u16)0x0266, /**< Transmission Complete interrupt */
UART2_IT_RXNE = (u16)0x0255, /**< Data Register Not Empty interrupt */
UART2_IT_IDLE = (u16)0x0244, /**< Idle line detected interrupt */
UART2_IT_OR = (u16)0x0235, /**< OverRun error interrupt */
UART2_IT_PE = (u16)0x0100, /**< Parity Error interrupt */
UART2_IT_LBDF = (u16)0x0346, /**< LIN Break Detection interrupt */
UART2_IT_LHDF = (u16)0x0412, /**< LIN Header Detection interrupt*/
UART2_IT_RXNE_OR = (u16)0x0205 /*!< Receive/Overrun interrupt */
} UART2_IT_TypeDef;
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/* Exported macros ------------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/** @addtogroup UART2_Private_Macros
* @{
*/
/**
* @brief Macro used by the assert function to check the different functions parameters.
*/
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity
* values for the MODEs possible combination should be one of the following.
*/
#define IS_UART2_MODE_OK(Mode) \
(((Mode) == (u8)UART2_MODE_RX_ENABLE) || \
((Mode) == (u8)UART2_MODE_RX_DISABLE) || \
((Mode) == (u8)UART2_MODE_TX_ENABLE) || \
((Mode) == (u8)UART2_MODE_TX_DISABLE) || \
((Mode) == (u8)UART2_MODE_TXRX_ENABLE) || \
((Mode) == (u8)((u8)UART2_MODE_TX_ENABLE|(u8)UART2_MODE_RX_ENABLE)) || \
((Mode) == (u8)((u8)UART2_MODE_TX_ENABLE|(u8)UART2_MODE_RX_DISABLE)) || \
((Mode) == (u8)((u8)UART2_MODE_TX_DISABLE|(u8)UART2_MODE_RX_DISABLE)) || \
((Mode) == (u8)((u8)UART2_MODE_TX_DISABLE|(u8)UART2_MODE_RX_ENABLE)))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the WordLengths
*/
#define IS_UART2_WORDLENGTH_OK(WordLength) \
(((WordLength) == UART2_WORDLENGTH_8D) || \
((WordLength) == UART2_WORDLENGTH_9D))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the SyncModes; it should exclude values such as UART2_CLOCK_ENABLE|UART2_CLOCK_DISABLE
* UART2_SyncMode value should exclude values such as UART2_CLOCK_ENABLE|UART2_CLOCK_DISABLE
*/
#define IS_UART2_SYNCMODE_OK(SyncMode) \
(!((((SyncMode)&(((u8)UART2_SYNCMODE_CLOCK_ENABLE)|((u8)UART2_SYNCMODE_CLOCK_DISABLE))) == (((u8)UART2_SYNCMODE_CLOCK_ENABLE)|((u8)UART2_SYNCMODE_CLOCK_DISABLE))) || \
(((SyncMode)&(((u8)UART2_SYNCMODE_CPOL_LOW )|((u8)UART2_SYNCMODE_CPOL_HIGH))) == (((u8)UART2_SYNCMODE_CPOL_LOW )|((u8)UART2_SYNCMODE_CPOL_HIGH))) || \
(((SyncMode)&(((u8)UART2_SYNCMODE_CPHA_MIDDLE)|((u8)UART2_SYNCMODE_CPHA_BEGINING))) == (((u8)UART2_SYNCMODE_CPHA_MIDDLE)|((u8)UART2_SYNCMODE_CPHA_BEGINING))) || \
(((SyncMode)&(((u8)UART2_SYNCMODE_LASTBIT_DISABLE)|((u8)UART2_SYNCMODE_LASTBIT_ENABLE))) == (((u8)UART2_SYNCMODE_LASTBIT_DISABLE)|((u8)UART2_SYNCMODE_LASTBIT_ENABLE)))))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the FLAGs
*/
#define IS_UART2_FLAG_OK(Flag) \
(((Flag) == UART2_FLAG_TXE) || \
((Flag) == UART2_FLAG_TC) || \
((Flag) == UART2_FLAG_RXNE) || \
((Flag) == UART2_FLAG_IDLE) || \
((Flag) == UART2_FLAG_OR_LHE) || \
((Flag) == UART2_FLAG_NF) || \
((Flag) == UART2_FLAG_FE) || \
((Flag) == UART2_FLAG_PE) || \
((Flag) == UART2_FLAG_SBK) || \
((Flag) == UART2_FLAG_LSF) || \
((Flag) == UART2_FLAG_LHDF) || \
((Flag) == UART2_FLAG_LBDF))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the FLAGs that can be cleared by writing 0
*/
#define IS_UART2_CLEAR_FLAG_OK(Flag) \
(((Flag) == UART2_FLAG_RXNE) || \
((Flag) == UART2_FLAG_LHDF) || \
((Flag) == UART2_FLAG_LSF) || \
((Flag) == UART2_FLAG_LBDF))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the Interrupts
*/
#define IS_UART2_CONFIG_IT_OK(Interrupt) \
(((Interrupt) == UART2_IT_PE) || \
((Interrupt) == UART2_IT_TXE) || \
((Interrupt) == UART2_IT_TC) || \
((Interrupt) == UART2_IT_RXNE_OR ) || \
((Interrupt) == UART2_IT_IDLE) || \
((Interrupt) == UART2_IT_LHDF) || \
((Interrupt) == UART2_IT_LBDF))
/**
* @brief Macro used by the assert function in order to check the different sensitivity values for the pending bit
*/
#define IS_UART2_GET_IT_OK(ITPendingBit) \
(((ITPendingBit) == UART2_IT_TXE) || \
((ITPendingBit) == UART2_IT_TC) || \
((ITPendingBit) == UART2_IT_RXNE) || \
((ITPendingBit) == UART2_IT_IDLE) || \
((ITPendingBit) == UART2_IT_OR) || \
((ITPendingBit) == UART2_IT_LBDF) || \
((ITPendingBit) == UART2_IT_LHDF) || \
((ITPendingBit) == UART2_IT_PE))
/**
* @brief Macro used by the assert function in order to check the different sensitivity values for the pending bit that can be cleared by writing 0
*/
#define IS_UART2_CLEAR_IT_OK(ITPendingBit) \
(((ITPendingBit) == UART2_IT_RXNE) || \
((ITPendingBit) == UART2_IT_LHDF) || \
((ITPendingBit) == UART2_IT_LBDF))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the IrDAModes
*/
#define IS_UART2_IRDAMODE_OK(IrDAMode) \
(((IrDAMode) == UART2_IRDAMODE_LOWPOWER) || \
((IrDAMode) == UART2_IRDAMODE_NORMAL))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the WakeUps
*/
#define IS_UART2_WAKEUP_OK(WakeUp) \
(((WakeUp) == UART2_WAKEUP_IDLELINE) || \
((WakeUp) == UART2_WAKEUP_ADDRESSMARK))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the LINBreakDetectionLengths
*/
#define IS_UART2_LINBREAKDETECTIONLENGTH_OK(LINBreakDetectionLength) \
(((LINBreakDetectionLength) == UART2_LINBREAKDETECTIONLENGTH_10BITS) || \
((LINBreakDetectionLength) == UART2_LINBREAKDETECTIONLENGTH_11BITS))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the UART2_StopBits
*/
#define IS_UART2_STOPBITS_OK(StopBit) (((StopBit) == UART2_STOPBITS_1) || \
((StopBit) == UART2_STOPBITS_0_5) || \
((StopBit) == UART2_STOPBITS_2) || \
((StopBit) == UART2_STOPBITS_1_5 ))
/**
* @brief Macro used by the assert_param function in order to check the different sensitivity values for the Paritys
*/
#define IS_UART2_PARITY_OK(Parity) (((Parity) == UART2_PARITY_NO) || \
((Parity) == UART2_PARITY_EVEN) || \
((Parity) == UART2_PARITY_ODD ))
/**
* @brief Macro used by the assert_param function in order to check the maximum baudrate value
*/
#define IS_UART2_BAUDRATE_OK(NUM) ((NUM) <= (u32)625000)
/**
* @brief Macro used by the assert_param function in order to check the address of the UART2 or UART node
*/
#define UART2_ADDRESS_MAX ((u8)16)
#define IS_UART2_ADDRESS_OK(node) ((node) < UART2_ADDRESS_MAX )
/**
* @brief Macro used by the assert_param function in order to check the LIN mode
*/
#define IS_UART2_SLAVE_OK(Mode) \
(((Mode) == UART2_LIN_MODE_MASTER) || \
((Mode) == UART2_LIN_MODE_SLAVE))
/**
* @brief Macro used by the assert_param function in order to check the LIN automatic resynchronization mode
*/
#define IS_UART2_AUTOSYNC_OK(AutosyncMode) \
(((AutosyncMode) == UART2_LIN_AUTOSYNC_ENABLE) || \
((AutosyncMode) == UART2_LIN_AUTOSYNC_DISABLE))
/**
* @brief Macro used by the assert_param function in order to check the LIN divider update method
*/
#define IS_UART2_DIVUP_OK(DivupMethode) \
(((DivupMethode) == UART2_LIN_DIVUP_LBRR1) || \
((DivupMethode) == UART2_LIN_DIVUP_NEXTRXNE))
/**
* @}
*/
/* Exported functions ------------------------------------------------------- */
/** @addtogroup UART2_Exported_Functions
* @{
*/
void UART2_DeInit(void);
void UART2_Init(u32 BaudRate, UART2_WordLength_TypeDef WordLength, UART2_StopBits_TypeDef StopBits, UART2_Parity_TypeDef Parity, UART2_SyncMode_TypeDef SyncMode, UART2_Mode_TypeDef Mode);
void UART2_Cmd(FunctionalState NewState);
void UART2_ITConfig(UART2_IT_TypeDef UART2_IT, FunctionalState NewState);
void UART2_HalfDuplexCmd(FunctionalState NewState);
void UART2_IrDAConfig(UART2_IrDAMode_TypeDef UART2_IrDAMode);
void UART2_IrDACmd(FunctionalState NewState);
void UART2_LINBreakDetectionConfig(UART2_LINBreakDetectionLength_TypeDef UART2_LINBreakDetectionLength);
void UART2_LINConfig(UART2_LinMode_TypeDef UART2_Mode, UART2_LinAutosync_TypeDef UART2_Autosync, UART2_LinDivUp_TypeDef UART2_DivUp);
void UART2_LINCmd(FunctionalState NewState);
void UART2_SmartCardCmd(FunctionalState NewState);
void UART2_SmartCardNACKCmd(FunctionalState NewState);
void UART2_WakeUpConfig(UART2_WakeUp_TypeDef UART2_WakeUp);
void UART2_ReceiverWakeUpCmd(FunctionalState NewState);
u8 UART2_ReceiveData8(void);
u16 UART2_ReceiveData9(void);
void UART2_SendData8(u8 Data);
void UART2_SendData9(u16 Data);
void UART2_SendBreak(void);
void UART2_SetAddress(u8 UART2_Address);
void UART2_SetGuardTime(u8 UART2_GuardTime);
void UART2_SetPrescaler(u8 UART2_Prescaler);
FlagStatus UART2_GetFlagStatus(UART2_Flag_TypeDef UART2_FLAG);
void UART2_ClearFlag(UART2_Flag_TypeDef UART2_FLAG);
ITStatus UART2_GetITStatus(UART2_IT_TypeDef UART2_IT);
void UART2_ClearITPendingBit(UART2_IT_TypeDef UART2_IT);
/**
* @}
*/
#endif /* __STM8S_UART2_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -23,8 +23,6 @@
#ifndef __STM8S_CONF_H
#define __STM8S_CONF_H
/* Atomthreads port: Use STM8S105 */
#define STM8S105
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
@@ -127,8 +125,9 @@
/* #define _UART1 (1) */
#endif /* (STM8S208) ||(STM8S207) || (STM8S103) || (STM8S903) */
/* Atomthreads port: Use UART2 on STM8S Discovery, change if required */
#ifdef STM8S105
/* #define _UART2 (1) */
#define _UART2 (1)
#endif /* STM8S105 */
#if defined(STM8S208) ||defined(STM8S207)

View File

@@ -28,10 +28,13 @@
*/
#include <stdio.h>
#include "atom.h"
#include "atomport-private.h"
#include "atomtests.h"
#include "atomtimer.h"
#include "uart.h"
#include "stm8s.h"
@@ -58,14 +61,21 @@
* this with your own application thread.
*
* In this case the Main thread is responsible for calling out to the
* test routines. Once a test routine has finished, the thread remains
* running in a loop flashing a LED.
* test routines. Once a test routine has finished, the test status is
* printed out on the UART and the thread remains running in a loop
* flashing a LED.
*
* The Main thread stack generally needs to be larger than the idle
* thread stack, as not only does it need to store interrupt handler
* stack saves and context switch saves, but the application main thread
* will generally be carrying out more nested function calls and require
* stack for application code local variables etc.
*
* With all OS tests implemented to date on the STM8, the Main thread
* stack has not exceeded 256 bytes. To allow all tests to run we set
* a minimum main thread stack size of 204 bytes. This may increase in
* future as the codebase changes but for the time being is enough to
* cope with all of the automated tests.
*/
#define MAIN_STACK_SIZE_BYTES 256
@@ -174,7 +184,16 @@ void main ( void )
static void main_thread_func (uint32_t data)
{
uint32_t test_status;
int sleep_ticks;
int sleep_ticks;
/* Initialise UART (9600bps) */
if (uart_init(9600) != 0)
{
/* Error initialising UART */
}
/* Put a message out on the UART */
printf("Go\n");
/* Start test. All tests use the same start API. */
test_status = test_start();
@@ -191,12 +210,29 @@ static void main_thread_func (uint32_t data)
/* Check the thread did not use up to the end of stack */
if (free_bytes == 0)
{
printf ("Main stack overflow\n");
test_status++;
}
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
printf ("MainUse:%d\n", (int)used_bytes);
#endif
}
}
#endif
/* Log final status */
if (test_status == 0)
{
printf ("Pass\n");
}
else
{
printf ("Fail(%d)\n", (int)test_status);
}
/* Flash LED once per second if passed, very quickly if failed */
sleep_ticks = (test_status == 0) ? SYSTEM_TICKS_PER_SEC : (SYSTEM_TICKS_PER_SEC/8);

75
ports/stm8/uart.c Normal file
View File

@@ -0,0 +1,75 @@
#include <stdio.h>
#include "stm8s.h"
#include "atom.h"
#include "atommutex.h"
#include "uart.h"
/*
* Semaphore for single-threaded access to UART device
*/
static ATOM_MUTEX uart_mutex;
/*
* Initialize the UART to requested baudrate, tx/rx, 8N1.
*/
int uart_init(uint32_t baudrate)
{
int status;
/**
* Set up UART2 for putting out debug messages.
* This the UART used on STM8S Discovery, change if required.
*/
UART2_DeInit();
UART2_Init (baudrate, UART2_WORDLENGTH_8D, UART2_STOPBITS_1, UART2_PARITY_NO,
UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);
/* Create a mutex for single-threaded putchar() access */
if (atomMutexCreate (&uart_mutex) != ATOM_OK)
{
status = -1;
}
else
{
status = 0;
}
/* Finished */
return (status);
}
/**
* \b putchar
*
* Retarget putchar() to use UART2
*
* @param[in] c Character to send
*
* @return Character sent
*/
char putchar (char c)
{
/* Block on private access to the UART */
if (atomMutexGet(&uart_mutex, 0) == ATOM_OK)
{
/* Convert \n to \r\n */
if (c == '\n')
putchar('\r');
/* Write a character to the UART2 */
UART2_SendData8(c);
/* Loop until the end of transmission */
while (UART2_GetFlagStatus(UART2_FLAG_TXE) == RESET)
;
}
return (c);
}

9
ports/stm8/uart.h Normal file
View File

@@ -0,0 +1,9 @@
#include "atom.h"
/*
* Perform UART startup initialization.
*/
int uart_init(uint32_t baudrate);

View File

@@ -195,7 +195,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -166,7 +166,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -274,7 +274,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -255,7 +255,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -226,7 +226,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -223,7 +223,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -237,7 +237,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -228,7 +228,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -192,7 +192,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -175,7 +175,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -167,7 +167,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -220,7 +220,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -252,7 +252,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -243,7 +243,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -198,7 +198,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -175,7 +175,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -218,7 +218,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -281,7 +281,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -222,7 +222,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -212,7 +212,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -175,7 +175,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -158,7 +158,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -244,7 +244,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -203,7 +203,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -168,7 +168,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}

View File

@@ -137,7 +137,7 @@ uint32_t test_start (void)
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
ATOMLOG (_STR("StackUse:%d\n"), (int)used_bytes);
#endif
}
}