X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fzy1000%2Fzy1000.c;h=c8bee2f506292c282f03e4cb1271ebb7712b76fe;hp=28c65b6e56658e9312e1ca3ca642b71a0dcdbc05;hb=6468c593c7ece11aa7735d8d6aa9a546b9505cc3;hpb=495ef923ef6eaced194bf17ce9080b66a7fee4ea diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index 28c65b6e56..c8bee2f506 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -62,6 +62,9 @@ #ifdef CYGPKG_HAL_NIOS2 #include #include +#define ZYLIN_KHZ 60000 +#else +#define ZYLIN_KHZ 64000 #endif #define ZYLIN_VERSION GIT_ZY1000_VERSION @@ -70,6 +73,9 @@ #define ZYLIN_OPENOCD GIT_OPENOCD_VERSION #define ZYLIN_OPENOCD_VERSION "ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE +#else +/* Assume we're connecting to a revc w/60MHz clock. */ +#define ZYLIN_KHZ 60000 #endif @@ -84,7 +90,33 @@ static int zy1000_khz(int khz, int *jtag_speed) } else { - *jtag_speed = 64000/khz; + int speed; + /* Round speed up to nearest divisor. + * + * E.g. 16000kHz + * (64000 + 15999) / 16000 = 4 + * (4 + 1) / 2 = 2 + * 2 * 2 = 4 + * + * 64000 / 4 = 16000 + * + * E.g. 15999 + * (64000 + 15998) / 15999 = 5 + * (5 + 1) / 2 = 3 + * 3 * 2 = 6 + * + * 64000 / 6 = 10666 + * + */ + speed = (ZYLIN_KHZ + (khz -1)) / khz; + speed = (speed + 1 ) / 2; + speed *= 2; + if (speed > 8190) + { + /* maximum dividend */ + speed = 8190; + } + *jtag_speed = speed; } return ERROR_OK; } @@ -97,7 +129,7 @@ static int zy1000_speed_div(int speed, int *khz) } else { - *khz = 64000/speed; + *khz = ZYLIN_KHZ / speed; } return ERROR_OK; @@ -239,13 +271,17 @@ int zy1000_speed(int speed) { if (speed > 8190 || speed < 2) { - LOG_USER("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz"); + LOG_USER("valid ZY1000 jtag_speed=[8190,2]. With divisor is %dkHz / even values between 8190-2, i.e. min %dHz, max %dMHz", + ZYLIN_KHZ, (ZYLIN_KHZ * 1000) / 8190, ZYLIN_KHZ / (2 * 1000)); return ERROR_INVALID_ARGUMENTS; } - LOG_USER("jtag_speed %d => JTAG clk=%f", speed, 64.0/(float)speed); + int khz; + speed &= ~1; + zy1000_speed_div(speed, &khz); + LOG_USER("jtag_speed %d => JTAG clk=%d kHz", speed, khz); ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x100); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x1c, speed&~1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x1c, speed); } return ERROR_OK; } @@ -285,7 +321,7 @@ COMMAND_HANDLER(handle_power_command) return ERROR_OK; } -#if !BUILD_ECOSBOARD +#if !BUILD_ZY1000_MASTER static char *tcp_server = "notspecified"; static int jim_zy1000_server(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -966,6 +1002,7 @@ static const struct command_registration zy1000_commands[] = { "With no arguments, prints status.", .usage = "('on'|'off)", }, +#if BUILD_ZY1000_MASTER #if BUILD_ECOSBOARD { .name = "zy1000_version", @@ -974,6 +1011,7 @@ static const struct command_registration zy1000_commands[] = { .help = "Print version info for zy1000.", .usage = "['openocd'|'zy1000'|'date'|'time'|'pcb'|'fpga']", }, +#endif #else { .name = "zy1000_server", @@ -1002,6 +1040,7 @@ static const struct command_registration zy1000_commands[] = { }; +#if !BUILD_ZY1000_MASTER || BUILD_ECOSBOARD static int tcp_ip = -1; /* Write large packets if we can */ @@ -1070,6 +1109,7 @@ static bool readLong(uint32_t *out_data) *out_data = data; return true; } +#endif enum ZY1000_CMD { @@ -1080,7 +1120,7 @@ enum ZY1000_CMD }; -#if !BUILD_ECOSBOARD +#if !BUILD_ZY1000_MASTER #include /* for socket(), connect(), send(), and recv() */ #include /* for sockaddr_in and inet_addr() */ @@ -1530,20 +1570,48 @@ static void watchdog_server(cyg_addrword_t data) } #endif +#endif + +#if BUILD_ZY1000_MASTER int interface_jtag_add_sleep(uint32_t us) { jtag_sleep(us); return ERROR_OK; } - #endif +#if BUILD_ZY1000_MASTER && !BUILD_ECOSBOARD +volatile void *zy1000_jtag_master; +#include +#endif int zy1000_init(void) { #if BUILD_ECOSBOARD LOG_USER("%s", ZYLIN_OPENOCD_VERSION); +#elif BUILD_ZY1000_MASTER + int fd; + if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) + { + LOG_ERROR("No access to /dev/mem"); + return ERROR_FAIL; + } +#ifndef REGISTERS_BASE +#define REGISTERS_BASE 0x9002000 +#define REGISTERS_SPAN 128 #endif + + zy1000_jtag_master = mmap(0, REGISTERS_SPAN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, REGISTERS_BASE); + + if(zy1000_jtag_master == (void *) -1) + { + close(fd); + LOG_ERROR("No access to /dev/mem"); + return ERROR_FAIL; + } +#endif + + ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x30); // Turn on LED1 & LED2