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 /*
nxp_ip 5:57c345099873 31 * "hardware_abs" module has been made to abstract hardware: Hardware abstract layer
nxp_ip 5:57c345099873 32 * This is file which will be modified when the porting done for other MCUs.
nxp_ip 5:57c345099873 33 */
nxp_ip 5:57c345099873 34
nxp_ip 5:57c345099873 35 /*
nxp_ip 5:57c345099873 36 * This sample code has been made for mbed. The code emulates parallel SRAM bus using the mbed's GPIO ports.
nxp_ip 5:57c345099873 37 * To maximize the port access speed, PortOut and PortInOut libraly used.
nxp_ip 5:57c345099873 38 */
nxp_ip 5:57c345099873 39
nxp_ip 5:57c345099873 40 #include "mbed.h"
nxp_ip 5:57c345099873 41 #include "hardware_abs.h"
nxp_ip 5:57c345099873 42
nxp_ip 5:57c345099873 43 // GPIO port setting
nxp_ip 5:57c345099873 44
nxp_ip 5:57c345099873 45 #define ADDR_MASK 0x07878000 // 8 bit address mask on PORT0: Address value will be set into this bit position
nxp_ip 5:57c345099873 46 #define DATA_MASK 0x00000FF0 // 8 bit data mask on PORT0: Data value will be appeared on this bit position
nxp_ip 5:57c345099873 47 #define CONTROL_MASK 0x00000038 // Control signals CS=bit5(pin21), WR=bit4(pin22), RD=bit3(pin23)
nxp_ip 5:57c345099873 48
nxp_ip 5:57c345099873 49 PortOut addr_port( Port0, ADDR_MASK );
nxp_ip 5:57c345099873 50 PortInOut data_port( Port0, DATA_MASK );
nxp_ip 5:57c345099873 51 PortOut ctrl_port( Port2, CONTROL_MASK );
nxp_ip 5:57c345099873 52 InterruptIn int_port( p26 );
nxp_ip 5:57c345099873 53
nxp_ip 5:57c345099873 54 // The very early version of PCU9669 mini board has different configuration.
nxp_ip 5:57c345099873 55 // Following part switches the port configuration for those board versions.
nxp_ip 5:57c345099873 56
nxp_ip 5:57c345099873 57 //#define PROTOTYPE_BREADBOARD
nxp_ip 5:57c345099873 58
nxp_ip 5:57c345099873 59 DigitalInOut reset_port( p20 );
nxp_ip 5:57c345099873 60 //DigitalOut trig_port( p19 );
nxp_ip 5:57c345099873 61
nxp_ip 5:57c345099873 62 // Next two macros defines interface for temporaly interrupt disable/enable functions.
nxp_ip 5:57c345099873 63 // These macros are used to blocking interrupt until a bus access cycle completed.
nxp_ip 5:57c345099873 64 // Because if the interrupt happened in a cycle, the emulated parallel port state will be disturbed.
nxp_ip 5:57c345099873 65 // For the mbed, library routine: __disable_irq() / __enable_irq() can be used.
nxp_ip 5:57c345099873 66
nxp_ip 5:57c345099873 67 #define interrupt_enable() __enable_irq()
nxp_ip 5:57c345099873 68 #define interrupt_disable() __disable_irq()
nxp_ip 5:57c345099873 69
nxp_ip 5:57c345099873 70 // "prev_access_was_write" is a variable to keep the previous data directions.
nxp_ip 5:57c345099873 71 // Using this flag, successive write and read addess overhead can be reduced.
nxp_ip 5:57c345099873 72 // This mechanism will not be required if the MCU has parallel port
nxp_ip 5:57c345099873 73
nxp_ip 5:57c345099873 74 char prev_access_was_write;
nxp_ip 5:57c345099873 75
nxp_ip 5:57c345099873 76 // ISR routine installer
nxp_ip 5:57c345099873 77
nxp_ip 5:57c345099873 78 void install_ISR( void (*fptr)(void) ) {
nxp_ip 5:57c345099873 79 int_port.fall( fptr );
nxp_ip 5:57c345099873 80 }
nxp_ip 5:57c345099873 81
nxp_ip 5:57c345099873 82 // Hardware initialize: it defines initial state of the (emulated) parallel bus
nxp_ip 5:57c345099873 83
nxp_ip 5:57c345099873 84 void hardware_initialize( void ) {
nxp_ip 5:57c345099873 85 prev_access_was_write = 0;
nxp_ip 5:57c345099873 86 ctrl_port = 0x38; // CS, WR and RD are deaserted (HIGH)
nxp_ip 5:57c345099873 87 data_port.input(); // data bus set to Hi-Z
nxp_ip 5:57c345099873 88 reset_port.output();
nxp_ip 5:57c345099873 89 reset_port.mode( PullUp );
nxp_ip 5:57c345099873 90 }
nxp_ip 5:57c345099873 91
nxp_ip 5:57c345099873 92 // Hardware reset for PCU9669: It asserts RESET signal for 4us and waits 650us after deassert (reset recovery time)
nxp_ip 5:57c345099873 93
nxp_ip 5:57c345099873 94 void reset( int reset_pulse_width_us, int reset_recovery_us ) {
nxp_ip 5:57c345099873 95 hardware_reset( ASSERT ); // Minimum pulse width is 4us for PCU9669
nxp_ip 5:57c345099873 96 hw_wait_us( reset_pulse_width_us );
nxp_ip 5:57c345099873 97 hardware_reset( DEASSERT ); // deassert hardware /RESET sgnal
nxp_ip 5:57c345099873 98 hw_wait_us( reset_recovery_us );
nxp_ip 5:57c345099873 99 }
nxp_ip 5:57c345099873 100
nxp_ip 5:57c345099873 101 // Interface to Control hardware RESET signal
nxp_ip 5:57c345099873 102
nxp_ip 5:57c345099873 103 void hardware_reset( char signal ) {
nxp_ip 5:57c345099873 104 reset_port = signal;
nxp_ip 5:57c345099873 105 }
nxp_ip 5:57c345099873 106
nxp_ip 5:57c345099873 107 // Interface to Control hardware TRIGGER signal
nxp_ip 5:57c345099873 108
nxp_ip 5:57c345099873 109 void hardware_trigger( char signal ) {
nxp_ip 5:57c345099873 110 // trig_port = signal;
nxp_ip 5:57c345099873 111 }
nxp_ip 5:57c345099873 112
nxp_ip 5:57c345099873 113 // Single write cycle on (emulated) parallel bus
nxp_ip 5:57c345099873 114
nxp_ip 5:57c345099873 115 void write_data( char addr, char data ) {
nxp_ip 5:57c345099873 116 interrupt_disable(); // disable interrupt first
nxp_ip 5:57c345099873 117
nxp_ip 5:57c345099873 118 addr_port = (addr << 19) | (addr << 15); // Address output
nxp_ip 5:57c345099873 119 ctrl_port = 0x08; // Assert CS and WR signals
nxp_ip 5:57c345099873 120
nxp_ip 5:57c345099873 121 if ( !prev_access_was_write ) // Data bus direction control
nxp_ip 5:57c345099873 122 data_port.output();
nxp_ip 5:57c345099873 123
nxp_ip 5:57c345099873 124 prev_access_was_write = 1;
nxp_ip 5:57c345099873 125
nxp_ip 5:57c345099873 126 data_port = data << 4; // Data output
nxp_ip 5:57c345099873 127 ctrl_port = 0x38; // Deassert CS and WR
nxp_ip 5:57c345099873 128
nxp_ip 5:57c345099873 129 interrupt_enable(); // enable interrupt again
nxp_ip 5:57c345099873 130 }
nxp_ip 5:57c345099873 131
nxp_ip 5:57c345099873 132
nxp_ip 5:57c345099873 133 char read_data( char addr ) {
nxp_ip 5:57c345099873 134 volatile char tmp;
nxp_ip 5:57c345099873 135 interrupt_disable(); // disable interrupt first
nxp_ip 5:57c345099873 136
nxp_ip 5:57c345099873 137 if ( prev_access_was_write ) // Data bus direction control
nxp_ip 5:57c345099873 138 data_port.input();
nxp_ip 5:57c345099873 139
nxp_ip 5:57c345099873 140 prev_access_was_write = 0;
nxp_ip 5:57c345099873 141
nxp_ip 5:57c345099873 142 addr_port = (addr << 19) | (addr << 15); // Address output
nxp_ip 5:57c345099873 143 ctrl_port = 0x10; // Assert CS and RD signals
nxp_ip 5:57c345099873 144 ctrl_port = 0x10; // asserting CS and RD pulse twice (but those are kept LOW) to wait short time till actual read timing
nxp_ip 5:57c345099873 145 tmp = (data_port >> 4) & 0xFF; // Read data bus into var
nxp_ip 5:57c345099873 146 ctrl_port = 0x38; // Deassert CS and RD
nxp_ip 5:57c345099873 147
nxp_ip 5:57c345099873 148 interrupt_enable(); // enable interrupt again
nxp_ip 5:57c345099873 149
nxp_ip 5:57c345099873 150 return ( tmp );
nxp_ip 5:57c345099873 151 }
nxp_ip 5:57c345099873 152
nxp_ip 5:57c345099873 153 // Wait for micro-seconds
nxp_ip 5:57c345099873 154
nxp_ip 5:57c345099873 155 void hw_wait_us( int v ) {
nxp_ip 5:57c345099873 156 wait_us( v );
nxp_ip 5:57c345099873 157 }
nxp_ip 5:57c345099873 158
nxp_ip 5:57c345099873 159 // Wait for seconds
nxp_ip 5:57c345099873 160
nxp_ip 5:57c345099873 161 void wait_sec( float f ) {
nxp_ip 5:57c345099873 162 wait( f );
nxp_ip 5:57c345099873 163 }
nxp_ip 5:57c345099873 164
nxp_ip 5:57c345099873 165 // Following part is an optionto accerelate bus access.
nxp_ip 5:57c345099873 166 // If such trick is not required, undefine the "BURST_DATA_ACCESS" and don't touch it.
nxp_ip 5:57c345099873 167 //
nxp_ip 5:57c345099873 168 // Next two functions access single address with repeating read/write.
nxp_ip 5:57c345099873 169 // The repeating read/write are used often for PCU9669 like SLATABLE, TRANCONFIG and DATA (buffer accesses).
nxp_ip 5:57c345099873 170 // So this accerelation contributes saving MCU time.
nxp_ip 5:57c345099873 171 //
nxp_ip 5:57c345099873 172 // For the porting, it may be good idea to modify those routines to DMA access.
nxp_ip 5:57c345099873 173
nxp_ip 5:57c345099873 174 #ifdef BURST_DATA_ACCESS
nxp_ip 5:57c345099873 175
nxp_ip 5:57c345099873 176 void write_data_burst( char addr, char *data, char length ) {
nxp_ip 5:57c345099873 177 int i;
nxp_ip 5:57c345099873 178
nxp_ip 5:57c345099873 179 interrupt_disable(); // disable interrupt first
nxp_ip 5:57c345099873 180
nxp_ip 5:57c345099873 181 addr_port = (addr << 19) | (addr << 15); // Address output
nxp_ip 5:57c345099873 182
nxp_ip 5:57c345099873 183 if ( !prev_access_was_write ) // Data bus direction control
nxp_ip 5:57c345099873 184 data_port.output();
nxp_ip 5:57c345099873 185
nxp_ip 5:57c345099873 186 prev_access_was_write = 1;
nxp_ip 5:57c345099873 187
nxp_ip 5:57c345099873 188 for ( i = 0; i < length; i++ ) { // repeat data write access
nxp_ip 5:57c345099873 189 ctrl_port = 0x08;
nxp_ip 5:57c345099873 190 data_port = *(data + i) << 4;
nxp_ip 5:57c345099873 191 ctrl_port = 0x38;
nxp_ip 5:57c345099873 192 }
nxp_ip 5:57c345099873 193
nxp_ip 5:57c345099873 194 interrupt_enable();
nxp_ip 5:57c345099873 195 }
nxp_ip 5:57c345099873 196
nxp_ip 5:57c345099873 197 void read_data_burst( char addr, char *data, char length ) {
nxp_ip 5:57c345099873 198 int i;
nxp_ip 5:57c345099873 199
nxp_ip 5:57c345099873 200 interrupt_disable(); // disable interrupt first
nxp_ip 5:57c345099873 201
nxp_ip 5:57c345099873 202 addr_port = (addr << 19) | (addr << 15); // Address output
nxp_ip 5:57c345099873 203
nxp_ip 5:57c345099873 204 if ( prev_access_was_write ) // Data bus direction control
nxp_ip 5:57c345099873 205 data_port.input();
nxp_ip 5:57c345099873 206
nxp_ip 5:57c345099873 207 prev_access_was_write = 0;
nxp_ip 5:57c345099873 208
nxp_ip 5:57c345099873 209 for ( i = 0; i < length; i++ ) { // repeat data read access
nxp_ip 5:57c345099873 210 ctrl_port = 0x10;
nxp_ip 5:57c345099873 211 ctrl_port = 0x10;
nxp_ip 5:57c345099873 212
nxp_ip 5:57c345099873 213 *(data + i) = (data_port >> 4) & 0xFF;
nxp_ip 5:57c345099873 214 ctrl_port = 0x38;
nxp_ip 5:57c345099873 215 }
nxp_ip 5:57c345099873 216 interrupt_enable();
nxp_ip 5:57c345099873 217 }
nxp_ip 5:57c345099873 218
nxp_ip 5:57c345099873 219 #endif
nxp_ip 5:57c345099873 220