mini board PCU9669 (and PCA9665) sample code
Dependencies: mbed PCU9669 utility PCA9665 I2C_slaves parallel_bus
Fork of mini_board_PCU9669_old by
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
mini_board_libs/parallel_bus/hardware_abs.c@5:57c345099873, 2012-03-26 (annotated)
- 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?
User | Revision | Line number | New 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 |