summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
authorLeo C2014-09-08 19:54:08 +0200
committerLeo C2014-09-08 19:54:08 +0200
commit6035a17b2becc788c0daaf440deb6cc37d364029 (patch)
tree79735e7b353f4848bcfbd4ee2cb4f902dae474ec /avr
parent9e689a832629fd09ad60161ddacfe7b05bb00dc5 (diff)
downloadz180-stamp-6035a17b2becc788c0daaf440deb6cc37d364029.zip
Programmable Z180 clock, clock commandhexrel-2
Diffstat (limited to 'avr')
-rw-r--r--avr/cmd_boot.c49
-rw-r--r--avr/cmd_mem.c20
-rw-r--r--avr/command_tbl.c6
-rw-r--r--avr/z80-if.c141
4 files changed, 157 insertions, 59 deletions
diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c
index 3e2dcdb..58c4f56 100644
--- a/avr/cmd_boot.c
+++ b/avr/cmd_boot.c
@@ -44,13 +44,13 @@ command_ret_t do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
{
(void) cmdtp; (void) flag; (void) argc; (void) argv;
- if (z80_bus_state() & ZST_RUNNING) {
+ if (z80_bus_state() & ZST_RUNNING) {
printf_P(PSTR("## Can't load while CPU is running!\n"));
- return CMD_RET_FAILURE;
+ return CMD_RET_FAILURE;
}
z80_load_mem();
-
+
return CMD_RET_SUCCESS;
}
@@ -61,7 +61,7 @@ command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const
(void) cmdtp; (void) flag;
- if (!(z80_bus_state() & ZST_RUNNING)) {
+ if (!(z80_bus_state() & ZST_RUNNING)) {
printf_P(PSTR("## CPU is not running!\n"));
return CMD_RET_FAILURE;
}
@@ -82,7 +82,7 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
uint32_t addr;
(void) cmdtp; (void) flag;
-
+
if (argc < 2)
return CMD_RET_USAGE;
addr = strtoul(argv[1], NULL, 16);
@@ -91,9 +91,9 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
" (Out of logical address space (0x00000-0x0ffff))\n"),
addr);
return CMD_RET_FAILURE;
- }
+ }
- if (z80_bus_state() & ZST_RUNNING) {
+ if (z80_bus_state() & ZST_RUNNING) {
printf_P(PSTR("## CPU allready running!\n"));
return CMD_RET_FAILURE;
}
@@ -103,7 +103,7 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (addr != 0) {
uint8_t tmp[3];
uint_fast8_t i;
-
+
z80_bus_cmd(Request);
for (i = 0; i < 3; i++)
tmp[i] = z80_read(i);
@@ -118,7 +118,7 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
z80_write(i, tmp[i]);
} else
z80_bus_cmd(Run);
-
+
z80_bus_cmd(Release);
return CMD_RET_SUCCESS;
@@ -143,3 +143,34 @@ command_ret_t do_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
return CMD_RET_SUCCESS;
}
+
+command_ret_t do_clock(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ uint32_t freq;
+
+ (void) cmdtp; (void) flag;
+
+ if (argc == 2) {
+ freq = strtoul(argv[1], NULL, 10);
+ if (freq == 0) {
+ printf_P(PSTR("CPU clock cannot be 0\n"));
+ return CMD_RET_USAGE;
+ }
+
+ if (freq > F_CPU / 2) {
+ printf_P(PSTR("Max CPU clock freq. is: %luHz\n"), F_CPU/2);
+ return CMD_RET_USAGE;
+ }
+
+ if (z80_clock_set(freq) < 0) {
+ printf_P(PSTR("Setting CPU clock freq. to %luHz failed.\n"),
+ freq);
+ }
+ }
+
+ printf_P(PSTR("CPU clock: %luHz\n"), z80_clock_get());
+
+
+ return CMD_RET_SUCCESS;
+}
+
diff --git a/avr/cmd_mem.c b/avr/cmd_mem.c
index 91668bd..f1f34c0 100644
--- a/avr/cmd_mem.c
+++ b/avr/cmd_mem.c
@@ -22,9 +22,6 @@
#include "con-utils.h"
#include "z80-if.h"
-/*
- * TODO: printf() --> printf_P()
- */
#ifndef CONFIG_SYS_MEMTEST_SCRATCH
#define CONFIG_SYS_MEMTEST_SCRATCH 0
@@ -55,10 +52,10 @@ int z180_dump_mem(uint32_t startaddr, uint32_t len, const char *title)
uint32_t addr = startaddr & ~0x0f;
len += pre;
uint8_t i;
-
+
if (title && *title)
printf_P(PSTR("%s\n"),title);
-
+
while (len) {
if (len < 16)
llen = len;
@@ -117,10 +114,10 @@ int z180_dump_mem(uint32_t startaddr, uint32_t len, const char *title)
command_ret_t do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
uint32_t addr, length;
-
+
(void) cmdtp;
-#if 0
+#if 0
printf_P(PSTR("flag: %d, argc: %d"), flag, argc);
for (int i = 0; i < argc; i++) {
printf_P(PSTR(", argv[%d]: %s"), i, argv[i] ? argv[i] : "<NULL>");
@@ -264,7 +261,7 @@ command_ret_t do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
z80_bus_cmd(Request);
while (count-- > 0) {
z80_write(addr, writeval);
- ++addr;
+ ++addr;
}
z80_bus_cmd(Release);
@@ -354,8 +351,8 @@ command_ret_t do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
byte2 = z80_read(addr2);
z80_bus_cmd(Release);
if (byte1 != byte2) {
- printf( "byte at 0x%05lx (%#02x) != "
- "byte at 0x%05lx (%#02x)\n",
+ printf_P(PSTR("byte at 0x%05lx (%#02x) != "
+ "byte at 0x%05lx (%#02x)\n"),
addr1, byte1, addr2, byte2);
rcode = CMD_RET_FAILURE;
break;
@@ -395,7 +392,7 @@ command_ret_t do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
my_puts_P(PSTR("Zero length?\n"));
return CMD_RET_FAILURE;
}
-
+
if (dest > src) {
src += count - 1;
dest += count - 1;
@@ -875,4 +872,3 @@ command_ret_t do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
return ret; /* not reached */
}
#endif /* CONFIG_CMD_MEMTEST */
-
diff --git a/avr/command_tbl.c b/avr/command_tbl.c
index 6e8a91b..c721d53 100644
--- a/avr/command_tbl.c
+++ b/avr/command_tbl.c
@@ -18,6 +18,7 @@ extern command_ret_t do_dump_mem(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_eep_cp(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_busreq_pulse(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_date(cmd_tbl_t *, int, int, char * const []);
+extern command_ret_t do_clock(cmd_tbl_t *, int, int, char * const []);
cmd_tbl_t cmd_tbl[] = {
@@ -119,6 +120,11 @@ CMD_TBL_ITEM(
"Perform RESET of the CPU",
""
),
+CMD_TBL_ITEM(
+ clock, 2, 0, do_clock,
+ "Set or get CPU frequency",
+ ""
+),
CMD_TBL_ITEM(
md, 3, 1, do_mem_md,
diff --git a/avr/z80-if.c b/avr/z80-if.c
index 726e50b..c0f128e 100644
--- a/avr/z80-if.c
+++ b/avr/z80-if.c
@@ -157,8 +157,87 @@ static zstate_t zstate;
/*--------------------------------------------------------------------------*/
+static
+void z80_setup_clock(void)
+{
+ /* ZCLK: Output and low */
+ DDR_ZCLK |= _BV(ZCLK);
+ Z80_O_ZCLK = 0;
+
+ DDRB |= _BV(6); /* Debug */
+ PORTB |= _BV(6); /* Debug */
+
+ PRR0 &= ~_BV(PRTIM1);
+
+ /* Timer1: CTC: Toggle OC1C on compare match */
+ OCR1A = 0;
+ OCR1C = 0;
+ TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
+ TCCR1B = (0b01 << WGM12) | (0b001 << CS10);
+}
-static void z80_setup_addrbus_tristate(void)
+
+int z80_clock_set(unsigned long freq)
+{
+ unsigned long ocrval = F_CPU / freq / 2;
+ uint8_t prescale = 0;
+
+ while (ocrval > (1L<<16)) {
+ prescale++;
+ if (prescale < 3)
+ ocrval = ocrval / 8;
+ else
+ ocrval = ocrval / 4;
+ }
+
+ if ((ocrval == 0) || (prescale > 4))
+ return -1;
+
+ ocrval -= 1;
+
+ PINB |= _BV(6); /* Debug */
+
+ /* Stop Timer */
+ TCCR1B = (0b01 << WGM12) | (0b000 << CS10);
+ TCNT1 = 0;
+
+ OCR1A = ocrval;
+ OCR1CL = ocrval;
+ TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
+ TCCR1B = (0b01 << WGM12) | ((prescale+1) << CS10);
+
+ if (ocrval == 0) {
+// TCCR1C |= _BV(FOC1C);
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ TCNT1 = 0xFFFF;
+ }
+ }
+
+ PINB |= _BV(6); /* Debug */
+
+ return 0;
+}
+
+uint32_t z80_clock_get(void)
+{
+ uint32_t count = (OCR1A + 1L) * 2;
+ uint8_t pre = (TCCR1B & 7) - 1;
+
+ while (pre) {
+ if (pre > 2)
+ count *= 4;
+ else
+ count *= 8;
+ pre--;
+
+ }
+
+ return F_CPU/count;
+}
+
+
+
+static void z80_addrbus_set_tristate(void)
{
/* /MREQ, /RD, /WR: Input, no pullup */
DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
@@ -175,7 +254,7 @@ static void z80_setup_addrbus_tristate(void)
}
-static void z80_setup_addrbus_active(void)
+static void z80_addrbus_set_active(void)
{
/* /MREQ, /RD, /WR: Output and high */
Z80_O_MREQ = 1;
@@ -189,14 +268,14 @@ static void z80_setup_addrbus_active(void)
}
-static void z80_setup_dbus_in(void)
+static void z80_dbus_set_in(void)
{
DDR_DB = 0;
P_DB = 0;
}
-static void z80_setup_dbus_out(void)
+static void z80_dbus_set_out(void)
{
DDR_DB = 0xff;
}
@@ -209,20 +288,6 @@ static void z80_reset_pulse(void)
Z80_O_RST = 1;
}
-static
-void z80_setup_clock(void)
-{
- /* ZCLK: Output and low */
- DDR_ZCLK |= _BV(ZCLK);
- Z80_O_ZCLK = 0;
-
- /* Timer1: CTC: Toggle OC1C on compare match */
- PRR0 &= ~_BV(PRTIM1);
- OCR1A = 0;
- OCR1C = 0;
- TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
- TCCR1B = (0b01 << WGM12) | (0b001 << CS10);
-}
void z80_setup_bus(void)
{
@@ -244,8 +309,8 @@ void z80_setup_bus(void)
DDR_IOCS1 &= ~_BV(IOCS1);
P_IOCS1 &= ~_BV(IOCS1);
- z80_setup_addrbus_tristate();
- z80_setup_dbus_in();
+ z80_addrbus_set_tristate();
+ z80_dbus_set_in();
zstate = RESET;
}
@@ -259,8 +324,8 @@ zstate_t z80_bus_state(void)
static void z80_busreq_hpulse(void)
{
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
Z80_O_BUSREQ = 1;
@@ -271,7 +336,7 @@ static void z80_busreq_hpulse(void)
if (zstate & ZST_ACQUIRED) {
while(Z80_I_BUSACK == 1)
;
- z80_setup_addrbus_active();
+ z80_addrbus_set_active();
}
}
@@ -310,8 +375,8 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
switch (cmd) {
case Reset:
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
Z80_O_RST = 0;
Z80_O_BUSREQ = 1;
zstate = RESET;
@@ -324,7 +389,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
Z80_O_RST = 1;
while(Z80_I_BUSACK == 1)
;
- z80_setup_addrbus_active();
+ z80_addrbus_set_active();
zstate = RESET_AQRD;
break;
@@ -332,7 +397,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
Z80_O_BUSREQ = 0;
while(Z80_I_BUSACK == 1)
;
- z80_setup_addrbus_active();
+ z80_addrbus_set_active();
zstate = RUNNING_AQRD;
break;
@@ -344,15 +409,15 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
case Release:
switch (zstate) {
case RESET_AQRD:
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
Z80_O_RST = 0;
Z80_O_BUSREQ = 1;
zstate = RESET;
break;
case RUNNING_AQRD:
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
Z80_O_BUSREQ = 1;
zstate = RUNNING;
break;
@@ -369,10 +434,10 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
break;
case RESET_AQRD:
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
z80_reset_pulse();
- z80_setup_addrbus_active();
+ z80_addrbus_set_active();
zstate = RUNNING_AQRD;
break;
default:
@@ -421,7 +486,7 @@ void z80_write(uint32_t addr, uint8_t data)
{
z80_setaddress(addr);
Z80_O_MREQ = 0;
- z80_setup_dbus_out();
+ z80_dbus_set_out();
P_DB = data;
P_DB = data;
Z80_O_WR = 0;
@@ -436,7 +501,7 @@ uint8_t z80_read(uint32_t addr)
z80_setaddress(addr);
Z80_O_MREQ = 0;
- z80_setup_dbus_in();
+ z80_dbus_set_in();
Z80_O_RD = 0;
Z80_O_RD = 0;
Z80_O_RD = 0;
@@ -450,7 +515,7 @@ uint8_t z80_read(uint32_t addr)
void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
{
- z80_setup_dbus_out();
+ z80_dbus_set_out();
Z80_O_MREQ = 0;
while(length--) {
z80_setaddress(addr++);
@@ -467,7 +532,7 @@ void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
{
uint8_t data;
- z80_setup_dbus_out();
+ z80_dbus_set_out();
Z80_O_MREQ = 0;
while(length--) {
z80_setaddress(dest++);