[abe0cdb1] | 1 | # |
---|
| 2 | # $Id$ |
---|
| 3 | # |
---|
| 4 | |
---|
| 5 | ===================== |
---|
| 6 | Copyright and License |
---|
| 7 | ===================== |
---|
| 8 | |
---|
| 9 | For Copyright and License of the source code, see the header in |
---|
| 10 | libi2c.c. |
---|
| 11 | |
---|
| 12 | ========= |
---|
| 13 | Overview |
---|
| 14 | ======== |
---|
| 15 | |
---|
| 16 | This directory contains a general I2C/SPI API library. It offers a |
---|
| 17 | standard API to I2C or SPI based device drivers, abstracting the low |
---|
| 18 | level driver (dealing with the I2C/SPI controller hardware of the |
---|
| 19 | board) from the high-level drivers (dealing with devices connected to |
---|
| 20 | the I2C or SPI bus). |
---|
| 21 | |
---|
| 22 | In most cases throughout this document, i2c and spi devices are |
---|
| 23 | handled in a similar way. Therefore spi will not be explicitly named |
---|
| 24 | in every location. |
---|
| 25 | |
---|
| 26 | ========= |
---|
| 27 | Features |
---|
| 28 | ========= |
---|
| 29 | |
---|
| 30 | + supports multiple i2c and/or spi busses |
---|
| 31 | |
---|
| 32 | + supports multiple devices connected to each i2c/spi bus |
---|
| 33 | |
---|
| 34 | + handles bus and device registration to the I/O manager |
---|
| 35 | |
---|
| 36 | ========= |
---|
| 37 | Structure |
---|
| 38 | ========= |
---|
| 39 | |
---|
| 40 | This library defines a layered API to i2c and spi devices. The |
---|
| 41 | layering is: |
---|
| 42 | |
---|
[797c232] | 43 | +----------------------------------------+ |
---|
| 44 | 6| Application | |
---|
| 45 | +----------------------------------------+ |
---|
| 46 | 5| RTEMS I/O Manager | |
---|
| 47 | +----------------------------------------+ |
---|
| 48 | 4|** libi2c OS adaption layer **| |
---|
| 49 | +----------------------------------------+ |
---|
| 50 | 3| high level i2c device driver | |
---|
| 51 | | (EEPROM, RTC, ...) | |
---|
| 52 | | (e.g. in c/src/libchip/i2c) | |
---|
| 53 | +----------------------------------------+ |
---|
| 54 | 2|** libi2c low level abstraction layer **| |
---|
| 55 | +----------------------------------------+ |
---|
| 56 | 1| i2c controller driver | |
---|
| 57 | | (in BSP) | |
---|
| 58 | +----------------------------------------+ |
---|
[abe0cdb1] | 59 | |
---|
| 60 | This document will describe the following interfaces in separate |
---|
| 61 | sections: |
---|
| 62 | |
---|
| 63 | + the interface between the RTEMS I/O Manager and the libi2c OS |
---|
| 64 | interface (5<->4) |
---|
| 65 | |
---|
| 66 | + the interface between the libi2c OS interface and the high level |
---|
| 67 | i2c device driver (4<->3) |
---|
| 68 | |
---|
| 69 | + the interface between the high level i2c device driver and the |
---|
| 70 | libi2c low level abstraction layer (3<->2) |
---|
| 71 | |
---|
| 72 | + the interface between the libi2c low level abstraction layer and |
---|
| 73 | the i2c controller driver (2<->1) |
---|
| 74 | |
---|
[c47890c] | 75 | =================================== |
---|
| 76 | Differences between i2c and spi bus |
---|
| 77 | =================================== |
---|
| 78 | SPI and I2C has many similarities, but also some differences: |
---|
| 79 | |
---|
| 80 | - I2C uses inband addressing (the first bits sent select, which slave |
---|
| 81 | device is addressed) while SPI uses dedicated select lines to address |
---|
| 82 | a slave device |
---|
| 83 | |
---|
| 84 | - SPI supports combined full duplex read-write transactions while I2C |
---|
| 85 | either sends or receives data from a slave device |
---|
| 86 | |
---|
| 87 | - SPI supports a varity of per-slave options, which include: |
---|
| 88 | - number of bits per character to transfer |
---|
| 89 | - polarity and phase of clock wrt data |
---|
| 90 | - clock frequency |
---|
| 91 | |
---|
| 92 | The libi2c API defines a superset of functions to handle both flavours |
---|
| 93 | of serial data transmission, but care should be taken not to use |
---|
| 94 | features dedicated to the wrong type of serial bus. |
---|
| 95 | |
---|
[abe0cdb1] | 96 | |
---|
| 97 | ====================== |
---|
| 98 | Library Initialization |
---|
| 99 | ====================== |
---|
| 100 | Before any libi2c API is used, the library must be initialized. This |
---|
| 101 | is achived with a call to function |
---|
| 102 | |
---|
| 103 | rtems_libi2c_initialize (). |
---|
| 104 | |
---|
| 105 | It creates a global mutex to lock internal data structures and |
---|
| 106 | registers the OS adaption layer to the RTEMS I/O manager. |
---|
| 107 | |
---|
| 108 | Any subsequent call to this function will be silently ignored. |
---|
| 109 | |
---|
| 110 | Typically the BSP startup code will perform this initialization. |
---|
| 111 | |
---|
[d2ff24c2] | 112 | A proper place for initializing the i2c layer and populating it |
---|
| 113 | with busses and device drivers (see 'Bus Registration' and |
---|
| 114 | 'Device/Driver Registration' below) is the 'predriver_hook' |
---|
| 115 | where most facilities (such as malloc, libio) are already |
---|
| 116 | available. Note, however, that 'stdio' is not yet functional |
---|
| 117 | at this point and all i2c bus and device drivers should carefully |
---|
| 118 | avoid using stdio so that other drivers which may build on top |
---|
| 119 | of i2c devices may be initialized properly (this may happen |
---|
| 120 | just after 'predriver_hook' when stdio is still not available). |
---|
| 121 | E.g., drivers listed in the configuration table are initialized |
---|
| 122 | during this step. |
---|
| 123 | |
---|
| 124 | Note that while 'libi2c' could be initialized from the rtems |
---|
| 125 | configuration table like other drivers there is no easy |
---|
| 126 | way of populating the i2c framework with bus- and device- |
---|
| 127 | drivers at this point (unless a special 'i2c' configuration |
---|
| 128 | table describing the bus layout is implemented in the future). |
---|
| 129 | |
---|
| 130 | For the time being, we must rely on the BSP (predriver_hook) |
---|
| 131 | to initialize the i2c system if it is used by other drivers |
---|
| 132 | (e.g., the RTC driver may have to use a i2c device). |
---|
| 133 | |
---|
[abe0cdb1] | 134 | =================== |
---|
| 135 | Bus Registration |
---|
| 136 | =================== |
---|
| 137 | Each i2c and/or spi bus available must be registerd with a call to |
---|
| 138 | |
---|
| 139 | int rtems_libi2c_register_bus (char *name, |
---|
| 140 | rtems_libi2c_bus_t * bus) |
---|
| 141 | |
---|
| 142 | It registers the bus to the libi2c internal data structures and |
---|
| 143 | creates a device node in the RTEMS filesystem with the given name. If |
---|
| 144 | no name is given (name==NULL), then the default name "/dev/i2c" is |
---|
| 145 | used instead. |
---|
| 146 | |
---|
| 147 | With the second calling parameter "rtems_libi2c_bus_t * bus" the |
---|
| 148 | caller passes in a set of function pointers, which define the entries |
---|
| 149 | into the i2c controller driver (defined in the BSP). |
---|
| 150 | |
---|
| 151 | This call returns an integer bus number, which can be used in |
---|
| 152 | subsequent calls to register devices attached to this bus (see below). |
---|
| 153 | |
---|
| 154 | Typically the BSP startup code will perform this registration for each |
---|
| 155 | bus available on the board. |
---|
| 156 | |
---|
[c47890c] | 157 | ========================== |
---|
| 158 | Device/Driver Registration |
---|
| 159 | ========================== |
---|
| 160 | Each device attached to an i2c or spi bus must be registered with a |
---|
| 161 | call to |
---|
| 162 | |
---|
| 163 | int |
---|
| 164 | rtems_libi2c_register_drv (char *name, rtems_libi2c_drv_t * drvtbl, |
---|
| 165 | unsigned bus, unsigned i2caddr); |
---|
| 166 | |
---|
| 167 | With this call, libi2c is informed, that: |
---|
| 168 | |
---|
| 169 | - a device is attached to the given "bus" number (which in fact is the |
---|
| 170 | return value received from a previous rtems_libi2c_register_bus() |
---|
| 171 | call) with the address "i2caddr" |
---|
| 172 | |
---|
| 173 | - the device is managed by a driver, who's entry functions are listed |
---|
| 174 | in "drvtbl" |
---|
| 175 | |
---|
| 176 | - the device should be registered with the given "name" in the device |
---|
| 177 | tree of the filesystem. |
---|
| 178 | |
---|
| 179 | The call will create a proper minor device number, which has the bus |
---|
| 180 | number and i2c_address encoded. This minor number is the return value |
---|
| 181 | of the call and is also associated with the filesystem node created |
---|
| 182 | for this device. |
---|
| 183 | |
---|
| 184 | Note: If you have multiple devices of the same type, you must register |
---|
| 185 | each of them through a separate call (with the same "drvtbl", but |
---|
| 186 | different name/bus/i2caddr). |
---|
[abe0cdb1] | 187 | |
---|
| 188 | ==================================================================== |
---|
| 189 | (5<->4) RTEMS I/O Manager and the libi2c OS adaption layer IF |
---|
| 190 | ==================================================================== |
---|
| 191 | |
---|
| 192 | The RTEMS I/O Manager regards the libi2c OS adaption layer as a normal |
---|
| 193 | RTEMS Device Driver with one unique major number and a set of minor |
---|
| 194 | numbers, one for each bus and one for each device attached to one of |
---|
| 195 | the busses. |
---|
| 196 | |
---|
| 197 | Therefore the libi2c OS adaption layer provides the standard calls: |
---|
| 198 | |
---|
| 199 | static rtems_driver_address_table libi2c_io_ops = { |
---|
| 200 | initialization_entry: i2c_init, |
---|
| 201 | open_entry: i2c_open, |
---|
| 202 | close_entry: i2c_close, |
---|
| 203 | read_entry: i2c_read, |
---|
| 204 | write_entry: i2c_write, |
---|
| 205 | control_entry: i2c_ioctl |
---|
| 206 | }; |
---|
| 207 | |
---|
| 208 | These calls perform some parameter checking and then call the |
---|
[c47890c] | 209 | appropriate high level i2c device driver function, if available, |
---|
| 210 | according to the entries in the "drvtbl" passed in the |
---|
| 211 | rtems_libi2c_register_drv() call. |
---|
[abe0cdb1] | 212 | |
---|
| 213 | There are two exceptions: when i2c_read or i2c_write is called with a |
---|
| 214 | minor number specifying a bus (and not a device attached to the bus), |
---|
| 215 | then the respective transfer is performed as a raw byte stream |
---|
| 216 | transfer to the bus. |
---|
| 217 | |
---|
| 218 | The main reason for the libi2c OS adaption layer is, that it |
---|
[c47890c] | 219 | dispatches the RTEMS I/O Manager calls to the proper device driver |
---|
[abe0cdb1] | 220 | according to the minor number used. |
---|
| 221 | |
---|
| 222 | ==================================================================== |
---|
| 223 | libi2c OS adaption layer and the high level i2c device driver IF |
---|
| 224 | ==================================================================== |
---|
| 225 | |
---|
| 226 | Each high level i2c device driver provides a set of functions in the |
---|
| 227 | rtems_libi2c_drv_t data structure passed the libi2c when the device is |
---|
[c47890c] | 228 | registered (see "Device registration" above). These function directly match |
---|
[abe0cdb1] | 229 | the RTEMS I/O Mangers calls "open", "close", "read", "write", |
---|
| 230 | "control", and they are passed the same arguments. Functions not |
---|
[c47890c] | 231 | needed may be ommited (and replaced by a NULL pointer in |
---|
| 232 | rtems_libi2c_drv_t). |
---|
[abe0cdb1] | 233 | |
---|
| 234 | ====================================================================== |
---|
| 235 | high level i2c device driver and libi2c low level abstraction layer IF |
---|
| 236 | ====================================================================== |
---|
[c47890c] | 237 | libi2c provides a set of functions for the high level drivers. These |
---|
| 238 | functions are: |
---|
| 239 | |
---|
| 240 | rtems_libi2c_send_start(); |
---|
| 241 | rtems_libi2c_send_stop(); |
---|
| 242 | rtems_libi2c_send_addr(); |
---|
| 243 | rtems_libi2c_read_bytes(); |
---|
| 244 | rtems_libi2c_write_bytes(); |
---|
| 245 | rtems_libi2c_start_read_bytes(); |
---|
| 246 | rtems_libi2c_start_write_bytes(); |
---|
| 247 | rtems_libi2c_ioctl(); |
---|
| 248 | |
---|
| 249 | Please look into libi2c.h for the proper parameters and return codes. |
---|
| 250 | |
---|
| 251 | These functions perform the proper i2c operations when called. |
---|
| 252 | |
---|
| 253 | A typical access sequence for the I2C bus would be: |
---|
| 254 | |
---|
| 255 | rtems_libi2c_send_start(); |
---|
| 256 | rtems_libi2c_send_addr(); |
---|
| 257 | rtems_libi2c_write_bytes(); |
---|
| 258 | rtems_libi2c_send_stop(); |
---|
| 259 | |
---|
| 260 | Alternatively, the rtems_libi2c_write_bytes() call could be relpaced |
---|
| 261 | with a |
---|
| 262 | rtems_libi2c_read_bytes() |
---|
| 263 | |
---|
| 264 | call or a sequence of multiple calls. |
---|
| 265 | |
---|
| 266 | Note: rtems_libi2c_send_start() locks the i2c/spi bus used, so no other |
---|
| 267 | device can use this i2c/spi bus, until rtems_libi2c_send_stop() function |
---|
| 268 | is called for the same device. |
---|
| 269 | |
---|
| 270 | Special provisions for SPI devices: |
---|
| 271 | =================================== |
---|
| 272 | For SPI devices and their drivers, the libi2c interface is used |
---|
| 273 | slightly differently: |
---|
| 274 | |
---|
| 275 | rtems_libi2c_send_start() will lock access to the SPI bus, but has no |
---|
| 276 | effect on the hardware bus interface. |
---|
| 277 | |
---|
| 278 | rtems_libi2c_ioctl(...,RTEMS_LIBI2C_IOCTL_SET_TFRMODE,...) will set |
---|
| 279 | the transfer mode (bit rate, clock phase and polaritiy, bits per |
---|
| 280 | char...) according to the rtems_libi2c_tfr_mode_t structure passed in. |
---|
| 281 | |
---|
| 282 | rtems_libi2c_send_addr() will activate the proper select line to |
---|
| 283 | address a certain SPI device. The correspondance between an address |
---|
| 284 | and the select line pulled is BSP specific. |
---|
| 285 | |
---|
| 286 | rtems_libi2c_send_stop(); will deactivate the address line and unlock |
---|
| 287 | the bus. |
---|
| 288 | |
---|
| 289 | A typical access sequence for the SPI bus would be: |
---|
| 290 | |
---|
| 291 | rtems_libi2c_send_start(); |
---|
| 292 | rtems_libi2c_ioctl(...,RTEMS_LIBI2C_IOCTL_SET_TFRMODE,...); |
---|
| 293 | rtems_libi2c_send_addr(); |
---|
| 294 | rtems_libi2c_write_bytes(); |
---|
| 295 | rtems_libi2c_send_stop(); |
---|
| 296 | |
---|
| 297 | Alternatively, the rtems_libi2c_write_bytes() call could be relpaced |
---|
| 298 | with a |
---|
| 299 | rtems_libi2c_read_bytes() |
---|
| 300 | or a |
---|
| 301 | rtems_libi2c_ioctl(...,RTEMS_LIBI2C_IOCTL_READ_WRITE,...) |
---|
| 302 | call or a sequence of multiple calls. |
---|
[abe0cdb1] | 303 | |
---|
| 304 | ==================================================================== |
---|
| 305 | libi2c low level abstraction layer and i2c controller driver IF |
---|
| 306 | ==================================================================== |
---|
[c47890c] | 307 | Each low level i2c/spi driver must provide a set of bus_ops functions |
---|
| 308 | as defined in the rtems_libi2c_bus_ops_t structure. |
---|
| 309 | |
---|
| 310 | typedef struct rtems_libi2c_bus_ops_ |
---|
| 311 | { |
---|
| 312 | /* Initialize the bus; might be called again to reset the bus driver */ |
---|
| 313 | rtems_status_code (*init) (rtems_libi2c_bus_t * bushdl); |
---|
| 314 | /* Send start condition */ |
---|
| 315 | rtems_status_code (*send_start) (rtems_libi2c_bus_t * bushdl); |
---|
| 316 | /* Send stop condition */ |
---|
| 317 | rtems_status_code (*send_stop) (rtems_libi2c_bus_t * bushdl); |
---|
| 318 | /* initiate transfer from (rw!=0) or to a device */ |
---|
| 319 | rtems_status_code (*send_addr) (rtems_libi2c_bus_t * bushdl, |
---|
| 320 | uint32_t addr, int rw); |
---|
| 321 | /* read a number of bytes */ |
---|
| 322 | int (*read_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes, |
---|
| 323 | int nbytes); |
---|
| 324 | /* write a number of bytes */ |
---|
| 325 | int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes, |
---|
| 326 | int nbytes); |
---|
| 327 | /* ioctl misc functions */ |
---|
| 328 | int (*ioctl) (rtems_libi2c_bus_t * bushdl, |
---|
| 329 | int cmd, |
---|
| 330 | void *buffer; |
---|
| 331 | ); |
---|
| 332 | } rtems_libi2c_bus_ops_t; |
---|
| 333 | |
---|
| 334 | Each of these functions performs the corresponding function to the i2c |
---|
| 335 | bus. |
---|
| 336 | |
---|
| 337 | Special provisions for SPI devices: |
---|
| 338 | =================================== |
---|
| 339 | For SPI busses, special behaviour is required: |
---|
| 340 | |
---|
| 341 | (*send_start) (rtems_libi2c_bus_t * bushdl) |
---|
| 342 | normally is an empty function. |
---|
| 343 | |
---|
| 344 | (*send_addr) (rtems_libi2c_bus_t * bushdl, uint32_t addr, int rw) |
---|
| 345 | will activate the SPI select line matching to addr. |
---|
| 346 | |
---|
| 347 | (*send_stop) (rtems_libi2c_bus_t * bushdl) |
---|
| 348 | will deactivate the SPI select line |
---|
| 349 | |
---|
| 350 | (*ioctl(...,RTEMS_LIBI2C_IOCTL_SET_TFRMODE,...) |
---|
| 351 | will set the transfer mode (bit rate, clock phase and |
---|
| 352 | polaritiy, bits per char...) according to the |
---|
| 353 | rtems_libi2c_tfr_mode_t structure passed in. |
---|
| 354 | |
---|
| 355 | (*ioctl(...,RTEMS_LIBI2C_IOCTL_READ_WRITE,...) |
---|
| 356 | will send and receive data at the same time. |
---|
| 357 | |
---|
| 358 | Note: |
---|
| 359 | |
---|
| 360 | - low-level I2C drivers normally are specific to the master |
---|
| 361 | device, but independent from the board hardware. So in many cases they |
---|
| 362 | can totally reside in libcpu or libchip. |
---|
| 363 | |
---|
| 364 | - low-level SPI drivers are mostly board independent, but the |
---|
| 365 | addressing is board/BSP dependent. Therefore the (*send_start), |
---|
| 366 | (*send_addr) and (*send_stop) functions are typically defined in the |
---|
| 367 | BSP. The rest of the functions can reside in libcpu or libchip. |
---|