This commit is contained in:
Mike Trudeau
2026-02-13 20:30:52 +00:00
parent 71ffec0d88
commit 5b106896a1
127 changed files with 35217 additions and 0 deletions

20
fw/.gitignore vendored Normal file
View File

@@ -0,0 +1,20 @@
*.p1
*.d
*.pre
*.sym
*.cmf
*.cof
*.hxl
*.lst
*.obj
*.rlf
*.sdb
*.elf
*.rel
*.rst
*.asm
*.cdb
*.ihx
*.lk
*.lib

View File

@@ -0,0 +1,42 @@
DFOSC = -DFOSC_160000
DFONTSET_MINI ?= -DFONTSET_MINI
SRCDIR = ./src
INCDIR = ./inc
## Get program name from enclosing directory name
PROGRAM = $(lastword $(subst /, ,$(CURDIR)))
SOURCES=$(wildcard *.c $(SRCDIR)/*.c)
OBJECTS=$(SOURCES:.c=.rel)
HEADERS=$(wildcard *.h $(INCDIR)/*.h)
CC = sdcc
AS = sdas8051
MCU_MODEL = mcs51
MODEL = small
CODE_SIZE = --code-size 18432
IRAM_SIZE = --iram-size 256
XRAM_SIZE = --xram-size 768
AFLAGS = -l -s
CFLAGS = -I$(INCDIR) -m$(MCU_MODEL) --model-$(MODEL) --out-fmt-ihx --no-xinit-opt $(DFOSC) $(DFONTSET_MINI)
LFLAGS = $(LIBPATH) $(LIBS) -m$(MCU_MODEL) --model-$(MODEL) $(CODE_SIZE) $(IRAM_SIZE) $(XRAM_SIZE) --out-fmt-ihx $(DEBUG) $(DFOSC) $(DFONTSET_MINI)
AR = sdar
ARFLAGS = -rc
.PHONY: all clean flash
all: $(PROGRAM).lib
$(PROGRAM).lib: $(OBJECTS)
$(AR) $(ARFLAGS) $(PROGRAM).lib $^
%.rel : %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
CCOMPILEDFILES=$(SOURCES:.c=.asm) $(SOURCES:.c=.lst) $(SOURCES:.c=.rel) \
$(SOURCES:.c=.rst) $(SOURCES:.c=.sym)
clean:
@rm -f $(PROGRAM).lib $(PROGRAM).cdb $(PROGRAM).lk $(PROGRAM).map $(CCOMPILEDFILES)

38
fw/n76e003/common/inc/Common.h Executable file
View File

@@ -0,0 +1,38 @@
typedef __bit BIT;
typedef unsigned char UINT8;
typedef unsigned int UINT16;
typedef unsigned long UINT32;
typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef unsigned long uint32_t;
#define CID_READ 0x0B
#define DID_READ 0x0C
#define ERASE_APROM 0x22
#define READ_APROM 0x00
#define PROGRAM_APROM 0x21
#define ERASE_LDROM
#define READ_LDROM
#define PROGRAM_LDROM
#define READ_CFG 0xC0
#define PROGRAM_CFG 0xE1
#define READ_UID 0x04
void InitialUART0_Timer1(UINT32 u32Baudrate); //T1M = 1, SMOD = 1
void InitialUART0_Timer3(UINT32 u32Baudrate); //Timer3 as Baudrate, SMOD=1, Prescale=0
void InitialUART1_Timer3(UINT32 u32Baudrate);
void Send_Data_To_UART0(UINT8 c);
UINT8 Receive_Data_From_UART0(void);
void Send_Data_To_UART1(UINT8 c);
UINT8 Receive_Data_From_UART1(void);
void InitialUART1(UINT32 u32Baudrate);
//unsigned char _sdcc_external_startup (void);
extern __bit BIT_TMP;

8
fw/n76e003/common/inc/Delay.h Executable file
View File

@@ -0,0 +1,8 @@
void Timer0_Delay100us(UINT32 u32CNT);
void Timer0_Delay1ms(UINT32 u32CNT);
void Timer1_Delay10ms(UINT32 u32CNT);
void Timer2_Delay500us(UINT32 u32CNT);
void Timer3_Delay100ms(UINT32 u32CNT);
void Timer0_Delay40ms(UINT32 u32CNT);
void Timer3_Delay10us(UINT32 u32CNT);

View File

@@ -0,0 +1,543 @@
/*--------------------------------------------------------------------------
N76E003 Function_define.h V1.02
All function define inital setting file for Nuvoton N76E003
--------------------------------------------------------------------------*/
#include <stdio.h>
#define nop __asm__ ("NOP");
//16 --> 8 x 2
#define HIBYTE(v1) ((UINT8)((v1)>>8)) //v1 is UINT16
#define LOBYTE(v1) ((UINT8)((v1)&0xFF))
//8 x 2 --> 16
#define MAKEWORD(v1,v2) ((((UINT16)(v1))<<8)+(UINT16)(v2)) //v1,v2 is UINT8
//8 x 4 --> 32
#define MAKELONG(v1,v2,v3,v4) (UINT32)((v1<<32)+(v2<<16)+(v3<<8)+v4) //v1,v2,v3,v4 is UINT8
//32 --> 16 x 2
#define YBYTE1(v1) ((UINT16)((v1)>>16)) //v1 is UINT32
#define YBYTE0(v1) ((UINT16)((v1)&0xFFFF))
//32 --> 8 x 4
#define TBYTE3(v1) ((UINT8)((v1)>>24)) //v1 is UINT32
#define TBYTE2(v1) ((UINT8)((v1)>>16))
#define TBYTE1(v1) ((UINT8)((v1)>>8))
#define TBYTE0(v1) ((UINT8)((v1)&0xFF))
#define SET_BIT0 0x01
#define SET_BIT1 0x02
#define SET_BIT2 0x04
#define SET_BIT3 0x08
#define SET_BIT4 0x10
#define SET_BIT5 0x20
#define SET_BIT6 0x40
#define SET_BIT7 0x80
#define SET_BIT8 0x0100
#define SET_BIT9 0x0200
#define SET_BIT10 0x0400
#define SET_BIT11 0x0800
#define SET_BIT12 0x1000
#define SET_BIT13 0x2000
#define SET_BIT14 0x4000
#define SET_BIT15 0x8000
#define CLR_BIT0 0xFE
#define CLR_BIT1 0xFD
#define CLR_BIT2 0xFB
#define CLR_BIT3 0xF7
#define CLR_BIT4 0xEF
#define CLR_BIT5 0xDF
#define CLR_BIT6 0xBF
#define CLR_BIT7 0x7F
#define CLR_BIT8 0xFEFF
#define CLR_BIT9 0xFDFF
#define CLR_BIT10 0xFBFF
#define CLR_BIT11 0xF7FF
#define CLR_BIT12 0xEFFF
#define CLR_BIT13 0xDFFF
#define CLR_BIT14 0xBFFF
#define CLR_BIT15 0x7FFF
#define FAIL 1
#define PASS 0
/*****************************************************************************************
* For GPIO INIT setting
*****************************************************************************************/
//------------------- Define Port as Quasi mode -------------------
#define P00_Quasi_Mode P0M1&=~SET_BIT0;P0M2&=~SET_BIT0
#define P01_Quasi_Mode P0M1&=~SET_BIT1;P0M2&=~SET_BIT1
#define P02_Quasi_Mode P0M1&=~SET_BIT2;P0M2&=~SET_BIT2
#define P03_Quasi_Mode P0M1&=~SET_BIT3;P0M2&=~SET_BIT3
#define P04_Quasi_Mode P0M1&=~SET_BIT4;P0M2&=~SET_BIT4
#define P05_Quasi_Mode P0M1&=~SET_BIT5;P0M2&=~SET_BIT5
#define P06_Quasi_Mode P0M1&=~SET_BIT6;P0M2&=~SET_BIT6
#define P07_Quasi_Mode P0M1&=~SET_BIT7;P0M2&=~SET_BIT7
#define P10_Quasi_Mode P1M1&=~SET_BIT0;P1M2&=~SET_BIT0
#define P11_Quasi_Mode P1M1&=~SET_BIT1;P1M2&=~SET_BIT1
#define P12_Quasi_Mode P1M1&=~SET_BIT2;P1M2&=~SET_BIT2
#define P13_Quasi_Mode P1M1&=~SET_BIT3;P1M2&=~SET_BIT3
#define P14_Quasi_Mode P1M1&=~SET_BIT4;P1M2&=~SET_BIT4
#define P15_Quasi_Mode P1M1&=~SET_BIT5;P1M2&=~SET_BIT5
#define P16_Quasi_Mode P1M1&=~SET_BIT6;P1M2&=~SET_BIT6
#define P17_Quasi_Mode P1M1&=~SET_BIT7;P1M2&=~SET_BIT7
#define P30_Quasi_Mode P3M1&=~SET_BIT0;P3M2&=~SET_BIT0
//------------------- Define Port as Push Pull mode -------------------
#define P00_PushPull_Mode P0M1&=~SET_BIT0;P0M2|=SET_BIT0
#define P01_PushPull_Mode P0M1&=~SET_BIT1;P0M2|=SET_BIT1
#define P02_PushPull_Mode P0M1&=~SET_BIT2;P0M2|=SET_BIT2
#define P03_PushPull_Mode P0M1&=~SET_BIT3;P0M2|=SET_BIT3
#define P04_PushPull_Mode P0M1&=~SET_BIT4;P0M2|=SET_BIT4
#define P05_PushPull_Mode P0M1&=~SET_BIT5;P0M2|=SET_BIT5
#define P06_PushPull_Mode P0M1&=~SET_BIT6;P0M2|=SET_BIT6
#define P07_PushPull_Mode P0M1&=~SET_BIT7;P0M2|=SET_BIT7
#define P10_PushPull_Mode P1M1&=~SET_BIT0;P1M2|=SET_BIT0
#define P11_PushPull_Mode P1M1&=~SET_BIT1;P1M2|=SET_BIT1
#define P12_PushPull_Mode P1M1&=~SET_BIT2;P1M2|=SET_BIT2
#define P13_PushPull_Mode P1M1&=~SET_BIT3;P1M2|=SET_BIT3
#define P14_PushPull_Mode P1M1&=~SET_BIT4;P1M2|=SET_BIT4
#define P15_PushPull_Mode P1M1&=~SET_BIT5;P1M2|=SET_BIT5
#define P16_PushPull_Mode P1M1&=~SET_BIT6;P1M2|=SET_BIT6
#define P17_PushPull_Mode P1M1&=~SET_BIT7;P1M2|=SET_BIT7
#define P30_PushPull_Mode P3M1&=~SET_BIT0;P3M2|=SET_BIT0
#define GPIO1_PushPull_Mode P1M1&=~SET_BIT0;P1M2|=SET_BIT0
//------------------- Define Port as Input Only mode -------------------
#define P00_Input_Mode P0M1|=SET_BIT0;P0M2&=~SET_BIT0
#define P01_Input_Mode P0M1|=SET_BIT1;P0M2&=~SET_BIT1
#define P02_Input_Mode P0M1|=SET_BIT2;P0M2&=~SET_BIT2
#define P03_Input_Mode P0M1|=SET_BIT3;P0M2&=~SET_BIT3
#define P04_Input_Mode P0M1|=SET_BIT4;P0M2&=~SET_BIT4
#define P05_Input_Mode P0M1|=SET_BIT5;P0M2&=~SET_BIT5
#define P06_Input_Mode P0M1|=SET_BIT6;P0M2&=~SET_BIT6
#define P07_Input_Mode P0M1|=SET_BIT7;P0M2&=~SET_BIT7
#define P10_Input_Mode P1M1|=SET_BIT0;P1M2&=~SET_BIT0
#define P11_Input_Mode P1M1|=SET_BIT1;P1M2&=~SET_BIT1
#define P12_Input_Mode P1M1|=SET_BIT2;P1M2&=~SET_BIT2
#define P13_Input_Mode P1M1|=SET_BIT3;P1M2&=~SET_BIT3
#define P14_Input_Mode P1M1|=SET_BIT4;P1M2&=~SET_BIT4
#define P15_Input_Mode P1M1|=SET_BIT5;P1M2&=~SET_BIT5
#define P16_Input_Mode P1M1|=SET_BIT6;P1M2&=~SET_BIT6
#define P17_Input_Mode P1M1|=SET_BIT7;P1M2&=~SET_BIT7
#define P30_Input_Mode P3M1|=SET_BIT0;P3M2&=~SET_BIT0
//-------------------Define Port as Open Drain mode -------------------
#define P00_OpenDrain_Mode P0M1|=SET_BIT0;P0M2|=SET_BIT0
#define P01_OpenDrain_Mode P0M1|=SET_BIT1;P0M2|=SET_BIT1
#define P02_OpenDrain_Mode P0M1|=SET_BIT2;P0M2|=SET_BIT2
#define P03_OpenDrain_Mode P0M1|=SET_BIT3;P0M2|=SET_BIT3
#define P04_OpenDrain_Mode P0M1|=SET_BIT4;P0M2|=SET_BIT4
#define P05_OpenDrain_Mode P0M1|=SET_BIT5;P0M2|=SET_BIT5
#define P06_OpenDrain_Mode P0M1|=SET_BIT6;P0M2|=SET_BIT6
#define P07_OpenDrain_Mode P0M1|=SET_BIT7;P0M2|=SET_BIT7
#define P10_OpenDrain_Mode P1M1|=SET_BIT0;P1M2|=SET_BIT0
#define P11_OpenDrain_Mode P1M1|=SET_BIT1;P1M2|=SET_BIT1
#define P12_OpenDrain_Mode P1M1|=SET_BIT2;P1M2|=SET_BIT2
#define P13_OpenDrain_Mode P1M1|=SET_BIT3;P1M2|=SET_BIT3
#define P14_OpenDrain_Mode P1M1|=SET_BIT4;P1M2|=SET_BIT4
#define P15_OpenDrain_Mode P1M1|=SET_BIT5;P1M2|=SET_BIT5
#define P16_OpenDrain_Mode P1M1|=SET_BIT6;P1M2|=SET_BIT6
#define P17_OpenDrain_Mode P1M1|=SET_BIT7;P1M2|=SET_BIT7
#define P30_OpenDrain_Mode P3M1|=SET_BIT0;P3M2|=SET_BIT0
//--------- Define all port as quasi mode ---------
#define Set_All_GPIO_Quasi_Mode P0M1=0;P0M2=0;P1M1=0;P1M2=0;P3M1=0;P3M2=0
#define set_GPIO1 P12=1
#define clr_GPIO1 P12=0
/****************************************************************************
Enable INT port 0~3
***************************************************************************/
#define Enable_INT_Port0 PICON &= 0xFB;
#define Enable_INT_Port1 PICON |= 0x01;
#define Enable_INT_Port2 PICON |= 0x02;
#define Enable_INT_Port3 PICON |= 0x03;
/*****************************************************************************
Enable each bit low level trig mode
*****************************************************************************/
#define Enable_BIT7_LowLevel_Trig PICON&=0x7F;PINEN|=0x80;PIPEN&=0x7F
#define Enable_BIT6_LowLevel_Trig PICON&=0x7F;PINEN|=0x40;PIPEN&=0xBF
#define Enable_BIT5_LowLevel_Trig PICON&=0xBF;PINEN|=0x20;PIPEN&=0xDF
#define Enable_BIT4_LowLevel_Trig PICON&=0xBF;PINEN|=0x10;PIPEN&=0xEF
#define Enable_BIT3_LowLevel_Trig PICON&=0xDF;PINEN|=0x08;PIPEN&=0xF7
#define Enable_BIT2_LowLevel_Trig PICON&=0xEF;PINEN|=0x04;PIPEN&=0xFB
#define Enable_BIT1_LowLevel_Trig PICON&=0xF7;PINEN|=0x02;PIPEN&=0xFD
#define Enable_BIT0_LowLevel_Trig PICON&=0xFD;PINEN|=0x01;PIPEN&=0xFE
/*****************************************************************************
Enable each bit high level trig mode
*****************************************************************************/
#define Enable_BIT7_HighLevel_Trig PICON&=0x7F;PINEN&=0x7F;PIPEN|=0x80
#define Enable_BIT6_HighLevel_Trig PICON&=0x7F;PINEN&=0xBF;PIPEN|=0x40
#define Enable_BIT5_HighLevel_Trig PICON&=0xBF;PINEN&=0xDF;PIPEN|=0x20
#define Enable_BIT4_HighLevel_Trig PICON&=0xBF;PINEN&=0xEF;PIPEN|=0x10
#define Enable_BIT3_HighLevel_Trig PICON&=0xDF;PINEN&=0xF7;PIPEN|=0x08
#define Enable_BIT2_HighLevel_Trig PICON&=0xEF;PINEN&=0xFB;PIPEN|=0x04
#define Enable_BIT1_HighLevel_Trig PICON&=0xF7;PINEN&=0xFD;PIPEN|=0x02
#define Enable_BIT0_HighLevel_Trig PICON&=0xFD;PINEN&=0xFE;PIPEN|=0x01
/*****************************************************************************
Enable each bit falling edge trig mode
*****************************************************************************/
#define Enable_BIT7_FallEdge_Trig PICON|=0x80;PINEN|=0x80;PIPEN&=0x7F
#define Enable_BIT6_FallEdge_Trig PICON|=0x80;PINEN|=0x40;PIPEN&=0xBF
#define Enable_BIT5_FallEdge_Trig PICON|=0x40;PINEN|=0x20;PIPEN&=0xDF
#define Enable_BIT4_FallEdge_Trig PICON|=0x40;PINEN|=0x10;PIPEN&=0xEF
#define Enable_BIT3_FallEdge_Trig PICON|=0x20;PINEN|=0x08;PIPEN&=0xF7
#define Enable_BIT2_FallEdge_Trig PICON|=0x10;PINEN|=0x04;PIPEN&=0xFB
#define Enable_BIT1_FallEdge_Trig PICON|=0x08;PINEN|=0x02;PIPEN&=0xFD
#define Enable_BIT0_FallEdge_Trig PICON|=0x04;PINEN|=0x01;PIPEN&=0xFE
/*****************************************************************************
Enable each bit rasing edge trig mode
*****************************************************************************/
#define Enable_BIT7_RasingEdge_Trig PICON|=0x80;PINEN&=0x7F;PIPEN|=0x80
#define Enable_BIT6_RasingEdge_Trig PICON|=0x80;PINEN&=0xBF;PIPEN|=0x40
#define Enable_BIT5_RasingEdge_Trig PICON|=0x40;PINEN&=0xDF;PIPEN|=0x20
#define Enable_BIT4_RasingEdge_Trig PICON|=0x40;PINEN&=0xEF;PIPEN|=0x10
#define Enable_BIT3_RasingEdge_Trig PICON|=0x20;PINEN&=0xF7;PIPEN|=0x08
#define Enable_BIT2_RasingEdge_Trig PICON|=0x10;PINEN&=0xFB;PIPEN|=0x04
#define Enable_BIT1_RasingEdge_Trig PICON|=0x08;PINEN&=0xFD;PIPEN|=0x02
#define Enable_BIT0_RasingEdge_Trig PICON|=0x04;PINEN&=0xFE;PIPEN|=0x01
/*****************************************************************************************
* For TIMER VALUE setting is base on " option -> C51 -> Preprocesser Symbols -> Define "
*****************************************************************************************/
#ifdef FOSC_110592 // if Fsys = 11.0592MHz
#define TIMER_DIV12_VALUE_10us 65536-9 //9*12/11.0592 = 10 uS, // Timer divider = 12 for TM0/TM1
#define TIMER_DIV12_VALUE_1ms 65536-923 //923*12/11.0592 = 1 mS // Timer divider = 12
#define TIMER_DIV12_VALUE_10ms 65536-9216 //18432*12/22118400 = 10 ms // Timer divider = 12
#define TIMER_DIV4_VALUE_10us 65536-28 //28*4/11.0592 = 10 uS // Timer divider = 4 for TM2/TM3
#define TIMER_DIV4_VALUE_1ms 65536-2765 //2765*4/11.0592 = 1 mS // Timer divider = 4
#define TIMER_DIV4_VALUE_100us 65536-277 //553*4/22118400 = 100 us // Timer divider = 4
#define TIMER_DIV4_VALUE_200us 65536-553 //1106*4/22118400 = 200 us // Timer divider = 4
#define TIMER_DIV4_VALUE_500us 65536-1383 //2765*4/22118400 = 500 us // Timer divider = 4
#define TIMER_DIV16_VALUE_10ms 65536-6912 //1500*16/22118400 = 10 ms // Timer divider = 16
#define TIMER_DIV64_VALUE_30ms 65536-5184 //10368*64/22118400 = 30 ms // Timer divider = 64
#define TIMER_DIV128_VALUE_100ms 65536-8640 //17280*128/22118400 = 100 ms // Timer divider = 128
#define TIMER_DIV128_VALUE_200ms 65536-17280 //34560*128/22118400 = 200 ms // Timer divider = 128
#define TIMER_DIV256_VALUE_500ms 65536-21600 //43200*256/22118400 = 500 ms // Timer divider = 256
#define TIMER_DIV512_VALUE_1s 65536-21600 //43200*512/22118400 = 1 s // Timer divider = 512
#endif
#ifdef FOSC_160000 // if Fsys = 16MHz
#define TIMER_DIV12_VALUE_10us 65536-13 //13*12/16000000 = 10 uS, // Timer divider = 12 for TM0/TM1
#define TIMER_DIV12_VALUE_100us 65536-130 //130*12/16000000 = 10 uS, // Timer divider = 12
#define TIMER_DIV12_VALUE_1ms 65536-1334 //1334*12/16000000 = 1 mS, // Timer divider = 12
#define TIMER_DIV12_VALUE_10ms 65536-13334 //13334*12/16000000 = 10 mS // Timer divider = 12
#define TIMER_DIV12_VALUE_40ms 65536-53336 //53336*12/16000000 = 40 ms // Timer divider = 12
#define TIMER_DIV4_VALUE_10us 65536-40 //40*4/16000000 = 10 uS, // Timer divider = 4 for TM2/TM3
#define TIMER_DIV4_VALUE_100us 65536-400 //400*4/16000000 = 100 us // Timer divider = 4
#define TIMER_DIV4_VALUE_200us 65536-800 //800*4/16000000 = 200 us // Timer divider = 4
#define TIMER_DIV4_VALUE_500us 65536-2000 //2000*4/16000000 = 500 us // Timer divider = 4
#define TIMER_DIV4_VALUE_1ms 65536-4000 //4000*4/16000000 = 1 mS, // Timer divider = 4
#define TIMER_DIV16_VALUE_10ms 65536-10000 //10000*16/16000000 = 10 ms // Timer divider = 16
#define TIMER_DIV64_VALUE_30ms 65536-7500 //7500*64/16000000 = 30 ms // Timer divider = 64
#define TIMER_DIV128_VALUE_100ms 65536-12500 //12500*128/16000000 = 100 ms // Timer divider = 128
#define TIMER_DIV128_VALUE_200ms 65536-25000 //25000*128/16000000 = 200 ms // Timer divider = 128
#define TIMER_DIV128_VALUE_250ms 65536-31250 //31250*128/16000000 = 250 ms // Timer divider = 128
#define TIMER_DIV256_VALUE_500ms 65536-31250 //31250*256/16000000 = 500 ms // Timer divider = 256
#define TIMER_DIV512_VALUE_1s 65536-31250 //31250*512/16000000 = 1 s. // Timer Divider = 512
#endif
#ifdef FOSC_166000 // if Fsys = 16.6MHz
#define TIMER_DIV12_VALUE_10us 65536-13 //13*12/16600000 = 10 uS, // Timer divider = 12 for TM0/TM1
#define TIMER_DIV12_VALUE_100us 65536-138 //138*12/16600000 = 100 uS, // Timer divider = 12
#define TIMER_DIV12_VALUE_1ms 65536-1384 //1384*12/16600000 = 1 mS, // Timer divider = 12
#define TIMER_DIV12_VALUE_10ms 65536-13834 //13834*12/16600000 = 10 mS // Timer divider = 12
#define TIMER_DIV12_VALUE_40ms 65536-55334 //55334*12/16600000 = 40 ms // Timer divider = 12
#define TIMER_DIV4_VALUE_10us 65536-41 //41*4/16600000 = 10 uS, // Timer divider = 4 for TM2/TM3
#define TIMER_DIV4_VALUE_100us 65536-415 //415*4/16600000 = 100 us // Timer divider = 4
#define TIMER_DIV4_VALUE_200us 65536-830 //830*4/16600000 = 200 us // Timer divider = 4
#define TIMER_DIV4_VALUE_500us 65536-2075 //2075*4/16600000 = 500 us // Timer divider = 4
#define TIMER_DIV4_VALUE_1ms 65536-4150 //4150*4/16600000 = 1 mS, // Timer divider = 4
#define TIMER_DIV16_VALUE_10ms 65536-10375 //10375*16/16600000 = 10 ms // Timer divider = 16
#define TIMER_DIV64_VALUE_30ms 65536-7781 //7781*64/16600000 = 30 ms // Timer divider = 64
#define TIMER_DIV128_VALUE_100ms 65536-12969 //12969*128/16600000 = 100 ms // Timer divider = 128
#define TIMER_DIV128_VALUE_200ms 65536-25938 //25938*128/16600000 = 200 ms // Timer divider = 128
#define TIMER_DIV256_VALUE_500ms 65536-32422 //32422*256/16600000 = 500 ms // Timer divider = 256
#define TIMER_DIV512_VALUE_1s 65536-32422 //32422*512/16600000 = 1 s. // Timer Divider = 512
#endif
#ifdef FOSC_184320 // if Fsys = 18.432MHz
#define TIMER_DIV12_VALUE_10us 65536-15 //15*12/18.432 = 10 uS, Timer Clock = Fsys/12
#define TIMER_DIV12_VALUE_1ms 65536-1536 //1536*12/18.432 = 1 mS, Timer Clock = Fsys/12
#define TIMER_DIV4_VALUE_10us 65536-46 //46*4/18.432 = 10 uS, Timer Clock = Fsys/4
#define TIMER_DIV4_VALUE_1ms 65536-4608 //4608*4/18.432 = 1 mS, Timer Clock = Fsys/4
#endif
#ifdef FOSC_200000 // if Fsys = 20 MHz
#define TIMER_DIV12_VALUE_10us 65536-17 //17*12/20000000 = 10 uS, Timer Clock = Fsys/12
#define TIMER_DIV12_VALUE_1ms 65536-1667 //1667*12/20000000 = 1 mS, Timer Clock = Fsys/12
#define TIMER_DIV4_VALUE_10us 65536-50 //50*4/20000000 = 10 uS, Timer Clock = Fsys/4
#define TIMER_DIV4_VALUE_1ms 65536-5000 //5000*4/20000000 = 1 mS, Timer Clock = Fsys/4
#endif
#ifdef FOSC_221184 // if Fsys = 22.1184 MHz
#define TIMER_DIV12_VALUE_10us 65536-18 //18*12/22118400 = 10 uS, // Timer divider = 12
#define TIMER_DIV12_VALUE_1ms 65536-1843 //1843*12/22118400 = 1 mS, // Timer divider = 12
#define TIMER_DIV12_VALUE_10ms 65536-18432 //18432*12/22118400 = 10 ms // Timer divider = 12
#define TIMER_DIV4_VALUE_10us 65536-56 //9*4/22118400 = 10 uS, // Timer divider = 4
#define TIMER_DIV4_VALUE_1ms 65536-5530 //923*4/22118400 = 1 mS, // Timer divider = 4
#define TIMER_DIV4_VALUE_100us 65536-553 //553*4/22118400 = 100 us // Timer divider = 4
#define TIMER_DIV4_VALUE_200us 65536-1106 //1106*4/22118400 = 200 us // Timer divider = 4
#define TIMER_DIV4_VALUE_500us 65536-2765 //2765*4/22118400 = 500 us // Timer divider = 4
#define TIMER_DIV16_VALUE_10ms 65536-13824 //1500*16/22118400 = 10 ms // Timer divider = 16
#define TIMER_DIV64_VALUE_30ms 65536-10368 //10368*64/22118400 = 30 ms // Timer divider = 64
#define TIMER_DIV128_VALUE_100ms 65536-17280 //17280*128/22118400 = 100 ms // Timer divider = 128
#define TIMER_DIV128_VALUE_200ms 65536-34560 //34560*128/22118400 = 200 ms // Timer divider = 128
#define TIMER_DIV256_VALUE_500ms 65536-43200 //43200*256/22118400 = 500 ms // Timer divider = 256
#define TIMER_DIV512_VALUE_1s 65536-43200 //43200*512/22118400 = 1 s // Timer divider = 512
#endif
#ifdef FOSC_240000 // if Fsys = 20 MHz
#define TIMER_DIV12_VALUE_10us 65536-20 //20*12/24000000 = 10 uS, // Timer divider = 12
#define TIMER_DIV12_VALUE_1ms 65536-2000 //2000*12/24000000 = 1 mS, // Timer divider = 12
#define TIMER_DIV12_VALUE_10ms 65536-20000 //2000*12/24000000 = 10 mS // Timer divider = 12
#define TIMER_DIV4_VALUE_10us 65536-60 //60*4/24000000 = 10 uS, // Timer divider = 4
#define TIMER_DIV4_VALUE_100us 65536-600 //600*4/24000000 = 100 us // Timer divider = 4
#define TIMER_DIV4_VALUE_200us 65536-1200 //1200*4/24000000 = 200 us // Timer divider = 4
#define TIMER_DIV4_VALUE_500us 65536-3000 //3000*4/24000000 = 500 us // Timer divider = 4
#define TIMER_DIV4_VALUE_1ms 65536-6000 //6000*4/24000000 = 1 mS, // Timer divider = 4
#define TIMER_DIV16_VALUE_10ms 65536-15000 //15000*16/24000000 = 10 ms // Timer divider = 16
#define TIMER_DIV64_VALUE_30ms 65536-11250 //11250*64/24000000 = 30 ms // Timer divider = 64
#define TIMER_DIV128_VALUE_100ms 65536-18750 //37500*128/24000000 = 200 ms // Timer divider = 128
#define TIMER_DIV128_VALUE_200ms 65536-37500 //37500*128/24000000 = 200 ms // Timer divider = 128
#define TIMER_DIV256_VALUE_500ms 65536-46875 //46875*256/24000000 = 500 ms // Timer divider = 256
#define TIMER_DIV512_VALUE_1s 65536-46875 //46875*512/24000000 = 1 s. // Timer Divider = 512
#endif
//-------------------- Timer0 function define --------------------
#define TIMER1_MODE0_ENABLE TMOD&=0x0F
#define TIMER1_MODE1_ENABLE TMOD&=0x0F;TMOD|=0x10
#define TIMER1_MODE2_ENABLE TMOD&=0x0F;TMOD|=0x20
#define TIMER1_MODE3_ENABLE TMOD&=0x0F;TMOD|=0x30
//-------------------- Timer1 function define --------------------
#define TIMER0_MODE0_ENABLE TMOD&=0xF0
#define TIMER0_MODE1_ENABLE TMOD&=0xF0;TMOD|=0x01
#define TIMER0_MODE2_ENABLE TMOD&=0xF0;TMOD|=0x02
#define TIMER0_MODE3_ENABLE TMOD&=0xF0;TMOD|=0x03
//-------------------- Timer2 function define --------------------
#define TIMER2_DIV_4 T2MOD|=0x10;T2MOD&=0x9F
#define TIMER2_DIV_16 T2MOD|=0x20;T2MOD&=0xAF
#define TIMER2_DIV_32 T2MOD|=0x30;T2MOD&=0xBF
#define TIMER2_DIV_64 T2MOD|=0x40;T2MOD&=0xCF
#define TIMER2_DIV_128 T2MOD|=0x50;T2MOD&=0xDF
#define TIMER2_DIV_256 T2MOD|=0x60;T2MOD&=0xEF
#define TIMER2_DIV_512 T2MOD|=0x70
#define TIMER2_Auto_Reload_Delay_Mode T2CON&=~SET_BIT0;T2MOD|=SET_BIT7;T2MOD|=SET_BIT3
#define TIMER2_Compare_Capture_Mode T2CON|=SET_BIT0;T2MOD&=~SET_BIT7;T2MOD|=SET_BIT2
#define TIMER2_CAP0_Capture_Mode T2CON&=~SET_BIT0;T2MOD=0x89
#define TIMER2_CAP1_Capture_Mode T2CON&=~SET_BIT0;T2MOD=0x8A
#define TIMER2_CAP2_Capture_Mode T2CON&=~SET_BIT0;T2MOD=0x8B
//-------------------- Timer2 Capture define --------------------
//--- Falling Edge -----
#define IC0_P12_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC1_P11_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON3|=0x01;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC2_P10_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON3|=0x02;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC3_P00_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON3|=0x03;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC3_P04_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON3|=0x04;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC4_P01_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON3|=0x05;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC5_P03_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON3|=0x06;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC6_P05_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON3|=0x07;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC7_P15_CAP0_FallingEdge_Capture CAPCON1&=0xFC;CAPCON3&=0xF0;CAPCON3|=0x08;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC0_P12_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC1_P11_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON3|=0x10;CAPCON0|=SET_BIT5;CAPCON0|=SET_BIT5
#define IC2_P10_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON3|=0x20;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC3_P00_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON3|=0x30;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC3_P04_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON3|=0x40;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC4_P01_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON3|=0x50;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC5_P03_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON3|=0x60;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC6_P05_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON3|=0x70;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC7_P15_CAP1_FallingEdge_Capture CAPCON1&=0xF3;CAPCON3&=0x0F;CAPCON3|=0x80;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC0_P12_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
#define IC1_P11_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON4|=0x10;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
#define IC2_P10_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON4|=0x20;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
#define IC3_P00_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON4|=0x30;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
#define IC3_P04_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON4|=0x40;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
#define IC4_P01_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON4|=0x50;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
#define IC5_P03_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON4|=0x60;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
#define IC6_P05_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON4|=0x70;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
#define IC7_P15_CAP2_FallingEdge_Capture CAPCON1&=0x0F;CAPCON4&=0xF0;CAPCON4|=0x80;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6
//----- Rising edge ----
#define IC0_P12_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC1_P11_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0;CAPCON3|=0x01;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC2_P10_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0;CAPCON3|=0x02;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC3_P00_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0;CAPCON3|=0x03;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC3_P04_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0;CAPCON3|=0x04;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC4_P01_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0;CAPCON3|=0x05;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC5_P03_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0;CAPCON3|=0x06;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC6_P05_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0;CAPCON3|=0x07;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC7_P15_CAP0_RisingEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x01;CAPCON3&=0xF0;CAPCON3|=0x08;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4;
#define IC0_P12_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0FCAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC1_P11_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0F;CAPCON3|=0x10;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC2_P10_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0F;CAPCON3|=0x20;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC3_P00_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0F;CAPCON3|=0x30;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC3_P04_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0F;CAPCON3|=0x40;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC4_P01_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0F;CAPCON3|=0x50;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC5_P03_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0F;CAPCON3|=0x60;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC6_P05_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0F;CAPCON3|=0x70;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC7_P15_CAP1_RisingEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x04;CAPCON3&=0x0F;CAPCON3|=0x80;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC0_P12_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC1_P11_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON4|=0x01;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC2_P10_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON4|=0x02;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC3_P00_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON4|=0x03;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC3_P04_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON4|=0x04;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC4_P01_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON4|=0x05;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC5_P03_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON4|=0x06;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC6_P05_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON4|=0x07;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC7_P15_CAP3_RisingEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x10;CAPCON4&=0xF0;CAPCON4|=0x08;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
//-----BOTH edge ----
#define IC0_P12_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC1_P11_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON3|=0x01;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC2_P10_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON3|=0x02;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC3_P00_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON3|=0x03;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC3_P04_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON3|=0x04;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC4_P01_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON3|=0x05;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC5_P03_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON3|=0x06;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC6_P05_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON3|=0x07;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC7_P15_CAP0_BothEdge_Capture CAPCON1&=0xFC;CAPCON1|=0x02;CAPCON3&=0xF0;CAPCON3|=0x08;CAPCON0|=SET_BIT4;CAPCON2|=SET_BIT4
#define IC0_P12_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5
#define IC1_P11_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON3|=0x10;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC2_P10_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON3|=0x20;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC3_P00_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON3|=0x30;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC3_P04_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON3|=0x40;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC4_P01_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON3|=0x50;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC5_P03_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON3|=0x60;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC6_P05_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON3|=0x70;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC7_P15_CAP1_BothEdge_Capture CAPCON1&=0xF3;CAPCON1|=0x08;CAPCON3&=0x0F;CAPCON3|=0x80;CAPCON0|=SET_BIT5;CAPCON2|=SET_BIT5;
#define IC0_P12_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC1_P11_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON4|=0x01;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC2_P10_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON4|=0x02;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC3_P00_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON4|=0x03;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC3_P04_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON4|=0x04;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC4_P01_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON4|=0x05;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC5_P03_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON4|=0x06;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC6_P05_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON4|=0x07;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define IC7_P15_CAP3_BothEdge_Capture CAPCON1&=0x0F;CAPCON1|=0x20;CAPCON4&=0xF0;CAPCON4|=0x08;CAPCON0|=SET_BIT6;CAPCON2|=SET_BIT6;
#define TIMER2_IC2_DISABLE CAPCON0&=~SET_BIT6
#define TIMER2_IC1_DISABLE CAPCON0&=~SET_BIT5
#define TIMER2_IC0_DISABLE CAPCON0&=~SET_BIT4
/*****************************************************************************************
* For PWM setting
*****************************************************************************************/
//--------- PMW clock source select define ---------------------
#define PWM_CLOCK_FSYS CKCON&=0xBF
#define PWM_CLOCK_TIMER1 CKCON|=0x40
//--------- PWM clock devide define ----------------------------
#define PWM_CLOCK_DIV_2 PWMCON1|=0x01;PWMCON1&=0xF9
#define PWM_CLOCK_DIV_4 PWMCON1|=0x02;PWMCON1&=0xFA
#define PWM_CLOCK_DIV_8 PWMCON1|=0x03;PWMCON1&=0xFB
#define PWM_CLOCK_DIV_16 PWMCON1|=0x04;PWMCON1&=0xFC
#define PWM_CLOCK_DIV_32 PWMCON1|=0x05;PWMCON1&=0xFD
#define PWM_CLOCK_DIV_64 PWMCON1|=0x06;PWMCON1&=0xFE
#define PWM_CLOCK_DIV_128 PWMCON1|=0x07
//--------- PWM I/O select define ------------------------------
#define PWM5_P15_OUTPUT_ENABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;SFRS|=0x01;PIOCON1|=0x20;TA=0xAA;TA=0x55;SFRS&=0xFE;EA=BIT_TMP //P1.5 as PWM5 output enable
#define PWM5_P03_OUTPUT_ENABLE PIOCON0|=0x20 //P0.3 as PWM5
#define PWM4_P01_OUTPUT_ENABLE PIOCON0|=0x10 //P0.1 as PWM4 output enable
#define PWM3_P04_OUTPUT_ENABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;SFRS|=0x01;PIOCON1|=0x08;TA=0xAA;TA=0x55;SFRS&=0xFE;EA=BIT_TMP //P0.4 as PWM3 output enable
#define PWM3_P00_OUTPUT_ENABLE PIOCON0|=0x08 //P0.0 as PWM3
#define PWM2_P05_OUTPUT_ENABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;SFRS|=0x01;PIOCON1|=0x04;TA=0xAA;TA=0x55;SFRS&=0xFE;EA=BIT_TMP //P1.0 as PWM2 output enable
#define PWM2_P10_OUTPUT_ENABLE PIOCON0|=0x04 //P1.0 as PWM2
#define PWM1_P14_OUTPUT_ENABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;SFRS|=0x01;PIOCON1|=0x02;TA=0xAA;TA=0x55;SFRS&=0xFE;EA=BIT_TMP //P1.4 as PWM1 output enable
#define PWM1_P11_OUTPUT_ENABLE PIOCON0|=0x02 //P1.1 as PWM1
#define PWM0_P12_OUTPUT_ENABLE PIOCON0|=0x01 //P1.2 as PWM0 output enable
#define ALL_PWM_OUTPUT_ENABLE PIOCON0=0xFF;PIOCON1=0xFF
#define PWM5_P15_OUTPUT_DISABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;SFRS|=0x01;PIOCON1&=0xDF;TA=0xAA;TA=0x55;SFRS&=0xFE;EA=BIT_TMP //P1.5 as PWM5 output disable
#define PWM5_P03_OUTPUT_DISABLE PIOCON0&=0xDF //P0.3 as PWM5
#define PWM4_P01_OUTPUT_DISABLE PIOCON0&=0xEF //P0.1 as PWM4 output disable
#define PWM3_P04_OUTPUT_DISABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;SFRS|=0x01;PIOCON1&=0xF7;TA=0xAA;TA=0x55;SFRS&=0xFE;EA=BIT_TMP //P0.4 as PWM3 output disable
#define PWM3_P00_OUTPUT_DISABLE PIOCON0&=0xF7 //P0.0 as PWM3
#define PWM2_P05_OUTPUT_DISABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;SFRS|=0x01;PIOCON1&=0xFB;TA=0xAA;TA=0x55;SFRS&=0xFE;EA=BIT_TMP //P1.0 as PWM2 output disable
#define PWM2_P10_OUTPUT_DISABLE PIOCON0&=0xFB //P1.0 as PWM2
#define PWM1_P14_OUTPUT_DISABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;SFRS|=0x01;PIOCON1&=0xFD;TA=0xAA;TA=0x55;SFRS&=0xFE;EA=BIT_TMP //P1.4 as PWM1 output disable
#define PWM1_P11_OUTPUT_DISABLE PIOCON0&=0xFD //P1.1 as PWM1
#define PWM0_P12_OUTPUT_DISABLE PIOCON0&=0xFE //P1.2 as PWM0 output disable
#define ALL_PWM_OUTPUT_DISABLE PIOCON0=0x00;PIOCON1=0x00
//--------- PWM I/O Polarity Control ---------------------------
#define PWM5_OUTPUT_INVERSE PNP|=0x20
#define PWM4_OUTPUT_INVERSE PNP|=0x10
#define PWM3_OUTPUT_INVERSE PNP|=0x08
#define PWM2_OUTPUT_INVERSE PNP|=0x04
#define PWM1_OUTPUT_INVERSE PNP|=0x02
#define PWM0_OUTPUT_INVERSE PNP|=0x01
#define PWM_OUTPUT_ALL_INVERSE PNP=0xFF
#define PWM5_OUTPUT_NORMAL PNP&=0xDF
#define PWM4_OUTPUT_NORMAL PNP&=0xEF
#define PWM3_OUTPUT_NORMAL PNP&=0xF7
#define PWM2_OUTPUT_NORMAL PNP&=0xFB
#define PWM1_OUTPUT_NORMAL PNP&=0xFD
#define PWM0_OUTPUT_NORMAL PNP&=0xFE
#define PWM_OUTPUT_ALL_NORMAL PNP=0x00
//--------- PWM type define ------------------------------------
#define PWM_EDGE_TYPE PWMCON1&=~SET_BIT4
#define PWM_CENTER_TYPE PWMCON1|=SET_BIT4
//--------- PWM mode define ------------------------------------
#define PWM_IMDEPENDENT_MODE PWMCON1&=0x3F
#define PWM_COMPLEMENTARY_MODE PWMCON1|=0x40;PWMCON1&=0x7F
#define PWM_SYNCHRONIZED_MODE PWMCON1|=0x80;PWMCON1&=0xBF
#define PWM_GP_MODE_ENABLE PWMCON1|=0x20
#define PWM_GP_MODE_DISABLE PWMCON1&=0xDF
//--------- PMW interrupt setting ------------------------------
#define PWM_FALLING_INT BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC&=0xCF;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
#define PWM_RISING_INT BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC|=0x10;PWMCON0&=0xDF;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
#define PWM_CENTRAL_POINT_INT BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC|=0x20;PWMCON0&=0xEF;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
#define PWM_PERIOD_END_INT BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC|=0x30;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
//--------- PWM interrupt pin select ---------------------------
#define PWM_INT_PWM0 BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC&=0xF8;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
#define PWM_INT_PWM1 BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC&=0xF8;PWMINTC|=0x01;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
#define PWM_INT_PWM2 BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC&=0xF8;PWMINTC|=0x02;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
#define PWM_INT_PWM3 BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC&=0xF8;PWMINTC|=0x03;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
#define PWM_INT_PWM4 BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC&=0xF8;PWMINTC|=0x04;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
#define PWM_INT_PWM5 BIT_TMP=EA;TA=0xAA;TA=0x55;SFRS=0x01;PWMINTC&=0xF8;PWMINTC|=0x05;TA=0xAA;TA=0x55;SFRS=0x00;EA=BIT_TMP
//--------- PWM Dead time setting ------------------------------
#define PWM45_DEADTIME_ENABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;PDTEN|=0x04;EA=BIT_TMP
#define PWM34_DEADTIME_ENABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;PDTEN|=0x02;EA=BIT_TMP
#define PWM01_DEADTIME_ENABLE BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;PDTEN|=0x01;EA=BIT_TMP
/*****************************************************************************************
* For ADC INIT setting
*****************************************************************************************/
#define Enable_ADC_AIN0 ADCCON0&=0xF0;P17_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT0;ADCCON1|=SET_BIT0 //P17
#define Enable_ADC_AIN1 ADCCON0&=0xF0;ADCCON0|=0x01;P30_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT1;ADCCON1|=SET_BIT0 //P30
#define Enable_ADC_AIN2 ADCCON0&=0xF0;ADCCON0|=0x02;P07_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT2;ADCCON1|=SET_BIT0 //P07
#define Enable_ADC_AIN3 ADCCON0&=0xF0;ADCCON0|=0x03;P06_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT3;ADCCON1|=SET_BIT0 //P06
#define Enable_ADC_AIN4 ADCCON0&=0xF0;ADCCON0|=0x04;P05_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT4;ADCCON1|=SET_BIT0 //P05
#define Enable_ADC_AIN5 ADCCON0&=0xF0;ADCCON0|=0x05;P04_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT5;ADCCON1|=SET_BIT0 //P04
#define Enable_ADC_AIN6 ADCCON0&=0xF0;ADCCON0|=0x06;P03_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT6;ADCCON1|=SET_BIT0 //P03
#define Enable_ADC_AIN7 ADCCON0&=0xF0;ADCCON0|=0x07;P11_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT7;ADCCON1|=SET_BIT0 //P11
#define Enable_ADC_BandGap ADCCON0|=SET_BIT3;ADCCON0&=0xF8;ADCCON1|=SET_BIT0 //Band-gap 1.22V
#define Disable_ADC ADCCON1&=0xFE;
#define PWM0_FALLINGEDGE_TRIG_ADC ADCCON0&=~SET_BIT5;ADCCON0&=~SET_BIT4;ADCCON1&=~SET_BIT3;ADCCON1&=~SET_BIT2;ADCCON1|=SET_BIT1
#define PWM2_FALLINGEDGE_TRIG_ADC ADCCON0&=~SET_BIT5;ADCCON0|=SET_BIT4;ADCCON1&=~SET_BIT3;ADCCON1&=~SET_BIT2;ADCCON1|=SET_BIT1
#define PWM4_FALLINGEDGE_TRIG_ADC ADCCON0|=SET_BIT5;ADCCON0&=~SET_BIT4;ADCCON1&=~SET_BIT3;ADCCON1&=~SET_BIT2;ADCCON1|=SET_BIT1
#define PWM0_RISINGEDGE_TRIG_ADC ADCCON0&=~SET_BIT5;ADCCON0&=~SET_BIT4;ADCCON1&=~SET_BIT3;ADCCON1|=SET_BIT2;ADCCON1|=SET_BIT1
#define PWM2_RISINGEDGE_TRIG_ADC ADCCON0&=~SET_BIT5;ADCCON0|=SET_BIT4;ADCCON1&=~SET_BIT3;ADCCON1|=SET_BIT2;ADCCON1|=SET_BIT1
#define PWM4_RISINGEDGE_TRIG_ADC ADCCON0|=SET_BIT5;ADCCON0&=~SET_BIT4;ADCCON1&=~SET_BIT3;ADCCON1|=SET_BIT2;ADCCON1|=SET_BIT1
#define PWM0_CENTRAL_TRIG_ADC ADCCON0&=~SET_BIT5;ADCCON0&=~SET_BIT4;ADCCON1|=SET_BIT3;ADCCON1&=~SET_BIT2;ADCCON1|=SET_BIT1
#define PWM2_CENTRAL_TRIG_ADC ADCCON0&=~SET_BIT5;ADCCON0|=SET_BIT4;ADCCON1|=SET_BIT3;ADCCON1&=~SET_BIT2;ADCCON1|=SET_BIT1
#define PWM4_CENTRAL_TRIG_ADC ADCCON0|=SET_BIT5;ADCCON0&=~SET_BIT4;ADCCON1|=SET_BIT3;ADCCON1&=~SET_BIT2;ADCCON1|=SET_BIT1
#define PWM0_END_TRIG_ADC ADCCON0&=~SET_BIT5;ADCCON0&=~SET_BIT4;ADCCON1|=SET_BIT3;ADCCON1|=SET_BIT2;ADCCON1|=SET_BIT1
#define PWM2_END_TRIG_ADC ADCCON0&=~SET_BIT5;ADCCON0|=SET_BIT4;ADCCON1|=SET_BIT3;ADCCON1|=SET_BIT2;ADCCON1|=SET_BIT1
#define PWM4_END_TRIG_ADC ADCCON0|=SET_BIT5;ADCCON0&=~SET_BIT4;ADCCON1|=SET_BIT3;ADCCON1|=SET_BIT2;ADCCON1|=SET_BIT1
#define P04_FALLINGEDGE_TRIG_ADC ADCCON0|=0x30;ADCCON1&=0xF3;ADCCON1|=SET_BIT1;ADCCON1&=~SET_BIT6
#define P13_FALLINGEDGE_TRIG_ADC ADCCON0|=0x30;ADCCON1&=0xF3;ADCCON1|=SET_BIT1;ADCCON1|=SET_BIT6
#define P04_RISINGEDGE_TRIG_ADC ADCCON0|=0x30;ADCCON1&=~SET_BIT3;ADCCON1|=SET_BIT2;ADCCON1|=SET_BIT1;ADCCON1&=~SET_BIT6
#define P13_RISINGEDGE_TRIG_ADC ADCCON0|=0x30;ADCCON1&=~SET_BIT3;ADCCON1|=SET_BIT2;ADCCON1|=SET_BIT1;ADCCON1|=SET_BIT6
/*****************************************************************************************
* For SPI INIT setting
*****************************************************************************************/
#define SPICLK_DIV2 clr_SPR0;clr_SPR1
#define SPICLK_DIV4 set_SPR0;clr_SPR1
#define SPICLK_DIV8 clr_SPR0;set_SPR1
#define SPICLK_DIV16 set_SPR0;set_SPR1
#define Enable_SPI_Interrupt set_ESPI;set_EA
#define SS P15

306
fw/n76e003/common/inc/N76E003.h Executable file
View File

@@ -0,0 +1,306 @@
/*--------------------------------------------------------------------------
N76E003.H
Header file for Nuvoton N76E003 (SDCC version)
--------------------------------------------------------------------------*/
#ifndef N76E003_H
#define N76E003_H
__sfr __at (0x80) P0;
__sfr __at (0x81) SP;
__sfr __at (0x82) DPL;
__sfr __at (0x83) DPH;
__sfr __at (0x84) RCTRIM0;
__sfr __at (0x85) RCTRIM1;
__sfr __at (0x86) RWK;
__sfr __at (0x87) PCON;
__sfr __at (0x88) TCON;
__sfr __at (0x89) TMOD;
__sfr __at (0x8A) TL0;
__sfr __at (0x8B) TL1;
__sfr __at (0x8C) TH0;
__sfr __at (0x8D) TH1;
__sfr __at (0x8E) CKCON;
__sfr __at (0x8F) WKCON;
__sfr __at (0x90) P1;
__sfr __at (0x91) SFRS; //TA Protection
__sfr __at (0x92) CAPCON0;
__sfr __at (0x93) CAPCON1;
__sfr __at (0x94) CAPCON2;
__sfr __at (0x95) CKDIV;
__sfr __at (0x96) CKSWT; //TA Protection
__sfr __at (0x97) CKEN; //TA Protection
__sfr __at (0x98) SCON;
__sfr __at (0x99) SBUF;
__sfr __at (0x9A) SBUF_1;
__sfr __at (0x9B) EIE;
__sfr __at (0x9C) EIE1;
__sfr __at (0x9F) CHPCON; //TA Protection
__sfr __at (0xA0) P2;
__sfr __at (0xA2) AUXR1;
__sfr __at (0xA3) BODCON0; //TA Protection
__sfr __at (0xA4) IAPTRG; //TA Protection
__sfr __at (0xA5) IAPUEN; //TA Protection
__sfr __at (0xA6) IAPAL;
__sfr __at (0xA7) IAPAH;
__sfr __at (0xA8) IE;
__sfr __at (0xA9) SADDR;
__sfr __at (0xAA) WDCON; //TA Protection
__sfr __at (0xAB) BODCON1; //TA Protection
__sfr __at (0xAC) P3M1;
__sfr __at (0xAC) P3S; //Page1
__sfr __at (0xAD) P3M2;
__sfr __at (0xAD) P3SR; //Page1
__sfr __at (0xAE) IAPFD;
__sfr __at (0xAF) IAPCN;
__sfr __at (0xB0) P3;
__sfr __at (0xB1) P0M1;
__sfr __at (0xB1) P0S; //Page1
__sfr __at (0xB2) P0M2;
__sfr __at (0xB2) P0SR; //Page1
__sfr __at (0xB3) P1M1;
__sfr __at (0xB3) P1S; //Page1
__sfr __at (0xB4) P1M2;
__sfr __at (0xB4) P1SR; //Page1
__sfr __at (0xB5) P2S;
__sfr __at (0xB7) IPH;
__sfr __at (0xB7) PWMINTC; //Page1
__sfr __at (0xB8) IP;
__sfr __at (0xB9) SADEN;
__sfr __at (0xBA) SADEN_1;
__sfr __at (0xBB) SADDR_1;
__sfr __at (0xBC) I2DAT;
__sfr __at (0xBD) I2STAT;
__sfr __at (0xBE) I2CLK;
__sfr __at (0xBF) I2TOC;
__sfr __at (0xC0) I2CON;
__sfr __at (0xC1) I2ADDR;
__sfr __at (0xC2) ADCRL;
__sfr __at (0xC3) ADCRH;
__sfr __at (0xC4) T3CON;
__sfr __at (0xC4) PWM4H; //Page1
__sfr __at (0xC5) RL3;
__sfr __at (0xC5) PWM5H; //Page1
__sfr __at (0xC6) RH3;
__sfr __at (0xC6) PIOCON1; //Page1
__sfr __at (0xC7) TA;
__sfr __at (0xC8) T2CON;
__sfr __at (0xC9) T2MOD;
__sfr __at (0xCA) RCMP2L;
__sfr __at (0xCB) RCMP2H;
__sfr __at (0xCC) TL2;
__sfr __at (0xCC) PWM4L; //Page1
__sfr __at (0xCD) TH2;
__sfr __at (0xCD) PWM5L; //Page1
__sfr __at (0xCE) ADCMPL;
__sfr __at (0xCF) ADCMPH;
__sfr __at (0xD0) PSW;
__sfr __at (0xD1) PWMPH;
__sfr __at (0xD2) PWM0H;
__sfr __at (0xD3) PWM1H;
__sfr __at (0xD4) PWM2H;
__sfr __at (0xD5) PWM3H;
__sfr __at (0xD6) PNP;
__sfr __at (0xD7) FBD;
__sfr __at (0xD8) PWMCON0;
__sfr __at (0xD9) PWMPL;
__sfr __at (0xDA) PWM0L;
__sfr __at (0xDB) PWM1L;
__sfr __at (0xDC) PWM2L;
__sfr __at (0xDD) PWM3L;
__sfr __at (0xDE) PIOCON0;
__sfr __at (0xDF) PWMCON1;
__sfr __at (0xE0) ACC;
__sfr __at (0xE1) ADCCON1;
__sfr __at (0xE2) ADCCON2;
__sfr __at (0xE3) ADCDLY;
__sfr __at (0xE4) C0L;
__sfr __at (0xE5) C0H;
__sfr __at (0xE6) C1L;
__sfr __at (0xE7) C1H;
__sfr __at (0xE8) ADCCON0;
__sfr __at (0xE9) PICON;
__sfr __at (0xEA) PINEN;
__sfr __at (0xEB) PIPEN;
__sfr __at (0xEC) PIF;
__sfr __at (0xED) C2L;
__sfr __at (0xEE) C2H;
__sfr __at (0xEF) EIP;
__sfr __at (0xF0) B;
__sfr __at (0xF1) CAPCON3;
__sfr __at (0xF2) CAPCON4;
__sfr __at (0xF3) SPCR;
__sfr __at (0xF3) SPCR2; //Page1
__sfr __at (0xF4) SPSR;
__sfr __at (0xF5) SPDR;
__sfr __at (0xF6) AINDIDS;
__sfr __at (0xF7) EIPH;
__sfr __at (0xF8) SCON_1;
__sfr __at (0xF9) PDTEN; //TA Protection
__sfr __at (0xFA) PDTCNT; //TA Protection
__sfr __at (0xFB) PMEN;
__sfr __at (0xFC) PMD;
__sfr __at (0xFE) EIP1;
__sfr __at (0xFF) EIPH1;
/* BIT Registers */
/* SCON_1 */
__sbit __at (0xFF) SM0_1 ; // SCON_1^7;
__sbit __at (0xFF) FE_1 ; // SCON_1^7;
__sbit __at (0xFE) SM1_1 ; // SCON_1^6;
__sbit __at (0xFD) SM2_1 ; // SCON_1^5;
__sbit __at (0xFC) REN_1 ; // SCON_1^4;
__sbit __at (0xFB) TB8_1 ; // SCON_1^3;
__sbit __at (0xFA) RB8_1 ; // SCON_1^2;
__sbit __at (0xF9) TI_1 ; // SCON_1^1;
__sbit __at (0xF8) RI_1 ; // SCON_1^0;
/* ADCCON0 */
__sbit __at (0xEF) ADCF ; // ADCCON0^7;
__sbit __at (0xEE) ADCS ; // ADCCON0^6;
__sbit __at (0xED) ETGSEL1 ; // ADCCON0^5;
__sbit __at (0xEC) ETGSEL0 ; // ADCCON0^4;
__sbit __at (0xEB) ADCHS3 ; // ADCCON0^3;
__sbit __at (0xEA) ADCHS2 ; // ADCCON0^2;
__sbit __at (0xE9) ADCHS1 ; // ADCCON0^1;
__sbit __at (0xE8) ADCHS0 ; // ADCCON0^0;
/* PWMCON0 */
__sbit __at (0xDF) PWMRUN ; // PWMCON0^7;
__sbit __at (0xDE) LOAD ; // PWMCON0^6;
__sbit __at (0xDD) PWMF ; // PWMCON0^5;
__sbit __at (0xDC) CLRPWM ; // PWMCON0^4;
/* PSW */
__sbit __at (0xD7) CY ; // PSW^7;
__sbit __at (0xD6) AC ; // PSW^6;
__sbit __at (0xD5) F0 ; // PSW^5;
__sbit __at (0xD4) RS1 ; // PSW^4;
__sbit __at (0xD3) RS0 ; // PSW^3;
__sbit __at (0xD2) OV ; // PSW^2;
__sbit __at (0xD0) P ; // PSW^0;
/* T2CON */
__sbit __at (0xCF) TF2 ; // T2CON^7;
__sbit __at (0xCA) TR2 ; // T2CON^2;
__sbit __at (0xC8) CM_RL2 ; // T2CON^0;
/* I2CON */
__sbit __at (0xC6) I2CEN ; // I2CON^6;
__sbit __at (0xC5) STA ; // I2CON^5;
__sbit __at (0xC4) STO ; // I2CON^4;
__sbit __at (0xC3) SI ; // I2CON^3;
__sbit __at (0xC2) AA ; // I2CON^2;
__sbit __at (0xC0) I2CPX ; // I2CON^0;
/* IP */
__sbit __at (0xBE) PADC ; // IP^6;
__sbit __at (0xBD) PBOD ; // IP^5;
__sbit __at (0xBC) PS ; // IP^4;
__sbit __at (0xBB) PT1 ; // IP^3;
__sbit __at (0xBA) PX1 ; // IP^2;
__sbit __at (0xB9) PT0 ; // IP^1;
__sbit __at (0xB8) PX0 ; // IP^0;
/* P3 */
__sbit __at (0xB0) P30 ;// P3^0;
/* IE */
__sbit __at (0xAF) EA ; // IE^7;
__sbit __at (0xAE) EADC ; // IE^6;
__sbit __at (0xAD) EBOD ; // IE^5;
__sbit __at (0xAC) ES ; // IE^4;
__sbit __at (0xAB) ET1 ; // IE^3;
__sbit __at (0xAA) EX1 ; // IE^2;
__sbit __at (0xA9) ET0 ; // IE^1;
__sbit __at (0xA8) EX0 ; // IE^0;
/* P2 */
__sbit __at (0xA0) P20 ; // P2^0;
/* SCON */
__sbit __at (0x9F) SM0 ; // SCON^7;
__sbit __at (0x9F) FE ; // SCON^7;
__sbit __at (0x9E) SM1 ; // SCON^6;
__sbit __at (0x9D) SM2 ; // SCON^5;
__sbit __at (0x9C) REN ; // SCON^4;
__sbit __at (0x9B) TB8 ; // SCON^3;
__sbit __at (0x9A) RB8 ; // SCON^2;
__sbit __at (0x99) TI ; // SCON^1;
__sbit __at (0x98) RI ; // SCON^0;
/* P1 */
__sbit __at (0x97) P17; // P1^7;
__sbit __at (0x96) P16; // P1^6;
__sbit __at (0x96) TXD_1; // P1^6;
__sbit __at (0x95) P15; // P1^5;
__sbit __at (0x94) P14; // P1^4;
__sbit __at (0x94) SDA; // P1^4;
__sbit __at (0x93) P13; // P1^3;
__sbit __at (0x93) SCL; // P1^3;
__sbit __at (0x92) P12 ; // P1^2;
__sbit __at (0x91) P11 ; // P1^1;
__sbit __at (0x90) P10 ; // P1^0;
/* TCON */
__sbit __at (0x8F) TF1 ; // TCON^7;
__sbit __at (0x8E) TR1 ; // TCON^6;
__sbit __at (0x8D) TF0 ; // TCON^5;
__sbit __at (0x8C) TR0 ; // TCON^4;
__sbit __at (0x8B) IE1 ; // TCON^3;
__sbit __at (0x8A) IT1 ; // TCON^2;
__sbit __at (0x89) IE0 ; // TCON^1;
__sbit __at (0x88) IT0 ; // TCON^0;
/* P0 */
__sbit __at (0x87) P07 ; // P0^7;
__sbit __at (0x87) RXD ; // P0^7;
__sbit __at (0x86) P06 ; // P0^6;
__sbit __at (0x86) TXD ; // P0^6;
__sbit __at (0x85) P05 ; // P0^5;
__sbit __at (0x84) P04 ; // P0^4;
__sbit __at (0x84) STADC ; // P0^4;
__sbit __at (0x83) P03 ; // P0^3;
__sbit __at (0x82) P02 ; // P0^2;
__sbit __at (0x82) RXD_1 ; // P0^2;
__sbit __at (0x81) P01 ; // P0^1;
__sbit __at (0x81) MISO ; // P0^1;
__sbit __at (0x80) P00 ; // P0^0;
__sbit __at (0x80) MOSI ; // P0^0;
#endif

1178
fw/n76e003/common/inc/SFR_Macro.h Executable file

File diff suppressed because it is too large Load Diff

2832
fw/n76e003/common/inc/font.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
#ifndef LCD_H
#define LCD_H
#include <stdlib.h>
#include <string.h>
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "spi.h"
#include "font.h"
/*
* Initialize LCD.
*
* Pinout:
* CS -> P1.1
* DC -> P0.3
* RES -> P1.7
* SCK -> P1.0;SPCLK [spi]
* MOSI -> P0.0;MOSI [spi]
*/
#define LCD_TRANSACTION_START clr_P11;
#define LCD_TRANSACTION_END set_P11;
#define LCD_MODE_COMMAND clr_P03;
#define LCD_MODE_DATA set_P03;
#define LCD_NORMALDISPLAY 0xA7
#define LCD_INVERTDISPLAY 0xA6
#define LCD_CLEARON 0xA5
#define LCD_CLEAROFF 0xA4
#define LCD_RESET 0xE2
#define LCD_LCDWIDTH 128
#define LCD_LCDHEIGHT 64
#define LCD_PIX_START 0
typedef struct LCD_SEGMENT
{
uint8_t clearChar;
uint8_t **buffer;
uint16_t bufferDepth;
uint8_t fontWidth;
uint8_t fontHeight;
uint8_t fontSpacing;
uint8_t page0;
uint8_t rows;
};
bool lcd_init(bool reset);
bool lcd_clear_segment(struct LCD_SEGMENT *segment);
bool lcd_display_segment(struct LCD_SEGMENT *segment);
void lcd_command1(uint8_t c);
void lcd_command_list(const uint8_t *c, uint8_t n);
void lcd_clear(uint8_t d);
#endif /* LCD_H */

View File

@@ -0,0 +1,32 @@
#ifndef MAX6675_H
#define MAX6675_H
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "spi.h"
/**
* Initialize MAX6675.
*
* Pinout:
* CS -> P3.0
* SCK -> P1.0 [spi]
* MISO -> P0.1 [spi]
*
*/
#define MAX6675_TRANSACTION_START \
set_P10; \
clr_P30;
#define MAX6675_TRANSACTION_END \
set_P10; \
set_P30;
void max6675_init();
uint16_t max6675_read();
#endif /* MAX6675_H */

View File

@@ -0,0 +1,25 @@
#ifndef SPI_H
#define SPI_H
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
/*
* Initialize SPI
*
* Pinout:
* SCK -> P1.0
* MOSI -> P0.0
* MISO -> P0.1
* CS -> user defined
*/
void spi_init();
uint8_t spi_write(uint8_t data);
uint8_t spi_read();
#endif /* SPI_H */

147
fw/n76e003/common/src/Common.c Executable file
View File

@@ -0,0 +1,147 @@
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2016 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
//***********************************************************************************************************
// Nuvoton Technoledge Corp.
// Website: http://www.nuvoton.com
// E-Mail : MicroC-8bit@nuvoton.com
// Date : Apr/21/2016
//***********************************************************************************************************
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
//----------------------------------------------------------------------------------
// UART0 baud rate initial setting
//----------------------------------------------------------------------------------
void InitialUART0_Timer1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1
{
P06_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
P07_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
SCON = 0x50; //UART0 Mode1,REN=1,TI=1
TMOD |= 0x20; //Timer1 Mode1
set_SMOD; //UART0 Double Rate Enable
set_T1M;
clr_BRCK; //Serial port 0 baud rate clock source = Timer1
#ifdef FOSC_160000
TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */
#endif
#ifdef FOSC_166000
TH1 = 256 - (1037500/u32Baudrate); /*16.6 MHz */
#endif
set_TR1;
set_TI; //For printf function must setting TI = 1
}
//---------------------------------------------------------------
void InitialUART0_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator
{
P06_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
P07_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
SCON = 0x50; //UART0 Mode1,REN=1,TI=1
set_SMOD; //UART0 Double Rate Enable
T3CON &= 0xF8; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1)
set_BRCK; //UART0 baud rate clock source = Timer3
#ifdef FOSC_160000
RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
#endif
#ifdef FOSC_166000
RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
#endif
set_TR3; //Trigger Timer3
set_TI; //For printf function must setting TI = 1
}
UINT8 Receive_Data_From_UART0(void)
{
UINT8 c;
while (!RI);
c = SBUF;
RI = 0;
return (c);
}
void Send_Data_To_UART0 (UINT8 c)
{
TI = 0;
SBUF = c;
while(TI==0);
}
//----------------------------------------------------------------------------------
// UART1 baud rate initial setting
//----------------------------------------------------------------------------------
void InitialUART1_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator
{
P02_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
P16_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
SCON_1 = 0x50; //UART1 Mode1,REN_1=1,TI_1=1
T3CON = 0x08; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1
clr_BRCK;
#ifdef FOSC_160000
RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
#endif
#ifdef FOSC_166000
RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
#endif
set_TR3; //Trigger Timer3
}
UINT8 Receive_Data_From_UART1(void)
{
UINT8 c;
while (!RI_1);
c = SBUF_1;
RI_1 = 0;
return (c);
}
void Send_Data_To_UART1 (UINT8 c)
{
TI_1 = 0;
SBUF_1 = c;
while(TI_1==0);
}
/*==========================================================================*/
#ifdef SW_Reset
void SW_Reset(void)
{
TA = 0xAA;
TA = 0x55;
set_SWRST;
}
#endif
unsigned char
_sdcc_external_startup (void)
{
__asm
mov 0xC7, #0xAA
mov 0xC7, #0x55
mov 0xFD, #0x5A
mov 0xC7, #0xAA
mov 0xC7, #0x55
mov 0xFD, #0xA5
__endasm;
return 0;
}

116
fw/n76e003/common/src/Delay.c Executable file
View File

@@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2016 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
//***********************************************************************************************************
// Nuvoton Technoledge Corp.
// Website: http://www.nuvoton.com
// E-Mail : MicroC-8bit@nuvoton.com
// Date : Apr/21/2016
//***********************************************************************************************************
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
__bit BIT_TMP;
//-------------------------------------------------------------------------
void Timer0_Delay100us(UINT32 u32CNT)
{
clr_T0M; //T0M=0, Timer0 Clock = Fsys/12
TMOD |= 0x01; //Timer0 is 16-bit mode
set_TR0; //Start Timer0
while (u32CNT != 0)
{
TL0 = LOBYTE(TIMER_DIV12_VALUE_100us); //Find define in "Function_define.h" "TIMER VALUE"
TH0 = HIBYTE(TIMER_DIV12_VALUE_100us);
while (TF0 != 1); //Check Timer0 Time-Out Flag
clr_TF0;
u32CNT --;
}
clr_TR0; //Stop Timer0
}
//------------------------------------------------------------------------------
void Timer0_Delay1ms(UINT32 u32CNT)
{
clr_T0M; //T0M=0, Timer0 Clock = Fsys/12
TMOD |= 0x01; //Timer0 is 16-bit mode
set_TR0; //Start Timer0
while (u32CNT != 0)
{
TL0 = LOBYTE(TIMER_DIV12_VALUE_1ms); //Find define in "Function_define.h" "TIMER VALUE"
TH0 = HIBYTE(TIMER_DIV12_VALUE_1ms);
while (TF0 != 1); //Check Timer0 Time-Out Flag
clr_TF0;
u32CNT --;
}
clr_TR0; //Stop Timer0
}
//------------------------------------------------------------------------------
void Timer1_Delay10ms(UINT32 u32CNT)
{
clr_T1M; //T1M=0, Timer1 Clock = Fsys/12
TMOD |= 0x10; //Timer1 is 16-bit mode
set_TR1; //Start Timer1
while (u32CNT != 0)
{
TL1 = LOBYTE(TIMER_DIV12_VALUE_10ms); //Find define in "Function_define.h" "TIMER VALUE"
TH1 = HIBYTE(TIMER_DIV12_VALUE_10ms);
while (TF1 != 1); //Check Timer1 Time-Out Flag
clr_TF1;
u32CNT --;
}
clr_TR1; //Stop Timer1
}
//------------------------------------------------------------------------------
void Timer2_Delay500us(UINT32 u32CNT)
{
clr_T2DIV2; //Timer2 Clock = Fsys/4
clr_T2DIV1;
set_T2DIV0;
set_TR2; //Start Timer2
while (u32CNT != 0)
{
TL2 = LOBYTE(TIMER_DIV4_VALUE_500us); //Find define in "Function_define.h" "TIMER VALUE"
TH2 = HIBYTE(TIMER_DIV4_VALUE_500us);
while (TF2 != 1); //Check Timer2 Time-Out Flag
clr_TF2;
u32CNT --;
}
clr_TR2; //Stop Timer2
}
//------------------------------------------------------------------------------
void Timer3_Delay100ms(UINT32 u32CNT)
{
T3CON = 0x07; //Timer3 Clock = Fsys/128
set_TR3; //Trigger Timer3
while (u32CNT != 0)
{
RL3 = LOBYTE(TIMER_DIV128_VALUE_100ms); //Find define in "Function_define.h" "TIMER VALUE"
RH3 = HIBYTE(TIMER_DIV128_VALUE_100ms);
while ((T3CON&SET_BIT4) != SET_BIT4); //Check Timer3 Time-Out Flag
clr_TF3;
u32CNT --;
}
clr_TR3; //Stop Timer3
}
//------------------------------------------------------------------------------
void Timer3_Delay10us(UINT32 u32CNT)
{
T3CON = 0x07; //Timer3 Clock = Fsys/128
set_TR3; //Trigger Timer3
while (u32CNT != 0)
{
RL3 = LOBYTE(TIMER_DIV4_VALUE_10us); //Find define in "Function_define.h" "TIMER VALUE"
RH3 = HIBYTE(TIMER_DIV4_VALUE_10us);
while ((T3CON&SET_BIT4) != SET_BIT4); //Check Timer3 Time-Out Flag
clr_TF3;
u32CNT --;
}
clr_TR3; //Stop Timer3
}

167
fw/n76e003/common/src/lcd.c Normal file
View File

@@ -0,0 +1,167 @@
#include <stdbool.h>
#include "lcd.h"
bool lcd_init(bool reset)
{
/* Initialize CS pin HIGH */
P11_PushPull_Mode;
set_P11;
/* Initialize RES pin HIGH */
P17_PushPull_Mode;
set_P17;
/* Initialize DC pin LOW */
P03_PushPull_Mode;
clr_P03;
/* Initialize spi */
spi_init();
if (reset)
{
//lcd_command1(LCD_RESET); // Clear Bias: bias 0
set_P17;
Timer0_Delay1ms(1);
clr_P17;
Timer0_Delay1ms(1);
set_P17;
Timer0_Delay1ms(5);
}
//lcd_command1(0xA1); // Reverse direction (SEG131-SEG0)
//lcd_command1(0xC8); // SHL 1,COM63-COM0
lcd_command1(0xA2); // Clear Bias: bias 0
// Power_Control 4 (internal converter ON) + 2 (internal regulator ON) + 1 (internal follower ON)
lcd_command1(0x28 | 0x07); // Power Control
// Regulator resistor select
// 1+Rb/Ra Vo=(1+Rb/Ra)Vev Vev=(1-(63-a)/162)Vref 2.1v
// 0 3.0 4 5.0(default)
// 1 3.5 5 5.5
// 2 4 6 6
// 3 4.5 7 6.4
//
lcd_command1(0x20 | 0x05); // Regulator resistor
// a(0-63) 32=default Vev=(1-(63-a)/162)Vref 2.1v
lcd_command1(0x81); // Set Contrast
lcd_command1(21);
lcd_command1(0x40); // DisplayLine=0
lcd_clear(0x00); //was 00
lcd_command1(0xAF); // Display ON
return true;
}
void lcd_command1(uint8_t c)
{
LCD_TRANSACTION_START
LCD_MODE_COMMAND
spi_write(c);
LCD_TRANSACTION_END
}
void lcd_command_list(const uint8_t *c, uint8_t n)
{
LCD_TRANSACTION_START
LCD_MODE_COMMAND
for (uint8_t i = 0; i < n; i++)
spi_write(c[i]);
LCD_TRANSACTION_END
}
void lcd_clear(uint8_t d)
{
for (uint8_t page = 0; page < 8; page++)
{
uint8_t dlist1[] = {
0x40 | LCD_PIX_START,
0xB0 | page,
0x10,
(0x0f & 0x00)}; // 0x04 is offset foir normal; 0x00 for upsidedown
lcd_command_list(dlist1, sizeof(dlist1));
LCD_TRANSACTION_START
LCD_MODE_DATA
for (uint8_t idx = 0; idx < 128; idx++)
spi_write(d);
LCD_TRANSACTION_END
}
}
bool lcd_clear_segment(struct LCD_SEGMENT *segment)
{
memset(segment->buffer, segment->clearChar, segment->bufferDepth);
return true;
}
__xdata uint8_t spiBuffer[128];
bool lcd_display_segment(struct LCD_SEGMENT *segment)
{
uint8_t *sBuffer = (uint8_t *)segment->buffer;
uint8_t cols = segment->bufferDepth / segment->rows;
uint8_t spiIdx, rb_now, rbit, rpix2, glyph = 0x00;
uint16_t glyphP = 0x00;
uint8_t spiDepth = cols * ((segment->fontWidth * _FONT_W) + segment->fontSpacing);
memset(spiBuffer, 0x00, spiDepth);
// row by row
for (uint8_t row = 0; row < segment->rows; row++)
{
for (uint8_t fH_now = 0; fH_now < segment->fontHeight; fH_now++)
{
uint8_t dlist1[] = {
0x40 | LCD_PIX_START,
0xB0 | (segment->page0 + row + fH_now),
0x10,
(0x0f & 0x00)}; // |0x04 is offset for normal; 0x00 for upsidedown
lcd_command_list(dlist1, sizeof(dlist1));
spiIdx = 0;
rb_now = _FONT_H * fH_now;
for (uint8_t col = 0; col < cols; col++)
{
glyph = sBuffer[(row * cols) + col];
#ifdef FONTSET_MINI
if (glyph < 0x20 || glyph > 0x60)
glyph = 0x00;
else
glyph -= 0x20;
#endif
glyphP = glyph * _FONT_W;
for (uint8_t fw = 0; fw < _FONT_W; fw++)
{
uint8_t line = _font[glyphP + fw];
if (segment->fontHeight > 1)
{
uint8_t new_line = 0x00;
for (uint8_t idx_now = 0; idx_now < 8; idx_now++)
{
rbit = rb_now + idx_now;
rpix2 = (rbit / segment->fontHeight);
if ((line & (1 << rpix2)))
new_line |= (1 << idx_now);
}
line = new_line;
}
for (uint8_t fW_now = 0; fW_now < segment->fontWidth; fW_now++)
{
spiBuffer[spiIdx++] = line;
}
}
for (uint8_t fs = 0; fs < segment->fontSpacing; fs++)
{
spiBuffer[spiIdx++] = 0x00;
}
}
LCD_TRANSACTION_START
LCD_MODE_DATA
for (uint8_t idx = 0; idx < spiDepth; idx++)
spi_write(spiBuffer[idx]);
LCD_TRANSACTION_END
}
}
return true;
}

View File

@@ -0,0 +1,26 @@
#include "max6675.h"
void max6675_init()
{
/* Initialize CS pin HIGH */
P30_PushPull_Mode;
set_P30;
/* Initialize spi */
spi_init();
}
uint16_t max6675_read()
{
MAX6675_TRANSACTION_START
uint8_t val0 = spi_read();
uint8_t val1 = spi_read();
MAX6675_TRANSACTION_END
uint16_t value = MAKEWORD(val0, val1);
if (value & 0x4)
{
return 0;
}
return (value >> 3);
}

View File

@@ -0,0 +1,34 @@
#include "spi.h"
void spi_init()
{
P10_Quasi_Mode; // P10 (SPCLK) Quasi mode
P00_Quasi_Mode; // P00 (MOSI) Quasi mode
P01_Quasi_Mode; // P01 (MISO) Quasi mode
set_DISMODF; // SS General purpose I/O ( No Mode Fault )
clr_SSOE;
clr_LSBFE; // MSB first
clr_CPOL; // The SPI clock is low in idle mode
clr_CPHA; // The data is sample on the first edge of SPI clock
set_MSTR; // SPI in Master mode
SPICLK_DIV2; // Select SPI clock
set_SPIEN; // Enable SPI function
clr_SPIF;
set_P10;
}
uint8_t spi_write(uint8_t data)
{
SPDR = data;
while(!(SPSR & SET_BIT7));
clr_SPIF;
return SPDR;
}
uint8_t spi_read()
{
SPDR = 0xFF;
while(!(SPSR & SET_BIT7));
clr_SPIF;
return SPDR;
}

View File

@@ -0,0 +1,51 @@
## A directory for n76e003 include file & lib
COMMONDIR = ../common
## Get program name from enclosing directory name
PROGRAM = $(lastword $(subst /, ,$(CURDIR)))
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.rel)
HEADERS=$(wildcard *.h $(COMMONDIR)/inc/*.h)
CC = sdcc
AS = sdas8051
MCU_MODEL = mcs51
MODEL = small
CODE_SIZE = --code-size 18432
IRAM_SIZE = --iram-size 256
XRAM_SIZE = --xram-size 768
DFOSC = -DFOSC_160000
AFLAGS = -l -s
CPPFLAGS = -I$(COMMONDIR)/inc
CFLAGS = -I$(INCDIR) -m$(MCU_MODEL) --model-$(MODEL) --out-fmt-ihx --no-xinit-opt $(DFOSC)
LFLAGS = $(LIBPATH) $(LIBS) -m$(MCU_MODEL) --model-$(MODEL) $(CODE_SIZE) $(IRAM_SIZE) $(XRAM_SIZE) --out-fmt-ihx $(DEBUG) $(DFOSC)
LDLIBS = -L$(COMMONDIR) -lcommon.lib
FLASHTOOL=nuvoprog
.PHONY: all clean flash
all: $(PROGRAM).ihx
@echo $(SOURCES)
exit
@ls -la $(PROGRAM).ihx
$(PROGRAM).ihx: $(OBJECTS) $(COMMONDIR)/common.lib
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(COMMONDIR)/common.lib:
@make -C $(COMMONDIR) all
%.rel : %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
CCOMPILEDFILES=$(SOURCES:.c=.asm) $(SOURCES:.c=.lst) $(SOURCES:.c=.rel) \
$(SOURCES:.c=.rst) $(SOURCES:.c=.sym)
flash: $(PROGRAM).ihx
$(FLASHTOOL) -c $(PROGRAMMER) -p $(DEVICE) -w $(PROGRAM).ihx
clean:
@rm -f $(PROGRAM).ihx $(PROGRAM).cdb $(PROGRAM).lk $(PROGRAM).map $(CCOMPILEDFILES)

View File

@@ -0,0 +1,72 @@
#ifndef DEFAULTS_H
#define DEFAULTS_H
#define LED0 P14
#define SW0 P13
#define BUZZER_CLK (16000000 / 12)
#define BUZZER_FREQ (1200 * 2)
#define BUZZER_PERIOD (0xFFFF - ((BUZZER_CLK / BUZZER_FREQ) - 1))
#define PWM_CLK (16000000 / 8)
#define PWM_FREQ 240
#define PWM_PERIOD ((PWM_CLK / PWM_FREQ) - 1)
#define PWM_SLICE (PWM_PERIOD / 100)
#define SRV0_START 0
#define NUMBER_OF_OUTPUTS 2
#define DEFAULT_TEMP_COOL 45
#define DEFAULT_TEMP_HOT 50
#define DEFAULT_MAX_TEMP 280
#define DEFAULT_MAX_DEVIATION 20
enum
{
SM_GO_NULL = 0,
SM_NULL,
SM_GO_RUN,
SM_RUN,
SM_START_COOLING,
SM_COOLING,
SM_DONE,
SM_DONE_Q
};
enum
{
DISPLAY_CURRENT_SECOND = 0,
DISPLAY_COUNTDOWN_TIMER,
DISPLAY_PROFILE_TIMER,
};
enum
{
ELEMENT_TOP = 0,
ELEMENT_BOTTOM
};
enum
{
PROFILE_FIRST = 0,
PROFILE_MIDDLE,
PROFILE_LAST,
};
#define PID_P 2
#define PID_I 3
#define PID_D 0
#define BIAS_MAX 100
#define BIAS_B 100
#define BIAS_T 75
const uint8_t profile[3][2] = {{150,40},{190,10},{245,12}};
#define PROFILE_LEN 3
#define PROFILE_TEMP 0
#define PROFILE_TIME 1
#define PROFILE_OVERSHOOT 10 // FIX the PID, don't do this!!
#define PROFILE_ADJUST 1
#endif /* DEFAULTS_H */

517
fw/n76e003/ebake1/main.c Normal file
View File

@@ -0,0 +1,517 @@
/*
* N76E003-TOASTER
*
* LED
* LED0 -> [11] P1.4 (RED; HOT)
* SSR
* SSR0 -> [20] P0.4;PWM3 > TOP
* SSR1 -> [10] P1.5;PWM5 > BOTTOM
* SERVO
* SRV0 -> [13] P1.2;PWM0
* SW
* SW0 -> [12] P1.3
* LCD
* CS -> [14] P1.1
* DC -> [19] P0.3
* RES -> [06] P1.7
* SCK -> [15] P1.0;SPCLK [spi]
* MOSI -> [16] P0.0;MOSI [spi]
* MAX6675
* CS -> [05] P3.0
* SCK -> [15] P1.0;SPCLK [spi]
* MISO -> [17] P0.1;MISO [spi]
* BEEP
* BEEP -> [01] P0.5;T0
* UART1 115200 8N1
* TX -> [02] P0.6
* RX -> [03] P0.7
*/
#include <N76E003.h>
#include <SFR_Macro.h>
#include <Function_define.h>
#include <Common.h>
#include <Delay.h>
#include <stdbool.h>
#include <max6675.h>
#include <lcd.h>
#include "defaults.h"
#include "strings.h"
#include "pid.h"
/* Needed for printf */
int putchar(int c)
{
while (!TI)
;
TI = 0;
SBUF = c;
return c;
}
void TIM0_ISR(void) __interrupt(1)
{
clr_TF0;
TL0 = LOBYTE(BUZZER_PERIOD);
TH0 = HIBYTE(BUZZER_PERIOD);
}
volatile uint16_t tim2Value = 0;
void TIM2_ISR(void) __interrupt(5)
{
clr_TF2;
tim2Value++;
}
volatile uint8_t sw0Counter;
void PinInterrupt_ISR(void) __interrupt(7)
{
if (PIF == 0x08)
{
PIF = 0;
sw0Counter++;
}
}
void setOutput(uint8_t value0, uint8_t value1)
{
uint16_t pwm = PWM_SLICE * value0;
if (pwm > 0)
{
PWM3H = HIBYTE(pwm);
PWM3L = LOBYTE(pwm);
}
else
{
PWM3H = 0;
PWM3L = 0;
}
pwm = PWM_SLICE * value1;
if (pwm > 0)
{
set_SFRPAGE;
PWM5H = HIBYTE(pwm);
PWM5L = LOBYTE(pwm);
clr_SFRPAGE;
}
else
{
set_SFRPAGE;
PWM5H = 0;
PWM5L = 0;
clr_SFRPAGE;
}
while (LOAD == 1)
;
set_LOAD;
}
uint16_t setServo(uint8_t value0)
{
uint16_t srv0 = (PWM_SLICE * 6) + (value0 * (PWM_SLICE/4));
PWM0H = HIBYTE(srv0);
PWM0L = LOBYTE(srv0);
while (LOAD == 1)
;
set_LOAD;
return srv0;
}
void setText(bool stdout, bool isTitle, struct LCD_SEGMENT *segment, uint8_t *format, ...)
{
uint8_t *ptr = (uint8_t*)segment->buffer;
lcd_clear_segment(segment);
if (isTitle)
{
*ptr++;
*ptr++;
}
va_list args;
va_start(args, format);
vsprintf(ptr, format, args);
va_end(args);
if (stdout)
{
if (isTitle)
*ptr++;
printf_tiny("%s: '%s'\r\n", ((isTitle) ? " TITLE" : "STATUS"), ptr);
// printf_tiny((isTitle) ? "TITLE: '" : "STATUS: '");
// printf_tiny("%s", ptr);
// printf_tiny("'\r\n");
}
}
/*==========================================================================*/
void main(void)
{
__xdata uint16_t previousTicks = 0xffff;
__xdata uint16_t previousSecond = 0xffff;
__xdata uint8_t servo0 = SRV0_START;
__xdata uint8_t previousDutyCycle[NUMBER_OF_OUTPUTS] = {0, 0};
__xdata uint8_t currentDutyCycle[NUMBER_OF_OUTPUTS] = {0, 0};
__xdata bool isHeating = false;
__xdata uint8_t stateMachine = SM_GO_NULL;
__xdata uint8_t beeps = 2;
__xdata bool beepOn = false;
__xdata uint16_t profileTimer = 0;
__xdata bool profileTimerRunning = false;
__xdata uint8_t profileStep = 0;
__xdata uint16_t desiredTemperature = 0;
__xdata uint8_t currentPidDutyCycle = 0;
__xdata uint8_t previousPidDutyCycle = 0xff;
__xdata uint16_t countdownTimer = 0;
__xdata uint8_t displayTime = DISPLAY_CURRENT_SECOND;
__xdata uint8_t displayType = '+';
__xdata pid_struct pid = {
0, 0, //dstate, istate
10, 0, //imax, imin
99, 0, //max/min output limits
PID_P, PID_I, PID_D //p, i, d gains
};
clr_EA;
/* SW0 setup */
sw0Counter = 0;
P13_Input_Mode;
clr_PIPS1;
set_PIPS0;
Enable_BIT3_FallEdge_Trig;
set_EPI;
/* LED setup */
P14_Quasi_Mode;
/* TIM0 setup / BUZZER */
P05_PushPull_Mode;
TIMER0_MODE1_ENABLE;
TL0 = LOBYTE(BUZZER_PERIOD);
TH0 = HIBYTE(BUZZER_PERIOD);
set_ET0;
set_T0OE;
clr_TR0;
/* TIM2 setup ~200ms */
TIMER2_DIV_128;
TIMER2_Auto_Reload_Delay_Mode;
RCMP2L = LOBYTE(TIMER_DIV128_VALUE_250ms);
RCMP2H = HIBYTE(TIMER_DIV128_VALUE_250ms);
TL2 = 0;
TH2 = 0;
set_ET2;
set_TR2;
/* PWM setup */
PWM_IMDEPENDENT_MODE;
PWM_CENTER_TYPE;
PWM_CLOCK_DIV_8;
PWMPH = HIBYTE(PWM_PERIOD);
PWMPL = LOBYTE(PWM_PERIOD);
set_PWMRUN;
/* SSR setup */
P04_PushPull_Mode;
P15_PushPull_Mode;
PWM3_P04_OUTPUT_ENABLE;
PWM5_P15_OUTPUT_ENABLE;
/* SERVO setup */
P12_PushPull_Mode;
PWM0_P12_OUTPUT_ENABLE;
/* MAX6675 setup */
max6675_init();
/* LCD setup */
lcd_init(true);
__xdata uint8_t lcdTitleBuffer[21];
__xdata struct LCD_SEGMENT lcdTitle = {
'#', // clearChar
lcdTitleBuffer, // buffer
sizeof(lcdTitleBuffer), // bufferDepth
1, // fontWidth
1, // fontHeight
1, // fontSpacing
0, // page0
1, // rows
};
lcd_clear_segment(&lcdTitle);
__xdata uint8_t lcdTimeBuffer[11];
__xdata struct LCD_SEGMENT lcdTime = {
' ', // clearChar
&lcdTimeBuffer, // buffer
sizeof(lcdTimeBuffer), // bufferDepth
2, // fontWidth
2, // fontHeight
1, // fontSpacing
1, // page0
1, // rows
};
lcd_clear_segment(&lcdTime);
__xdata uint8_t lcdPowerTempBuffer[11];
__xdata struct LCD_SEGMENT lcdPowerTemp = {
' ', // clearChar
lcdPowerTempBuffer, // buffer
sizeof(lcdPowerTempBuffer), // bufferDepth
2, // fontWidth
3, // fontHeight
1, // fontSpacing
3, // page0
1, // rows
};
lcd_clear_segment(&lcdPowerTemp);
__xdata uint8_t lcdStatusBuffer[21];
__xdata struct LCD_SEGMENT lcdStatus = {
'#', // clearChar
lcdStatusBuffer, // buffer
sizeof(lcdStatusBuffer), // bufferDepth
1, // fontWidth
2, // fontHeight
1, // fontSpacing
6, // page0
1, // rows
};
lcd_clear_segment(&lcdStatus);
/* UART0 setup */
InitialUART0_Timer3(115200);
TI = 1;
set_EA;
printf_tiny("\r\n\r\n");
do
{
uint8_t currentSW0 = sw0Counter;
sw0Counter = 0;
uint16_t currentTicks = tim2Value;
uint16_t currentTemperatureRaw = max6675_read();
uint16_t currentTemperature = currentTemperatureRaw / 4;
uint16_t currentTemperaturePoint = (currentTemperatureRaw - (currentTemperature * 4)) * 100;
uint16_t currentSecond = (currentTicks / 4);
bool isOneSecondInterval = false;
if (previousTicks != currentTicks)
{
previousTicks = currentTicks;
if (previousSecond != currentSecond)
{
previousSecond = currentSecond;
isOneSecondInterval = true;
if (profileTimerRunning)
profileTimer++;
}
if (beeps)
{
if ((currentTicks % 2) == 0)
{
set_TR0;
beepOn = true;
}
else if (beepOn)
{
clr_TR0;
beepOn = false;
beeps--;
}
}
}
if (currentSW0 && stateMachine == SM_NULL)
{
stateMachine = SM_GO_RUN;
}
else if (currentSW0 && stateMachine == SM_DONE_Q)
{
stateMachine = SM_GO_NULL;
}
else if (currentSW0 && stateMachine > SM_NULL && stateMachine < SM_START_COOLING)
{
beeps += 2;
stateMachine = SM_START_COOLING;
}
else if (currentTemperature > DEFAULT_TEMP_HOT && stateMachine < SM_GO_RUN)
{
setText(true, false, &lcdStatus, "%s %uC", ST_START_HOT, currentTemperature);
beeps += 2;
stateMachine = SM_START_COOLING;
}
if (currentTemperature == 0 && stateMachine > SM_GO_NULL)
{
setText(true, false, &lcdStatus, "%s", ST_THERMOCOUPLE_ERROR);
beeps += 4;
stateMachine = SM_START_COOLING;
}
else if (currentTemperature >= DEFAULT_TEMP_HOT)
{
LED0 = 0;
}
else if (currentTemperature < DEFAULT_TEMP_COOL)
{
LED0 = 1;
}
if (currentTemperature > DEFAULT_MAX_TEMP && stateMachine < SM_START_COOLING)
{
setText(true, false, &lcdStatus, "%s", ST_OVERTEMP);
beeps += 4;
stateMachine = SM_START_COOLING;
}
switch (stateMachine)
{
case SM_GO_NULL:
setText(true, true, &lcdTitle, " %s %s", ST_TITLE, ST_VER);
setText(true, false, &lcdStatus, "%s", ST_PRESS_BUTTON_TO_START);
isHeating = false;
profileStep = 0;
displayTime = DISPLAY_CURRENT_SECOND;
beeps = 0;
clr_TR0;
stateMachine = SM_NULL;
case SM_NULL:
break;
case SM_GO_RUN:
setText(true, true, &lcdTitle, " %s", ST_RUN);
lcd_clear_segment(&lcdStatus);
profileTimer = 0;
profileTimerRunning = false;
desiredTemperature = profile[profileStep][PROFILE_TEMP] + PROFILE_OVERSHOOT;
displayTime = DISPLAY_PROFILE_TIMER;
beeps += 1;
isHeating = true;
stateMachine = SM_RUN;
case SM_RUN:
if (!isOneSecondInterval)
break;
currentPidDutyCycle = update_pid(&pid, pid_guard(desiredTemperature, currentTemperature), currentTemperature);
if ((profileTimerRunning == false) && (profile[profileStep][PROFILE_TEMP] - PROFILE_ADJUST <= currentTemperature))
{
desiredTemperature = profile[profileStep][PROFILE_TEMP] + PROFILE_ADJUST;
profileTimer = 0;
profileTimerRunning = true;
}
if ((profileTimerRunning == true) && (profile[profileStep][PROFILE_TIME] <= profileTimer))
{
beeps += 1;
if (++profileStep == PROFILE_LEN)
stateMachine = SM_START_COOLING;
else
stateMachine = SM_GO_RUN;
}
break;
case SM_START_COOLING:
setText(true, true, &lcdTitle, " %s", ST_COOLING);
isHeating = false;
profileTimerRunning = true;
profileTimer = 0;
displayTime = DISPLAY_PROFILE_TIMER;
beeps += 2;
stateMachine = SM_COOLING;
case SM_COOLING:
if (isOneSecondInterval)
{
if (currentTemperature < DEFAULT_TEMP_HOT && profileTimer >= 1)
{
isHeating = false;
stateMachine = SM_DONE;
}
}
break;
case SM_DONE:
setText(true, true, &lcdTitle, " %s", ST_DONE);
setText(true, false, &lcdStatus, "%s", ST_PRESS_TO_RESTART);
isHeating = false;
beeps += 6;
stateMachine = SM_DONE_Q;
case SM_DONE_Q:
break;
}
if (isHeating)
{
if (previousPidDutyCycle != currentPidDutyCycle)
{
previousPidDutyCycle = currentPidDutyCycle;
currentDutyCycle[ELEMENT_TOP] = currentPidDutyCycle * BIAS_T / BIAS_MAX;
currentDutyCycle[ELEMENT_BOTTOM] = currentPidDutyCycle * BIAS_B / BIAS_MAX;
setOutput(currentDutyCycle[ELEMENT_TOP], currentDutyCycle[ELEMENT_BOTTOM]);
}
}
else
{
if (previousPidDutyCycle != 0)
{
setOutput(0, 0);
previousDutyCycle[ELEMENT_TOP] = 0;
previousDutyCycle[ELEMENT_BOTTOM] = 0;
}
}
if (isOneSecondInterval)
{
lcd_clear_segment(&lcdTime);
lcd_clear_segment(&lcdPowerTemp);
if (stateMachine == SM_DONE_Q)
{ /*
format_sprintf(oledTime->buffer, ((learningFailed) ? ST_FAILED : ((learningAborted) ? ST_ABORTED : ST_SUCCESS)));
if (learningFailed)
format_sprintf(oledPowerTemp->buffer, "%s #%04u", ST_ERROR, learningFailed);
else if (!learningAborted)
format_sprintf(oledPowerTemp->buffer, "%2u %3u %3u", learnedDutyCycle, learnedInertia, learnedInsulation);
*/
}
else
{
uint16_t dT = (displayTime == DISPLAY_CURRENT_SECOND) ? currentSecond : ((displayTime == DISPLAY_COUNTDOWN_TIMER) ? countdownTimer : profileTimer);
uint16_t lm = (dT / 60);
uint16_t tm = (lm % 60);
uint8_t th = (lm / 60);
uint8_t ts = (dT % 60);
setText(false, false, &lcdTime, "%c %02u:%02u:%02u", displayType, th, tm, ts);
if (isHeating)
setText(false, false, &lcdPowerTemp, "%02u:%02u %3u C", currentDutyCycle[ELEMENT_TOP], currentDutyCycle[ELEMENT_BOTTOM], currentTemperature);
else
setText(false, false, &lcdPowerTemp, "--:-- %3u C", currentTemperature);
}
// setText(true, false, &lcdTime, "? %02u:%02u:%02u", th, tm, ts);
lcd_display_segment(&lcdTitle);
lcd_display_segment(&lcdTime);
lcd_display_segment(&lcdPowerTemp);
lcd_display_segment(&lcdStatus);
}
set_IDL;
} while (1);
}

47
fw/n76e003/ebake1/pid.c Normal file
View File

@@ -0,0 +1,47 @@
#include "pid.h"
int8_t update_pid(pid_struct *pid, int8_t error, uint8_t position)
{
int16_t pterm, iterm, dterm, res;
//proportional calculation
pterm = pid->pgain * error;
// update integrator state
pid->istate += error;
if (pid->istate > pid->imax)
pid->istate = pid->imax;
else if (pid->istate < pid->imin)
pid->istate = pid->imin;
//integral calcucation
iterm = pid->igain * pid->istate;
//differential calculation
dterm = pid->dgain * (position - pid->dstate);
pid->dstate = position;
res = pterm + iterm - dterm;
//cut by limits
if (res > pid->vmax)
res = pid->vmax;
else if (res < pid->vmin)
res = pid->vmin;
return res;
}
int8_t pid_guard(uint16_t desired, uint16_t current)
{
int16_t temp_error;
temp_error = desired - current;
if (temp_error > 127)
temp_error = 127;
else if (temp_error < -127)
temp_error = -127;
return (int8_t)temp_error;
}

26
fw/n76e003/ebake1/pid.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef PID_H
#define PID_H
#include <N76E003.h>
#include <SFR_Macro.h>
#include <Function_define.h>
#include <Common.h>
#include <Delay.h>
#include <stdbool.h>
typedef signed char int8_t;
typedef int int16_t;
typedef struct {
int8_t dstate; //last position input
int8_t istate; //integrator state
int8_t imax, imin; //integratir limits
int8_t vmax,vmin; //result limits
int8_t pgain, igain, dgain;
} pid_struct;
int8_t update_pid(pid_struct *pid, int8_t error, uint8_t position);
int8_t pid_guard(uint16_t desired, uint16_t current);
#endif /* PID_H */

View File

@@ -0,0 +1,27 @@
#ifndef STRINGS_H
#define STRINGS_H
const uint8_t ST_TITLE[] = "EASYBAKE";
const uint8_t ST_VER[] = "V1.4";
const uint8_t ST_PRESS_BUTTON_TO_START[] = "PRESS TO START";
const uint8_t ST_PRESS_TO_RESTART[] = "PRESS TO RESTART";
const uint8_t ST_START_HOT[] = "START HOT";
const uint8_t ST_RUN[] = "RUN";
const uint8_t ST_COOLING[] = "COOLING";
const uint8_t ST_DONE[] = "DONE";
const uint8_t ST_THERMOCOUPLE_ERROR[] = "THERMOCOUPLE ERROR";
const uint8_t ST_UNABLE_TO_REACH[] = "UNABLE TO REACH";
const uint8_t ST_OVERTEMP[] = "OVERTEMP";
const uint8_t ST_UNDERTEMP[] = "UNDERTEMP";
const uint8_t ST_UNABLE_TO_COOL[] = "UNABLE TO COOL";
const uint8_t ST_ERROR[] = "ERROR";
const uint8_t ST_FAILED[] = "FAILED";
const uint8_t ST_ABORTED[] = "ABORTED";
const uint8_t ST_SUCCESS[] = "SUCCESS";
#endif /* STRINGS_H */

45
fw/n76e003/test1/Makefile Normal file
View File

@@ -0,0 +1,45 @@
## A directory for n76e003 include file & lib
COMMONDIR = ../common
## Get program name from enclosing directory name
PROGRAM = $(lastword $(subst /, ,$(CURDIR)))
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.rel)
HEADERS=$(wildcard *.h $(COMMONDIR)/inc/*.h)
CC = sdcc
AS = sdas8051
MCU_MODEL = mcs51
MODEL = small
CODE_SIZE = --code-size 18432
IRAM_SIZE = --iram-size 256
XRAM_SIZE = --xram-size 768
DFOSC = -DFOSC_160000
AFLAGS = -l -s
CPPFLAGS = -I$(COMMONDIR)/inc
CFLAGS = -I$(INCDIR) -m$(MCU_MODEL) --model-$(MODEL) --out-fmt-ihx --no-xinit-opt $(DFOSC)
LFLAGS = $(LIBPATH) $(LIBS) -m$(MCU_MODEL) --model-$(MODEL) $(CODE_SIZE) $(IRAM_SIZE) $(XRAM_SIZE) --out-fmt-ihx $(DEBUG) $(DFOSC)
LDLIBS = -L$(COMMONDIR) -lcommon.lib
.PHONY: all clean flash
all: $(PROGRAM).ihx
@echo $(SOURCES)
exit
@ls -la $(PROGRAM).ihx
$(PROGRAM).ihx: $(OBJECTS) $(COMMONDIR)/common.lib
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(COMMONDIR)/common.lib:
@make -C $(COMMONDIR) all
%.rel : %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
CCOMPILEDFILES=$(SOURCES:.c=.asm) $(SOURCES:.c=.lst) $(SOURCES:.c=.rel) \
$(SOURCES:.c=.rst) $(SOURCES:.c=.sym)
clean:
@rm -f $(PROGRAM).ihx $(PROGRAM).cdb $(PROGRAM).lk $(PROGRAM).map $(CCOMPILEDFILES)

View File

@@ -0,0 +1,18 @@
#ifndef DEFAULTS_H
#define DEFAULTS_H
#define LED0 P14
#define SW0 P13
#define BUZZER_CLK (16000000 / 12)
#define BUZZER_FREQ (1200 * 2)
#define BUZZER_PERIOD (0xFFFF - ((BUZZER_CLK / BUZZER_FREQ) - 1))
#define PWM_CLK (16000000 / 8)
#define PWM_FREQ 240
#define PWM_PERIOD ((PWM_CLK / PWM_FREQ) - 1)
#define PWM_SLICE (PWM_PERIOD / 100)
#define SRV0_START 0
#endif /* DEFAULTS_H */

317
fw/n76e003/test1/main.c Normal file
View File

@@ -0,0 +1,317 @@
/*
* N76E003-TEST1
*
* LED
* LED0 -> P1.4 (RED; HOT)
* SSR
* SSR0 -> P0.4;PWM3 > TOP
* SSR1 -> P1.5;PWM5 > BOTTOM
* SERVO
* SRV0 -> P1.2;PWM0
* SW
* SW0 -> P1.3
* LCD
* CS -> P1.1
* DC -> P0.3
* RES -> P1.2
* SCK -> P1.0;SPCLK [spi]
* MOSI -> P0.0;MOSI [spi]
* MAX6675
* CS -> P3.0
* SCK -> P1.0;SPCLK [spi]
* MISO -> P0.1;MISO [spi]
* BEEP
* BEEP -> P0.5;T0
* UART1
* TX -> P0.6
* RX -> P0.7
*/
#include <N76E003.h>
#include <SFR_Macro.h>
#include <Function_define.h>
#include <Common.h>
#include <Delay.h>
#include <stdbool.h>
#include <max6675.h>
#include <lcd.h>
#include "defaults.h"
/* Needed for printf */
int putchar(int c)
{
while (!TI)
;
TI = 0;
SBUF = c;
return c;
}
void TIM0_ISR(void) __interrupt(1)
{
clr_TF0;
TL0 = LOBYTE(BUZZER_PERIOD);
TH0 = HIBYTE(BUZZER_PERIOD);
}
volatile uint16_t tim2Value = 0;
void TIM2_ISR(void) __interrupt(5)
{
clr_TF2;
tim2Value++;
}
volatile uint8_t sw0Counter;
void PinInterrupt_ISR(void) __interrupt(7)
{
if (PIF == 0x08)
{
PIF = 0;
sw0Counter++;
}
}
void setOutput(uint8_t value0, uint8_t value1)
{
uint16_t pwm = PWM_SLICE * value0;
if (pwm > 0)
{
PWM3H = HIBYTE(pwm);
PWM3L = LOBYTE(pwm);
}
else
{
PWM3H = 0;
PWM3L = 0;
}
pwm = PWM_SLICE * value1;
if (pwm > 0)
{
set_SFRPAGE;
PWM5H = HIBYTE(pwm);
PWM5L = LOBYTE(pwm);
clr_SFRPAGE;
}
else
{
set_SFRPAGE;
PWM5H = 0;
PWM5L = 0;
clr_SFRPAGE;
}
while (LOAD == 1)
;
set_LOAD;
}
uint16_t setServo(uint8_t value0)
{
uint16_t srv0 = (PWM_SLICE * 6) + (value0 * (PWM_SLICE/4));
PWM0H = HIBYTE(srv0);
PWM0L = LOBYTE(srv0);
while (LOAD == 1)
;
set_LOAD;
return srv0;
}
/*==========================================================================*/
void main(void)
{
uint16_t previousTicks = 0xffff;
uint16_t previousSecond = 0xffff;
uint8_t servo0 = SRV0_START;
uint8_t beeps = 2;
bool beepOn = false;
clr_EA;
/* SW0 setup */
sw0Counter = 0;
P13_Input_Mode;
clr_PIPS1;
set_PIPS0;
Enable_BIT3_FallEdge_Trig;
set_EPI;
/* LED setup */
P14_Quasi_Mode;
/* TIM0 setup / BUZZER */
P05_PushPull_Mode;
TIMER0_MODE1_ENABLE;
TL0 = LOBYTE(BUZZER_PERIOD);
TH0 = HIBYTE(BUZZER_PERIOD);
set_ET0;
set_T0OE;
clr_TR0;
/* TIM2 setup ~200ms */
TIMER2_DIV_128;
TIMER2_Auto_Reload_Delay_Mode;
RCMP2L = LOBYTE(TIMER_DIV128_VALUE_250ms);
RCMP2H = HIBYTE(TIMER_DIV128_VALUE_250ms);
TL2 = 0;
TH2 = 0;
set_ET2;
set_TR2;
/* PWM setup */
PWM_IMDEPENDENT_MODE;
//PWM_CENTER_TYPE;
PWM_CLOCK_DIV_8;
PWMPH = HIBYTE(PWM_PERIOD);
PWMPL = LOBYTE(PWM_PERIOD);
set_PWMRUN;
/* SSR setup */
P04_PushPull_Mode;
P15_PushPull_Mode;
PWM3_P04_OUTPUT_ENABLE;
PWM5_P15_OUTPUT_ENABLE;
/* SERVO setup */
P12_PushPull_Mode;
PWM0_P12_OUTPUT_ENABLE;
/* MAX6675 setup */
max6675_init();
/* LCD setup */
lcd_init(true);
__xdata uint8_t lcdTitleBuffer[21];
__xdata struct LCD_SEGMENT lcdTitle = {
'#', // clearChar
lcdTitleBuffer, // buffer
sizeof(lcdTitleBuffer), // bufferDepth
1, // fontWidth
1, // fontHeight
1, // fontSpacing
0, // page0
1, // rows
};
lcd_clear_segment(&lcdTitle);
__xdata uint8_t lcdTimeBuffer[11];
__xdata struct LCD_SEGMENT lcdTime = {
' ', // clearChar
lcdTimeBuffer, // buffer
sizeof(lcdTimeBuffer), // bufferDepth
2, // fontWidth
2, // fontHeight
1, // fontSpacing
1, // page0
1, // rows
};
lcd_clear_segment(&lcdTime);
__xdata uint8_t lcdPowerTempBuffer[11];
__xdata struct LCD_SEGMENT lcdPowerTemp = {
' ', // clearChar
lcdPowerTempBuffer, // buffer
sizeof(lcdPowerTempBuffer), // bufferDepth
2, // fontWidth
3, // fontHeight
1, // fontSpacing
3, // page0
1, // rows
};
lcd_clear_segment(&lcdPowerTemp);
__xdata uint8_t lcdStatusBuffer[21];
__xdata struct LCD_SEGMENT lcdStatus = {
'#', // clearChar
lcdStatusBuffer, // buffer
sizeof(lcdStatusBuffer), // bufferDepth
1, // fontWidth
2, // fontHeight
1, // fontSpacing
6, // page0
1, // rows
};
lcd_clear_segment(&lcdStatus);
/* UART0 setup */
InitialUART0_Timer3(115200);
TI = 1;
set_EA;
printf_tiny("\r\nTEST1\r\n");
setOutput(99, 99);
do
{
uint8_t currentSW0 = sw0Counter;
sw0Counter = 0;
uint16_t currentTicks = tim2Value;
uint16_t currentSecond = (currentTicks / 4);
bool isOneSecondInterval = false;
if (previousTicks != currentTicks)
{
previousTicks = currentTicks;
if (previousSecond != currentSecond)
{
previousSecond = currentSecond;
isOneSecondInterval = true;
}
if (beeps)
{
if ((currentTicks % 2) == 0)
{
set_TR0;
beepOn = true;
}
else if (beepOn)
{
clr_TR0;
beepOn = false;
beeps--;
}
}
}
if (currentSW0)
{
beeps += 2;
}
if (isOneSecondInterval)
{
lcd_clear_segment(&lcdTime);
lcd_clear_segment(&lcdPowerTemp);
uint16_t dT = currentSecond;
uint16_t currentTemperatureRaw = max6675_read();
uint16_t currentTemperature = currentTemperatureRaw / 4;
uint16_t currentTemperaturePoint = (currentTemperatureRaw - (currentTemperature * 4)) * 100;
uint16_t lm = (dT / 60);
uint16_t tm = (lm % 60);
uint8_t th = (lm / 60);
uint8_t ts = (dT % 60);
servo0 += 15;
if (servo0 > 180)
{
servo0 = SRV0_START;
}
uint16_t pos0 = setServo(servo0);
printf_tiny("%d:%d:%d > %d\r\n", th, tm, ts, pos0);
sprintf(lcdTimeBuffer, "? %02u:%02u:%02u", th, tm, ts);
sprintf(lcdPowerTempBuffer, "--:-- %3u C", currentTemperature);
LED0 = !LED0;
lcd_display_segment(&lcdTitle);
lcd_display_segment(&lcdTime);
lcd_display_segment(&lcdPowerTemp);
lcd_display_segment(&lcdStatus);
}
set_IDL;
} while (1);
}

40
fw/stm8s/common/Makefile Normal file
View File

@@ -0,0 +1,40 @@
DEVICE = stm8s103f3
F_CPU ?= 16000000
OLED ?= SSD1306_128_64
FONTSET_MINI ?= FONTSET_MINI
SRCDIR = ./src
INCDIR = ./inc
## Get program name from enclosing directory name
PROGRAM = $(lastword $(subst /, ,$(CURDIR)))
SOURCES=$(wildcard *.c $(SRCDIR)/*.c)
OBJECTS=$(SOURCES:.c=.rel)
HEADERS=$(wildcard *.h $(INCDIR)/*.h)
CC = sdcc
PROGRAMMER = stlinkv2
DEFINES=
DEFINES += -DSTM8S103
CPPFLAGS = -I$(INCDIR)
CFLAGS = --Werror --std-sdcc99 -mstm8 --opt-code-size $(DEFINES) -DF_CPU=$(F_CPU)UL -D$(OLED) -D$(FONTSET_MINI)
AR = sdar
ARFLAGS = -rc
.PHONY: all clean flash
all: $(PROGRAM).lib
$(PROGRAM).lib: $(OBJECTS)
$(AR) $(ARFLAGS) $(PROGRAM).lib $^
%.rel : %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
CCOMPILEDFILES=$(SOURCES:.c=.asm) $(SOURCES:.c=.lst) $(SOURCES:.c=.rel) \
$(SOURCES:.c=.rst) $(SOURCES:.c=.sym)
clean:
@rm -f $(PROGRAM).lib $(PROGRAM).cdb $(PROGRAM).lk $(PROGRAM).map $(CCOMPILEDFILES)

216
fw/stm8s/common/extra.def Normal file
View File

@@ -0,0 +1,216 @@
// Extra rules generated by rules_gen.py
// REG ^= (1 << 0)
replace restart {
ld a, %1
xor a, #0x01
ld %1, a
} by {
bcpl %1, #0 ; peephole replaced xor by bcpl.
} if notUsed('a')
// REG |= (1 << 0)
replace restart {
ld a, %1
or a, #0x01
ld %1, a
} by {
bset %1, #0 ; peephole replaced or by bset.
} if notUsed('a')
// REG &= ~(1 << 0)
replace restart {
ld a, %1
and a, #0xfe
ld %1, a
} by {
bres %1, #0 ; peephole replaced and by bres.
} if notUsed('a')
// REG ^= (1 << 1)
replace restart {
ld a, %1
xor a, #0x02
ld %1, a
} by {
bcpl %1, #1 ; peephole replaced xor by bcpl.
} if notUsed('a')
// REG |= (1 << 1)
replace restart {
ld a, %1
or a, #0x02
ld %1, a
} by {
bset %1, #1 ; peephole replaced or by bset.
} if notUsed('a')
// REG &= ~(1 << 1)
replace restart {
ld a, %1
and a, #0xfd
ld %1, a
} by {
bres %1, #1 ; peephole replaced and by bres.
} if notUsed('a')
// REG ^= (1 << 2)
replace restart {
ld a, %1
xor a, #0x04
ld %1, a
} by {
bcpl %1, #2 ; peephole replaced xor by bcpl.
} if notUsed('a')
// REG |= (1 << 2)
replace restart {
ld a, %1
or a, #0x04
ld %1, a
} by {
bset %1, #2 ; peephole replaced or by bset.
} if notUsed('a')
// REG &= ~(1 << 2)
replace restart {
ld a, %1
and a, #0xfb
ld %1, a
} by {
bres %1, #2 ; peephole replaced and by bres.
} if notUsed('a')
// REG ^= (1 << 3)
replace restart {
ld a, %1
xor a, #0x08
ld %1, a
} by {
bcpl %1, #3 ; peephole replaced xor by bcpl.
} if notUsed('a')
// REG |= (1 << 3)
replace restart {
ld a, %1
or a, #0x08
ld %1, a
} by {
bset %1, #3 ; peephole replaced or by bset.
} if notUsed('a')
// REG &= ~(1 << 3)
replace restart {
ld a, %1
and a, #0xf7
ld %1, a
} by {
bres %1, #3 ; peephole replaced and by bres.
} if notUsed('a')
// REG ^= (1 << 4)
replace restart {
ld a, %1
xor a, #0x10
ld %1, a
} by {
bcpl %1, #4 ; peephole replaced xor by bcpl.
} if notUsed('a')
// REG |= (1 << 4)
replace restart {
ld a, %1
or a, #0x10
ld %1, a
} by {
bset %1, #4 ; peephole replaced or by bset.
} if notUsed('a')
// REG &= ~(1 << 4)
replace restart {
ld a, %1
and a, #0xef
ld %1, a
} by {
bres %1, #4 ; peephole replaced and by bres.
} if notUsed('a')
// REG ^= (1 << 5)
replace restart {
ld a, %1
xor a, #0x20
ld %1, a
} by {
bcpl %1, #5 ; peephole replaced xor by bcpl.
} if notUsed('a')
// REG |= (1 << 5)
replace restart {
ld a, %1
or a, #0x20
ld %1, a
} by {
bset %1, #5 ; peephole replaced or by bset.
} if notUsed('a')
// REG &= ~(1 << 5)
replace restart {
ld a, %1
and a, #0xdf
ld %1, a
} by {
bres %1, #5 ; peephole replaced and by bres.
} if notUsed('a')
// REG ^= (1 << 6)
replace restart {
ld a, %1
xor a, #0x40
ld %1, a
} by {
bcpl %1, #6 ; peephole replaced xor by bcpl.
} if notUsed('a')
// REG |= (1 << 6)
replace restart {
ld a, %1
or a, #0x40
ld %1, a
} by {
bset %1, #6 ; peephole replaced or by bset.
} if notUsed('a')
// REG &= ~(1 << 6)
replace restart {
ld a, %1
and a, #0xbf
ld %1, a
} by {
bres %1, #6 ; peephole replaced and by bres.
} if notUsed('a')
// REG ^= (1 << 7)
replace restart {
ld a, %1
xor a, #0x80
ld %1, a
} by {
bcpl %1, #7 ; peephole replaced xor by bcpl.
} if notUsed('a')
// REG |= (1 << 7)
replace restart {
ld a, %1
or a, #0x80
ld %1, a
} by {
bset %1, #7 ; peephole replaced or by bset.
} if notUsed('a')
// REG &= ~(1 << 7)
replace restart {
ld a, %1
and a, #0x7f
ld %1, a
} by {
bres %1, #7 ; peephole replaced and by bres.
} if notUsed('a')

View File

@@ -0,0 +1,16 @@
#ifndef BEEP_H
#define BEEP_H
/*
* BEEP -> PD4
*/
#include <stdint.h>
#include "stm8s.h"
void beep_init(void);
void beep_on(void);
void beep_off(void);
void beep_freq(uint8_t freq);
#endif /* BEEP_H */

View File

@@ -0,0 +1,21 @@
#ifndef CLOCK_H
#define CLOCK_H
#ifndef F_CPU
#warning "F_CPU not defined, using 2MHz by default"
#define F_CPU 16000000UL
#endif
#include <stdint.h>
#include "stm8s.h"
inline void clock_init(void)
{
#if (F_CPU == 2000000UL)
#elif (F_CPU == 16000000UL)
CLK_CKDIVR = 0x00; // Set the frequency to 16 MHz
#endif
}
#endif /* CLOCK_H */

View File

@@ -0,0 +1,23 @@
#ifndef DELAY_H
#define DELAY_H
#ifndef F_CPU
#warning "F_CPU not defined, using 2MHz by default"
#define F_CPU 2000000UL
#endif
#include <stdint.h>
inline void delay_ms(uint32_t ms) {
for (uint32_t i = 0; i < ((F_CPU / 18 / 1000UL) * ms); i++) {
__asm__("nop");
}
}
inline void delay_us(uint32_t us) {
for (uint32_t i = 0; i < ((F_CPU / 18 /1000UL / 1000UL) * us); i++) {
__asm__("nop");
}
}
#endif /* DELAY_H */

View File

@@ -0,0 +1,14 @@
#ifndef EEPROM_H
#define EEPROM_H
#include <stdint.h>
#include "stm8s.h"
void eeprom_unlock();
void eeprom_lock();
void eeprom_wait_busy();
void eeprom_read(uint16_t addr, uint8_t *buf, int len);
void eeprom_write(uint16_t addr, uint8_t *buf, uint16_t len);
#endif /* EEPROM_H */

2832
fw/stm8s/common/inc/font.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
#ifndef FORMAT_H
#define FORMAT_H
#include <stdint.h>
#include <stdarg.h>
void format_vsprintf(uint8_t *str, uint8_t *format, va_list args);
void format_sprintf(uint8_t *str, uint8_t *format, ...);
#endif /* FORMAT_H */

View File

@@ -0,0 +1,69 @@
#ifndef LCD12864_H
#define LCD12864_H
#include "stdint.h"
#include "stdbool.h"
#include "stm8s.h"
/*
* Initialize LCD12864.
*
* Pinout:
* SCK -> PC5 [spi]
* MOSI -> PC6 [spi]
* MISO -> PC7 [spi]
* CS -> PC4
* RES -> PA2 //PC3
* DC -> PD2
*/
#define LCD12864_TRANSACTION_START \
SPI_CR1 = SPI_CR1_MSTR | SPI_CR1_BR(0) | SPI_CR1_SPE; \
PC_ODR &= ~PIN4;
#define LCD12864_TRANSACTION_END \
while ((SPI_SR & SPI_SR_BSY)) \
; \
PC_ODR |= PIN4; \
SPI_CR1 &= ~SPI_CR1_SPE;
#define LCD12864_MODE_COMMAND PD_ODR &= ~PIN2;
#define LCD12864_MODE_DATA PD_ODR |= PIN2;
#define LCD12864_NORMALDISPLAY 0xA7
#define LCD12864_INVERTDISPLAY 0xA6
#define LCD12864_CLEARON 0xA5
#define LCD12864_CLEAROFF 0xA4
#define LCD12864_RESET 0xE2
#define LCD12864_LCDWIDTH 128
#define LCD12864_LCDHEIGHT 64
#define LCD12864_PIX_START 0
struct LCD12864_SEGMENT
{
uint8_t fontWidth;
uint8_t fontHeight;
uint8_t fontSpacing;
uint8_t rows;
uint8_t cols;
uint8_t width;
uint8_t height;
uint8_t *buffer;
uint16_t bufferDepth;
uint8_t page0;
uint8_t clearChar;
};
bool lcd12864_init(bool reset);
void lcd12864_invert_display(bool i);
void lcd12864_clear_display(bool i);
struct LCD12864_SEGMENT *lcd12864_new_segment(uint8_t page0, uint8_t fontWidth, uint8_t fontHeight, uint8_t fontSpacing, uint8_t rows, uint8_t clearChar);
bool lcd12864_free_segment(struct LCD12864_SEGMENT *segment);
bool lcd12864_clear_segment(struct LCD12864_SEGMENT *segment);
bool lcd12864_display_segment(struct LCD12864_SEGMENT *segment);
void lcd12864_clear(uint8_t d);
void lcd12864_command1(uint8_t c);
void lcd12864_command_list(const uint8_t *c, uint8_t n);
#endif /* LCD12864_H */

View File

@@ -0,0 +1,26 @@
#ifndef MAX31855K_H
#define MAX31855K_H
#include <stdint.h>
/**
* Initialize MAX31855K.
*
* Pinout:
* CS -> PA1
* SCK -> PC5 [spi]
* MISO -> PC7 [spi]
*
*/
#define MAX31855K_TRANSACTION_START \
PC_ODR |= PIN5; \
PA_ODR &= ~PIN1;
#define MAX31855K_TRANSACTION_END \
PA_ODR |= PIN1;
void max31855k_init();
uint16_t max31855k_read();
#endif /* MAX31855K_H */

View File

@@ -0,0 +1,27 @@
#ifndef MAX6675_H
#define MAX6675_H
#include <stdint.h>
//#include "spi.h"
/**
* Initialize MAX6675.
*
* Pinout:
* CS -> PA1
* SCK -> PC5 [spi]
* MISO -> PC7 [spi]
*
*/
#define MAX6675_TRANSACTION_START \
PC_ODR |= PIN5; \
PA_ODR &= ~PIN1;
#define MAX6675_TRANSACTION_END \
PA_ODR |= PIN1;
void max6675_init();
uint16_t max6675_read();
#endif /* MAX6675_H */

108
fw/stm8s/common/inc/oled.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef OLED_H
#define OLED_H
#include "stdint.h"
#include "stdbool.h"
#include "stm8s.h"
/*
* Initialize OLED.
*
* Pinout:
* SCK -> PC5 [spi]
* MOSI -> PC6 [spi]
* MISO -> PC7 [spi]
* CS -> PC4
* RES -> PC3
* DC -> PD6
*/
struct SEGMENT
{
uint8_t fontWidth;
uint8_t fontHeight;
uint8_t fontSpacing;
uint8_t rows;
uint8_t cols;
uint8_t width;
uint8_t height;
uint8_t *buffer;
uint16_t bufferDepth;
uint8_t page0;
uint8_t clearChar;
};
bool oled_init(uint8_t vcs, bool reset);
struct SEGMENT *oled_new_segment(uint8_t page0, uint8_t fontWidth, uint8_t fontHeight, uint8_t fontSpacing, uint8_t rows, uint8_t clearChar);
bool oled_free_segment(struct SEGMENT *segment);
bool oled_clear_segment(struct SEGMENT *segment);
bool oled_display_segment(struct SEGMENT *segment);
void oled_clear_display(void);
void oled_invert_display(bool i);
void oled_dim_display(bool dim);
void oled_command_list(const uint8_t *c, uint8_t n);
void oled_command1(uint8_t c);
#if defined SSD1306_128_64
#define OLED_LCDWIDTH 128
#define OLED_LCDHEIGHT 64
#define OLED_PIX_START 0
#endif
#if defined SSD1306_128_32
#define OLED_LCDWIDTH 128
#define OLED_LCDHEIGHT 32
#define OLED_PIX_START 0
#endif
#if defined SH1106_128_64
#define OLED_LCDWIDTH 128
#define OLED_LCDHEIGHT 64
#define OLED_PIX_START 2
#endif
#ifndef OLED_LCDWIDTH
#define OLED_LCDWIDTH 128
#define OLED_LCDHEIGHT 64
#define OLED_PIX_START 0
#endif
#define SSD1306_BLACK 0 ///< Draw 'off' pixels
#define SSD1306_WHITE 1 ///< Draw 'on' pixels
#define SSD1306_INVERSE 2 ///< Invert pixels
#define TRANSACTION_START \
SPI_CR1 = SPI_CR1_MSTR | SPI_CR1_BR(0) | SPI_CR1_SPE; \
PC_ODR &= ~PIN4;
#define TRANSACTION_END \
while ((SPI_SR & SPI_SR_BSY)) \
; \
PC_ODR |= PIN4; \
SPI_CR1 &= ~SPI_CR1_SPE;
#define OLED_MODE_COMMAND PD_ODR &= ~PIN6;
#define OLED_MODE_DATA PD_ODR |= PIN6;
#define SSD1306_EXTERNALVCC 0x01 ///< External display voltage source
#define SSD1306_SWITCHCAPVCC 0x02 ///< Gen. display voltage from 3.3V
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR 0x22
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#endif /* OLED_H */

21
fw/stm8s/common/inc/spi.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef SPI_H
#define SPI_H
#include <stdint.h>
/*
* Initialize SPI in MODE1.
*
* Pinout:
* SCK -> PC5
* MOSI -> PC6
* MISO -> PC7
* CS -> user defined
*/
void spi_init();
void spi_write(uint8_t data);
uint8_t spi_read();
#endif /* SPI_H */

425
fw/stm8s/common/inc/stm8s.h Normal file
View File

@@ -0,0 +1,425 @@
/*
* Register definitions for STM8S103 (and STM8S003)
* Still incomplete.
*/
#ifndef _STH8_H
#define _STH8_H
/* Handy macros for GPIO */
#define CONCAT(a, b) a##_##b
#define PORT(a, b) CONCAT(a, b)
#define PIN0 (1 << 0)
#define PIN1 (1 << 1)
#define PIN2 (1 << 2)
#define PIN3 (1 << 3)
#define PIN4 (1 << 4)
#define PIN5 (1 << 5)
#define PIN6 (1 << 6)
#define PIN7 (1 << 7)
/* Register addresses */
/* Clock */
#define CLK_CKDIVR *(volatile unsigned char *)0x50C6
/* GPIO */
#define PA_ODR *(volatile unsigned char *)0x5000
#define PA_IDR *(volatile unsigned char *)0x5001
#define PA_DDR *(volatile unsigned char *)0x5002
#define PA_CR1 *(volatile unsigned char *)0x5003
#define PA_CR2 *(volatile unsigned char *)0x5004
#define PB_ODR *(volatile unsigned char *)0x5005
#define PB_IDR *(volatile unsigned char *)0x5006
#define PB_DDR *(volatile unsigned char *)0x5007
#define PB_CR1 *(volatile unsigned char *)0x5008
#define PB_CR2 *(volatile unsigned char *)0x5009
#define PC_ODR *(volatile unsigned char *)0x500A
#define PC_IDR *(volatile unsigned char *)0x500B
#define PC_DDR *(volatile unsigned char *)0x500C
#define PC_CR1 *(volatile unsigned char *)0x500D
#define PC_CR2 *(volatile unsigned char *)0x500E
#define PD_ODR *(volatile unsigned char *)0x500F
#define PD_IDR *(volatile unsigned char *)0x5010
#define PD_DDR *(volatile unsigned char *)0x5011
#define PD_CR1 *(volatile unsigned char *)0x5012
#define PD_CR2 *(volatile unsigned char *)0x5013
#define EXTI_CR1 *(volatile unsigned char *)0x50A0
#define EXTI_CR2 *(volatile unsigned char *)0x50A1
/* UART */
#define UART1_SR *(volatile unsigned char *)0x5230
#define UART1_DR *(volatile unsigned char *)0x5231
#define UART1_BRR1 *(volatile unsigned char *)0x5232
#define UART1_BRR2 *(volatile unsigned char *)0x5233
#define UART1_CR1 *(volatile unsigned char *)0x5234
#define UART1_CR2 *(volatile unsigned char *)0x5235
#define UART1_CR3 *(volatile unsigned char *)0x5236
#define UART1_CR4 *(volatile unsigned char *)0x5237
#define UART1_CR5 *(volatile unsigned char *)0x5238
#define UART1_GTR *(volatile unsigned char *)0x5239
#define UART1_PSCR *(volatile unsigned char *)0x523A
#define UART_SR_TXE (1 << 7)
#define UART_SR_TC (1 << 6)
#define UART_SR_RXNE (1 << 5)
#define UART_SR_IDLE (1 << 4)
#define UART_SR_OR (1 << 3)
#define UART_SR_NF (1 << 2)
#define UART_SR_FE (1 << 1)
#define UART_SR_PE (1 << 0)
#define UART_CR1_R8 (1 << 7)
#define UART_CR1_T8 (1 << 6)
#define UART_CR1_UARTD (1 << 5)
#define UART_CR1_M (1 << 4)
#define UART_CR1_WAKE (1 << 3)
#define UART_CR1_PCEN (1 << 2)
#define UART_CR1_PS (1 << 1)
#define UART_CR1_PIEN (1 << 0)
#define UART_CR2_TIEN (1 << 7)
#define UART_CR2_TCIEN (1 << 6)
#define UART_CR2_RIEN (1 << 5)
#define UART_CR2_ILIEN (1 << 4)
#define UART_CR2_TEN (1 << 3)
#define UART_CR2_REN (1 << 2)
#define UART_CR2_RWU (1 << 1)
#define UART_CR2_SBK (1 << 0)
#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_CPOL (1 << 2)
#define UART_CR3_CPHA (1 << 1)
#define UART_CR3_LBCL (1 << 0)
/* Timers */
#define TIM1_CR1 *(volatile unsigned char *)0x5250
#define TIM1_CR2 *(volatile unsigned char *)0x5251
#define TIM1_SMCR *(volatile unsigned char *)0x5252
#define TIM1_ETR *(volatile unsigned char *)0x5253
#define TIM1_IER *(volatile unsigned char *)0x5254
#define TIM1_SR1 *(volatile unsigned char *)0x5255
#define TIM1_SR2 *(volatile unsigned char *)0x5256
#define TIM1_EGR *(volatile unsigned char *)0x5257
#define TIM1_CCMR1 *(volatile unsigned char *)0x5258
#define TIM1_CCMR2 *(volatile unsigned char *)0x5259
#define TIM1_CCMR3 *(volatile unsigned char *)0x525A
#define TIM1_CCMR4 *(volatile unsigned char *)0x525B
#define TIM1_CCER1 *(volatile unsigned char *)0x525C
#define TIM1_CCER2 *(volatile unsigned char *)0x525D
#define TIM1_CNTRH *(volatile unsigned char *)0x525E
#define TIM1_CNTRL *(volatile unsigned char *)0x525F
#define TIM1_PSCRH *(volatile unsigned char *)0x5260
#define TIM1_PSCRL *(volatile unsigned char *)0x5261
#define TIM1_ARRH *(volatile unsigned char *)0x5262
#define TIM1_ARRL *(volatile unsigned char *)0x5263
#define TIM1_RCR *(volatile unsigned char *)0x5264
#define TIM1_CCR1H *(volatile unsigned char *)0x5265
#define TIM1_CCR1L *(volatile unsigned char *)0x5266
#define TIM1_CCR2H *(volatile unsigned char *)0x5267
#define TIM1_CCR2L *(volatile unsigned char *)0x5268
#define TIM1_CCR3H *(volatile unsigned char *)0x5269
#define TIM1_CCR3L *(volatile unsigned char *)0x526A
#define TIM1_CCR4H *(volatile unsigned char *)0x526B
#define TIM1_CCR4L *(volatile unsigned char *)0x526C
#define TIM1_BKR *(volatile unsigned char *)0x526D
#define TIM1_DTR *(volatile unsigned char *)0x526E
#define TIM1_OISR *(volatile unsigned char *)0x526F
/* Note these are for STM8S103 and STM8S003
STM8S105,104/207/208 are different */
#define TIM2_CR1 *(volatile unsigned char *)0x5300
#define TIM2_CR2 *(volatile unsigned char *)0x5301
#define TIM2_SMCR *(volatile unsigned char *)0x5302
#define TIM2_IER *(volatile unsigned char *)0x5303
#define TIM2_SR1 *(volatile unsigned char *)0x5304
#define TIM2_SR2 *(volatile unsigned char *)0x5305
#define TIM2_EGR *(volatile unsigned char *)0x5306
#define TIM2_CCMR1 *(volatile unsigned char *)0x5307
#define TIM2_CCMR2 *(volatile unsigned char *)0x5308
#define TIM2_CCMR3 *(volatile unsigned char *)0x5309
#define TIM2_CCER1 *(volatile unsigned char *)0x530A
#define TIM2_CCER2 *(volatile unsigned char *)0x530B
#define TIM2_CNTRH *(volatile unsigned char *)0x530C
#define TIM2_CNTRL *(volatile unsigned char *)0x530D
#define TIM2_PSCR *(volatile unsigned char *)0x530E
#define TIM2_ARRH *(volatile unsigned char *)0x530F
#define TIM2_ARRL *(volatile unsigned char *)0x5310
#define TIM2_CCR1H *(volatile unsigned char *)0x5311
#define TIM2_CCR1L *(volatile unsigned char *)0x5312
#define TIM2_CCR2H *(volatile unsigned char *)0x5313
#define TIM2_CCR2L *(volatile unsigned char *)0x5314
#define TIM2_CCR3H *(volatile unsigned char *)0x5315
#define TIM2_CCR3L *(volatile unsigned char *)0x5316
#define TIM2_CR1_CEN (1 << 0)
#define TIM2_CCER1_CC1P (1 << 1)
#define TIM2_CCER1_CC1E (1 << 0)
#define TIM2_CCER1_CC2P (1 << 5)
#define TIM2_CCER1_CC2E (1 << 4)
#define TIM2_CCER2_CC3P (1 << 1)
#define TIM2_CCER2_CC3E (1 << 0)
#define TIM2_CCMR2_OC2M0 (1 << 4)
#define TIM2_CCMR2_OC2M1 (1 << 5)
#define TIM2_CCMR2_OC2M2 (1 << 6)
/* Note these are for STM8S103 and STM8S003
STM8S105,104/207/208 are different */
#define TIM4_CR1 *(volatile unsigned char *)0x5340
#define TIM4_CR2 *(volatile unsigned char *)0x5341
#define TIM4_SMCR *(volatile unsigned char *)0x5342
#define TIM4_IER *(volatile unsigned char *)0x5343
#define TIM4_SR *(volatile unsigned char *)0x5344
#define TIM4_EGR *(volatile unsigned char *)0x5345
#define TIM4_CNTR *(volatile unsigned char *)0x5346
#define TIM4_PSCR *(volatile unsigned char *)0x5347
#define TIM4_ARR *(volatile unsigned char *)0x5348
#define TIM_IER_BIE (1 << 7)
#define TIM_IER_TIE (1 << 6)
#define TIM_IER_COMIE (1 << 5)
#define TIM_IER_CC4IE (1 << 4)
#define TIM_IER_CC3IE (1 << 3)
#define TIM_IER_CC2IE (1 << 2)
#define TIM_IER_CC1IE (1 << 1)
#define TIM_IER_UIE (1 << 0)
#define TIM_CR1_APRE (1 << 7)
#define TIM_CR1_CMSH (1 << 6)
#define TIM_CR1_CMSL (1 << 5)
#define TIM_CR1_DIR (1 << 4)
#define TIM_CR1_OPM (1 << 3)
#define TIM_CR1_URS (1 << 2)
#define TIM_CR1_UDIS (1 << 1)
#define TIM_CR1_CEN (1 << 0)
#define TIM_SR1_BIF (1 << 7)
#define TIM_SR1_TIF (1 << 6)
#define TIM_SR1_COMIF (1 << 5)
#define TIM_SR1_CC4IF (1 << 4)
#define TIM_SR1_CC3IF (1 << 3)
#define TIM_SR1_CC2IF (1 << 2)
#define TIM_SR1_CC1IF (1 << 1)
#define TIM_SR1_UIF (1 << 0)
/* SPI */
#define SPI_CR1 *(volatile unsigned char *)0x5200
#define SPI_CR2 *(volatile unsigned char *)0x5201
#define SPI_ICR *(volatile unsigned char *)0x5202
#define SPI_SR *(volatile unsigned char *)0x5203
#define SPI_DR *(volatile unsigned char *)0x5204
#define SPI_CRCPR *(volatile unsigned char *)0x5205
#define SPI_RXCRCR *(volatile unsigned char *)0x5206
#define SPI_TXCRCR *(volatile unsigned char *)0x5207
#define SPI_CR1_LSBFIRST (1 << 7)
#define SPI_CR1_SPE (1 << 6)
#define SPI_CR1_BR(br) ((br) << 3)
#define SPI_CR1_MSTR (1 << 2)
#define SPI_CR1_CPOL (1 << 1)
#define SPI_CR1_CPHA (1 << 0)
#define SPI_CR2_BDM (1 << 7)
#define SPI_CR2_BDOE (1 << 6)
#define SPI_CR2_CRCEN (1 << 5)
#define SPI_CR2_CRCNEXT (1 << 4)
#define SPI_CR2_RXONLY (1 << 2)
#define SPI_CR2_SSM (1 << 1)
#define SPI_CR2_SSI (1 << 0)
#define SPI_ICR_TXIE (1 << 7)
#define SPI_ICR_RXIE (1 << 6)
#define SPI_ICR_ERRIE (1 << 5)
#define SPI_ICR_WKIE (1 << 4)
#define SPI_SR_BSY (1 << 7)
#define SPI_SR_OVR (1 << 6)
#define SPI_SR_MODF (1 << 5)
#define SPI_SR_CRCERR (1 << 4)
#define SPI_SR_WKUP (1 << 3)
#define SPI_SR_TXE (1 << 1)
#define SPI_SR_RxNE (1 << 0)
/* I2C */
#define I2C_CR1 *(volatile unsigned char *)0x5210
#define I2C_CR2 *(volatile unsigned char *)0x5211
#define I2C_FREQR *(volatile unsigned char *)0x5212
#define I2C_OARL *(volatile unsigned char *)0x5213
#define I2C_OARH *(volatile unsigned char *)0x5214
#define I2C_DR *(volatile unsigned char *)0x5216
#define I2C_SR1 *(volatile unsigned char *)0x5217
#define I2C_SR2 *(volatile unsigned char *)0x5218
#define I2C_SR3 *(volatile unsigned char *)0x5219
#define I2C_ITR *(volatile unsigned char *)0x521A
#define I2C_CCRL *(volatile unsigned char *)0x521B
#define I2C_CCRH *(volatile unsigned char *)0x521C
#define I2C_TRISER *(volatile unsigned char *)0x521D
#define I2C_PECR *(volatile unsigned char *)0x521E
/* ADC */
#define ADC_DBxR *(volatile unsigned char *)0x53E0
#define ADC_CSR *(volatile unsigned char *)0x5400
#define ADC_CR1 *(volatile unsigned char *)0x5401
#define ADC_CR2 *(volatile unsigned char *)0x5402
#define ADC_CR3 *(volatile unsigned char *)0x5403
#define ADC_DRH *(volatile unsigned char *)0x5404
#define ADC_DRL *(volatile unsigned char *)0x5405
#define ADC_TDRH *(volatile unsigned char *)0x5406
#define ADC_TDRL *(volatile unsigned char *)0x5407
#define ADC_HTRH *(volatile unsigned char *)0x5408
#define ADC_HTRL *(volatile unsigned char *)0x5409
#define ADC_LTRH *(volatile unsigned char *)0x540A
#define ADC_LTRL *(volatile unsigned char *)0x540B
#define ADC_AWSRH *(volatile unsigned char *)0x540C
#define ADC_AWSRL *(volatile unsigned char *)0x540D
#define ADC_AWCRH *(volatile unsigned char *)0x540E
#define ADC_AWCRL *(volatile unsigned char *)0x540F
#define ADC_CSR_EOC (1 << 7)
#define ADC_CSR_AWD (1 << 6)
#define ADC_CSR_EOCIE (1 << 5)
#define ADC_CSR_AWDIE (1 << 4)
#define ADC_CR1_CONT (1 << 1)
#define ADC_CR1_ADON (1 << 0)
#define ADC_CR2_EXTTRIG (1 << 6)
#define ADC_CR2_EXTSEL (1 << 4)
#define ADC_CR2_ALIGN (1 << 3)
#define ADC_CR2_SCAN (1 << 1)
/* BEEP */
#define BEEP_CSR *(volatile unsigned char *)0x50F3
#define BEEP_CSR_EN (1 << 5)
#define BEEP_CSR_SEL(sel) ((sel & 0b00000011) << 6)
#define BEEP_CSR_DIV(div) ((div & 0b00011111) << 0)
#define BEEP_CSR_BEEPDIV ((uint8_t)0x1F) /*!< Beeper Divider prescalar mask */
#define BEEP_FREQUENCY_1KHZ ((uint8_t)0x00) /*!< Beep signal output frequency equals to 1 KHz */
#define BEEP_FREQUENCY_2KHZ ((uint8_t)0x40) /*!< Beep signal output frequency equals to 2 KHz */
#define BEEP_FREQUENCY_4KHZ ((uint8_t)0x80) /*!< Beep signal output frequency equals to 4 KHz */
#define BEEP_CALIBRATION_DEFAULT ((uint8_t)0x0B) /*!< Default value when calibration is not done */
#define LSI_FREQUENCY_MIN ((uint32_t)110000) /*!< LSI minimum value in Hertz */
#define LSI_FREQUENCY_MAX ((uint32_t)150000) /*!< LSI maximum value in Hertz */
/* FLASH */
#define FLASH_IAPSR *(volatile unsigned char *)0x505F
#define FLASH_IAPSR_DUL (1 << 3)
#define FLASH_IAPSR_EOP (1 << 2)
#define FLASH_PUKR_KEY1 0x56
#define FLASH_PUKR_KEY2 0xAE
#define FLASH_DUKR *(volatile unsigned char *)0x5064
#define FLASH_DUKR_KEY1 FLASH_PUKR_KEY2
#define FLASH_DUKR_KEY2 FLASH_PUKR_KEY1
#define EEPROM_START_ADDR 0x4000
#define EEPROM_END_ADDR 0x407F
/* Interrupt commands */
#define enableInterrupts() \
{ \
__asm__("rim\n"); \
} /* enable interrupts */
#define disableInterrupts() \
{ \
__asm__("sim\n"); \
} /* disable interrupts */
#define rim() \
{ \
__asm__("rim\n"); \
} /* enable interrupts */
#define sim() \
{ \
__asm__("sim\n"); \
} /* disable interrupts */
#define nop() \
{ \
__asm__("nop\n"); \
} /* No Operation */
#define trap() \
{ \
__asm__("trap\n"); \
} /* Trap (soft IT) */
#define wfi() \
{ \
__asm__("wfi\n"); \
} /* Wait For Interrupt */
#define halt() \
{ \
__asm__("halt\n"); \
} /* Halt */
/* Interrupt numbers */
#define TIM1_OVR_UIF_IRQ 11
#define TIM2_OVR_UIF_IRQ 13
#define TIM3_OVR_UIF_IRQ 15
#define ADC1_EOC_IRQ 22
#define TIM4_OVR_UIF_IRQ 23
#define ISR(name, vector) void name(void) __interrupt(vector - 2)
#define EXTI_PORTA_vector 0x05
#define EXTI_PORTB_vector 0x06
/*
Interrupts:
0 TLI
1 AWU Auto Wake up from Halt
2 CLK Clock controller
3 EXTI0 Port A external interrupts
4 EXTI1 Port B external interrupts
5 EXTI2 Port C external interrupts
6 EXTI3 Port D external interrupts
7 EXTI4 Port E external interrupts
8 CAN CAN RX interrupt
9 CAN CAN TX/ER/SC interrupt
10 SPI End of Transfer
11 TIM1 Update /Overflow/Underflow/Trigger/Break
12 TIM1 Capture/Compare
13 TIM2 Update /Overflow
14 TIM2 Capture/Compare
15 TIM3 Update /Overflow
16 TIM3 Capture/Compare
17 UART1 Tx complete
18 UART1 Receive Register DATA FULL
19 I2C I2C interrupt
20 UART2/3 Tx complete
21 UART2/3 Receive Register DATA FULL
22 ADC End of Conversion
23 TIM4 Update/Overflow
24 FLASH EOP/WR_PG_DIS
TLI 0
AWU 1
CLK 2
EXTI_PORTA 3
EXTI_PORTB 4
EXTI_PORTC
EXTI_PORTD
EXTI_PORTE
CAN_RX
CAN_TX
SPI
TIM1_UPD_OVF_TRG_BRK
TIM1_CAP_COM
TIM2_UPD_OVF_BRK
TIM2_CAP_COM
TIM3_UPD_OVF_BRK
TIM3_CAP_COM
UART1_TX
UART1_RX
I2C 19
ADC1 22
TIM4_UPD_OVF 23
EEPROM_EEC 24
*/
#endif

View File

@@ -0,0 +1,28 @@
#ifndef UART_H
#define UART_H
#include <stdint.h>
#ifndef BAUDRATE
#define BAUDRATE 115200
#endif
#ifndef F_CPU
#warning "F_CPU not defined, using 2MHz by default"
#define F_CPU 2000000UL
#endif
/**
* Initialize UART1.
* Mode: 8-N-1, flow-control: none.
*
* PD5 -> TX
* PD6 -> RX
*/
void uart_init();
void uart_write(uint8_t data);
uint8_t uart_read();
#endif /* UART_H */

View File

@@ -0,0 +1,6 @@
#ifndef UART_STDIN_H
#define UART_STDIN_H
int getchar(void);
#endif /* UART_STDIN_H */

View File

@@ -0,0 +1,8 @@
#ifndef UART_STDOUT_H
#define UART_STDOUT_H
int putchar(int c);
void putstring(uint8_t *str);
void putsf(uint8_t *format, ...);
#endif /* UART_STDOUT_H */

View File

@@ -0,0 +1,6 @@
#include "beep.h"
void beep_freq(uint8_t freq)
{
BEEP_CSR_DIV(freq);
}

View File

@@ -0,0 +1,7 @@
#include "beep.h"
void beep_init(void)
{
BEEP_CSR &= ~BEEP_CSR_BEEPDIV; /* Clear bits */
BEEP_CSR |= BEEP_CALIBRATION_DEFAULT;
}

View File

@@ -0,0 +1,6 @@
#include "beep.h"
void beep_off(void)
{
BEEP_CSR &= ~BEEP_CSR_EN;
}

View File

@@ -0,0 +1,6 @@
#include "beep.h"
void beep_on(void)
{
BEEP_CSR |= BEEP_CSR_EN;
}

View File

@@ -0,0 +1,3 @@
#include "clock.h"
extern inline void clock_init(void);

View File

@@ -0,0 +1,3 @@
#include "delay.h"
extern inline void delay_ms(uint32_t ms);

View File

@@ -0,0 +1,3 @@
#include "delay.h"
extern inline void delay_us(uint32_t us);

View File

@@ -0,0 +1,5 @@
#include "eeprom.h"
void eeprom_lock() {
FLASH_IAPSR &= ~FLASH_IAPSR_DUL;
}

View File

@@ -0,0 +1,6 @@
#include "eeprom.h"
void eeprom_read(uint16_t addr, uint8_t *buf, int len) {
for (int i = 0; i < len; i++, addr++)
buf[i] = (*(volatile uint8_t *)(addr));
}

View File

@@ -0,0 +1,7 @@
#include "eeprom.h"
void eeprom_unlock() {
FLASH_DUKR = FLASH_DUKR_KEY1;
FLASH_DUKR = FLASH_DUKR_KEY2;
while (!(FLASH_IAPSR & FLASH_IAPSR_DUL));
}

View File

@@ -0,0 +1,5 @@
#include "eeprom.h"
void eeprom_wait_busy() {
while (!(FLASH_IAPSR & FLASH_IAPSR_EOP));
}

View File

@@ -0,0 +1,10 @@
#include "eeprom.h"
void eeprom_write(uint16_t addr, uint8_t *buf, uint16_t len) {
eeprom_unlock();
for (uint16_t i = 0; i < len; i++, addr++) {
(*(volatile uint8_t *)(addr)) = buf[i];
eeprom_wait_busy();
}
eeprom_unlock();
}

View File

@@ -0,0 +1,12 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include "format.h"
void format_sprintf(uint8_t *str, uint8_t *format, ...)
{
va_list args;
va_start(args, format);
format_vsprintf(str, format, args);
va_end(args);
}

View File

@@ -0,0 +1,114 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include "uart_stdout.h"
#include "format.h"
static const uint16_t dv[] = {
10000,
1000,
100,
10,
1,
};
static uint8_t xtoa(uint8_t *str, uint16_t x, const uint16_t *dp)
{
uint8_t len = 0;
uint8_t c;
uint16_t d;
if (x)
{
while (x < *dp)
++dp;
do
{
d = *dp++;
c = '0';
while (x >= d)
++c, x -= d;
*str++ = c;
len++;
} while (!(d & 1));
}
else
{
len++;
*str++ = (uint8_t)'0';
}
*str++ = 0x00;
return len;
}
void format_vsprintf(uint8_t *str, uint8_t *format, va_list args) {
uint8_t c, len;
int16_t i;
uint8_t *string_temp;
uint8_t buff[6];
while (c = *format++)
{
bool zl = false;
uint8_t zs = 0;
uint8_t cnt = 0;
if (c == '%')
{
if (*format == (uint8_t)'0')
{
*format++;
zl = true;
}
if (*format >= (uint8_t)'1' && *format <= (uint8_t)'5')
{
zs = (uint8_t)*format - 0x30;
*format++;
}
switch (c = *format++)
{
case '%': // %
*str++ = (uint8_t)'%';
break;
case 's': // String
string_temp = va_arg(args, uint8_t *);
while (*string_temp != 0)
{
*str++ = *string_temp++;
}
break;
case 'c': // Char
*str++ = va_arg(args, uint8_t);
break;
case 'i': // 16 bit Integer
case 'u': // 16 bit Unsigned
i = va_arg(args, int16_t);
if (c == 'i' && i < 0)
i = -i, *str++ = (uint8_t)'-';
len = xtoa(buff, (uint16_t)i, dv);
if (zs && (len < zs))
{
while (++len <= zs)
*str++ = (zl) ? (uint8_t)'0' : (uint8_t)' ';
}
string_temp = &buff[0];
for (uint8_t index = 0; index <= sizeof(buff); index++)
while (*string_temp != 0)
{
*str++ = *string_temp++;
}
break;
case 0:
return;
default:
goto bad_fmt;
}
}
else
{
bad_fmt:
*str++ = c;
}
}
*str++ = 0x00;
}

View File

@@ -0,0 +1,21 @@
#include <stdint.h>
#include "lcd12864.h"
#include "spi.h"
void lcd12864_clear(uint8_t d)
{
for (uint8_t page = 0; page < 8; page++)
{
uint8_t dlist1[] = {
0x40 | LCD12864_PIX_START,
0xB0 | page,
(0x10 | (0 >> 4)),
(0x0f & 0) | 0x04};
lcd12864_command_list(dlist1, sizeof(dlist1));
LCD12864_TRANSACTION_START
LCD12864_MODE_DATA
for (uint8_t idx = 0; idx < 128; idx++)
spi_write(d);
LCD12864_TRANSACTION_END
}
}

View File

@@ -0,0 +1,10 @@
#include <stdbool.h>
#include "lcd12864.h"
#include "spi.h"
#include "stm8s.h"
void lcd12864_clear_display(bool i)
{
lcd12864_command1(i ? LCD12864_CLEARON : LCD12864_CLEAROFF);
}

View File

@@ -0,0 +1,13 @@
#include <stdbool.h>
#include <string.h>
#include "lcd12864.h"
bool lcd12864_clear_segment(struct LCD12864_SEGMENT *segment)
{
if (!segment)
return false;
memset(segment->buffer, segment->clearChar, segment->bufferDepth);
return true;
}

View File

@@ -0,0 +1,11 @@
#include <stdint.h>
#include "lcd12864.h"
#include "spi.h"
void lcd12864_command1(uint8_t c)
{
LCD12864_TRANSACTION_START
LCD12864_MODE_COMMAND
spi_write(c);
LCD12864_TRANSACTION_END
}

View File

@@ -0,0 +1,13 @@
#include <stdint.h>
#include "lcd12864.h"
#include "spi.h"
#include "stm8s.h"
void lcd12864_command_list(const uint8_t *c, uint8_t n)
{
LCD12864_TRANSACTION_START
LCD12864_MODE_COMMAND
for (uint8_t i = 0; i < n; i++)
spi_write(c[i]);
LCD12864_TRANSACTION_END
}

View File

@@ -0,0 +1,88 @@
#include <stdlib.h>
#include <string.h>
#include "lcd12864.h"
#include "font.h"
#include "spi.h"
bool lcd12864_display_segment(struct LCD12864_SEGMENT *segment)
{
if (!segment)
return false;
// allocate spi buffer (for page)
uint8_t spiDepth = segment->cols * ((segment->fontWidth * _FONT_W) + segment->fontSpacing);
uint8_t *spiBuffer = (uint8_t *)malloc(spiDepth);
if (!spiBuffer)
return false;
memset(spiBuffer, 0x00, spiDepth);
uint8_t spiIdx, rb_now, rbit, rpix2, glyph = 0x00;
uint16_t glyphP = 0x00;
uint8_t seg_fH = segment->fontHeight;
// row by row
for (uint8_t row = 0; row < segment->rows; row++)
{
for (uint8_t fH_now = 0; fH_now < seg_fH; fH_now++)
{
uint8_t dlist1[] = {
0x40 | LCD12864_PIX_START,
0xB0 | (segment->page0 + row + fH_now),
(0x10 | (0 >> 4)),
(0x0f & 0x00)}; // |0x04 is offset for normal; 0x00 for upsidedown
lcd12864_command_list(dlist1, sizeof(dlist1));
spiIdx = 0;
rb_now = _FONT_H * fH_now;
for (uint8_t col = 0; col < segment->cols; col++)
{
glyph = segment->buffer[(row * segment->cols) + col];
#ifdef FONTSET_MINI
if (glyph < 0x20 || glyph > 0x60)
glyph = 0x00;
else
glyph -= 0x20;
#endif
glyphP = glyph * _FONT_W;
for (uint8_t fw = 0; fw < _FONT_W; fw++)
{
uint8_t line = _font[glyphP + fw];
if (seg_fH > 1)
{
uint8_t new_line = 0x00;
for (uint8_t idx_now = 0; idx_now < 8; idx_now++)
{
rbit = rb_now + idx_now;
rpix2 = (rbit / seg_fH);
if ((line & (1 << rpix2)))
new_line |= (1 << idx_now);
}
line = new_line;
}
for (uint8_t fW_now = 0; fW_now < segment->fontWidth; fW_now++)
{
spiBuffer[spiIdx++] = line;
}
}
for (uint8_t fs = 0; fs < segment->fontSpacing; fs++)
{
spiBuffer[spiIdx++] = 0x00;
}
}
// push page to display
LCD12864_TRANSACTION_START
LCD12864_MODE_DATA
for (uint8_t idx = 0; idx < spiDepth; idx++)
spi_write(spiBuffer[idx]);
LCD12864_TRANSACTION_END
}
}
if (spiBuffer)
{
free(spiBuffer);
spiBuffer = NULL;
}
return true;
}

View File

@@ -0,0 +1,19 @@
#include <stdbool.h>
#include <stdlib.h>
#include "lcd12864.h"
bool lcd12864_free_segment(struct LCD12864_SEGMENT *segment)
{
if (segment->buffer)
{
free(segment->buffer);
segment->buffer = NULL;
}
if (segment)
{
free(segment);
segment = NULL;
}
return true;
}

View File

@@ -0,0 +1,63 @@
#include <stdint.h>
#include <stdbool.h>
#include "stm8s.h"
#include "lcd12864.h"
#include "spi.h"
#include "delay.h"
bool lcd12864_init(bool reset)
{
/* Initialize CS pin HIGH */
PC_DDR |= PIN4;
PC_CR1 |= PIN4;
PC_ODR |= PIN4;
/* Initialize RES pin HIGH */
PA_DDR |= PIN2;
PA_CR1 |= PIN2;
PA_ODR |= PIN2;
/* Initialize DC pin LOW */
PD_DDR |= PIN2;
PD_CR1 |= PIN2;
PD_ODR &= ~PIN2;
/* Initialize spi */
spi_init();
if (reset)
{
lcd12864_command1(LCD12864_RESET); // Clear Bias: bias 0
PA_ODR |= PIN2;
delay_ms(2);
PA_ODR &= ~PIN2;
delay_ms(2);
PA_ODR |= PIN2;
delay_ms(10);
}
//lcd12864_command1(0xA1); // Reverse direction (SEG131-SEG0)
//lcd12864_command1(0xC8); // SHL 1,COM63-COM0
lcd12864_command1(0xA2); // Clear Bias: bias 0
// Power_Control 4 (internal converter ON) + 2 (internal regulator ON) + 1 (internal follower ON)
lcd12864_command1(0x28 | 0x07); // Power Control
/* Regulator resistor select
** 1+Rb/Ra Vo=(1+Rb/Ra)Vev Vev=(1-(63-a)/162)Vref 2.1v
** 0 3.0 4 5.0(default)
** 1 3.5 5 5.5
** 2 4 6 6
** 3 4.5 7 6.4
*/
lcd12864_command1(0x20 | 0x05); // Regulator resistor
// a(0-63) 32=default Vev=(1-(63-a)/162)Vref 2.1v
lcd12864_command1(0x81); // Set Contrast
lcd12864_command1(21);
lcd12864_command1(0x40); // DisplayLine=0
lcd12864_clear(0x00);
lcd12864_command1(0xAF); // Display ON
return true;
}

View File

@@ -0,0 +1,9 @@
#include <stdbool.h>
#include "lcd12864.h"
#include "spi.h"
#include "stm8s.h"
void lcd12864_invert_display(bool i)
{
lcd12864_command1(i ? LCD12864_INVERTDISPLAY : LCD12864_NORMALDISPLAY);
}

View File

@@ -0,0 +1,31 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "lcd12864.h"
#include "font.h"
struct LCD12864_SEGMENT *lcd12864_new_segment(uint8_t page0, uint8_t fontWidth, uint8_t fontHeight, uint8_t fontSpacing, uint8_t rows, uint8_t clearChar)
{
struct LCD12864_SEGMENT *pSeg = malloc(sizeof(struct LCD12864_SEGMENT));
if (!pSeg)
return NULL;
pSeg->page0 = page0;
pSeg->fontWidth = fontWidth;
pSeg->fontHeight = fontHeight;
pSeg->rows = rows;
pSeg->clearChar = clearChar;
pSeg->fontSpacing = fontSpacing;
pSeg->bufferDepth = (LCD12864_LCDWIDTH / ((fontWidth * _FONT_W) + fontSpacing)) * rows;
pSeg->cols = pSeg->bufferDepth / rows;
if ((!pSeg->buffer) && !(pSeg->buffer = (uint8_t *)malloc(pSeg->bufferDepth)))
{
lcd12864_free_segment(pSeg);
return NULL;
}
lcd12864_clear_segment(pSeg);
return pSeg;
}

View File

@@ -0,0 +1,20 @@
#include "max31855k.h"
#include "stm8s.h"
#include "spi.h"
void max31855k_init()
{
// CS (PA1) as output
PA_DDR |= PIN1;
PA_CR1 |= PIN1;
PA_ODR |= PIN1; // CS high
// CLK PC5 as output
PC_DDR |= PIN5;
PC_CR1 |= PIN5;
PC_ODR |= PIN5; // CLK high
/* Initialize spi */
spi_init();
}

View File

@@ -0,0 +1,30 @@
#include <stdint.h>
#include "delay.h"
#include "max31855k.h"
#include "stm8s.h"
uint16_t max31855k_read()
{
volatile uint16_t value = 0;
// I'm doing bit-bang spi here to return a 16bit uint...
// there is probably a cleaner way..
MAX31855K_TRANSACTION_START
for (uint8_t i = 16; i >= 1; --i)
{
PC_ODR &= ~PIN5;
delay_us(100);
if (PC_IDR & PIN7)
value |= (1 << (i - 1));
PC_ODR |= PIN5;
}
// I stop after 16bits, it works...
MAX31855K_TRANSACTION_END
// With just 16 bits.. We only get a working or not working...
if (value & 0x01)
{
return 0;
}
// Ignoring +/- (always returns as postivive)
return ( value & 0x7fff ) >> 2;
}

View File

@@ -0,0 +1,20 @@
#include "max6675.h"
#include "delay.h"
#include "stm8s.h"
//#include "spi.h"
void max6675_init()
{
// CS (PA1) as output
PA_DDR |= PIN1;
PA_CR1 |= PIN1;
PA_ODR |= PIN1; // CS high
// CLK PC5 as output
PC_DDR |= PIN5;
PC_CR1 |= PIN5;
PC_ODR |= PIN5; // CLK high
delay_ms(600); // gross startup delay
}

View File

@@ -0,0 +1,25 @@
#include <stdint.h>
#include "delay.h"
#include "max6675.h"
#include "stm8s.h"
uint16_t max6675_read()
{
volatile uint16_t value = 0;
MAX6675_TRANSACTION_START
for (uint8_t i = 16; i >= 1; --i)
{
PC_ODR &= ~PIN5;
delay_us(100);
if (PC_IDR & PIN7)
value |= (1 << (i - 1));
PC_ODR |= PIN5;
}
MAX6675_TRANSACTION_END
if (value & 0x4)
{
return 0;
}
return (value >> 3);
}

View File

@@ -0,0 +1,23 @@
#include <stdint.h>
#include "oled.h"
#include "spi.h"
#include "stm8s.h"
void oled_clear_display(void)
{
TRANSACTION_START
for (uint8_t page = 0; page < (OLED_LCDHEIGHT / 8); page++)
{
OLED_MODE_COMMAND
uint8_t dlist1[] = {
0xB0 + page,
OLED_PIX_START,
0x10};
oled_command_list(dlist1, sizeof(dlist1));
OLED_MODE_DATA
for (uint16_t i = 0; i < OLED_LCDWIDTH; i++)
spi_write(0x00);
}
TRANSACTION_END
}

View File

@@ -0,0 +1,14 @@
#include <stdbool.h>
#include <string.h>
#include "oled.h"
bool oled_clear_segment(struct SEGMENT *segment)
{
if (!segment)
return false;
memset(segment->buffer, segment->clearChar, segment->bufferDepth);
return true;
}

View File

@@ -0,0 +1,9 @@
#include <stdint.h>
#include "oled.h"
#include "spi.h"
void oled_command1(uint8_t c)
{
OLED_MODE_COMMAND
spi_write(c);
}

View File

@@ -0,0 +1,12 @@
#include <stdint.h>
#include "oled.h"
#include "spi.h"
#include "stm8s.h"
void oled_command_list(const uint8_t *c, uint8_t n)
{
OLED_MODE_COMMAND
for (uint8_t i = 0; i < n; i++)
spi_write(c[i]);
}

View File

@@ -0,0 +1,19 @@
#include <stdint.h>
#include <stdbool.h>
#include "oled.h"
#include "spi.h"
#include "stm8s.h"
extern uint8_t _contrast;
/*
* Fix me
*/
void oled_dim_display(bool dim)
{
uint8_t contrast = (dim) ? 0 : _contrast;
TRANSACTION_START
oled_command1(SSD1306_SETCONTRAST);
oled_command1(contrast);
TRANSACTION_END
}

View File

@@ -0,0 +1,90 @@
#include <stdlib.h>
#include <string.h>
#include "oled.h"
#include "font.h"
#include "spi.h"
bool oled_display_segment(struct SEGMENT *segment)
{
if (!segment)
return false;
// allocate spi buffer (for page)
uint8_t spiDepth = segment->cols * ((segment->fontWidth * _FONT_W) + segment->fontSpacing);
uint8_t *spiBuffer = (uint8_t *)malloc(spiDepth);
if (!spiBuffer)
return false;
memset(spiBuffer, 0x00, spiDepth);
TRANSACTION_START
uint8_t spiIdx, rb_now, rbit, rpix2, glyph = 0x00;
uint16_t glyphP = 0x00;
uint8_t seg_fH = segment->fontHeight;
// row by row
for (uint8_t row = 0; row < segment->rows; row++)
{
for (uint8_t fH_now = 0; fH_now < seg_fH; fH_now++)
{
OLED_MODE_COMMAND
uint8_t dlist1[] = {
0xB0 + segment->page0 + row + fH_now,
OLED_PIX_START,
0x10};
oled_command_list(dlist1, sizeof(dlist1));
OLED_MODE_DATA
spiIdx = 0;
rb_now = _FONT_H * fH_now;
for (uint8_t col = 0; col < segment->cols; col++)
{
glyph = segment->buffer[(row * segment->cols) + col];
#ifdef FONTSET_MINI
if (glyph < 0x20 || glyph > 0x60)
glyph = 0x00;
else
glyph -= 0x20;
#endif
glyphP = glyph * _FONT_W;
for (uint8_t fw = 0; fw < _FONT_W; fw++)
{
uint8_t line = _font[glyphP + fw];
if (seg_fH > 1)
{
uint8_t new_line = 0x00;
for (uint8_t idx_now = 0; idx_now < 8; idx_now++)
{
rbit = rb_now + idx_now;
rpix2 = (rbit / seg_fH);
if ((line & (1 << rpix2)))
new_line |= (1 << idx_now);
}
line = new_line;
}
for (uint8_t fW_now = 0; fW_now < segment->fontWidth; fW_now++)
{
spiBuffer[spiIdx++] = line;
}
}
for (uint8_t fs = 0; fs < segment->fontSpacing; fs++)
{
spiBuffer[spiIdx++] = 0x00;
}
}
// push page to display
for (uint8_t idx = 0; idx < spiDepth; idx++)
spi_write(spiBuffer[idx]);
}
}
TRANSACTION_END
if (spiBuffer)
{
free(spiBuffer);
spiBuffer = NULL;
}
return true;
}

View File

@@ -0,0 +1,21 @@
#include <stdbool.h>
#include <stdlib.h>
#include "oled.h"
bool oled_free_segment(struct SEGMENT *segment)
{
if (segment->buffer)
{
free(segment->buffer);
segment->buffer = NULL;
}
if (segment)
{
free(segment);
segment = NULL;
}
return true;
}

View File

@@ -0,0 +1,100 @@
#include <stdint.h>
#include <stdbool.h>
#include "stm8s.h"
#include "oled.h"
#include "spi.h"
#include "delay.h"
uint8_t _contrast;
bool oled_init(uint8_t vcs, bool reset)
{
/* Initialize CS pin HIGH */
PC_DDR |= PIN4;
PC_CR1 |= PIN4;
PC_ODR |= PIN4;
/* Initialize RES pin LOW */
PC_DDR |= PIN3;
PC_CR1 |= PIN3;
PC_ODR &= ~PIN3;
/* Initialize DC pin LOW */
PD_DDR |= PIN6;
PD_CR1 |= PIN6;
PD_ODR &= ~PIN6;
/* Initialize spi */
spi_init();
if (reset)
{
PC_ODR |= PIN3;
delay_ms(1);
PC_ODR &= ~PIN3;
delay_ms(10);
PC_ODR |= PIN3;
}
TRANSACTION_START
// Init sequence
static const uint8_t init1[] = {
SSD1306_DISPLAYOFF, // 0xAE
SSD1306_SETDISPLAYCLOCKDIV, // 0xD5
0x80, // the suggested ratio 0x80
SSD1306_SETMULTIPLEX}; // 0xA8
oled_command_list(init1, sizeof(init1));
oled_command1(OLED_LCDHEIGHT - 1);
static const uint8_t init2[] = {
SSD1306_SETDISPLAYOFFSET, // 0xD3
0x0, // no offset
SSD1306_SETSTARTLINE | 0x0, // line #0
SSD1306_CHARGEPUMP}; // 0x8D
oled_command_list(init2, sizeof(init2));
oled_command1((vcs == SSD1306_EXTERNALVCC) ? 0x10 : 0x14);
static const uint8_t init3[] = {
SSD1306_SEGREMAP | 0x1,
SSD1306_COMSCANDEC};
oled_command_list(init3, sizeof(init3));
uint8_t comPins = 0x02;
uint8_t contrast = 0x8F;
#if ((OLED_LCDWIDTH == 128) && (OLED_LCDHEIGHT == 32))
comPins = 0x02;
contrast = 0x8F;
#elif ((OLED_LCDWIDTH == 128) && (OLED_LCDHEIGHT == 64))
comPins = 0x12;
contrast = (vcs == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF;
#elif ((OLED_LCDWIDTH == 96) && (OLED_LCDHEIGHT == 16))
comPins = 0x2;
contrast = (vcs == SSD1306_EXTERNALVCC) ? 0x10 : 0xAF;
#endif
oled_command1(SSD1306_SETCOMPINS);
oled_command1(comPins);
oled_command1(SSD1306_SETCONTRAST);
oled_command1(contrast);
_contrast = contrast;
oled_command1(SSD1306_SETPRECHARGE); // 0xd9
oled_command1((vcs == SSD1306_EXTERNALVCC) ? 0x22 : 0xF1);
static const uint8_t init5[] = {
SSD1306_SETVCOMDETECT, // 0xDB
0x40,
SSD1306_DISPLAYALLON_RESUME, // 0xA4
SSD1306_NORMALDISPLAY, // 0xA6
SSD1306_DEACTIVATE_SCROLL,
SSD1306_DISPLAYON}; // Main screen turn on
oled_command_list(init5, sizeof(init5));
TRANSACTION_END
oled_clear_display();
return true;
}

View File

@@ -0,0 +1,12 @@
#include <stdbool.h>
#include "oled.h"
#include "spi.h"
#include "stm8s.h"
void oled_invert_display(bool i)
{
TRANSACTION_START
oled_command1(i ? SSD1306_INVERTDISPLAY : SSD1306_NORMALDISPLAY);
TRANSACTION_END
}

View File

@@ -0,0 +1,30 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "oled.h"
#include "font.h"
struct SEGMENT *oled_new_segment(uint8_t page0, uint8_t fontWidth, uint8_t fontHeight, uint8_t fontSpacing, uint8_t rows, uint8_t clearChar)
{
struct SEGMENT *pSeg = malloc(sizeof(struct SEGMENT));
if (!pSeg)
return NULL;
pSeg->page0 = page0;
pSeg->fontWidth = fontWidth;
pSeg->fontHeight = fontHeight;
pSeg->rows = rows;
pSeg->clearChar = clearChar;
pSeg->fontSpacing = fontSpacing;
pSeg->bufferDepth = (OLED_LCDWIDTH / ((fontWidth * _FONT_W) + fontSpacing)) * rows;
pSeg->cols = pSeg->bufferDepth / rows;
if ((!pSeg->buffer) && !(pSeg->buffer = (uint8_t *)malloc(pSeg->bufferDepth)))
{
oled_free_segment(pSeg);
return NULL;
}
oled_clear_segment(pSeg);
return pSeg;
}

View File

@@ -0,0 +1,9 @@
#include "spi.h"
#include "stm8s.h"
void spi_init()
{
/* Initialize SPI master at 2mHz */
//SPI_CR2 = SPI_CR2_SSM | SPI_CR2_SSI;
SPI_CR1 = SPI_CR1_MSTR; // | SPI_CR1_BR(0b010);
}

View File

@@ -0,0 +1,10 @@
#include "spi.h"
#include "stm8s.h"
uint8_t spi_read()
{
spi_write(0xFF);
while (!(SPI_SR & SPI_SR_RxNE))
;
return SPI_DR;
}

View File

@@ -0,0 +1,9 @@
#include "spi.h"
#include "stm8s.h"
void spi_write(uint8_t data)
{
SPI_DR = data;
while (!(SPI_SR & SPI_SR_TXE))
;
}

View File

@@ -0,0 +1,12 @@
#include "uart.h"
#include "stm8s.h"
void uart_init() {
/* round to nearest integer */
uint16_t div = (F_CPU + BAUDRATE / 2) / BAUDRATE;
/* madness.. */
UART1_BRR2 = ((div >> 8) & 0xF0) + (div & 0x0F);
UART1_BRR1 = div >> 4;
/* enable transmitter and receiver */
UART1_CR2 = UART_CR2_TEN | UART_CR2_REN;
}

View File

@@ -0,0 +1,7 @@
#include "uart.h"
#include "stm8s.h"
uint8_t uart_read() {
while (!(UART1_SR & UART_SR_RXNE));
return UART1_DR;
}

View File

@@ -0,0 +1,10 @@
#include "uart.h"
#include "uart_stdin.h"
/*
* Redirect stdin to UART
*/
int getchar()
{
return uart_read();
}

View File

@@ -0,0 +1,11 @@
#include "uart.h"
#include "uart_stdout.h"
/*
* Redirect stdout to UART
*/
int putchar(int c)
{
uart_write(c);
return 0;
}

View File

@@ -0,0 +1,10 @@
#include "uart.h"
#include "uart_stdout.h"
void putstring(uint8_t *str)
{
while (*str !=0)
{
putchar(*str++);
}
}

View File

@@ -0,0 +1,7 @@
#include "uart.h"
#include "stm8s.h"
void uart_write(uint8_t data) {
UART1_DR = data;
while (!(UART1_SR & UART_SR_TC));
}

47
fw/stm8s/ebake1/Makefile Normal file
View File

@@ -0,0 +1,47 @@
DEVICE = stm8s103f3
F_CPU ?= 16000000
## A directory for stm8s include file & lib
COMMONDIR = ../common
## Get program name from enclosing directory name
PROGRAM = $(lastword $(subst /, ,$(CURDIR)))
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.rel)
HEADERS=$(wildcard *.h $(COMMONDIR)/inc/*.h)
CC = sdcc
PROGRAMMER = stlinkv2
DEFINES=
DEFINES += -DSTM8S103
CPPFLAGS = -I$(COMMONDIR)/inc
CFLAGS = --Werror --std-sdcc99 -mstm8 --opt-code-size $(DEFINES) -DF_CPU=$(F_CPU)UL
LDFLAGS = -lstm8 -mstm8 --out-fmt-ihx
LDLIBS = -L$(COMMONDIR) -lcommon.lib
.PHONY: all clean flash
all: $(PROGRAM).ihx
@echo $(SOURCES)
exit
@ls -la $(PROGRAM).ihx
$(PROGRAM).ihx: $(OBJECTS) $(COMMONDIR)/common.lib
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(COMMONDIR)/common.lib:
@make -C $(COMMONDIR) all
%.rel : %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
CCOMPILEDFILES=$(SOURCES:.c=.asm) $(SOURCES:.c=.lst) $(SOURCES:.c=.rel) \
$(SOURCES:.c=.rst) $(SOURCES:.c=.sym)
clean:
@rm -f $(PROGRAM).ihx $(PROGRAM).cdb $(PROGRAM).lk $(PROGRAM).map $(CCOMPILEDFILES)
flash: $(PROGRAM).ihx
stm8flash -c $(PROGRAMMER) -p $(DEVICE) -w $(PROGRAM).ihx

View File

@@ -0,0 +1,70 @@
#ifndef DEFAULTS_H
#define DEFAULTS_H
#define LED0_PORT PB
#define LED0_PIN PIN5
#define SSR0_PORT PD
#define SSR0_PIN PIN3
#define SSR1_PORT PA
#define SSR1_PIN PIN3
#define NUMBER_OF_OUTPUTS 2
#define PWM_PSCR 2
#define PWM_CLK (F_CPU / 4)
#define PWM_FREQ 240
#define PWM_ARR (PWM_CLK / PWM_FREQ) - 1
#define DEFAULT_TEMP_COOL 45
#define DEFAULT_TEMP_HOT 50
#define DEFAULT_MAX_TEMP 280
#define DEFAULT_MAX_DEVIATION 20
enum
{
SM_GO_NULL = 0,
SM_NULL,
SM_GO_RUN,
SM_RUN,
SM_START_COOLING,
SM_COOLING,
SM_DONE,
SM_DONE_Q
};
enum
{
DISPLAY_CURRENT_SECOND = 0,
DISPLAY_COUNTDOWN_TIMER,
DISPLAY_PROFILE_TIMER,
};
enum
{
ELEMENT_TOP = 0,
ELEMENT_BOTTOM
};
enum
{
PROFILE_FIRST = 0,
PROFILE_MIDDLE,
PROFILE_LAST,
};
#define PID_P 2
#define PID_I 3
#define PID_D 0
#define BIAS_MAX 100
#define BIAS_T 75
#define BIAS_B 100
const uint8_t profile[3][2] = {{150,40},{190,10},{245,12}};
#define PROFILE_LEN 3
#define PROFILE_TEMP 0
#define PROFILE_TIME 1
#define PROFILE_OVERSHOOT 10 // FIX the PID, don't do this!!
#define PROFILE_ADJUST 1
#endif /* DEFAULTS_H */

416
fw/stm8s/ebake1/main.c Normal file
View File

@@ -0,0 +1,416 @@
/*
* STM8S-TOASTER
*
* LED
* LED0 -> [11] PB5 (RED; HOT)
* SSR
* SSR0 -> [20] PD3 [tim2-ch2] > TOP
* SSR1 -> [10] PA3 [tim2-ch3] > BOTTOM
* SERVO
* SRV0 -> [13] ??
* SW
* SW0 -> [12] PB4
* OLED
* CS -> [14] PC4
* DC -> [19] PD2
* RES -> [06] PA2
* SCK -> [15] PC5 [spi]
* MOSI -> [16] PC6 [spi]
* MAX6675
* CS -> [05] PA1
* SCK -> [15] PC5 [spi]
* MISO -> [17] PC7 [spi]
* BEEP
* BEEP -> [01] PD4
* UART1 115200 8N1
* TX -> [02] PD5
* RX -> [03] PD6
*/
#include <stdint.h>
#include <stdbool.h>
#include <stm8s.h>
#include <clock.h>
#include <format.h>
#include <uart_stdout.h>
#include <uart.h>
#include <lcd12864.h>
#include <max6675.h>
#include <beep.h>
#include "defaults.h"
#include "strings.h"
#include "pid.h"
void setOutput(uint8_t value0, uint8_t value1)
{
uint16_t ccr = ((PWM_CLK / PWM_FREQ) * value0) / 100;
if (ccr > 0)
{
TIM2_CCR2H = ccr >> 8; // Start off
TIM2_CCR2L = ccr & 0x00FF;
}
else
{
TIM2_CCR2H = 0;
TIM2_CCR2L = 0;
}
ccr = ((PWM_CLK / PWM_FREQ) * value1) / 100;
if (ccr > 0)
{
TIM2_CCR3H = ccr >> 8; // Start off
TIM2_CCR3L = ccr & 0x00FF;
}
else
{
TIM2_CCR3H = 0;
TIM2_CCR3L = 0;
}
}
void setText(bool stdout, bool isTitle, struct LCD12864_SEGMENT *segment, uint8_t *format, ...)
{
uint8_t *ptr = segment->buffer;
lcd12864_clear_segment(segment);
if (isTitle)
{
*ptr++;
*ptr++;
}
va_list args;
va_start(args, format);
format_vsprintf(ptr, format, args);
va_end(args);
if (stdout)
{
if (isTitle)
*ptr++;
putstring((isTitle) ? "TITLE: '" : "STATUS: '");
putstring(ptr);
putstring("'\r\n");
}
}
/* TIM1 Update/Overflow interrupt handling routine */
static volatile uint16_t tim1Value;
void TIM1_update(void) __interrupt(TIM1_OVR_UIF_IRQ)
{
tim1Value++;
TIM1_SR1 &= ~TIM_SR1_UIF;
}
static volatile uint8_t extiButton;
ISR(gpio_isr, EXTI_PORTB_vector)
{
extiButton++;
}
int main(void)
{
volatile uint16_t previousTicks = 0xffff;
volatile uint16_t previousSecond = 0xffff;
volatile uint8_t previousDutyCycle[NUMBER_OF_OUTPUTS] = {0, 0};
volatile uint8_t currentDutyCycle[NUMBER_OF_OUTPUTS] = {0, 0};
volatile bool isHeating = false;
volatile uint8_t stateMachine = SM_GO_NULL;
volatile uint8_t beeps = 2;
volatile bool beepOn = false;
volatile uint16_t profileTimer = 0;
volatile bool profileTimerRunning = false;
volatile uint8_t profileStep = 0;
volatile uint16_t desiredTemperature = 0;
volatile uint8_t currentPidDutyCycle = 0;
volatile uint8_t previousPidDutyCycle = 0xff;
volatile uint16_t countdownTimer = 0;
volatile uint8_t displayTime = DISPLAY_CURRENT_SECOND;
volatile uint8_t displayType = '+';
volatile pid_struct pid = {
0, 0, //dstate, istate
10, 0, //imax, imin
99, 0, //max/min output limits
PID_P, PID_I, PID_D //p, i, d gains
};
/* LED setup */
PORT(LED0_PORT, DDR) |= LED0_PIN;
PORT(LED0_PORT, CR1) |= LED0_PIN;
PORT(LED0_PORT, ODR) |= LED0_PIN;
sim();
clock_init();
/* TIM1 setup ~250ms */
tim1Value = 0;
TIM1_PSCRH = 0x10;
TIM1_PSCRL = 0x00;
TIM1_ARRH = 0x03;
TIM1_ARRL = 0xd0;
TIM1_IER |= TIM_IER_UIE;
TIM1_CR1 |= TIM_CR1_CEN;
/* TIM2/PWM setup */
TIM2_PSCR = PWM_PSCR;
TIM2_ARRH = PWM_ARR >> 8;
TIM2_ARRL = PWM_ARR & 0x00FF;
PORT(SSR0_PORT, DDR) |= SSR0_PIN;
PORT(SSR0_PORT, CR1) |= SSR0_PIN;
TIM2_CCER1 |= TIM2_CCER1_CC2E;
TIM2_CCMR2 |= (TIM2_CCMR2_OC2M1 | TIM2_CCMR2_OC2M2);
TIM2_CCMR2 &= ~TIM2_CCMR2_OC2M0;
TIM2_CCR2H = 0;
TIM2_CCR2L = 0;
PORT(SSR1_PORT, DDR) |= SSR1_PIN;
PORT(SSR1_PORT, CR1) |= SSR1_PIN;
TIM2_CCER2 |= TIM2_CCER2_CC3E;
TIM2_CCMR3 |= (TIM2_CCMR2_OC2M1 | TIM2_CCMR2_OC2M2);
TIM2_CCMR3 &= ~TIM2_CCMR2_OC2M0;
TIM2_CCR3H = 0;
TIM2_CCR3L = 0;
TIM2_CR1 |= TIM2_CR1_CEN;
/* EXTI1 BUTTON setup */
extiButton = 0;
PB_CR2 = PIN4;
EXTI_CR1 &= ~0x0C;
EXTI_CR1 |= 0x08;
rim();
if (!lcd12864_init(true))
{
while (1)
;
}
struct LCD12864_SEGMENT *lcdTitle = lcd12864_new_segment(0, 1, 1, 1, 1, '#');
struct LCD12864_SEGMENT *lcdTime = lcd12864_new_segment(1, 2, 2, 1, 1, ' ');
struct LCD12864_SEGMENT *lcdPowerTemp = lcd12864_new_segment(3, 2, 3, 1, 1, ' ');
struct LCD12864_SEGMENT *lcdStatus = lcd12864_new_segment(6, 1, 2, 1, 1, '#');
beep_init();
uart_init();
putstring("\r\n\r\n");
max6675_init();
do
{
volatile uint16_t currentTicks = tim1Value;
volatile uint8_t currentButton = extiButton;
volatile uint16_t currentTemperature = (max6675_read() / 4);
extiButton = 0;
volatile uint16_t currentSecond = (currentTicks / 4);
volatile bool isOneSecondInterval = false;
if (previousTicks != currentTicks)
{
previousTicks = currentTicks;
if (previousSecond != currentSecond)
{
previousSecond = currentSecond;
isOneSecondInterval = true;
if (profileTimerRunning)
profileTimer++;
}
if (beeps)
{
if ((currentTicks % 2) == 0)
{
beep_on();
beepOn = true;
}
else if (beepOn)
{
beep_off();
beepOn = false;
beeps--;
}
}
}
if (currentButton && stateMachine == SM_NULL)
{
stateMachine = SM_GO_RUN;
}
else if (currentButton && stateMachine == SM_DONE_Q)
{
stateMachine = SM_GO_NULL;
}
else if (currentButton && stateMachine > SM_NULL && stateMachine < SM_START_COOLING)
{
beeps += 2;
stateMachine = SM_START_COOLING;
}
else if (currentTemperature > DEFAULT_TEMP_HOT && stateMachine < SM_GO_RUN)
{
setText(true, false, lcdStatus, "%s %uC", ST_START_HOT, currentTemperature);
beeps += 2;
stateMachine = SM_START_COOLING;
}
if (currentTemperature == 0 && stateMachine > SM_GO_NULL)
{
setText(true, false, lcdStatus, "%s", ST_THERMOCOUPLE_ERROR);
beeps += 4;
stateMachine = SM_START_COOLING;
}
else if (currentTemperature >= DEFAULT_TEMP_HOT)
{
PORT(LED0_PORT, ODR) &= ~LED0_PIN;
}
else if (currentTemperature < DEFAULT_TEMP_COOL)
{
PORT(LED0_PORT, ODR) |= LED0_PIN;
}
if (currentTemperature > DEFAULT_MAX_TEMP && stateMachine < SM_START_COOLING)
{
setText(true, false, lcdStatus, "%s", ST_OVERTEMP);
beeps += 4;
stateMachine = SM_START_COOLING;
}
switch (stateMachine)
{
case SM_GO_NULL:
setText(true, true, lcdTitle, " %s %s", ST_TITLE, ST_VER);
setText(true, false, lcdStatus, "%s", ST_PRESS_BUTTON_TO_START);
isHeating = false;
profileStep = 0;
displayTime = DISPLAY_CURRENT_SECOND;
beeps = 0;
beep_off();
stateMachine = SM_NULL;
case SM_NULL:
break;
case SM_GO_RUN:
setText(true, true, lcdTitle, " %s", ST_RUN);
lcd12864_clear_segment(lcdStatus);
profileTimer = 0;
profileTimerRunning = false;
desiredTemperature = profile[profileStep][PROFILE_TEMP] + PROFILE_OVERSHOOT;
displayTime = DISPLAY_PROFILE_TIMER;
beeps += 1;
isHeating = true;
stateMachine = SM_RUN;
case SM_RUN:
if (!isOneSecondInterval)
break;
currentPidDutyCycle = update_pid(&pid, pid_guard(desiredTemperature, currentTemperature), currentTemperature);
if ((profileTimerRunning == false) && (profile[profileStep][PROFILE_TEMP] - PROFILE_ADJUST <= currentTemperature))
{
desiredTemperature = profile[profileStep][PROFILE_TEMP] + PROFILE_ADJUST;
profileTimer = 0;
profileTimerRunning = true;
}
if ((profileTimerRunning == true) && (profile[profileStep][PROFILE_TIME] <= profileTimer))
{
beeps += 1;
if (++profileStep == PROFILE_LEN)
stateMachine = SM_START_COOLING;
else
stateMachine = SM_GO_RUN;
}
break;
case SM_START_COOLING:
setText(true, true, lcdTitle, " %s", ST_COOLING);
isHeating = false;
profileTimerRunning = true;
profileTimer = 0;
displayTime = DISPLAY_PROFILE_TIMER;
beeps += 2;
stateMachine = SM_COOLING;
case SM_COOLING:
if (isOneSecondInterval)
{
if (currentTemperature < DEFAULT_TEMP_HOT && profileTimer >= 1)
{
isHeating = false;
stateMachine = SM_DONE;
}
}
break;
case SM_DONE:
setText(true, true, lcdTitle, " %s", ST_DONE);
setText(true, false, lcdStatus, "%s", ST_PRESS_TO_RESTART);
isHeating = false;
beeps += 6;
stateMachine = SM_DONE_Q;
case SM_DONE_Q:
break;
}
if (isHeating)
{
if (previousPidDutyCycle != currentPidDutyCycle)
{
previousPidDutyCycle = currentPidDutyCycle;
currentDutyCycle[ELEMENT_TOP] = currentPidDutyCycle * BIAS_T / BIAS_MAX;
currentDutyCycle[ELEMENT_BOTTOM] = currentPidDutyCycle * BIAS_B / BIAS_MAX;
setOutput(currentDutyCycle[ELEMENT_TOP], currentDutyCycle[ELEMENT_BOTTOM]);
}
}
else
{
if (previousPidDutyCycle != 0)
{
setOutput(0, 0);
previousDutyCycle[ELEMENT_TOP] = 0;
previousDutyCycle[ELEMENT_BOTTOM] = 0;
}
}
if (isOneSecondInterval)
{
lcd12864_clear_segment(lcdTime);
lcd12864_clear_segment(lcdPowerTemp);
if (stateMachine == SM_DONE_Q)
{ /*
format_sprintf(oledTime->buffer, ((learningFailed) ? ST_FAILED : ((learningAborted) ? ST_ABORTED : ST_SUCCESS)));
if (learningFailed)
format_sprintf(oledPowerTemp->buffer, "%s #%04u", ST_ERROR, learningFailed);
else if (!learningAborted)
format_sprintf(oledPowerTemp->buffer, "%2u %3u %3u", learnedDutyCycle, learnedInertia, learnedInsulation);
*/
}
else
{
uint16_t dT = (displayTime == DISPLAY_CURRENT_SECOND) ? currentSecond : ((displayTime == DISPLAY_COUNTDOWN_TIMER) ? countdownTimer : profileTimer);
uint16_t lm = (dT / 60);
uint16_t tm = (lm % 60);
uint8_t th = (lm / 60);
uint8_t ts = (dT % 60);
format_sprintf(lcdTime->buffer, "%c %02u:%02u:%02u", (uint8_t)displayType, th, tm, ts);
format_sprintf(lcdPowerTemp->buffer, "--:-- %3u C", currentTemperature);
if (isHeating)
format_sprintf(lcdPowerTemp->buffer, "%02u:%02u", currentDutyCycle[ELEMENT_TOP], currentDutyCycle[ELEMENT_BOTTOM]);
}
lcd12864_display_segment(lcdTitle);
lcd12864_display_segment(lcdTime);
lcd12864_display_segment(lcdPowerTemp);
lcd12864_display_segment(lcdStatus);
}
wfi();
} while (1);
}

47
fw/stm8s/ebake1/pid.c Normal file
View File

@@ -0,0 +1,47 @@
#include "pid.h"
int8_t update_pid(pid_struct *pid, int8_t error, uint8_t position)
{
int16_t pterm, iterm, dterm, res;
//proportional calculation
pterm = pid->pgain * error;
// update integrator state
pid->istate += error;
if (pid->istate > pid->imax)
pid->istate = pid->imax;
else if (pid->istate < pid->imin)
pid->istate = pid->imin;
//integral calcucation
iterm = pid->igain * pid->istate;
//differential calculation
dterm = pid->dgain * (position - pid->dstate);
pid->dstate = position;
res = pterm + iterm - dterm;
//cut by limits
if (res > pid->vmax)
res = pid->vmax;
else if (res < pid->vmin)
res = pid->vmin;
return res;
}
int8_t pid_guard(uint16_t desired, uint16_t current)
{
int16_t temp_error;
temp_error = desired - current;
if (temp_error > 127)
temp_error = 127;
else if (temp_error < -127)
temp_error = -127;
return (int8_t)temp_error;
}

18
fw/stm8s/ebake1/pid.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef PID_H
#define PID_H
#include <stdint.h>
typedef struct {
int8_t dstate; //last position input
int8_t istate; //integrator state
int8_t imax, imin; //integratir limits
int8_t vmax,vmin; //result limits
int8_t pgain, igain, dgain;
} pid_struct;
int8_t update_pid(pid_struct *pid, int8_t error, uint8_t position);
int8_t pid_guard(uint16_t desired, uint16_t current);
#endif /* PID_H */

28
fw/stm8s/ebake1/strings.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef STRINGS_H
#define STRINGS_H
#include <stdint.h>
const uint8_t ST_TITLE[] = "EASYBAKE";
const uint8_t ST_VER[] = "V1.4";
const uint8_t ST_PRESS_BUTTON_TO_START[] = "PRESS TO START";
const uint8_t ST_PRESS_TO_RESTART[] = "PRESS TO RESTART";
const uint8_t ST_START_HOT[] = "START HOT";
const uint8_t ST_RUN[] = "RUN";
const uint8_t ST_COOLING[] = "COOLING";
const uint8_t ST_DONE[] = "DONE";
const uint8_t ST_THERMOCOUPLE_ERROR[] = "THERMOCOUPLE ERROR";
const uint8_t ST_UNABLE_TO_REACH[] = "UNABLE TO REACH";
const uint8_t ST_OVERTEMP[] = "OVERTEMP";
const uint8_t ST_UNDERTEMP[] = "UNDERTEMP";
const uint8_t ST_UNABLE_TO_COOL[] = "UNABLE TO COOL";
const uint8_t ST_ERROR[] = "ERROR";
const uint8_t ST_FAILED[] = "FAILED";
const uint8_t ST_ABORTED[] = "ABORTED";
const uint8_t ST_SUCCESS[] = "SUCCESS";
#endif /* STRINGS_H */

47
fw/stm8s/test1/Makefile Normal file
View File

@@ -0,0 +1,47 @@
DEVICE = stm8s103f3
F_CPU ?= 16000000
## A directory for stm8s include file & lib
COMMONDIR = ../common
## Get program name from enclosing directory name
PROGRAM = $(lastword $(subst /, ,$(CURDIR)))
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.rel)
HEADERS=$(wildcard *.h $(COMMONDIR)/inc/*.h)
CC = sdcc
PROGRAMMER = stlinkv2
DEFINES=
DEFINES += -DSTM8S103
CPPFLAGS = -I$(COMMONDIR)/inc
CFLAGS = --Werror --std-sdcc99 -mstm8 --opt-code-size $(DEFINES) -DF_CPU=$(F_CPU)UL
LDFLAGS = -lstm8 -mstm8 --out-fmt-ihx
LDLIBS = -L$(COMMONDIR) -lcommon.lib
.PHONY: all clean flash
all: $(PROGRAM).ihx
@echo $(SOURCES)
exit
@ls -la $(PROGRAM).ihx
$(PROGRAM).ihx: $(OBJECTS) $(COMMONDIR)/common.lib
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(COMMONDIR)/common.lib:
@make -C $(COMMONDIR) all
%.rel : %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
CCOMPILEDFILES=$(SOURCES:.c=.asm) $(SOURCES:.c=.lst) $(SOURCES:.c=.rel) \
$(SOURCES:.c=.rst) $(SOURCES:.c=.sym)
clean:
@rm -f $(PROGRAM).ihx $(PROGRAM).cdb $(PROGRAM).lk $(PROGRAM).map $(CCOMPILEDFILES)
flash: $(PROGRAM).ihx
stm8flash -c $(PROGRAMMER) -p $(DEVICE) -w $(PROGRAM).ihx

17
fw/stm8s/test1/defaults.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef DEFAULTS_H
#define DEFAULTS_H
#define LED0_PORT PB
#define LED0_PIN PIN5
#define SSR0_PORT PD
#define SSR0_PIN PIN3
#define SSR1_PORT PA
#define SSR1_PIN PIN3
#define PWM_PSCR 2
#define PWM_CLK (F_CPU / 4)
#define PWM_FREQ 240
#define PWM_ARR (PWM_CLK / PWM_FREQ) - 1
#endif /* DEFAULTS_H */

193
fw/stm8s/test1/main.c Normal file
View File

@@ -0,0 +1,193 @@
/*
* STM8S-TOASTER
*
* LED
* LED0 -> PB5 (RED; HOT)
* SSR
* SSR0 -> PD3 [tim2-ch2] > TOP
* SSR1 -> PA3 [tim2-ch3] > BOTTOM
* SW
* SW0 -> PB4
* OLED
* CS -> PC4
* DC -> PD2
* RES -> PC3
* SCK -> PC5 [spi]
* MOSI -> PC6 [spi]
* MAX6675
* CS -> PA1
* SCK -> PC5 [spi]
* MISO -> PC7 [spi]
* BEEP
* BEEP -> PD4
* UART1
* TX -> PD5
* RX -> PD6
*/
#include <stdint.h>
#include <stdbool.h>
#include <stm8s.h>
#include <format.h>
#include <clock.h>
#include <uart_stdout.h>
#include <uart.h>
#include <lcd12864.h>
#include <max6675.h>
#include <beep.h>
#include "defaults.h"
/* TIM1 Update/Overflow interrupt handling routine */
static volatile uint16_t tim1Value;
void TIM1_update(void) __interrupt(TIM1_OVR_UIF_IRQ)
{
tim1Value++;
TIM1_SR1 &= ~TIM_SR1_UIF;
}
void setOutput(uint8_t value0, uint8_t value1)
{
uint16_t ccr = ((PWM_CLK / PWM_FREQ) * value0) / 100;
if (ccr > 0)
{
TIM2_CCR2H = ccr >> 8; // Start off
TIM2_CCR2L = ccr & 0x00FF;
}
else
{
TIM2_CCR2H = 0;
TIM2_CCR2L = 0;
}
ccr = ((PWM_CLK / PWM_FREQ) * value1) / 100;
if (ccr > 0)
{
TIM2_CCR3H = ccr >> 8; // Start off
TIM2_CCR3L = ccr & 0x00FF;
}
else
{
TIM2_CCR3H = 0;
TIM2_CCR3L = 0;
}
}
int main(void)
{
volatile uint16_t previousTicks = 0xffff;
volatile uint16_t previousSecond = 0xffff;
volatile uint8_t beeps = 2;
volatile bool beepOn = false;
sim();
clock_init();
uart_init();
max6675_init();
beep_init();
/* LED setup */
PORT(LED0_PORT, DDR) |= LED0_PIN;
PORT(LED0_PORT, CR1) |= LED0_PIN;
/* TIM1 setup ~250ms */
tim1Value = 0;
TIM1_PSCRH = 0x10;
TIM1_PSCRL = 0x00;
TIM1_ARRH = 0x03;
TIM1_ARRL = 0xd0;
TIM1_IER |= TIM_IER_UIE;
TIM1_CR1 |= TIM_CR1_CEN;
/* TIM2/PWM setup */
TIM2_PSCR = PWM_PSCR;
TIM2_ARRH = PWM_ARR >> 8;
TIM2_ARRL = PWM_ARR & 0x00FF;
PORT(SSR0_PORT, DDR) |= SSR0_PIN;
PORT(SSR0_PORT, CR1) |= SSR0_PIN;
TIM2_CCER1 |= TIM2_CCER1_CC2E;
TIM2_CCMR2 |= (TIM2_CCMR2_OC2M1 | TIM2_CCMR2_OC2M2);
TIM2_CCMR2 &= ~TIM2_CCMR2_OC2M0;
TIM2_CCR2H = 0;
TIM2_CCR2L = 0;
PORT(SSR1_PORT, DDR) |= SSR1_PIN;
PORT(SSR1_PORT, CR1) |= SSR1_PIN;
TIM2_CCER2 |= TIM2_CCER2_CC3E;
TIM2_CCMR3 |= (TIM2_CCMR2_OC2M1 | TIM2_CCMR2_OC2M2);
TIM2_CCMR3 &= ~TIM2_CCMR2_OC2M0;
TIM2_CCR3H = 0;
TIM2_CCR3L = 0;
TIM2_CR1 |= TIM2_CR1_CEN;
rim();
putstring("\r\nTEST1\r\n\r\n");
setOutput(25, 50);
lcd12864_init(true);
struct LCD12864_SEGMENT *lcdTitle = lcd12864_new_segment(0, 1, 1, 1, 1, '#');
struct LCD12864_SEGMENT *lcdTime = lcd12864_new_segment(1, 2, 2, 1, 1, ' ');
struct LCD12864_SEGMENT *lcdPowerTemp = lcd12864_new_segment(3, 2, 3, 1, 1, ' ');
struct LCD12864_SEGMENT *lcdStatus = lcd12864_new_segment(6, 1, 2, 1, 1, '#');
do
{
volatile uint16_t currentTicks = tim1Value;
volatile uint16_t currentSecond = (currentTicks / 4);
volatile bool isOneSecondInterval = false;
if (previousTicks != currentTicks)
{
previousTicks = currentTicks;
if (previousSecond != currentSecond)
{
previousSecond = currentSecond;
isOneSecondInterval = true;
}
if (beeps)
{
if ((currentTicks % 2) == 0)
{
beep_on();
PORT(LED0_PORT, ODR) &= ~LED0_PIN;
beepOn = true;
}
else if (beepOn)
{
beep_off();
PORT(LED0_PORT, ODR) |= LED0_PIN;
beepOn = false;
beeps--;
}
}
}
if (isOneSecondInterval)
{
uint16_t dT = currentSecond;
volatile uint16_t currentTemperatureRaw = max6675_read();
volatile uint16_t currentTemperature = currentTemperatureRaw / 4;
volatile uint16_t currentTemperaturePoint = (currentTemperatureRaw - (currentTemperature * 4)) * 100;
uint16_t lm = (dT / 60);
uint16_t tm = (lm % 60);
uint8_t th = (lm / 60);
uint8_t ts = (dT % 60);
format_sprintf(lcdTime->buffer, "? %02u:%02u:%02u", th, tm, ts);
format_sprintf(lcdPowerTemp->buffer, "--:-- %3u C", currentTemperature);
uint8_t *ptr = lcdTime->buffer;
putstring(ptr);
putstring(" ");
ptr = lcdPowerTemp->buffer;
putstring(ptr);
putstring("\r\n");
lcd12864_display_segment(lcdTitle);
lcd12864_display_segment(lcdTime);
lcd12864_display_segment(lcdPowerTemp);
lcd12864_display_segment(lcdStatus);
}
wfi();
} while (1);
}