Skip to content
This repository has been archived by the owner on Mar 12, 2021. It is now read-only.

Commit

Permalink
A1: CoinCraft-Desk driver variant
Browse files Browse the repository at this point in the history
The CoinCraft-Desk product includes up to 5 8-chip modules
that are accessed over a TCA9539 IO multiplexer.

This is the initial support for the CCD.
  • Loading branch information
zefir-k committed Feb 19, 2014
1 parent 60534e5 commit 1448e15
Show file tree
Hide file tree
Showing 4 changed files with 790 additions and 338 deletions.
147 changes: 147 additions & 0 deletions A1-desk-board-selector-tca9535.c
@@ -0,0 +1,147 @@
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#include <stdint.h>
#include <stdbool.h>
#include <fcntl.h>

#include "miner.h"

struct tca9535_ctx {
uint8_t addr;
uint8_t board_mask;
int file;
uint8_t active_board;
pthread_mutex_t lock;
};

static struct tca9535_ctx board_ctx = {
.addr = 0x27,
.board_mask = 0xff,
.file = -1,
.active_board = 255,
};


#define UNUSED_BITS 0xe0
#define SLEEP_US_AFTER_CS 200
#define RESET_LOW_TIME_MS 200
#define RESET_HI_TIME_MS 100

static bool tca9535_write(int fdesc, uint8_t p0, uint8_t p1)
{
union i2c_smbus_data data;
data.byte = p1;

struct i2c_smbus_ioctl_data args;
__s32 err;

args.read_write = I2C_SMBUS_WRITE;
args.command = p0;
args.size = I2C_SMBUS_BYTE_DATA;
args.data = &data;

err = ioctl(fdesc, I2C_SMBUS, &args);
if (err == -1) {
applog(LOG_ERR, "Failed to write to fdesc %d: %s\n",
fdesc, strerror(errno));
err = -errno;
} else {
applog(LOG_DEBUG, "written: 0x%02x, 0x%02x", p0, p1);
cgsleep_us(SLEEP_US_AFTER_CS);
}
return err == 0;
}

void lock_board_selector(void)
{
// applog(LOG_WARNING, "lock_board_selector()");
mutex_lock(&board_ctx.lock);
}

void unlock_board_selector(void)
{
// applog(LOG_WARNING, "unlock_board_selector()");
mutex_unlock(&board_ctx.lock);
}

bool a1_board_selector_init(void)
{
mutex_init(&board_ctx.lock);
applog(LOG_WARNING, "a1_board_selector_init()");

board_ctx.file = open("/dev/i2c-1", O_RDWR);
if (board_ctx.file < 0) {
fprintf(stderr,
"Error: Could not open i2c-1.%d: %s\n",
board_ctx.addr, strerror(errno));
return false;
}

if (ioctl(board_ctx.file, I2C_SLAVE, board_ctx.addr) < 0) {
fprintf(stderr,
"Error: Could not set address to 0x%02x: %s\n",
board_ctx.addr, strerror(errno));
return false;
}
bool retval = tca9535_write(board_ctx.file, 0x06, 0xe0) &&
tca9535_write(board_ctx.file, 0x07, 0xe0) &&
tca9535_write(board_ctx.file, 0x02, 0x1f) &&
tca9535_write(board_ctx.file, 0x03, 0x00);
return retval;
}

void a1_board_selector_exit(void)
{
close(board_ctx.file);
board_ctx.file = -1;
}

bool a1_board_selector_select_board(uint8_t board)
{
if (board > 7)
return false;

// applog(LOG_WARNING, "board_selector_select_board(%d)", board);
lock_board_selector();
if (board_ctx.active_board == board)
return true;

board_ctx.active_board = board;
board_ctx.board_mask = 1 << board_ctx.active_board;
return tca9535_write(board_ctx.file, 0x02, ~board_ctx.board_mask);
}

static bool __board_selector_reset(void)
{
if (!tca9535_write(board_ctx.file, 0x03, board_ctx.board_mask))
return false;
cgsleep_ms(RESET_LOW_TIME_MS);
if (!tca9535_write(board_ctx.file, 0x03, 0x00))
return false;
cgsleep_ms(RESET_HI_TIME_MS);
return true;
}
// we assume we are already holding the mutex
bool a1_board_selector_reset_board(void)
{
bool retval = __board_selector_reset();
return retval;
}

bool a1_board_selector_reset_all_boards(void)
{
lock_board_selector();
board_ctx.board_mask = 0xff & ~UNUSED_BITS;
bool retval = __board_selector_reset();
unlock_board_selector();
return retval;
}

/////////////////////////////////////////////////////////////////////////////
158 changes: 158 additions & 0 deletions A1-desk-board-selector.c
@@ -0,0 +1,158 @@
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#include <stdint.h>
#include <stdbool.h>
#include <fcntl.h>

#include "miner.h"

struct pcf8575_ctx {
uint8_t addr;
uint8_t p0;
uint8_t p1;
int file;
uint8_t active_board;
pthread_mutex_t lock;
};

static struct pcf8575_ctx board_ctx = { 0x27, 0xff, 0xff, -1, .active_board = 255,};


#define UNUSED_BITS 0xe0
#define SLEEP_MS_AFTER_CS 0
static bool pcf8575_write(void)
{
union i2c_smbus_data data;
data.byte = board_ctx.p1 | UNUSED_BITS;

struct i2c_smbus_ioctl_data args;
__s32 err;

args.read_write = I2C_SMBUS_WRITE;
args.command = board_ctx.p0 | UNUSED_BITS;
args.size = I2C_SMBUS_BYTE_DATA;
args.data = &data;

err = ioctl(board_ctx.file, I2C_SMBUS, &args);
if (err == -1) {
fprintf(stderr,
"Error: Failed to write: %s\n",
strerror(errno));
err = -errno;
} else {
applog(LOG_DEBUG, "written: 0x%02x, 0x%02x", board_ctx.p0, board_ctx.p1);
// usleep(25000);
cgsleep_ms(SLEEP_MS_AFTER_CS);
}
return err == 0;
}

void lock_board_selector(void)
{
// applog(LOG_WARNING, "lock_board_selector()");
mutex_lock(&board_ctx.lock);
}

void unlock_board_selector(void)
{
// applog(LOG_WARNING, "unlock_board_selector()");
mutex_unlock(&board_ctx.lock);
}

bool a1_board_selector_init(void)
{
mutex_init(&board_ctx.lock);
applog(LOG_WARNING, "a1_board_selector_init()");

board_ctx.file = open("/dev/i2c-1", O_RDWR);
if (board_ctx.file < 0) {
fprintf(stderr,
"Error: Could not open i2c-1: %s\n",
board_ctx.addr, strerror(errno));
return false;
}

if (ioctl(board_ctx.file, I2C_SLAVE, board_ctx.addr) < 0) {
fprintf(stderr,
"Error: Could not set address to 0x%02x: %s\n",
board_ctx.addr, strerror(errno));
return false;
}
return pcf8575_write();
}

void a1_board_selector_exit(void)
{
close(board_ctx.file);
board_ctx.file = -1;
}

bool a1_board_selector_select_board(uint8_t board)
{
if (board > 7)
return false;

// applog(LOG_WARNING, "board_selector_select_board(%d)", board);
lock_board_selector();
if (board_ctx.active_board == board)
return true;

board_ctx.active_board = board;
board_ctx.p0 = 1 << board_ctx.active_board;
board_ctx.p1 = 0xff;
bool retval = pcf8575_write();
return retval;
}

static bool __board_selector_reset(void)
{
board_ctx.p1 = ~board_ctx.p0;
if (!pcf8575_write())
return false;
usleep(1000000);
board_ctx.p1 = 0xff;
if (!pcf8575_write())
return false;
usleep(1000000);
return true;
}
// we assume we are already holding the mutex
bool a1_board_selector_reset_board(void)
{
// lock_board_selector();
bool retval = __board_selector_reset();
// unlock_board_selector();
return retval;
}

bool a1_board_selector_reset_all_boards(void)
{
lock_board_selector();
board_ctx.p1 = 0;
bool retval = __board_selector_reset();
unlock_board_selector();
return retval;
}

#if 0
int main(void)
{
if (init_pcf8575(&board_ctx)) {
if (!pcf8575_write(&g_ctx)) {
fprintf(stderr,
"Error: Failed to write: %s\n",
strerror(errno));
}
a1_board_selector_exit(&g_ctx);
}
return 0;
}
#endif
/////////////////////////////////////////////////////////////////////////////
7 changes: 3 additions & 4 deletions configure.ac
Expand Up @@ -214,7 +214,6 @@ if test "x$drillbit" = xyes; then
fi
AM_CONDITIONAL([HAS_DRILLBIT], [test x$drillbit = xyes])


hashfast="no"

AC_ARG_ENABLE([hashfast],
Expand Down Expand Up @@ -525,12 +524,12 @@ if test "x$cointerra" = xyes; then
echo " Cointerra.ASICs......: Enabled"
else
echo " Cointerra.ASICs......: Disabled"
fi

if test "x$bitmine_A1" = xyes; then
echo " Bitmine-A1.ASICs........: Enabled"
echo " Bitmine-A1.ASICs.....: Enabled"
else
echo " Bitmine-A1.ASICs........: Disabled"

echo " Bitmine-A1.ASICs.....: Disabled"
fi

if test "x$drillbit" = xyes; then
Expand Down

0 comments on commit 1448e15

Please sign in to comment.