______________________________________________________________________ > < > I2C driver v1.00 < > for < > PICos release 1.02 < > < > PICOS - Real-time kernel for PIC24/PIC30/PIC33 families < > < > < > www.picos18.com www.pragmatec.net < >______________________________________________________________________< This file contains all necessary informations to use properly the PIC MSSP I2C driver for PICos v1.00. Download the last PICos kernel version from www.picos18.com. ______________________________________________________________________ > < > I - Zip file content < >______________________________________________________________________< The drv_i2c zip file contains : - drv_i2c.c - drv_i2c.h : header file - drv_i2c.txt : this file To use the PICos I2C driver, first unzip the file. Place the C and H file in your project directory. This driver is supposed to be use with PICos and has been tested with MPLAB 7.30 and C30 v2.00. ______________________________________________________________________ > < > II - Hardware settings < >______________________________________________________________________< Adapt the I2CBRG according to the oscillator frequency to set the correct baud rate generator (file drv_i2c.c). // Baud rate setting for 400kHz I2C // I2CBRG = ( (Fcy/Fscl)-(Fcy/1 111 111) ) -1 // Fcy = 59MHz // Fscl = 100kHz => 590 - 53 - 1 = 536 I2CBRG = 536; Have a look at the PIC datasheet for different settings. ______________________________________________________________________ > < > III - TASCDESC settings (1) < >______________________________________________________________________< Update also the tascdesc.c file to take into account the new I2C task in your application : /********************************************************************** * ----------------------- TASK & STACK DEFINITION -------------------- **********************************************************************/ DeclareTask(TASK0); DeclareTask(I2C_Drv); ... u_int __attribute__((__section__(".stack_tsk0"))) stack0[DEFAULT_STACK_SIZE]; u_int __attribute__((__section__(".stack_tski2c"))) stack_i2c[DEFAULT_STACK_SIZE]; ... ______________________________________________________________________ > < > IV - TASCDESC settings (2) < >______________________________________________________________________< Finally add the task and alarm descriptor to the tascdesc.c file : ... , /******************************************************************* * -------------------------- Task I2C ------------------------------ *******************************************************************/ { SREG(stack_i2c), /* Stack_register */ FREG(stack_i2c), /* Frame_register */ I2C_Drv, /* StartAddress */ stack_i2c, /* StackAddress */ sizeof(stack_i2c), /* StackSize */ I2C_DRV_ID, /* TaskID */ DRV_I2C_PRIO, /* Priority */ NONE, /* EventWaited */ NONE, /* EventReceived */ READY, /* State */ EXTENDED, /* Type */ 0, /* Time */ NULL /* next */ }, ... AlarmObject Alarm_list[] = { /******************************************************************* * -------------------------- First task --------------------------- *******************************************************************/ { OFF, /* State */ 0, /* AlarmValue */ 0, /* Cycle */ &Counter_kernel, /* ptrCounter */ TASK0_ID, /* TaskID2Activate */ ALARM_EVENT, /* EventToPost */ 0 /* CallBack */ }, ..., /******************************************************************* * ---------------------- Alarm I2C task --------------------------- *******************************************************************/ { OFF, /* State */ 0, /* AlarmValue */ 0, /* Cycle */ &Counter_kernel, /* ptrCounter */ I2C_DRV_ID, /* TaskID2Activate */ TIMEOUT_EVENT, /* EventToPost */ 0 /* CallBack */ } }; Note : In the drv_i2c.c, adapt the I2C_TIMEOUT_ALARM definition in order to match with the above structure position. ______________________________________________________________________ > < > V - TASK Settings < >______________________________________________________________________< Open define.h and add this 3 definitions with correct value : #define I2C_NEW_MSG 0x02 #define TIMEOUT_EVENT 0x04 #define BUSERROR_EVENT 0x08 #define IDLE_EVENT 0x10 #define I2C_QUEUE_EMPTY 0x20 Note : this last define shoulb be different of any other defines in the application task. Modify it if you're already use the 0x20 value. #define I2C_DRV_ID 7 #define DRV_I2C_PRIO 12 The I2C task is considered like a driver, that means you have to give one of the highest priority to the I2C driver to let it run each time the I2C buffer is updated. ______________________________________________________________________ > < > VI - ISR connection < >______________________________________________________________________< No special ISR connection to do : direct mapping ______________________________________________________________________ > < > VII - I2C driver usage < >______________________________________________________________________< In the application task, include the driver header: #include "drv_i2c.h" And declare an I2C message (type message_t): message_t My_I2C_Message; In the task, set the I2C Message to match the specification of the target connected to the I2C bus. Have a look at the following example. See hereafter a basic example to acces an extenal EEPROM from the I2C bus: #include "define.h" #include "drv_i2c.h" /********************************************************************** * Definition dedicated to the local functions. **********************************************************************/ #define ALARM_TSK0 0 /********************************************************************** * ------------------------------ TASK0 ------------------------------- * * First task of the tutorial. * **********************************************************************/ TASK(TASK0) { I2C_message_t TC74_I2C; unsigned char Value; // R/W bit (LSB) and 7 bytes for the target address TC74_I2C.control = 0b11100000; // Sub address of the target (for EEPROM) TC74_I2C.addr_high = 0; TC74_I2C.addr_low = 0x00; // Buffer to receive data from TC74 TC74_I2C.ram_data = &Value; TC74_I2C.num_bytes = 1; // Option flags : short addr, SMBUS mode TC74_I2C.flags.long_addr = 0; TC74_I2C.flags.SMBus = 1; // Send the message to the I2C buffer I2C_enqMsg(&TC74_I2C); SetEvent(I2C_DRV_ID, I2C_NEW_MSG); // Wait for the answer from I2C driver // if data expected (read operation) WaitEvent(I2C_QUEUE_EMPTY); ClearEvent(I2C_QUEUE_EMPTY); // Data has been received in the EEPROM_value buffer // Call a function here to manage the EEPROM data // You can check the "TC74_I2C.error" field to check // if transfert is successfull or not. // If the target does not respond some time to time // you can use the automatic retry with the // "TC74_I2C.retry_counter" field. TerminateTask(); } ______________________________________________________________________ > < > VIII - Conclusion < >______________________________________________________________________< This I2C driver is provided from the PICos18 web site with other drivers dedicated to toher peripherals. Some zip files are also provided to be used with a driver. For instance a "TC74 temperature sensor" file should be delivered to get the temperature from this I2C chip. Do not hesitate to check periodicaly the www.picos18.com web site in order to download the last versions of PIC30 drivers for PICos. /* End of File : drv_i2c.txt */