void SPI::begin(int busNo,uint32_t spi_speed){ if(spiIsInitialized){ return; } /* set spidev accordingly to busNo like: * busNo = 23 -> /dev/spidev2.3 * * a bit messy but simple * */ char device[] = "/dev/spidev0.0"; device[11] += (busNo / 10) % 10; device[13] += busNo % 10; if(this->fd >=0) // check whether spi is already open { close(this->fd); this->fd=-1; } this->fd = open(device, O_RDWR); if (this->fd < 0) throw SPIException("can't open device"); /* { perror("can't open device"); abort(); }*/ spiIsInitialized = true; init(spi_speed); }
SPI::SPI( int bus, int ce, uint8_t mode ) { std::stringstream devname; devname << SPIDEV_PREFIX << bus << "." << ce; this->fd = open(devname.str().c_str(), O_RDWR); if( this->fd < 0 ) { throw SPIException(string("Can't open spidev: ") + devname.str() ); } // SPIモードセット if( ioctl(this->fd, SPI_IOC_WR_MODE, &mode) < 0 ) { throw SPIException(string( "SPI_IOC_WR_MODE failed")); } // パラメータ初期値セット this->bits_per_word = 8; // 8ビット this->cs_change = LOW; // Active Low this->speed = 1000000; // 1MHz this->delay_usecs = 0; // ディレイ0 }
void SPI::init(uint32_t speed) { uint8_t bits = RF24_SPIDEV_BITS; uint8_t mode = 0; int ret; /* * spi mode */ ret = ioctl(this->fd, SPI_IOC_WR_MODE, &mode); if (ret == -1) throw SPIException("cant set WR spi mode"); /*{ perror("can't set spi mode"); abort(); }*/ ret = ioctl(this->fd, SPI_IOC_RD_MODE, &mode); if (ret == -1) throw SPIException("can't set RD spi mode"); /*{ perror("can't set spi mode"); abort(); }*/ /* * bits per word */ ret = ioctl(this->fd, SPI_IOC_WR_BITS_PER_WORD, &bits); if (ret == -1) throw SPIException("can't set WR bits per word"); /*{ perror("can't set bits per word"); abort(); }*/ ret = ioctl(this->fd, SPI_IOC_RD_BITS_PER_WORD, &bits); if (ret == -1) throw SPIException("can't set RD bits per word"); /*{ perror("can't set bits per word"); abort(); }*/ /* * max speed hz */ ret = ioctl(this->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); if (ret == -1) throw SPIException("can't WR set max speed hz"); /*{ perror("can't set max speed hz"); abort(); }*/ ret = ioctl(this->fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); if (ret == -1) throw SPIException("can't RD set max speed hz"); /*{ perror("can't set max speed hz"); abort(); }*/ _spi_speed=speed; }
void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len) { struct spi_ioc_transfer tr; memset(&tr, 0, sizeof(tr)); tr.tx_buf = (unsigned long)tbuf; tr.rx_buf = (unsigned long)rbuf; tr.len = len; tr.speed_hz = _spi_speed; //RF24_SPIDEV_SPEED; tr.delay_usecs = 0; tr.bits_per_word = RF24_SPIDEV_BITS; tr.cs_change = 0; int ret; ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) throw SPIException("can't send spi message"); /*{ perror("can't send spi message"); abort(); }*/ }
uint8_t *SPI::transfer( int len , uint8_t *txbuf) { struct spi_ioc_transfer send; uint8_t *rxbuf = new uint8_t[len]; send.tx_buf = (unsigned long)txbuf; send.rx_buf = (unsigned long)rxbuf; send.len = len; send.delay_usecs = this->delay_usecs; send.speed_hz = this->speed; send.bits_per_word = this->bits_per_word; send.cs_change = this->cs_change; errno = 0; int r = ioctl( this->fd, SPI_IOC_MESSAGE(1), &send ); printf("errno : %d\n", errno); if( r < 1 ) { delete(rxbuf); throw SPIException(string("SPI transfer error")); } return rxbuf; }
uint8_t SPI::transfer(uint8_t tx) { struct spi_ioc_transfer tr; memset(&tr, 0, sizeof(tr)); tr.tx_buf = (unsigned long)&tx; uint8_t rx; tr.rx_buf = (unsigned long)℞ tr.len = sizeof(tx); tr.speed_hz = _spi_speed; //RF24_SPIDEV_SPEED; tr.delay_usecs = 0; tr.bits_per_word = RF24_SPIDEV_BITS; tr.cs_change = 0; int ret; ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) throw SPIException("can't send spi message"); /*{ perror("can't send spi message"); abort(); }*/ return rx; }