Mini board PCU9669 evaluation kit library
Dependents: mini_board_PCU9669
PCA9665_access.c@1:d7f7e0790f60, 2012-03-26 (annotated)
- Committer:
- nxp_ip
- Date:
- Mon Mar 26 15:12:56 2012 +0000
- Revision:
- 1:d7f7e0790f60
- Parent:
- 0:0737f5596e3d
- Child:
- 2:da1b02ca97ee
first release version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nxp_ip | 0:0737f5596e3d | 1 | /** A sample code for "mini board PCU9669/PCA9665" |
nxp_ip | 0:0737f5596e3d | 2 | * |
nxp_ip | 1:d7f7e0790f60 | 3 | * @author Akifumi (Tedd) OKANO, NXP Semiconductors |
nxp_ip | 1:d7f7e0790f60 | 4 | * @version 1.0 |
nxp_ip | 1:d7f7e0790f60 | 5 | * @date 26-Mar-2011 |
nxp_ip | 0:0737f5596e3d | 6 | * |
nxp_ip | 0:0737f5596e3d | 7 | * Released under the MIT License: http://mbed.org/license/mit |
nxp_ip | 0:0737f5596e3d | 8 | * |
nxp_ip | 0:0737f5596e3d | 9 | * An operation sample of PCU9669/PCA9665 I2C bus controller. |
nxp_ip | 0:0737f5596e3d | 10 | * The mbed accesses the bus controller's parallel port (8/2 bit address and 8 bit data) by bit-banging. |
nxp_ip | 0:0737f5596e3d | 11 | * The bit-banging is poerformed by PortInOut function of mbed library. |
nxp_ip | 0:0737f5596e3d | 12 | * |
nxp_ip | 0:0737f5596e3d | 13 | * To make the code porting easier, all codes are partitioned into layers to abstract other parts. |
nxp_ip | 0:0737f5596e3d | 14 | * The mbed specific parts are concentrated in lowest layer: "hardware_abs.*". |
nxp_ip | 0:0737f5596e3d | 15 | * This module may need to be modified for the porting. |
nxp_ip | 0:0737f5596e3d | 16 | * |
nxp_ip | 0:0737f5596e3d | 17 | * All other upper layers are writen in standard-C. |
nxp_ip | 0:0737f5596e3d | 18 | * |
nxp_ip | 0:0737f5596e3d | 19 | * base code is written from 05-Sep-2011 to 09-Sep-2011. |
nxp_ip | 0:0737f5596e3d | 20 | * And demo code has been build on 11-Sep-2011. |
nxp_ip | 0:0737f5596e3d | 21 | * Debug and code adjustment has been done on 08-Sep-2011. |
nxp_ip | 0:0737f5596e3d | 22 | * Small sanitization for main.cpp. All mbed related codes are moved in to "hardware_abs.*". 13-Oct-2011 |
nxp_ip | 0:0737f5596e3d | 23 | * hardware_abs are moved into parallel_bus library folder, 3 LED driver operation sample 13-Feb.-2012 |
nxp_ip | 0:0737f5596e3d | 24 | * PCU9669 and PCA9665 codes are packed in a project 14-Feb-2012. |
nxp_ip | 0:0737f5596e3d | 25 | * |
nxp_ip | 0:0737f5596e3d | 26 | * Before builidng the code, please edit the file mini_board_PCU9669/config.h |
nxp_ip | 1:d7f7e0790f60 | 27 | * Un-comment the target name what you want to target. |
nxp_ip | 0:0737f5596e3d | 28 | */ |
nxp_ip | 0:0737f5596e3d | 29 | |
nxp_ip | 0:0737f5596e3d | 30 | #include "PCA9665_access.h" |
nxp_ip | 0:0737f5596e3d | 31 | #include "hardware_abs.h" |
nxp_ip | 0:0737f5596e3d | 32 | |
nxp_ip | 0:0737f5596e3d | 33 | #define BUS_CONTINUE 0 |
nxp_ip | 0:0737f5596e3d | 34 | #define BUS_STOP 1 |
nxp_ip | 0:0737f5596e3d | 35 | #define BUS_RELEASE 2 |
nxp_ip | 0:0737f5596e3d | 36 | |
nxp_ip | 0:0737f5596e3d | 37 | typedef enum { |
nxp_ip | 0:0737f5596e3d | 38 | I2CSTA = 0x0, |
nxp_ip | 0:0737f5596e3d | 39 | INDPTR = 0x0, |
nxp_ip | 0:0737f5596e3d | 40 | I2CDAT, |
nxp_ip | 0:0737f5596e3d | 41 | INDIRECT, |
nxp_ip | 0:0737f5596e3d | 42 | I2CCON |
nxp_ip | 0:0737f5596e3d | 43 | } |
nxp_ip | 0:0737f5596e3d | 44 | pca9665_direct_registers; |
nxp_ip | 0:0737f5596e3d | 45 | |
nxp_ip | 0:0737f5596e3d | 46 | typedef enum { |
nxp_ip | 0:0737f5596e3d | 47 | I2CCOUNT, |
nxp_ip | 0:0737f5596e3d | 48 | I2CADR, |
nxp_ip | 0:0737f5596e3d | 49 | I2CSCLL, |
nxp_ip | 0:0737f5596e3d | 50 | I2CSCLH, |
nxp_ip | 0:0737f5596e3d | 51 | I2CTO, |
nxp_ip | 0:0737f5596e3d | 52 | I2CPRESET, |
nxp_ip | 0:0737f5596e3d | 53 | I2CMODE |
nxp_ip | 0:0737f5596e3d | 54 | } |
nxp_ip | 0:0737f5596e3d | 55 | pca9665_indirect_registers; |
nxp_ip | 0:0737f5596e3d | 56 | |
nxp_ip | 0:0737f5596e3d | 57 | typedef enum { |
nxp_ip | 0:0737f5596e3d | 58 | ILLEGAL_START_STOP = 0x00, |
nxp_ip | 0:0737f5596e3d | 59 | MASTER_START_TXed = 0x08, |
nxp_ip | 0:0737f5596e3d | 60 | MASTER_RESTART_TXed = 0x10, |
nxp_ip | 0:0737f5596e3d | 61 | MASTER_SLA_W_ACK = 0x18, |
nxp_ip | 0:0737f5596e3d | 62 | MASTER_SLA_W_NAK = 0x20, |
nxp_ip | 0:0737f5596e3d | 63 | MASTER_DATA_W_ACK = 0x28, |
nxp_ip | 0:0737f5596e3d | 64 | MASTER_DATA_W_NAK = 0x30, |
nxp_ip | 0:0737f5596e3d | 65 | MASTER_ARB_LOST = 0x38, |
nxp_ip | 0:0737f5596e3d | 66 | MASTER_SLA_R_ACK = 0x40, |
nxp_ip | 0:0737f5596e3d | 67 | MASTER_SLA_R_NAK = 0x48, |
nxp_ip | 0:0737f5596e3d | 68 | MASTER_DATA_R_ACK = 0x50, |
nxp_ip | 0:0737f5596e3d | 69 | MASTER_DATA_R_NAK = 0x58, |
nxp_ip | 0:0737f5596e3d | 70 | SLAVE_ADDRESSED_W = 0x60, |
nxp_ip | 0:0737f5596e3d | 71 | SLAVE_AL_ADDRESSED_W = 0x68, |
nxp_ip | 0:0737f5596e3d | 72 | SDA_STUCK = 0x70, |
nxp_ip | 0:0737f5596e3d | 73 | SCL_STUCK = 0x78, |
nxp_ip | 0:0737f5596e3d | 74 | SLAVE_DATA_RX_ACK = 0x80, |
nxp_ip | 0:0737f5596e3d | 75 | SLAVE_DATA_RX_NAK = 0x88, |
nxp_ip | 0:0737f5596e3d | 76 | SLAVE_STOP_OR_RESTART = 0xA0, |
nxp_ip | 0:0737f5596e3d | 77 | SLAVE_ADDRESSED_R = 0xA8, |
nxp_ip | 0:0737f5596e3d | 78 | SLAVE_AL_ADDRESSED_R = 0xB0, |
nxp_ip | 0:0737f5596e3d | 79 | SLAVE_DATA_TX_ACK = 0xB8, |
nxp_ip | 0:0737f5596e3d | 80 | SLAVE_DATA_TX_NAK = 0xC0, |
nxp_ip | 0:0737f5596e3d | 81 | SLAVE_LAST_DATA_TX_ACK = 0xC8, |
nxp_ip | 0:0737f5596e3d | 82 | SLAVE_GENERALCALL = 0xD0, |
nxp_ip | 0:0737f5596e3d | 83 | SLAVE_GENERALCALL_AL = 0xD8, |
nxp_ip | 0:0737f5596e3d | 84 | SLAVE_GENERALCALL_DATA_RX_ACK = 0xE0, |
nxp_ip | 0:0737f5596e3d | 85 | SLAVE_GENERALCALL_DATA_RX_NAK = 0xE8, |
nxp_ip | 0:0737f5596e3d | 86 | IDLE = 0xF8, |
nxp_ip | 0:0737f5596e3d | 87 | ILLEGAL_I2CCOUNT = 0xFC |
nxp_ip | 0:0737f5596e3d | 88 | } |
nxp_ip | 0:0737f5596e3d | 89 | pca9665_status; |
nxp_ip | 0:0737f5596e3d | 90 | |
nxp_ip | 0:0737f5596e3d | 91 | typedef struct _speed_mode_st { |
nxp_ip | 0:0737f5596e3d | 92 | char i2cmode; |
nxp_ip | 0:0737f5596e3d | 93 | char i2cscll; |
nxp_ip | 0:0737f5596e3d | 94 | char i2csclh; |
nxp_ip | 0:0737f5596e3d | 95 | } |
nxp_ip | 0:0737f5596e3d | 96 | speed_mode_st; |
nxp_ip | 0:0737f5596e3d | 97 | |
nxp_ip | 0:0737f5596e3d | 98 | speed_mode_st speed_mode[ 3 ] = { |
nxp_ip | 0:0737f5596e3d | 99 | { 0x00, 0x9D, 0x86 }, |
nxp_ip | 0:0737f5596e3d | 100 | { 0x01, 0x2C, 0x14 }, |
nxp_ip | 0:0737f5596e3d | 101 | { 0x02, 0x011, 0x09 } |
nxp_ip | 0:0737f5596e3d | 102 | }; |
nxp_ip | 0:0737f5596e3d | 103 | |
nxp_ip | 0:0737f5596e3d | 104 | int buffer_mode_enable = DISABLE; |
nxp_ip | 0:0737f5596e3d | 105 | char int_happened = 0; |
nxp_ip | 0:0737f5596e3d | 106 | char op_mode_flag = OP_MODE_MASTER_ONLY; |
nxp_ip | 0:0737f5596e3d | 107 | |
nxp_ip | 0:0737f5596e3d | 108 | void interrupt_handler_PCA9665( void ) { |
nxp_ip | 0:0737f5596e3d | 109 | int_happened = 1; |
nxp_ip | 0:0737f5596e3d | 110 | } |
nxp_ip | 0:0737f5596e3d | 111 | |
nxp_ip | 0:0737f5596e3d | 112 | void PCA9665_init( void ) { |
nxp_ip | 0:0737f5596e3d | 113 | write_data( I2CCON, 0x40 ); |
nxp_ip | 0:0737f5596e3d | 114 | hw_wait_us( 1000 ); |
nxp_ip | 0:0737f5596e3d | 115 | |
nxp_ip | 0:0737f5596e3d | 116 | install_ISR( &interrupt_handler_PCA9665 ); // interrupt service routine install |
nxp_ip | 0:0737f5596e3d | 117 | |
nxp_ip | 0:0737f5596e3d | 118 | // initialize PCA9955 registers |
nxp_ip | 0:0737f5596e3d | 119 | } |
nxp_ip | 0:0737f5596e3d | 120 | |
nxp_ip | 0:0737f5596e3d | 121 | void set_speed_mode( int mode ) { |
nxp_ip | 0:0737f5596e3d | 122 | indirect_write( I2CMODE, speed_mode[ mode ].i2cmode ); |
nxp_ip | 0:0737f5596e3d | 123 | indirect_write( I2CSCLL, speed_mode[ mode ].i2cscll ); |
nxp_ip | 0:0737f5596e3d | 124 | indirect_write( I2CSCLH, speed_mode[ mode ].i2csclh ); |
nxp_ip | 0:0737f5596e3d | 125 | } |
nxp_ip | 0:0737f5596e3d | 126 | |
nxp_ip | 0:0737f5596e3d | 127 | void set_buffer_mode( int mode ) { |
nxp_ip | 0:0737f5596e3d | 128 | buffer_mode_enable = mode; |
nxp_ip | 0:0737f5596e3d | 129 | } |
nxp_ip | 0:0737f5596e3d | 130 | |
nxp_ip | 0:0737f5596e3d | 131 | int i2c_write( char addr, char *dp, char length, char restart_flag ) { |
nxp_ip | 0:0737f5596e3d | 132 | return ( |
nxp_ip | 0:0737f5596e3d | 133 | buffer_mode_enable ? |
nxp_ip | 0:0737f5596e3d | 134 | i2c_write_buffer_mode( addr, dp, length, restart_flag ) |
nxp_ip | 0:0737f5596e3d | 135 | : |
nxp_ip | 0:0737f5596e3d | 136 | i2c_write_byte_mode( addr, dp, length, restart_flag ) |
nxp_ip | 0:0737f5596e3d | 137 | ); |
nxp_ip | 0:0737f5596e3d | 138 | } |
nxp_ip | 0:0737f5596e3d | 139 | |
nxp_ip | 0:0737f5596e3d | 140 | int i2c_read( char addr, char *dp, char length, char restart_flag ) { |
nxp_ip | 0:0737f5596e3d | 141 | return ( |
nxp_ip | 0:0737f5596e3d | 142 | buffer_mode_enable ? |
nxp_ip | 0:0737f5596e3d | 143 | i2c_read_buffer_mode( addr, dp, length, restart_flag ) |
nxp_ip | 0:0737f5596e3d | 144 | : |
nxp_ip | 0:0737f5596e3d | 145 | i2c_read_byte_mode( addr, dp, length, restart_flag ) |
nxp_ip | 0:0737f5596e3d | 146 | ); |
nxp_ip | 0:0737f5596e3d | 147 | } |
nxp_ip | 0:0737f5596e3d | 148 | |
nxp_ip | 0:0737f5596e3d | 149 | |
nxp_ip | 0:0737f5596e3d | 150 | int i2c_write_buffer_mode( char addr, char *dp, char length, char restart_flag ) { |
nxp_ip | 0:0737f5596e3d | 151 | int done = BUS_CONTINUE; |
nxp_ip | 0:0737f5596e3d | 152 | char state; |
nxp_ip | 0:0737f5596e3d | 153 | char return_value = 0xFF; |
nxp_ip | 0:0737f5596e3d | 154 | #ifdef PCA9665_BURST_DATA_ACCESS |
nxp_ip | 0:0737f5596e3d | 155 | #else |
nxp_ip | 0:0737f5596e3d | 156 | int i; |
nxp_ip | 0:0737f5596e3d | 157 | #endif |
nxp_ip | 0:0737f5596e3d | 158 | |
nxp_ip | 0:0737f5596e3d | 159 | if ( 67 < length ) |
nxp_ip | 0:0737f5596e3d | 160 | return ( 0xFE ); |
nxp_ip | 0:0737f5596e3d | 161 | |
nxp_ip | 0:0737f5596e3d | 162 | write_data( I2CCON, 0x61 ); |
nxp_ip | 0:0737f5596e3d | 163 | |
nxp_ip | 0:0737f5596e3d | 164 | while ( !done ) { |
nxp_ip | 0:0737f5596e3d | 165 | if ( int_happened ) { |
nxp_ip | 0:0737f5596e3d | 166 | int_happened = 0; |
nxp_ip | 0:0737f5596e3d | 167 | |
nxp_ip | 0:0737f5596e3d | 168 | state = read_data( I2CSTA ); |
nxp_ip | 0:0737f5596e3d | 169 | |
nxp_ip | 0:0737f5596e3d | 170 | switch ( state ) { |
nxp_ip | 0:0737f5596e3d | 171 | case MASTER_START_TXed : |
nxp_ip | 0:0737f5596e3d | 172 | case MASTER_RESTART_TXed : |
nxp_ip | 0:0737f5596e3d | 173 | indirect_write( I2CCOUNT, length + 1 ); |
nxp_ip | 0:0737f5596e3d | 174 | write_data( I2CDAT, addr & 0xFE ); |
nxp_ip | 0:0737f5596e3d | 175 | |
nxp_ip | 0:0737f5596e3d | 176 | #ifdef PCA9665_BURST_DATA_ACCESS |
nxp_ip | 0:0737f5596e3d | 177 | write_data_burst( I2CDAT, dp, length ); |
nxp_ip | 0:0737f5596e3d | 178 | #else |
nxp_ip | 0:0737f5596e3d | 179 | for ( i = 0; i < length; i++ ) |
nxp_ip | 0:0737f5596e3d | 180 | write_data( I2CDAT, *dp++ ); |
nxp_ip | 0:0737f5596e3d | 181 | #endif |
nxp_ip | 0:0737f5596e3d | 182 | |
nxp_ip | 0:0737f5596e3d | 183 | write_data( I2CCON, 0x41 ); |
nxp_ip | 0:0737f5596e3d | 184 | break; |
nxp_ip | 0:0737f5596e3d | 185 | case MASTER_SLA_W_ACK : // SLA+W TXed |
nxp_ip | 0:0737f5596e3d | 186 | case MASTER_DATA_W_ACK : // DATA TXed |
nxp_ip | 0:0737f5596e3d | 187 | return_value = 0x00; |
nxp_ip | 0:0737f5596e3d | 188 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 189 | break; |
nxp_ip | 0:0737f5596e3d | 190 | case MASTER_SLA_W_NAK : |
nxp_ip | 0:0737f5596e3d | 191 | case MASTER_DATA_W_NAK : |
nxp_ip | 0:0737f5596e3d | 192 | return_value = 0x01; |
nxp_ip | 0:0737f5596e3d | 193 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 194 | break; |
nxp_ip | 0:0737f5596e3d | 195 | case MASTER_ARB_LOST : |
nxp_ip | 0:0737f5596e3d | 196 | case SLAVE_AL_ADDRESSED_R : |
nxp_ip | 0:0737f5596e3d | 197 | case SLAVE_AL_ADDRESSED_W : |
nxp_ip | 0:0737f5596e3d | 198 | case SLAVE_GENERALCALL_AL : |
nxp_ip | 0:0737f5596e3d | 199 | /* bus should be released for other master */ |
nxp_ip | 0:0737f5596e3d | 200 | default : |
nxp_ip | 0:0737f5596e3d | 201 | /* unexpected bus error */ |
nxp_ip | 0:0737f5596e3d | 202 | done = BUS_RELEASE; |
nxp_ip | 0:0737f5596e3d | 203 | break; |
nxp_ip | 0:0737f5596e3d | 204 | } |
nxp_ip | 0:0737f5596e3d | 205 | } |
nxp_ip | 0:0737f5596e3d | 206 | } |
nxp_ip | 0:0737f5596e3d | 207 | |
nxp_ip | 0:0737f5596e3d | 208 | if ( OP_MODE_MASTER_ONLY == op_mode_flag ) |
nxp_ip | 0:0737f5596e3d | 209 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 210 | |
nxp_ip | 0:0737f5596e3d | 211 | if ( (BUS_STOP == done) && !restart_flag ) |
nxp_ip | 0:0737f5596e3d | 212 | write_data( I2CCON, 0x50 ); |
nxp_ip | 0:0737f5596e3d | 213 | |
nxp_ip | 0:0737f5596e3d | 214 | return ( return_value ); |
nxp_ip | 0:0737f5596e3d | 215 | } |
nxp_ip | 0:0737f5596e3d | 216 | |
nxp_ip | 0:0737f5596e3d | 217 | int i2c_read_buffer_mode( char addr, char *dp, char length, char restart_flag ) { |
nxp_ip | 0:0737f5596e3d | 218 | int done = BUS_CONTINUE; |
nxp_ip | 0:0737f5596e3d | 219 | char state; |
nxp_ip | 0:0737f5596e3d | 220 | char return_value = 0xFF; |
nxp_ip | 0:0737f5596e3d | 221 | |
nxp_ip | 0:0737f5596e3d | 222 | #ifdef PCA9665_BURST_DATA_ACCESS |
nxp_ip | 0:0737f5596e3d | 223 | #else |
nxp_ip | 0:0737f5596e3d | 224 | int i; |
nxp_ip | 0:0737f5596e3d | 225 | #endif |
nxp_ip | 0:0737f5596e3d | 226 | |
nxp_ip | 0:0737f5596e3d | 227 | if ( 68 < length ) |
nxp_ip | 0:0737f5596e3d | 228 | return ( 0xFE ); |
nxp_ip | 0:0737f5596e3d | 229 | |
nxp_ip | 0:0737f5596e3d | 230 | if ( !length ) // zero byte read may cause invalid STOP to START signal output |
nxp_ip | 0:0737f5596e3d | 231 | return ( 0 ); |
nxp_ip | 0:0737f5596e3d | 232 | |
nxp_ip | 0:0737f5596e3d | 233 | write_data( I2CCON, 0x61 ); |
nxp_ip | 0:0737f5596e3d | 234 | |
nxp_ip | 0:0737f5596e3d | 235 | while ( !done ) { |
nxp_ip | 0:0737f5596e3d | 236 | if ( int_happened ) { |
nxp_ip | 0:0737f5596e3d | 237 | int_happened = 0; |
nxp_ip | 0:0737f5596e3d | 238 | |
nxp_ip | 0:0737f5596e3d | 239 | state = read_data( I2CSTA ); |
nxp_ip | 0:0737f5596e3d | 240 | |
nxp_ip | 0:0737f5596e3d | 241 | switch ( state ) { |
nxp_ip | 0:0737f5596e3d | 242 | case MASTER_START_TXed : |
nxp_ip | 0:0737f5596e3d | 243 | case MASTER_RESTART_TXed : |
nxp_ip | 0:0737f5596e3d | 244 | write_data( I2CDAT, addr | 0x01 ); |
nxp_ip | 0:0737f5596e3d | 245 | indirect_write( I2CCOUNT, length | 0x80 ); |
nxp_ip | 0:0737f5596e3d | 246 | write_data( I2CCON, 0x41 ); |
nxp_ip | 0:0737f5596e3d | 247 | break; |
nxp_ip | 0:0737f5596e3d | 248 | case MASTER_SLA_R_ACK : // SLA+R TXed |
nxp_ip | 0:0737f5596e3d | 249 | case MASTER_DATA_R_ACK : // DATA RXed |
nxp_ip | 0:0737f5596e3d | 250 | return_value = 0x00; |
nxp_ip | 0:0737f5596e3d | 251 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 252 | break; |
nxp_ip | 0:0737f5596e3d | 253 | case MASTER_SLA_R_NAK : // SLA+R TXed |
nxp_ip | 0:0737f5596e3d | 254 | return_value = 0x01; |
nxp_ip | 0:0737f5596e3d | 255 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 256 | break; |
nxp_ip | 0:0737f5596e3d | 257 | case MASTER_DATA_R_NAK : |
nxp_ip | 0:0737f5596e3d | 258 | return_value = length - (indirect_read( I2CCOUNT ) & 0x7F); |
nxp_ip | 0:0737f5596e3d | 259 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 260 | |
nxp_ip | 0:0737f5596e3d | 261 | break; |
nxp_ip | 0:0737f5596e3d | 262 | case MASTER_ARB_LOST : |
nxp_ip | 0:0737f5596e3d | 263 | case SLAVE_AL_ADDRESSED_R : |
nxp_ip | 0:0737f5596e3d | 264 | case SLAVE_AL_ADDRESSED_W : |
nxp_ip | 0:0737f5596e3d | 265 | case SLAVE_GENERALCALL_AL : |
nxp_ip | 0:0737f5596e3d | 266 | /* bus should be released for other master */ |
nxp_ip | 0:0737f5596e3d | 267 | default : |
nxp_ip | 0:0737f5596e3d | 268 | /* unexpected bus error */ |
nxp_ip | 0:0737f5596e3d | 269 | done = BUS_RELEASE; |
nxp_ip | 0:0737f5596e3d | 270 | break; |
nxp_ip | 0:0737f5596e3d | 271 | } |
nxp_ip | 0:0737f5596e3d | 272 | } |
nxp_ip | 0:0737f5596e3d | 273 | } |
nxp_ip | 0:0737f5596e3d | 274 | |
nxp_ip | 0:0737f5596e3d | 275 | #ifdef PCA9665_BURST_DATA_ACCESS |
nxp_ip | 0:0737f5596e3d | 276 | read_data_burst( I2CDAT, dp, length ); |
nxp_ip | 0:0737f5596e3d | 277 | #else |
nxp_ip | 0:0737f5596e3d | 278 | for ( i = 0; i < length; i++ ) |
nxp_ip | 0:0737f5596e3d | 279 | *dp++ = read_data( I2CDAT ); |
nxp_ip | 0:0737f5596e3d | 280 | #endif |
nxp_ip | 0:0737f5596e3d | 281 | |
nxp_ip | 0:0737f5596e3d | 282 | if ( OP_MODE_MASTER_ONLY == op_mode_flag ) |
nxp_ip | 0:0737f5596e3d | 283 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 284 | |
nxp_ip | 0:0737f5596e3d | 285 | if ( (BUS_STOP == done) && !restart_flag ) |
nxp_ip | 0:0737f5596e3d | 286 | write_data( I2CCON, 0x50 ); |
nxp_ip | 0:0737f5596e3d | 287 | |
nxp_ip | 0:0737f5596e3d | 288 | return ( return_value ); |
nxp_ip | 0:0737f5596e3d | 289 | } |
nxp_ip | 0:0737f5596e3d | 290 | |
nxp_ip | 0:0737f5596e3d | 291 | int i2c_write_byte_mode( char addr, char *dp, char length, char restart_flag ) { |
nxp_ip | 0:0737f5596e3d | 292 | int done = BUS_CONTINUE; |
nxp_ip | 0:0737f5596e3d | 293 | char state; |
nxp_ip | 0:0737f5596e3d | 294 | |
nxp_ip | 0:0737f5596e3d | 295 | write_data( I2CCON, 0x60 ); |
nxp_ip | 0:0737f5596e3d | 296 | |
nxp_ip | 0:0737f5596e3d | 297 | while ( !done ) { |
nxp_ip | 0:0737f5596e3d | 298 | if ( int_happened ) { |
nxp_ip | 0:0737f5596e3d | 299 | int_happened = 0; |
nxp_ip | 0:0737f5596e3d | 300 | |
nxp_ip | 0:0737f5596e3d | 301 | state = read_data( I2CSTA ); |
nxp_ip | 0:0737f5596e3d | 302 | |
nxp_ip | 0:0737f5596e3d | 303 | switch ( state ) { |
nxp_ip | 0:0737f5596e3d | 304 | case MASTER_START_TXed : |
nxp_ip | 0:0737f5596e3d | 305 | case MASTER_RESTART_TXed : |
nxp_ip | 0:0737f5596e3d | 306 | write_data( I2CDAT, addr & 0xFE ); |
nxp_ip | 0:0737f5596e3d | 307 | write_data( I2CCON, 0x40 ); |
nxp_ip | 0:0737f5596e3d | 308 | break; |
nxp_ip | 0:0737f5596e3d | 309 | case MASTER_DATA_W_ACK : // DATA TXed |
nxp_ip | 0:0737f5596e3d | 310 | length--; |
nxp_ip | 0:0737f5596e3d | 311 | /* FALLTHROUGH */ |
nxp_ip | 0:0737f5596e3d | 312 | case MASTER_SLA_W_ACK : // SLA+W TXed |
nxp_ip | 0:0737f5596e3d | 313 | if ( !length ) { |
nxp_ip | 0:0737f5596e3d | 314 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 315 | break; |
nxp_ip | 0:0737f5596e3d | 316 | } |
nxp_ip | 0:0737f5596e3d | 317 | write_data( I2CDAT, *dp++ ); |
nxp_ip | 0:0737f5596e3d | 318 | write_data( I2CCON, 0x40 ); |
nxp_ip | 0:0737f5596e3d | 319 | break; |
nxp_ip | 0:0737f5596e3d | 320 | case MASTER_SLA_W_NAK : |
nxp_ip | 0:0737f5596e3d | 321 | case MASTER_DATA_W_NAK : |
nxp_ip | 0:0737f5596e3d | 322 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 323 | break; |
nxp_ip | 0:0737f5596e3d | 324 | case MASTER_ARB_LOST : |
nxp_ip | 0:0737f5596e3d | 325 | case SLAVE_AL_ADDRESSED_R : |
nxp_ip | 0:0737f5596e3d | 326 | case SLAVE_AL_ADDRESSED_W : |
nxp_ip | 0:0737f5596e3d | 327 | case SLAVE_GENERALCALL_AL : |
nxp_ip | 0:0737f5596e3d | 328 | /* bus should be released for other master */ |
nxp_ip | 0:0737f5596e3d | 329 | default : |
nxp_ip | 0:0737f5596e3d | 330 | /* unexpected bus error */ |
nxp_ip | 0:0737f5596e3d | 331 | done = BUS_RELEASE; |
nxp_ip | 0:0737f5596e3d | 332 | break; |
nxp_ip | 0:0737f5596e3d | 333 | } |
nxp_ip | 0:0737f5596e3d | 334 | } |
nxp_ip | 0:0737f5596e3d | 335 | } |
nxp_ip | 0:0737f5596e3d | 336 | |
nxp_ip | 0:0737f5596e3d | 337 | if ( OP_MODE_MASTER_ONLY == op_mode_flag ) |
nxp_ip | 0:0737f5596e3d | 338 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 339 | |
nxp_ip | 0:0737f5596e3d | 340 | if ( (BUS_STOP == done) && !restart_flag ) |
nxp_ip | 0:0737f5596e3d | 341 | write_data( I2CCON, 0x50 ); |
nxp_ip | 0:0737f5596e3d | 342 | |
nxp_ip | 0:0737f5596e3d | 343 | return ( length ); |
nxp_ip | 0:0737f5596e3d | 344 | } |
nxp_ip | 0:0737f5596e3d | 345 | |
nxp_ip | 0:0737f5596e3d | 346 | int i2c_read_byte_mode( char addr, char *dp, char length, char restart_flag ) { |
nxp_ip | 0:0737f5596e3d | 347 | int done = BUS_CONTINUE; |
nxp_ip | 0:0737f5596e3d | 348 | char state; |
nxp_ip | 0:0737f5596e3d | 349 | |
nxp_ip | 0:0737f5596e3d | 350 | if ( !length ) // zero byte read may cause invalid STOP to START signal output |
nxp_ip | 0:0737f5596e3d | 351 | return ( 0 ); |
nxp_ip | 0:0737f5596e3d | 352 | |
nxp_ip | 0:0737f5596e3d | 353 | write_data( I2CCON, 0x60 ); |
nxp_ip | 0:0737f5596e3d | 354 | |
nxp_ip | 0:0737f5596e3d | 355 | while ( !done ) { |
nxp_ip | 0:0737f5596e3d | 356 | if ( int_happened ) { |
nxp_ip | 0:0737f5596e3d | 357 | int_happened = 0; |
nxp_ip | 0:0737f5596e3d | 358 | |
nxp_ip | 0:0737f5596e3d | 359 | state = read_data( I2CSTA ); |
nxp_ip | 0:0737f5596e3d | 360 | |
nxp_ip | 0:0737f5596e3d | 361 | switch ( state ) { |
nxp_ip | 0:0737f5596e3d | 362 | case MASTER_START_TXed : |
nxp_ip | 0:0737f5596e3d | 363 | case MASTER_RESTART_TXed : |
nxp_ip | 0:0737f5596e3d | 364 | write_data( I2CDAT, addr | 0x01 ); |
nxp_ip | 0:0737f5596e3d | 365 | write_data( I2CCON, 0x40 ); |
nxp_ip | 0:0737f5596e3d | 366 | break; |
nxp_ip | 0:0737f5596e3d | 367 | case MASTER_DATA_R_NAK : |
nxp_ip | 0:0737f5596e3d | 368 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 369 | /* FALLTHROUGH */ |
nxp_ip | 0:0737f5596e3d | 370 | case MASTER_DATA_R_ACK : // DATA RXed |
nxp_ip | 0:0737f5596e3d | 371 | *dp++ = read_data( I2CDAT ); |
nxp_ip | 0:0737f5596e3d | 372 | length--; |
nxp_ip | 0:0737f5596e3d | 373 | /* FALLTHROUGH */ |
nxp_ip | 0:0737f5596e3d | 374 | case MASTER_SLA_R_ACK : // SLA+R TXed |
nxp_ip | 0:0737f5596e3d | 375 | if ( !length ) |
nxp_ip | 0:0737f5596e3d | 376 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 377 | |
nxp_ip | 0:0737f5596e3d | 378 | if ( !done ) |
nxp_ip | 0:0737f5596e3d | 379 | write_data( I2CCON, (length == 1) ? 0x40 : 0xC0 ); |
nxp_ip | 0:0737f5596e3d | 380 | break; |
nxp_ip | 0:0737f5596e3d | 381 | case MASTER_SLA_R_NAK : |
nxp_ip | 0:0737f5596e3d | 382 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 383 | break; |
nxp_ip | 0:0737f5596e3d | 384 | case MASTER_ARB_LOST : |
nxp_ip | 0:0737f5596e3d | 385 | case SLAVE_AL_ADDRESSED_R : |
nxp_ip | 0:0737f5596e3d | 386 | case SLAVE_AL_ADDRESSED_W : |
nxp_ip | 0:0737f5596e3d | 387 | case SLAVE_GENERALCALL_AL : |
nxp_ip | 0:0737f5596e3d | 388 | /* bus should be released for other master */ |
nxp_ip | 0:0737f5596e3d | 389 | default : |
nxp_ip | 0:0737f5596e3d | 390 | /* unexpected bus error */ |
nxp_ip | 0:0737f5596e3d | 391 | done = BUS_RELEASE; |
nxp_ip | 0:0737f5596e3d | 392 | break; |
nxp_ip | 0:0737f5596e3d | 393 | } |
nxp_ip | 0:0737f5596e3d | 394 | } |
nxp_ip | 0:0737f5596e3d | 395 | } |
nxp_ip | 0:0737f5596e3d | 396 | |
nxp_ip | 0:0737f5596e3d | 397 | if ( OP_MODE_MASTER_ONLY == op_mode_flag ) |
nxp_ip | 0:0737f5596e3d | 398 | done = BUS_STOP; |
nxp_ip | 0:0737f5596e3d | 399 | |
nxp_ip | 0:0737f5596e3d | 400 | if ( (BUS_STOP == done) && !restart_flag ) |
nxp_ip | 0:0737f5596e3d | 401 | write_data( I2CCON, 0x50 ); |
nxp_ip | 0:0737f5596e3d | 402 | |
nxp_ip | 0:0737f5596e3d | 403 | return ( length ); |
nxp_ip | 0:0737f5596e3d | 404 | } |
nxp_ip | 0:0737f5596e3d | 405 | |
nxp_ip | 0:0737f5596e3d | 406 | void indirect_write( char idaddr, char data ) { |
nxp_ip | 0:0737f5596e3d | 407 | write_data( INDPTR, idaddr ); |
nxp_ip | 0:0737f5596e3d | 408 | write_data( INDIRECT, data ); |
nxp_ip | 0:0737f5596e3d | 409 | } |
nxp_ip | 0:0737f5596e3d | 410 | |
nxp_ip | 0:0737f5596e3d | 411 | char indirect_read( char idaddr ) { |
nxp_ip | 0:0737f5596e3d | 412 | write_data( INDPTR, idaddr ); |
nxp_ip | 0:0737f5596e3d | 413 | return ( read_data( INDIRECT ) ); |
nxp_ip | 0:0737f5596e3d | 414 | } |