Mini board PCU9669 evaluation kit library

Dependents:   mini_board_PCU9669

Committer:
nxp_ip
Date:
Thu Mar 15 04:01:44 2012 +0000
Revision:
0:0737f5596e3d
Child:
1:d7f7e0790f60

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nxp_ip 0:0737f5596e3d 1 /** A sample code for "mini board PCU9669/PCA9665"
nxp_ip 0:0737f5596e3d 2 *
nxp_ip 0:0737f5596e3d 3 * @author Tedd OKANO, NXP Semiconductors
nxp_ip 0:0737f5596e3d 4 * @version 0.9
nxp_ip 0:0737f5596e3d 5 * @date 14-Feb-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 0:0737f5596e3d 27 * Uncomment 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 hardware_reset( ASSERT ); // assert hardware /RESET sgnal
nxp_ip 0:0737f5596e3d 114 hw_wait_us( 1000 );
nxp_ip 0:0737f5596e3d 115 hardware_reset( DEASSERT ); // deassert hardware /RESET sgnal
nxp_ip 0:0737f5596e3d 116 hw_wait_us( 1000 );
nxp_ip 0:0737f5596e3d 117
nxp_ip 0:0737f5596e3d 118 write_data( I2CCON, 0x40 );
nxp_ip 0:0737f5596e3d 119 hw_wait_us( 1000 );
nxp_ip 0:0737f5596e3d 120
nxp_ip 0:0737f5596e3d 121 install_ISR( &interrupt_handler_PCA9665 ); // interrupt service routine install
nxp_ip 0:0737f5596e3d 122
nxp_ip 0:0737f5596e3d 123 // initialize PCA9955 registers
nxp_ip 0:0737f5596e3d 124 }
nxp_ip 0:0737f5596e3d 125
nxp_ip 0:0737f5596e3d 126 void set_speed_mode( int mode ) {
nxp_ip 0:0737f5596e3d 127 indirect_write( I2CMODE, speed_mode[ mode ].i2cmode );
nxp_ip 0:0737f5596e3d 128 indirect_write( I2CSCLL, speed_mode[ mode ].i2cscll );
nxp_ip 0:0737f5596e3d 129 indirect_write( I2CSCLH, speed_mode[ mode ].i2csclh );
nxp_ip 0:0737f5596e3d 130 }
nxp_ip 0:0737f5596e3d 131
nxp_ip 0:0737f5596e3d 132 void set_buffer_mode( int mode ) {
nxp_ip 0:0737f5596e3d 133 buffer_mode_enable = mode;
nxp_ip 0:0737f5596e3d 134 }
nxp_ip 0:0737f5596e3d 135
nxp_ip 0:0737f5596e3d 136 int i2c_write( char addr, char *dp, char length, char restart_flag ) {
nxp_ip 0:0737f5596e3d 137 return (
nxp_ip 0:0737f5596e3d 138 buffer_mode_enable ?
nxp_ip 0:0737f5596e3d 139 i2c_write_buffer_mode( addr, dp, length, restart_flag )
nxp_ip 0:0737f5596e3d 140 :
nxp_ip 0:0737f5596e3d 141 i2c_write_byte_mode( addr, dp, length, restart_flag )
nxp_ip 0:0737f5596e3d 142 );
nxp_ip 0:0737f5596e3d 143 }
nxp_ip 0:0737f5596e3d 144
nxp_ip 0:0737f5596e3d 145 int i2c_read( char addr, char *dp, char length, char restart_flag ) {
nxp_ip 0:0737f5596e3d 146 return (
nxp_ip 0:0737f5596e3d 147 buffer_mode_enable ?
nxp_ip 0:0737f5596e3d 148 i2c_read_buffer_mode( addr, dp, length, restart_flag )
nxp_ip 0:0737f5596e3d 149 :
nxp_ip 0:0737f5596e3d 150 i2c_read_byte_mode( addr, dp, length, restart_flag )
nxp_ip 0:0737f5596e3d 151 );
nxp_ip 0:0737f5596e3d 152 }
nxp_ip 0:0737f5596e3d 153
nxp_ip 0:0737f5596e3d 154
nxp_ip 0:0737f5596e3d 155 int i2c_write_buffer_mode( char addr, char *dp, char length, char restart_flag ) {
nxp_ip 0:0737f5596e3d 156 int done = BUS_CONTINUE;
nxp_ip 0:0737f5596e3d 157 char state;
nxp_ip 0:0737f5596e3d 158 char return_value = 0xFF;
nxp_ip 0:0737f5596e3d 159 #ifdef PCA9665_BURST_DATA_ACCESS
nxp_ip 0:0737f5596e3d 160 #else
nxp_ip 0:0737f5596e3d 161 int i;
nxp_ip 0:0737f5596e3d 162 #endif
nxp_ip 0:0737f5596e3d 163
nxp_ip 0:0737f5596e3d 164 if ( 67 < length )
nxp_ip 0:0737f5596e3d 165 return ( 0xFE );
nxp_ip 0:0737f5596e3d 166
nxp_ip 0:0737f5596e3d 167 write_data( I2CCON, 0x61 );
nxp_ip 0:0737f5596e3d 168
nxp_ip 0:0737f5596e3d 169 while ( !done ) {
nxp_ip 0:0737f5596e3d 170 if ( int_happened ) {
nxp_ip 0:0737f5596e3d 171 int_happened = 0;
nxp_ip 0:0737f5596e3d 172
nxp_ip 0:0737f5596e3d 173 state = read_data( I2CSTA );
nxp_ip 0:0737f5596e3d 174
nxp_ip 0:0737f5596e3d 175 switch ( state ) {
nxp_ip 0:0737f5596e3d 176 case MASTER_START_TXed :
nxp_ip 0:0737f5596e3d 177 case MASTER_RESTART_TXed :
nxp_ip 0:0737f5596e3d 178 indirect_write( I2CCOUNT, length + 1 );
nxp_ip 0:0737f5596e3d 179 write_data( I2CDAT, addr & 0xFE );
nxp_ip 0:0737f5596e3d 180
nxp_ip 0:0737f5596e3d 181 #ifdef PCA9665_BURST_DATA_ACCESS
nxp_ip 0:0737f5596e3d 182 write_data_burst( I2CDAT, dp, length );
nxp_ip 0:0737f5596e3d 183 #else
nxp_ip 0:0737f5596e3d 184 for ( i = 0; i < length; i++ )
nxp_ip 0:0737f5596e3d 185 write_data( I2CDAT, *dp++ );
nxp_ip 0:0737f5596e3d 186 #endif
nxp_ip 0:0737f5596e3d 187
nxp_ip 0:0737f5596e3d 188 write_data( I2CCON, 0x41 );
nxp_ip 0:0737f5596e3d 189 break;
nxp_ip 0:0737f5596e3d 190 case MASTER_SLA_W_ACK : // SLA+W TXed
nxp_ip 0:0737f5596e3d 191 case MASTER_DATA_W_ACK : // DATA TXed
nxp_ip 0:0737f5596e3d 192 return_value = 0x00;
nxp_ip 0:0737f5596e3d 193 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 194 break;
nxp_ip 0:0737f5596e3d 195 case MASTER_SLA_W_NAK :
nxp_ip 0:0737f5596e3d 196 case MASTER_DATA_W_NAK :
nxp_ip 0:0737f5596e3d 197 return_value = 0x01;
nxp_ip 0:0737f5596e3d 198 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 199 break;
nxp_ip 0:0737f5596e3d 200 case MASTER_ARB_LOST :
nxp_ip 0:0737f5596e3d 201 case SLAVE_AL_ADDRESSED_R :
nxp_ip 0:0737f5596e3d 202 case SLAVE_AL_ADDRESSED_W :
nxp_ip 0:0737f5596e3d 203 case SLAVE_GENERALCALL_AL :
nxp_ip 0:0737f5596e3d 204 /* bus should be released for other master */
nxp_ip 0:0737f5596e3d 205 default :
nxp_ip 0:0737f5596e3d 206 /* unexpected bus error */
nxp_ip 0:0737f5596e3d 207 done = BUS_RELEASE;
nxp_ip 0:0737f5596e3d 208 break;
nxp_ip 0:0737f5596e3d 209 }
nxp_ip 0:0737f5596e3d 210 }
nxp_ip 0:0737f5596e3d 211 }
nxp_ip 0:0737f5596e3d 212
nxp_ip 0:0737f5596e3d 213 if ( OP_MODE_MASTER_ONLY == op_mode_flag )
nxp_ip 0:0737f5596e3d 214 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 215
nxp_ip 0:0737f5596e3d 216 if ( (BUS_STOP == done) && !restart_flag )
nxp_ip 0:0737f5596e3d 217 write_data( I2CCON, 0x50 );
nxp_ip 0:0737f5596e3d 218
nxp_ip 0:0737f5596e3d 219 return ( return_value );
nxp_ip 0:0737f5596e3d 220 }
nxp_ip 0:0737f5596e3d 221
nxp_ip 0:0737f5596e3d 222 int i2c_read_buffer_mode( char addr, char *dp, char length, char restart_flag ) {
nxp_ip 0:0737f5596e3d 223 int done = BUS_CONTINUE;
nxp_ip 0:0737f5596e3d 224 char state;
nxp_ip 0:0737f5596e3d 225 char return_value = 0xFF;
nxp_ip 0:0737f5596e3d 226
nxp_ip 0:0737f5596e3d 227 #ifdef PCA9665_BURST_DATA_ACCESS
nxp_ip 0:0737f5596e3d 228 #else
nxp_ip 0:0737f5596e3d 229 int i;
nxp_ip 0:0737f5596e3d 230 #endif
nxp_ip 0:0737f5596e3d 231
nxp_ip 0:0737f5596e3d 232 if ( 68 < length )
nxp_ip 0:0737f5596e3d 233 return ( 0xFE );
nxp_ip 0:0737f5596e3d 234
nxp_ip 0:0737f5596e3d 235 if ( !length ) // zero byte read may cause invalid STOP to START signal output
nxp_ip 0:0737f5596e3d 236 return ( 0 );
nxp_ip 0:0737f5596e3d 237
nxp_ip 0:0737f5596e3d 238 write_data( I2CCON, 0x61 );
nxp_ip 0:0737f5596e3d 239
nxp_ip 0:0737f5596e3d 240 while ( !done ) {
nxp_ip 0:0737f5596e3d 241 if ( int_happened ) {
nxp_ip 0:0737f5596e3d 242 int_happened = 0;
nxp_ip 0:0737f5596e3d 243
nxp_ip 0:0737f5596e3d 244 state = read_data( I2CSTA );
nxp_ip 0:0737f5596e3d 245
nxp_ip 0:0737f5596e3d 246 switch ( state ) {
nxp_ip 0:0737f5596e3d 247 case MASTER_START_TXed :
nxp_ip 0:0737f5596e3d 248 case MASTER_RESTART_TXed :
nxp_ip 0:0737f5596e3d 249 write_data( I2CDAT, addr | 0x01 );
nxp_ip 0:0737f5596e3d 250 indirect_write( I2CCOUNT, length | 0x80 );
nxp_ip 0:0737f5596e3d 251 write_data( I2CCON, 0x41 );
nxp_ip 0:0737f5596e3d 252 break;
nxp_ip 0:0737f5596e3d 253 case MASTER_SLA_R_ACK : // SLA+R TXed
nxp_ip 0:0737f5596e3d 254 case MASTER_DATA_R_ACK : // DATA RXed
nxp_ip 0:0737f5596e3d 255 return_value = 0x00;
nxp_ip 0:0737f5596e3d 256 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 257 break;
nxp_ip 0:0737f5596e3d 258 case MASTER_SLA_R_NAK : // SLA+R TXed
nxp_ip 0:0737f5596e3d 259 return_value = 0x01;
nxp_ip 0:0737f5596e3d 260 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 261 break;
nxp_ip 0:0737f5596e3d 262 case MASTER_DATA_R_NAK :
nxp_ip 0:0737f5596e3d 263 return_value = length - (indirect_read( I2CCOUNT ) & 0x7F);
nxp_ip 0:0737f5596e3d 264 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 265
nxp_ip 0:0737f5596e3d 266 break;
nxp_ip 0:0737f5596e3d 267 case MASTER_ARB_LOST :
nxp_ip 0:0737f5596e3d 268 case SLAVE_AL_ADDRESSED_R :
nxp_ip 0:0737f5596e3d 269 case SLAVE_AL_ADDRESSED_W :
nxp_ip 0:0737f5596e3d 270 case SLAVE_GENERALCALL_AL :
nxp_ip 0:0737f5596e3d 271 /* bus should be released for other master */
nxp_ip 0:0737f5596e3d 272 default :
nxp_ip 0:0737f5596e3d 273 /* unexpected bus error */
nxp_ip 0:0737f5596e3d 274 done = BUS_RELEASE;
nxp_ip 0:0737f5596e3d 275 break;
nxp_ip 0:0737f5596e3d 276 }
nxp_ip 0:0737f5596e3d 277 }
nxp_ip 0:0737f5596e3d 278 }
nxp_ip 0:0737f5596e3d 279
nxp_ip 0:0737f5596e3d 280 #ifdef PCA9665_BURST_DATA_ACCESS
nxp_ip 0:0737f5596e3d 281 read_data_burst( I2CDAT, dp, length );
nxp_ip 0:0737f5596e3d 282 #else
nxp_ip 0:0737f5596e3d 283 for ( i = 0; i < length; i++ )
nxp_ip 0:0737f5596e3d 284 *dp++ = read_data( I2CDAT );
nxp_ip 0:0737f5596e3d 285 #endif
nxp_ip 0:0737f5596e3d 286
nxp_ip 0:0737f5596e3d 287 if ( OP_MODE_MASTER_ONLY == op_mode_flag )
nxp_ip 0:0737f5596e3d 288 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 289
nxp_ip 0:0737f5596e3d 290 if ( (BUS_STOP == done) && !restart_flag )
nxp_ip 0:0737f5596e3d 291 write_data( I2CCON, 0x50 );
nxp_ip 0:0737f5596e3d 292
nxp_ip 0:0737f5596e3d 293 return ( return_value );
nxp_ip 0:0737f5596e3d 294 }
nxp_ip 0:0737f5596e3d 295
nxp_ip 0:0737f5596e3d 296 int i2c_write_byte_mode( char addr, char *dp, char length, char restart_flag ) {
nxp_ip 0:0737f5596e3d 297 int done = BUS_CONTINUE;
nxp_ip 0:0737f5596e3d 298 char state;
nxp_ip 0:0737f5596e3d 299
nxp_ip 0:0737f5596e3d 300 write_data( I2CCON, 0x60 );
nxp_ip 0:0737f5596e3d 301
nxp_ip 0:0737f5596e3d 302 while ( !done ) {
nxp_ip 0:0737f5596e3d 303 if ( int_happened ) {
nxp_ip 0:0737f5596e3d 304 int_happened = 0;
nxp_ip 0:0737f5596e3d 305
nxp_ip 0:0737f5596e3d 306 state = read_data( I2CSTA );
nxp_ip 0:0737f5596e3d 307
nxp_ip 0:0737f5596e3d 308 switch ( state ) {
nxp_ip 0:0737f5596e3d 309 case MASTER_START_TXed :
nxp_ip 0:0737f5596e3d 310 case MASTER_RESTART_TXed :
nxp_ip 0:0737f5596e3d 311 write_data( I2CDAT, addr & 0xFE );
nxp_ip 0:0737f5596e3d 312 write_data( I2CCON, 0x40 );
nxp_ip 0:0737f5596e3d 313 break;
nxp_ip 0:0737f5596e3d 314 case MASTER_DATA_W_ACK : // DATA TXed
nxp_ip 0:0737f5596e3d 315 length--;
nxp_ip 0:0737f5596e3d 316 /* FALLTHROUGH */
nxp_ip 0:0737f5596e3d 317 case MASTER_SLA_W_ACK : // SLA+W TXed
nxp_ip 0:0737f5596e3d 318 if ( !length ) {
nxp_ip 0:0737f5596e3d 319 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 320 break;
nxp_ip 0:0737f5596e3d 321 }
nxp_ip 0:0737f5596e3d 322 write_data( I2CDAT, *dp++ );
nxp_ip 0:0737f5596e3d 323 write_data( I2CCON, 0x40 );
nxp_ip 0:0737f5596e3d 324 break;
nxp_ip 0:0737f5596e3d 325 case MASTER_SLA_W_NAK :
nxp_ip 0:0737f5596e3d 326 case MASTER_DATA_W_NAK :
nxp_ip 0:0737f5596e3d 327 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 328 break;
nxp_ip 0:0737f5596e3d 329 case MASTER_ARB_LOST :
nxp_ip 0:0737f5596e3d 330 case SLAVE_AL_ADDRESSED_R :
nxp_ip 0:0737f5596e3d 331 case SLAVE_AL_ADDRESSED_W :
nxp_ip 0:0737f5596e3d 332 case SLAVE_GENERALCALL_AL :
nxp_ip 0:0737f5596e3d 333 /* bus should be released for other master */
nxp_ip 0:0737f5596e3d 334 default :
nxp_ip 0:0737f5596e3d 335 /* unexpected bus error */
nxp_ip 0:0737f5596e3d 336 done = BUS_RELEASE;
nxp_ip 0:0737f5596e3d 337 break;
nxp_ip 0:0737f5596e3d 338 }
nxp_ip 0:0737f5596e3d 339 }
nxp_ip 0:0737f5596e3d 340 }
nxp_ip 0:0737f5596e3d 341
nxp_ip 0:0737f5596e3d 342 if ( OP_MODE_MASTER_ONLY == op_mode_flag )
nxp_ip 0:0737f5596e3d 343 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 344
nxp_ip 0:0737f5596e3d 345 if ( (BUS_STOP == done) && !restart_flag )
nxp_ip 0:0737f5596e3d 346 write_data( I2CCON, 0x50 );
nxp_ip 0:0737f5596e3d 347
nxp_ip 0:0737f5596e3d 348 return ( length );
nxp_ip 0:0737f5596e3d 349 }
nxp_ip 0:0737f5596e3d 350
nxp_ip 0:0737f5596e3d 351 int i2c_read_byte_mode( char addr, char *dp, char length, char restart_flag ) {
nxp_ip 0:0737f5596e3d 352 int done = BUS_CONTINUE;
nxp_ip 0:0737f5596e3d 353 char state;
nxp_ip 0:0737f5596e3d 354
nxp_ip 0:0737f5596e3d 355 if ( !length ) // zero byte read may cause invalid STOP to START signal output
nxp_ip 0:0737f5596e3d 356 return ( 0 );
nxp_ip 0:0737f5596e3d 357
nxp_ip 0:0737f5596e3d 358 write_data( I2CCON, 0x60 );
nxp_ip 0:0737f5596e3d 359
nxp_ip 0:0737f5596e3d 360 while ( !done ) {
nxp_ip 0:0737f5596e3d 361 if ( int_happened ) {
nxp_ip 0:0737f5596e3d 362 int_happened = 0;
nxp_ip 0:0737f5596e3d 363
nxp_ip 0:0737f5596e3d 364 state = read_data( I2CSTA );
nxp_ip 0:0737f5596e3d 365
nxp_ip 0:0737f5596e3d 366 switch ( state ) {
nxp_ip 0:0737f5596e3d 367 case MASTER_START_TXed :
nxp_ip 0:0737f5596e3d 368 case MASTER_RESTART_TXed :
nxp_ip 0:0737f5596e3d 369 write_data( I2CDAT, addr | 0x01 );
nxp_ip 0:0737f5596e3d 370 write_data( I2CCON, 0x40 );
nxp_ip 0:0737f5596e3d 371 break;
nxp_ip 0:0737f5596e3d 372 case MASTER_DATA_R_NAK :
nxp_ip 0:0737f5596e3d 373 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 374 /* FALLTHROUGH */
nxp_ip 0:0737f5596e3d 375 case MASTER_DATA_R_ACK : // DATA RXed
nxp_ip 0:0737f5596e3d 376 *dp++ = read_data( I2CDAT );
nxp_ip 0:0737f5596e3d 377 length--;
nxp_ip 0:0737f5596e3d 378 /* FALLTHROUGH */
nxp_ip 0:0737f5596e3d 379 case MASTER_SLA_R_ACK : // SLA+R TXed
nxp_ip 0:0737f5596e3d 380 if ( !length )
nxp_ip 0:0737f5596e3d 381 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 382
nxp_ip 0:0737f5596e3d 383 if ( !done )
nxp_ip 0:0737f5596e3d 384 write_data( I2CCON, (length == 1) ? 0x40 : 0xC0 );
nxp_ip 0:0737f5596e3d 385 break;
nxp_ip 0:0737f5596e3d 386 case MASTER_SLA_R_NAK :
nxp_ip 0:0737f5596e3d 387 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 388 break;
nxp_ip 0:0737f5596e3d 389 case MASTER_ARB_LOST :
nxp_ip 0:0737f5596e3d 390 case SLAVE_AL_ADDRESSED_R :
nxp_ip 0:0737f5596e3d 391 case SLAVE_AL_ADDRESSED_W :
nxp_ip 0:0737f5596e3d 392 case SLAVE_GENERALCALL_AL :
nxp_ip 0:0737f5596e3d 393 /* bus should be released for other master */
nxp_ip 0:0737f5596e3d 394 default :
nxp_ip 0:0737f5596e3d 395 /* unexpected bus error */
nxp_ip 0:0737f5596e3d 396 done = BUS_RELEASE;
nxp_ip 0:0737f5596e3d 397 break;
nxp_ip 0:0737f5596e3d 398 }
nxp_ip 0:0737f5596e3d 399 }
nxp_ip 0:0737f5596e3d 400 }
nxp_ip 0:0737f5596e3d 401
nxp_ip 0:0737f5596e3d 402 if ( OP_MODE_MASTER_ONLY == op_mode_flag )
nxp_ip 0:0737f5596e3d 403 done = BUS_STOP;
nxp_ip 0:0737f5596e3d 404
nxp_ip 0:0737f5596e3d 405 if ( (BUS_STOP == done) && !restart_flag )
nxp_ip 0:0737f5596e3d 406 write_data( I2CCON, 0x50 );
nxp_ip 0:0737f5596e3d 407
nxp_ip 0:0737f5596e3d 408 return ( length );
nxp_ip 0:0737f5596e3d 409 }
nxp_ip 0:0737f5596e3d 410
nxp_ip 0:0737f5596e3d 411 void indirect_write( char idaddr, char data ) {
nxp_ip 0:0737f5596e3d 412 write_data( INDPTR, idaddr );
nxp_ip 0:0737f5596e3d 413 write_data( INDIRECT, data );
nxp_ip 0:0737f5596e3d 414 }
nxp_ip 0:0737f5596e3d 415
nxp_ip 0:0737f5596e3d 416 char indirect_read( char idaddr ) {
nxp_ip 0:0737f5596e3d 417 write_data( INDPTR, idaddr );
nxp_ip 0:0737f5596e3d 418 return ( read_data( INDIRECT ) );
nxp_ip 0:0737f5596e3d 419 }