Closed mangoalx closed 6 years ago
Uhm interesting. I will try with a Rpi, conceptually should be similar. I'll let you know.. Thanks
My suggestion to make it work with your code, is to try first with a very simple routine. Like getting just one byte back to the BB, then try with 2 or more bytes of a given value, so a very basic code. If that works, you can tell if it is a compatibility with the library or not.
I am using Hardwire library for a project to simulate an I2C slave device. The master will write a byte (register address) then read 1 word (content of the register). Anyway, the data trasferred is always 0x00nn, the second byte is 0 all the time. I wonder if I did anything wrong. I am using a beaglebone as the i2c master and using i2cget command to read data. i2cget -y 2 0x1c 5 w
define SLAVE_ADDRESS 0x1C //slave address,any number from 0x01 to 0x7F
define SLAVE_MASK 0x4 //This value is put in TWAMR, the bit will be ignored, so 0x1E will also
define REG_MAP_SIZE 18 //9 registers of 2 bytes data, last one Resolution is single byte, check later
define MAX_SENT_BYTES 3 //3 bytes can be written in - reg address, 2 bytes of data maximum
define MANUFACTUREID 0x0054
define DEVICEID 0X0400
define RFU 0x001F
const byte defaultReg[REG_MAP_SIZE] = {0x0,0x1F, //RFU 0x0,0x0, //config 0x0,0x0, //Tupper 0x0,0x0, //Tlower 0x0,0x0, //Tcrit 0x0,0x0, //Ta 0x0,0x54, //ManufactureID 0x04,0x0, //DeviceID 0x03,0x0 //Resolution, 1 byte, fill 0 the last byte };
const byte TaRegister=5; //no.5 register is Temperature ambient, will be used as default pointer value
/* Global Variables ***/
byte registerMap[REG_MAP_SIZE];
byte registerMapTemp[REG_MAP_SIZE];
byte receivedCommands[MAX_SENT_BYTES];
byte regPointer=TaRegister; //write only, to specify the register to access,default to Ta register byte dataReceived=0; //how many byte data received byte mapPointer=2*regPointer; //index for registerMap
include "commandline.h"
void setup()
{
for(byte i=0;i<REG_MAP_SIZE;i++) //copy deault data into registers registerMap[i]=defaultReg[i];
Wire.begin(SLAVE_ADDRESS); Wire.onRequest(requestEvent); Wire.onReceive(receiveEvent); }
void loop()
{ processDataReceved(); //Check if we received data to be written to registers if(getCommandLineFromSerialPort(CommandLine)) //global CommandLine is defined in CommandLine.h DoMyCommand(CommandLine); delay(1);
} //This handler needs to be short,there is just several uS to get ready for sending data. Maybe it holds the scl if not ready void requestEvent()
{
Wire.write(registerMap+regPointer*2, 2); //Send 2 bytes data only
}
//This handler needs to short, cause it hold the i2c until quit void receiveEvent(int bytesReceived)
{ //if only 1 byte is received, it is register address, put it into register pointer if(bytesReceived==1) regPointer=Wire.read();
else{ for (dataReceived = 0; dataReceived < bytesReceived && dataReceived<MAX_SENT_BYTES; dataReceived++)
// if we receive more data than allowed just throw it away, I just leave them un-read here, should not need to read the rest
// if only 1 byte received, this is the reg address, and a read operation is coming { regPointer = receivedCommands[0]; //if the reg address is valid, then set the pointer dataReceived = 0; //clear dataReceived, no more process is needed } }
}
void processDataReceved(void) { if(dataReceived != 0){ int i = receivedCommands[0]; if (i>0 && i<5 && dataReceived == 3) { //Register 1 to 4 registerMap[i2]=receivedCommands[1]; registerMap[i2+1]=receivedCommands[2]; } else if (i==8 && dataReceived == 2) { registerMap[i*2]=receivedCommands[1]; //Register 8 resolution, 1 byte } dataReceived=0; //Clear dataReceived } }