view target-utils/include/timer.h @ 497:74610c4f10f7

target-utils: added 10 ms delay at the end of abb_power_off() The deosmification of the ABB access code (replacement of osmo_delay_ms() bogus delays with correctly-timed ones, which are significantly shorter) had one annoying side effect: when executing the poweroff command from any of the programs, one last '=' prompt character was being sent (and received by the x86 host) as the Calypso board powers off. With delays being shorter now, the abb_power_off() function was returning and the standalone program's main loop was printing its prompt before the Iota chip fully executed the switch-off sequence! I thought about inserting an endless tight loop at the end of the abb_power_off() function, but the implemented solution of a 10 ms delay is a little nicer IMO because if the DEVOFF operation doesn't happen for some reason in a manual hacking scenario, there won't be an artificial blocker in the form of a tight loop keeping us from further poking around.
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 25 May 2019 20:44:05 +0000
parents 0f11da299b7d
children
line wrap: on
line source

/*
 * Definitions for Calypso general-purpose timer registers
 *
 * This header is usable from both .c and .S source files.
 */

#ifndef _CALYPSO_TIMER_H
#define _CALYPSO_TIMER_H

#define	TIMER1_BASE_ADDR	0xFFFE3800
#define	TIMER2_BASE_ADDR	0xFFFE6800

#ifdef __ASSEMBLER__

/*
 * Assembly source with cpp
 *
 * The most convenient way to access registers like these from ARM
 * assembly is to load the base address of the register block in some
 * ARM register, using only one ldr rN, =xxx instruction and only one
 * literal pool entry, and then access various registers in the block
 * from the same base using the immediate offset addressing mode.
 *
 * Here we define the offsets for the usage scenario above.
 */

#define	CNTL_TIM	0x00
#define	LOAD_TIM	0x02
#define	READ_TIM	0x04

#else

/*
 * C source
 *
 * For access from C, we define the layout of each timer register block
 * as a struct, and then define a pleudo-global-var for easy "volatile"
 * access to each of the 2 timers.
 */

struct timer_regs {
	unsigned char	cntl;
	unsigned char	pad;
	unsigned short	load;
	unsigned short	read;
};

#define	TIMER1_REGS	(*(volatile struct timer_regs *) TIMER1_BASE_ADDR)
#define	TIMER2_REGS	(*(volatile struct timer_regs *) TIMER2_BASE_ADDR)

#endif

/* CNTL register bit definitions */
#define	CNTL_START		0x01
#define	CNTL_AUTO_RELOAD	0x02
#define	CNTL_CLOCK_ENABLE	0x20

#endif /* include guard */