From 17d1bea1f20f77a25093bef7c8fad3c2593583a9 Mon Sep 17 00:00:00 2001 From: forkye Date: Wed, 10 Sep 2014 01:23:41 +0800 Subject: [PATCH 1/5] Fix reading temperature problem --- firmware/main.c | 12 ++++++------ firmware/miner.c | 2 +- firmware/twipwm.c | 43 ++++++++++++++++++++++++++++++++++++++----- firmware/twipwm.h | 4 ++-- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/firmware/main.c b/firmware/main.c index fbbacbc..a5be700 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -39,7 +39,8 @@ static int g_local_work = 0; static int g_hw_work = 0; uint32_t g_clock_conf_count = 0; - +uint16_t temperature0[10] = {0}; +uint16_t temperature1[10] = {0}; static uint32_t g_nonce2_offset = 0; static uint32_t g_nonce2_range = 0xffffffff; @@ -85,7 +86,7 @@ static void encode_pkg(uint8_t *p, int type, uint8_t *buf, unsigned int len) memcpy(data, buf, len); break; case AVA2_P_STATUS: - tmp = read_temp0() << 16 | read_temp1(); + tmp = read_temp0(temperature0) << 16 | read_temp1(temperature1); memcpy(data + 0, &tmp, 4); tmp = read_fan0() << 16 | read_fan1(); @@ -229,7 +230,7 @@ static int decode_pkg(uint8_t *p, struct mm_work *mw) case AVA2_P_REQUIRE: break; case AVA2_P_SET: - if (read_temp0() >= IDLE_TEMP || read_temp1() >= IDLE_TEMP) + if (read_temp0(temperature0) >= IDLE_TEMP || read_temp1(temperature1) >= IDLE_TEMP) break; memcpy(&tmp, data, 4); @@ -327,7 +328,6 @@ static int get_pkg(struct mm_work *mw) start = 0; count = 2; - if (decode_pkg(g_pkg, mw)) { #ifdef CFG_ENABLE_ACK send_pkg(AVA2_P_NAK, NULL, 0); @@ -385,7 +385,7 @@ int main(int argv, char **argc) uart_init(); debug32("%d:MM-%s\n", g_module_id, MM_VERSION); - debug32("T:%d, %d\n", read_temp0(), read_temp1()); + debug32("T:%d, %d\n", read_temp0(temperature0), read_temp1(temperature1)); timer_set(0, IDLE_TIME); g_new_stratum = 0; @@ -403,7 +403,7 @@ int main(int argv, char **argc) wdg_feed((CPU_FREQUENCY / 1000) * 2); if ((!timer_read(0) && g_new_stratum) || - (read_temp0() >= IDLE_TEMP && read_temp1() >= IDLE_TEMP)) { + (read_temp0(temperature0) >= IDLE_TEMP && read_temp1(temperature1) >= IDLE_TEMP)) { g_new_stratum = 0; g_local_work = 0; g_hw_work = 0; diff --git a/firmware/miner.c b/firmware/miner.c index cd2fe44..222f29b 100644 --- a/firmware/miner.c +++ b/firmware/miner.c @@ -248,7 +248,7 @@ void miner_gen_nonce2_work(struct mm_work *mw, uint32_t nonce2, struct work *wor tmp32 = bswap_32(nonce2); work->nonce2 = nonce2; - if(mw->coinbase_len > AVA2_P_COINBASE_SIZE) { + if (mw->coinbase_len > AVA2_P_COINBASE_SIZE) { nonce2_offset_posthash = (mw->nonce2_offset % SHA256_BLOCK_SIZE) + 32; coinbase_len_posthash = mw->coinbase_len - mw->nonce2_offset + (mw->nonce2_offset % SHA256_BLOCK_SIZE); memcpy(mw->coinbase + nonce2_offset_posthash, (uint8_t *)(&tmp32), mw->nonce2_size); diff --git a/firmware/twipwm.c b/firmware/twipwm.c index 5cb41cd..8978c5b 100644 --- a/firmware/twipwm.c +++ b/firmware/twipwm.c @@ -12,7 +12,6 @@ #include "defines.h" #include "io.h" - static struct lm32_twipwm *tp = (struct lm32_twipwm *)TWIPWM_BASE; static void twi_start(void) @@ -120,12 +119,46 @@ void adjust_fan(uint32_t pwm) write_pwm(value); } -uint16_t read_temp0() +uint16_t read_temp0(uint16_t *temperature) { - return (twi_read_2byte(LM32_TWI_REG_TEMP0) >> 4) / 16; + int i; + uint32_t sum = 0; + uint16_t min = temperature[0]; + uint16_t max = temperature[0]; + uint16_t temp[10] = {0}; + + memcpy(temp, temperature + 1, 9 * sizeof(uint16_t)); + temp[9] = (twi_read_2byte(LM32_TWI_REG_TEMP0) >> 4) / 16; + memcpy(temperature, temp, 10 * sizeof(uint16_t)); + for(i = 0; i < 10; i++) + { + if(max < temperature[i]) + max = temperature[i]; + if(min > temp[i]) + min = temperature[i]; + sum = sum + temperature[i]; + } + return (uint16_t)((sum - max - min) / 8); } -uint16_t read_temp1() +uint16_t read_temp1(uint16_t *temperature) { - return (twi_read_2byte(LM32_TWI_REG_TEMP1) >> 4) / 16; + int i; + uint32_t sum = 0; + uint16_t min = temperature[0]; + uint16_t max = temperature[0]; + uint16_t temp[10] = {0}; + + memcpy(temp, temperature + 1, 9 * sizeof(uint16_t)); + temp[9] = (twi_read_2byte(LM32_TWI_REG_TEMP0) >> 4) / 16; + memcpy(temperature, temp, 10 * sizeof(uint16_t)); + for(i = 0; i < 10; i++) + { + if(max < temperature[i]) + max = temperature[i]; + if(min > temp[i]) + min = temperature[i]; + sum = sum + temperature[i]; + } + return (uint16_t)((sum - max - min) / 8); } diff --git a/firmware/twipwm.h b/firmware/twipwm.h index 3eb27c9..f58fd95 100644 --- a/firmware/twipwm.h +++ b/firmware/twipwm.h @@ -20,8 +20,8 @@ void wdg_feed(uint32_t value); uint32_t read_fan0(); uint32_t read_fan1(); -uint16_t read_temp0(); -uint16_t read_temp1(); +uint16_t read_temp0(uint16_t *temperature); +uint16_t read_temp1(uint16_t *temperature); void adjust_fan(uint32_t pwm); void reset(); From 8f96871486e2d0268d13a21c1b2c9ac27b49b35b Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 18 Sep 2014 20:29:36 +0000 Subject: [PATCH 2/5] Introduce job flags, beginning with a "full coinbase" flag (enabled by default) to indicate the entire generation transaction is included in the AVA2_P_COINBASE data; if the software unsets this flag, the data is always interpreted as a SHA256 midstate followed by datatail A negative flag has been chosen to remain compatible with the prior AVA2_P_LONGCOINBASE protocol change Over-long generation transactions remain interpreted as midstate+datatail even if the "full coinbase" flag is set --- firmware/main.c | 8 ++++++++ firmware/miner.c | 2 +- firmware/miner.h | 2 ++ firmware/protocol.h | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/firmware/main.c b/firmware/main.c index a5be700..2c7041e 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -189,6 +189,10 @@ static int decode_pkg(uint8_t *p, struct mm_work *mw) mw->nmerkles, mw->diff, mw->pool_no); + + /* Initialise default flags for software that doesn't support JOB_FLAGS command */ + mw->flags = AVA2_P_FULLCOINBASE; + break; case AVA2_P_JOB_ID: memcpy(mw->job_id, data, 4); @@ -199,6 +203,10 @@ static int decode_pkg(uint8_t *p, struct mm_work *mw) memset(mw->coinbase, 0, sizeof(mw->coinbase)); memcpy(mw->coinbase + (idx - 1) * AVA2_P_DATA_LEN, data, AVA2_P_DATA_LEN); break; + case AVA2_P_JOB_FLAGS: + memcpy(mw->flags, data, 4); + debug32("Job flags: %08x\n", mw->flags); + break; case AVA2_P_MERKLES: memcpy(mw->merkles[idx - 1], data, AVA2_P_DATA_LEN); break; diff --git a/firmware/miner.c b/firmware/miner.c index 222f29b..49c817b 100644 --- a/firmware/miner.c +++ b/firmware/miner.c @@ -248,7 +248,7 @@ void miner_gen_nonce2_work(struct mm_work *mw, uint32_t nonce2, struct work *wor tmp32 = bswap_32(nonce2); work->nonce2 = nonce2; - if (mw->coinbase_len > AVA2_P_COINBASE_SIZE) { + if (mw->coinbase_len > AVA2_P_COINBASE_SIZE || !(mw->flags & AVA2_P_FULLCOINBASE)) { nonce2_offset_posthash = (mw->nonce2_offset % SHA256_BLOCK_SIZE) + 32; coinbase_len_posthash = mw->coinbase_len - mw->nonce2_offset + (mw->nonce2_offset % SHA256_BLOCK_SIZE); memcpy(mw->coinbase + nonce2_offset_posthash, (uint8_t *)(&tmp32), mw->nonce2_size); diff --git a/firmware/miner.h b/firmware/miner.h index 758d285..5e0003a 100644 --- a/firmware/miner.h +++ b/firmware/miner.h @@ -62,6 +62,8 @@ struct mm_work { uint32_t pool_no; uint8_t target[32]; + + uint32_t flags; }; void miner_init_work(struct mm_work *mw, struct work *work); diff --git a/firmware/protocol.h b/firmware/protocol.h index d039fe2..41849d6 100644 --- a/firmware/protocol.h +++ b/firmware/protocol.h @@ -38,5 +38,9 @@ #define AVA2_P_STATUS 24 #define AVA2_P_ACKDETECT 25 #define AVA2_P_TEST_RET 26 +#define AVA2_P_JOB_FLAGS 27 + +/* Job flags */ +#define AVA2_P_FULLCOINBASE (1<<0) #endif /* _PROTOCOL_H_ */ From 47d2b6b11d138592dc470f8b5b7d6394ba5c00e1 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 18 Sep 2014 20:30:17 +0000 Subject: [PATCH 3/5] Bump MM_VERSION --- firmware/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/Makefile b/firmware/Makefile index eb0f3e8..ff94c73 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -11,7 +11,7 @@ BIN_DIR:=$(shell date +%Y-%m-%d) GIT_VERSION:=$(shell git rev-parse HEAD | cut -c 1-7) GIT_STATUS:=$(shell ([ -z "`git status -s -uno`" ] && echo 0) || echo +) -CFLAGS += -DMM_VERSION='"331408-$(GIT_VERSION)$(GIT_STATUS)"' +CFLAGS += -DMM_VERSION='"331410-$(GIT_VERSION)$(GIT_STATUS)"' -include config.mk # ----- Customer ---------------------------------------------------------- From d7f07c7f09b2da06b5020bdd3769c0c3159a18a1 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 18 Sep 2014 21:48:48 +0000 Subject: [PATCH 4/5] firmware/doc: Spelling and generic --- firmware/doc/protocol.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/firmware/doc/protocol.md b/firmware/doc/protocol.md index 8d1a3f3..cf0887c 100644 --- a/firmware/doc/protocol.md +++ b/firmware/doc/protocol.md @@ -1,5 +1,5 @@ # Protocol -Between cgminer and FPGA controller +Between software and FPGA controller # Physical link Multiple FPGA controllers are daisy-chained together using TTL UART. @@ -18,10 +18,10 @@ Format: |2B:HEAD|1B:TYPE|1B:IDX|1B:CNT|32B:DATA|2B:CRC| # Conceptual model ## Detect MM controller -1. P_DETECT: send out this package, attach the modular id at the end of pakcage +1. P_DETECT: send out this package, attach the modular id at the end of package 2. P_ACTDETECT: MM will send back this package, include The MM version in this package -## Cgminer broadcasts the stratum information to all MM controllers +## Software broadcasts the stratum information to all MM controllers 1. P_STATIC: Send the length info first, the package like: coinbase length, nonce2 offset, nonce2 size, merkle offset, merkles count, pool diff, pool no. each variable using 32bits. the P_STATIC will make MM stop generate works. until a P_SET pkg send out. 2. P_TARGET: Send out the package, 3. P_JOB_ID: Send out the stratum package @@ -30,11 +30,11 @@ Format: |2B:HEAD|1B:TYPE|1B:IDX|1B:CNT|32B:DATA|2B:CRC| 6. P_HEADER: Send out the block header of the stratum message. 7. P_SET: Send the MM configurations: fan pwm, chip voltage, chip frequency, nonce2 start, nonce2 range, each variable using 32bits. the P_SET will trigger MM to start generate works. -## Cgminer will polling the MM controllers +## Software will polling the MM controllers The MM controller selects its own partition of extranonce in coinbase, base on own modular id and nonce2 start and nonce range. there are 2 type of packages send back 1. P_POLLING: 2. P_NONCE: miner id, pool no, nonce2, nonce, job id, attach the modular id at the end of package. -3. P_STATUS: temp, fan, frequency, voltage, local works, hardware error works, attach the modular id at the end of pakcage. +3. P_STATUS: temp, fan, frequency, voltage, local works, hardware error works, attach the modular id at the end of package. ## Module ID Each module have it's own ID. All ID was attach to the end of the data. \ No newline at end of file From 8ba8aad743b7682cdb33aeb0e69362f66d93373c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 18 Sep 2014 21:50:18 +0000 Subject: [PATCH 5/5] firmware/doc: document P_JOB_FLAGS --- firmware/doc/protocol.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/firmware/doc/protocol.md b/firmware/doc/protocol.md index cf0887c..feae9f8 100644 --- a/firmware/doc/protocol.md +++ b/firmware/doc/protocol.md @@ -28,7 +28,8 @@ Format: |2B:HEAD|1B:TYPE|1B:IDX|1B:CNT|32B:DATA|2B:CRC| 4. P_COINBASE: Send out the whole coinbase, split by 32Bytes, we using IDX/CNT here. max length: **6KB** 5. P_MERKLES: Send out the merkels one by one , we using IDX/CNT here. max count: **20** 6. P_HEADER: Send out the block header of the stratum message. -7. P_SET: Send the MM configurations: fan pwm, chip voltage, chip frequency, nonce2 start, nonce2 range, each variable using 32bits. the P_SET will trigger MM to start generate works. +7. P_JOB_FLAGS: Send out the flags for the job. This bitmask has one bit defined, P_FULLCOINBASE; set if you are not sending a midstate. +8. P_SET: Send the MM configurations: fan pwm, chip voltage, chip frequency, nonce2 start, nonce2 range, each variable using 32bits. the P_SET will trigger MM to start generate works. ## Software will polling the MM controllers The MM controller selects its own partition of extranonce in coinbase, base on own modular id and nonce2 start and nonce range. there are 2 type of packages send back