Add STM8 port (Cosmic compiler). Modify timer4 automated test now that timer API has changed to take ticks as parameter.

This commit is contained in:
Kelvin Lawson
2010-02-16 23:07:48 +00:00
parent 5665974ca7
commit 2124b5f5a1
20 changed files with 9465 additions and 0 deletions

1161
ports/stm8/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

103
ports/stm8/Makefile Normal file
View File

@@ -0,0 +1,103 @@
############
# Settings #
############
# Build all test applications:
# make
# Location of build tools and atomthreads sources
KERNEL_DIR=../../kernel
TESTS_DIR=../../tests
PERIPHS_DIR=stm8s-periphs
LIBS_DIR="C:\Program Files\COSMIC\CXSTM8_16K\Lib"
CC=cxstm8
ASM=castm8
LINK=clnk
CHEX=chex
# Directory for built objects
BUILD_DIR=build
# Port/application object files
APP_OBJECTS = atomport.o tests-main.o stm8_interrupt_vector.o
APP_ASM_OBJECTS = atomport-asm.o
# STM8S Peripheral driver object files
PERIPH_OBJECTS = stm8s_gpio.o stm8s_tim1.o
# Kernel object files
KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o
# Collection of built objects (excluding test applications)
ALL_OBJECTS = $(APP_OBJECTS) $(APP_ASM_OBJECTS) $(PERIPH_OBJECTS) $(KERNEL_OBJECTS)
BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS))
# Test object files (dealt with separately as only one per application build)
TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c)))
# Target application filenames (.elf and .hex) for each test object
TEST_STM8S = $(patsubst %.o,%.stm8,$(TEST_OBJECTS))
TEST_S19S = $(patsubst %.o,%.s19,$(TEST_OBJECTS))
# Search build/output directory for dependencies
vpath %.o .\$(BUILD_DIR)
vpath %.elf .\$(BUILD_DIR)
vpath %.hex .\$(BUILD_DIR)
# Compiler/Assembler flags
CFLAGS=+modsl0 -pp
DBG_CFLAGS=+modsl0 +debug -pxp -no -pp -l
ASMFLAGS=
DBG_ASMFLAGS=-xx -u
#################
# Build targets #
#################
# All tests
all: $(BUILD_DIR) $(TEST_S19S) Makefile
# Make build/output directory
$(BUILD_DIR):
mkdir $(BUILD_DIR)
# Test HEX files (one application build for each test)
$(TEST_S19S): %.s19: %.stm8
@echo Building $@
$(CHEX) -fm -o $(BUILD_DIR)/$@ $(BUILD_DIR)/$<
# Test ELF files (one application build for each test)
$(TEST_STM8S): %.stm8: %.o $(KERNEL_OBJECTS) $(PERIPH_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS)
$(LINK) -l$(LIBS_DIR) -o $(BUILD_DIR)/$@ atomthreads.lkf $(BUILD_DIR)/$(notdir $<)
# Kernel objects builder
$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c
$(CC) $(CFLAGS) -i. -i$(PERIPHS_DIR) -co$(BUILD_DIR) $<
# Test objects builder
$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c
$(CC) $(CFLAGS) -i. -i$(KERNEL_DIR) -i$(PERIPHS_DIR) -co$(BUILD_DIR) $<
# Kernel objects builder
$(PERIPH_OBJECTS): %.o: $(PERIPHS_DIR)/%.c
$(CC) $(CFLAGS) -i. -i$(PERIPHS_DIR) -co$(BUILD_DIR) $<
# Application C objects builder
$(APP_OBJECTS): %.o: ./%.c
$(CC) $(CFLAGS) -i. -i$(KERNEL_DIR) -i$(TESTS_DIR) -i$(PERIPHS_DIR) -co$(BUILD_DIR) $<
# Application asm objects builder
$(APP_ASM_OBJECTS): %.o: ./%.s
$(ASM) $(ASMFLAGS) -i. -i$(KERNEL_DIR) -o$(BUILD_DIR)/$(notdir $@) $<
# Clean
clean:
rm -f *.o *.elf *.map *.hex *.bin *.lst *.stm8 *.s19
rm -rf doxygen-kernel
rm -rf doxygen-stm8
rm -rf build
doxygen:
doxygen $(KERNEL_DIR)/Doxyfile
doxygen ./Doxyfile

353
ports/stm8/atomport-asm.s Normal file
View File

@@ -0,0 +1,353 @@
;
; Copyright (c) 2005, Atomthreads Project. All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; Modification, are permitted provided that the following conditions
; are met:
;
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; 3. No personal names or organizations' names associated with the
; Atomthreads project may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
; POSSIBILITY OF SUCH DAMAGE.
;
; Export functions to other modules
xdef _archContextSwitch, _archFirstThreadRestore
; \b archContextSwitch
;
; Architecture-specific context switch routine.
;
; Note that interrupts are always locked out when this routine is
; called. For cooperative switches, the scheduler will have entered
; a critical region. For preemptions (called from an ISR), the
; ISR will have disabled interrupts on entry.
;
; @param[in] old_tcb_ptr Pointer to the thread being scheduled out
; @param[in] new_tcb_ptr Pointer to the thread being scheduled in
;
; @return None
;
; void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr)
_archContextSwitch:
; Parameter locations:
; old_tcb_ptr = X register (word-width)
; new_tcb_ptr = stack (word-width)
; STM8 CPU Registers:
;
; A, X, Y: Standard working registers
; SP: Stack pointer
; PC: Program counter
; CC: Code condition register
;
;
; If this is a cooperative context switch (a thread has called us
; to schedule itself out), the Cosmic compiler will have saved any
; of the registers which it does not want us to clobber. There are
; no registers which are expected to retain their value across a
; function call, hence for cooperative context switches with this
; compiler we do not actually need to save any registers at all.
;
; If we were called from an interrupt routine (because a thread
; is being preemptively scheduled out), the situation is exactly
; the same. Any ISR which calls out to a subroutine will have
; similarly saved all registers which it needs us not to clobber
; which in the case of this compiler is all registers. Again, we
; do not need to save any registers because no registers are
; expected to be unclobbered by a subroutine.
;
; This is an unusual context switch routine, because it does not
; need to actually save any registers. Instead, the act of
; calling this function causes all registers which must not be
; clobbered to be saved on the stack anyway in the case of
; cooperative context switches. For preemptive switches, the
; interrupt service routine which calls out to here causes all
; registers to be saved in a similar fashion.
; We do have to do some work in here though: we need to store
; the current stack pointer to the current thread's TCB, and
; switch in the new thread by taking the stack pointer from
; the new thread's TCB and making that our new stack pointer.
; The parameter pointing to the the old TCB (a word-width
; pointer) is still untouched in the X register.
; Store current stack pointer as first entry in old_tcb_ptr
ldw Y, SP ; Move current stack pointer into Y register
ldw (X), Y ; Store current stack pointer at first offset in TCB
; At this point, all of the current thread's context has been saved
; so we no longer care about keeping the contents of any registers.
; We do still need the first two bytes on the current thread's stack,
; however, which contain new_tcb_ptr (a pointer to the TCB of the
; thread which we wish to switch in).
;
; Our stack frame now contains all registers (if this is a preemptive
; switch due to an interrupt handler) or those registers which the
; calling function did not wish to be clobbered (if this is a
; cooperative context switch). It also contains the return address
; which will be either a function called via an ISR (for preemptive
; switches) or a function called from thread context (for cooperative
; switches). Finally, the stack also contains the aforementioned
; word which is the new_tcb_ptr parameter passed via the stack.
;
; In addition, the thread's stack pointer (after context-save) is
; stored in the thread's TCB.
; We are now ready to restore the new thread's context. In most
; architecture ports we would typically switch our stack pointer
; to the new thread's stack pointer, and pop all of its context
; off the stack, before returning to the caller (the original
; caller when the new thread was last scheduled out). In this
; port, however, we do not need to actually restore any
; registers here because none are saved when we switch out (at
; least not by this function). We switch to the new thread's
; stack pointer and then return to the original caller, which
; will restore any registers which had to be saved.
; Get the new thread's stack pointer off the TCB (new_tcb_ptr).
; new_tcb_ptr is still stored in the previous thread's stack.
; We are free to use any registers here.
; Pull the new_tcb_ptr parameter from the stack into X register
ldw X,($3,SP)
; Pull the first entry out of new_tcb_ptr (the new thread's
; stack pointer) into X register.
ldw X,(X)
; Switch our current stack pointer to that of the new thread.
ldw SP,X
; Normally we would start restoring registers from the new
; thread's stack here, but we don't save/restore any. We're
; almost done.
; The return address on the stack will now be the new thread's return
; address - i.e. although we just entered this function from a
; function called by the old thread, now that we have restored the new
; thread's stack, we actually return from this function to wherever
; the new thread was when it was previously scheduled out. This could
; be either a regular C routine if the new thread previously scheduled
; itself out cooperatively, or it could be an ISR if this new thread was
; previously preempted (on exiting the ISR, execution will return to
; wherever the new thread was originally interrupted).
; Return to the caller. Note that we always use a regular RET here
; because this is a subroutine regardless of whether we were called
; during an ISR or by a thread cooperatively switching out. The
; difference between RET and IRET on the STM8 architecture is that
; RET only pops the return address off the stack, while IRET also
; pops from the stack all of the CPU registers saved when the ISR
; started, including restoring the interrupt-enable bits from the CC
; register.
;
; It is important that whenever we call this function (whether from
; an ISR for preemptive switches or from thread context for
; cooperative switches) interrupts are always disabled. This means
; that whichever method by which we leave this routine we always
; have to reenable interrupts, so we can use the same context-switch
; routine for preemptive and cooperative switches.
;
; The possible call/return paths are as follows:
;
; Scenario 1 (cooperative -> cooperative):
; Thread A: cooperatively switches out
; * Thread A relinquishes control / cooperatively switches out
; * Interrupts already disabled by kernel for cooperative reschedules
; * Partial register context saved by calling function
; * Call here at thread context
; * Switch to Thread B
; Thread B (was previously cooperatively switched out):
; * Stack context for Thread B contains its return address
; * Return to function which was called at thread context
; * Interrupts are reenabled by CRITICAL_END() call in kernel
; * Return to Thread B application code
;
; Scenario 2 (preemptive -> preemptive):
; Thread A: preemptively switches out
; * ISR occurs
; * Interrupts disabled by CPU at ISR entry (assume no nesting allowed)
; * Full register context saved by CPU at ISR entry
; * Call here at ISR context
; * Switch to Thread B
; Thread B (was previously preemptively switched out):
; * Stack context for Thread B contains its return address
; and all context saved by the CPU on ISR entry
; * Return to function which was called at ISR context
; * Eventually returns to calling ISR which calls IRET
; * IRET performs full register context restore
; * IRET reenables interrupts
; * Return to Thread B application code
;
; Scenario 3 (cooperative -> preemptive):
; Thread A: cooperatively switches out
; * Thread A relinquishes control / cooperatively switches out
; * Interrupts already disabled by kernel for cooperative reschedules
; * Partial register context saved by calling function
; * Call here at thread context
; * Switch to Thread B
; Thread B (was previously preemptively switched out):
; * Stack context for Thread B contains its return address
; and all context saved by the CPU on ISR entry
; * Return to function which was called at ISR context
; * Eventually returns to calling ISR which calls IRET
; * IRET performs full register context restore
; * IRET reenables interrupts
; * Return to Thread B application code
;
; Scenario 4 (preemptive -> cooperative):
; Thread A: preemptively switches out
; * ISR occurs
; * Interrupts disabled by CPU at ISR entry (assume no nesting allowed)
; * Full register context saved by CPU at ISR entry
; * Call here at ISR context
; * Switch to Thread B
; Thread B (was previously cooperatively switched out):
; * Stack context for Thread B contains its return address
; * Return to function which was called at thread context
; * Interrupts are reenabled by CRITICAL_END() call in kernel
; * Return to Thread B application code
;
; The above shows that it does not matter whether we are rescheduling
; from/to thread context or ISR context. It is perfectly valid to
; enter here at ISR context but leave via a thread which previously
; cooperatively switched out because:
; 1. Although the CPU handles ISRs differently by automatically
; stacking all 6 CPU registers, and restoring them on an IRET,
; we handle this because we switch the stack pointer to a
; different thread's stack. Because the stack pointer is
; switched, it does not matter that on entry via ISRs more
; registers are saved on the original thread's stack than entries
; via non-ISRs. Those extra registers will be restored properly
; by an IRET when the thread is eventually scheduled back in
; (which could be a long way off). This assumes that the CPU does
; not have hidden behaviour that occurs on interrupts, and we can
; in fact trick it into leaving via another thread's call stack,
; and performing the IRET much later.
; 2. Although the CPU handles ISRs differently by setting the CC
; register interrupt-enable bits on entry/exit, we handle this
; anyway by always assuming interrupts are disabled on entry
; and exit regardless of the call path.
; Return from subroutine
ret
; \b archFirstThreadRestore
;
; Architecture-specific function to restore and start the first thread.
; This is called by atomOSStart() when the OS is starting. Its job is to
; restore the context for the first thread and start running at its
; entry point.
;
; All new threads have a stack context pre-initialised with suitable
; data for being restored by either this function or the normal
; function used for scheduling threads in, archContextSwitch(). Only
; the first thread run by the system is launched via this function,
; after which all other new threads will first be run by
; archContextSwitch().
;
; Typically ports will implement something similar here to the
; latter half of archContextSwitch(). In this port the context
; switch does not restore many registers, and instead relies on the
; fact that returning from any function which called
; archContextSwitch() will restore any of the necessary registers.
; For new threads which have never been run there is no calling
; function which will restore context on return, therefore we
; do not restore many register values here. It is not necessary
; for the new threads to have initialised values for the scratch
; registers A, X and Y or the code condition register CC which
; leaves SP and PC. SP is restored because this is always needed to
; switch to a new thread's stack context. It is not necessary to
; restore PC, because the thread's entry point is in the stack
; context (when this function returns using RET the PC is
; automatically changed to the thread's entry point because the
; entry point is stored in the preinitialised stack).
;
; When new threads are started interrupts must be enabled, so there
; is some scope for enabling interrupts in the CC here. It must be
; done for all new threads, however, not just the first thread, so
; we use a different system. We instead use a thread shell routine
; which all functions run when they are first started, and
; interrupts are enabled in there. This allows us to avoid having
; to enable interrupts both in here and in the normal context
; switch routine (archContextSwitch()). For the normal context
; switch routine we would otherwise need to pass in notification of
; and implement special handling for the first time a thread is
; restored.
;
; In summary, first threads do not require a set of CPU registers
; to be initialised to known values, so we only set SP to the new
; thread's stack pointer. PC is restored for free because the RET
; call at the end of this function pops the return address off the
; stack.
;
; Note that you can create more than one thread before starting
; the OS - only one thread is restored using this function, so
; all other threads are actually restored by archContextSwitch().
; This is another reminder that the initial context set up by
; archThreadContextInit() must look the same whether restored by
; archFirstThreadRestore() or archContextSwitch().
;
; @param[in] new_tcb_ptr Pointer to the thread being scheduled in
;
; @return None
;
; void archFirstThreadRestore (ATOM_TCB *new_tcb_ptr)
_archFirstThreadRestore:
; Parameter locations:
; new_tcb_ptr = X register (word-width)
; As described above, first thread restores in this port do not
; expect any initial register context to be pre-initialised in
; the thread's stack area. The thread's initial stack need only
; contain the thread's initial entry point, and we do not even
; "restore" that within this function. We leave the thread's entry
; point in the stack, and RET at the end of the function pops it
; off and "returns" to the entry point as if we were called from
; there.
;
; The one thing we do need to set in here, though, is the thread's
; stack pointer. This is available from the passed thread TCB
; structure.
; Get the new thread's stack pointer off the TCB (new_tcb_ptr).
; new_tcb_ptr is stored in the parameter register X. The stack
; pointer it conveniently located at the top of the TCB so no
; indexing is required to pull it out.
ldw X,(X)
; Switch our current stack pointer to that of the new thread.
ldw SP,X
; The "return address" left on the stack now will be the new
; thread's entry point. RET will take us there as if we had
; actually been there before calling this subroutine, whereas
; the return address was actually set up by archThreadContextInit().
ret
end

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ATOM_PORT_PRIVATE_H
#define __ATOM_PORT_PRIVATE_H
/* Function prototypes */
void archInitSystemTickTimer (void);
@far @interrupt void TIM1_SystemTickISR (void);
#endif /* __ATOM_PORT_PRIVATE_H */

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ATOM_PORT_TESTS_H
#define __ATOM_PORT_TESTS_H
/* Include Atomthreads kernel API */
#include "atom.h"
/* Logger macro for viewing test results (UART not used on this platform) */
#define ATOMLOG
/*
* String location macro: for platforms which need to place strings in
* alternative locations. Not used on this platform.
*/
#define _STR
/* Default thread stack size (in bytes) */
#define TEST_THREAD_STACK_SIZE 196
#endif /* __ATOM_PORT_TESTS_H */

259
ports/stm8/atomport.c Normal file
View File

@@ -0,0 +1,259 @@
/*
* Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "atom.h"
#include "atomport-private.h"
#include "stm8s_tim1.h"
/** Forward declarations */
static void thread_shell (void);
/**
* \b thread_shell
*
* Shell routine which is used to call all thread entry points.
*
* This routine is called whenever a new thread is starting, and is
* responsible for taking the entry point parameter off the TCB
* and passing this into the thread entry point, as well as enabling
* interrupts.
*
* This is an optional function for a port, because interrupts could
* be enabled by the first-thread and normal context restore routines,
* but that would require special handling in the normal context
* switch routine (archContextSwitch()) that is only needed the first
* time a thread is started. A much neater method is to direct all
* threads through this shell routine first, so that interrupts will
* always be enabled at thread startup, and no special first-time-run
* handling is required in the context restore routines (i.e. we
* don't affect normal context switch times just for the benefit of
* the first time a thread is restored by adding extra complication
* to the thread restore routines).
*
* Other ports are free to implement whatever scheme they wish. In
* particular if you save all necessary registers (including the
* interrupt enable register) on a context switch then you need not
* worry about any special requirements for starting threads for the
* first time because you can preinitialise the stack context with
* a suitable register value that will enable interrupts.
*
* @return None
*/
static void thread_shell (void)
{
ATOM_TCB *curr_tcb;
/* Get the TCB of the thread being started */
curr_tcb = atomCurrentContext();
/**
* Enable interrupts - these will not be enabled when a thread
* is first restored.
*/
_asm("rim");
/* Call the thread entry point */
if (curr_tcb && curr_tcb->entry_point)
{
curr_tcb->entry_point(curr_tcb->entry_param);
}
/* Not reached - threads should never return from the entry point */
}
/**
* \b archThreadContextInit
*
* Architecture-specific thread context initialisation routine.
*
* This function must set up a thread's context ready for restoring
* and running the thread via archFirstThreadRestore() or
* archContextSwitch().
*
* On this port we take advantage of the fact that when the context
* switch routine is called the compiler will automatically stack
* all registers which should not be clobbered. This means that the
* context switch need only save and restore the stack pointer,
* which is stored in the thread's TCB. Because of this, it is not
* necessary to prefill a new thread's stack with any register
* values here. The only entry we need to make in the stack is the
* thread's entry point - this is not exactly restored when the
* the thread is context switched in, but rather is popped off the
* stack by the context switch routine's RET call. That is used to
* direct the program counter to our thread's entry point - we are
* faking a return to a caller which never actually existed.
*
* We could pre-initialise the stack so that the RET call goes
* directly to the thread entry point, with the thread entry
* parameter filled in. On this architecture, however, we use an
* outer thread shell routine which is used to call all threads.
* The thread entry point and parameter are stored in the thread's
* TCB which the thread shell uses to make the actual call to the
* entry point. We don't therefore need to store the actual thread
* entry and parameter within the stack.
*
* Note that interrupts must be enabled the first time a thread is
* run. On some architectures this might be done by setting an
* initial value for the interrupt-enable register within the stack
* area. In this port, however, we use the thread shell to enable
* interrupts at the start of any thread.
*
* @param[in] tcb_ptr Pointer to the TCB of the thread being created
* @param[in] stack_top Pointer to the top of the new thread's stack
* @param[in] entry_point Pointer to the thread entry point function
* @param[in] entry_param Parameter to be passed to the thread entry point
*
* @return None
*/
void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(uint32_t), uint32_t entry_param)
{
uint8_t *stack_ptr;
/** Start at stack top */
stack_ptr = (uint8_t *)stack_top;
/**
* The thread restore routines will perform a RET which expects to
* find the address of the calling routine on the stack. In this case
* (the first time a thread is run) we "return" to the entry point for
* the thread. That is, we store the thread entry point in the
* place that RET will look for the return address: the stack.
*
* Note that we are using the thread_shell() routine to start all
* threads, so we actually store the address of thread_shell()
* here. Other ports may store the real thread entry point here
* and call it directly from the thread restore routines.
*
* Because we are filling the stack from top to bottom, this goes
* on the stack first (at the top).
*/
*stack_ptr-- = (uint8_t)((uint16_t)thread_shell & 0xFF);
*stack_ptr-- = (uint8_t)(((uint16_t)thread_shell >> 8) & 0xFF);
/**
* Because we are using a thread shell which is responsible for
* calling the real entry point, it also passes the parameters
* to entry point and we need not stack the entry parameter here.
*
* Other ports may wish to store entry_param in the appropriate
* parameter registers when creating a thread's context,
* particularly if that port saves those registers anyway.
*/
/**
* In this port we do not initialise any registers via the initial
* stack context at all. All thread context has now been
* initialised. All that is left is to save the current stack
* pointer to the thread's TCB so that it knows where to start
* looking when the thread is started.
*/
tcb_ptr->sp_save_ptr = stack_ptr;
}
/**
* \b archInitSystemTickTimer
*
* Initialise the system tick timer. Uses the STM8's TIM1 facility.
*
* @return None
*/
void archInitSystemTickTimer ( void )
{
/* Reset TIM1 */
TIM1_DeInit();
/* Configure a 10ms tick */
TIM1_TimeBaseInit(10000, TIM1_COUNTERMODE_UP, 1, 0);
/* Generate an interrupt on timer count overflow */
TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
/* Enable TIM1 */
TIM1_Cmd(ENABLE);
}
/**
*
* System tick ISR.
*
* This is responsible for regularly calling the OS system tick handler.
* The system tick handler checks if any timer callbacks are necessary,
* and runs the scheduler.
*
* The CPU automatically saves all registers before calling out to an
* interrupt handler like this.
*
* The system may decide to schedule in a new thread during the call to
* atomTimerTick(), in which case the program counter will be redirected
* to the new thread's running location during atomIntExit(). This ISR
* function will not actually complete until the thread we interrupted is
* scheduled back in, at which point the end of this function will be
* reached (after atomIntExit()) and the IRET call by the compiler will
* return us to the interrupted thread as if we hadn't run any other
* thread in the meantime. In other words the interrupted thread can be
* scheduled out by atomIntExit() and several threads could run before we
* actually reach the end of this function. When this function does
* finally complete, the return address (the PC of the thread which was
* interrupted) will be on the interrupted thread's stack because it was
* saved on there by the CPU when the interrupt triggered.
*
* As with all interrupts, the ISR should call atomIntEnter() and
* atomIntExit() on entry and exit. This serves two purposes:
*
* a) To notify the OS that it is running in interrupt context
* b) To defer the scheduler until after the ISR is completed
*
* We defer all scheduling decisions until after the ISR has completed
* in case the interrupt handler makes more than one thread ready.
*
* @return None
*/
void TIM1_SystemTickISR (void)
{
/* Call the interrupt entry routine */
atomIntEnter();
/* Call the OS system tick handler */
atomTimerTick();
/* Ack the interrupt */
TIM1_ClearITPendingBit(TIM1_IT_UPDATE);
/* Call the interrupt exit routine */
atomIntExit(TRUE);
}

59
ports/stm8/atomport.h Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ATOM_PORT_H
#define __ATOM_PORT_H
#include "stm8s_type.h"
/* Required number of system ticks per second (normally 100 for 10ms tick) */
#define SYSTEM_TICKS_PER_SEC 100
/**
* Architecture-specific types.
*/
#define int8_t s8
#define int16_t s16
#define int32_t s32
#define uint8_t u8
#define uint16_t u16
#define uint32_t u32
#define POINTER void *
/* Critical region protection */
#define CRITICAL_STORE uint8_t ccr
#define CRITICAL_START() _asm ("push CC\npop a\nld (X),A\nsim", &ccr)
#define CRITICAL_END() _asm ("ld A,(X)\npush A\npop CC", &ccr)
#endif /* __ATOM_PORT_H */

View File

@@ -0,0 +1,63 @@
# Segment configuration
#<BEGIN SEGMENT_CONF>
# Segment Code,Constants:
+seg .const -b 0x8080 -m 0x7f80 -n .const -it
+seg .text -a .const -n .text
# Segment Eeprom:
+seg .eeprom -b 0x4000 -m 0x400 -n .eeprom
# Segment Zero Page (this deliberately avoids 0x0 to avoid
# NULL pointers to real data):
+seg .bsct -b 0x2 -m 0xfe -n .bsct
+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
+seg .bss -a .data -n .bss
#<END SEGMENT_CONF>
# Startup file
#<BEGIN STARTUP_FILE>
crtsi0.sm8
#<END STARTUP_FILE>
# Object files list - section reserved for STVD
#<BEGIN OBJECT_FILES>
build\atomkernel.o
build\atommutex.o
build\atomqueue.o
build\atomsem.o
build\atomtimer.o
build\stm8s_gpio.o
build\stm8s_tim1.o
build\tests-main.o
build\atomport.o
build\atomport-asm.o
# Caller passes in test application object name as param1
@1
#<END OBJECT_FILES>
# Library list
#<BEGIN LIBRARY_FILES>
libis0.sm8
libm0.sm8
#<END LIBRARY_FILES>
# Interrupt vectors file
#<BEGIN VECTOR_FILE>
+seg .const -b 0x8000 -k
build/stm8_interrupt_vector.o
#<END VECTOR_FILE>
# Defines
#<BEGIN DEFINED_VARIABLES>
+def __endzp=@.ubsct # end of uninitialized zpage
+def __memory=@.bss # end of bss segment
+def __startmem=@.bss
+def __endmem=0x5ff
+def __stack=0x7ff
#<END DEFINED_VARIABLES>

View File

@@ -0,0 +1,60 @@
/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices
* Copyright (c) 2007 STMicroelectronics
*/
/* Import Atomthreads system tick ISR prototype */
#include "atomport-private.h"
typedef void @far (*interrupt_handler_t)(void);
struct interrupt_vector {
unsigned char interrupt_instruction;
interrupt_handler_t interrupt_handler;
};
@far @interrupt void NonHandledInterrupt (void)
{
/* in order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction
*/
return;
}
extern void _stext(); /* startup routine */
struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)_stext}, /* reset */
{0x82, NonHandledInterrupt}, /* trap */
{0x82, NonHandledInterrupt}, /* irq0 */
{0x82, NonHandledInterrupt}, /* irq1 */
{0x82, NonHandledInterrupt}, /* irq2 */
{0x82, NonHandledInterrupt}, /* irq3 */
{0x82, NonHandledInterrupt}, /* irq4 */
{0x82, NonHandledInterrupt}, /* irq5 */
{0x82, NonHandledInterrupt}, /* irq6 */
{0x82, NonHandledInterrupt}, /* irq7 */
{0x82, NonHandledInterrupt}, /* irq8 */
{0x82, NonHandledInterrupt}, /* irq9 */
{0x82, NonHandledInterrupt}, /* irq10 */
{0x82, (interrupt_handler_t)TIM1_SystemTickISR}, /* irq11 */
{0x82, NonHandledInterrupt}, /* irq12 */
{0x82, NonHandledInterrupt}, /* irq13 */
{0x82, NonHandledInterrupt}, /* irq14 */
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, NonHandledInterrupt}, /* irq17 */
{0x82, NonHandledInterrupt}, /* irq18 */
{0x82, NonHandledInterrupt}, /* irq19 */
{0x82, NonHandledInterrupt}, /* irq20 */
{0x82, NonHandledInterrupt}, /* irq21 */
{0x82, NonHandledInterrupt}, /* irq22 */
{0x82, NonHandledInterrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,404 @@
/**
******************************************************************************
* @file stm8s_clk.h
* @brief This file contains all functions prototype and macros 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
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM8S_CLK_H
#define __STM8S_CLK_H
/* Includes ------------------------------------------------------------------*/
/* Contains the description of all STM8 hardware registers */
#include "stm8s.h"
/* Exported types ------------------------------------------------------------*/
/** @addtogroup CLK_Exported_Types
* @{
*/
/**
* @brief Switch Mode Auto, Manual.
*/
typedef enum {
CLK_SWITCHMODE_MANUAL = (u8)0x00, /*!< Enable the manual clock switching mode */
CLK_SWITCHMODE_AUTO = (u8)0x01 /*!< Enable the automatic clock switching mode */
} CLK_SwitchMode_TypeDef;
/**
* @brief Current Clock State.
*/
typedef enum {
CLK_CURRENTCLOCKSTATE_DISABLE = (u8)0x00, /*!< Current clock disable */
CLK_CURRENTCLOCKSTATE_ENABLE = (u8)0x01 /*!< Current clock enable */
} CLK_CurrentClockState_TypeDef;
/**
* @brief Clock security system configuration.
*/
typedef enum {
CLK_CSSCONFIG_ENABLEWITHIT = (u8)0x05, /*!< Enable CSS with detection interrupt */
CLK_CSSCONFIG_ENABLE = (u8)0x01, /*!< Enable CSS without detection interrupt */
CLK_CSSCONFIG_DISABLE = (u8)0x00 /*!< Leave CSS desactivated (to be used in CLK_Init() function) */
} CLK_CSSConfig_TypeDef;
/**
* @brief CLK Clock Source.
*/
typedef enum {
CLK_SOURCE_HSI = (u8)0xE1, /*!< Clock Source HSI. */
CLK_SOURCE_LSI = (u8)0xD2, /*!< Clock Source LSI. */
CLK_SOURCE_HSE = (u8)0xB4 /*!< Clock Source HSE. */
} CLK_Source_TypeDef;
/**
* @brief CLK HSI Calibration Value.
*/
typedef enum {
CLK_HSITRIMVALUE_0 = (u8)0x00, /*!< HSI Calibtation Value 0 */
CLK_HSITRIMVALUE_1 = (u8)0x01, /*!< HSI Calibtation Value 1 */
CLK_HSITRIMVALUE_2 = (u8)0x02, /*!< HSI Calibtation Value 2 */
CLK_HSITRIMVALUE_3 = (u8)0x03, /*!< HSI Calibtation Value 3 */
CLK_HSITRIMVALUE_4 = (u8)0x04, /*!< HSI Calibtation Value 4 */
CLK_HSITRIMVALUE_5 = (u8)0x05, /*!< HSI Calibtation Value 5 */
CLK_HSITRIMVALUE_6 = (u8)0x06, /*!< HSI Calibtation Value 6 */
CLK_HSITRIMVALUE_7 = (u8)0x07 /*!< HSI Calibtation Value 7 */
} CLK_HSITrimValue_TypeDef;
/**
* @brief CLK Clock Output
*/
typedef enum {
CLK_OUTPUT_HSI = (u8)0x00, /*!< Clock Output HSI */
CLK_OUTPUT_LSI = (u8)0x02, /*!< Clock Output LSI */
CLK_OUTPUT_HSE = (u8)0x04, /*!< Clock Output HSE */
CLK_OUTPUT_CPU = (u8)0x08, /*!< Clock Output CPU */
CLK_OUTPUT_CPUDIV2 = (u8)0x0A, /*!< Clock Output CPU/2 */
CLK_OUTPUT_CPUDIV4 = (u8)0x0C, /*!< Clock Output CPU/4 */
CLK_OUTPUT_CPUDIV8 = (u8)0x0E, /*!< Clock Output CPU/8 */
CLK_OUTPUT_CPUDIV16 = (u8)0x10, /*!< Clock Output CPU/16 */
CLK_OUTPUT_CPUDIV32 = (u8)0x12, /*!< Clock Output CPU/32 */
CLK_OUTPUT_CPUDIV64 = (u8)0x14, /*!< Clock Output CPU/64 */
CLK_OUTPUT_HSIRC = (u8)0x16, /*!< Clock Output HSI RC */
CLK_OUTPUT_MASTER = (u8)0x18, /*!< Clock Output Master */
CLK_OUTPUT_OTHERS = (u8)0x1A /*!< Clock Output OTHER */
} CLK_Output_TypeDef;
/**
* @brief CLK Enable peripheral
*/
/* Elements values convention: 0xXY
X = choice between the peripheral registers
X = 0 : PCKENR1
X = 1 : PCKENR2
Y = Peripheral position in the register
*/
typedef enum {
CLK_PERIPHERAL_I2C = (u8)0x00, /*!< Peripheral Clock Enable 1, I2C */
CLK_PERIPHERAL_SPI = (u8)0x01, /*!< Peripheral Clock Enable 1, SPI */
#if defined(STM8S208) || defined(STM8S207)
CLK_PERIPHERAL_UART1 = (u8)0x02, /*!< Peripheral Clock Enable 1, UART1 */
#else
CLK_PERIPHERAL_UART1 = (u8)0x03, /*!< Peripheral Clock Enable 1, UART1 */
#endif
CLK_PERIPHERAL_UART2 = (u8)0x03, /*!< Peripheral Clock Enable 1, UART2 */
CLK_PERIPHERAL_UART3 = (u8)0x03, /*!< Peripheral Clock Enable 1, UART3 */
CLK_PERIPHERAL_TIMER6 = (u8)0x04, /*!< Peripheral Clock Enable 1, Timer6 */
CLK_PERIPHERAL_TIMER4 = (u8)0x04, /*!< Peripheral Clock Enable 1, Timer4 */
CLK_PERIPHERAL_TIMER5 = (u8)0x05, /*!< Peripheral Clock Enable 1, Timer5 */
CLK_PERIPHERAL_TIMER2 = (u8)0x05, /*!< Peripheral Clock Enable 1, Timer2 */
CLK_PERIPHERAL_TIMER3 = (u8)0x06, /*!< Peripheral Clock Enable 1, Timer3 */
CLK_PERIPHERAL_TIMER1 = (u8)0x07, /*!< Peripheral Clock Enable 1, Timer1 */
CLK_PERIPHERAL_AWU = (u8)0x12, /*!< Peripheral Clock Enable 2, AWU */
CLK_PERIPHERAL_ADC = (u8)0x13, /*!< Peripheral Clock Enable 2, ADC */
CLK_PERIPHERAL_CAN = (u8)0x17 /*!< Peripheral Clock Enable 2, CAN */
} CLK_Peripheral_TypeDef;
/**
* @brief CLK Flags.
*/
/* Elements values convention: 0xXZZ
X = choice between the flags registers
X = 1 : ICKR
X = 2 : ECKR
X = 3 : SWCR
X = 4 : CSSR
X = 5 : CCOR
ZZ = flag mask in the register (same as map file)
*/
typedef enum {
CLK_FLAG_LSIRDY = (u16)0x0110, /*!< Low speed internal oscillator ready Flag */
CLK_FLAG_HSIRDY = (u16)0x0102, /*!< High speed internal oscillator ready Flag */
CLK_FLAG_HSERDY = (u16)0x0202, /*!< High speed external oscillator ready Flag */
CLK_FLAG_SWIF = (u16)0x0308, /*!< Clock switch interrupt Flag */
CLK_FLAG_SWBSY = (u16)0x0301, /*!< Switch busy Flag */
CLK_FLAG_CSSD = (u16)0x0408, /*!< Clock security system detection Flag */
CLK_FLAG_AUX = (u16)0x0402, /*!< Auxiliary oscillator connected to master clock */
CLK_FLAG_CCOBSY = (u16)0x0504, /*!< Configurable clock output busy */
CLK_FLAG_CCORDY = (u16)0x0502 /*!< Configurable clock output ready */
}CLK_Flag_TypeDef;
/**
* @brief CLK interrupt configuration and Flags cleared by software.
*/
typedef enum {
CLK_IT_CSSD = (u8)0x0C, /*!< Clock security system detection Flag */
CLK_IT_SWIF = (u8)0x1C /*!< Clock switch interrupt Flag */
}CLK_IT_TypeDef;
/**
* @brief CLK Clock Divisor.
*/
/* Warning:
0xxxxxx = HSI divider
1xxxxxx = CPU divider
Other bits correspond to the divider's bits mapping
*/
typedef enum {
CLK_PRESCALER_HSIDIV1 = (u8)0x00, /*!< High speed internal clock prescaler: 1 */
CLK_PRESCALER_HSIDIV2 = (u8)0x08, /*!< High speed internal clock prescaler: 2 */
CLK_PRESCALER_HSIDIV4 = (u8)0x10, /*!< High speed internal clock prescaler: 4 */
CLK_PRESCALER_HSIDIV8 = (u8)0x18, /*!< High speed internal clock prescaler: 8 */
CLK_PRESCALER_CPUDIV1 = (u8)0x80, /*!< CPU clock division factors 1 */
CLK_PRESCALER_CPUDIV2 = (u8)0x81, /*!< CPU clock division factors 2 */
CLK_PRESCALER_CPUDIV4 = (u8)0x82, /*!< CPU clock division factors 4 */
CLK_PRESCALER_CPUDIV8 = (u8)0x83, /*!< CPU clock division factors 8 */
CLK_PRESCALER_CPUDIV16 = (u8)0x84, /*!< CPU clock division factors 16 */
CLK_PRESCALER_CPUDIV32 = (u8)0x85, /*!< CPU clock division factors 32 */
CLK_PRESCALER_CPUDIV64 = (u8)0x86, /*!< CPU clock division factors 64 */
CLK_PRESCALER_CPUDIV128 = (u8)0x87 /*!< CPU clock division factors 128 */
} CLK_Prescaler_TypeDef;
/**
* @brief SWIM Clock divider.
*/
typedef enum {
CLK_SWIMDIVIDER_2 = (u8)0x00, /*!< SWIM clock is divided by 2 */
CLK_SWIMDIVIDER_OTHER = (u8)0x01 /*!< SWIM clock is not divided by 2 */
}CLK_SWIMDivider_TypeDef;
/**
* @brief External CAN clock dividern.
*/
typedef enum{
CLK_CANDIVIDER_1 = (u8)0x00, /*!< External CAN clock = HSE/1 */
CLK_CANDIVIDER_2 = (u8)0x01, /*!< External CAN clock = HSE/2 */
CLK_CANDIVIDER_3 = (u8)0x02, /*!< External CAN clock = HSE/3 */
CLK_CANDIVIDER_4 = (u8)0x03, /*!< External CAN clock = HSE/4 */
CLK_CANDIVIDER_5 = (u8)0x04, /*!< External CAN clock = HSE/5 */
CLK_CANDIVIDER_6 = (u8)0x05, /*!< External CAN clock = HSE/6 */
CLK_CANDIVIDER_7 = (u8)0x06, /*!< External CAN clock = HSE/7 */
CLK_CANDIVIDER_8 = (u8)0x07 /*!< External CAN clock = HSE/8 */
}CLK_CANDivider_TypeDef;
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/** @addtogroup CLK_Exported_Constants
* @{
*/
#define HSI_VALUE ((u32)16000000) /*!< Typical Value of the HSI in Hz */
#define LSI_VALUE ((u32)128000) /*!< Typical Value of the LSI in Hz */
#define CLK_TIMEOUT ((u16)0x491) /*!< Timeout for the clock switch operation. */
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/** @addtogroup CLK_Private_Macros
* @{
*/
/**
* @brief Macros used by the assert function in order to check the different functions parameters.
*/
/**
* @brief Macros used by the assert function in order to check the clock switching modes.
*/
#define IS_CLK_SWITCHMODE_OK(MODE) (((MODE) == CLK_SWITCHMODE_MANUAL) || ((MODE) == CLK_SWITCHMODE_AUTO))
/**
* @brief Macros used by the assert function in order to check the current clock state.
*/
#define IS_CLK_CURRENTCLOCKSTATE_OK(STATE) (((STATE) == CLK_CURRENTCLOCKSTATE_DISABLE) || ((STATE) == CLK_CURRENTCLOCKSTATE_ENABLE))
/**
* @brief Macros used by the assert function in order to check the CSS configuration.
*/
#define IS_CLK_CSSCONFIG_OK(CSSVALUE) (((CSSVALUE) == CLK_CSSCONFIG_ENABLEWITHIT) ||\
((CSSVALUE) == CLK_CSSCONFIG_ENABLE) ||\
((CSSVALUE) == CLK_CSSCONFIG_DISABLE))
/**
* @brief Macros used by the assert function in order to check the different clock sources.
*/
#define IS_CLK_SOURCE_OK(SOURCE) (((SOURCE) == CLK_SOURCE_HSI) ||\
((SOURCE) == CLK_SOURCE_LSI) ||\
((SOURCE) == CLK_SOURCE_HSE))
/**
* @brief Macros used by the assert function in order to check the different HSI trimming values.
*/
#define IS_CLK_HSITRIMVALUE_OK(TRIMVALUE) (((TRIMVALUE) == CLK_HSITRIMVALUE_0) ||\
((TRIMVALUE) == CLK_HSITRIMVALUE_1) ||\
((TRIMVALUE) == CLK_HSITRIMVALUE_2) ||\
((TRIMVALUE) == CLK_HSITRIMVALUE_3) ||\
((TRIMVALUE) == CLK_HSITRIMVALUE_4) ||\
((TRIMVALUE) == CLK_HSITRIMVALUE_5) ||\
((TRIMVALUE) == CLK_HSITRIMVALUE_6) ||\
((TRIMVALUE) == CLK_HSITRIMVALUE_7))
/**
* @brief Macros used by the assert function in order to check the different clocks to output.
*/
#define IS_CLK_OUTPUT_OK(OUTPUT) (((OUTPUT) == CLK_OUTPUT_HSI) ||\
((OUTPUT) == CLK_OUTPUT_HSE) ||\
((OUTPUT) == CLK_OUTPUT_LSI) ||\
((OUTPUT) == CLK_OUTPUT_CPU) ||\
((OUTPUT) == CLK_OUTPUT_CPUDIV2) ||\
((OUTPUT) == CLK_OUTPUT_CPUDIV4) ||\
((OUTPUT) == CLK_OUTPUT_CPUDIV8) ||\
((OUTPUT) == CLK_OUTPUT_CPUDIV16) ||\
((OUTPUT) == CLK_OUTPUT_CPUDIV32) ||\
((OUTPUT) == CLK_OUTPUT_CPUDIV64) ||\
((OUTPUT) == CLK_OUTPUT_HSIRC) ||\
((OUTPUT) == CLK_OUTPUT_MASTER) ||\
((OUTPUT) == CLK_OUTPUT_OTHERS))
/**
* @brief Macros used by the assert function in order to check the different peripheral's clock.
*/
#define IS_CLK_PERIPHERAL_OK(PERIPHERAL) (((PERIPHERAL) == CLK_PERIPHERAL_I2C) ||\
((PERIPHERAL) == CLK_PERIPHERAL_SPI) ||\
((PERIPHERAL) == CLK_PERIPHERAL_UART3) ||\
((PERIPHERAL) == CLK_PERIPHERAL_UART2) ||\
((PERIPHERAL) == CLK_PERIPHERAL_UART1) ||\
((PERIPHERAL) == CLK_PERIPHERAL_TIMER4) ||\
((PERIPHERAL) == CLK_PERIPHERAL_TIMER2) ||\
((PERIPHERAL) == CLK_PERIPHERAL_TIMER5) ||\
((PERIPHERAL) == CLK_PERIPHERAL_TIMER6) ||\
((PERIPHERAL) == CLK_PERIPHERAL_TIMER3) ||\
((PERIPHERAL) == CLK_PERIPHERAL_TIMER1) ||\
((PERIPHERAL) == CLK_PERIPHERAL_CAN) ||\
((PERIPHERAL) == CLK_PERIPHERAL_ADC) ||\
((PERIPHERAL) == CLK_PERIPHERAL_AWU))
/**
* @brief Macros used by the assert function in order to check the different clock flags.
*/
#define IS_CLK_FLAG_OK(FLAG) (((FLAG) == CLK_FLAG_LSIRDY) ||\
((FLAG) == CLK_FLAG_HSIRDY) ||\
((FLAG) == CLK_FLAG_HSERDY) ||\
((FLAG) == CLK_FLAG_SWIF) ||\
((FLAG) == CLK_FLAG_SWBSY) ||\
((FLAG) == CLK_FLAG_CSSD) ||\
((FLAG) == CLK_FLAG_AUX) ||\
((FLAG) == CLK_FLAG_CCOBSY) ||\
((FLAG) == CLK_FLAG_CCORDY))
/**
* @brief Macros used by the assert function in order to check the different clock IT pending bits.
*/
#define IS_CLK_IT_OK(IT) (((IT) == CLK_IT_CSSD) || ((IT) == CLK_IT_SWIF))
/**
* @brief Macros used by the assert function in order to check the different HSI prescaler values.
*/
#define IS_CLK_HSIPRESCALER_OK(PRESCALER) (((PRESCALER) == CLK_PRESCALER_HSIDIV1) ||\
((PRESCALER) == CLK_PRESCALER_HSIDIV2) ||\
((PRESCALER) == CLK_PRESCALER_HSIDIV4) ||\
((PRESCALER) == CLK_PRESCALER_HSIDIV8))
/**
* @brief Macros used by the assert function in order to check the different clock prescaler values.
*/
#define IS_CLK_PRESCALER_OK(PRESCALER) (((PRESCALER) == CLK_PRESCALER_HSIDIV1) ||\
((PRESCALER) == CLK_PRESCALER_HSIDIV2) ||\
((PRESCALER) == CLK_PRESCALER_HSIDIV4) ||\
((PRESCALER) == CLK_PRESCALER_HSIDIV8) ||\
((PRESCALER) == CLK_PRESCALER_CPUDIV1) ||\
((PRESCALER) == CLK_PRESCALER_CPUDIV2) ||\
((PRESCALER) == CLK_PRESCALER_CPUDIV4) ||\
((PRESCALER) == CLK_PRESCALER_CPUDIV8) ||\
((PRESCALER) == CLK_PRESCALER_CPUDIV16) ||\
((PRESCALER) == CLK_PRESCALER_CPUDIV32) ||\
((PRESCALER) == CLK_PRESCALER_CPUDIV64) ||\
((PRESCALER) == CLK_PRESCALER_CPUDIV128))
/**
* @brief Macros used by the assert function in order to check the different SWIM dividers values.
*/
#define IS_CLK_SWIMDIVIDER_OK(SWIMDIVIDER) (((SWIMDIVIDER) == CLK_SWIMDIVIDER_2) || ((SWIMDIVIDER) == CLK_SWIMDIVIDER_OTHER))
/**
* @brief Macros used by the assert function in order to check the different CAN dividers values.
*/
#define IS_CLK_CANDIVIDER_OK(CANDIVIDER) (((CANDIVIDER) == CLK_CANDIVIDER_1) ||\
((CANDIVIDER) == CLK_CANDIVIDER_2) ||\
((CANDIVIDER) == CLK_CANDIVIDER_3) ||\
((CANDIVIDER) == CLK_CANDIVIDER_4) ||\
((CANDIVIDER) == CLK_CANDIVIDER_5) ||\
((CANDIVIDER) == CLK_CANDIVIDER_6) ||\
((CANDIVIDER) == CLK_CANDIVIDER_7) ||\
((CANDIVIDER) == CLK_CANDIVIDER_8))
/**
* @}
*/
/** @addtogroup CLK_Exported_functions
* @{
*/
void CLK_DeInit(void);
void CLK_HSECmd(FunctionalState NewState);
void CLK_HSICmd(FunctionalState NewState);
void CLK_LSICmd(FunctionalState NewState);
void CLK_CCOCmd(FunctionalState NewState);
void CLK_ClockSwitchCmd(FunctionalState NewState);
void CLK_FastHaltWakeUpCmd(FunctionalState NewState);
void CLK_SlowActiveHaltWakeUpCmd(FunctionalState NewState);
void CLK_PeripheralClockConfig(CLK_Peripheral_TypeDef CLK_Peripheral, FunctionalState NewState);
ErrorStatus CLK_ClockSwitchConfig(CLK_SwitchMode_TypeDef CLK_SwitchMode, CLK_Source_TypeDef CLK_NewClock, FunctionalState ITState, CLK_CurrentClockState_TypeDef CLK_CurrentClockState);
void CLK_HSIPrescalerConfig(CLK_Prescaler_TypeDef HSIPrescaler);
void CLK_CCOConfig(CLK_Output_TypeDef CLK_CCO);
void CLK_ITConfig(CLK_IT_TypeDef CLK_IT, FunctionalState NewState);
void CLK_SYSCLKConfig(CLK_Prescaler_TypeDef CLK_Prescaler);
void CLK_SWIMConfig(CLK_SWIMDivider_TypeDef CLK_SWIMDivider);
void CLK_CANConfig(CLK_CANDivider_TypeDef CLK_CANDivider);
void CLK_ClockSecuritySystemEnable(void);
void CLK_SYSCLKEmergencyClear(void);
void CLK_AdjustHSICalibrationValue(CLK_HSITrimValue_TypeDef CLK_HSICalibrationValue);
u32 CLK_GetClockFreq(void);
CLK_Source_TypeDef CLK_GetSYSCLKSource(void);
FlagStatus CLK_GetFlagStatus(CLK_Flag_TypeDef CLK_FLAG);
ITStatus CLK_GetITStatus(CLK_IT_TypeDef CLK_IT);
void CLK_ClearITPendingBit(CLK_IT_TypeDef CLK_IT);
/**
* @}
*/
#endif /* __STM8S_CLK_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,242 @@
/**
******************************************************************************
* @file stm8s_gpio.c
* @brief This file contains all the functions for the GPIO 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_gpio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/
/**
* @addtogroup GPIO_Public_Functions
* @{
*/
/**
* @brief Deinitializes the GPIOx peripheral registers to their default reset
* values.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @retval None
*/
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
{
GPIOx->ODR = GPIO_ODR_RESET_VALUE; /* Reset Output Data Register */
GPIOx->DDR = GPIO_DDR_RESET_VALUE; /* Reset Data Direction Register */
GPIOx->CR1 = GPIO_CR1_RESET_VALUE; /* Reset Control Register 1 */
GPIOx->CR2 = GPIO_CR2_RESET_VALUE; /* Reset Control Register 2 */
}
/**
* @brief Initializes the GPIOx according to the specified parameters.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @param[in] GPIO_Pin : This parameter contains the pin number, it can be one or many members
* of the @ref GPIO_Pin_TypeDef enumeration.
* @param[in] GPIO_Mode : This parameter can be any of the @Ref GPIO_Mode_TypeDef enumeration.
* @retval None
*/
void GPIO_Init(GPIO_TypeDef* GPIOx,
GPIO_Pin_TypeDef GPIO_Pin,
GPIO_Mode_TypeDef GPIO_Mode)
{
/*----------------------*/
/* Check the parameters */
/*----------------------*/
assert_param(IS_GPIO_MODE_OK(GPIO_Mode));
assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
/*-----------------------------*/
/* Input/Output mode selection */
/*-----------------------------*/
if ((((u8)(GPIO_Mode)) & (u8)0x80) != (u8)0x00) /* Output mode */
{
if ((((u8)(GPIO_Mode)) & (u8)0x10) != (u8)0x00) /* High level */
{
GPIOx->ODR |= (u8)GPIO_Pin;
} else /* Low level */
{
GPIOx->ODR &= (u8)(~(GPIO_Pin));
}
/* Set Output mode */
GPIOx->DDR |= (u8)GPIO_Pin;
} else /* Input mode */
{
/* Set Input mode */
GPIOx->DDR &= (u8)(~(GPIO_Pin));
}
/*------------------------------------------------------------------------*/
/* Pull-Up/Float (Input) or Push-Pull/Open-Drain (Output) modes selection */
/*------------------------------------------------------------------------*/
if ((((u8)(GPIO_Mode)) & (u8)0x40) != (u8)0x00) /* Pull-Up or Push-Pull */
{
GPIOx->CR1 |= (u8)GPIO_Pin;
} else /* Float or Open-Drain */
{
GPIOx->CR1 &= (u8)(~(GPIO_Pin));
}
/*-----------------------------------------------------*/
/* Interrupt (Input) or Slope (Output) modes selection */
/*-----------------------------------------------------*/
if ((((u8)(GPIO_Mode)) & (u8)0x20) != (u8)0x00) /* Interrupt or Slow slope */
{
GPIOx->CR2 |= (u8)GPIO_Pin;
} else /* No external interrupt or No slope control */
{
GPIOx->CR2 &= (u8)(~(GPIO_Pin));
}
}
/**
* @brief Writes data to the specified GPIO data port.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @param[in] PortVal : Specifies the value to be written to the port output.
* data register.
* @retval None
* @par Required preconditions:
* The port must be configured in output mode.
*/
void GPIO_Write(GPIO_TypeDef* GPIOx, u8 PortVal)
{
GPIOx->ODR = PortVal;
}
/**
* @brief Writes high level to the specified GPIO pins.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @param[in] PortPins : Specifies the pins to be turned high to the port output.
* data register.
* @retval None
* @par Required preconditions:
* The port must be configured in output mode.
*/
void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
{
GPIOx->ODR |= (u8)PortPins;
}
/**
* @brief Writes low level to the specified GPIO pins.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @param[in] PortPins : Specifies the pins to be turned low to the port output.
* data register.
* @retval None
* @par Required preconditions:
* The port must be configured in output mode.
*/
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
{
GPIOx->ODR &= (u8)(~PortPins);
}
/**
* @brief Writes reverse level to the specified GPIO pins.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @param[in] PortPins : Specifies the pins to be reversed to the port output.
* data register.
* @retval None
* @par Required preconditions:
* The port must be configured in output mode.
*/
void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
{
GPIOx->ODR ^= (u8)PortPins;
}
/**
* @brief Reads the specified GPIO output data port.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @retval u8 : GPIO output data port value.
* @par Required preconditions:
* The port must be configured in input mode.
*/
u8 GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
{
return ((u8)GPIOx->ODR);
}
/**
* @brief Reads the specified GPIO input data port.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @retval u8 : GPIO input data port value.
* @par Required preconditions:
* The port must be configured in input mode.
*/
u8 GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
{
return ((u8)GPIOx->IDR);
}
/**
* @brief Reads the specified GPIO input data pin.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @param[in] GPIO_Pin : This parameter contains the pin number, it can be one member
* of the @ref GPIO_Pin_TypeDef enumeration.
* @retval BitStatus : GPIO input pin status.
* This parameter can be any of the @ref BitStatus enumeration.
* @par Required preconditions:
* The port must be configured in input mode.
*/
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)
{
return ((BitStatus)(GPIOx->IDR & (vu8)GPIO_Pin));
}
/**
* @brief Configures the external pull-up on GPIOx pins.
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
* @param[in] GPIO_Pin : This parameter contains the pin number, it can be one or many members
* of the @ref GPIO_Pin_TypeDef enumeration.
* @param[in] NewState : The new state of the pull up pin.
* This parameter can be any of the @ref FunctionalState enumeration.
* @retval None
*/
void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE) /* External Pull-Up Set*/
{
GPIOx->CR1 |= (u8)GPIO_Pin;
} else /* External Pull-Up Reset*/
{
GPIOx->CR1 &= (u8)(~(GPIO_Pin));
}
}
/**
* @}
*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,149 @@
/**
******************************************************************************
* @file stm8s_gpio.h
* @brief This file contains all functions prototype and macros for the GPIO 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_GPIO_H
#define __STM8S_GPIO_H
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
/* Exported variables ------------------------------------------------------- */
/* Exported types ------------------------------------------------------------*/
/** @addtogroup GPIO_Exported_Types
* @{
*/
/**
* @brief GPIO modes
*
* Bits definitions:
* - Bit 7: 0 = INPUT mode
* 1 = OUTPUT mode
* 1 = PULL-UP (input) or PUSH-PULL (output)
* - Bit 5: 0 = No external interrupt (input) or No slope control (output)
* 1 = External interrupt (input) or Slow control enabled (output)
* - Bit 4: 0 = Low level (output)
* 1 = High level (output push-pull) or HI-Z (output open-drain)
*/
typedef enum
{
GPIO_MODE_IN_FL_NO_IT = (u8)0b00000000, /*!< Input floating, no external interrupt */
GPIO_MODE_IN_PU_NO_IT = (u8)0b01000000, /*!< Input pull-up, no external interrupt */
GPIO_MODE_IN_FL_IT = (u8)0b00100000, /*!< Input floating, external interrupt */
GPIO_MODE_IN_PU_IT = (u8)0b01100000, /*!< Input pull-up, external interrupt */
GPIO_MODE_OUT_OD_LOW_FAST = (u8)0b10100000, /*!< Output open-drain, low level, 10MHz */
GPIO_MODE_OUT_PP_LOW_FAST = (u8)0b11100000, /*!< Output push-pull, low level, 10MHz */
GPIO_MODE_OUT_OD_LOW_SLOW = (u8)0b10000000, /*!< Output open-drain, low level, 2MHz */
GPIO_MODE_OUT_PP_LOW_SLOW = (u8)0b11000000, /*!< Output push-pull, low level, 2MHz */
GPIO_MODE_OUT_OD_HIZ_FAST = (u8)0b10110000, /*!< Output open-drain, high-impedance level,10MHz */
GPIO_MODE_OUT_PP_HIGH_FAST = (u8)0b11110000, /*!< Output push-pull, high level, 10MHz */
GPIO_MODE_OUT_OD_HIZ_SLOW = (u8)0b10010000, /*!< Output open-drain, high-impedance level, 2MHz */
GPIO_MODE_OUT_PP_HIGH_SLOW = (u8)0b11010000 /*!< Output push-pull, high level, 2MHz */
}GPIO_Mode_TypeDef;
/**
* @brief Definition of the GPIO pins. Used by the @ref GPIO_Init function in
* order to select the pins to be initialized.
*/
typedef enum
{
GPIO_PIN_0 = ((u8)0x01), /*!< Pin 0 selected */
GPIO_PIN_1 = ((u8)0x02), /*!< Pin 1 selected */
GPIO_PIN_2 = ((u8)0x04), /*!< Pin 2 selected */
GPIO_PIN_3 = ((u8)0x08), /*!< Pin 3 selected */
GPIO_PIN_4 = ((u8)0x10), /*!< Pin 4 selected */
GPIO_PIN_5 = ((u8)0x20), /*!< Pin 5 selected */
GPIO_PIN_6 = ((u8)0x40), /*!< Pin 6 selected */
GPIO_PIN_7 = ((u8)0x80), /*!< Pin 7 selected */
GPIO_PIN_LNIB = ((u8)0x0F), /*!< Low nibble pins selected */
GPIO_PIN_HNIB = ((u8)0xF0), /*!< High nibble pins selected */
GPIO_PIN_ALL = ((u8)0xFF) /*!< All pins selected */
}GPIO_Pin_TypeDef;
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/** @addtogroup GPIO_Private_Macros
* @{
*/
/**
* @brief Macro used by the assert function to check the different functions parameters.
*/
/**
* @brief Macro used by the assert function in order to check the different
* values of GPIOMode_TypeDef.
*/
#define IS_GPIO_MODE_OK(MODE) \
(((MODE) == GPIO_MODE_IN_FL_NO_IT) || \
((MODE) == GPIO_MODE_IN_PU_NO_IT) || \
((MODE) == GPIO_MODE_IN_FL_IT) || \
((MODE) == GPIO_MODE_IN_PU_IT) || \
((MODE) == GPIO_MODE_OUT_OD_LOW_FAST) || \
((MODE) == GPIO_MODE_OUT_PP_LOW_FAST) || \
((MODE) == GPIO_MODE_OUT_OD_LOW_SLOW) || \
((MODE) == GPIO_MODE_OUT_PP_LOW_SLOW) || \
((MODE) == GPIO_MODE_OUT_OD_HIZ_FAST) || \
((MODE) == GPIO_MODE_OUT_PP_HIGH_FAST) || \
((MODE) == GPIO_MODE_OUT_OD_HIZ_SLOW) || \
((MODE) == GPIO_MODE_OUT_PP_HIGH_SLOW))
/**
* @brief Macro used by the assert function in order to check the different
* values of GPIO_Pins.
*/
#define IS_GPIO_PIN_OK(PIN) ((PIN) != (u8)0x00)
/**
* @}
*/
/* Exported functions ------------------------------------------------------- */
/** @addtogroup GPIO_Exported_Functions
* @{
*/
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode);
void GPIO_Write(GPIO_TypeDef* GPIOx, u8 PortVal);
void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);
void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);
u8 GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
u8 GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin);
void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState);
/**
* @}
*/
#endif /* __STM8L_GPIO_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,316 @@
/**
******************************************************************************
* @file stm8s_itc.c
* @brief This file contains all the functions for the ITC 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_itc.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @addtogroup ITC_Private_Functions
* @{
*/
/**
* @brief Utility function used to read CC register.
* @par Parameters:
* None
* @retval u8 Content of CC register (in A register).
*/
u8 ITC_GetCPUCC(void)
{
#ifdef _COSMIC_
_asm("push cc");
_asm("pop a");
return; /* Ignore compiler warning, the returned value is in A register */
#else /* _RAISONANCE_ */
return _getCC_();
#endif /* _COSMIC_*/
}
/**
* @}
*/
/* Public functions ----------------------------------------------------------*/
/** @addtogroup ITC_Public_Functions
* @{
*/
/**
* @brief Deinitializes the ITC registers to their default reset value.
* @par Parameters:
* None
* @retval
* None
*/
void ITC_DeInit(void)
{
ITC->ISPR1 = ITC_SPRX_RESET_VALUE;
ITC->ISPR2 = ITC_SPRX_RESET_VALUE;
ITC->ISPR3 = ITC_SPRX_RESET_VALUE;
ITC->ISPR4 = ITC_SPRX_RESET_VALUE;
ITC->ISPR5 = ITC_SPRX_RESET_VALUE;
ITC->ISPR6 = ITC_SPRX_RESET_VALUE;
ITC->ISPR7 = ITC_SPRX_RESET_VALUE;
ITC->ISPR8 = ITC_SPRX_RESET_VALUE;
}
/**
* @brief Get the software interrupt priority bits (I1, I0) value from CPU CC register.
* @par Parameters:
* None
* @retval u8 The software interrupt priority bits value.
*/
u8 ITC_GetSoftIntStatus(void)
{
return (u8)(ITC_GetCPUCC() & CPU_CC_I1I0);
}
/**
* @brief Get the software priority of the specified interrupt source.
* @param[in] IrqNum The IRQ number to access.
* @retval ITC_PriorityLevel_TypeDef The software priority of the interrupt source.
*/
ITC_PriorityLevel_TypeDef ITC_GetSoftwarePriority(ITC_Irq_TypeDef IrqNum)
{
u8 Value = 0;
u8 Mask;
/* Check function parameters */
assert_param(IS_ITC_IRQ_OK((u8)IrqNum));
/* Define the mask corresponding to the bits position in the SPR register */
Mask = (u8)(0x03U << (((u8)IrqNum % 4U) * 2U));
switch (IrqNum)
{
case ITC_IRQ_TLI: /* TLI software priority can be read but has no meaning */
case ITC_IRQ_AWU:
case ITC_IRQ_CLK:
case ITC_IRQ_PORTA:
Value = (u8)(ITC->ISPR1 & Mask); /* Read software priority */
break;
case ITC_IRQ_PORTB:
case ITC_IRQ_PORTC:
case ITC_IRQ_PORTD:
case ITC_IRQ_PORTE:
Value = (u8)(ITC->ISPR2 & Mask); /* Read software priority */
break;
#ifdef STM8S208
case ITC_IRQ_CAN_RX:
case ITC_IRQ_CAN_TX:
#endif /*STM8S208*/
#ifdef STM8S903
case ITC_IRQ_PORTF:
#endif /*STM8S903*/
case ITC_IRQ_SPI:
case ITC_IRQ_TIM1_OVF:
Value = (u8)(ITC->ISPR3 & Mask); /* Read software priority */
break;
case ITC_IRQ_TIM1_CAPCOM:
#ifdef STM8S903
case ITC_IRQ_TIM5_OVFTRI:
case ITC_IRQ_TIM5_CAPCOM:
#else
case ITC_IRQ_TIM2_OVF:
case ITC_IRQ_TIM2_CAPCOM:
#endif /*STM8S903*/
case ITC_IRQ_TIM3_OVF:
Value = (u8)(ITC->ISPR4 & Mask); /* Read software priority */
break;
case ITC_IRQ_TIM3_CAPCOM:
case ITC_IRQ_UART1_TX:
case ITC_IRQ_UART1_RX:
case ITC_IRQ_I2C:
Value = (u8)(ITC->ISPR5 & Mask); /* Read software priority */
break;
#ifdef STM8S105
case ITC_IRQ_UART2_TX:
case ITC_IRQ_UART2_RX:
#endif /*STM8S105*/
#if defined(STM8S208) ||defined(STM8S207)
case ITC_IRQ_UART3_TX:
case ITC_IRQ_UART3_RX:
case ITC_IRQ_ADC2:
#endif /*STM8S208 or STM8S207*/
#if defined(STM8S105) ||defined(STM8S103) ||defined(STM8S905)
case ITC_IRQ_ADC1:
#endif /*STM8S105, STM8S103 or STM8S905 */
#ifdef STM8S903
case ITC_IRQ_TIM6_OVFTRI:
#else
case ITC_IRQ_TIM4_OVF:
#endif /*STM8S903*/
Value = (u8)(ITC->ISPR6 & Mask); /* Read software priority */
break;
case ITC_IRQ_EEPROM_EEC:
Value = (u8)(ITC->ISPR7 & Mask); /* Read software priority */
break;
default:
break;
}
Value >>= (u8)(((u8)IrqNum % 4u) * 2u);
return((ITC_PriorityLevel_TypeDef)Value);
}
/**
* @brief Set the software priority of the specified interrupt source.
* @param[in] IrqNum The interrupt source to access.
* @param[in] PriorityValue The software priority value to set.
* @retval ITC_PriorityLevel_TypeDef The software priority of the interrupt source.
* @par Required preconditions:
* - The modification of the software priority is only possible when the interrupts are disabled.
* - The normal behavior is to disable the interrupts before calling this function, and re-enable it after.
* - The priority level 0 cannot be set (see product specification for more details).
*/
void ITC_SetSoftwarePriority(ITC_Irq_TypeDef IrqNum, ITC_PriorityLevel_TypeDef PriorityValue)
{
u8 Mask;
u8 NewPriority;
/* Check function parameters */
assert_param(IS_ITC_IRQ_OK((u8)IrqNum));
assert_param(IS_ITC_PRIORITY_OK(PriorityValue));
/* Check if interrupts are disabled */
assert_param(IS_ITC_INTERRUPTS_DISABLED);
/* Define the mask corresponding to the bits position in the SPR register */
/* The mask is reversed in order to clear the 2 bits after more easily */
Mask = (u8)(~(u8)(0x03U << (((u8)IrqNum % 4U) * 2U)));
/* Define the new priority to write */
NewPriority = (u8)((u8)(PriorityValue) << (((u8)IrqNum % 4U) * 2U));
switch (IrqNum)
{
case ITC_IRQ_TLI: /* TLI software priority can be written but has no meaning */
case ITC_IRQ_AWU:
case ITC_IRQ_CLK:
case ITC_IRQ_PORTA:
ITC->ISPR1 &= Mask;
ITC->ISPR1 |= NewPriority;
break;
case ITC_IRQ_PORTB:
case ITC_IRQ_PORTC:
case ITC_IRQ_PORTD:
case ITC_IRQ_PORTE:
ITC->ISPR2 &= Mask;
ITC->ISPR2 |= NewPriority;
break;
#ifdef STM8S208
case ITC_IRQ_CAN_RX:
case ITC_IRQ_CAN_TX:
#endif /*STM8S208*/
#ifdef STM8S903
case ITC_IRQ_PORTF:
#endif /*STM8S903*/
case ITC_IRQ_SPI:
case ITC_IRQ_TIM1_OVF:
ITC->ISPR3 &= Mask;
ITC->ISPR3 |= NewPriority;
break;
case ITC_IRQ_TIM1_CAPCOM:
#ifdef STM8S903
case ITC_IRQ_TIM5_OVFTRI:
case ITC_IRQ_TIM5_CAPCOM:
#else
case ITC_IRQ_TIM2_OVF:
case ITC_IRQ_TIM2_CAPCOM:
#endif /*STM8S903*/
case ITC_IRQ_TIM3_OVF:
ITC->ISPR4 &= Mask;
ITC->ISPR4 |= NewPriority;
break;
case ITC_IRQ_TIM3_CAPCOM:
case ITC_IRQ_UART1_TX:
case ITC_IRQ_UART1_RX:
case ITC_IRQ_I2C:
ITC->ISPR5 &= Mask;
ITC->ISPR5 |= NewPriority;
break;
#ifdef STM8S105
case ITC_IRQ_UART2_TX:
case ITC_IRQ_UART2_RX:
#endif /*STM8S105*/
#if defined(STM8S208) ||defined(STM8S207)
case ITC_IRQ_UART3_TX:
case ITC_IRQ_UART3_RX:
case ITC_IRQ_ADC2:
#endif /*STM8S208 or STM8S207*/
#if defined(STM8S105) ||defined(STM8S103) ||defined(STM8S905)
case ITC_IRQ_ADC1:
#endif /*STM8S105, STM8S103 or STM8S905 */
#ifdef STM8S903
case ITC_IRQ_TIM6_OVFTRI:
#else
case ITC_IRQ_TIM4_OVF:
#endif /*STM8S903*/
ITC->ISPR6 &= Mask;
ITC->ISPR6 |= NewPriority;
break;
case ITC_IRQ_EEPROM_EEC:
ITC->ISPR7 &= Mask;
ITC->ISPR7 |= NewPriority;
break;
default:
break;
}
}
/**
* @}
*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,168 @@
/**
******************************************************************************
* @file stm8s_itc.h
* @brief This file contains all functions prototype and macros for the ITC 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_ITC_H__
#define __STM8S_ITC_H__
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
/* Exported types ------------------------------------------------------------*/
/** @addtogroup ITC_Exported_Types
* @{
*/
/**
* @brief ITC Interrupt Lines selection
*/
typedef enum {
ITC_IRQ_TLI = (u8)0,
ITC_IRQ_AWU = (u8)1,
ITC_IRQ_CLK = (u8)2,
ITC_IRQ_PORTA = (u8)3,
ITC_IRQ_PORTB = (u8)4,
ITC_IRQ_PORTC = (u8)5,
ITC_IRQ_PORTD = (u8)6,
ITC_IRQ_PORTE = (u8)7,
#ifdef STM8S208
ITC_IRQ_CAN_RX = (u8)8,
ITC_IRQ_CAN_TX = (u8)9,
#endif /*STM8S208*/
#ifdef STM8S903
ITC_IRQ_PORTF = (u8)8,
#endif /*STM8S903*/
ITC_IRQ_SPI = (u8)10,
ITC_IRQ_TIM1_OVF = (u8)11,
ITC_IRQ_TIM1_CAPCOM = (u8)12,
#ifdef STM8S903
ITC_IRQ_TIM5_OVFTRI = (u8)13,
ITC_IRQ_TIM5_CAPCOM = (u8)14,
#else
ITC_IRQ_TIM2_OVF = (u8)13,
ITC_IRQ_TIM2_CAPCOM = (u8)14,
#endif /*STM8S903*/
ITC_IRQ_TIM3_OVF = (u8)15,
ITC_IRQ_TIM3_CAPCOM = (u8)16,
ITC_IRQ_UART1_TX = (u8)17,
ITC_IRQ_UART1_RX = (u8)18,
ITC_IRQ_I2C = (u8)19,
#ifdef STM8S105
ITC_IRQ_UART2_TX = (u8)20,
ITC_IRQ_UART2_RX = (u8)21,
#endif /*STM8S105*/
#if defined(STM8S208) ||defined(STM8S207)
ITC_IRQ_UART3_TX = (u8)20,
ITC_IRQ_UART3_RX = (u8)21,
ITC_IRQ_ADC2 = (u8)22,
#endif /*STM8S208 or STM8S207*/
#if defined(STM8S105) ||defined(STM8S103) ||defined(STM8S905)
ITC_IRQ_ADC1 = (u8)22,
#endif /*STM8S105, STM8S103 or STM8S905 */
#ifdef STM8S903
ITC_IRQ_TIM6_OVFTRI = (u8)23,
#else
ITC_IRQ_TIM4_OVF = (u8)23,
#endif /*STM8S903*/
ITC_IRQ_EEPROM_EEC = (u8)24
} ITC_Irq_TypeDef;
/**
* @brief ITC Priority Levels selection
*/
typedef enum {
ITC_PRIORITYLEVEL_0 = (u8)0x02, /*!< Software priority level 0 (cannot be written) */
ITC_PRIORITYLEVEL_1 = (u8)0x01, /*!< Software priority level 1 */
ITC_PRIORITYLEVEL_2 = (u8)0x00, /*!< Software priority level 2 */
ITC_PRIORITYLEVEL_3 = (u8)0x03 /*!< Software priority level 3 */
} ITC_PriorityLevel_TypeDef;
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/** @addtogroup ITC_Exported_Constants
* @{
*/
#define CPU_SOFT_INT_DISABLED ((u8)0x28) /*!< Mask for I1 and I0 bits in CPU_CC register */
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/**
* @brief Macros used by the assert function in order to check the different functions parameters.
* @addtogroup ITC_Private_Macros
* @{
*/
/* Used by assert function */
#define IS_ITC_IRQ_OK(IRQ) ((IRQ) <= (u8)24)
/* Used by assert function */
#define IS_ITC_PRIORITY_OK(PriorityValue) \
(((PriorityValue) == ITC_PRIORITYLEVEL_0) || \
((PriorityValue) == ITC_PRIORITYLEVEL_1) || \
((PriorityValue) == ITC_PRIORITYLEVEL_2) || \
((PriorityValue) == ITC_PRIORITYLEVEL_3))
/* Used by assert function */
#define IS_ITC_INTERRUPTS_DISABLED (ITC_GetSoftIntStatus() == CPU_SOFT_INT_DISABLED)
/**
* @}
*/
/* Exported functions ------------------------------------------------------- */
/** @addtogroup ITC_Exported_Functions
* @{
*/
u8 ITC_GetCPUCC(void);
void ITC_DeInit(void);
u8 ITC_GetSoftIntStatus(void);
void ITC_SetSoftwarePriority(ITC_Irq_TypeDef IrqNum, ITC_PriorityLevel_TypeDef PriorityValue);
ITC_PriorityLevel_TypeDef ITC_GetSoftwarePriority(ITC_Irq_TypeDef IrqNum);
/**
* @}
*/
#endif /* __STM8S_ITC_H__ */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,565 @@
/**
******************************************************************************
* @file stm8s_tim1.h
* @brief This file contains all functions prototype and macros for the TIM1 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_TIM1_H
#define __STM8S_TIM1_H
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
/* Exported types ------------------------------------------------------------*/
/** TIM1 Output Compare and PWM modes */
typedef enum
{
TIM1_OCMODE_TIMING = ((u8)0x00),
TIM1_OCMODE_ACTIVE = ((u8)0x10),
TIM1_OCMODE_INACTIVE = ((u8)0x20),
TIM1_OCMODE_TOGGLE = ((u8)0x30),
TIM1_OCMODE_PWM1 = ((u8)0x60),
TIM1_OCMODE_PWM2 = ((u8)0x70)
}TIM1_OCMode_TypeDef;
#define IS_TIM1_OC_MODE_OK(MODE) (((MODE) == TIM1_OCMODE_TIMING) || \
((MODE) == TIM1_OCMODE_ACTIVE) || \
((MODE) == TIM1_OCMODE_INACTIVE) || \
((MODE) == TIM1_OCMODE_TOGGLE)|| \
((MODE) == TIM1_OCMODE_PWM1) || \
((MODE) == TIM1_OCMODE_PWM2))
#define IS_TIM1_OCM_OK(MODE)(((MODE) == TIM1_OCMODE_TIMING) || \
((MODE) == TIM1_OCMODE_ACTIVE) || \
((MODE) == TIM1_OCMODE_INACTIVE) || \
((MODE) == TIM1_OCMODE_TOGGLE)|| \
((MODE) == TIM1_OCMODE_PWM1) || \
((MODE) == TIM1_OCMODE_PWM2) || \
((MODE) == TIM1_FORCEDACTION_ACTIVE) || \
((MODE) == TIM1_FORCEDACTION_INACTIVE))
/** TIM1 One Pulse Mode */
typedef enum
{
TIM1_OPMODE_SINGLE = ((u8)0x01),
TIM1_OPMODE_REPETITIVE = ((u8)0x00)
}TIM1_OPMode_TypeDef;
#define IS_TIM1_OPM_MODE_OK(MODE) (((MODE) == TIM1_OPMODE_SINGLE) || \
((MODE) == TIM1_OPMODE_REPETITIVE))
/** TIM1 Channel */
typedef enum
{
TIM1_CHANNEL_1 = ((u8)0x00),
TIM1_CHANNEL_2 = ((u8)0x01),
TIM1_CHANNEL_3 = ((u8)0x02),
TIM1_CHANNEL_4 = ((u8)0x03)
}TIM1_Channel_TypeDef;
#define IS_TIM1_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM1_CHANNEL_1) || \
((CHANNEL) == TIM1_CHANNEL_2) || \
((CHANNEL) == TIM1_CHANNEL_3) || \
((CHANNEL) == TIM1_CHANNEL_4))
#define IS_TIM1_PWMI_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM1_CHANNEL_1) || \
((CHANNEL) == TIM1_CHANNEL_2))
#define IS_TIM1_COMPLEMENTARY_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM1_CHANNEL_1) || \
((CHANNEL) == TIM1_CHANNEL_2) || \
((CHANNEL) == TIM1_CHANNEL_3))
/** TIM1 Counter Mode */
typedef enum
{
TIM1_COUNTERMODE_UP = ((u8)0x00),
TIM1_COUNTERMODE_DOWN = ((u8)0x10),
TIM1_COUNTERMODE_CENTERALIGNED1 = ((u8)0x20),
TIM1_COUNTERMODE_CENTERALIGNED2 = ((u8)0x40),
TIM1_COUNTERMODE_CENTERALIGNED3 = ((u8)0x60)
}TIM1_CounterMode_TypeDef;
#define IS_TIM1_COUNTER_MODE_OK(MODE) (((MODE) == TIM1_COUNTERMODE_UP) || \
((MODE) == TIM1_COUNTERMODE_DOWN) || \
((MODE) == TIM1_COUNTERMODE_CENTERALIGNED1) || \
((MODE) == TIM1_COUNTERMODE_CENTERALIGNED2) || \
((MODE) == TIM1_COUNTERMODE_CENTERALIGNED3))
/** TIM1 Output Compare Polarity */
typedef enum
{
TIM1_OCPOLARITY_HIGH = ((u8)0x00),
TIM1_OCPOLARITY_LOW = ((u8)0x22)
}TIM1_OCPolarity_TypeDef;
#define IS_TIM1_OC_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_OCPOLARITY_HIGH) || \
((POLARITY) == TIM1_OCPOLARITY_LOW))
/** TIM1 Output Compare N Polarity */
typedef enum
{
TIM1_OCNPOLARITY_HIGH = ((u8)0x00),
TIM1_OCNPOLARITY_LOW = ((u8)0x88)
}TIM1_OCNPolarity_TypeDef;
#define IS_TIM1_OCN_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_OCNPOLARITY_HIGH) || \
((POLARITY) == TIM1_OCNPOLARITY_LOW))
/** TIM1 Output Compare states */
typedef enum
{
TIM1_OUTPUTSTATE_DISABLE = ((u8)0x00),
TIM1_OUTPUTSTATE_ENABLE = ((u8)0x11)
}TIM1_OutputState_TypeDef;
#define IS_TIM1_OUTPUT_STATE_OK(STATE) (((STATE) == TIM1_OUTPUTSTATE_DISABLE) || \
((STATE) == TIM1_OUTPUTSTATE_ENABLE))
/** TIM1 Output Compare N States */
typedef enum
{
TIM1_OUTPUTNSTATE_DISABLE = ((u8)0x00),
TIM1_OUTPUTNSTATE_ENABLE = ((u8)0x44)
} TIM1_OutputNState_TypeDef;
#define IS_TIM1_OUTPUTN_STATE_OK(STATE) (((STATE) == TIM1_OUTPUTNSTATE_DISABLE) ||\
((STATE) == TIM1_OUTPUTNSTATE_ENABLE))
/** TIM1 Break Input enable/disable */
typedef enum
{
TIM1_BREAK_ENABLE = ((u8)0x10),
TIM1_BREAK_DISABLE = ((u8)0x00)
}TIM1_BreakState_TypeDef;
#define IS_TIM1_BREAK_STATE_OK(STATE) (((STATE) == TIM1_BREAK_ENABLE) || \
((STATE) == TIM1_BREAK_DISABLE))
/** TIM1 Break Polarity */
typedef enum
{
TIM1_BREAKPOLARITY_LOW = ((u8)0x00),
TIM1_BREAKPOLARITY_HIGH = ((u8)0x20)
}TIM1_BreakPolarity_TypeDef;
#define IS_TIM1_BREAK_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_BREAKPOLARITY_LOW) || \
((POLARITY) == TIM1_BREAKPOLARITY_HIGH))
/** TIM1 AOE Bit Set/Reset */
typedef enum
{
TIM1_AUTOMATICOUTPUT_ENABLE = ((u8)0x40),
TIM1_AUTOMATICOUTPUT_DISABLE = ((u8)0x00)
}TIM1_AutomaticOutput_TypeDef;
#define IS_TIM1_AUTOMATIC_OUTPUT_STATE_OK(STATE) (((STATE) == TIM1_AUTOMATICOUTPUT_ENABLE) || \
((STATE) == TIM1_AUTOMATICOUTPUT_DISABLE))
/** TIM1 Lock levels */
typedef enum
{
TIM1_LOCKLEVEL_OFF = ((u8)0x00),
TIM1_LOCKLEVEL_1 = ((u8)0x01),
TIM1_LOCKLEVEL_2 = ((u8)0x02),
TIM1_LOCKLEVEL_3 = ((u8)0x03)
}TIM1_LockLevel_TypeDef;
#define IS_TIM1_LOCK_LEVEL_OK(LEVEL) (((LEVEL) == TIM1_LOCKLEVEL_OFF) || \
((LEVEL) == TIM1_LOCKLEVEL_1) || \
((LEVEL) == TIM1_LOCKLEVEL_2) || \
((LEVEL) == TIM1_LOCKLEVEL_3))
/** TIM1 OSSI: Off-State Selection for Idle mode states */
typedef enum
{
TIM1_OSSISTATE_ENABLE = ((u8)0x04),
TIM1_OSSISTATE_DISABLE = ((u8)0x00)
}TIM1_OSSIState_TypeDef;
#define IS_TIM1_OSSI_STATE_OK(STATE) (((STATE) == TIM1_OSSISTATE_ENABLE) || \
((STATE) == TIM1_OSSISTATE_DISABLE))
/** TIM1 Output Compare Idle State */
typedef enum
{
TIM1_OCIDLESTATE_SET = ((u8)0x55),
TIM1_OCIDLESTATE_RESET = ((u8)0x00)
}TIM1_OCIdleState_TypeDef;
#define IS_TIM1_OCIDLE_STATE_OK(STATE) (((STATE) == TIM1_OCIDLESTATE_SET) || \
((STATE) == TIM1_OCIDLESTATE_RESET))
/** TIM1 Output Compare N Idle State */
typedef enum
{
TIM1_OCNIDLESTATE_SET = ((u8)0x2A),
TIM1_OCNIDLESTATE_RESET = ((u8)0x00)
}TIM1_OCNIdleState_TypeDef;
#define IS_TIM1_OCNIDLE_STATE_OK(STATE) (((STATE) == TIM1_OCNIDLESTATE_SET) || \
((STATE) == TIM1_OCNIDLESTATE_RESET))
/** TIM1 Input Capture Polarity */
typedef enum
{
TIM1_ICPOLARITY_RISING = ((u8)0x00),
TIM1_ICPOLARITY_FALLING = ((u8)0x01)
}TIM1_ICPolarity_TypeDef;
#define IS_TIM1_IC_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_ICPOLARITY_RISING) || \
((POLARITY) == TIM1_ICPOLARITY_FALLING))
/** TIM1 Input Capture Selection */
typedef enum
{
TIM1_ICSELECTION_DIRECTTI = ((u8)0x01),
TIM1_ICSELECTION_INDIRECTTI = ((u8)0x02),
TIM1_ICSELECTION_TRGI = ((u8)0x03)
}TIM1_ICSelection_TypeDef;
#define IS_TIM1_IC_SELECTION_OK(SELECTION) (((SELECTION) == TIM1_ICSELECTION_DIRECTTI) || \
((SELECTION) == TIM1_ICSELECTION_INDIRECTTI) || \
((SELECTION) == TIM1_ICSELECTION_TRGI))
/** TIM1 Input Capture Prescaler */
typedef enum
{
TIM1_ICPSC_DIV1 = ((u8)0x00),
TIM1_ICPSC_DIV2 = ((u8)0x04),
TIM1_ICPSC_DIV4 = ((u8)0x08),
TIM1_ICPSC_DIV8 = ((u8)0x0C)
}TIM1_ICPSC_TypeDef;
#define IS_TIM1_IC_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM1_ICPSC_DIV1) || \
((PRESCALER) == TIM1_ICPSC_DIV2) || \
((PRESCALER) == TIM1_ICPSC_DIV4) || \
((PRESCALER) == TIM1_ICPSC_DIV8))
/** TIM1 Input Capture Filer Value */
#define IS_TIM1_IC_FILTER_OK(ICFILTER) (ICFILTER <= 0x0F)
/** TIM1 External Trigger Filer Value */
#define IS_TIM1_EXT_TRG_FILTER_OK(FILTER) (FILTER <= 0x0F)
/** TIM1 interrupt sources */
typedef enum
{
TIM1_IT_UPDATE = ((u8)0x01),
TIM1_IT_CC1 = ((u8)0x02),
TIM1_IT_CC2 = ((u8)0x04),
TIM1_IT_CC3 = ((u8)0x08),
TIM1_IT_CC4 = ((u8)0x10),
TIM1_IT_COM = ((u8)0x20),
TIM1_IT_TRIGGER = ((u8)0x40),
TIM1_IT_BREAK = ((u8)0x80)
}TIM1_IT_TypeDef;
#define IS_TIM1_IT_OK(IT) (IT != 0x00)
#define IS_TIM1_GET_IT_OK(IT) (((IT) == TIM1_IT_UPDATE) || \
((IT) == TIM1_IT_CC1) || \
((IT) == TIM1_IT_CC2) || \
((IT) == TIM1_IT_CC3) || \
((IT) == TIM1_IT_CC4) || \
((IT) == TIM1_IT_COM) || \
((IT) == TIM1_IT_TRIGGER) || \
((IT) == TIM1_IT_BREAK))
/** TIM1 External Trigger Prescaler */
typedef enum
{
TIM1_EXTTRGPSC_OFF = ((u8)0x00),
TIM1_EXTTRGPSC_DIV2 = ((u8)0x10),
TIM1_EXTTRGPSC_DIV4 = ((u8)0x20),
TIM1_EXTTRGPSC_DIV8 = ((u8)0x30)
}TIM1_ExtTRGPSC_TypeDef;
#define IS_TIM1_EXT_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM1_EXTTRGPSC_OFF) || \
((PRESCALER) == TIM1_EXTTRGPSC_DIV2) || \
((PRESCALER) == TIM1_EXTTRGPSC_DIV4) || \
((PRESCALER) == TIM1_EXTTRGPSC_DIV8))
/** TIM1 Internal Trigger Selection */
typedef enum
{
TIM1_TS_TIM6 = ((u8)0x00), /*!< TRIG Input source = TIM6 TRIG Output */
TIM1_TS_TIM5 = ((u8)0x30), /*!< TRIG Input source = TIM5 TRIG Output */
TIM1_TS_TI1F_ED = ((u8)0x40),
TIM1_TS_TI1FP1 = ((u8)0x50),
TIM1_TS_TI2FP2 = ((u8)0x60),
TIM1_TS_ETRF = ((u8)0x70)
}TIM1_TS_TypeDef;
#define IS_TIM1_TRIGGER_SELECTION_OK(SELECTION) (((SELECTION) == TIM1_TS_TI1F_ED) || \
((SELECTION) == TIM1_TS_TI1FP1) || \
((SELECTION) == TIM1_TS_TI2FP2) || \
((SELECTION) == TIM1_TS_ETRF) || \
((SELECTION) == TIM1_TS_TIM5) || \
((SELECTION) == TIM1_TS_TIM6))
#define IS_TIM1_TIX_TRIGGER_SELECTION_OK(SELECTION) (((SELECTION) == TIM1_TS_TI1F_ED) || \
((SELECTION) == TIM1_TS_TI1FP1) || \
((SELECTION) == TIM1_TS_TI2FP2))
/** TIM1 TIx External Clock Source */
typedef enum
{
TIM1_TIXEXTERNALCLK1SOURCE_TI1ED = ((u8)0x40),
TIM1_TIXEXTERNALCLK1SOURCE_TI1 = ((u8)0x50),
TIM1_TIXEXTERNALCLK1SOURCE_TI2 = ((u8)0x60)
}TIM1_TIxExternalCLK1Source_TypeDef;
#define IS_TIM1_TIXCLK_SOURCE_OK(SOURCE) (((SOURCE) == TIM1_TIXEXTERNALCLK1SOURCE_TI1ED) || \
((SOURCE) == TIM1_TIXEXTERNALCLK1SOURCE_TI2) || \
((SOURCE) == TIM1_TIXEXTERNALCLK1SOURCE_TI1))
/** TIM1 External Trigger Polarity */
typedef enum
{
TIM1_EXTTRGPOLARITY_INVERTED = ((u8)0x80),
TIM1_EXTTRGPOLARITY_NONINVERTED = ((u8)0x00)
}TIM1_ExtTRGPolarity_TypeDef;
#define IS_TIM1_EXT_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_EXTTRGPOLARITY_INVERTED) || \
((POLARITY) == TIM1_EXTTRGPOLARITY_NONINVERTED))
/** TIM1 Prescaler Reload Mode */
typedef enum
{
TIM1_PSCRELOADMODE_UPDATE = ((u8)0x00),
TIM1_PSCRELOADMODE_IMMEDIATE = ((u8)0x01)
}TIM1_PSCReloadMode_TypeDef;
#define IS_TIM1_PRESCALER_RELOAD_OK(RELOAD) (((RELOAD) == TIM1_PSCRELOADMODE_UPDATE) || \
((RELOAD) == TIM1_PSCRELOADMODE_IMMEDIATE))
/** TIM1 Encoder Mode */
typedef enum
{
TIM1_ENCODERMODE_TI1 = ((u8)0x01),
TIM1_ENCODERMODE_TI2 = ((u8)0x02),
TIM1_ENCODERMODE_TI12 = ((u8)0x03)
}TIM1_EncoderMode_TypeDef;
#define IS_TIM1_ENCODER_MODE_OK(MODE) (((MODE) == TIM1_ENCODERMODE_TI1) || \
((MODE) == TIM1_ENCODERMODE_TI2) || \
((MODE) == TIM1_ENCODERMODE_TI12))
/** TIM1 Event Source */
typedef enum
{
TIM1_EVENTSOURCE_UPDATE = ((u8)0x01),
TIM1_EVENTSOURCE_CC1 = ((u8)0x02),
TIM1_EVENTSOURCE_CC2 = ((u8)0x04),
TIM1_EVENTSOURCE_CC3 = ((u8)0x08),
TIM1_EVENTSOURCE_CC4 = ((u8)0x10),
TIM1_EVENTSOURCE_COM = ((u8)0x20),
TIM1_EVENTSOURCE_TRIGGER = ((u8)0x40),
TIM1_EVENTSOURCE_BREAK = ((u8)0x80)
}TIM1_EventSource_TypeDef;
#define IS_TIM1_EVENT_SOURCE_OK(SOURCE) ((SOURCE) != 0x00)
/** TIM1 Update Source */
typedef enum
{
TIM1_UPDATESOURCE_GLOBAL = ((u8)0x00),
TIM1_UPDATESOURCE_REGULAR = ((u8)0x01)
}TIM1_UpdateSource_TypeDef;
#define IS_TIM1_UPDATE_SOURCE_OK(SOURCE) (((SOURCE) == TIM1_UPDATESOURCE_GLOBAL) || \
((SOURCE) == TIM1_UPDATESOURCE_REGULAR))
/** TIM1 Trigger Output Source */
typedef enum
{
TIM1_TRGOSOURCE_RESET = ((u8)0x00),
TIM1_TRGOSOURCE_ENABLE = ((u8)0x10),
TIM1_TRGOSOURCE_UPDATE = ((u8)0x20),
TIM1_TRGOSource_OC1 = ((u8)0x30),
TIM1_TRGOSOURCE_OC1REF = ((u8)0x40),
TIM1_TRGOSOURCE_OC2REF = ((u8)0x50),
TIM1_TRGOSOURCE_OC3REF = ((u8)0x60)
}TIM1_TRGOSource_TypeDef;
#define IS_TIM1_TRGO_SOURCE_OK(SOURCE) (((SOURCE) == TIM1_TRGOSOURCE_RESET) || \
((SOURCE) == TIM1_TRGOSOURCE_ENABLE) || \
((SOURCE) == TIM1_TRGOSOURCE_UPDATE) || \
((SOURCE) == TIM1_TRGOSource_OC1) || \
((SOURCE) == TIM1_TRGOSOURCE_OC1REF) || \
((SOURCE) == TIM1_TRGOSOURCE_OC2REF) || \
((SOURCE) == TIM1_TRGOSOURCE_OC3REF))
/** TIM1 Slave Mode */
typedef enum
{
TIM1_SLAVEMODE_RESET = ((u8)0x04),
TIM1_SLAVEMODE_GATED = ((u8)0x05),
TIM1_SLAVEMODE_TRIGGER = ((u8)0x06),
TIM1_SLAVEMODE_EXTERNAL1 = ((u8)0x07)
}TIM1_SlaveMode_TypeDef;
#define IS_TIM1_SLAVE_MODE_OK(MODE) (((MODE) == TIM1_SLAVEMODE_RESET) || \
((MODE) == TIM1_SLAVEMODE_GATED) || \
((MODE) == TIM1_SLAVEMODE_TRIGGER) || \
((MODE) == TIM1_SLAVEMODE_EXTERNAL1))
/** TIM1 Flags */
typedef enum
{
TIM1_FLAG_UPDATE = ((u16)0x0001),
TIM1_FLAG_CC1 = ((u16)0x0002),
TIM1_FLAG_CC2 = ((u16)0x0004),
TIM1_FLAG_CC3 = ((u16)0x0008),
TIM1_FLAG_CC4 = ((u16)0x0010),
TIM1_FLAG_COM = ((u16)0x0020),
TIM1_FLAG_TRIGGER = ((u16)0x0040),
TIM1_FLAG_BREAK = ((u16)0x0080),
TIM1_FLAG_CC1OF = ((u16)0x0200),
TIM1_FLAG_CC2OF = ((u16)0x0400),
TIM1_FLAG_CC3OF = ((u16)0x0800),
TIM1_FLAG_CC4OF = ((u16)0x1000)
}TIM1_FLAG_TypeDef;
#define IS_TIM1_GET_FLAG_OK(FLAG) (((FLAG) == TIM1_FLAG_UPDATE) || \
((FLAG) == TIM1_FLAG_CC1) || \
((FLAG) == TIM1_FLAG_CC2) || \
((FLAG) == TIM1_FLAG_CC3) || \
((FLAG) == TIM1_FLAG_CC4) || \
((FLAG) == TIM1_FLAG_COM) || \
((FLAG) == TIM1_FLAG_TRIGGER) || \
((FLAG) == TIM1_FLAG_BREAK) || \
((FLAG) == TIM1_FLAG_CC1OF) || \
((FLAG) == TIM1_FLAG_CC2OF) || \
((FLAG) == TIM1_FLAG_CC3OF) || \
((FLAG) == TIM1_FLAG_CC4OF))
#define IS_TIM1_CLEAR_FLAG_OK(FLAG) ((((u16)FLAG & (u16)0xE100) == 0x0000) && (FLAG != 0x0000))
/** TIM1 Forced Action */
typedef enum
{
TIM1_FORCEDACTION_ACTIVE = ((u8)0x50),
TIM1_FORCEDACTION_INACTIVE = ((u8)0x40)
}TIM1_ForcedAction_TypeDef;
#define IS_TIM1_FORCED_ACTION_OK(ACTION) ((ACTION == TIM1_FORCEDACTION_ACTIVE) || \
(ACTION == TIM1_FORCEDACTION_INACTIVE))
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup TIM1_Exported_Functions
* @{
*/
void TIM1_DeInit(void);
void TIM1_TimeBaseInit(u16 TIM1_Prescaler, TIM1_CounterMode_TypeDef TIM1_CounterMode, u16 TIM1_Period, u8 TIM1_RepetitionCounter);
void TIM1_OC1Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, u16 TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState);
void TIM1_OC2Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, u16 TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState);
void TIM1_OC3Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, u16 TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState);
void TIM1_OC4Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, u16 TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState);
void TIM1_BDTRConfig(TIM1_OSSIState_TypeDef TIM1_OSSIState, TIM1_LockLevel_TypeDef TIM1_LockLevel, u8 TIM1_DeadTime, TIM1_BreakState_TypeDef TIM1_Break, TIM1_BreakPolarity_TypeDef TIM1_BreakPolarity, TIM1_AutomaticOutput_TypeDef TIM1_AutomaticOutput);
void TIM1_ICInit(TIM1_Channel_TypeDef TIM1_Channel, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, TIM1_ICSelection_TypeDef TIM1_ICSelection, TIM1_ICPSC_TypeDef TIM1_ICPrescaler, u8 TIM1_ICFilter);
void TIM1_PWMIConfig(TIM1_Channel_TypeDef TIM1_Channel, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, TIM1_ICSelection_TypeDef TIM1_ICSelection, TIM1_ICPSC_TypeDef TIM1_ICPrescaler, u8 TIM1_ICFilter);
void TIM1_Cmd(FunctionalState NewState);
void TIM1_CtrlPWMOutputs(FunctionalState Newstate);
void TIM1_ITConfig(TIM1_IT_TypeDef TIM1_IT, FunctionalState NewState);
void TIM1_InternalClockConfig(void);
void TIM1_ETRClockMode1Config(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, u8 ExtTRGFilter);
void TIM1_ETRClockMode2Config(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, u8 ExtTRGFilter);
void TIM1_ETRConfig(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, u8 ExtTRGFilter);
void TIM1_TIxExternalClockConfig(TIM1_TIxExternalCLK1Source_TypeDef TIM1_TIxExternalCLKSource, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, u8 ICFilter);
void TIM1_SelectInputTrigger(TIM1_TS_TypeDef TIM1_InputTriggerSource);
void TIM1_UpdateDisableConfig(FunctionalState Newstate);
void TIM1_UpdateRequestConfig(TIM1_UpdateSource_TypeDef TIM1_UpdateSource);
void TIM1_SelectHallSensor(FunctionalState Newstate);
void TIM1_SelectOnePulseMode(TIM1_OPMode_TypeDef TIM1_OPMode);
void TIM1_SelectOutputTrigger(TIM1_TRGOSource_TypeDef TIM1_TRGOSource);
void TIM1_SelectSlaveMode(TIM1_SlaveMode_TypeDef TIM1_SlaveMode);
void TIM1_SelectMasterSlaveMode(FunctionalState NewState);
void TIM1_EncoderInterfaceConfig(TIM1_EncoderMode_TypeDef TIM1_EncoderMode, TIM1_ICPolarity_TypeDef TIM1_IC1Polarity, TIM1_ICPolarity_TypeDef TIM1_IC2Polarity);
void TIM1_PrescalerConfig(u16 Prescaler, TIM1_PSCReloadMode_TypeDef TIM1_PSCReloadMode);
void TIM1_CounterModeConfig(TIM1_CounterMode_TypeDef TIM1_CounterMode);
void TIM1_ForcedOC1Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction);
void TIM1_ForcedOC2Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction);
void TIM1_ForcedOC3Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction);
void TIM1_ForcedOC4Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction);
void TIM1_ARRPreloadConfig(FunctionalState Newstate);
void TIM1_SelectCOM(FunctionalState Newstate);
void TIM1_CCPreloadControl(FunctionalState Newstate);
void TIM1_OC1PreloadConfig(FunctionalState Newstate);
void TIM1_OC2PreloadConfig(FunctionalState Newstate);
void TIM1_OC3PreloadConfig(FunctionalState Newstate);
void TIM1_OC4PreloadConfig(FunctionalState Newstate);
void TIM1_OC1FastConfig(FunctionalState Newstate);
void TIM1_OC2FastConfig(FunctionalState Newstate);
void TIM1_OC3FastConfig(FunctionalState Newstate);
void TIM1_OC4FastConfig(FunctionalState Newstate);
void TIM1_GenerateEvent(TIM1_EventSource_TypeDef TIM1_EventSource);
void TIM1_OC1PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity);
void TIM1_OC1NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity);
void TIM1_OC2PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity);
void TIM1_OC2NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity);
void TIM1_OC3PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity);
void TIM1_OC3NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity);
void TIM1_OC4PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity);
void TIM1_CCxCmd(TIM1_Channel_TypeDef TIM1_Channel, FunctionalState Newstate);
void TIM1_CCxNCmd(TIM1_Channel_TypeDef TIM1_Channel, FunctionalState Newstate);
void TIM1_SelectOCxM(TIM1_Channel_TypeDef TIM1_Channel, TIM1_OCMode_TypeDef TIM1_OCMode);
void TIM1_SetCounter(u16 Counter);
void TIM1_SetAutoreload(u16 Autoreload);
void TIM1_SetCompare1(u16 Compare1);
void TIM1_SetCompare2(u16 Compare2);
void TIM1_SetCompare3(u16 Compare3);
void TIM1_SetCompare4(u16 Compare4);
void TIM1_SetIC1Prescaler(TIM1_ICPSC_TypeDef TIM1_IC1Prescaler);
void TIM1_SetIC2Prescaler(TIM1_ICPSC_TypeDef TIM1_IC2Prescaler);
void TIM1_SetIC3Prescaler(TIM1_ICPSC_TypeDef TIM1_IC3Prescaler);
void TIM1_SetIC4Prescaler(TIM1_ICPSC_TypeDef TIM1_IC4Prescaler);
u16 TIM1_GetCapture1(void);
u16 TIM1_GetCapture2(void);
u16 TIM1_GetCapture3(void);
u16 TIM1_GetCapture4(void);
u16 TIM1_GetCounter(void);
u16 TIM1_GetPrescaler(void);
FlagStatus TIM1_GetFlagStatus(TIM1_FLAG_TypeDef TIM1_FLAG);
void TIM1_ClearFlag(TIM1_FLAG_TypeDef TIM1_FLAG);
ITStatus TIM1_GetITStatus(TIM1_IT_TypeDef TIM1_IT);
void TIM1_ClearITPendingBit(TIM1_IT_TypeDef TIM1_IT);
/**
* @}
*/
#endif /* __STM8S_TIM1_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,103 @@
/**
******************************************************************************
* @file stm8s_type.h
* @brief This file contains all common data types.
* @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_TYPE_H
#define __STM8S_TYPE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef signed long s32;
typedef signed short s16;
typedef signed char s8;
typedef signed long const sc32; /* Read Only */
typedef signed short const sc16; /* Read Only */
typedef signed char const sc8; /* Read Only */
typedef volatile signed long vs32;
typedef volatile signed short vs16;
typedef volatile signed char vs8;
typedef volatile signed long const vsc32; /* Read Only */
typedef volatile signed short const vsc16; /* Read Only */
typedef volatile signed char const vsc8; /* Read Only */
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned long const uc32; /* Read Only */
typedef unsigned short const uc16; /* Read Only */
typedef unsigned char const uc8; /* Read Only */
typedef volatile unsigned long vu32;
typedef volatile unsigned short vu16;
typedef volatile unsigned char vu8;
typedef volatile unsigned long const vuc32; /* Read Only */
typedef volatile unsigned short const vuc16; /* Read Only */
typedef volatile unsigned char const vuc8; /* Read Only */
typedef enum
{
FALSE = 0,
TRUE = !FALSE
}
bool;
typedef enum {
RESET = 0,
SET = !RESET
}
FlagStatus, ITStatus, BitStatus;
typedef enum {
DISABLE = 0,
ENABLE = !DISABLE
}
FunctionalState;
#define IS_FUNCTIONALSTATE_OK(VALUE) ( (VALUE == ENABLE) || (VALUE == DISABLE) )
typedef enum {
ERROR = 0,
SUCCESS = !ERROR
}
ErrorStatus;
#define U8_MAX ((u8)255)
#define S8_MAX ((s8)127)
#define S8_MIN ((s8)-128)
#define U16_MAX ((u16)65535u)
#define S16_MAX ((s16)32767)
#define S16_MIN ((s16)-32768)
#define U32_MAX ((u32)4294967295uL)
#define S32_MAX ((s32)2147483647)
#define S32_MIN ((s32)-2147483648)
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __STM8S_TYPE_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

259
ports/stm8/stm8s_conf.h Normal file
View File

@@ -0,0 +1,259 @@
/**
******************************************************************************
* @file stm8s_conf.h
* @brief This file is used to configure the Library.
* @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_CONF_H
#define __STM8S_CONF_H
/* Atomthreads port: Use STM8S105 */
#define STM8S105
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT 1 */
/* In the following line adjust the value of External High Speed oscillator (HSE)
used in your application */
#if defined (STM8S208) || defined (STM8S207)
#define HSE_VALUE ((u32)24000000) /* Value of the External oscillator in Hz*/
#else
#define HSE_VALUE ((u32)16000000) /* Value of the External oscillator in Hz*/
#endif
/* Uncomment the line below to enable peripheral header file inclusion */
/************************************* ADC ************************************/
#if defined(STM8S105) || defined(STM8S103) || defined(STM8S903)
/* #define _ADC1 (1) */
#endif /* (STM8S105) ||(STM8S103) || (STM8S903) */
#if defined(STM8S208) || defined(STM8S207)
/* #define _ADC2 (1) */
#endif /* (STM8S208) ||(STM8S207) */
/************************************* AWU ************************************/
/* #define _AWU (1) */
/************************************* BEEP ***********************************/
/* #define _BEEP (1) */
/************************************* CLK ************************************/
#ifdef STM8S208
/* #define _CAN (1) */
#endif /* (STM8S208) */
/************************************* CLK ************************************/
#define _CLK (1)
/************************************* EXTI ***********************************/
/* #define _EXTI (1) */
/******************************* FLASH/DATA EEPROM ****************************/
/* #define _FLASH (1) */
/********************************* OPTION BYTES *******************************/
/* #define _OPT (1) */
/************************************* GPIO ***********************************/
#define _GPIO (1)
/************************************* I2C ************************************/
/* #define _I2C (1) */
/************************************* ITC ************************************/
/* #define _ITC (1) */
/************************************* IWDG ***********************************/
/* #define _IWDG (1) */
/************************************* RST ************************************/
/* #define _RST (1) */
/************************************* SPI ************************************/
/* #define _SPI (1) */
/************************************* TIM1 ***********************************/
/* Atomthreads port: Use TIM1 for the system tick (10ms) */
#define _TIM1 (1)
/************************************* TIM2 ***********************************/
#if defined(STM8S208) ||defined(STM8S207) ||defined(STM8S103) ||defined(STM8S105)
/* #define _TIM2 (1) */
#endif /* (STM8S208) ||(STM8S207) || (STM8S103) || (STM8S105) */
/************************************* TIM3 ***********************************/
#if defined(STM8S208) ||defined(STM8S207) ||defined(STM8S105)
/* #define _TIM3 (1) */
#endif /* (STM8S208) ||(STM8S207) || (STM8S105) */
/************************************* TIM4 ***********************************/
#if defined(STM8S208) ||defined(STM8S207) ||defined(STM8S103) ||defined(STM8S105)
/* #define _TIM4 (1) */
#endif /* (STM8S208) ||(STM8S207) || (STM8S103) || (STM8S105) */
/************************************* TIM5 & TIM6 ****************************/
#ifdef STM8S903
/* #define _TIM5 (1) */
/* #define _TIM6 (1) */
#endif /* STM8S903 */
/************************************* UARTx **********************************/
#if defined(STM8S208) ||defined(STM8S207) ||defined(STM8S103) ||defined(STM8S903)
/* #define _UART1 (1) */
#endif /* (STM8S208) ||(STM8S207) || (STM8S103) || (STM8S903) */
#ifdef STM8S105
/* #define _UART2 (1) */
#endif /* STM8S105 */
#if defined(STM8S208) ||defined(STM8S207)
/* #define _UART3 (1) */
#endif /* (STM8S208) ||(STM8S207) */
/************************************* WWDG ***********************************/
/* #define _WWDG (1) */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval : None
*/
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((u8 *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(u8* file, u32 line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
/* Peripheral header file inclusion ******************************************/
#ifdef _ADC1
#include "stm8s_adc1.h"
#endif /* _ADC1 */
#ifdef _ADC2
#include "stm8s_adc2.h"
#endif /* _ADC2 */
#ifdef _AWU
#include "stm8s_awu.h"
#endif /* _AWU */
#ifdef _BEEP
#include "stm8s_beep.h"
#endif /* _BEEP */
#ifdef _CLK
#include "stm8s_clk.h"
#endif /* _CLK */
#ifdef _EXTI
#include "stm8s_exti.h"
#endif /* _EXTI */
#if defined(_FLASH) || defined(_OPT)
#include "stm8s_flash.h"
#endif /* _FLASH/OPT */
#ifdef _GPIO
#include "stm8s_gpio.h"
#endif /* _GPIOx */
#ifdef _I2C
#include "stm8s_i2c.h"
#endif /* _I2C */
#ifdef _ITC
#include "stm8s_itc.h"
#endif /* _ITC */
#ifdef _IWDG
#include "stm8s_iwdg.h"
#endif /* _IWDG */
#ifdef _RST
#include "stm8s_rst.h"
#endif /* _RST */
#ifdef _SPI
#include "stm8s_spi.h"
#endif /* _SPI */
#ifdef _TIM1
#include "stm8s_tim1.h"
#endif /* _TIM1 */
#ifdef _TIM2
#include "stm8s_tim2.h"
#endif /* _TIM2 */
#ifdef _TIM3
#include "stm8s_tim3.h"
#endif /* _TIM3 */
#ifdef _TIM4
#include "stm8s_tim4.h"
#endif /* _TIM4 */
#ifdef _TIM5
#include "stm8s_tim5.h"
#endif /* _TIM5 */
#ifdef _TIM6
#include "stm8s_tim6.h"
#endif /* _TIM6 */
#ifdef _UART1
#include "stm8s_uart1.h"
#endif /* _UART1 */
#ifdef _UART2
#include "stm8s_uart2.h"
#endif /* _UART2 */
#ifdef _UART3
#include "stm8s_uart3.h"
#endif /* _UART3 */
#ifdef _WWDG
#include "stm8s_wwdg.h"
#endif /* _WWDG */
#ifdef _CAN
#include "stm8s_can.h"
#endif /* _CAN */
#endif /* __STM8S_CONF_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

215
ports/stm8/tests-main.c Normal file
View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "atom.h"
#include "atomport-private.h"
#include "atomtests.h"
#include "atomtimer.h"
#include "stm8s.h"
/* Constants */
/*
* Idle thread stack size
*
* This needs to be large enough to handle any interrupt handlers
* and callbacks called by interrupt handlers (e.g. user-created
* timer callbacks) as well as the saving of all context when
* switching away from this thread.
*
* In this case, the idle stack is allocated on the BSS via the
* idle_thread_stack[] byte array.
*/
#define IDLE_STACK_SIZE_BYTES 196
/*
* Startup code stack size
*
* This defines the size of stack allowed for the main() startup
* code before the OS is actually started. This needs to be large
* enough to manage the atomOSInit(), atomOSStart() and
* atomThreadCreate() calls which occur before the OS is started.
*
* In this case we use the default startup stack location used by
* the STM8 compiler of the top of RAM above all data sections
* etc. After the OS is started this allocation is no longer required,
* therefore you could alternatively use some location which you
* know that your application will not use until the OS is started.
* Note that you cannot use the idle thread or main thread stack
* here because the stack contexts of these threads are initialised
* during OS creation.
*
* Instead of reusing some application area, here we set aside
* 64 bytes of RAM for this purpose, because we call out to
* several different test applications, and do not know of any
* particular application locations which will be free to use.
*/
#define STARTUP_STACK_SIZE_BYTES 64
/*
* Main thread stack size
*
* Here we utilise the space starting at 64 bytes below the startup
* stack for the Main application thread. Note that this is not a
* required OS kernel thread - you will replace 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 and loops flashing a LED slowly (if the test passed) or
* quickly (if the test failed).
*
* 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.
*
* Care must be taken to ensure that the data section, BSS section,
* and 64 byte startup section leave enough free space for the main
* thread. You can view the linker-generated map file to view the size
* of the various data sections in your applications. For example if you
* require a 196 byte main thread stack, then the data allocations and
* startup stack combined must not exceed RAMSIZE-196 bytes.
*/
/* Linker-provided startup stack location (usually top of RAM) */
extern int _stack;
/* Local data */
/* Application threads' TCBs */
static ATOM_TCB main_tcb;
/* Idle thread's stack area (large so place outside of the small page0 area on STM8) */
@near static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES];
/* Forward declarations */
static void main_thread_func (uint32_t data);
/**
* \b main
*
* Program entry point.
*
* Sets up the STM8 hardware resources (system tick timer interrupt) necessary
* for the OS to be started. Creates an application thread and starts the OS.
*/
void main ( void )
{
int8_t status;
/**
* Note: to protect OS structures and data during initialisation,
* interrupts must remain disabled until the first thread
* has been restored. They are reenabled at the very end of
* the first thread restore, at which point it is safe for a
* reschedule to take place.
*/
/* Initialise the OS before creating our threads */
status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1]);
if (status == ATOM_OK)
{
/* Enable the system tick timer */
archInitSystemTickTimer();
/* Create an application thread */
status = atomThreadCreate(&main_tcb,
TEST_THREAD_PRIO, main_thread_func, 0,
(POINTER)(&_stack-STARTUP_STACK_SIZE_BYTES));
if (status == ATOM_OK)
{
/**
* First application thread successfully created. It is
* now possible to start the OS. Execution will not return
* from atomOSStart(), which will restore the context of
* our application thread and start executing it.
*
* Note that interrupts are still disabled at this point.
* They will be enabled as we restore and execute our first
* thread in archFirstThreadRestore().
*/
atomOSStart();
}
}
while (1)
;
/* There was an error starting the OS if we reach here */
return;
}
/**
* \b main_thread_func
*
* Entry point for main application thread.
*
* This is the first thread that will be executed when the OS is started.
*
* @param[in] data Unused (optional thread entry parameter)
*
* @return None
*/
static void main_thread_func (uint32_t data)
{
uint32_t test_status;
int sleep_ticks;
/* Start test. All tests use the same start API. */
test_status = test_start();
/* 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);
/* Configure GPIO for flashing the STM8S Discovery LED on GPIO D0 */
GPIO_DeInit(GPIOD);
GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);
/* Test finished, flash slowly for pass, fast for fail */
while (1)
{
/* Toggle LED on pin D0 (Discovery-specific) */
GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
/* Sleep then toggle LED again */
atomTimerDelay(sleep_ticks);
}
}