summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2014-12-28 13:01:10 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2014-12-28 13:01:10 +0100
commitd5ab518f3d5fa632660e8377d31fbafd561fe5ca (patch)
tree3cb3c6e4c2bcb20ad072cba1b47d2f6d0b1bb313
parent0153e57f0c3b696ddf88582d9545773e4e56caf6 (diff)
WM8523 test.
-rw-r--r--.gitignore3
-rw-r--r--firmware/test/wm8523/Makefile107
-rw-r--r--firmware/test/wm8523/wm8523test.c226
3 files changed, 335 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 0fd2f37..933537a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,5 @@ toolchain/tarballs
*.hex
*.elf
*.map
-*.dump \ No newline at end of file
+*.dump
+tools/clkcalc
diff --git a/firmware/test/wm8523/Makefile b/firmware/test/wm8523/Makefile
new file mode 100644
index 0000000..f6e36a5
--- /dev/null
+++ b/firmware/test/wm8523/Makefile
@@ -0,0 +1,107 @@
+#/* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+# * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+# * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+# * THE AUTHORS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+# * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. USE IT AT YOUR OWN RISK */
+
+ARCH = arm-none-eabi
+top_srcdir=${PWD}/../..
+LPC=${top_srcdir}/lpc17xx
+DRV=${top_srcdir}/drivers
+SRC=${top_srcdir}/src
+
+PROJ=wm8523test
+EXECNAME=$(PROJ).elf
+
+# Tool definitions
+CC = $(ARCH)-gcc
+LD = $(ARCH)-ld
+AR = $(ARCH)-ar
+AS = $(ARCH)-as
+CP = $(ARCH)-objcopy
+OD = $(ARCH)-objdump
+SIZE = $(ARCH)-size
+RM = rm
+#Q = # @./quiet "$@"
+
+# Flags
+CFLAGS = -W -Wall -Werror -O0 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb
+CFLAGS += -ffunction-sections -fdata-sections
+CFLAGS += -I${DRV} -I${LPC}
+ASFLAGS =
+LDFLAGS = --gc-sections
+
+STDLIB_LDFLAGS =
+
+CPFLAGS =
+ODFLAGS = -x --syms
+PRFLAGS ?=
+
+# Source files
+LINKER_SCRIPT = ${LPC}/LPC17xx.ld
+CSRCS = \
+ ${LPC}/system_LPC17xx.c \
+ ${LPC}/startup_LPC17xx.c \
+ ${DRV}/led.c \
+ ${DRV}/i2s.c \
+ ${DRV}/cli.c \
+ ${DRV}/uart.c \
+ ${DRV}/wm8523.c \
+ ${DRV}/ssp.c \
+ ${DRV}/GPIO.c \
+ ../test.c
+
+CSRCS += ${PROJ}.c
+ASRCS =
+
+
+OBJS = $(CSRCS:.c=.o) $(ASRCS:.s=.o)
+
+.PHONY: all size clean nuke
+
+all: ${PROJ}.bin ${PROJ}.hex
+
+size: ${PROJ}.elf
+ @$(SIZE) $<
+
+%.hex: %.elf
+ $Q $(CP) $(CPFLAGS) -O ihex $< $*.hex
+
+%.bin: %.elf
+ $Q $(CP) $(CPFLAGS) -O binary $< $*.bin
+
+${PROJ}.elf: $(LINKER_SCRIPT) $(OBJS)
+ $Q $(LD) -Map $(@:.elf=.map) $(LDFLAGS) -T $^ -o $@ $(STDLIB_LDFLAGS)
+ $Q $(OD) $(ODFLAGS) $@ > $(@:.elf=.dump)
+ @$(SIZE) $@
+
+%.o: %.c
+ @$(CC) -MM $< -MF $*.d -MP
+ $Q $(CC) -c $(CFLAGS) $< -o $@
+
+%.o: %.S
+ $Q $(AS) $(ASFLAGS) $< -o $@
+
+clean:
+ @-$(RM) -f *.elf
+ @-\
+for D in "." "**"; do \
+ $(RM) -f $$D/*.o $$D/*.d $$D/*.lst $$D/*.dump $$D/*.map; \
+done
+
+nuke: clean
+ -$(RM) -f *.hex *.bin
+
+.PHONY : flash
+#flash: $(EXECNAME)
+# $(CP) -O ihex $(EXECNAME) $(PROJ).hex
+# openocd -f openocd.cfg -c 'flash write_image erase $(PROJ).hex' -c 'verify_image $(PROJ).hex' -c 'reset run'
+flash: $(EXECNAME)
+ $(CP) -O binary $(EXECNAME) $(PROJ).bin
+ ../../fix-lpcchecksum $(PROJ).bin
+ openocd -f ../../openocd.cfg \
+ -c 'flash write_image erase $(PROJ).bin' \
+ -c 'verify_image $(PROJ).bin' \
+ -c 'reset run'
+
+-include $(CSRCS:.c=.d)
diff --git a/firmware/test/wm8523/wm8523test.c b/firmware/test/wm8523/wm8523test.c
new file mode 100644
index 0000000..b67fd32
--- /dev/null
+++ b/firmware/test/wm8523/wm8523test.c
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * i2stest.c
+ *
+ * Mon Sep 1 20:25:48 CEST 2014
+ * Copyright 2014 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Pedal2Metal.
+ *
+ * Pedal2Metal 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.
+ *
+ * Pedal2Metal 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 Pedal2Metal; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include <wm8523.h>
+
+#include <i2s.h>
+#include <led.h>
+//#include <LPC17xx.h>
+#include <cli.h>
+
+#include "../../src/sample.h"
+unsigned int size = sizeof(samples) / sizeof(short);
+
+#include "../test.h"
+
+#if 0
+void I2S_IRQHandler (void)
+{
+
+ static int16_t cnt = 0;
+
+ for(int i = 0; i < 6; i++) {
+ //if(1 || (cnt % 24000) == 0) led_toggle();
+ i2s_write_pcm_16_stereo(cnt, cnt);
+ cnt++;
+ }
+ /*
+ uint32_t RxCount = 0;
+
+ if ( LPC_I2S->I2SSTATE & 0x01 )
+ {
+ RxCount = (LPC_I2S->I2SSTATE >> 8) & 0xFF;
+ if ( (RxCount != RXFIFO_EMPTY) && !I2SRXDone )
+ {
+ while ( RxCount > 0 )
+ {
+ if ( I2SReadLength == BUFSIZE )
+ {
+ LPC_I2S->I2SDAI |= ((0x01 << 3) | (0x01 << 4));
+ LPC_I2S->I2SIRQ &= ~(0x01 << 0); // Disable RX
+ I2SRXDone = 1;
+ break;
+ }
+ else
+ {
+ I2SRXBuffer[I2SReadLength++] = LPC_I2S->I2SRXFIFO;
+ }
+ RxCount--;
+ }
+ }
+ }
+ return;
+ */
+}
+#endif
+
+int main (void)
+{
+ led_init();
+
+ cli_init();
+
+ /////////// WM8523
+
+ uint8_t portnum = 0;
+
+ wm8523_init(portnum, WM8523_FS_48K);
+
+ if(wm8523_get_chip_id(portnum) != WM8532_CHIP_ID) error();
+
+ wm8523_reset_registers(portnum);
+
+ wm8523_power_mode_t pwr = WM8523_PWR_POWER_UP_TO_UNMUTE;
+ wm8523_set_power_mode(portnum, pwr);
+
+ wm8523_aif_ctrl1_t ctl1;
+ ctl1.fmt = WM8523_FMT_I2S;
+ ctl1.wlen = WM8523_WLEN_16;
+ ctl1.invctl = WM8523_INVCTL_SLAVE_RISING;
+ ctl1.lrclkinvctl = WM8523_LRCLKINVCTL_SLAVE_NORMAL;
+ ctl1.modesel = WM8523_MODESEL_SLAVE;
+ ctl1.deemp = WM8523_DEEMPH_ENABLED;
+ wm8523_set_aif_ctrl1(portnum, ctl1);
+
+ wm8523_aif_ctrl2_t ctl2;
+ ctl2.clkratio = WM8523_CLKRATIO_AUTO;
+ ctl2.clkdiv = WM8523_CLKDIV_MCLK_4;
+ ctl2.mix = WM8523_MIX_STEREO;
+ wm8523_set_aif_ctrl2(portnum, ctl2);
+
+ wm8523_dac_ctrl3_t ctl3;
+ ctl3.downramp = WM8523_VOL_DOWN_INSTANT;
+ ctl3.upramp = WM8523_VOL_UP_INSTANT;
+ ctl3.lmute = WM8523_DACL_UNMUTE;
+ ctl3.rmute = WM8523_DACR_UNMUTE;
+ ctl3.dac_zc = WM8523_ZERO_CROSSING_DISABLED;
+ wm8523_set_dac_ctrl3(portnum, ctl3);
+
+
+ int res = i2s_clkcalc_init(48000, 16, 2);
+
+ /*
+ // From: tools/clkcalc 48000 16 2
+ int pclkdiv = 8;
+ int bitrate = 3;
+ int x = 57;
+ int y = 59;
+ // err = 16.949153 bits/second
+
+ int bitwidth = 16;
+ int channels = 2;
+
+ int res = i2s_init(pclkdiv, bitrate, x, y, bitwidth, channels);
+ */
+ // if(res) error();
+ (void)res;
+
+ i2s_set_tx_mode_control(CLK_TX_SRC, 0, 1);
+
+ /*
+
+ //////// I2S
+#if 1
+
+ // From: tools/clkcalc 48000 16 2
+ int pclkdiv = 8;
+ int bitrate = 1;
+ int x = 29;
+ int y = 59;
+ // err = 16.949153 bits/second
+
+ int bitwidth = 16;
+ int channels = 2;
+
+ int res = i2s_init(pclkdiv, bitrate, x, y, bitwidth, channels);
+ if(res) error();
+
+ // I2SInit();
+
+ i2s_set_tx_mode_control(CLK_TX_SRC, 0, 1);
+
+ // Set up IRQ
+ uint32_t *i2sirq = (uint32_t*)0x400A801C;
+ *i2sirq &= ~(0b1111 << 16); // Reset tx irq depth
+ int depth = 2;
+ *i2sirq |= ((depth & 0b1111) << 16); // Set tx irq depth
+ *i2sirq |= 0b1 << 1; // Enable TX IRQ, pg. 479 table 412
+
+ i2s_tx_start();
+
+#else
+ // From: tools/clkcalc 48000 16 2
+ int pclkdiv = 8;
+ int bitrate = 1;
+ int x = 29;
+ int y = 59;
+ // err = 16.949153 bits/second
+
+ int bitwidth = 16;
+ int channels = 2;
+
+ int res = i2s_init(pclkdiv, bitrate, x, y, bitwidth, channels);
+ if(res) error();
+
+ // Set up IRQ
+ uint32_t *i2sirq = (uint32_t*)0x400A801C;
+ *i2sirq |= 0b1 << 0; // Enable IRQ, pg. 479 table 412
+ *i2sirq &= ~(0b1111 << 16); // Reset tx irq depth
+ int depth = 2;
+ *i2sirq |= ((depth & 0b1111) << 16); // Set tx irq depth
+ NVIC_EnableIRQ(I2S_IRQn); // I2S_IRQn = 27;
+
+
+
+ i2s_tx_reset_fifo();
+ i2s_tx_start();
+#endif
+ */
+
+ i2s_tx_start();
+
+ // int32_t *fifo = (int32_t*)0x400A8008;
+ unsigned int cnt = 0;
+ while(1) {
+ while(i2s_get_state_tx_level() > 7) {}
+ // i2s_write_pcm_16_stereo(cnt, cnt);
+ // *fifo = cnt;
+
+ // *fifo = (cnt / 40) | (cnt / 40) << 16;
+ if(cnt < size) {
+ i2s_write_pcm_16_stereo((samples[cnt] - 485) * 10,
+ (samples[cnt] - 485) * 10);
+ } else {
+ // repeat last sample
+ i2s_write_pcm_16_stereo(0, 0);
+ }
+
+ if(cnt > size * 30) cnt = 0;
+
+ // if(cnt > 64000) cnt = 0;
+ cnt++;
+ }
+}