changeset 77:0f11da299b7d

buzplayer: beginning of timer implementation
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 27 Oct 2016 04:01:16 +0000
parents 5bbba2cab6f3
children e3d40f49d8c4
files target-utils/buzplayer/Makefile target-utils/buzplayer/main.c target-utils/buzplayer/timer.c target-utils/include/timer.h
diffstat 4 files changed, 79 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/target-utils/buzplayer/Makefile	Thu Oct 27 03:50:40 2016 +0000
+++ b/target-utils/buzplayer/Makefile	Thu Oct 27 04:01:16 2016 +0000
@@ -7,7 +7,7 @@
 INSTDIR=/opt/freecalypso/target-bin
 
 PROG=	buzplayer
-OBJS=	crt0.o cmdtab.o main.o mygetchar.o
+OBJS=	crt0.o cmdtab.o main.o mygetchar.o timer.o
 LIBS=	../libcommon/libcommon.a ../libprintf/libprintf.a ../libbase/libbase.a
 LDS=	../env/iram.lds
 
--- a/target-utils/buzplayer/main.c	Thu Oct 27 03:50:40 2016 +0000
+++ b/target-utils/buzplayer/main.c	Thu Oct 27 04:01:16 2016 +0000
@@ -6,6 +6,7 @@
 	printf("FreeCalypso buzzer player running\n");
 	print_boot_rom_info();
 	*(volatile u16 *)0xfffe4806 = 0xFFF3;	/* enable ARMIO clock */
+	timer_init();
 	for (;;) {
 		putchar('=');
 		if (command_entry())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/target-utils/buzplayer/timer.c	Thu Oct 27 04:01:16 2016 +0000
@@ -0,0 +1,19 @@
+/*
+ * FreeCalypso buzzer "melodies" have times measured in TDMA frames,
+ * as that is the time unit in the main firmware which will ultimately
+ * play them.  In this standalone buzzer player we simulate TDMA frame
+ * timing by programming Calypso TIMER1 with the period of 1875, and
+ * we detect timer overflow (one virtual TDMA frame time having passed)
+ * by polling the read register to avoid the need for interrupt handling
+ * infrastructure.
+ */
+
+#include "types.h"
+#include "timer.h"
+
+timer_init()
+{
+	TIMER1_REGS.cntl = CNTL_CLOCK_ENABLE;
+	TIMER1_REGS.load = 1875;
+	TIMER1_REGS.cntl = CNTL_CLOCK_ENABLE | CNTL_AUTO_RELOAD | CNTL_START;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/target-utils/include/timer.h	Thu Oct 27 04:01:16 2016 +0000
@@ -0,0 +1,58 @@
+/*
+ * 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 */