int16_t Adafruit_ADXL345_Unified::read16(uint8_t reg) { if (_i2c) { Wire.beginTransmission(ADXL345_ADDRESS); i2cwrite(reg); Wire.endTransmission(); Wire.requestFrom(ADXL345_ADDRESS, 2); return (uint16_t)(i2cread() | (i2cread() << 8)); } else { reg |= 0x80 | 0x40; // read byte | multibyte digitalWrite(_cs, LOW); spixfer(_clk, _di, _do, reg); uint16_t reply = spixfer(_clk, _di, _do, 0xFF) | (spixfer(_clk, _di, _do, 0xFF) << 8); digitalWrite(_cs, HIGH); return reply; } }
void Adafruit_SSD1305::data(uint8_t c) { if (cs != -1) { // SPI of sorts digitalWrite(cs, HIGH); digitalWrite(dc, HIGH); if (sclk == -1) { #ifdef SPI_HAS_TRANSACTION SPI.beginTransaction(oledspi); #else SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(ADAFRUIT_SSD1305_SPI); #endif } digitalWrite(cs, LOW); spixfer(c); digitalWrite(cs, HIGH); #ifdef SPI_HAS_TRANSACTION if (sclk == -1) SPI.endTransaction(); // release the SPI bus #endif } else { // I2C uint8_t control = 0x40; // Co = 0, D/C = 1 Wire.beginTransmission(_i2caddr); Wire.write(control); Wire.write(c); Wire.endTransmission(); } }
uint8_t Adafruit_ADXL345_Unified::readRegister(uint8_t reg) { if (_i2c) { Wire.beginTransmission(ADXL345_ADDRESS); i2cwrite(reg); Wire.endTransmission(); Wire.requestFrom(ADXL345_ADDRESS, 1); return (i2cread()); } else { reg |= 0x80; // read byte digitalWrite(_cs, LOW); spixfer(_clk, _di, _do, reg); uint8_t reply = spixfer(_clk, _di, _do, 0xFF); digitalWrite(_cs, HIGH); return reply; } }
bool Adafruit_BluefruitLE_SPI::sendPacket(uint16_t command, const uint8_t* buf, uint8_t count, uint8_t more_data) { // flush old response before sending the new command if (more_data == 0) flush(); sdepMsgCommand_t msgCmd; msgCmd.header.msg_type = SDEP_MSGTYPE_COMMAND; msgCmd.header.cmd_id_high = highByte(command); msgCmd.header.cmd_id_low = lowByte(command); msgCmd.header.length = count; msgCmd.header.more_data = (count == SDEP_MAX_PACKETSIZE) ? more_data : 0; // Copy payload if ( buf != NULL && count > 0) memcpy(msgCmd.payload, buf, count); // Starting SPI transaction if (m_sck_pin == -1) SPI.beginTransaction(bluefruitSPI); SPI_CS_ENABLE(); TimeoutTimer tt(_timeout); // Bluefruit may not be ready while ( ( spixfer(msgCmd.header.msg_type) == SPI_IGNORED_BYTE ) && !tt.expired() ) { // Disable & Re-enable CS with a bit of delay for Bluefruit to ready itself SPI_CS_DISABLE(); delayMicroseconds(SPI_DEFAULT_DELAY_US); SPI_CS_ENABLE(); } bool result = !tt.expired(); if ( result ) { // transfer the rest of the data spixfer((void*) (((uint8_t*)&msgCmd) +1), sizeof(sdepMsgHeader_t)+count-1); } SPI_CS_DISABLE(); if (m_sck_pin == -1) SPI.endTransaction(); return result; }
void Adafruit_BluefruitLE_SPI::spixfer(void *buff, size_t len) { uint8_t *p = (uint8_t *)buff; while (len--) { p[0] = spixfer(p[0]); p++; } }
void Adafruit_LIS3DH::writeRegister8(uint8_t reg, uint8_t value) { if (_cs == -1) { Wire.beginTransmission((uint8_t)_i2caddr); Wire.write((uint8_t)reg); Wire.write((uint8_t)value); Wire.endTransmission(); } else { if (_sck == -1) SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); digitalWrite(_cs, LOW); spixfer(reg & ~0x80); // write, bit 7 low spixfer(value); digitalWrite(_cs, HIGH); if (_sck == -1) SPI.endTransaction(); // release the SPI bus } }
byte Adafruit_LSM9DS0::readBuffer(boolean type, byte reg, byte len, uint8_t *buffer) { byte address, _cs; if (type == GYROTYPE) { address = LSM9DS0_ADDRESS_GYRO; _cs = _csg; } else { address = LSM9DS0_ADDRESS_ACCELMAG; _cs = _csxm; } if (_i2c) { Wire.beginTransmission(address); Wire.write(reg); Wire.endTransmission(); Wire.requestFrom(address, (byte)len); // Wait around until enough data is available while (Wire.available() < len); for (uint8_t i=0; i<len; i++) { buffer[i] = Wire.read(); } Wire.endTransmission(); } else { if (_clk == -1) { SPCRback = SPCR; SPCR = mySPCR; } digitalWrite(_cs, LOW); // set address spixfer(reg | 0x80 | 0x40); // read multiple for (uint8_t i=0; i<len; i++) { buffer[i] = spixfer(0); } digitalWrite(_cs, HIGH); if (_clk == -1) { SPCR = SPCRback; } } return len; }
void mmc_clock_and_release(void) { uint8_t i; // SD cards require at least 8 final clocks for(i=0;i<10;i++) (void)spixfer(0xff); digitalWrite(SDSS,HIGH); // release CS }
uint8_t mmc_datatoken(void) { uint16_t i = 0xffff; uint8_t b = 0xff; while ((b != 0xfe) && (--i)) { b = spixfer(0xff); } return b; }
unsigned char SPI_Read(unsigned int addr) { unsigned char value; //data returned from spi transmission enablewiz(); // Activate the CS pin spiSend(WIZNET_READ_OPCODE); //Send Wiznet W5100 Write OpCode spiSend(addr >>8); // Send Wiznet W5100 Address High Byte spiSend(addr & 0x00FF); // Send Wiznet W5100 Address Low Byte value=spixfer(0xff); // Send Dummy transmission to read the data disablewiz(); // make CS pin inactive return(value); }
uint8_t Adafruit_LIS3DH::readRegister8(uint8_t reg) { uint8_t value; if (_cs == -1) { Wire.beginTransmission(_i2caddr); Wire.write((uint8_t)reg); Wire.endTransmission(); Wire.requestFrom(_i2caddr, 1); value = Wire.read(); } else { if (_sck == -1) SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); digitalWrite(_cs, LOW); spixfer(reg | 0x80); // read, bit 7 high value = spixfer(0); digitalWrite(_cs, HIGH); if (_sck == -1) SPI.endTransaction(); // release the SPI bus } return value; }
uint8_t mmc_get(void) { uint16_t i = 0xff; uint8_t b = 0xff; while ((b == 0xff) && (--i)) { b = spixfer(0xff); } if (b==0xff){ printf("\nmmc_get timeout\n"); } return b; }
int16_t Adafruit_CPlay_LIS3DH::readADC(uint8_t adc) { if ((adc < 1) || (adc > 3)) return 0; uint16_t value; adc--; uint8_t reg = LIS3DH_REG_OUTADC1_L + adc*2; if (_cs == -1) { // i2c Wire.beginTransmission(_i2caddr); Wire.write(reg | 0x80); // 0x80 for autoincrement Wire.endTransmission(); Wire.requestFrom(_i2caddr, 2); value = Wire.read(); value |= ((uint16_t)Wire.read()) << 8; } #ifndef __AVR_ATtiny85__ else { #if SPI_HAS_TRANSACTION if (_sck == -1) SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); #endif digitalWrite(_cs, LOW); spixfer(reg | 0x80 | 0x40); // read multiple, bit 7&6 high value = spixfer(); value |= ((uint16_t)spixfer()) << 8; digitalWrite(_cs, HIGH); #if SPI_HAS_TRANSACTION if (_sck == -1) SPI.endTransaction(); // release the SPI bus #endif } #endif return value; }
void Adafruit_CPlay_LIS3DH::writeRegister8(uint8_t reg, uint8_t value) { if (_cs == -1) { Wire.beginTransmission((uint8_t)_i2caddr); Wire.write((uint8_t)reg); Wire.write((uint8_t)value); Wire.endTransmission(); } #ifndef __AVR_ATtiny85__ else { #if SPI_HAS_TRANSACTION if (_sck == -1) SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); #endif digitalWrite(_cs, LOW); spixfer(reg & ~0x80); // write, bit 7 low spixfer(value); digitalWrite(_cs, HIGH); #if SPI_HAS_TRANSACTION if (_sck == -1) SPI.endTransaction(); // release the SPI bus #endif } #endif }
void Adafruit_CPlay_LIS3DH::read(void) { // read x y z at once if (_cs == -1) { // i2c Wire.beginTransmission(_i2caddr); Wire.write(LIS3DH_REG_OUT_X_L | 0x80); // 0x80 for autoincrement Wire.endTransmission(); Wire.requestFrom(_i2caddr, 6); x = Wire.read(); x |= ((uint16_t)Wire.read()) << 8; y = Wire.read(); y |= ((uint16_t)Wire.read()) << 8; z = Wire.read(); z |= ((uint16_t)Wire.read()) << 8; } #ifndef __AVR_ATtiny85__ else { #if SPI_HAS_TRANSACTION if (_sck == -1) SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); #endif digitalWrite(_cs, LOW); spixfer(LIS3DH_REG_OUT_X_L | 0x80 | 0x40); // read multiple, bit 7&6 high x = spixfer(); x |= ((uint16_t)spixfer()) << 8; y = spixfer(); y |= ((uint16_t)spixfer()) << 8; z = spixfer(); z |= ((uint16_t)spixfer()) << 8; digitalWrite(_cs, HIGH); #if SPI_HAS_TRANSACTION if (_sck == -1) SPI.endTransaction(); // release the SPI bus #endif } #endif uint8_t range = getRange(); uint16_t divider = 1; if (range == LIS3DH_RANGE_16_G) divider = 1365; if (range == LIS3DH_RANGE_8_G) divider = 4096; if (range == LIS3DH_RANGE_4_G) divider = 8190; if (range == LIS3DH_RANGE_2_G) divider = 16380; x_g = (float)x / divider; y_g = (float)y / divider; z_g = (float)z / divider; }
void Adafruit_SSD1325::display(void) { command(0x15); /* set column address */ command(0x00); /* set column start address */ command(0x3f); /* set column end address */ command(0x75); /* set row address */ command(0x00); /* set row start address */ command(0x3f); /* set row end address */ if (sclk == -1) { #ifdef SPI_HAS_TRANSACTION SPI.beginTransaction(oledspi); #else SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(ADAFRUIT_SSD1325_SPI); #endif } digitalWrite(cs, HIGH); digitalWrite(dc, HIGH); digitalWrite(cs, LOW); delay(1); for (uint16_t x=0; x<128; x+=2) { for (uint16_t y=0; y<64; y+=8) { // we write 8 pixels at once uint8_t left8 = buffer[y*16+x]; uint8_t right8 = buffer[y*16+x+1]; for (uint8_t p=0; p<8; p++) { uint8_t d = 0; if (left8 & (1 << p)) d |= 0xF0; if (right8 & (1 << p)) d |= 0x0F; spixfer(d); } } } digitalWrite(cs, HIGH); #ifdef SPI_HAS_TRANSACTION if (sclk == -1) SPI.endTransaction(); // release the SPI bus #endif }
void Adafruit_LIS3DH::read(void) { // read x y z at once if (_cs == -1) { // i2c Wire.beginTransmission(_i2caddr); Wire.write(LIS3DH_REG_OUT_X_L | 0x80); // 0x80 for autoincrement Wire.endTransmission(); Wire.requestFrom(_i2caddr, 6); x = Wire.read(); x |= ((uint16_t)Wire.read()) << 8; y = Wire.read(); y |= ((uint16_t)Wire.read()) << 8; z = Wire.read(); z |= ((uint16_t)Wire.read()) << 8; } else { if (_sck == -1) //SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); SPI.setBitOrder(MSBFIRST); SPI.setClockSpeed(500000); SPI.setDataMode(SPI_MODE0); digitalWrite(_cs, LOW); spixfer(LIS3DH_REG_OUT_X_L | 0x80 | 0x40); // read multiple, bit 7&6 high x = spixfer(); x |= ((uint16_t)spixfer()) << 8; y = spixfer(); y |= ((uint16_t)spixfer()) << 8; z = spixfer(); z |= ((uint16_t)spixfer()) << 8; digitalWrite(_cs, HIGH); if (_sck == -1) SPI.end(); // release the SPI bus } uint8_t range = getRange(); uint16_t divider = 1; if (range == LIS3DH_RANGE_16_G) divider = 2048; if (range == LIS3DH_RANGE_8_G) divider = 4096; if (range == LIS3DH_RANGE_4_G) divider = 8190; if (range == LIS3DH_RANGE_2_G) divider = 16380; x_g = (float)x / divider; y_g = (float)y / divider; z_g = (float)z / divider; }
void Adafruit_SSD1325::data(uint8_t c) { digitalWrite(cs, HIGH); digitalWrite(dc, HIGH); if (sclk == -1) { #ifdef SPI_HAS_TRANSACTION SPI.beginTransaction(oledspi); #else SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(ADAFRUIT_SSD1325_SPI); #endif } digitalWrite(cs, LOW); spixfer(c); digitalWrite(cs, HIGH); #ifdef SPI_HAS_TRANSACTION if (sclk == -1) SPI.endTransaction(); // release the SPI bus #endif }
void mmc_send_command(uint8_t command, uint16_t px, uint16_t py) { unsigned char x; //dummy to hold return value uint16_t pz; //temp to hold transmitted bottom byte of py; digitalWrite(SDSS,LOW); // enable CS printf(" sendcmd %x %x %x\n",command,px,py); x=spixfer(0xff); // dummy byte x=spixfer(command | 0x40); x=spixfer(px>>8); // high byte of param x x=spixfer(px&0xff); // low byte of param x x=spixfer(py>>8); // high byte of param y pz=py&0xff; printf("<%x,%x>",py,pz); x=spixfer(pz); // low byte of param y x=spixfer(0x95); // correct CRC for first command in SPI // after that CRC is ignored, so no problem with // always sending 0x95 x=spixfer(0xff); // ignore return byte }
bool Adafruit_BluefruitLE_SPI::getPacket(sdepMsgResponse_t* p_response) { sdepMsgHeader_t* p_header = &p_response->header; if (m_sck_pin == -1) SPI.beginTransaction(bluefruitSPI); SPI_CS_ENABLE(); TimeoutTimer tt(_timeout); // Bluefruit may not be ready while ( ( (p_header->msg_type = spixfer(0xff)) == SPI_IGNORED_BYTE ) && !tt.expired() ) { // Disable & Re-enable CS with a bit of delay for Bluefruit to ready itself SPI_CS_DISABLE(); delayMicroseconds(SPI_DEFAULT_DELAY_US); SPI_CS_ENABLE(); } bool result=false; // Not a loop, just a way to avoid goto with error handling do { if ( tt.expired() ) break; // Look for the header while ( p_header->msg_type != SDEP_MSGTYPE_RESPONSE && p_header->msg_type != SDEP_MSGTYPE_ERROR ) { p_header->msg_type = spixfer(0xff); } memset( (&p_header->msg_type)+1, 0xff, sizeof(sdepMsgHeader_t) - 1); spixfer((&p_header->msg_type)+1, sizeof(sdepMsgHeader_t) - 1); // Command is 16-bit at odd address, may have alignment issue with 32-bit chip uint16_t cmd_id = word(p_header->cmd_id_high, p_header->cmd_id_low); // Error Message Response if ( p_header->msg_type == SDEP_MSGTYPE_ERROR ) break; // Invalid command if (!(cmd_id == SDEP_CMDTYPE_AT_WRAPPER || cmd_id == SDEP_CMDTYPE_BLE_UARTTX || cmd_id == SDEP_CMDTYPE_BLE_UARTRX) ) { break; } // Invalid length if(p_header->length > SDEP_MAX_PACKETSIZE) break; // read payload memset(p_response->payload, 0xff, p_header->length); spixfer(p_response->payload, p_header->length); result = true; } while(0); SPI_CS_DISABLE(); if (m_sck_pin == -1) SPI.endTransaction(); return result; }
void Adafruit_SSD1305::display(void) { uint16_t i=0; uint8_t page; if (SSD1305_LCDHEIGHT == 64) page = 0; if (SSD1305_LCDHEIGHT == 32) page = 4; for(; page<8; page++) { command(SSD1305_SETPAGESTART + page); command(0x00); command(0x10); if (cs == -1) { // save I2C bitrate #ifndef __SAM3X8E__ uint8_t twbrbackup = TWBR; TWBR = 12; // upgrade to 400KHz! #endif //Serial.println(TWBR, DEC); //Serial.println(TWSR & 0x3, DEC); // I2C has max 16 bytes per xmision // send a bunch of data in one xmission for (uint8_t w=0; w<128/16; w++) { Wire.beginTransmission(_i2caddr); Wire.write(0x40); for (uint8_t x=0; x<16; x++) { Wire.write(buffer[i++]); } Wire.endTransmission(); } #ifndef __SAM3X8E__ TWBR = twbrbackup; #endif } else { // SPI if (sclk == -1) { #ifdef SPI_HAS_TRANSACTION SPI.beginTransaction(oledspi); #else SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(ADAFRUIT_SSD1305_SPI); #endif } digitalWrite(cs, HIGH); digitalWrite(dc, HIGH); digitalWrite(cs, LOW); for(uint8_t x=0; x<128; x++) { spixfer(buffer[i++]); } digitalWrite(cs, HIGH); #ifdef SPI_HAS_TRANSACTION if (sclk == -1) SPI.endTransaction(); // release the SPI bus #endif } } }
bool Adafruit_BluefruitLE_SPI::getPacket(sdepMsgResponse_t* p_response) { // Wait until IRQ is asserted, double timeout since some commands take long time to start responding TimeoutTimer tt(2*_timeout); while ( !digitalRead(m_irq_pin) ) { if (tt.expired()) return false; } sdepMsgHeader_t* p_header = &p_response->header; if (m_sck_pin == -1) SPI.beginTransaction(bluefruitSPI); SPI_CS_ENABLE(); tt.set(_timeout); do { if ( tt.expired() ) break; p_header->msg_type = spixfer(0xff); if (p_header->msg_type == SPI_IGNORED_BYTE) { // Bluefruit may not be ready // Disable & Re-enable CS with a bit of delay for Bluefruit to ready itself SPI_CS_DISABLE(); delayMicroseconds(SPI_DEFAULT_DELAY_US); SPI_CS_ENABLE(); } else if (p_header->msg_type == SPI_OVERREAD_BYTE) { // IRQ may not be pulled down by Bluefruit when returning all data in previous transfer. // This could happen when Arduino MCU is running at fast rate comparing to Bluefruit's MCU, // causing an SPI_OVERREAD_BYTE to be returned at stage. // // Walkaround: Disable & Re-enable CS with a bit of delay and keep waiting // TODO IRQ is supposed to be OFF then ON, it is better to use GPIO trigger interrupt. SPI_CS_DISABLE(); // wait for the clock to be enabled.. // while (!digitalRead(m_irq_pin)) { // if ( tt.expired() ) break; // } // if (!digitalRead(m_irq_pin)) break; delayMicroseconds(SPI_DEFAULT_DELAY_US); SPI_CS_ENABLE(); } } while (p_header->msg_type == SPI_IGNORED_BYTE || p_header->msg_type == SPI_OVERREAD_BYTE); bool result=false; // Not a loop, just a way to avoid goto with error handling do { // Look for the header // note that we should always get the right header at this point, and not doing so will really mess up things. // This whole loop isn't needed with my fix above.. while ( p_header->msg_type != SDEP_MSGTYPE_RESPONSE && p_header->msg_type != SDEP_MSGTYPE_ERROR && !tt.expired() ) { p_header->msg_type = spixfer(0xff); } if ( tt.expired() ) break; memset( (&p_header->msg_type)+1, 0xff, sizeof(sdepMsgHeader_t) - 1); spixfer((&p_header->msg_type)+1, sizeof(sdepMsgHeader_t) - 1); // Command is 16-bit at odd address, may have alignment issue with 32-bit chip uint16_t cmd_id = word(p_header->cmd_id_high, p_header->cmd_id_low); // Error Message Response if ( p_header->msg_type == SDEP_MSGTYPE_ERROR ) break; // Invalid command if (!(cmd_id == SDEP_CMDTYPE_AT_WRAPPER || cmd_id == SDEP_CMDTYPE_BLE_UARTTX || cmd_id == SDEP_CMDTYPE_BLE_UARTRX) ) { break; } // Invalid length if(p_header->length > SDEP_MAX_PACKETSIZE) break; // read payload memset(p_response->payload, 0xff, p_header->length); spixfer(p_response->payload, p_header->length); result = true; }while(0); SPI_CS_DISABLE(); if (m_sck_pin == -1) SPI.endTransaction(); return result; }