mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
SYS_TICK: Use Timer2 instead of Timer0.
Downside of Timer0 is, we have to manually reload the timer value. Timer2 can do that automaticly. This saves a lot of time in the interrupt-handler of the Timer. Currently Timer2 is used for baudrate-generation but in a separete commit this is moved to Timer1.
This commit is contained in:
+3
-3
@@ -16,12 +16,12 @@ __interrupt_vect:
|
||||
.ds 5
|
||||
ljmp _isr_ext1 ; 0x13
|
||||
.ds 5
|
||||
reti
|
||||
reti ; 0x1b TIMER 1 IRQ
|
||||
.ds 7
|
||||
ljmp _isr_serial ; 0x23
|
||||
.ds 5
|
||||
reti ; 0x2b TIMER 2 IRQ
|
||||
.ds 7
|
||||
ljmp _isr_timer2 ; 0x2b TIMER 2 IRQ
|
||||
.ds 5
|
||||
reti ; 0x33 NOT used by DW8051
|
||||
.ds 7
|
||||
reti ; 0x3b Serial port 1 RX/TX IRQ
|
||||
|
||||
+12
-5
@@ -40,11 +40,6 @@ __sfr __at(0x91) EXIF;
|
||||
__sfr __at(0xf8) EIP;
|
||||
__sbit __at(0xf9) PX3;
|
||||
|
||||
/* SFR control registers for serial communication */
|
||||
__sfr __at(0xc8) T2CON;
|
||||
__sfr __at(0xca) RCAP2L;
|
||||
__sfr __at(0xcb) RCAP2H;
|
||||
|
||||
/* SFR Bank control register: 0x0-3f. A value of 0 is bank 1 */
|
||||
__sfr __at(0x96) PSBANK;
|
||||
// SFR used to store return bank for trampoline
|
||||
@@ -101,3 +96,15 @@ __sfr __at(0xb6) SFR_NIC_RING_H;
|
||||
/* Standard 8051 sfr */
|
||||
// Timer 0 value
|
||||
__sfr16 __at(0x8c8a) T0_U16;
|
||||
|
||||
// Timer 1 enable interrupt
|
||||
__sbit __at(0xad) ET2;
|
||||
|
||||
// Timer 2
|
||||
__sfr __at(0xcc) TL2;
|
||||
__sfr __at(0xcd) TH2;
|
||||
__sfr16 __at(0xcdcc) T2_U16;
|
||||
__sfr __at(0xc8) T2CON;
|
||||
__sfr __at(0xca) RCAP2L;
|
||||
__sfr __at(0xcb) RCAP2H;
|
||||
__sfr16 __at(0xcbca) RCAP2_U16;
|
||||
|
||||
+40
-24
@@ -28,7 +28,6 @@ void crc16(__xdata uint8_t *v) __naked;
|
||||
// Upload Firmware to 1M
|
||||
#define FIRMWARE_UPLOAD_START 0x100000
|
||||
|
||||
#define SYS_TICK_HZ 200
|
||||
#define SERIAL_BAUD_RATE 115200
|
||||
|
||||
/* All RTL839x switches have an external 25MHz Oscillator,
|
||||
@@ -54,12 +53,20 @@ void crc16(__xdata uint8_t *v) __naked;
|
||||
#define CLOCK_DIV 0
|
||||
#endif
|
||||
|
||||
// Derive divider for the system ticks
|
||||
#define TIMER0_DIV (CLOCK_HZ / 12 / SYS_TICK_HZ)
|
||||
#if TIMER0_DIV > 0xFFFF
|
||||
#error "SYS_TICH_HZ to low, must be >= 158"
|
||||
/* Derive divider for the system ticks
|
||||
TIMER2 can divide the F_CPU by 4 or 12.
|
||||
So the F_TICKS are in the range of:
|
||||
- F_TIMER_DIV4_OVERFLOW = F_SYS / DIV4 / 1..65536 = 125MHz / 4 / 1..65536 = 31.25 MHz .. 476.8 Hz
|
||||
- T_TIMER_DIV12_OVERFLOW = F_SYS / DIV12 / 1..65536 = 125MHz / 12 / 1..65536 = 10.42 MHz .. 158.9 Hz
|
||||
Selecting dividor 12 settings to get lowest timer tick posiable which is already high.
|
||||
*/
|
||||
#define SYS_TICK_HZ 200
|
||||
|
||||
#define TIMER2_DIV (CLOCK_HZ / 12 / SYS_TICK_HZ)
|
||||
#if TIMER2_DIV > 0xFFFF
|
||||
#error "SYS_TICK_HZ to low, must be >= 159"
|
||||
#endif
|
||||
#define SYSTICK_TIMER0_VALUE (0x10000 - TIMER0_DIV)
|
||||
#define SYSTICK_TIMER2_VALUE (0x10000 - TIMER2_DIV)
|
||||
|
||||
__xdata uint8_t idle_ready;
|
||||
|
||||
@@ -118,15 +125,19 @@ __xdata uint8_t sfp_options[2];
|
||||
|
||||
void isr_timer0(void) __interrupt(1)
|
||||
{
|
||||
TR0 = 0; // Stop timer 0
|
||||
T0_U16 = SYSTICK_TIMER0_VALUE;
|
||||
TR0 = 1; // Re-start timer 0
|
||||
}
|
||||
|
||||
|
||||
// Timer2: Handle SYS_TICK
|
||||
void isr_timer2(void) __interrupt(5)
|
||||
{
|
||||
ticks++;
|
||||
if (sleep_ticks > 0)
|
||||
sleep_ticks--;
|
||||
sec_counter++;
|
||||
|
||||
// Clear TF2 & EXF2 by software
|
||||
T2CON &= ~0xC0;
|
||||
}
|
||||
|
||||
|
||||
@@ -287,18 +298,25 @@ void isr_ext3(void) __interrupt(9)
|
||||
write_char('W');
|
||||
}
|
||||
|
||||
|
||||
void setup_timer0(void)
|
||||
// Timer2: handles system tick.
|
||||
void setup_timer2(void)
|
||||
{
|
||||
TMOD = 0x11; // Timer 1: Mode 1, Timer 0: Mode 1, i.e. 16 bit counters, no auto-reload
|
||||
/* The TH0 registers contain the high/low byte that we load into Timer0 when T0
|
||||
* overflows to 0x10000
|
||||
*/
|
||||
T0_U16 = SYSTICK_TIMER0_VALUE;
|
||||
T2CON = 0x00; // Timer2: Mode 16-bit timer with auto-reload, disable the timer.
|
||||
|
||||
// Timer 2 clock select F_SYS / 12;
|
||||
// T2M = 0 uses clk/12;
|
||||
CKCON &= ~0x20;
|
||||
|
||||
// The RCAP2 registers contain the high/low byte that is loaded into
|
||||
// timer2 when T2 overflows to 0x10000
|
||||
RCAP2_U16 = SYSTICK_TIMER2_VALUE;
|
||||
|
||||
T2CON |= 0x04; // Timer2: Enable
|
||||
|
||||
// IP |= 0x20; // TEST: Make Timer 2 interrupt as high priority.
|
||||
ET2 = 1; // Enable Timer2 interrupt.
|
||||
|
||||
|
||||
CKCON &= 0xc7;
|
||||
TCON = 0x10; // Start timer 0
|
||||
ET0 = 1; // Enable timer interrupts
|
||||
}
|
||||
|
||||
|
||||
@@ -1704,16 +1722,14 @@ void bootloader(void)
|
||||
IE = 0;
|
||||
EIE = 0; // SFR e8: EIE. Disable all external IRQs
|
||||
|
||||
// Disable all interrupts (global interrupt enable bit)
|
||||
EA = 0; // SFR A8.7 / IE.7
|
||||
|
||||
idle_ready = 0;
|
||||
// HW setup, serial, timer, external IRQs
|
||||
setup_clock();
|
||||
setup_timer2();
|
||||
setup_serial();
|
||||
setup_timer0();
|
||||
setup_external_irqs();
|
||||
EA = 1; // Enable all IRQs
|
||||
|
||||
EA = 1; // Enable global interrupt
|
||||
|
||||
// Set default for SFP pins so we can start up a module already inserted
|
||||
sfp_pins_last = 0x33; // signal LOS and no module inserted (for both slots, even if only 1 present)
|
||||
|
||||
Reference in New Issue
Block a user