Edit

thodg/cgminer/mcp2210.c

Branch :

  • Show log

    Commit

  • Author : Con Kolivas
    Date : 2014-01-04 09:35:10
    Hash : 6f9b5767
    Message : Implement an mcp2210 spi cancel function.

  • mcp2210.c
  • /*
     * Copyright 2014 Con Kolivas
     *
     * This program is free software; you can redistribute it and/or modify it
     * under the terms of the GNU General Public License as published by the Free
     * Software Foundation; either version 3 of the License, or (at your option)
     * any later version.  See COPYING for more details.
     */
    #include "miner.h"
    #include "usbutils.h"
    #include "mcp2210.h"
    
    bool mcp2210_send_recv(struct cgpu_info *cgpu, char *buf, enum usb_cmds cmd)
    {
    	uint8_t mcp_cmd = buf[0];
    	int amount, err;
    
    	if (unlikely(cgpu->usbinfo.nodev))
    		return false;
    
    	err = usb_write(cgpu, buf, MCP2210_BUFFER_LENGTH, &amount, cmd);
    	if (err || amount != MCP2210_BUFFER_LENGTH) {
    		applog(LOG_WARNING, "%s %d: Error %d sending %s sent %d of %d",
    		       cgpu->drv->name, cgpu->device_id, err, usb_cmdname(cmd),
    		       amount, MCP2210_BUFFER_LENGTH);
    		return false;
    	}
    
    	err = usb_read_timeout(cgpu, buf, MCP2210_BUFFER_LENGTH, &amount, 10, cmd);
    	if (err || amount != MCP2210_BUFFER_LENGTH) {
    		applog(LOG_WARNING, "%s %d: Error %d receiving %s received %d of %d",
    		       cgpu->drv->name, cgpu->device_id, err, usb_cmdname(cmd),
    		       amount, MCP2210_BUFFER_LENGTH);
    		return false;
    	}
    
    	/* Return code should always echo original command */
    	if (buf[0] != mcp_cmd) {
    		applog(LOG_WARNING, "%s %d: Response code mismatch, asked for %u got %u",
    		       cgpu->drv->name, cgpu->device_id, mcp_cmd, buf[0]);
    		return false;
    	}
    	return true;
    }
    
    /* Get all the pin designations and store them in a gpio_pin struct */
    bool mcp2210_get_gpio_pindes(struct cgpu_info *cgpu, struct gpio_pin *gp)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    	int i;
    
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_GET_GPIO_SETTING;
    	if (!mcp2210_send_recv(cgpu, buf, C_MCP_GETGPIOSETTING))
    		return false;
    
    	for (i = 0; i < 9; i++)
    		gp->pin[i] = !!(buf[4 + i]);
    	return true;
    }
    
    
    /* Get all the pin vals and store them in a gpio_pin struct */
    bool mcp2210_get_gpio_pinvals(struct cgpu_info *cgpu, struct gpio_pin *gp)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    	int i;
    
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_GET_GPIO_PIN_VAL;
    	if (!mcp2210_send_recv(cgpu, buf, C_MCP_GETGPIOPINVAL))
    		return false;
    
    	for (i = 0; i < 8; i++)
    		gp->pin[i] = !!(buf[4] & (0x01u << i));
    	gp->pin[8] = buf[5] & 0x01u;
    
    	return true;
    }
    
    /* Get all the pindirs */
    bool mcp2210_get_gpio_pindirs(struct cgpu_info *cgpu, struct gpio_pin *gp)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    	int i;
    
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_GET_GPIO_PIN_DIR;
    	if (!mcp2210_send_recv(cgpu, buf, C_MCP_GETGPIOPINDIR))
    		return false;
    
    	for (i = 0; i < 8; i++)
    		gp->pin[i] = !!(buf[4] & (0x01u << i));
    	gp->pin[8] = buf[5] & 0x01u;
    
    	return true;
    }
    
    /* Get the designation of one pin */
    bool mcp2210_get_gpio_pin(struct cgpu_info *cgpu, int pin, int *des)
    {
    	struct gpio_pin gp;
    
    	if (!mcp2210_get_gpio_pindes(cgpu, &gp))
    		return false;
    
    	*des = gp.pin[pin];
    	return true;
    }
    
    /* Set the designation of one pin */
    bool mcp2210_set_gpio_pindes(struct cgpu_info *cgpu, int pin, int des)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    
    	/* Copy the current values */
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_GET_GPIO_SETTING;
    	if (!mcp2210_send_recv(cgpu, buf, C_MCP_GETGPIOSETTING))
    		return false;
    
    	buf[4 + pin] = des;
    	memset(buf + 18, 0, 45);
    	buf[0] = MCP2210_SET_GPIO_SETTING;
    	return (mcp2210_send_recv(cgpu, buf, C_MCP_SETGPIOSETTING));
    }
    
    /* Get one pinval */
    bool mcp2210_get_gpio_pinval(struct cgpu_info *cgpu, int pin, int *val)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_GET_GPIO_PIN_VAL;
    	if (!mcp2210_send_recv(cgpu, buf, C_MCP_GETGPIOPINVAL))
    		return false;
    
    	buf[0] = MCP2210_GET_GPIO_PIN_VAL;
    
    	if (pin < 8)
    		*val = !!(buf[4] & (0x01u << pin));
    	else
    		*val = !!(buf[5] & 0x01u);
    
    	return true;
    }
    
    /* Set one pinval */
    bool mcp2210_set_gpio_pinval(struct cgpu_info *cgpu, int pin, int val)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    
    	/* Get the current pin vals first since we're only changing one. */
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_GET_GPIO_PIN_VAL;
    	if (!mcp2210_send_recv(cgpu, buf, C_MCP_GETGPIOPINVAL))
    		return false;
    
    	buf[0] = MCP2210_SET_GPIO_PIN_VAL;
    
    	if (pin < 8) {
    		if (val)
    			buf[4] |= (0x01u << pin);
    		else
    			buf[4] &= ~(0x01u << pin);
    	} else {
    		if (val)
    			buf[5] |= 0x01u;
    		else
    			buf[5] &= ~0x01u;
    	}
    	return mcp2210_send_recv(cgpu, buf, C_MCP_SETGPIOPINVAL);
    }
    
    /* Get one pindir */
    bool mcp2210_get_gpio_pindir(struct cgpu_info *cgpu, int pin, int *dir)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_GET_GPIO_PIN_DIR;
    	if (!mcp2210_send_recv(cgpu, buf, C_MCP_GETGPIOPINDIR))
    		return false;
    
    	buf[0] = MCP2210_GET_GPIO_PIN_DIR;
    
    	if (pin < 8)
    		*dir = !!(buf[4] & (0x01u << pin));
    	else
    		*dir = !!(buf[5] & 0x01u);
    
    	return true;
    }
    
    /* Set one pindir */
    bool mcp2210_set_gpio_pindir(struct cgpu_info *cgpu, int pin, int dir)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    
    	/* Get the current pin dirs first since we're only changing one. */
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_GET_GPIO_PIN_DIR;
    	if (!mcp2210_send_recv(cgpu, buf, C_MCP_GETGPIOPINDIR))
    		return false;
    
    	buf[0] = MCP2210_SET_GPIO_PIN_DIR;
    
    	if (pin < 8) {
    		if (dir)
    			buf[4] |= (0x01u << pin);
    		else
    			buf[4] &= ~(0x01u << pin);
    	} else {
    		if (dir)
    			buf[5] |= 0x01u;
    		else
    			buf[5] &= ~0x01u;
    	}
    	return mcp2210_send_recv(cgpu, buf, C_MCP_SETGPIOPINDIR);
    }
    
    bool mcp2210_spi_cancel(struct cgpu_info *cgpu)
    {
    	char buf[MCP2210_BUFFER_LENGTH];
    
    	memset(buf, 0, MCP2210_BUFFER_LENGTH);
    	buf[0] = MCP2210_SPI_CANCEL;
    	return mcp2210_send_recv(cgpu, buf, C_MCP_SPICANCEL);
    }