initial
This commit is contained in:
commit
b07c0607d3
|
|
@ -0,0 +1 @@
|
|||
/build/
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
cmake_minimum_required(VERSION 3.22)
|
||||
project(s8-bathlight C ASM)
|
||||
|
||||
include(./_cmake/sdcc.cmake)
|
||||
|
||||
include_directories(./_common)
|
||||
|
||||
add_executable(s8-bathlight
|
||||
src/main.c
|
||||
)
|
||||
target_link_libraries(s8-bathlight)
|
||||
|
||||
target_compile_definitions(s8-bathlight
|
||||
PUBLIC
|
||||
F_CPU=16000000UL
|
||||
)
|
||||
|
||||
set_target_properties(s8-bathlight
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-mstm8 --nolospre --opt-code-size"
|
||||
LINK_FLAGS "-mstm8"
|
||||
FAMILY stm8
|
||||
PART stm8s103f3
|
||||
)
|
||||
|
||||
target_include_directories(s8-bathlight
|
||||
PUBLIC
|
||||
../_common
|
||||
)
|
||||
|
||||
set_target_properties(s8-bathlight
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-mstm8 --nolospre --opt-code-size"
|
||||
LINK_FLAGS "-mstm8"
|
||||
FAMILY stm8
|
||||
PART stm8s103f3
|
||||
)
|
||||
|
||||
add_upload_to_target(s8-bathlight)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# the name of the target operating system
|
||||
SET(CMAKE_SYSTEM_NAME Generic)
|
||||
|
||||
set(CMAKE_C_FLAGS_INIT "-mstm8 --std-sdcc11 --code-loc 0x8000") # -s
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "")
|
||||
|
||||
# which compilers to use for C and ASM
|
||||
SET(CMAKE_C_COMPILER /usr/bin/sdcc)
|
||||
SET(CMAKE_ASM_COMPILER /usr/bin/sdasstm8)
|
||||
|
||||
find_program (SDCC NAMES sdcc)
|
||||
get_filename_component(SDCC_BIN_DIR ${SDCC} DIRECTORY)
|
||||
get_filename_component(SDCC_PATH_DIR ${SDCC_BIN_DIR} DIRECTORY)
|
||||
|
||||
# here is the target environment is located
|
||||
SET(CMAKE_FIND_ROOT_PATH ${SDCC_PATH_DIR}/usr/share/sdcc)
|
||||
|
||||
# adjust the default behaviour of the FIND_XXX() commands:
|
||||
# search headers and libraries in the target environment, search
|
||||
# programs in the host environment
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
||||
# TODO This is not being recognised
|
||||
set(CMAKE_ASM_OUTPUT_EXTENSION ".rel")
|
||||
|
||||
set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_ASM_COMPILER} -o <OBJECT> <SOURCE>")
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
find_program(STM8FLASH stm8flash
|
||||
DOC "stm8flash binary location"
|
||||
)
|
||||
|
||||
set(STM8FLASH_PROGRAMMER
|
||||
"stlinkv2" CACHE STRING
|
||||
"Choice of stlink, stlinkv2 or espstlink, when not specified in target properties")
|
||||
|
||||
function(add_upload_to_target target)
|
||||
get_target_property(FAMILY ${target} FAMILY)
|
||||
|
||||
if (FAMILY STREQUAL "stm8")
|
||||
if (STM8FLASH STREQUAL "STM8FLASH-NOTFOUND")
|
||||
message(SEND_ERROR "stm8flash is not found")
|
||||
endif()
|
||||
|
||||
get_target_property(STM8_PART ${target} PART)
|
||||
get_target_property(PROGRAMMER ${target} PROGRAMMER)
|
||||
if(PROGRAMMER STREQUAL "PROGRAMMER-NOTFOUND")
|
||||
set(PROGRAMMER ${STM8FLASH_PROGRAMMER})
|
||||
endif()
|
||||
|
||||
add_custom_target(${target}-upload
|
||||
COMMAND ${STM8FLASH} -c ${PROGRAMMER} -p ${STM8_PART} -w ${target}.ihx
|
||||
DEPENDS ${target}
|
||||
COMMENT "Uploading ${target}"
|
||||
)
|
||||
endif()
|
||||
endfunction(add_upload_to_target)
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
#ifndef STM8S103F3_DEF
|
||||
#define STM8S103F3_DEF
|
||||
|
||||
#include <type.h>
|
||||
|
||||
// Interrupt codes
|
||||
#define IRQ_TOP_LVL 0x00
|
||||
#define IRQ_WAKE_UP 0x01
|
||||
#define IRQ_CLOCK 0x02
|
||||
#define IRQ_EXTI_A 0x03
|
||||
#define IRQ_EXTI_B 0x04
|
||||
#define IRQ_EXTI_C 0x05
|
||||
#define IRQ_EXTI_D 0x06
|
||||
#define IRQ_EXTI_E 0x07
|
||||
#define IRQ_SPI_END 0x0A
|
||||
#define IRQ_TIM1_OVERFLOW 0x0B
|
||||
#define IRQ_TIM1_COMCAP 0x0C
|
||||
#define IRQ_TIM2_OVERFLOW 0x0D
|
||||
#define IRQ_TIM2_COMCAP 0x0E
|
||||
#define IRQ_UART1_TX_C 0x11
|
||||
#define IRQ_UART1_RX_F 0x12
|
||||
#define IRQ_I2C 0x13
|
||||
#define IRQ_ADC_END 0x16
|
||||
#define IRQ_TIM4_OVERFLOW 0x17
|
||||
#define IRQ_FLASH 0x18
|
||||
|
||||
// Map port registres to structures
|
||||
#define PORT_A (*(Port*) 0x5000)
|
||||
#define PORT_B (*(Port*) 0x5005)
|
||||
#define PORT_C (*(Port*) 0x500A)
|
||||
#define PORT_D (*(Port*) 0x500F)
|
||||
#define PORT_E (*(Port*) 0x5014)
|
||||
#define PORT_F (*(Port*) 0x501A)
|
||||
|
||||
// Uart to structure
|
||||
#define UART1 (*(UART*) 0x5230)
|
||||
|
||||
// GPIO Interrupt control structures
|
||||
#define EXTI_CR1 (*(ExternalInterruptControlFull*) 0x50A0)
|
||||
#define EXTI_CR2 (*(ExternalInterruptControlLim*) 0x50A1)
|
||||
|
||||
// #define CLK_CKDIVR (*(volatile u08*) 0x50C6)
|
||||
// #define CLK_PCKENR1 (*(volatile u08*) 0x50C7)
|
||||
|
||||
#define UART_SR_TXE (1 << 7)
|
||||
|
||||
#define FLASH (*(Flash*) 0x505A)
|
||||
#define UNLOCK_DATA_KEY1 0xAE
|
||||
#define UNLOCK_DATA_KEY2 0x56
|
||||
|
||||
#define FLASH_PROG_START 0x8000
|
||||
#define FLASH_PROG_END 0x9FFF
|
||||
#define FLASH_DATA_START 0x4000
|
||||
#define FLASH_DATA_END 0x427F
|
||||
|
||||
// #define SERIAL_ADDRESS FLASH_DATA_START
|
||||
// #define SERIAL ((_MEM_(SERIAL_ADDRESS + 1) << 8) | _MEM_(SERIAL_ADDRESS))
|
||||
#define AES_KEY_ADDRESS (FLASH_DATA_START + 2)
|
||||
|
||||
#define TIM1 (*(AdvancedTimer*) 0x5250)
|
||||
#define I2C1 (*(volatile I2C*) 0x5210)
|
||||
#define CLK (*(Clock*) 0x50C0)
|
||||
#define WWDG (*(Watchdog*) 0x50D1)
|
||||
#define ADC1 (*(ADC*) 0x5400)
|
||||
#define TIM2 (*(GeneralTimer*) 0x5300)
|
||||
|
||||
#define I2C_SR1 (*(u08*) 0x5217)
|
||||
#define I2C_SR2 (*(u08*) 0x5218)
|
||||
#define I2C_SR3 (*(u08*) 0x5219)
|
||||
|
||||
#define CFG_GCR (*(u08*) 0x7F60)
|
||||
#define IWATCHDOG (*(IndependWatchdog*) 0x50E0)
|
||||
|
||||
#endif//STM8S103F3_DEF
|
||||
|
|
@ -0,0 +1,701 @@
|
|||
#ifndef STM_BASE_H
|
||||
#define STM_BASE_H
|
||||
|
||||
#include <type.h>
|
||||
|
||||
// Enable interrupts
|
||||
#define rim() {__asm__("rim\n");}
|
||||
|
||||
// Disable interrupts
|
||||
#define sim() {__asm__("sim\n");}
|
||||
|
||||
// Do nothing
|
||||
#define nop() {__asm__("nop\n");}
|
||||
|
||||
// Trap (Soft IT)
|
||||
#define trap() {__asm__("trap\n");}
|
||||
|
||||
// Wait for interrupt
|
||||
#define wfi() {__asm__("wfi\n");}
|
||||
|
||||
// Halt
|
||||
#define halt() {__asm__("halt\n");}
|
||||
|
||||
|
||||
// Interrupt
|
||||
#define interrupt(key, name) void name(void) __interrupt(key)
|
||||
|
||||
// Pins structure (easy access to each pin)
|
||||
typedef struct {
|
||||
u08 Pin0 :1;
|
||||
u08 Pin1 :1;
|
||||
u08 Pin2 :1;
|
||||
u08 Pin3 :1;
|
||||
u08 Pin4 :1;
|
||||
u08 Pin5 :1;
|
||||
u08 Pin6 :1;
|
||||
u08 Pin7 :1;
|
||||
} Pins;
|
||||
|
||||
// Port structure (all pins control)
|
||||
typedef struct {
|
||||
Pins ODR;
|
||||
Pins IDR;
|
||||
Pins DDR;
|
||||
Pins CR1;
|
||||
Pins CR2;
|
||||
} Port;
|
||||
|
||||
// Uart register structure
|
||||
typedef struct {
|
||||
u08 Status :8;
|
||||
u08 Data :8;
|
||||
u08 BRR1 :8;
|
||||
u08 BRR2 :8;
|
||||
u08 CR1 :8;
|
||||
u08 CR2 :8;
|
||||
u08 CR3 :8;
|
||||
u08 CR4 :8;
|
||||
u08 CR5 :8;
|
||||
u08 GTR :8;
|
||||
u08 PSCR :8;
|
||||
} UART;
|
||||
|
||||
// Uart configuration bits
|
||||
#define UART_TX_EMPTY (1 << 7)
|
||||
#define UART_TX_COMPLETE (1 << 6)
|
||||
#define UART_RX_NOT_EMPTY (1 << 5)
|
||||
#define UART_RX_IDLE (1 << 4)
|
||||
#define UART_RX_OVERRUN (1 << 3)
|
||||
#define UART_RX_NOISE (1 << 2)
|
||||
#define UART_RX_FRAME_ERROR (1 << 1)
|
||||
#define UART_RX_PARITY_ERROR (1 << 0)
|
||||
|
||||
#define UART_CR2_SBK (1 << 0)
|
||||
#define UART_CR2_RWU (1 << 1)
|
||||
#define UART_CR2_REN (1 << 2)
|
||||
#define UART_CR2_TEN (1 << 3)
|
||||
#define UART_CR2_IDLE_IVT (1 << 4)
|
||||
#define UART_CR2_RXNE_IVT (1 << 5)
|
||||
#define UART_CR2_TXC_IVT (1 << 6)
|
||||
#define UART_CR2_TXE_IVT (1 << 7)
|
||||
|
||||
#define UART_CR3_LINEN (1 << 6)
|
||||
#define UART_CR3_STOP2 (1 << 5)
|
||||
#define UART_CR3_STOP1 (1 << 4)
|
||||
#define UART_CR3_CLKEN (1 << 3)
|
||||
#define UART_CR3_CLKPOL (1 << 2)
|
||||
#define UART_CR3_CLKPHA (1 << 1)
|
||||
#define UART_CR3_LBCL (1 << 0)
|
||||
|
||||
// Delay function (in ticks)
|
||||
static void delay_tick(unsigned int t)
|
||||
{
|
||||
while(t--);
|
||||
}
|
||||
|
||||
// GPIO Control register structure (1)
|
||||
typedef struct {
|
||||
u08 PortA :2;
|
||||
u08 PortB :2;
|
||||
u08 PortC :2;
|
||||
u08 PortD :2;
|
||||
} ExternalInterruptControlFull;
|
||||
|
||||
// GPIO Control register structure (2)
|
||||
typedef struct {
|
||||
u08 PortE :2;
|
||||
} ExternalInterruptControlLim;
|
||||
|
||||
// GPIO interrupt mode
|
||||
#define EXTI_FALLING_LOW 0x00
|
||||
#define EXTI_RISING 0x01
|
||||
#define EXTI_FALLING 0x02
|
||||
#define EXTI_RISING_FALLING 0x03
|
||||
|
||||
// Flash control register struct (1)
|
||||
typedef struct {
|
||||
u08 FixedTime :1;
|
||||
u08 Interrupt :1;
|
||||
u08 ActiveHaltPowerDown :1;
|
||||
u08 HaltPowerDown :1;
|
||||
u08 :4;
|
||||
} FlashControl1;
|
||||
|
||||
// Flash control register struct (2)
|
||||
typedef struct {
|
||||
u08 StandardBlockProgramming :1;
|
||||
u08 :3;
|
||||
u08 FastBlockProgramming :1;
|
||||
u08 BlockErase :1;
|
||||
u08 WordProgramming :1;
|
||||
u08 WriteOptionBytes :1;
|
||||
} FlashControl2;
|
||||
|
||||
typedef struct {
|
||||
u08 UserBootAreaSize :6;
|
||||
u08 :2;
|
||||
} FlashProtection;
|
||||
|
||||
// Flash status register struct
|
||||
typedef struct {
|
||||
u08 AttemptWriteProtected :1;
|
||||
u08 FlashUnlocked :1;
|
||||
u08 EndOfOperation :1;
|
||||
u08 DataUnlocked :1;
|
||||
u08 :2;
|
||||
u08 EndOfHV :1;
|
||||
u08 :1;
|
||||
} FlashStatus;
|
||||
|
||||
typedef struct {
|
||||
FlashControl1 Control1;
|
||||
FlashControl2 Control2;
|
||||
FlashControl2 ComplimentaryControl;
|
||||
FlashProtection Protection;
|
||||
FlashProtection NProtection;
|
||||
FlashStatus Status;
|
||||
u16 :16;
|
||||
u08 FlashProtectionKey :8;
|
||||
u08 :8;
|
||||
u08 DataProtectionKey :8;
|
||||
} Flash;
|
||||
|
||||
#define FLASH_UNLOCK_KEY1 0x56
|
||||
#define FLASH_UNLOCK_KEY2 0xAE
|
||||
|
||||
#define DATA_UNLOCK_KEY1 0xAE
|
||||
#define DATA_UNLOCK_KEY2 0x56
|
||||
|
||||
#define _MEM_(mem_addr) (*(volatile u08*)(mem_addr))
|
||||
|
||||
|
||||
typedef struct {
|
||||
u08 CounterEnable :1;
|
||||
u08 UpdateDisable :1;
|
||||
u08 UpdateRequestSource :1;
|
||||
u08 OnePulseMode :1;
|
||||
u08 Direction :1;
|
||||
u08 CenterAlignedMode :1;
|
||||
u08 AutoReloadPreload :1;
|
||||
} TimerControl1;
|
||||
|
||||
typedef struct {
|
||||
u08 CaptureCountrolPreload :1;
|
||||
u08 :1;
|
||||
u08 CaptureControlUpdate :1;
|
||||
u08 :1;
|
||||
u08 MasterMode :3;
|
||||
u08 :1;
|
||||
} TimerControl2;
|
||||
|
||||
typedef struct {
|
||||
u08 Mode :3;
|
||||
u08 :1;
|
||||
u08 Trigger :3;
|
||||
u08 MasterSlave :1;
|
||||
} TimerSlaveControl;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u08 Filter :4;
|
||||
u08 Prescaler :2;
|
||||
u08 ExternalClock :1;
|
||||
u08 TriggerPolariry :1;
|
||||
} TimerExternalTrigger;
|
||||
|
||||
typedef struct {
|
||||
u08 UpdateInterrupt :1;
|
||||
u08 Capture1Interrupt :1;
|
||||
u08 Capture2Interrupt :1;
|
||||
u08 Capture3Interrupt :1;
|
||||
u08 Capture4Interrupt :1;
|
||||
u08 CommutationInterrupt :1;
|
||||
u08 TriggerInterrupt :1;
|
||||
u08 BreakInterrupt :1;
|
||||
} TimerInterrupt;
|
||||
|
||||
typedef struct {
|
||||
u08 UpdateInterruptFlag :1;
|
||||
u08 Capture1InterruptFlag :1;
|
||||
u08 Capture2InterruptFlag :1;
|
||||
u08 Capture3InterruptFlag :1;
|
||||
u08 Capture4InterruptFlag :1;
|
||||
u08 CommutationInterruptFlag :1;
|
||||
u08 TriggerInterruptFlag :1;
|
||||
u08 BreakInterruptFlag :1;
|
||||
} TimerStatus1;
|
||||
|
||||
typedef struct {
|
||||
u08 :1;
|
||||
u08 Capture1OvercaptureFlag :1;
|
||||
u08 Capture2OvercaptureFlag :1;
|
||||
u08 Capture3OvercaptureFlag :1;
|
||||
u08 Capture4OvercaptureFlag :1;
|
||||
u08 :3;
|
||||
} TimerStatus2;
|
||||
|
||||
typedef struct {
|
||||
u08 UpdateGeneration :1;
|
||||
u08 Capture1Generation :1;
|
||||
u08 Capture2Generation :1;
|
||||
u08 Capture3Generation :1;
|
||||
u08 Capture4Generation :1;
|
||||
u08 CaptureUpdateGeneration :1;
|
||||
u08 TriggerGeneration :1;
|
||||
u08 BreakGeneration :1;
|
||||
} TimerEventGen;
|
||||
|
||||
typedef struct {
|
||||
u08 Enable1 :1;
|
||||
u08 Polarity1 :1;
|
||||
u08 ComplimentaryEnable1 :1;
|
||||
u08 ComplimentaryPolarity1 :1;
|
||||
u08 Enable2 :1;
|
||||
u08 Polarity2 :1;
|
||||
u08 ComplimentaryEnable2 :1;
|
||||
u08 ComplimentaryPolarity2 :1;
|
||||
} TimerCaptureRegister1;
|
||||
|
||||
typedef struct {
|
||||
u08 Enable3 :1;
|
||||
u08 Polarity3 :1;
|
||||
u08 ComplimentaryEnable3 :1;
|
||||
u08 ComplimentaryPolarity3 :1;
|
||||
u08 Enable4 :1;
|
||||
u08 Polarity4 :1;
|
||||
u08 ComplimentaryEnable4 :1;
|
||||
u08 ComplimentaryPolarity4 :1;
|
||||
} TimerCaptureRegister2;
|
||||
|
||||
typedef struct {
|
||||
TimerControl1 Control1;
|
||||
TimerControl2 Control2;
|
||||
TimerSlaveControl SlaveControl;
|
||||
TimerExternalTrigger ExternalTrigger;
|
||||
TimerInterrupt Interrupt;
|
||||
TimerStatus1 Status1;
|
||||
TimerStatus2 Status2;
|
||||
TimerEventGen EventGeneration;
|
||||
u08 CaptureMode1 :8;
|
||||
u08 CaptureMode2 :8;
|
||||
u08 CaptureMode3 :8;
|
||||
u08 CaptureMode4 :8;
|
||||
TimerCaptureRegister1 Capture12;
|
||||
TimerCaptureRegister2 Capture34;
|
||||
u08 CounterH :8;
|
||||
u08 CounterL :8;
|
||||
u08 PrescalerH :8;
|
||||
u08 PrescalerL :8;
|
||||
u08 AutoReloadH :8;
|
||||
u08 AutoReloadL :8;
|
||||
} AdvancedTimer;
|
||||
|
||||
typedef struct {
|
||||
u08 Enable :1;
|
||||
u08 :5;
|
||||
u08 GeneralCallEnable :1;
|
||||
u08 NoStretch :1;
|
||||
} I2CControl1;
|
||||
|
||||
typedef struct {
|
||||
u08 Start :1;
|
||||
u08 Stop :1;
|
||||
u08 Acknowledge :1;
|
||||
u08 AcknowledgePosition :1;
|
||||
u08 :3;
|
||||
u08 SoftwareReset :1;
|
||||
} I2CControl2;
|
||||
|
||||
typedef struct {
|
||||
u08 Address10Bit0 :1;
|
||||
u08 Address :7;
|
||||
} I2CAddressL;
|
||||
|
||||
typedef struct {
|
||||
u08 :1;
|
||||
u08 Address10Bit89 :2;
|
||||
u08 :3;
|
||||
u08 AddressConfig :1;
|
||||
u08 AddressMode :1;
|
||||
} I2CAddressH;
|
||||
|
||||
typedef struct {
|
||||
u08 StartBit :1;
|
||||
u08 AddressSent :1;
|
||||
u08 ByteTransferFinished :1;
|
||||
u08 Address10Bit0 :1;
|
||||
u08 StopFlag :1;
|
||||
u08 :1;
|
||||
u08 ReceiveNotEmpty :1;
|
||||
u08 TransmitEmpty :1;
|
||||
} I2CStatus1;
|
||||
|
||||
typedef struct {
|
||||
u08 BusError :1;
|
||||
u08 ArbitrationLost :1;
|
||||
u08 AcknowledgeFailure :1;
|
||||
u08 Overrun :1;
|
||||
u08 :1;
|
||||
u08 WakeUp :1;
|
||||
u08 :2;
|
||||
} I2CStatus2;
|
||||
|
||||
typedef struct {
|
||||
u08 MasterMode :1;
|
||||
u08 BusBusy :1;
|
||||
u08 Transmitting :1;
|
||||
u08 :1;
|
||||
u08 GeneralCallHeader :1;
|
||||
u08 :2;
|
||||
u08 DualFlag :1;
|
||||
} I2CStatus3;
|
||||
|
||||
typedef struct {
|
||||
u08 Error :1;
|
||||
u08 Event :1;
|
||||
u08 Buffer :1;
|
||||
u08 :5;
|
||||
} I2CInterrupt;
|
||||
|
||||
typedef struct {
|
||||
u16 Clock :12;
|
||||
u08 :2;
|
||||
u08 FastModeDuty :1;
|
||||
u08 FastMode :1;
|
||||
} I2CClockControl;
|
||||
|
||||
typedef struct {
|
||||
u08 Time :6;
|
||||
u08 :2;
|
||||
} I2CRiseControl;
|
||||
|
||||
typedef struct {
|
||||
I2CControl1 Control1;
|
||||
I2CControl2 Control2;
|
||||
u08 Frequency :6;
|
||||
u08 :2;
|
||||
I2CAddressL AddressL;
|
||||
I2CAddressH AddressH;
|
||||
u08 :8;
|
||||
u08 Data :8;
|
||||
I2CStatus1 Status1;
|
||||
I2CStatus2 Status2;
|
||||
I2CStatus3 Status3;
|
||||
I2CInterrupt Interrupt;
|
||||
I2CClockControl ClockControl;
|
||||
I2CRiseControl TimeRise;
|
||||
u08 :8; // Errors
|
||||
} I2C;
|
||||
|
||||
typedef struct {
|
||||
u08 HighSpeedInternalEnable :1;
|
||||
u08 HighSpeedInternalReady :1;
|
||||
u08 FastWakeUp :1;
|
||||
u08 LowSpeedInternalEnable :1;
|
||||
u08 LowSpeedInternalReady :1;
|
||||
u08 RegulatorPoweroff :1;
|
||||
u08 :2;
|
||||
} ClockInternal;
|
||||
|
||||
typedef struct {
|
||||
u08 HighSpeedExternalEnable :1;
|
||||
u08 HighSpeedExternalReady :1;
|
||||
u08 :6;
|
||||
} ClockExternal;
|
||||
|
||||
typedef enum {
|
||||
HighSpeedExternal = 0xB4,
|
||||
LowSpeedInternal = 0xD2,
|
||||
HighSpeedInternal = 0xE1
|
||||
} ClockMasterType;
|
||||
|
||||
typedef struct {
|
||||
u08 SwitchBusy :1;
|
||||
u08 SwitchStartStop :1;
|
||||
u08 SwitchInterrupt :1;
|
||||
u08 SwitchInterruptFlag :1;
|
||||
u08 :4;
|
||||
} ClockSwitch;
|
||||
|
||||
typedef struct {
|
||||
u08 Prescaler :3;
|
||||
u08 HighSpeedPrescaler :2;
|
||||
u08 :3;
|
||||
} ClockDivider;
|
||||
|
||||
typedef struct {
|
||||
u08 I2C :1;
|
||||
u08 SPI :1;
|
||||
u08 :1;
|
||||
u08 Serial1 :1;
|
||||
u08 Timer4 :1;
|
||||
u08 Timer2 :1;
|
||||
u08 :1;
|
||||
u08 Timer1 :1;
|
||||
} ClockPeripheral1;
|
||||
|
||||
typedef struct {
|
||||
u08 :2;
|
||||
u08 AutoWakeUp :1;
|
||||
u08 AnalogDigitalConvertor :1;
|
||||
u08 :4;
|
||||
} ClockPeripheral2;
|
||||
|
||||
typedef struct {
|
||||
u08 Enable :1;
|
||||
u08 AuxiliaryConnected :1;
|
||||
u08 DetectionInterrupt :1;
|
||||
u08 Detection :1;
|
||||
u08 :4;
|
||||
} ClockSecuritySystem;
|
||||
|
||||
typedef struct {
|
||||
u08 Enable :1;
|
||||
u08 Selection :4;
|
||||
u08 Ready :1;
|
||||
u08 Busy :1;
|
||||
u08 :1;
|
||||
} ClockOutput;
|
||||
|
||||
typedef struct {
|
||||
u08 HighSpeedIntenalTrim :4;
|
||||
u08 :4;
|
||||
} ClockTrimming;
|
||||
|
||||
typedef struct {
|
||||
u08 Divider :1;
|
||||
u08 :7;
|
||||
} ClockSWIM;
|
||||
|
||||
typedef struct {
|
||||
ClockInternal Internal;
|
||||
ClockExternal External;
|
||||
u08 :8;
|
||||
ClockMasterType MasterStatus :8;
|
||||
ClockMasterType MasterSwitch :8;
|
||||
ClockSwitch SwitchControl;
|
||||
ClockDivider Divider;
|
||||
ClockPeripheral1 Peripheral1;
|
||||
ClockSecuritySystem SecuritySystem;
|
||||
ClockOutput Output;
|
||||
ClockPeripheral2 Peripheral2;
|
||||
u08 :8;
|
||||
ClockTrimming Trimming;
|
||||
ClockSWIM SWIM;
|
||||
} Clock;
|
||||
|
||||
typedef struct {
|
||||
u08 Counter :7;
|
||||
u08 Activate :1;
|
||||
} WatchdogControl;
|
||||
|
||||
typedef struct {
|
||||
u08 Counter :7;
|
||||
u08 :1;
|
||||
} WatchdogWindow;
|
||||
|
||||
typedef struct {
|
||||
WatchdogControl Control;
|
||||
WatchdogWindow Window;
|
||||
} Watchdog;
|
||||
|
||||
typedef struct {
|
||||
u08 High :8;
|
||||
u08 Low :8;
|
||||
} ADCBuffer;
|
||||
|
||||
typedef struct {
|
||||
u08 Channel :4;
|
||||
u08 AnalogWatchdogInterrupt :1;
|
||||
u08 Interrupt :1;
|
||||
u08 AnalogWatchdog :1;
|
||||
u08 EndOfConversion :1;
|
||||
} ADCControlStatus;
|
||||
|
||||
typedef struct {
|
||||
u08 ConverterOn :1;
|
||||
u08 ContinousConversion :1;
|
||||
u08 :2;
|
||||
u08 Prescaler :3;
|
||||
u08 :1;
|
||||
} ADCConfig1;
|
||||
|
||||
typedef struct {
|
||||
u08 :1;
|
||||
u08 ScanMode :1;
|
||||
u08 :1;
|
||||
u08 Alignment :1;
|
||||
u08 ExternalEventSelection :2;
|
||||
u08 ExternalTrigger :1;
|
||||
u08 :1;
|
||||
} ADCConfig2;
|
||||
|
||||
typedef struct {
|
||||
u08 :6;
|
||||
u08 OverrunFlag :1;
|
||||
u08 DataBufferEnable :1;
|
||||
} ADCConfig3;
|
||||
|
||||
typedef struct {
|
||||
u08 High :8;
|
||||
u08 Low :8;
|
||||
} ADCData;
|
||||
|
||||
typedef struct {
|
||||
u08 High :8;
|
||||
u08 Low :2;
|
||||
u08 :6;
|
||||
} ADCThreshold;
|
||||
|
||||
typedef struct {
|
||||
ADCControlStatus ControlStatus;
|
||||
ADCConfig1 Configuration1;
|
||||
ADCConfig2 Configuration2;
|
||||
ADCConfig3 Configuration3;
|
||||
ADCData Data;
|
||||
ADCData SchmittDisable;
|
||||
ADCThreshold HighThreshold;
|
||||
ADCThreshold LowThreshold;
|
||||
u08 :8; // Watchdog
|
||||
u08 :8; // Watchdog
|
||||
u08 :8; // Watchdog
|
||||
u08 :8; // Watchdog
|
||||
} ADC;
|
||||
|
||||
typedef struct {
|
||||
u08 Enable :1;
|
||||
u08 UpdateDisable :1;
|
||||
u08 UpdateRequestSource :1;
|
||||
u08 OnePulseMode :1;
|
||||
u08 :3;
|
||||
u08 AutoReload :1;
|
||||
} GeneralTimerControl1;
|
||||
|
||||
typedef struct {
|
||||
u08 :4;
|
||||
u08 MasterModeSelection :3;
|
||||
u08 :1;
|
||||
} GeneralTimerControl2;
|
||||
|
||||
typedef struct {
|
||||
u08 SlaveModeSelection :3;
|
||||
u08 :1;
|
||||
u08 TriggerSelection :3;
|
||||
u08 MasterSlaveMode :1;
|
||||
} GeneralTimerSlaveControl;
|
||||
|
||||
typedef struct {
|
||||
u08 UpdateInterrupt :1;
|
||||
u08 Capture1Interrupt :1;
|
||||
u08 Capture2Interrupt :1;
|
||||
u08 Capture3Interrupt :1;
|
||||
u08 :2;
|
||||
u08 TriggerInterrupt :1;
|
||||
u08 :1;
|
||||
} GeneralTimerInterrupt;
|
||||
|
||||
typedef struct {
|
||||
u08 UpdateInterruptFlag :1;
|
||||
u08 Capture1InterruptFlag :1;
|
||||
u08 Capture2InterruptFlag :1;
|
||||
u08 Capture3InterruptFlag :1;
|
||||
u08 :2;
|
||||
u08 TriggerInterruptFlag :1;
|
||||
u08 :1;
|
||||
} GeneralTimerStatus1;
|
||||
|
||||
typedef struct {
|
||||
u08 :1;
|
||||
u08 Overcapture1Flag :1;
|
||||
u08 Overcapture2Flag :1;
|
||||
u08 Overcapture3Flag :1;
|
||||
u08 :4;
|
||||
} GeneralTimerStatus2;
|
||||
|
||||
typedef struct {
|
||||
u08 UpdateGeneration :1;
|
||||
u08 Capture1Generation :1;
|
||||
u08 Capture2Generation :1;
|
||||
u08 Capture3Generation :1;
|
||||
u08 :2;
|
||||
u08 TriggerGeneration :1;
|
||||
u08 :1;
|
||||
} GeneralTimerEventGeneration;
|
||||
|
||||
typedef struct {
|
||||
u08 CaptureSelection :2;
|
||||
u08 :1;
|
||||
u08 PreloadEnable :1;
|
||||
u08 CompareMode :3;
|
||||
u08 :1;
|
||||
} GeneralTimerCaptureMode;
|
||||
|
||||
typedef struct {
|
||||
u08 Capture1Enable :1;
|
||||
u08 Capture1Polarity :1;
|
||||
u08 :2;
|
||||
u08 Capture2Enable :1;
|
||||
u08 Capture2Polarity :1;
|
||||
u08 :2;
|
||||
} GeneralTimerCaptureRegister1;
|
||||
|
||||
typedef struct {
|
||||
u08 Capture3Enable :1;
|
||||
u08 Capture3Polarity :1;
|
||||
u08 :6;
|
||||
} GeneralTimerCaptureRegister2;
|
||||
|
||||
typedef struct {
|
||||
u08 High :8;
|
||||
u08 Low :8;
|
||||
} GeneralTimer16Register;
|
||||
|
||||
|
||||
typedef struct {
|
||||
GeneralTimerControl1 Control1;
|
||||
u08 :8;
|
||||
u08 :8;
|
||||
GeneralTimerInterrupt Interrupt;
|
||||
GeneralTimerStatus1 Status1;
|
||||
GeneralTimerStatus2 Status2;
|
||||
GeneralTimerEventGeneration Event;
|
||||
GeneralTimerCaptureMode Capture1;
|
||||
GeneralTimerCaptureMode Capture2;
|
||||
GeneralTimerCaptureMode Capture3;
|
||||
GeneralTimerCaptureRegister1 CaptureReg1;
|
||||
GeneralTimerCaptureRegister2 CaptureReg2;
|
||||
GeneralTimer16Register Counter;
|
||||
u08 Prescaler :4;
|
||||
u08 :4;
|
||||
GeneralTimer16Register AutoReload;
|
||||
GeneralTimer16Register Compare1;
|
||||
GeneralTimer16Register Compare2;
|
||||
GeneralTimer16Register Compare3;
|
||||
} GeneralTimer;
|
||||
|
||||
typedef enum {
|
||||
IndependWatchdogOff = 0x00,
|
||||
IndependWatchdogEdit = 0x55,
|
||||
IndependWatchdogReset= 0xAA,
|
||||
IndependWatchdogOn = 0xCC
|
||||
} IndependWatchdogKey;
|
||||
|
||||
|
||||
typedef enum {
|
||||
WatchdogPrescaler_4 = 0x00,
|
||||
WatchdogPrescaler_8 = 0x01,
|
||||
WatchdogPrescaler_16 = 0x02,
|
||||
WatchdogPrescaler_32 = 0x03,
|
||||
WatchdogPrescaler_64 = 0x04,
|
||||
WatchdogPrescaler_128= 0x05,
|
||||
WatchdogPrescaler_256= 0x06
|
||||
} WatchdogPrescaler;
|
||||
|
||||
typedef struct {
|
||||
IndependWatchdogKey Key :8;
|
||||
WatchdogPrescaler Prescaler :3;
|
||||
u08 :5;
|
||||
u08 Reload :8;
|
||||
} IndependWatchdog;
|
||||
#endif//STM_BASE_H
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef STM_TYPE_H
|
||||
#define STM_TYPE_H
|
||||
|
||||
|
||||
// Here defined basic types used in code
|
||||
typedef unsigned char u08;
|
||||
typedef signed char i08;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short i16;
|
||||
typedef unsigned long u32;
|
||||
typedef signed long i32;
|
||||
typedef unsigned char bool;
|
||||
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
#define STRLLEN(x) (sizeof(x) - 1)
|
||||
|
||||
|
||||
#endif//STM_TYPE_H
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
mkdir -p build
|
||||
(cd build && cmake --toolchain ../_cmake/sdcc-toolchain.cmake .. && make)
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
#include <type.h>
|
||||
#include <stm_base.h>
|
||||
#include <stm8s103f3.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define WATCHDOG
|
||||
|
||||
#define BUFFER_LEN 48
|
||||
|
||||
#define LED_PIN_DIR PORT_C.DDR.Pin3
|
||||
#define LED_PIN_CR1 PORT_C.CR1.Pin3
|
||||
#define LED_PIN_CR2 PORT_C.CR2.Pin3
|
||||
#define LED_PIN_OUT PORT_C.ODR.Pin3
|
||||
|
||||
#define RX_PIN_DIR PORT_D.DDR.Pin6
|
||||
#define RX_PIN_CR1 PORT_D.CR1.Pin6
|
||||
#define RX_PIN_CR2 PORT_D.CR2.Pin6
|
||||
#define RX_PIN_OUT PORT_D.ODR.Pin6
|
||||
|
||||
#define TX_PIN_DIR PORT_D.DDR.Pin5
|
||||
#define TX_PIN_CR1 PORT_D.CR1.Pin5
|
||||
#define TX_PIN_CR2 PORT_D.CR2.Pin5
|
||||
#define TX_PIN_OUT PORT_D.ODR.Pin5
|
||||
|
||||
#define SHORT_PRESS_MS 25
|
||||
#define LONG_PRESS_MS 1000
|
||||
|
||||
// Countdown timestamp (2^15 max, sign used to notify "unitialized")
|
||||
volatile i16 countdown_tick = 0;
|
||||
|
||||
// volatile u08 exec = 0;
|
||||
volatile i16 timer = 0;
|
||||
|
||||
volatile u08 cmd[BUFFER_LEN];
|
||||
volatile u08 cmdPos = 0;
|
||||
volatile u08 cmdLen = 0;
|
||||
volatile u08 state = 0;
|
||||
|
||||
void reboot(void) {
|
||||
#ifdef WATCHDOG
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
#else
|
||||
delay_tick(0xffff);
|
||||
#endif
|
||||
WWDG.Control.Activate = 1;
|
||||
WWDG.Control.Counter = 0;
|
||||
}
|
||||
|
||||
void start_cmd(u08 len) {
|
||||
cmdPos = 0;
|
||||
cmdLen = len;
|
||||
UART1.CR2 |= UART_CR2_TXE_IVT;
|
||||
UART1.Data = cmd[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark current time for further comparison
|
||||
*/
|
||||
inline void start_countdown(void) {
|
||||
countdown_tick = (TIM1.CounterH << 8) | TIM1.CounterL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark countdown as unitialized
|
||||
*/
|
||||
inline void stop_countdown(void) {
|
||||
countdown_tick = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if countdown is active
|
||||
*/
|
||||
inline bool is_countdown_active(void) {
|
||||
return countdown_tick >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time elapsed from countdown start in ms
|
||||
*/
|
||||
i16 elapsed(void) {
|
||||
if (!is_countdown_active()) {
|
||||
return -1;
|
||||
}
|
||||
u16 next = (TIM1.CounterH << 8) | TIM1.CounterL;
|
||||
if (next < countdown_tick) {
|
||||
return (next + 2500) - countdown_tick;
|
||||
} else {
|
||||
return next - countdown_tick;
|
||||
}
|
||||
}
|
||||
|
||||
void send_some_command(void) {
|
||||
cmd[0] = 'C';
|
||||
cmd[1] = 'M';
|
||||
cmd[2] = 'D';
|
||||
start_cmd(3);
|
||||
}
|
||||
|
||||
void initialize_state(void) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
send_some_command();
|
||||
// initialization step 0
|
||||
break;
|
||||
case 1:
|
||||
send_some_command();
|
||||
// initialization step 1
|
||||
break;
|
||||
}
|
||||
state++;
|
||||
}
|
||||
|
||||
#define LED_DELAY 888
|
||||
u08 led_state = 0;
|
||||
void turn_on(void) {
|
||||
if (led_state == 1) {
|
||||
return;
|
||||
}
|
||||
led_state = 1;
|
||||
u16 delay = LED_DELAY;
|
||||
while (delay > 1) {
|
||||
LED_PIN_OUT ^= 1;
|
||||
delay_tick(delay);
|
||||
delay--;
|
||||
}
|
||||
LED_PIN_OUT = 1;
|
||||
}
|
||||
|
||||
void turn_off(void) {
|
||||
if (led_state == 0) {
|
||||
return;
|
||||
}
|
||||
led_state = 0;
|
||||
u16 delay = 1;
|
||||
while (delay < LED_DELAY) {
|
||||
LED_PIN_OUT ^= 1;
|
||||
delay_tick(delay);
|
||||
delay++;
|
||||
}
|
||||
LED_PIN_OUT = 0;
|
||||
}
|
||||
|
||||
void tick_250ms(void) {
|
||||
if (timer > 0) {
|
||||
timer--;
|
||||
}
|
||||
if (timer != 0) {
|
||||
turn_on();
|
||||
} else {
|
||||
turn_off();
|
||||
}
|
||||
if (state < 2) {
|
||||
initialize_state();
|
||||
}
|
||||
}
|
||||
|
||||
interrupt(IRQ_UART1_RX_F, uart_recv) {
|
||||
u08 s = UART1.Status;
|
||||
u08 c = UART1.Data;
|
||||
// if (exec == 1) {
|
||||
// switch (c) {
|
||||
// case 0x2A:
|
||||
// timer = 1200;
|
||||
// break;
|
||||
// case 0x2B:
|
||||
// timer = -1;
|
||||
// break;
|
||||
// case 0x2C:
|
||||
// timer = 0;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (c == 0x24) {
|
||||
// exec = 1;
|
||||
// } else {
|
||||
// exec = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
interrupt(IRQ_UART1_TX_C, uart_sent) {
|
||||
cmdPos++;
|
||||
if (cmdPos < cmdLen) {
|
||||
UART1.Data = cmd[cmdPos];
|
||||
} else {
|
||||
cmdPos = 0;
|
||||
cmdLen = 0;
|
||||
memset(cmd, '\0', BUFFER_LEN);
|
||||
UART1.CR2 &= ~UART_CR2_TXE_IVT;
|
||||
}
|
||||
}
|
||||
|
||||
interrupt(IRQ_EXTI_C, touch) {
|
||||
if (PORT_C.IDR.Pin4) {
|
||||
// Mark touch start
|
||||
start_countdown();
|
||||
} else if (is_countdown_active()) {
|
||||
// Get time on release
|
||||
i16 time = elapsed();
|
||||
if (time > LONG_PRESS_MS) {
|
||||
// Make light continuously if pressed for long
|
||||
timer = -1;
|
||||
} else if (time > SHORT_PRESS_MS) {
|
||||
// If it was short touch set timer for enough time
|
||||
timer = 30 * 4; // 30 seconds * 4 (250ms tick)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interrupt(IRQ_TIM1_OVERFLOW, timer1_tick) {
|
||||
TIM1.Status1.UpdateInterruptFlag = 0;
|
||||
#ifdef WATCHDOG
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
#endif
|
||||
tick_250ms();
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
// Setup clock (External, 16Mhz)
|
||||
CLK.External.HighSpeedExternalEnable = 1;
|
||||
while (CLK.External.HighSpeedExternalReady == 0) {
|
||||
nop();
|
||||
}
|
||||
CLK.MasterSwitch = HighSpeedExternal;
|
||||
while (CLK.SwitchControl.SwitchInterruptFlag == 0) {
|
||||
nop();
|
||||
}
|
||||
CLK.SwitchControl.SwitchStartStop = 1;
|
||||
CLK.Divider.Prescaler = 0x00;
|
||||
CLK.Divider.HighSpeedPrescaler = 0x00;
|
||||
CLK.Peripheral1.I2C= 0;
|
||||
CLK.Peripheral1.SPI = 0;
|
||||
CLK.Peripheral1.Timer2 = 0;
|
||||
CLK.Peripheral1.Timer4 = 0;
|
||||
CLK.Peripheral2.AnalogDigitalConvertor = 0;
|
||||
|
||||
// Setup UART pins
|
||||
RX_PIN_DIR = 0;
|
||||
RX_PIN_CR1 = 0;
|
||||
RX_PIN_CR2 = 0;
|
||||
TX_PIN_DIR = 1;
|
||||
|
||||
// Setup touch sensor pins
|
||||
PORT_C.DDR.Pin4 = 0;
|
||||
PORT_C.CR1.Pin4 = 0;
|
||||
PORT_C.CR2.Pin4 = 1;
|
||||
EXTI_CR1.PortC = EXTI_RISING_FALLING;
|
||||
|
||||
// Setup UART (115200 8N1, with interupt)
|
||||
// 115200 | 9600 | 57600
|
||||
UART1.CR3 &= ~(UART_CR3_STOP1 | UART_CR3_STOP2);
|
||||
// UART1.BRR2 = 0x0B; // 0x03; // 0x11;
|
||||
// UART1.BRR1 = 0x08; // 0x68; // 0x06;
|
||||
UART1.BRR2 = 0x03;
|
||||
UART1.BRR1 = 0x68;
|
||||
UART1.CR2 = UART_CR2_TEN | UART_CR2_REN | UART_CR2_RXNE_IVT | UART_CR2_SBK;
|
||||
CLK.Peripheral1.Serial1 = 1;
|
||||
|
||||
// Setup LED pin
|
||||
LED_PIN_DIR = 1;
|
||||
LED_PIN_CR1 = 1;
|
||||
LED_PIN_CR2 = 0;
|
||||
LED_PIN_OUT = 1;
|
||||
|
||||
// Setup timer 250ms tick
|
||||
CLK.Peripheral1.Timer1 = 1;
|
||||
const u16 div = 1599;
|
||||
const u16 cou = 2500;
|
||||
TIM1.PrescalerH = div >> 8;
|
||||
TIM1.PrescalerL = div & 0xFF;
|
||||
TIM1.AutoReloadH = cou >> 8;
|
||||
TIM1.AutoReloadL = cou & 0xFF;
|
||||
TIM1.Interrupt.UpdateInterrupt = 1;
|
||||
TIM1.Control1.CounterEnable = 1;
|
||||
|
||||
#ifdef INVERSION
|
||||
LED_PIN_OUT = 1;
|
||||
#else
|
||||
LED_PIN_OUT = 0;
|
||||
#endif
|
||||
|
||||
#ifdef WATCHDOG
|
||||
// Start watchdog
|
||||
IWATCHDOG.Key = IndependWatchdogOn;
|
||||
IWATCHDOG.Key = IndependWatchdogEdit;
|
||||
IWATCHDOG.Prescaler = WatchdogPrescaler_256; // Around 128kHz/256=500Hz=2ms
|
||||
IWATCHDOG.Reload = 0xFF; // 2ms*256=512ms
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
#endif
|
||||
|
||||
// Start interrupts
|
||||
rim();
|
||||
|
||||
// Fast blink on start
|
||||
/* for (u08 j = 0; j < 10; j++) {
|
||||
LED_PIN_OUT ^= 1;
|
||||
delay_tick(0xffff);
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
} */
|
||||
|
||||
// Just for test
|
||||
CFG_GCR |= 0x02; // Set AL for disable main();
|
||||
wfi();
|
||||
|
||||
// Infinite worker loop
|
||||
for (;;) {
|
||||
delay_tick(0xff);
|
||||
#ifdef WATCHDOG
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue