static int spi_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) { int ret, i; for (i = 0; i < length; i++) { ret = spi_reg_read(stmpe, reg + i); if (ret < 0) return ret; *(values + i) = ret; } return 0; }
int spi_transfer(struct spi_device *spidev, unsigned char *txbuf, unsigned char *rxbuf, int len) { unsigned int txword = 0, rxword = 0; unsigned int event = 0, command = 0; int isRead = 0, tm = 0, i = 0; command = (spidev->chip_select<<30)|(len - 1); /*enable chipselect and tell spi the length of data*/ spi_reg_write(&spidev->spi_reg->command, command); /*enable rx ints*/ spi_reg_write(&spidev->spi_reg->mask, SPIM_NE); #if 0 int len_count = len; do{ spi_reg_read(&spidev->spi_reg->event, &event); if(event & SPI_EV_NF) { txword = 0; txword = *(unsigned int *)txbuf; txbuf += 4; spi_reg_write(&spidev->spi_reg->transmit, txword); len_count -= 4; } }while(len_count>0); usleep(1); /*here wait tx data over*/ len_count = len; do{ for(tm = 0, isRead = 0; tm < SPI_TIMEOUT; tm++) { spi_reg_read(&spidev->spi_reg->event, &event); if (event & SPI_EV_NE) { spi_reg_read(&spidev->spi_reg->receive, &rxword); // printf("11rxword=0x%08x, event=0x%08x\n",rxword,event); *(unsigned int *) rxbuf = rxword; rxbuf += 4; break; } } if (tm >= SPI_TIMEOUT) { printf("spi error:Time out when spi transfer,event=0x%08x\n",event); return -1; } len_count = len_count - 4; }while(len_count>0); #else do{ spi_reg_read(&spidev->spi_reg->event, &event); if(event & SPI_EV_NF) { txword = 0; txword = *(unsigned int *)txbuf; txbuf += 4; spi_reg_write(&spidev->spi_reg->transmit, txword); } /*here wait tx data over*/ // usleep(5); // printf("txword=0x%08x, len=%d\n",txword, len); for(tm = 0, isRead = 0; tm < SPI_TIMEOUT; tm++) { spi_reg_read(&spidev->spi_reg->event, &event); if (event & SPI_EV_NE) { /*here wait rx over*/ for(i = 0; i < SPI_TIMEOUT; i++) { spi_reg_read(&spidev->spi_reg->event, &event); if(((event>>24)&0x3f) >= 4) break; } spi_reg_read(&spidev->spi_reg->receive, &rxword); // printf("in transfer rxword=0x%08x event=0x%08x\n",rxword,event); isRead = 1; *(unsigned int *) rxbuf = rxword; rxbuf += 4; } /* * Only bail when we've had both NE and NF events. * This will cause timeouts on RO devices, so maybe * in the future put an arbitrary delay after writing * the device. Arbitrary delays suck, though... */ if (isRead) break; } len -= 4; }while(len>0); if (tm >= SPI_TIMEOUT) { printf("spi error:Time out when spi transfer\n"); return -1; } #endif /*disable rx ints*/ spi_reg_write(&spidev->spi_reg->mask, 0); // spi_cs_invalid(spidev->chip_select); return 0; }
int spi_setup(struct spi_device *spidev) { unsigned int hw_mode; unsigned long flags; unsigned int regval; unsigned char bits_per_word, pm, cs_sel = spidev->chip_select; unsigned int hz = 0; unsigned int spibrg = 198000000; if(!spidev->max_speed_hz) return -1; if(!spidev->bits_per_word) spidev->bits_per_word = 8; spi_reg_read(&spidev->spi_reg->csmode[spidev->chip_select], &hw_mode); hw_mode &= ~(CSMODE_CP_BEGIN_EDGECLK | CSMODE_CI_INACTIVEHIGH | CSMODE_REV); if (spidev->mode & SPI_CPHA) hw_mode |= CSMODE_CP_BEGIN_EDGECLK; if (spidev->mode & SPI_CPOL) hw_mode |= CSMODE_CI_INACTIVEHIGH; if (!(spidev->mode & SPI_LSB_FIRST)) hw_mode |= CSMODE_REV; if (!hz) hz = spidev->max_speed_hz; /* mask out bits we are going to set */ hw_mode &= ~(CSMODE_LEN(0xF) | CSMODE_DIV16 | CSMODE_PM(0xF)); //hw_mode |= CSMODE_LEN(bits_per_word) | CSMODE_INIT_VAL; hw_mode |= CSMODE_LEN(spidev->bits_per_word-1); if ((spibrg / hz) > 32) { hw_mode |= CSMODE_DIV16; pm = spibrg / (hz * 32); if (pm > CSMODE_PM_MAX) { pm = CSMODE_PM_MAX; printf("Requested speed is too low: %d Hz. Will use %d Hz instead.\n", hz, spibrg / 32 * 16); } } else { pm = spibrg / (hz * 2); /*delete by zhangjj 2015-11-12 change spi max HZ*/ #if 0 if (pm < CSMODE_PM_MIN) pm = CSMODE_PM_MIN; #endif /*delete end*/ } hw_mode |= CSMODE_PM(pm); /* Reset the hw mode */ spi_reg_read(&spidev->spi_reg->mode, ®val); /* Turn off SPI unit prior changing mode */ spi_reg_write(&spidev->spi_reg->mode, regval & ~SPMODE_ENABLE); spi_reg_write(&spidev->spi_reg->csmode[cs_sel], hw_mode); spi_reg_write(&spidev->spi_reg->mode, regval); #if 0 unsigned int mmode=0,eevent = 0, mmask = 0,command = 0,ccmode=0; spi_reg_read(&spidev->spi_reg->mode, &mmode); spi_reg_read(&spidev->spi_reg->event, &eevent); spi_reg_read(&spidev->spi_reg->mask, &mmask); spi_reg_read(&spidev->spi_reg->command, &command); spi_reg_read(&spidev->spi_reg->csmode[cs_sel], &ccmode); printf("spi cs_sel=%d mode=0x%08x event=0x%08x mask=0x%08x command=0x%08x csmode=0x%08x\n", cs_sel,mmode,eevent,mmask,command, ccmode); #endif return 0; }