summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2008-05-16 21:16:01 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2008-05-16 21:16:01 +0000
commitac67d701738733035d051312f48a05963e1e0d80 (patch)
tree66ea7b89e1f39c00c1683e809f69dd30f01fcc07
parent7a8fc3fd9db99fa16976baf7e78059ad766a3ce5 (diff)
downloadrockbox-ac67d701738733035d051312f48a05963e1e0d80.zip
rockbox-ac67d701738733035d051312f48a05963e1e0d80.tar.gz
rockbox-ac67d701738733035d051312f48a05963e1e0d80.tar.bz2
rockbox-ac67d701738733035d051312f48a05963e1e0d80.tar.xz
Add beginning of DSP code (done by Catalin Patulea), but don't enable it
yet as there's no C54xx compiler in the toolchain yet.. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17547 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/tms320dm320/dsp/Makefile55
-rw-r--r--firmware/target/arm/tms320dm320/dsp/aic23.c58
-rw-r--r--firmware/target/arm/tms320dm320/dsp/arm.c49
-rw-r--r--firmware/target/arm/tms320dm320/dsp/arm.h32
-rw-r--r--firmware/target/arm/tms320dm320/dsp/audio.h26
-rw-r--r--firmware/target/arm/tms320dm320/dsp/dma.c87
-rw-r--r--firmware/target/arm/tms320dm320/dsp/dma.h28
-rw-r--r--firmware/target/arm/tms320dm320/dsp/ipc.h69
-rw-r--r--firmware/target/arm/tms320dm320/dsp/linker.cmd29
-rw-r--r--firmware/target/arm/tms320dm320/dsp/main.c145
-rw-r--r--firmware/target/arm/tms320dm320/dsp/registers.h93
-rw-r--r--firmware/target/arm/tms320dm320/dsp/tsc2100.c40
-rw-r--r--firmware/target/arm/tms320dm320/dsp/vectors.asm143
-rw-r--r--tools/scramble.c4
-rw-r--r--tools/xml2h.py191
15 files changed, 1046 insertions, 3 deletions
diff --git a/firmware/target/arm/tms320dm320/dsp/Makefile b/firmware/target/arm/tms320dm320/dsp/Makefile
new file mode 100644
index 0000000..8f01637
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/Makefile
@@ -0,0 +1,55 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id: Makefile 12058 2007-01-18 00:46:52Z dave $
+#
+
+# http://daniel.haxx.se/blog/2007/11/18/free-to-use-compiler-from-ti/
+CC = cl500
+LD = lnk500
+CFLAGS = $(BUILDDATE)
+# There's more in linker.cmd.
+LDFLAGS = -w
+
+OBJS = arm.obj main.obj vectors.obj dma.obj
+
+ifeq ($(findstring -DCREATIVE_ZV,$(TARGET)), -DCREATIVE_ZV)
+OBJS += aic23.obj
+else
+OBJS += tsc2100.obj
+endif
+
+OBJS := $(patsubst %.obj, $(OBJDIR)/%.obj, $(OBJS))
+
+all: $(BUILDDIR)/dsp-image.h
+
+clean:
+ $(call PRINTS,cleaning DSP firmware)rm -f $(OBJS) $(OBJDIR)/dsp-image.out $(OBJDIR)/dsp-image.xml
+
+$(BUILDDIR)/dsp-image.h: $(OBJS) linker.cmd
+ $(call PRINTS,LNK500 dsp-image.out)lnk500 $(LDFLAGS) -o $(OBJDIR)/dsp-image.out $^
+ $(call PRINTS,OFD500+XML2H $(@F))ofd500 -x -o /dev/stdout $(OBJDIR)/dsp-image.out | python $(TOOLSDIR)/xml2h.py $(OBJDIR)/dsp-image.xml > $@
+
+$(OBJDIR)/%.obj: %.asm
+ $(SILENT)mkdir -p $(dir $@)
+ $(call PRINTS,CL500 $<)$(CC) $(CFLAGS) -fr $(dir $@) $<
+
+$(OBJDIR)/%.obj: %.c
+ $(SILENT)mkdir -p $(dir $@)
+ $(call PRINTS,CL500 $<)$(CC) $(CFLAGS) -fr $(dir $@) $<
+
+$(OBJDIR)/arm.obj: arm.c arm.h registers.h ipc.h
+
+$(OBJDIR)/main.obj: main.c arm.h registers.h ipc.h dma.h audio.h
+
+$(OBJDIR)/aic23.obj: aic23.c audio.h registers.h
+
+$(OBJDIR)/tsc2100.obj: tsc2100.c audio.h registers.h
+
+$(OBJDIR)/dma.obj: dma.c dma.h registers.h ipc.h
+
+# For PRINTS.
+include $(TOOLSDIR)/make.inc
diff --git a/firmware/target/arm/tms320dm320/dsp/aic23.c b/firmware/target/arm/tms320dm320/dsp/aic23.c
new file mode 100644
index 0000000..e6eb8b4
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/aic23.c
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Maurus Cuelenaere
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "audio.h"
+#include "registers.h"
+
+/* based on http://archopen.svn.sourceforge.net/viewvc/archopen/ArchOpen/trunk/libdsp/aic23.c?revision=213&view=markup */
+void audiohw_init(void)
+{
+ /* port config */
+#if 0
+ SPCR10 = 0; /* DLB = 0 ** RJUST = 0 ** CLKSTP = 0 ** DXENA = 0 ** ABIS = 0 ** RINTM = 0 ** RSYNCER = 0 ** RFULL = 0 ** RRDY = 0 ** RRST = 0 */
+ SPCR20 = (1 << 9); /* FREE = 1 ** SOFT = 0 ** FRST = 0 ** GRST = 0 ** XINTM = 0 ** XSYNCER = 0 ** XEMPTY = 0 ** XRDY = 0 ** XRST = 0 */
+ RCR10 = (1 << 8) | (2 << 5); /* RFRLEN1 = 1 ** RWDLEN1 = 2 */
+ RCR20 = 0; /* RPHASE = 0 ** RFRLEN2 = 0 ** RWDLEN2 = 0 ** RCOMPAND = 0 ** RFIG = 0 ** RDATDLY = 0 */
+ XCR10 = (1 << 8) | (2 << 5); /* XFRLEN1 = 1 ** XWDLEN1 = 2 */
+ XCR20 = 0; /* XPHASE = 0 ** XFRLEN2 = 0 ** XWDLEN2 = 0 ** XCOMPAND = 0 ** XFIG = 0 ** XDATDLY = 0 */
+ SRGR10 = 0; /* FWID = 0 ** CLKGDV = 0 */
+ SRGR20 = 0; /* FREE = 0 ** CLKSP = 0 ** CLKSM = 0 ** FSGM = 0 ** FPER = 0 */
+ PCR0 = (1 << 1) | 1; /* IDLEEN = 0 ** XIOEN = 0 ** RIOEN = 0 ** FSXM = 0 ** FSRM = 0 ** SCLKME = 0 ** CLKSSTAT = 0 ** DXSTAT = 0 ** DRSTAT = 0 ** CLKXM = 0 ** CLKRM = 0 ** FSXP = 0 ** FSRP = 0 ** CLKXP = 1 ** CLKRP = 1 */
+#else
+ SPCR10 = 0;
+ SPCR20 = 0x0200; /* SPCR : free running mode */
+
+ RCR10 = 0x00A0;
+ RCR20 = 0x00A1; /* RCR : 32 bit receive data length */
+
+ XCR10 = 0x00A0;
+ XCR20 = 0x00A0; /* XCR : 32 bit transmit data length */
+
+ SRGR10 = 0;
+ SRGR20 = 0x3000; /* SRGR 1 & 2 */
+
+ PCR0 = 0x000E - 8; /* PCR : FSX, FSR active low, external FS/CLK source */
+#endif
+}
+
+void audiohw_postinit(void)
+{
+ /* Trigger first XEVT0 */
+ SPCR20 |= 1;
+}
diff --git a/firmware/target/arm/tms320dm320/dsp/arm.c b/firmware/target/arm/tms320dm320/dsp/arm.c
new file mode 100644
index 0000000..eedff7d
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/arm.c
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Catalin Patulea
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include "arm.h"
+#include "registers.h"
+#include "ipc.h"
+
+volatile struct ipc_message status;
+
+volatile int acked;
+interrupt void handle_int0(void) {
+ IFR = 1;
+ acked = 1;
+}
+
+void debugf(const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ status.msg = MSG_DEBUGF;
+ vsnprintf((char *)status.payload.debugf.buffer, sizeof(status), fmt, args);
+ va_end(args);
+
+ /* Wait until ARM has picked up data. */
+ acked = 0;
+ int_arm();
+ while (!acked) {
+ /* IDLE alone never seems to wake up :( */
+ asm(" IDLE 1");
+ asm(" NOP");
+ }
+ acked = 2;
+}
diff --git a/firmware/target/arm/tms320dm320/dsp/arm.h b/firmware/target/arm/tms320dm320/dsp/arm.h
new file mode 100644
index 0000000..515c75a
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/arm.h
@@ -0,0 +1,32 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Catalin Patulea
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef ARM_H
+#define ARM_H
+#include "registers.h"
+
+extern volatile struct ipc_message status;
+
+void debugf(const char *fmt, ...);
+
+inline void int_arm(void) {
+ CP_INTC = 1 << 3;
+}
+
+#endif
diff --git a/firmware/target/arm/tms320dm320/dsp/audio.h b/firmware/target/arm/tms320dm320/dsp/audio.h
new file mode 100644
index 0000000..e5bf003
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/audio.h
@@ -0,0 +1,26 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Maurus Cuelenaere
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef AUDIO_H
+#define AUDIO_H
+
+void audiohw_init(void);
+void audiohw_postinit(void);
+
+#endif
diff --git a/firmware/target/arm/tms320dm320/dsp/dma.c b/firmware/target/arm/tms320dm320/dsp/dma.c
new file mode 100644
index 0000000..fe39dc3
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/dma.c
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Catalin Patulea
+ * Copyright (C) 2008 by Maurus Cuelenaere
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "registers.h"
+#include "arm.h"
+#include "dma.h"
+
+/* This is placed at the right (aligned) address using linker.cmd. */
+#pragma DATA_SECTION (data, ".dma")
+signed short data[PCM_SIZE / 2];
+
+/* Filled in by loader. */
+unsigned short sdem_addrh;
+unsigned short sdem_addrl;
+
+interrupt void handle_dma0(void) {
+ unsigned long sdem_addr;
+ /* Byte offset to half-buffer locked by DMA0.
+ 0 for top, PCM_SIZE/2(0x4000) for bottom */
+ unsigned short dma0_locked;
+ unsigned short dma0_unlocked;
+
+ IFR = 1 << 6;
+
+ /* DMSRC0 is the beginning of the DMA0-locked SARAM half-buffer. */
+ DMSA = 0x00 /* DMSRC0 */;
+ dma0_locked = (DMSDN << 1) & (PCM_SIZE / 2);
+ dma0_unlocked = dma0_locked ^ (PCM_SIZE / 2);
+
+ /* ARM, decode into same half, in SDRAM. */
+ status.msg = MSG_REFILL;
+ status.payload.refill.topbottom = dma0_locked;
+ int_arm();
+
+ /* DMAC, copy opposite halves from SDRAM to SARAM. */
+ sdem_addr = ((unsigned long)sdem_addrh << 16 | sdem_addrl) + dma0_unlocked;
+ SDEM_ADDRL = sdem_addr & 0xffff;
+ SDEM_ADDRH = sdem_addr >> 16;
+ DSP_ADDRL = (unsigned short)data + (dma0_unlocked >> 1);
+ DSP_ADDRH = 0;
+ DMA_SIZE = PCM_SIZE / 2;
+ DMA_CTRL = 0;
+
+ status.payload.refill._DMA_TRG = DMA_TRG;
+ status.payload.refill._SDEM_ADDRH = SDEM_ADDRH;
+ status.payload.refill._SDEM_ADDRL = SDEM_ADDRL;
+ status.payload.refill._DSP_ADDRH = DSP_ADDRH;
+ status.payload.refill._DSP_ADDRL = DSP_ADDRL;
+
+ DMA_TRG = 1;
+}
+
+interrupt void handle_dmac(void) {
+ IFR = 1 << 11;
+}
+
+void dma_init(void) {
+ /* Configure DMA */
+ DMSFC0 = 2 << 12 | 1 << 11; /* Event XEVT0, 32-bit transfers, 0 frame count */
+ DMMCR0 = 1 << 14 | 1 << 13 | /* Interrupts generated, Half and full buffer */
+ 1 << 12 | 1 << 8 | 1 << 6 | 1; /* ABU mode,
+ From data space with postincrement,
+ To data space with no mod */
+ DMSRC0 = (unsigned short)&data;
+ DMDST0 = (unsigned short)&DXR20; /* First of two-word register pair */
+ DMCTR0 = sizeof(data);
+
+ /* Run, Rudolf, run! (with DMA0 interrupts) */
+ DMPREC = 2 << 6 | 1;
+}
diff --git a/firmware/target/arm/tms320dm320/dsp/dma.h b/firmware/target/arm/tms320dm320/dsp/dma.h
new file mode 100644
index 0000000..d776302
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/dma.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Maurus Cuelenaere
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef DMA_H
+#define DMA_H
+
+#include "ipc.h"
+
+extern signed short data[PCM_SIZE / 2];
+void dma_init(void);
+
+#endif
diff --git a/firmware/target/arm/tms320dm320/dsp/ipc.h b/firmware/target/arm/tms320dm320/dsp/ipc.h
new file mode 100644
index 0000000..ada4f17
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/ipc.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Catalin Patulea
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef IPC_H
+#define IPC_H
+
+/* Inter-Processor Communication */
+
+/* Meant to be included by both DSP and ARM code. */
+#ifdef __GNUC__
+/* aligned(2) is VERY IMPORTANT. It ensures gcc generates code with "STRH"
+ instead of with "STRB". STRB in the DSP memory range is broken because
+ the HPI is in 16-bit mode. */
+#define PACKED __attribute__((packed)) __attribute__((aligned (2)))
+#else
+#define PACKED
+#endif
+
+#define PCM_SIZE 32768 /* bytes */
+
+struct sdram_buffer {
+ unsigned long addr;
+ unsigned short bytes;
+} PACKED;
+
+#define SDRAM_BUFFERS 4
+
+struct ipc_message {
+ unsigned short msg;
+ union {
+#define MSG_INIT 1
+ struct msg_init {
+ unsigned short sdem_addrl;
+ unsigned short sdem_addrh;
+ } init PACKED;
+#define MSG_DEBUGF 2
+ struct {
+ short buffer[80];
+ } debugf PACKED;
+#define MSG_REFILL 3
+ struct {
+ unsigned short topbottom; /* byte offset to unlocked half-buffer */
+
+ unsigned short _DMA_TRG;
+ unsigned short _SDEM_ADDRH;
+ unsigned short _SDEM_ADDRL;
+ unsigned short _DSP_ADDRH;
+ unsigned short _DSP_ADDRL;
+ unsigned short _DMA_SIZE;
+ } refill PACKED;
+ } payload PACKED;
+} PACKED;
+#endif
diff --git a/firmware/target/arm/tms320dm320/dsp/linker.cmd b/firmware/target/arm/tms320dm320/dsp/linker.cmd
new file mode 100644
index 0000000..844fe25
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/linker.cmd
@@ -0,0 +1,29 @@
+-c
+-x
+-stack 0x1000
+-heap 0x100
+-l rts500.lib
+
+MEMORY
+{
+PAGE 0:
+ DARAM: origin = 80h, length = 7F80h
+ SARAM: origin = 8000h, length = 4000h
+}
+
+SECTIONS
+{
+ .text PAGE 0
+ .cinit PAGE 0
+ .switch PAGE 0
+
+ .bss PAGE 0
+ .const PAGE 0
+ .sysmem PAGE 0
+ .stack PAGE 0
+
+ .vectors : PAGE 0 load = 7F80h
+
+ /* DMA buffers for ABU mode must start on a 2*size boundary. */
+ .dma : PAGE 0 load = 0x8000
+}
diff --git a/firmware/target/arm/tms320dm320/dsp/main.c b/firmware/target/arm/tms320dm320/dsp/main.c
new file mode 100644
index 0000000..6ba001d
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/main.c
@@ -0,0 +1,145 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Catalin Patulea
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "registers.h"
+#include "arm.h"
+#include "ipc.h"
+#include "dma.h"
+#include "audio.h"
+#include <math.h>
+
+void main(void) {
+ register int i;
+ register signed short *p;
+
+ TCR = 1 << 4; /* Stop the timer. */
+ IMR = 0xffff; /* Unmask all interrupts. */
+ IFR = IFR; /* Clear all pending interrupts. */
+ asm(" rsbx INTM"); /* Globally enable interrupts. */
+
+ audiohw_init();
+
+ dma_init();
+
+ audiohw_postinit();
+
+#if 0
+ for (i = 0; i < 32; i++)
+ {
+ double ratio = ((double)i)/32.0;
+ double rad = 3.0*3.141592*ratio;
+ double normal = sin(rad);
+ double scaled = 32767.0*(normal);
+ data[2*i + 0] = -(signed short)scaled;
+ data[2*i + 1] = (signed short)scaled;
+ }
+
+ debugf("starting write");
+
+ i = 0;
+ p = data;
+ SPSA0 = 0x01;
+ for (;;) {
+ while ((SPSD0 & (1 << 1)) == 0);
+ DXR20 = *p++; // left channel
+ DXR10 = *p++; // right channel
+ if (++i == 32)
+ {
+ p = data;
+ i = 0;
+ }
+ }
+#endif
+ debugf("DSP inited...");
+
+ for (;;) {
+ asm(" IDLE 1");
+ asm(" NOP");
+ }
+}
+
+/* Obsoleted/testing snippets: */
+#ifdef REMAP_VECTORS
+ /* Remap vectors to 0x3F80 (set in linker.cmd). */
+ PMST = (PMST & 0x7f) | 0x3F80;
+
+ /* Make sure working interrupts aren't a fluke. */
+ memset((unsigned short *)0x7f80, 0, 0x80);
+#endif
+
+#ifdef DATA_32_SINE
+ for (i = 0; i < 32; i++) {
+ double ratio = ((double)i)/32.0;
+ double rad = 3.0*3.141592*ratio;
+ double normal = sin(rad);
+ double scaled = 32767.0*(normal);
+ data[2*i + 0] = -(signed short)scaled;
+ data[2*i + 1] = (signed short)scaled;
+ }
+#endif
+
+#ifdef MANUAL_TRANSFER
+ register signed short *p;
+
+ debugf("starting write");
+
+ i = 0;
+ p = data;
+ SPSA0 = 0x01;
+ for (;;) {
+ while ((SPSD0 & (1 << 1)) == 0);
+ DXR20 = *p++; // left channel
+ DXR10 = *p++; // right channel
+ if (++i == 32) {
+ p = data;
+ i = 0;
+ }
+ }
+#endif
+
+#ifdef INIT_MSG
+ /* Copy codec init data (before debugf, which clobbers status). */
+ if (status.msg != MSG_INIT) {
+ debugf("No init message (%04x: %04x %04x %04x %04x instead)",
+ (unsigned short)&status,
+ ((unsigned short *)&status)[0],
+ ((unsigned short *)&status)[1],
+ ((unsigned short *)&status)[2],
+ ((unsigned short *)&status)[3]);
+ return;
+ }
+
+ memcpy(&init, (void *)&status.payload.init, sizeof(init));
+#endif
+
+#ifdef IPC_SIZES
+ debugf("sizeof(ipc_message)=%uw offset(ipc_message.payload)=%uw",
+ sizeof(struct ipc_message), (int)&((struct ipc_message*)0)->payload);
+#endif
+
+#ifdef VERBOSE_INIT
+ debugf("codec started with PCM at SDRAM offset %04x:%04x",
+ sdem_addrh, sdem_addrl);
+#endif
+
+#ifdef SPIKE_DATA
+ for (i = 0; i < 0x2000; i++) {
+ data[2*i ] = data[2*i+1] = ((i % 32) == 0) * 32767;
+ }
+#endif
diff --git a/firmware/target/arm/tms320dm320/dsp/registers.h b/firmware/target/arm/tms320dm320/dsp/registers.h
new file mode 100644
index 0000000..57e32be
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/registers.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Catalin Patulea
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef REGISTERS_H
+#define REGISTERS_H
+
+#define C5409_REG(addr) (*(volatile unsigned short *)(addr))
+
+/* This is NOT good for reading, only for writing. */
+#define BANKED_REG(spsa, spsd, subaddr) spsa = (subaddr), spsd
+
+#define IMR C5409_REG(0x00)
+#define IFR C5409_REG(0x01)
+
+#define PMST C5409_REG(0x1D)
+
+#define TCR C5409_REG(0x26)
+
+/* McBSP 0 (SPRU302 Chapter 2) */
+#define DXR20 C5409_REG(0x22)
+#define DXR10 C5409_REG(0x23)
+#define SPSA0 C5409_REG(0x38)
+#define SPSD0 C5409_REG(0x39)
+#define SPCR10 BANKED_REG(SPSA0, SPSD0, 0x00)
+#define SPCR20 BANKED_REG(SPSA0, SPSD0, 0x01)
+#define RCR10 BANKED_REG(SPSA0, SPSD0, 0x02)
+#define RCR20 BANKED_REG(SPSA0, SPSD0, 0x03)
+#define XCR10 BANKED_REG(SPSA0, SPSD0, 0x04)
+#define XCR20 BANKED_REG(SPSA0, SPSD0, 0x05)
+#define SRGR10 BANKED_REG(SPSA0, SPSD0, 0x06)
+#define SRGR20 BANKED_REG(SPSA0, SPSD0, 0x07)
+#define PCR0 BANKED_REG(SPSA0, SPSD0, 0x0e)
+
+/* McBSP 1 */
+#define DXR21 C5409_REG(0x42)
+#define DXR11 C5409_REG(0x43)
+#define SPSA1 C5409_REG(0x48)
+#define SPSD1 C5409_REG(0x49)
+#define SPCR11 BANKED_REG(SPSA1, SPSD1, 0x00)
+#define SPCR21 BANKED_REG(SPSA1, SPSD1, 0x01)
+#define XCR11 BANKED_REG(SPSA1, SPSD1, 0x04)
+#define XCR21 BANKED_REG(SPSA1, SPSD1, 0x05)
+#define PCR1 BANKED_REG(SPSA1, SPSD1, 0x0e)
+
+/* DMA */
+#define DMPREC C5409_REG(0x54)
+#define DMSA C5409_REG(0x55)
+#define DMSDI C5409_REG(0x56)
+#define DMSDN C5409_REG(0x57)
+#define DMSRC0 BANKED_REG(DMSA, DMSDN, 0x00)
+#define DMDST0 BANKED_REG(DMSA, DMSDN, 0x01)
+#define DMCTR0 BANKED_REG(DMSA, DMSDN, 0x02)
+#define DMSFC0 BANKED_REG(DMSA, DMSDN, 0x03)
+#define DMMCR0 BANKED_REG(DMSA, DMSDN, 0x04)
+
+
+/* DM320 */
+ioport unsigned short port280;
+#define CP_INTC port280
+ioport unsigned short port8000;
+#define SDEM_ADDRL port8000
+ioport unsigned short port8001;
+#define SDEM_ADDRH port8001
+ioport unsigned short port8002;
+#define DSP_ADDRL port8002
+ioport unsigned short port8003;
+#define DSP_ADDRH port8003
+ioport unsigned short port8004;
+#define DMA_SIZE port8004
+ioport unsigned short port8005;
+#define DMA_CTRL port8005
+ioport unsigned short port8006;
+#define DMA_TRG port8006
+ioport unsigned short port8007;
+#define DMA_REST port8007
+
+#endif
diff --git a/firmware/target/arm/tms320dm320/dsp/tsc2100.c b/firmware/target/arm/tms320dm320/dsp/tsc2100.c
new file mode 100644
index 0000000..f9c7a2d
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/tsc2100.c
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Catalin Patulea
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "audio.h"
+#include "registers.h"
+
+void audiohw_init(void)
+{
+ /* Configure McBSP */
+ SPCR10 = 0; /* Receiver reset */
+ SPCR20 = 3 << 4; /* Rate gen disabled, RINT=XSYNCERR, TX disabled for now */
+ PCR0 = 1 << 1; /* Serial port pins, external frame sync, external clock,
+ frame sync FSX is active-high,
+ TX data sampled on falling clock */
+ XCR10 = 0x00a0; /* 1 word per frame, 32 bits per word */
+ XCR20 = 0; /* Single-phase, unexpected frame pulse restarts xfer,
+ 0-bit data delay */
+}
+
+void audiohw_postinit(void)
+{
+ /* Trigger first XEVT0 */
+ SPCR20 |= 1;
+}
diff --git a/firmware/target/arm/tms320dm320/dsp/vectors.asm b/firmware/target/arm/tms320dm320/dsp/vectors.asm
new file mode 100644
index 0000000..1551d99
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/vectors.asm
@@ -0,0 +1,143 @@
+;* Copyright (c) 2007, C.P.R. Baaij
+;* All rights reserved.
+;*
+;* Redistribution and use in source and binary forms, with or without
+;* modification, are permitted provided that the following conditions are met:
+;* * Redistributions of source code must retain the above copyright
+;* notice, this list of conditions and the following disclaimer.
+;* * Redistributions in binary form must reproduce the above copyright
+;* notice, this list of conditions and the following disclaimer in the
+;* documentation and/or other materials provided with the distribution.
+;*
+;* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+;* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+;* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+;* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+;* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+;* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+;* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+;* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;*-----------------------------------------------------------------------------*
+;* Interrupt Vectors *
+;*-----------------------------------------------------------------------------*
+ .mmregs
+
+ ; External Functions
+ .global _handle_int0
+ .global _c_int00
+ .global _handle_dma0
+ .global _handle_dmac
+
+ .sect ".vectors"
+; Reset Interrupt
+RS_V: BD _c_int00
+ NOP
+ NOP
+
+; Non-Maskable Interrupt
+NMI_V: RETE
+ NOP
+ NOP
+ NOP
+
+; Software Interrupts
+SINt17_V: .space 4*16
+SINt18_V: .space 4*16
+SINt19_V: .space 4*16
+SINt20_V: .space 4*16
+SINt21_V: .space 4*16
+SINt22_V: .space 4*16
+SINt23_V: .space 4*16
+SINt24_V: .space 4*16
+SINt25_V: .space 4*16
+SINt26_V: .space 4*16
+SINt27_V: .space 4*16
+SINt28_V: .space 4*16
+SINt29_V: .space 4*16
+SINt30_V: .space 4*16
+; INT0 - ARM Interrupting DSP via HPIB
+INT0_V: BD _handle_int0
+ NOP
+ NOP
+; INT1 - Interrupt is generated based on the settings of DSP_SYNC_STATE and
+; DSP_SYNC_MASK register of the coprocessor subsystem or when DSPINT1 bit in
+; CP_INTC is set.
+INT1_V: RETE
+ NOP
+ NOP
+ NOP
+; INT2 - Interrupt is generated when DSPINT2 bit in CP_INTC register of the
+; coprocessor subsystem is set.
+INT2_V: RETE
+ NOP
+ NOP
+ NOP
+; Timer Interrupt
+TINT_V: RETE
+ NOP
+ NOP
+ NOP
+; McBSP0 receive interrupt
+BRINT0_V: RETE
+ NOP
+ NOP
+ NOP
+; McBSP0 transmit interrupt
+BXINT0_V: RETE
+ NOP
+ NOP
+ NOP
+; DMA Channel-0 interrupt
+DMAC0_V: BD _handle_dma0
+ NOP
+ NOP
+; DMA Channel-1 interrupt
+DMAC1_V: RETE
+ NOP
+ NOP
+ NOP
+; INT3 - Interrupt is generated when DSPINT3 bit in CP_INTC register of the
+; coprocessor subsystem is set or on write of any value to BRKPT_TRG
+INT3_V: RETE
+ NOP
+ NOP
+ NOP
+; HPIB HINT to DSP
+HINT_V: RETE
+ NOP
+ NOP
+ NOP
+; BRINT1/DMAC2 McBSP1 receive interrupt
+BRINT1_V: RETE
+ NOP
+ NOP
+ NOP
+; BXINT1/DMAC3 McBSP1 transmit interrupt
+BXINT1_V: RETE
+ NOP
+ NOP
+ NOP
+; DMA Channel-4 interrupt
+DMAC4_V: RETE
+ NOP
+ NOP
+ NOP
+; DMA Channel-5 interrupt
+DMAC5_V: RETE
+ NOP
+ NOP
+ NOP
+; HPIB DMAC interrupt
+HPIB_DMA_V: BD _handle_dmac
+ NOP
+ NOP
+
+; EHIF interrupt to DSP
+EHIV_V: RETE
+ NOP
+ NOP
+ NOP
+ .end
diff --git a/tools/scramble.c b/tools/scramble.c
index 2dcfd0c..3730f1b 100644
--- a/tools/scramble.c
+++ b/tools/scramble.c
@@ -119,7 +119,7 @@ void usage(void)
"\t-add=X Rockbox generic \"add-up\" checksum format\n"
"\t (X values: h100, h120, h140, h300, ipco, nano, ipvd, mn2g\n"
"\t ip3g, ip4g, mini, iax5, iam5, iam3, h10, h10_5gb,\n"
- "\t tpj2, c200, e200, giga, gigs, m100, m500, d2, zvm)\n");
+ "\t tpj2, c200, e200, giga, gigs, m100, m500, d2)\n");
printf("\nNo option results in Archos standard player/recorder format.\n");
exit(1);
@@ -271,8 +271,6 @@ int main (int argc, char** argv)
modelnum = 24;
else if(!strcmp(&argv[1][5], "iam3"))
modelnum = 25;
- else if(!strcmp(&argv[1][5], "zvm"))
- modelnum = 26;
else {
fprintf(stderr, "unsupported model: %s\n", &argv[1][5]);
return 2;
diff --git a/tools/xml2h.py b/tools/xml2h.py
new file mode 100644
index 0000000..d259c5b
--- /dev/null
+++ b/tools/xml2h.py
@@ -0,0 +1,191 @@
+#!/usr/bin/python
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+# Copyright (C) 2007 Catalin Patulea <cat@vv.carleton.ca>
+#
+# All files in this archive are subject to the GNU General Public License.
+# See the file COPYING in the source tree root for full license agreement.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+import sys, os.path, array, re
+from xml.dom import Node
+from xml.dom.minidom import parse
+
+
+C_IDENT_RE = re.compile('^[0-9a-zA-Z_]+$')
+
+
+def getText(nodelist):
+ rc = ""
+ for node in nodelist:
+ if node.nodeType == node.TEXT_NODE:
+ rc = rc + node.data
+ return rc
+
+
+def descendAll(root, tagname):
+ for child in root.childNodes:
+ if child.nodeType == Node.ELEMENT_NODE and child.tagName == tagname:
+ yield child
+
+
+def descend(root, tagname):
+ return descendAll(root, tagname).next()
+
+
+def getTagText(root, tagname):
+ try:
+ tag = descend(root, tagname)
+ except StopIteration:
+ return None
+ return getText(tag.childNodes)
+
+
+def main():
+ dom = parse(sys.stdin)
+
+ ofd = descend(dom, "ofd")
+ object_file = descend(ofd, "object_file")
+ object_file_name = descend(object_file, "name")
+
+ out_filepath = getText(object_file_name.childNodes)
+ sys.stderr.write("*.out filename (input): %s\n" % out_filepath)
+
+ out_file = open(out_filepath, "rb")
+ h_file = sys.stdout
+
+ h_file.write("""#ifndef DSP_IMAGE
+#define DSP_IMAGE
+/*
+ * Automatically generated by xml2h.py from %s.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+""" % out_filepath)
+
+ # Section data and directory.
+ h_directory = ["""
+static const struct dsp_section dsp_image[] = {"""]
+
+ ti_coff = descend(object_file, "ti_coff")
+ for section in descendAll(ti_coff, "section"):
+ page = int(getTagText(section, "page") or "0", 16)
+ name = getTagText(section, "name")
+ physical_addr = int(getTagText(section, "physical_addr"), 16)
+ raw_data_size = int(getTagText(section, "raw_data_size"), 16)
+ copy = getTagText(section, "copy")
+ data = getTagText(section, "data")
+ regular = getTagText(section, "regular")
+ text = getTagText(section, "text")
+ bss = getTagText(section, "bss")
+
+ file_offsets = descend(section, "file_offsets")
+ raw_data_ptr = int(getTagText(file_offsets, "raw_data_ptr"), 16)
+
+ if copy:
+ # Empirically, .debug* sections have this attribute set.
+ sys.stderr.write(
+ "%s: didn't copy debug section ('copy' attribute set)\n" %
+ name)
+ continue
+
+ if raw_data_size == 0:
+ sys.stderr.write("%s: not copying empty section\n" % name)
+ continue
+
+ if raw_data_size % 2 != 0:
+ sys.stderr.write("%s: error, raw_data_size 0x%04x not a multiple "
+ "of word size (2 bytes)\n" % (name, raw_data_size))
+ break
+
+ if data or regular or text:
+ sys.stderr.write("%s: placing 0x%04x words at 0x%04x from offset "
+ "0x%08x\n" % (
+ name, raw_data_size >> 1, physical_addr, raw_data_ptr))
+
+ sanitized_name = name.replace(".", "_")
+ h_file.write(("static const unsigned short _section%s[] = {\n" %
+ sanitized_name))
+
+ out_file.seek(raw_data_ptr)
+ data = array.array('H')
+ data.fromfile(out_file, raw_data_size >> 1)
+ h_file.write("\t")
+ for word in data:
+ h_file.write("0x%04x, " % word)
+ h_file.write("""
+};
+""")
+
+ h_directory.append("\t{_section%s, 0x%04x, 0x%04x}," % (
+ sanitized_name, physical_addr, raw_data_size >> 1))
+
+ continue
+
+ if bss:
+ sys.stderr.write("%s: bss section, 0x%04x words at 0x%04x\n" % (
+ name, raw_data_size >> 1, physical_addr))
+
+ h_directory.append("\t{NULL /* %s */, 0x%04x, 0x%04x}," % (
+ name, physical_addr, raw_data_size >> 1))
+ continue
+
+ sys.stderr.write("%s: error, unprocessed section\n" % name)
+
+ h_file.write("\n")
+
+ h_directory.append("\t{NULL, 0, 0}")
+ h_directory.append("};")
+
+ h_file.write("\n".join(h_directory))
+ h_file.write("\n")
+
+ # Symbols.
+ symbol_table = descend(ti_coff, "symbol_table")
+ h_file.write("""
+/* Symbol table, usable with the DSP_() macro (see dsp-target.h). */
+""")
+ for symbol in descendAll(symbol_table, "symbol"):
+ name = getTagText(symbol, "name")
+ kind = getTagText(symbol, "kind")
+ value = int(getTagText(symbol, "value"), 16)
+
+ if kind != "defined":
+ continue
+
+ if not C_IDENT_RE.match(name):
+ continue
+
+ h_file.write("#define %s 0x%04x\n" % (name, value))
+
+ h_file.write("\n#endif\n")
+ h_file.close()
+ out_file.close()
+
+ dom.unlink()
+
+
+if __name__ == "__main__":
+ main()