/*Requires Delay after call*/ uint8 MagReadByte(uint8 registerAddress, uint8 *readPtr) { /* Pointer to the register address */ //uint8 *writePtr = ®isterAddress;/* changed writeptr to ®isterAddress*/ uint8 i2c_status = I2C_MasterClearStatus(); //LCD_ClearDisplay(); LCD_Position(1,7); LCD_PrintInt8(i2c_status); I2C_MasterClearReadBuf(); I2C_MasterClearWriteBuf(); /* Start the I2C transmission for a read */ uint8 status = I2C_MasterWriteBuf(SLAVE_ADDRESS, ®isterAddress, 1, I2C_MODE_NO_STOP); /*wait for the tranmission to finish */ while (I2C_MasterStatus() && !I2C_MSTAT_WR_CMPLT){} /* Needed because of some bug in the psoc I2C tramission */ CyDelay(1); /* read a byte using I2C */ //return I2C_MasterReadBuf(SLAVE_ADDRESS, readPtr, 1, I2C_MODE_REPEAT_START); //or TO ENSURE READ IS COMPLETE BEFORE ADDITIONAL CODE EXECUTED status |= I2C_MasterReadBuf(SLAVE_ADDRESS,readPtr , 1, I2C_MODE_REPEAT_START); while (I2C_MasterStatus() && !I2C_MSTAT_RD_CMPLT){} CyDelay(1); //Needed because of some bug in the psoc I2C tramission return status; }
void RunNunchuck(void){ uint8 clear[] = {0x00}; uint8 buffer[16]; unsigned short wiichuck[7]; Err_LED_1_Write(0); Err_LED_2_Write(0); JoystickInit(); I2C_Start(); InitNunchuck(); for(;;) { I2C_MasterClearStatus(); CyDelay(1); I2C_MasterWriteBuf(0x52, clear, 1, I2C_MODE_COMPLETE_XFER); CyDelay(1); I2C_MasterWriteBuf(0x52, clear, 1, I2C_MODE_COMPLETE_XFER); CyDelay(1); I2C_MasterWriteBuf(0x52, clear, 1, I2C_MODE_COMPLETE_XFER); CyDelay(1); if (0u != (I2C_MasterStatus() & I2C_MSTAT_ERR_XFER)){ InitNunchuck(); }else{ I2C_MasterClearStatus(); CyDelay(1); I2C_MasterReadBuf(0x52, buffer, 6, I2C_MODE_COMPLETE_XFER); // Nunchuck data is 6 bytes, but for whatever reason, MEMOREX Wireless Nunchuck wants to send 8... CyDelay(1); if (0u != (I2C_MasterStatus() & I2C_MSTAT_ERR_XFER)){ InitNunchuck(); }else{ wiichuck[0] = buffer[1];// X Axis Joystick wiichuck[1] = buffer[0];// Y Axis Joystick wiichuck[2] = (((unsigned short) buffer[2]) << 2) + (((unsigned short) buffer[5]) & (3<<2)); // X Axis Accel wiichuck[3] = (((unsigned short) buffer[3]) << 2) + (((unsigned short) buffer[5]) & (3<<4)); // Y Axis Accel wiichuck[4] = (((unsigned short) buffer[4]) << 2) + (((unsigned short) buffer[5]) & (3<<6)); // Z Axis Accel wiichuck[5] = buffer[5] & (1 << 1) ? 0 : 1; //'C' Button wiichuck[6] = buffer[5] & (1 << 0) ? 0 : 1; //'Z' Button if(wiichuck[5]) JoystickOut(128,128); else JoystickOut(wiichuck[0],wiichuck[1]); } } Err_LED_2_Write(~Err_LED_2_Read()); CyDelay(100); } }
void InitNunchuck(){ uint8 init1[2] = {0xF0, 0x55}; uint8 init2[2] = {0xFB, 0x00}; uint8 finish = 0; Err_LED_1_Write(1); JoystickOut(128,128); while(finish==0){ I2C_MasterClearStatus(); I2C_MasterWriteBuf(0x52, init1, 2, I2C_MODE_COMPLETE_XFER); CyDelay(1); if (0u == (I2C_MasterStatus() & I2C_MSTAT_ERR_XFER)){ I2C_MasterClearStatus(); I2C_MasterWriteBuf(0x52, init2, 2, I2C_MODE_COMPLETE_XFER); CyDelay(1); if (0u == (I2C_MasterStatus() & I2C_MSTAT_ERR_XFER)){ finish = 1; } } CyDelay(100); } Err_LED_1_Write(0); }
/** * @brief Write multiple bytes of data to the MAG3110 in sequential memory * @details User supplies the register that the write will start on. User also supplues a buffer of data to write * to the MAG3110 and the size of the buffer as well. * * @param firstRegister Register the sequential write will start on * @param bufferPtr Pointer that points to the buffer of data to write * @param size umber of elements that are in the buffer * @return Error status of the function */ uint8 MagWriteMultipleBytes(uint8 firstRegister, uint8 *bufferPtr, uint8 size) { /* Create a new buffer that has that has the firstRegistsre as first element and the other elements as the data pointed to in bufferPtr */ uint8 i2c_status = I2C_MasterClearStatus(); //LCD_ClearDisplay(); LCD_Position(1,7); LCD_PrintInt8(i2c_status); I2C_MasterClearReadBuf(); I2C_MasterClearWriteBuf(); /* Pinter to the write buffer that will be written */ /* Set the first element of the buffer equal to the first register we will write to */ //*(Global_WritePtr) = firstRegister; /* Tranfers the data from the buffer that was passed to the function to the buffer that is to be written */ //uint8 i = 1; //for(i=1;i<=size;i++) //{ // *(Global_WritePtr+i) = bufferPtr[i-1]; //} /* Set the first element of the buffer equal to the first register we will write to */ uint8 j; for(j = size;j>0;j--) { bufferPtr[j] = bufferPtr[j-1]; } bufferPtr[0] = firstRegister; /* Write multiple bytes to the MAG3110 */ uint8 status = I2C_MasterWriteBuf(SLAVE_ADDRESS, bufferPtr, (size+1), I2C_MODE_COMPLETE_XFER); while (I2C_MasterStatus() && !I2C_MSTAT_WR_CMPLT){} /* Needed because of some bug in the psoc I2C tramission */ CyDelay(1); //functioncomplete_flag = 1;/*set Flag for write completion*/ return status; }
/* * @brief Write a byte to the MAG3110 * @details Takes a register address that we are going to write to and a byte of datat that we will write to the register * * @param registerAddress Address of the register on the MAG3110 * @param data Byte that will be written to the MAG3110 * * @return Error status of the function */ uint8 MagWriteByte(uint8 registerAddress, uint8 value) { //functioncomplete_flag = 0;/*set Flag for function Incomplete*/ I2C_MasterClearReadBuf(); I2C_MasterClearWriteBuf(); uint8 i2c_status = I2C_MasterClearStatus(); //LCD_ClearDisplay(); LCD_Position(1,7); LCD_PrintInt8(i2c_status); /* Buffer that holds the data to be written */ uint8 writeBuffer[2] = {registerAddress, value}; /* Pointer to the buffer that will be written */ uint8 *writePtr = writeBuffer; /* Write to MAG3110 */ uint8 status = I2C_MasterWriteBuf(SLAVE_ADDRESS, writePtr, 2, I2C_MODE_COMPLETE_XFER); /*Wait for transmission to finish*/ while (I2C_MasterStatus() && !I2C_MSTAT_WR_CMPLT){} CyDelay(1); //functioncomplete_flag = 1;/*set Flag for function complete*/ return status; }
/** Blocking sending data. * @param obj The i2c object * @param address 7-bit address (last bit is 0) * @param data The buffer for sending * @param length Number of bytes to wrte * @param stop Stop to be generated after the transfer is done * @return Number of written bytes */ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { if (!obj->initied) { CyGlobalIntEnable; I2C_Start(); obj->initied = 1; } int status = I2C_MasterWriteBuf(address, (uint8_t*)data, length, stop ? I2C_MODE_COMPLETE_XFER : I2C_MODE_NO_STOP); if (status != I2C_MSTR_NO_ERROR) { debug("mbed I2C write failed with err: %i\r\n",status); return 0; } int timeout = 100, to = 0; while ((I2C_MasterStatus() & (I2C_MSTAT_WR_CMPLT | I2C_MSTAT_ERR_XFER)) == 0 && to++ < timeout) { CyDelayUs(10); } if (I2C_MasterStatus() & I2C_MSTAT_ERR_XFER) { debug("i2c write failed with status: 0x%X\r\n",I2C_MasterStatus()); return 0; } if (to == timeout) { debug("I2C write timeout!\r\n"); return 0; } return length; }
/** * @brief Read multiple bytes from the MAG3110 * @details User supplies the register that we are going to read from and the buffer that we are going to place the data * that we read from the MAG3110. REQUIRES DELAY AFTER CALL * * @param registerAddress Address of the first register we are going to read * @param readPtr Pointer to the buffer that the data that we read will be placed * @param size Number of bytes that we are going to read from the MAG3110 * @return Error status of the function */ uint8 MagReadMultipleByte(uint8 registerAddress, uint8 *readPtr,uint8 size) { uint8 i2c_status = I2C_MasterClearStatus(); LCD_Position(1,7); LCD_PrintInt8(i2c_status); I2C_MasterClearReadBuf(); I2C_MasterClearWriteBuf(); /* We start by writng the slave address and the register we are going to start the rea from*/ uint8 status = I2C_MasterWriteBuf(SLAVE_ADDRESS, ®isterAddress, 1, I2C_MODE_NO_STOP); /*wait for the tranmission to finish */ while (I2C_MasterStatus() && !I2C_MSTAT_RD_CMPLT){} /* Needed because of some bug in the psoc I2C tramission */ CyDelay(1); /* read data from the MAG I2C */ //return I2C_MasterReadBuf(SLAVE_ADDRESS,readPtr , size, I2C_MODE_REPEAT_START); //or TO ENSURE READ IS COMPLETE BEFORE ADDITIONAL CODE EXECUTED status |= I2C_MasterReadBuf(SLAVE_ADDRESS,readPtr , size, I2C_MODE_REPEAT_START); while (I2C_MasterStatus() && !I2C_MSTAT_RD_CMPLT){} CyDelay(1); //Needed because of some bug in the psoc I2C tramission return status; }