Example #1
0
//写一页数据
int w25qxx_write_page(uint32_t addr, uint8_t *buf, uint32_t len)
{
    w25qxx_write_enable();

    /* send addr */
    spi_xfer(W25X_PageProgram, W25QXX_CS_LOW);
    spi_xfer((uint8_t)((addr)>>16), W25QXX_CS_LOW);
    spi_xfer((uint8_t)((addr)>>8), W25QXX_CS_LOW);
    spi_xfer((uint8_t)addr, W25QXX_CS_LOW);
    
    w25_dev.ops.xfer(NULL, buf, len, W25QXX_CS_HIGH);
    while(w25_dev.ops.get_reamin() != 0)
    {
        w25_dev.ops.delayms(10);
    }

    
    /* wait busy */
    while((w25qxx_read_sr() & 0x01) == 0x01)
    {
        w25_dev.ops.delayms(1);
    }
    return 0;
}
Example #2
0
/* control backlight pwm (display brightness).
 * allow values 0-250 with 0 = turn off and 250 = max brightness
 */
void mergerbox_tft_dim(u16 value)
{
    struct spi_slave *slave;
    u16 din;
    u16 dout = 0;

    if (value > 0 && value < 250)
        dout = 0x4000 | value;

    slave = spi_setup_slave(0, 0, 1000000, SPI_MODE_0 | SPI_CS_HIGH);
    spi_claim_bus(slave);
    spi_xfer(slave, 16, &dout, &din, SPI_XFER_BEGIN | SPI_XFER_END);
    spi_release_bus(slave);
    spi_free_slave(slave);
}
Example #3
0
void rtc_set_time(uint8_t year, uint8_t month, uint8_t day,
		uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t weekday)
{
	RTC_BEGIN();
	spi_xfer(RTC_WRITE_CMD(2));
	spi_xfer(seconds);
	spi_xfer(minutes);
	spi_xfer(hours);
	spi_xfer(day);
	spi_xfer(weekday);
	spi_xfer(month);
	spi_xfer(year);
	RTC_END();

	/* read what we just wrote */
	rtc_get_time();
}
void lcd_spi_send(unsigned char reg_addr, unsigned char reg_data)
{
    int ret = 0;
    int msg,imsg;
    uchar omsg[2];
    msg=(reg_addr<<10)|reg_data;

    // note big endian, so swap
    omsg[0]=(msg>>8)&0xff;
    omsg[1]=(msg)&0xff;

    spi_xfer(spi_chipsel[0], 16,( uchar *)omsg, (uchar *) &imsg);

    // wait for transaction to finish
    udelay(400);
}
Example #5
0
void SPITouch_Init()
{
    if(! HAS_TOUCH)
        return;
#if 0
    /* Enable SPI1 */
    rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_SPI1EN);
    /* Enable GPIOA */
    rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
    /* Enable GPIOB */
    rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
#endif
    /* CS */
    gpio_set_mode(_TOUCH_PORT, GPIO_MODE_OUTPUT_50_MHZ,
                  GPIO_CNF_OUTPUT_PUSHPULL, _TOUCH_PIN);

    /* PenIRQ is pull-up input*/
    gpio_set_mode(_TOUCH_PORT, GPIO_MODE_INPUT,
                  GPIO_CNF_INPUT_PULL_UPDOWN, _TOUCH_IRQ_PIN);
    gpio_set(_TOUCH_PORT, _TOUCH_IRQ_PIN);

    CS_LO();
    spi_xfer(SPI1, RESET);
    CS_HI();
    //SPITouch_Calibrate(197312, 147271, -404, -20); /* Read from my Tx */
#if 0
    /* SCK, MOSI */
    gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
                  GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO5 | GPIO7);
    /* MISO */
    gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
                  GPIO_CNF_INPUT_FLOAT, GPIO6);
    /* Includes enable */
    spi_init_master(SPI1, 
                    SPI_CR1_BAUDRATE_FPCLK_DIV_4,
                    SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE,
                    SPI_CR1_CPHA_CLK_TRANSITION_2, 
                    SPI_CR1_DFF_8BIT,
                    SPI_CR1_MSBFIRST);
    spi_enable_software_slave_management(SPI1);
    spi_set_nss_high(SPI1);

    spi_enable(SPI1);
#endif
}
Example #6
0
int spi_flash_adr_write(struct spi_slave *spi,  u32 adr){

	unsigned flags=SPI_XFER_END;
	int ret;

	ret=adr;	
	flags|=SPI_XFER_ADR;
	
	ret=spi_xfer(spi,4*8,&ret,NULL,flags);
	
	if(ret)	{
	
		debug("SF: Faild to send adr(%zu bytes): %d\n",4,ret);
	}

	return ret;

}
Example #7
0
void radio_configure()
{
	radio_in_tx = 0;
	radio_command(SIDLE);
	
	radio_select();
	for (int i = 0; i < sizeof(cc1101_regs); ++i)
	{
		spi_xfer(cc1101_regs[i]);
	}
	radio_deselect();
	
	radio_write(IOCFG2, 6 | GDOx_INVERT);
	
	radio_channel(current_channel);
	
	radio_command(SFRX);
	radio_command(SRX);
}
Example #8
0
u8 A7105_ReadReg(u8 address)
{
    u8 data;

    CS_LO();
    spi_xfer(SPI2, 0x40 | address);
    spi_disable(SPI2);
    spi_set_bidirectional_receive_only_mode(SPI2);
    spi_enable(SPI2);
    int i;
    for(i = 0; i < 10; i++)
       ;
    spi_disable(SPI2);
    data = spi_read(SPI2);
    CS_HI();
    spi_set_unidirectional_mode(SPI2);
    spi_enable(SPI2);
    return data;
}
Example #9
0
File: spi.c Project: grepz/STM32_bl
void spi_exchange_nodma(const uint8_t *txbuf, uint8_t *rxbuf, size_t n)
{
    uint8_t byte;
    const uint8_t *txptr = txbuf;
    uint8_t *rxptr = rxbuf;

    while (n-- > 0) {
        if (txptr)
            byte = *txptr++;
        else
            byte = 0xFF;

        while (!(SPI_SR(SPI2) & SPI_SR_TXE));
        byte = (uint8_t)spi_xfer(SPI2, byte);

        if (rxptr)
            *rxptr++ = byte;
    }
}
Example #10
0
void nowplus_lcd_disable(void)
{
    u32 memsize = gdev.winSizeX*gdev.winSizeY*gdev.gdfBytesPP;
    memset((void *)gdev.frameAdrs, 0x00, memsize);

    //disable graphics pipeline
    //writel(readl(DISPC_GFX_ATTRIBUTES) & ~(0x1), DISPC_GFX_ATTRIBUTES);
#if 0
    static unsigned int	bus;
    static unsigned int	cs;
    static unsigned int	mode;
    static int   		bitlen;
    static uchar 		dout[MAX_SPI_BYTES];
    static uchar 		din[MAX_SPI_BYTES];
    static struct spi_slave *slave;

    slave = spi_setup_slave(0, 0, 37500000, mode);
    if (!slave) {
        printf("Invalid device %d:%d\n", bus, cs);
        return 1;
    }

    spi_claim_bus(slave);
    //spi1write(0x14, 0x00);  // set black
    //spi1write(0x1D, 0xA1);  // standby on
    if(spi_xfer(slave, bitlen, dout, din,
                SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
        printf("Error during SPI transaction\n");
        rcode = 1;
    }
    spi_release_bus(slave);
    spi_free_slave(slave);

    //Wait 200ms
    msleep(250);	//mdelay(200);
#endif

#if 0
    //disable display
    writel(readl(DISPC_CONTROL) & ~0x3, DISPC_CONTROL);
#endif
}
Example #11
0
/**
 * Performs an SPI transfer
 */
static int
do_spi_transfer(const struct spi_slave_params* cfg, void* txbuf, unsigned int wcount, 
                void* rxbuf, unsigned int rcount)
{
    int ret;
    int status;

    set_speed(cfg);
    chip_select(cfg, SPI_CS_ASSERT);

    /* Begin the transfer */
    ret = spi_xfer(spi_bus, txbuf, wcount, rxbuf, rcount, spi_complete_callback, &status);
    if(ret >= 0){
        bus_sem_wait();
        ret = status;
    }

    chip_select(cfg, SPI_CS_RELEASE);
    return ret;
}
Example #12
0
static void UseModule(int module)
{
    if (module == last_module_used) return;

    u8 cmd = (module & 0x07) | extra_bits;
    CS_LO();
    spi_xfer(PROTO_SPI.spi, cmd);
    CS_HI();

    // Adjust baud rate
    spi_disable(PROTO_SPI.spi);
    if (module == MODULE_FLASH) {
        spi_set_baudrate_prescaler(PROTO_SPI.spi, SPI_CR1_BR_FPCLK_DIV_4);
    } else if (last_module_used == MODULE_FLASH) {
        spi_set_baudrate_prescaler(PROTO_SPI.spi, SPI_CR1_BR_FPCLK_DIV_16);
    }
    spi_enable(PROTO_SPI.spi);

    last_module_used = module;
}
Example #13
0
int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes)
{
	int rv;

	/* Do the transfer */
	if (spi_claim_bus(dev->spi)) {
		debug("%s: Cannot claim SPI bus\n", __func__);
		return -1;
	}

	rv = spi_xfer(dev->spi, max(out_bytes, in_bytes) * 8,
		      dev->dout, dev->din,
		      SPI_XFER_BEGIN | SPI_XFER_END);

	spi_release_bus(dev->spi);

	if (rv) {
		debug("%s: Cannot complete SPI transfer\n", __func__);
		return -1;
	}

	return in_bytes;
}
Example #14
0
/******************************************************************************
 *
 * Function:    Fpga_write
 *
 * Description: This function writes data to the FPGA
 *
 * Parameters:  uint8_t* cmd      - pointer to the Command to be send to FPGA
 *              uint32_t cmd_len  - Length of the command in bytes
 *              uint8_t* Data     - Pointer to the data to be written
 *              uint32_t data_len - Length of the data in bytes
 ******************************************************************************/
FPGA_STATUS fpga_spi_write(uint8_t* cmd,uint32_t cmd_len,uint8_t* data,uint32_t data_len)
{
		FPGA_STATUS ret;
		uint8_t writecmd = CMDPKT_FPGA_WRITE;
		/* Claim the SPI controller */
	   ret = fpga_spiclaim(SPI_FPGA_OPFREQ);
	   if (ret) {
	    	    spi_release();
	            return FAIL;
	        	}
	    spi_xfer(1,&writecmd,NULL,0);
	    printf("Write command sent:%d\n",writecmd);

	    ret = spi_cmd_write(cmd,cmd_len,data,data_len);
	    if (ret)
	    {
	    	  spi_release();
	    	  return FAIL;
	    }
	    else
	    {     spi_release();
	   	   	  return SUCCESS;
	    }
}
Example #15
0
void m25_write_disable(void)
{
  spi_slave_select(SPI_SLAVE_FLASH);
  spi_xfer(SPI_BUS_FLASH, M25_WRDI);
  spi_slave_deselect();
}
Example #16
0
void CC2500_Strobe(u8 state)
{
    CS_LO();
    spi_xfer(SPI2, state);
    CS_HI();
}
Example #17
0
/**
 * Send a command to a LPC CROS_EC device and return the reply.
 *
 * The device's internal input/output buffers are used.
 *
 * @param dev		CROS_EC device
 * @param cmd		Command to send (EC_CMD_...)
 * @param cmd_version	Version of command to send (EC_VER_...)
 * @param dout		Output data (may be NULL If dout_len=0)
 * @param dout_len      Size of output data in bytes
 * @param dinp		Returns pointer to response data. This will be
 *			untouched unless we return a value > 0.
 * @param din_len	Maximum size of response in bytes
 * @return number of bytes in response, or -1 on error
 */
int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
		     const uint8_t *dout, int dout_len,
		     uint8_t **dinp, int din_len)
{
	int in_bytes = din_len + 4;	/* status, length, checksum, trailer */
	uint8_t *out;
	uint8_t *p;
	int csum, len;
	int rv;

	if (dev->protocol_version != 2) {
		debug("%s: Unsupported EC protcol version %d\n",
		      __func__, dev->protocol_version);
		return -1;
	}

	/*
	 * Sanity-check input size to make sure it plus transaction overhead
	 * fits in the internal device buffer.
	 */
	if (in_bytes > sizeof(dev->din)) {
		debug("%s: Cannot receive %d bytes\n", __func__, din_len);
		return -1;
	}

	/* We represent message length as a byte */
	if (dout_len > 0xff) {
		debug("%s: Cannot send %d bytes\n", __func__, dout_len);
		return -1;
	}

	/*
	 * Clear input buffer so we don't get false hits for MSG_HEADER
	 */
	memset(dev->din, '\0', in_bytes);

	if (spi_claim_bus(dev->spi)) {
		debug("%s: Cannot claim SPI bus\n", __func__);
		return -1;
	}

	out = dev->dout;
	out[0] = EC_CMD_VERSION0 + cmd_version;
	out[1] = cmd;
	out[2] = (uint8_t)dout_len;
	memcpy(out + 3, dout, dout_len);
	csum = cros_ec_calc_checksum(out, 3)
	       + cros_ec_calc_checksum(dout, dout_len);
	out[3 + dout_len] = (uint8_t)csum;

	/*
	 * Send output data and receive input data starting such that the
	 * message body will be dword aligned.
	 */
	p = dev->din + sizeof(int64_t) - 2;
	len = dout_len + 4;
	cros_ec_dump_data("out", cmd, out, len);
	rv = spi_xfer(dev->spi, max(len, in_bytes) * 8, out, p,
		      SPI_XFER_BEGIN | SPI_XFER_END);

	spi_release_bus(dev->spi);

	if (rv) {
		debug("%s: Cannot complete SPI transfer\n", __func__);
		return -1;
	}

	len = min(p[1], din_len);
	cros_ec_dump_data("in", -1, p, len + 3);

	/* Response code is first byte of message */
	if (p[0] != EC_RES_SUCCESS) {
		printf("%s: Returned status %d\n", __func__, p[0]);
		return -(int)(p[0]);
	}

	/* Check checksum */
	csum = cros_ec_calc_checksum(p, len + 2);
	if (csum != p[len + 2]) {
		debug("%s: Invalid checksum rx %#02x, calced %#02x\n", __func__,
		      p[2 + len], csum);
		return -1;
	}

	/* Anything else is the response data */
	*dinp = p + 2;

	return len;
}
Example #18
0
int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	struct spi_slave *slave;
	char  *cp = 0;
	uchar tmp;
	int   j;
	int   rcode = 0;

	/*
	 * We use the last specified parameters, unless new ones are
	 * entered.
	 */

	if ((flag & CMD_FLAG_REPEAT) == 0)
	{
		if (argc >= 2) {
			mode = CONFIG_DEFAULT_SPI_MODE;
			bus = simple_strtoul(argv[1], &cp, 10);
			if (*cp == ':') {
				cs = simple_strtoul(cp+1, &cp, 10);
			} else {
				cs = bus;
				bus = CONFIG_DEFAULT_SPI_BUS;
			}
			if (*cp == '.')
				mode = simple_strtoul(cp+1, NULL, 10);
		}
		if (argc >= 3)
			bitlen = simple_strtoul(argv[2], NULL, 10);
		if (argc >= 4) {
			cp = argv[3];
			for(j = 0; *cp; j++, cp++) {
				tmp = *cp - '0';
				if(tmp > 9)
					tmp -= ('A' - '0') - 10;
				if(tmp > 15)
					tmp -= ('a' - 'A');
				if(tmp > 15) {
					printf("Hex conversion error on %c\n", *cp);
					return 1;
				}
				if((j % 2) == 0)
					dout[j / 2] = (tmp << 4);
				else
					dout[j / 2] |= tmp;
			}
		}
	}

	if ((bitlen < 0) || (bitlen >  (MAX_SPI_BYTES * 8))) {
		printf("Invalid bitlen %d\n", bitlen);
		return 1;
	}

	slave = spi_setup_slave(bus, cs, 1000000, mode);
	if (!slave) {
		printf("Invalid device %d:%d\n", bus, cs);
		return 1;
	}

	spi_claim_bus(slave);
	if(spi_xfer(slave, bitlen, dout, din,
				SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
		printf("Error during SPI transaction\n");
		rcode = 1;
	} else {
		for(j = 0; j < ((bitlen + 7) / 8); j++) {
			printf("%02X", din[j]);
		}
		printf("\n");
	}
	spi_release_bus(slave);
	spi_free_slave(slave);

	return rcode;
}
static int ksz8893m_transfer(struct spi_slave *slave, uchar dir, uchar reg,
			     uchar data, uchar result[3])
{
	unsigned char dout[3] = { dir, reg, data, };
	return spi_xfer(slave, sizeof(dout) * 8, dout, result, SPI_XFER_BEGIN | SPI_XFER_END);
}
Example #20
0
void exti3_isr(void) {
  int i, j;
  uint16_t endFillByte;
  gpio_set(GREEN_LED_PORT, GREEN_LED_PIN);
//   gpio_set(RED_LED_PORT, RED_LED_PIN);
//   iprintf("fill bytes\r\n");
  exti_reset_request(EXTI3);
  iprintf("exti3_isr\r\n");
  if(media_file.buffer_ready[media_file.active_buffer] == 0) {
    iprintf("Buffer %d was ready...\r\n", media_file.active_buffer);
  while(gpio_get(CODEC_DREQ_PORT, CODEC_DREQ)) {
//     iprintf("loop\r\n");
    gpio_set(CODEC_PORT, CODEC_CS);
    if(!media_file.near_end) {
      for(i=0;i<32;i++) {
        spi_xfer(CODEC_SPI, media_file.buffer[media_file.active_buffer][current_track.byte_count++]);
      }
      if((current_track.byte_count % 512) == 0) {
        gpio_clear(CODEC_PORT, CODEC_CS);
      }
      if(current_track.byte_count == MEDIA_BUFFER_SIZE) {
//         iprintf("reading\r\n");
        sdfat_read_media();
        current_track.byte_count = 0;
        gpio_clear(CODEC_PORT, CODEC_CS);
//         iprintf("swapping...\r\n");
        /* fetch the value of current decode position */
        vs1053_SCI_write(SCI_WRAMADDR, PARAM_POSITION_LO);
        for(i=0;i<150;i++) {__asm__("nop\n\t");}
        current_track.pos = vs1053_SCI_read(SCI_WRAM);
        for(i=0;i<150;i++) {__asm__("nop\n\t");}
        vs1053_SCI_write(SCI_WRAMADDR, PARAM_POSITION_HI);
        for(i=0;i<150;i++) {__asm__("nop\n\t");}
        current_track.pos += vs1053_SCI_read(SCI_WRAM) << 16;
//         iprintf("swap\r\n");
        gpio_set(CODEC_PORT, CODEC_CS);
        while(media_file.buffer_ready[media_file.active_buffer]) {__asm__("nop\n\t");}
//           iprintf("Breaking out\r\n");
//           break;
//         }
      }
    } else {
      for(i=0;i<32;i++) {
        if(current_track.byte_count > media_file.file_end) {
          iprintf("ending\r\n");
          // Ought to do this next bit by issuing a player_stop job so that the cleanup code
          // is all in one place and we can power down everything automatically for power saving
          
          /* now need to clean up the fifos and stop the player */
          gpio_clear(CODEC_PORT, CODEC_CS);
          /* fetch the value of endFillByte */
          vs1053_SCI_write(SCI_WRAMADDR, PARAM_END_FILL_BYTE);
          while(!gpio_get(CODEC_DREQ_PORT, CODEC_DREQ)) {__asm__("nop\n\t");}
          endFillByte = vs1053_SCI_read(SCI_WRAM) & 0xFF;

          iprintf("End Fill Byte %02X\r\n", endFillByte);
          gpio_set(CODEC_PORT, CODEC_CS);
          for(i=0;i<65;i++) {
            while(!gpio_get(CODEC_DREQ_PORT, CODEC_DREQ)) {__asm__("nop\n\t");}
            for(j=0;j<32;j++) {
              spi_xfer(CODEC_SPI, endFillByte);
            }
          }
          gpio_clear(CODEC_PORT, CODEC_CS);
          i = vs1053_SCI_read(SCI_MODE);
          i |= SM_CANCEL;
          vs1053_SCI_write(SCI_MODE, i);
          gpio_set(CODEC_PORT, CODEC_CS);
          j = 0;
          while(j < 2048) {
            while(!gpio_get(CODEC_DREQ_PORT, CODEC_DREQ)) {__asm__("nop\n\t");}
            for(i=0;i<32;i++) {
              spi_xfer(CODEC_SPI, endFillByte);
            }
            j += 32;
            if(!(vs1053_SCI_read(SCI_MODE) & SM_CANCEL)) {
              break;
            }
          }
          gpio_clear(CODEC_PORT, CODEC_CS);
          if(j >= 2048) {
            /* need to do a software reset */
            vs1053_SCI_write(SCI_MODE, SM_RESET);
          }
          iprintf("End Fill Byte %02X\r\n", endFillByte);
          
          current_track_playing = 0;
          
          exti_reset_request(EXTI3);
          exti_disable_request(EXTI3);
          nvic_disable_irq(NVIC_EXTI3_IRQ);
          return;
        } else {
          spi_xfer(CODEC_SPI, media_file.buffer[media_file.active_buffer][current_track.byte_count++]);
        }
      }
    }
  }
  }

  gpio_clear(GREEN_LED_PORT, GREEN_LED_PIN);
}
static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd,
		struct mmc_data *data)
{
	struct spi_slave *spi = mmc->priv;
	u8 r1;
	int i;
	int ret = 0;
	debug("%s:cmd%d %x %x\n", __func__,
	      cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
	spi_claim_bus(spi);
	spi_cs_activate(spi);
	r1 = mmc_spi_sendcmd(mmc, cmd->cmdidx, cmd->cmdarg);
	if (r1 == 0xff) { /* no response */
		ret = NO_CARD_ERR;
		goto done;
	} else if (r1 & R1_SPI_COM_CRC) {
		ret = COMM_ERR;
		goto done;
	} else if (r1 & ~R1_SPI_IDLE) { /* other errors */
		ret = TIMEOUT;
		goto done;
	} else if (cmd->resp_type == MMC_RSP_R2) {
		r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16);
		for (i = 0; i < 4; i++)
			cmd->response[i] = be32_to_cpu(cmd->response[i]);
		debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1],
		      cmd->response[2], cmd->response[3]);
	} else if (!data) {
		switch (cmd->cmdidx) {
		case SD_CMD_APP_SEND_OP_COND:
		case MMC_CMD_SEND_OP_COND:
			cmd->response[0] = (r1 & R1_SPI_IDLE) ? 0 : OCR_BUSY;
			break;
		case SD_CMD_SEND_IF_COND:
		case MMC_CMD_SPI_READ_OCR:
			spi_xfer(spi, 4 * 8, NULL, cmd->response, 0);
			cmd->response[0] = be32_to_cpu(cmd->response[0]);
			debug("r32 %x\n", cmd->response[0]);
			break;
		case MMC_CMD_SEND_STATUS:
			spi_xfer(spi, 1 * 8, NULL, cmd->response, 0);
			cmd->response[0] = (cmd->response[0] & 0xff) ?
				MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA;
			break;
		}
	} else {
		debug("%s:data %x %x %x\n", __func__,
		      data->flags, data->blocks, data->blocksize);
		if (data->flags == MMC_DATA_READ)
			r1 = mmc_spi_readdata(mmc, data->dest,
				data->blocks, data->blocksize);
		else if  (data->flags == MMC_DATA_WRITE)
			r1 = mmc_spi_writedata(mmc, data->src,
				data->blocks, data->blocksize,
				(cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK));
		if (r1 & R1_SPI_COM_CRC)
			ret = COMM_ERR;
		else if (r1) /* other errors */
			ret = TIMEOUT;
	}
done:
	spi_cs_deactivate(spi);
	spi_release_bus(spi);
	return ret;
}
static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
			      u32 bcnt, u32 bsize, int multi)
{
	struct spi_slave *spi = mmc->priv;
	const u8 *buf = xbuf;
	u8 r1;
	u16 crc;
	u8 tok[2];
	int i;
	tok[0] = 0xff;
	tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;
	while (bcnt--) {
#ifdef CONFIG_MMC_SPI_CRC_ON
		crc = cpu_to_be16(cyg_crc16((u8 *)buf, bsize));
#endif
		spi_xfer(spi, 2 * 8, tok, NULL, 0);
		spi_xfer(spi, bsize * 8, buf, NULL, 0);
		spi_xfer(spi, 2 * 8, &crc, NULL, 0);
		for (i = 0; i < CTOUT; i++) {
			spi_xfer(spi, 1 * 8, NULL, &r1, 0);
			if ((r1 & 0x10) == 0) /* response token */
				break;
		}
		debug("%s:tok%d %x\n", __func__, i, r1);
		if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) {
			for (i = 0; i < WTOUT; i++) { /* wait busy */
				spi_xfer(spi, 1 * 8, NULL, &r1, 0);
				if (i && r1 == 0xff) {
					r1 = 0;
					break;
				}
			}
			if (i == WTOUT) {
				debug("%s:wtout %x\n", __func__, r1);
				r1 = R1_SPI_ERROR;
				break;
			}
		} else {
			debug("%s: err %x\n", __func__, r1);
			r1 = R1_SPI_COM_CRC;
			break;
		}
		buf += bsize;
	}
	if (multi && bcnt == -1) { /* stop multi write */
		tok[1] = SPI_TOKEN_STOP_TRAN;
		spi_xfer(spi, 2 * 8, tok, NULL, 0);
		for (i = 0; i < WTOUT; i++) { /* wait busy */
			spi_xfer(spi, 1 * 8, NULL, &r1, 0);
			if (i && r1 == 0xff) {
				r1 = 0;
				break;
			}
		}
		if (i == WTOUT) {
			debug("%s:wstop %x\n", __func__, r1);
			r1 = R1_SPI_ERROR;
		}
	}
	return r1;
}
Example #23
0
/*
 * Once transaction is initiated and the TPM indicated that it is ready to go,
 * read the actual bytes from the register.
 */
static void read_bytes(void *buffer, size_t bytes)
{
	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
	spi_xfer(spi_slave, NULL, 0, buffer, bytes);
}
Example #24
0
void flash_write_enable()
{
	spi_begin();
	spi_xfer(0x06, 8);
	spi_end();
}
Example #25
0
void flash_power_up()
{
	spi_begin();
	spi_xfer(0xAB, 8);
	spi_end();
}
Example #26
0
void processSPI(void)
{
    uint8_t b, c;

    b = spi_xfer(0);

    switch (b) {
    case 0x80: // set brightness
        c = spi_xfer(0);
        set_brightness(c);
        eeprom_write_byte(&b_brightness, c);
        break;
    case 0x82: // clear
        clear_screen();
        counter = 0;
        dots = 0;
        break;
    case 0x83: // set scroll mode
        c = spi_xfer(0);

        if (c == 0)
            scroll_mode = ROTATE;
        else
            scroll_mode = SCROLL;
        break;
    case 0x84: // receive segment data
        c = spi_xfer(0);

        /*
        if (scroll_mode == ROTATE) {
        	set_segments_at(c, counter++);
        	if (counter >= 4) counter = 0;
        }
        else {
        	shift_in_segments(c);
        }
        */

        break;
    case 0x85: // set dots (the four bits of the second byte controls dots individually)
        dots = spi_xfer(0);
        break;
    case 0x88: // display integer
    {
        uint8_t i1 = spi_xfer(0);
        uint8_t i2 = spi_xfer(0);

        uint16_t i = (i2 << 8) + i1;
        set_number(i);
    }
    break;
    case 0x89: // set position (only valid for ROTATE mode)
        counter = spi_xfer(0);
        break;
    case 0x8a: // get firmware revision
        spi_xfer(3);
        break;
    case 0x8b: // get number of digits
        spi_xfer(8);
        break;

    default:
        if (b >= 0x80) break; // anything above 0x80 is considered a reserved command and is ignored

        if (scroll_mode == ROTATE) {
            set_char_at(b, counter++);
            if (counter >= 8) counter = 0;
        }
        else {
            shift_in(b);
        }
        break;
    }
}
Example #27
0
uint8_t spi_msg(uint8_t dat) {
  return spi_xfer(CODEC_SPI, dat);
}
Example #28
0
/*
 * Each TPM2 SPI transaction starts the same: CS is asserted, the 4 byte
 * header is sent to the TPM, the master waits til TPM is ready to continue.
 *
 * Returns 1 on success, 0 on failure (TPM SPI flow control timeout.)
 */
static int start_transaction(int read_write, size_t bytes, unsigned addr)
{
	spi_frame_header header;
	uint8_t byte;
	int i;
	struct stopwatch sw;
	static int tpm_sync_needed CAR_GLOBAL;
	static struct stopwatch wake_up_sw CAR_GLOBAL;
	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
	/*
	 * First Cr50 access in each coreboot stage where TPM is used will be
	 * prepended by a wake up pulse on the CS line.
	 */
	int wakeup_needed = 1;

	/* Wait for TPM to finish previous transaction if needed */
	if (car_get_var(tpm_sync_needed)) {
		tpm_sync();
		/*
		 * During the first invocation of this function on each stage
		 * this if () clause code does not run (as tpm_sync_needed
		 * value is zero), during all following invocations the
		 * stopwatch below is guaranteed to be started.
		 */
		if (!stopwatch_expired(car_get_var_ptr(&wake_up_sw)))
			wakeup_needed = 0;
	} else {
		car_set_var(tpm_sync_needed, 1);
	}

	if (wakeup_needed) {
		/* Just in case Cr50 is asleep. */
		spi_claim_bus(spi_slave);
		udelay(1);
		spi_release_bus(spi_slave);
		udelay(100);
	}

	/*
	 * The Cr50 on H1 does not go to sleep for 1 second after any
	 * SPI slave activity, let's be conservative and limit the
	 * window to 900 ms.
	 */
	stopwatch_init_msecs_expire(car_get_var_ptr(&wake_up_sw), 900);

	/*
	 * The first byte of the frame header encodes the transaction type
	 * (read or write) and transfer size (set to lentgh - 1), limited to
	 * 64 bytes.
	 */
	header.body[0] = (read_write ? 0x80 : 0) | 0x40 | (bytes - 1);

	/* The rest of the frame header is the TPM register address. */
	for (i = 0; i < 3; i++)
		header.body[i + 1] = (addr >> (8 * (2 - i))) & 0xff;

	/* CS assert wakes up the slave. */
	spi_claim_bus(spi_slave);

	/*
	 * The TCG TPM over SPI specification introduces the notion of SPI
	 * flow control (Section "6.4.5 Flow Control").
	 *
	 * Again, the slave (TPM device) expects each transaction to start
	 * with a 4 byte header trasmitted by master. The header indicates if
	 * the master needs to read or write a register, and the register
	 * address.
	 *
	 * If the slave needs to stall the transaction (for instance it is not
	 * ready to send the register value to the master), it sets the MOSI
	 * line to 0 during the last clock of the 4 byte header. In this case
	 * the master is supposed to start polling the SPI bus, one byte at
	 * time, until the last bit in the received byte (transferred during
	 * the last clock of the byte) is set to 1.
	 *
	 * Due to some SPI controllers' shortcomings (Rockchip comes to
	 * mind...) we trasmit the 4 byte header without checking the byte
	 * transmitted by the TPM during the transaction's last byte.
	 *
	 * We know that cr50 is guaranteed to set the flow control bit to 0
	 * during the header transfer, but real TPM2 might be fast enough not
	 * to require to stall the master, this would present an issue.
	 * crosbug.com/p/52132 has been opened to track this.
	 */
	spi_xfer(spi_slave, header.body, sizeof(header.body), NULL, 0);

	/*
	 * Now poll the bus until TPM removes the stall bit. Give it up to 100
	 * ms to sort it out - it could be saving stuff in nvram at some
	 * point.
	 */
	stopwatch_init_msecs_expire(&sw, 100);
	do {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "TPM flow control failure\n");
			spi_release_bus(spi_slave);
			return 0;
		}
		spi_xfer(spi_slave, NULL, 0, &byte, 1);
	} while (!(byte & 1));
	return 1;
}
Example #29
0
/*
 * Once transaction is initiated and the TPM indicated that it is ready to go,
 * write the actual bytes to the register.
 */
static void write_bytes(const void *buffer, size_t bytes)
{
	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
	spi_xfer(spi_slave, buffer, bytes, NULL, 0);
}
Example #30
0
int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	struct spi_slave *slave;
	char  *cp = 0;
	uchar tmp;
	int   j;
	int   rcode = 0;

	/*
	 * We use the last specified parameters, unless new ones are
	 * entered.
	 */

	if ((flag & CMD_FLAG_REPEAT) == 0)
	{
		if (argc >= 2)
			device = simple_strtoul(argv[1], NULL, 10);
		if (argc >= 3)
			bitlen = simple_strtoul(argv[2], NULL, 10);
		if (argc >= 4) {
			cp = argv[3];
			for(j = 0; *cp; j++, cp++) {
				tmp = *cp - '0';
				if(tmp > 9)
					tmp -= ('A' - '0') - 10;
				if(tmp > 15)
					tmp -= ('a' - 'A');
				if(tmp > 15) {
					printf("Hex conversion error on %c, giving up.\n", *cp);
					return 1;
				}
				if((j % 2) == 0)
					dout[j / 2] = (tmp << 4);
				else
					dout[j / 2] |= tmp;
			}
		}
	}

	if ((bitlen < 0) || (bitlen >  (MAX_SPI_BYTES * 8))) {
		printf("Invalid bitlen %d, giving up.\n", bitlen);
		return 1;
	}

	/* FIXME: Make these parameters run-time configurable */
	slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, device, 1000000,
			CONFIG_DEFAULT_SPI_MODE);
	if (!slave) {
		printf("Invalid device %d, giving up.\n", device);
		return 1;
	}

	debug ("spi chipsel = %08X\n", device);

	spi_claim_bus(slave);
	if(spi_xfer(slave, bitlen, dout, din,
				SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
		printf("Error with the SPI transaction.\n");
		rcode = 1;
	} else {
		for(j = 0; j < ((bitlen + 7) / 8); j++) {
			printf("%02X", din[j]);
		}
		printf("\n");
	}
	spi_release_bus(slave);
	spi_free_slave(slave);

	return rcode;
}