Get the M:Robe 500 main build booting again, fix a bug and commit the rest of Cat's work to get sound working. The code is messy right now, but it plays a file (test.raw) in a normal build when you go into the debug ports screen. Take 2.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20116 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Karl Kurbjun 2009-02-26 21:23:10 +00:00
parent 38436038a9
commit 1e3f529921
9 changed files with 482 additions and 46 deletions

View file

@ -40,7 +40,7 @@ void pcm_play_dma_init(void)
audiohw_set_frequency(HW_FREQ_DEFAULT);
/* init DSP */
dsp_init();
// dsp_init();
}
void pcm_postinit(void)
@ -48,7 +48,7 @@ void pcm_postinit(void)
audiohw_postinit();
/* wake DSP */
dsp_wake();
// dsp_wake();
}
const void * pcm_play_dma_get_peak_buffer(int *count)

View file

@ -143,7 +143,7 @@ start:
bhi 1b
/* Set up stack for IRQ mode */
msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
msr cpsr_c, #0xd2 /* IRQ disabled, FIQ enabled */
ldr sp, =irq_stack
/* Set up stack for FIQ mode */
msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */

View file

@ -31,8 +31,17 @@
#include "debug-target.h"
#include "lcd-target.h"
#ifndef CREATIVE_ZVx
#include "tsc2100.h"
#endif
bool __dbg_ports(void)
{
dsp_init();
#ifndef CREATIVE_ZVx
tsc2100_writereg(TSDACGAIN_PAGE, TSDACGAIN_ADDRESS, 0x2020/*x0303*/);
#endif
dsp_wake();
return false;
}

View file

@ -23,7 +23,9 @@
#include "system.h"
#include "debug.h"
#include "string.h"
#include "file.h"
#include "dsp-target.h"
#include "dsp/ipc.h"
/* A "DSP image" is an array of these, terminated by raw_data_size_half = 0. */
struct dsp_section {
@ -33,7 +35,9 @@ struct dsp_section {
};
/* Must define struct dsp_section before including the image. */
#include "dsp_image_helloworld.h"
#include "dsp/dsp-image.h"
#define dsp_message (*(volatile struct ipc_message *)&DSP_(_status))
#ifdef DEBUG
static void dsp_status(void)
@ -127,27 +131,180 @@ static void dsp_load(const struct dsp_section *im)
}
}
static signed short *the_rover = (signed short *)0x1900000;
static unsigned int index_rover = 0;
static signed short __attribute__((aligned (16))) pcm_buffer[PCM_SIZE / 2];
void dsp_init(void)
{
unsigned long sdem_addr;
int fd;
int bytes;
IO_INTC_IRQ0 = 1 << 11;
IO_INTC_EINT0 |= 1 << 11;
IO_DSPC_HPIB_CONTROL = 1 << 10 | 1 << 9 | 1 << 8 | 1 << 7 | 1 << 3 | 1 << 0;
dsp_reset();
dsp_load(dsp_image_helloworld);
dsp_load(dsp_image);
/* Initialize codec. */
sdem_addr = (unsigned long)pcm_buffer - CONFIG_SDRAM_START;
DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
(unsigned long)pcm_buffer, (unsigned long)sdem_addr);
DSP_(_sdem_addrl) = sdem_addr & 0xffff;
DSP_(_sdem_addrh) = sdem_addr >> 16;
fd = open("/test.raw", O_RDONLY);
bytes = read(fd, the_rover, 4*1024*1024);
close(fd);
DEBUGF("read %d rover bytes", bytes);
#if 0
{
unsigned int i;
memset(pcm_buffer, 0x80, PCM_SIZE);
for (i = 0; i < 8192; i++) {
signed short val = 0;
/*if (i < PCM_SIZE/4/2) {
val = 128*(i%256);
} else {
val = 2*128*128-128*(i%256);
}*/
val = 128*(i%256);
pcm_buffer[2*i] = pcm_buffer[2*i+1] = val;
}
clean_dcache();
{
unsigned int i;
volatile signed short *pdata = &DSP_(_data);
DEBUGF("dsp__data at %08x", pdata);
for (i = 0; i < 4096; i++) {
pdata[2*i]=pdata[2*i+1]=(i&1)*32767;
}
for (i = 4096; i < 8192; i++) {
pdata[2*i]=pdata[2*i+1]=0;
}
}
#endif
#ifdef IPC_SIZES
DEBUGF("dsp_message at 0x%08x", &dsp_message);
DEBUGF("sizeof(ipc_message)=%uB offset(ipc_message.payload)=%uB",
sizeof(struct ipc_message), (int)&((struct ipc_message*)0)->payload);
#endif
#ifdef INIT_MSG
/* Prepare init message. */
/* DSP accesses MUST be done a word at a time. */
dsp_message.msg = MSG_INIT;
sdem_addr = (unsigned long)pcm_sdram - CONFIG_SDRAM_START;
DEBUGF("pcm_sdram at 0x%08x, sdem_addr 0x%08x", pcm_sdram, sdem_addr);
dsp_message.payload.init.sdem_addrl = sdem_addr & 0xffff;
dsp_message.payload.init.sdem_addrh = sdem_addr >> 16;
DEBUGF("dsp_message: %04x %04x %04x %04x",
((unsigned short *)&dsp_message)[0],
((unsigned short *)&dsp_message)[1],
((unsigned short *)&dsp_message)[2],
((unsigned short *)&dsp_message)[3]);
#endif
}
void DSPHINT(void)
{
unsigned int i;
char buffer[80];
static unsigned short level = 2;
unsigned short *pcm_topbottom, *pcm_topbottom_end;
IO_INTC_IRQ0 = 1 << 11;
/* DSP stores one character per word. */
for (i = 0; i < sizeof(buffer); i++) {
buffer[i] = (&DSP_(_status))[i];
switch (dsp_message.msg)
{
case MSG_DEBUGF:
/* DSP stores one character per word. */
for (i = 0; i < sizeof(buffer); i++)
{
buffer[i] = dsp_message.payload.debugf.buffer[i];
}
/* Release shared area to DSP. */
dsp_wake();
DEBUGF("DSP: %s", buffer);
break;
case MSG_REFILL:
DEBUGF("DSP: DMA0 with topbottom=%u (fill at %04lx)",
dsp_message.payload.refill.topbottom,
(unsigned long)pcm_buffer +
dsp_message.payload.refill.topbottom);
pcm_topbottom = pcm_buffer + dsp_message.payload.refill.topbottom / 2;
/*
i = 0;
while (i < PCM_SIZE/4) {
unsigned int j;
for (j = 0; j < level; j++) {
pcm_topbottom[i+j] = -32768;
}
for (j = level; j < 2*level; j++) {
pcm_topbottom[i+j] = 32767;
}
i += 2*level;
}
level += 2;
if (level > 256) {
level = 2;
}*/
memcpy(pcm_topbottom, the_rover + index_rover, PCM_SIZE/2);
index_rover += PCM_SIZE/4;
if (index_rover >= 2*1024*1024) {
index_rover = 0;
}
/*
pcm_topbottom = &p_pcm_sdram[dsp_message.payload.refill.topbottom/2];
DEBUGF("DSP: tofill begins: %04x %04x %04x %04x",
pcm_topbottom[0],
pcm_topbottom[1],
pcm_topbottom[2],
pcm_topbottom[3]
);
pcm_topbottom_end = &p_pcm_sdram[(dsp_message.payload.refill.topbottom+PCM_SIZE/2)/2];
DEBUGF("DSP: tofill ends: %04x %04x %04x %04x",
pcm_topbottom_end[-4],
pcm_topbottom_end[-3],
pcm_topbottom_end[-2],
pcm_topbottom_end[-1]
);
*/
/*
DEBUGF("DSP: DMA0: SD %04x:%04x -> DSP %04x:%04x, TRG %04x",
dsp_message.payload.refill._SDEM_ADDRH,
dsp_message.payload.refill._SDEM_ADDRL,
dsp_message.payload.refill._DSP_ADDRH,
dsp_message.payload.refill._DSP_ADDRL,
dsp_message.payload.refill._DMA_TRG);
*/
break;
default:
DEBUGF("DSP: unknown msg 0x%04x", dsp_message.msg);
break;
}
/* Release shared area to DSP. */

View file

@ -10,10 +10,12 @@
# http://daniel.haxx.se/blog/2007/11/18/free-to-use-compiler-from-ti/
CC = cl500
LD = lnk500
CFLAGS = $(BUILDDATE)
CFLAGS =
# There's more in linker.cmd.
LDFLAGS = -w
OBJDIR=./build
OBJS = arm.obj main.obj vectors.obj dma.obj
ifeq ($(findstring -DCREATIVE_ZV,$(TARGET)), -DCREATIVE_ZV)
@ -24,14 +26,15 @@ endif
OBJS := $(patsubst %.obj, $(OBJDIR)/%.obj, $(OBJS))
all: $(BUILDDIR)/dsp-image.h
all: dsp-image.h
clean:
$(call PRINTS,cleaning DSP firmware)rm -f $(OBJS) $(OBJDIR)/dsp-image.out $(OBJDIR)/dsp-image.xml
rmdir $(OBJDIR)
$(BUILDDIR)/dsp-image.h: $(OBJS) linker.cmd
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 > $@
$(call PRINTS,OFD500+XML2H $(@F))ofd500 -x -o /dev/stdout $(OBJDIR)/dsp-image.out | python xml2h.py $(OBJDIR)/dsp-image.xml > $@
$(OBJDIR)/%.obj: %.asm
$(SILENT)mkdir -p $(dir $@)
@ -51,5 +54,3 @@ $(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

File diff suppressed because one or more lines are too long

View file

@ -34,7 +34,7 @@
#define PACKED
#endif
#define PCM_SIZE 32768 /* bytes */
#define PCM_SIZE 0x8000 /* bytes */
struct sdram_buffer {
unsigned long addr;

View file

@ -41,9 +41,10 @@ void main(void) {
audiohw_postinit();
#if 0
for (i = 0; i < 32; i++)
{
debugf("DSP inited...");
#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);
@ -51,24 +52,7 @@ void main(void) {
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");
@ -85,16 +69,6 @@ void main(void) {
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;

View file

@ -0,0 +1,193 @@
#!/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()