Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce job flags #9

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion firmware/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 ----------------------------------------------------------
Expand Down
13 changes: 7 additions & 6 deletions firmware/doc/protocol.md
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -18,23 +18,24 @@ 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
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.

## 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.
20 changes: 14 additions & 6 deletions firmware/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -188,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);
Expand All @@ -198,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;
Expand Down Expand Up @@ -229,7 +238,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);
Expand Down Expand Up @@ -327,7 +336,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);
Expand Down Expand Up @@ -385,7 +393,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;
Expand All @@ -403,7 +411,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;
Expand Down
2 changes: 1 addition & 1 deletion firmware/miner.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions firmware/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions firmware/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
43 changes: 38 additions & 5 deletions firmware/twipwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
4 changes: 2 additions & 2 deletions firmware/twipwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down