Mini board PCU9669 evaluation kit library

Dependents:   mini_board_PCU9669

Committer:
nxp_ip
Date:
Wed Jan 14 04:30:37 2015 +0000
Revision:
4:b69135913a8f
Parent:
3:930ef1a6bc99
PCA9665 error handling improved

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