mini board PCU9669 (and PCA9665) sample code

Dependencies:   mbed PCU9669 utility PCA9665 I2C_slaves parallel_bus

Fork of mini_board_PCU9669_old by InetrfaceProducts NXP

Sample code for PCU9669 (PCU9661, PCA9663, PCA9661 and PCA9665) evaluation board.

PCU9669 evaluation board: Mini board PCU9669
User manual is available -> http://www.nxp.com/documents/user_manual/UM10580.pdf

Committer:
nxp_ip
Date:
Mon Mar 26 06:17:23 2012 +0000
Revision:
5:57c345099873
tempolary version for trouble shooting

Who changed what in which revision?

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