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:
parent
38436038a9
commit
1e3f529921
9 changed files with 482 additions and 46 deletions
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
102
firmware/target/arm/tms320dm320/dsp/dsp-image.h
Normal file
102
firmware/target/arm/tms320dm320/dsp/dsp-image.h
Normal file
File diff suppressed because one or more lines are too long
|
@ -34,7 +34,7 @@
|
|||
#define PACKED
|
||||
#endif
|
||||
|
||||
#define PCM_SIZE 32768 /* bytes */
|
||||
#define PCM_SIZE 0x8000 /* bytes */
|
||||
|
||||
struct sdram_buffer {
|
||||
unsigned long addr;
|
||||
|
|
|
@ -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;
|
||||
|
|
193
firmware/target/arm/tms320dm320/dsp/xml2h.py
Normal file
193
firmware/target/arm/tms320dm320/dsp/xml2h.py
Normal 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()
|
||||
|
Loading…
Reference in a new issue