void event_i2c_abuse_test(void) { if (i2c_idle(&I2C_ABUSE_PORT)) { LED_ON(5); // green = idle LED_OFF(4); } else { LED_ON(4); // red = busy LED_OFF(5); } // Wait for I2C transaction object to be released by the I2C driver before changing anything if ((i2c_abuse_test_counter < 12) && (i2c_abuse_test_counter > 3)) { if ((i2c_test2.status == I2CTransFailed) || (i2c_test2.status == I2CTransSuccess)) { //i2c_test2.slave_addr = 0x90; i2c_test2.type = I2CTransRx; i2c_test2.slave_addr = 0x92; i2c_test2.len_r = 2; i2c_submit(&I2C_ABUSE_PORT,&i2c_test2); } } if ((i2c_test1.status == I2CTransFailed) || (i2c_test1.status == I2CTransSuccess)) { if (i2c_abuse_test_counter < 16) { i2c_abuse_test_counter++; } else { // wait until ready: if (i2c_idle(&I2C_ABUSE_PORT)) { i2c_abuse_test_counter = 1; i2c_setbitrate(&I2C_ABUSE_PORT, i2c_abuse_test_bitrate); i2c_abuse_test_bitrate += 17000; if (i2c_abuse_test_bitrate > 410000) { i2c_abuse_test_bitrate -= 410000; } } } if (i2c_abuse_test_counter < 16) { RunOnceEvery(100,LED_TOGGLE(I2C_ABUSE_LED)); i2c_abuse_send_transaction( i2c_abuse_test_counter ); } } }
void i2c_setbitrate(struct i2c_periph *periph, int bitrate) { if (i2c_idle(periph)) { if (periph == &i2c2) { I2C2_InitStruct.I2C_ClockSpeed = bitrate; I2C_Init(I2C2, i2c2.init_struct); } #ifdef I2C_DEBUG_LED __disable_irq(); LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); __enable_irq(); #endif } }
void i2c_write(unsigned char data) { // Send the Data to I2C Bus SSPBUF = data; if (SSPCON1bits.WCOL) // Check for write collision return; while(SSPSTATbits.BF); // Wait until write cycle is complete i2c_idle(); // Ensure the I2C module is idle }
unsigned char i2c_read(void) { // Ensure the I2C module is idle i2c_idle(); // Enable Receive Mode SSPCON2bits.RCEN = 1; // Enable master for 1 byte reception while(!SSPSTATbits.BF); // Wait until buffer is full return(SSPBUF); }
void i2c_start(unsigned char stype) { i2c_idle(); // Ensure the I2C module is idle if (stype == I2C_START_CMD) { SSPCON2bits.SEN = 1; // Start I2C Transmission while(SSPCON2bits.SEN); } else { SSPCON2bits.RSEN = 1; // ReStart I2C Transmission while(SSPCON2bits.RSEN); } }
void baro_periodic(void) { // check i2c_done if (!i2c_idle(&i2c2)) { return; } switch (baro_board.status) { case LBS_UNINITIALIZED: baro_board_send_reset(); baro_board.status = LBS_RESETED; break; case LBS_RESETED: baro_board_send_config_abs(); baro_board.status = LBS_INITIALIZING_ABS; break; case LBS_INITIALIZING_ABS: baro_board_set_current_register(BARO_ABS_ADDR, 0x00); baro_board.status = LBS_INITIALIZING_ABS_1; break; case LBS_INITIALIZING_ABS_1: baro_board_send_config_diff(); baro_board.status = LBS_INITIALIZING_DIFF; break; case LBS_INITIALIZING_DIFF: baro_board_set_current_register(BARO_DIFF_ADDR, 0x00); baro_board.status = LBS_INITIALIZING_DIFF_1; // baro_board.status = LBS_UNINITIALIZED; break; case LBS_INITIALIZING_DIFF_1: baro_board.running = true; /* Falls through. */ case LBS_READ_DIFF: baro_board_read_from_current_register(BARO_ABS_ADDR); baro_board.status = LBS_READING_ABS; break; case LBS_READ_ABS: baro_board_read_from_current_register(BARO_DIFF_ADDR); baro_board.status = LBS_READING_DIFF; break; default: break; } #ifdef BARO_LED if (baro_board.running == TRUE) { LED_ON(BARO_LED); } else { LED_TOGGLE(BARO_LED); } #endif }
void baro_periodic(void) { // check i2c_done if (!i2c_idle(&i2c2)) return; switch (baro_board.status) { case LBS_UNINITIALIZED: baro_board_send_reset(); baro_board.status = LBS_RESETED; break; case LBS_RESETED: baro_board_send_config_abs(); baro_board.status = LBS_INITIALIZING_ABS; break; case LBS_INITIALIZING_ABS: baro_board_set_current_register(BARO_ABS_ADDR, 0x00); baro_board.status = LBS_INITIALIZING_ABS_1; break; case LBS_INITIALIZING_ABS_1: baro_board_send_config_diff(); baro_board.status = LBS_INITIALIZING_DIFF; break; case LBS_INITIALIZING_DIFF: baro_board_set_current_register(BARO_DIFF_ADDR, 0x00); baro_board.status = LBS_INITIALIZING_DIFF_1; // baro_board.status = LBS_UNINITIALIZED; break; case LBS_INITIALIZING_DIFF_1: baro.status = BS_RUNNING; case LBS_READ_DIFF: baro_board_read_from_current_register(BARO_ABS_ADDR); baro_board.status = LBS_READING_ABS; //LED_TOGGLE(6); break; case LBS_READ_ABS: baro_board_read_from_current_register(BARO_DIFF_ADDR); baro_board.status = LBS_READING_DIFF; LED_TOGGLE(6); break; default: break; } }
void hmc5843_idle_task(void) { if (hmc5843.i2c_trans.status == I2CTransFailed) { hmc5843.sent_tx = 0; hmc5843.sent_rx = 0; } if (hmc5843.i2c_trans.status == I2CTransRunning || hmc5843.i2c_trans.status == I2CTransPending) { return; } if (hmc5843.initialized && mag_eoc() && !hmc5843.sent_tx && !hmc5843.sent_rx) { if (HMC5843_I2C_DEV.status == I2CIdle && i2c_idle(&HMC5843_I2C_DEV)) { hmc5843.i2c_trans.type = I2CTransTx; hmc5843.i2c_trans.len_w = 1; hmc5843.i2c_trans.buf[0] = 0x3; i2c_submit(&HMC5843_I2C_DEV, &hmc5843.i2c_trans); hmc5843.sent_tx = 1; return; } } if (hmc5843.sent_tx) { hmc5843.i2c_trans.type = I2CTransRx; hmc5843.i2c_trans.len_r = 6; hmc5843.i2c_trans.len_w = 1; hmc5843.i2c_trans.buf[0] = 0x3; i2c_submit(&HMC5843_I2C_DEV, &hmc5843.i2c_trans); hmc5843.sent_rx = 1; hmc5843.sent_tx = 0; return; } if (hmc5843.sent_rx && hmc5843.i2c_trans.status == I2CTransSuccess) { hmc5843.sent_rx = 0; hmc5843.sent_tx = 0; hmc5843.timeout = 0; hmc5843.data_available = TRUE; memcpy(hmc5843.data.buf, (const void *) hmc5843.i2c_trans.buf, 6); for (int i = 0; i < 3; i++) { hmc5843.data.value[i] = bswap_16(hmc5843.data.value[i]); } } }
void hmc5843_idle_task(void) { if (hmc5843.initialized && hmc5843.ready_for_read && (hmc5843.i2c_trans.status == I2CTransSuccess || hmc5843.i2c_trans.status == I2CTransFailed)) { if (i2c2.status == I2CIdle && i2c_idle(&i2c2)) { hmc5843.i2c_trans.type = I2CTransRx; hmc5843.i2c_trans.len_r = 7; i2c_submit(&i2c2, &hmc5843.i2c_trans); hmc5843.reading = TRUE; hmc5843.ready_for_read = FALSE; } } if (hmc5843.reading && hmc5843.i2c_trans.status == I2CTransSuccess) { hmc5843.timeout = 0; hmc5843.data_available = TRUE; hmc5843.reading = FALSE; memcpy(hmc5843.data.buf, (const void *) hmc5843.i2c_trans.buf, 6); for (int i = 0; i < 3; i++) { hmc5843.data.value[i] = bswap_16(hmc5843.data.value[i]); } } }
void baro_periodic(void) { // check that nothing is in progress if (baro_trans.status == I2CTransPending) return; if (baro_trans.status == I2CTransRunning) return; if (!i2c_idle(&i2c2)) return; switch (baro_board.status) { case LBS_UNINITIALIZED: baro_board_send_reset(); baro_board.status = LBS_REQUEST; baro.status = BS_RUNNING; break; case LBS_REQUEST: bmp085_request_pressure(); baro_board.status = LBS_READ; break; case LBS_READ: if (baro_eoc()) { bmp085_read_pressure(); baro_board.status = LBS_READING; } break; case LBS_REQUEST_TEMP: bmp085_request_temp(); baro_board.status = LBS_READ_TEMP; break; case LBS_READ_TEMP: if (baro_eoc()) { bmp085_read_temp(); baro_board.status = LBS_READING_TEMP; } break; default: break; } }
void hmc5843_periodic(void) { if (!hmc5843.initialized) { send_config(); hmc5843.initialized = TRUE; } else if (hmc5843.timeout++ > HMC5843_TIMEOUT && HMC5843_I2C_DEV.status == I2CIdle && i2c_idle(&HMC5843_I2C_DEV)) { #ifdef USE_HMC59843_ARCH_RESET hmc5843_arch_reset(); #endif hmc5843.i2c_trans.type = I2CTransTx; hmc5843.i2c_trans.len_w = 1; hmc5843.i2c_trans.buf[0] = 0x3; i2c_submit(&HMC5843_I2C_DEV, &hmc5843.i2c_trans); while (hmc5843.i2c_trans.status == I2CTransPending || hmc5843.i2c_trans.status == I2CTransRunning); hmc5843.i2c_trans.type = I2CTransRx; hmc5843.i2c_trans.len_r = 6; i2c_submit(&HMC5843_I2C_DEV, &hmc5843.i2c_trans); while (hmc5843.i2c_trans.status == I2CTransPending || hmc5843.i2c_trans.status == I2CTransRunning); hmc5843.timeout = 0; } #ifdef HMC5843_NO_IRQ // < 50Hz fake_mag_eoc = 1; #endif }
void i2c_setbitrate(struct i2c_periph *periph, int bitrate) { // If NOT Busy if (i2c_idle(periph)) { volatile int devider; volatile int risetime; uint32_t i2c = (uint32_t) periph->reg_addr; /***************************************************** Bitrate: -CR2 + CCR + TRISE registers -only change when PE=0 e.g. 10kHz: 36MHz + Standard 0x708 + 0x25 70kHz: 36MHz + Standard 0x101 + 400kHz: 36MHz + Fast 0x1E + 0xb // 1) Program peripheral input clock CR2: to get correct timings // 2) Configure clock control registers // 3) Configure rise time register ******************************************************/ if (bitrate < 3000) bitrate = 3000; // rcc_ppre1_frequency is normally configured to max: 36MHz on F1 and 42MHz on F4 // in fast mode: 2counts low 1 count high -> / 3: // in standard mode: 1 count low, 1 count high -> /2: devider = (rcc_ppre1_frequency/2000) / (bitrate/1000); // never allow faster than 600kbps if (devider < 20) devider = 20; // no overflow either if (devider >=4095) devider = 4095; // risetime can be up to 1/6th of the period risetime = 1000000 / (bitrate/1000) / 6 / 28; if (risetime < 10) risetime = 10; // more will overflow the register: for more you should lower the FREQ if (risetime >=31) risetime = 31; // we do not expect an interrupt as the interface should have been idle, but just in case... __disable_irq(); // this code is in user space: // CCR can only be written when PE is disabled // p731 note 5 i2c_peripheral_disable(i2c); // 1) #ifdef STM32F1 i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_36MHZ); #else // STM32F4 i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_42MHZ); #endif // 2) //i2c_set_fast_mode(i2c); i2c_set_ccr(i2c, devider); // 3) i2c_set_trise(i2c, risetime); // Re-Enable i2c_peripheral_enable(i2c); __enable_irq(); #ifdef I2C_DEBUG_LED __disable_irq(); // this code is in user space: LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); __enable_irq(); #endif } }
/******************************************************************************* * PRIVATE FUNCTION: uc_i2c_write * * PARAMETERS: * ~ uc_slave_address - The I2C slave address. * ~ uc_register_add - The register address that we want to write. * ~ uc_data - The data that we want to write. * * RETURN: * ~ void * * DESCRIPTIONS: * This function will write a single byte of data using the I2C. * *******************************************************************************/ void uc_i2c_write(unsigned char uc_slave_address, unsigned char uc_register_add, unsigned char uc_data) { // Clear the error flag before we start a new I2C operation. b_i2c_error_flag = 0; // Send start bit. SSPCON2bits.SEN = 1; while (SSPCON2bits.SEN == 1); // Send slave address and indicate to write. SSPBUF = (uc_slave_address << 1) & 0xfe; // Wait for slave to acknowledge. //while (SSPSTATbits.R_W == 1); i2c_idle(); //wait for the message sending process complete // If slave does not acknowledge... if (SSPCON2bits.ACKSTAT == 1) { // Send stop bit. SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Set the error flag and exit. b_i2c_error_flag = 1; return; } // Send the register address that we want to write. SSPBUF = uc_register_add; // Wait for slave to acknowledge. //while (SSPSTATbits.R_W == 1); i2c_idle(); //wait for the message sending process complete // If slave does not acknowledge... if (SSPCON2bits.ACKSTAT == 1) { // Send stop bit. SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Set the error flag and exit. b_i2c_error_flag = 1; return; } // Send the data. SSPBUF = uc_data; // Wait for slave to acknowledge. //while (SSPSTATbits.R_W == 1); i2c_idle(); //wait for the message sending process complete // If slave does not acknowledge... if (SSPCON2bits.ACKSTAT == 1) { // Send stop bit. SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Set the error flag and exit. b_i2c_error_flag = 1; return; } // Send stop bit SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Clear the error flag. b_i2c_error_flag = 0; }
void i2c_setbitrate(struct i2c_periph *periph, int bitrate) { // If NOT Busy if (i2c_idle(periph)) { volatile int devider; volatile int risetime; uint32_t i2c = (uint32_t) periph->reg_addr; /***************************************************** Bitrate: -CR2 + CCR + TRISE registers -only change when PE=0 e.g. 10kHz: 36MHz + Standard 0x708 + 0x25 70kHz: 36MHz + Standard 0x101 + 400kHz: 36MHz + Fast 0x1E + 0xb // 1) Program peripheral input clock CR2: to get correct timings // 2) Configure clock control registers // 3) Configure rise time register ******************************************************/ if (bitrate < 3000) bitrate = 3000; // 36MHz, fast scl: 2counts low 1 count high -> / 3: devider = 18000 / (bitrate/1000); // never allow faster than 600kbps if (devider < 20) devider = 20; // no overflow either if (devider >=4095) devider = 4095; // risetime can be up to 1/6th of the period risetime = 1000000 / (bitrate/1000) / 6 / 28; if (risetime < 10) risetime = 10; // more will overflow the register: for more you should lower the FREQ if (risetime >=31) risetime = 31; // we do not expect an interrupt as the interface should have been idle, but just in case... __disable_irq(); // this code is in user space: // CCR can only be written when PE is disabled // p731 note 5 I2C_CR1(i2c) &= ~ I2C_CR1_PE; // 1) I2C_CR2(i2c) = 0x0324; // 2) //I2C_CCR(i2c) = 0x8000 + devider; I2C_CCR(i2c) = 0x0000 + devider; // 3) I2C_TRISE(i2c) = risetime; // Re-Enable I2C_CR1(i2c) |= I2C_CR1_PE; __enable_irq(); #ifdef I2C_DEBUG_LED __disable_irq(); // this code is in user space: LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); __enable_irq(); #endif } }
void i2c_event(void) { static uint32_t cnt = 0; //I2C_TypeDef *regs; cnt++; if (cnt > 10000) cnt = 0; #ifndef I2C_DEBUG_LED #ifdef USE_I2C1 if (i2c1.status == I2CIdle) { if (i2c_idle(&i2c1)) { __disable_irq(); // More work to do if (i2c1.trans_extract_idx != i2c1.trans_insert_idx) { // Restart transaction doing the Rx part now PPRZ_I2C_SEND_START(&i2c1); } __enable_irq(); } } #endif #endif #ifdef USE_I2C2 #ifdef I2C_DEBUG_LED if (cnt == 0) { __disable_irq(); LED2_ON(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); if (i2c2.status == I2CIdle) { LED1_ON(); LED1_OFF(); } else if (i2c2.status == I2CStartRequested) { LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); } LED2_OFF(); //regs = (I2C_TypeDef *) i2c2.reg_addr; //LED_SHOW_ACTIVE_BITS(regs); __enable_irq(); } #endif //if (i2c2.status == I2CIdle) { //if (i2c_idle(&i2c2)) { //__disable_irq(); // More work to do //if (i2c2.trans_extract_idx != i2c2.trans_insert_idx) { // Restart transaction doing the Rx part now //PPRZ_I2C_SEND_START(&i2c2); } //__enable_irq(); } } #endif }
void main(void) { const unsigned char *mas="\r\n---------------MASTER DEVICE-----------------\r\n"; const unsigned char * arr1 = "\r\nTaking in the text \r\n"; const unsigned char *arr2="\r\nEnter your choice \r\n 1.Slave 1(Address:0xAA\r\n2.Slave 2(Address:0xBB)\r\n3.Slave 3(Address:0xCC\r\n"; const unsigned char *arr3= "You have entered:\r\n"; const unsigned char *arr4= "\r\nUART Initialised\r\n"; const unsigned char *arr5= "\r\nI2C initialised:\r\n"; const unsigned char *msg1="\r\nSending to Slave 1 (Address 0xAA)\r\n"; const unsigned char *msg2="\r\nSending to Slave 2 (Address 0xBB)\r\n"; const unsigned char *msg3="\r\nSending to Slave 3 (Address 0xCC)\r\n"; const unsigned char *msg4="\r\nAddress sent\r\n"; const unsigned char *msg5="\r\nData sent\r\n"; const unsigned char *err="\r\nNo message will be sent since no slave no entered\r\n"; const unsigned char *fin="\r\nClosing Communication!\r\n"; const unsigned char *msgm="\r\nYou have entered choice number:\r\n"; unsigned char choice; OSCCONbits.IRCF = 0x07; // Configure Internal OSC for 8MHz Clock while(!OSCCONbits.HTS); // Wait Until Internal Osc is Stable INTCON=0; // purpose of disabling the interrupts. UART_Init(baud_rate); UART_Write_Text(mas); UART_Write_Text(arr4); delay_ms(500); I2C_init(); UART_Write_Text(arr5); //Initialisation done while(1) { UART_Write_Text(arr1); i2c_idle(); //receive the characters until ENTER is pressed (ASCII for ENTER = 13) is=UART_Read_Text(); UART_Write_Text(arr3); UART_Write_Text(is); UART_Write_Text(arr2); choice=UART_Read(); UART_Write_Text(msgm); UART_Write(choice); switch(choice) { case 0x31: { UART_Write_Text(msg1); I2C_Start(); if(I2C_address_send())//device address { delay_us(20);//clock settle and then send I2C_Write_Text(is); } else break; I2C_Stop(); break; } case 0x32: { UART_Write_Text(msg2); I2C_Start(); if(I2C_address_send1())//device address { delay_us(20);//clock settle and then send I2C_Write_Text(is); } else break; I2C_Stop(); break; } case 0x33: { UART_Write_Text(msg3); I2C_Start(); if(I2C_address_send2())//device address { delay_us(20);//clock settle and then send I2C_Write_Text(is); } else break; I2C_Stop(); break; } default: UART_Write_Text(err); break; } //Choice entered data sent respectively to slaves now stop //i2c_SendAcknowledge(I2C_LAST); PIR1bits.SSPIF = 0; UART_Write_Text(fin); } }
/******************************************************************************* * PUBLIC FUNCTION: uc_i2c_read * * PARAMETERS: * ~ uc_slave_address - The I2C slave address. * ~ uc_register - The register that we want to read. * * RETURN: * ~ The data that we read from the I2C. * * DESCRIPTIONS: * This function will read a single byte of data using the I2C. * *******************************************************************************/ unsigned char uc_i2c_read(unsigned char uc_slave_address, unsigned char uc_register_add) { // Buffer for the received byte. unsigned char uc_received_byte; unsigned long count = 10000; // Clear the error flag before we start a new I2C operation. b_i2c_error_flag = 0; // Send start bit. SSPCON2bits.SEN = 1; while (SSPCON2bits.SEN == 1); // Send slave address and indicate to write. SSPBUF = (uc_slave_address << 1) & 0xfe; // Wait for slave to acknowledge. //while (SSPSTATbits.R_W == 1); i2c_idle(); //wait for the message sending process complete // If slave does not acknowledge... if (SSPCON2bits.ACKSTAT == 1) { // Send stop bit. SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Set the error flag and exit. b_i2c_error_flag = 1; return 0; } // Send the register address that we want to read and I2C will start transmitting out SSPBUF = uc_register_add; // Wait for slave to acknowledge. //while (SSPSTATbits.R_W == 1); i2c_idle(); //wait for the message sending process complete // If slave does not acknowledge... if (SSPCON2bits.ACKSTAT == 1) { // Send stop bit. SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Set the error flag and exit. b_i2c_error_flag = 1; return 0; } // Send repeated start bit. SSPCON2bits.RSEN = 1; while (SSPCON2bits.RSEN == 1); // Send slave address and indicate to read. SSPBUF = (uc_slave_address << 1) | 0x01; // Wait for slave to acknowledge. //while (SSPSTATbits.R_W == 1); i2c_idle(); //wait for the message sending process complete // If slave does not acknowledge... if (SSPCON2bits.ACKSTAT == 1) { // Send stop bit. SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Set the error flag and exit. b_i2c_error_flag = 1; return 0; } // Enable receive. SSPCON2bits.RCEN = 1; // Wait until the data is received. while (SSPSTATbits.BF == 0) { // If timeout... if (--count == 0) { // Send stop bit. SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Set the error flag and exit. b_i2c_error_flag = 1; return 0; } } // Read the received data. uc_received_byte = SSPBUF; // Send Not Acknowledge. SSPCON2bits.ACKDT = 1; SSPCON2bits.ACKEN = 1; while (SSPCON2bits.ACKEN == 1); // Send stop bit SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN == 1); // Clear the error flag and return the received data. b_i2c_error_flag = 0; return uc_received_byte; }