Mini board PCU9669 evaluation kit library

Dependents:   mini_board_PCU9669

Committer:
nxp_ip
Date:
Wed Jul 11 11:18:52 2012 +0000
Revision:
3:930ef1a6bc99
Parent:
2:da1b02ca97ee
Child:
4:b69135913a8f
for mini_board_PCU9669 v1.1 release

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 1:d7f7e0790f60 3 * @author Akifumi (Tedd) OKANO, NXP Semiconductors
nxp_ip 3:930ef1a6bc99 4 * @version 1.1
nxp_ip 3:930ef1a6bc99 5 * @date 11-Jul-2012
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 }