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
Diff: mini_board_libs/parallel_bus/hardware_abs.c
- Revision:
- 5:57c345099873
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mini_board_libs/parallel_bus/hardware_abs.c Mon Mar 26 06:17:23 2012 +0000 @@ -0,0 +1,220 @@ +/** A sample code for "mini board PCU9669/PCA9665" + * + * @author Tedd OKANO, NXP Semiconductors + * @version 0.9 + * @date 14-Feb-2011 + * + * Released under the MIT License: http://mbed.org/license/mit + * + * An operation sample of PCU9669/PCA9665 I2C bus controller. + * The mbed accesses the bus controller's parallel port (8/2 bit address and 8 bit data) by bit-banging. + * The bit-banging is poerformed by PortInOut function of mbed library. + * + * To make the code porting easier, all codes are partitioned into layers to abstract other parts. + * The mbed specific parts are concentrated in lowest layer: "hardware_abs.*". + * This module may need to be modified for the porting. + * + * All other upper layers are writen in standard-C. + * + * base code is written from 05-Sep-2011 to 09-Sep-2011. + * And demo code has been build on 11-Sep-2011. + * Debug and code adjustment has been done on 08-Sep-2011. + * Small sanitization for main.cpp. All mbed related codes are moved in to "hardware_abs.*". 13-Oct-2011 + * hardware_abs are moved into parallel_bus library folder, 3 LED driver operation sample 13-Feb.-2012 + * PCU9669 and PCA9665 codes are packed in a project 14-Feb-2012. + * + * Before builidng the code, please edit the file mini_board_PCU9669/config.h + * Uncomment the target name what you want to target. + */ + +/* + * "hardware_abs" module has been made to abstract hardware: Hardware abstract layer + * This is file which will be modified when the porting done for other MCUs. + */ + +/* + * This sample code has been made for mbed. The code emulates parallel SRAM bus using the mbed's GPIO ports. + * To maximize the port access speed, PortOut and PortInOut libraly used. + */ + +#include "mbed.h" +#include "hardware_abs.h" + +// GPIO port setting + +#define ADDR_MASK 0x07878000 // 8 bit address mask on PORT0: Address value will be set into this bit position +#define DATA_MASK 0x00000FF0 // 8 bit data mask on PORT0: Data value will be appeared on this bit position +#define CONTROL_MASK 0x00000038 // Control signals CS=bit5(pin21), WR=bit4(pin22), RD=bit3(pin23) + +PortOut addr_port( Port0, ADDR_MASK ); +PortInOut data_port( Port0, DATA_MASK ); +PortOut ctrl_port( Port2, CONTROL_MASK ); +InterruptIn int_port( p26 ); + +// The very early version of PCU9669 mini board has different configuration. +// Following part switches the port configuration for those board versions. + +//#define PROTOTYPE_BREADBOARD + +DigitalInOut reset_port( p20 ); +//DigitalOut trig_port( p19 ); + +// Next two macros defines interface for temporaly interrupt disable/enable functions. +// These macros are used to blocking interrupt until a bus access cycle completed. +// Because if the interrupt happened in a cycle, the emulated parallel port state will be disturbed. +// For the mbed, library routine: __disable_irq() / __enable_irq() can be used. + +#define interrupt_enable() __enable_irq() +#define interrupt_disable() __disable_irq() + +// "prev_access_was_write" is a variable to keep the previous data directions. +// Using this flag, successive write and read addess overhead can be reduced. +// This mechanism will not be required if the MCU has parallel port + +char prev_access_was_write; + +// ISR routine installer + +void install_ISR( void (*fptr)(void) ) { + int_port.fall( fptr ); +} + +// Hardware initialize: it defines initial state of the (emulated) parallel bus + +void hardware_initialize( void ) { + prev_access_was_write = 0; + ctrl_port = 0x38; // CS, WR and RD are deaserted (HIGH) + data_port.input(); // data bus set to Hi-Z + reset_port.output(); + reset_port.mode( PullUp ); +} + +// Hardware reset for PCU9669: It asserts RESET signal for 4us and waits 650us after deassert (reset recovery time) + +void reset( int reset_pulse_width_us, int reset_recovery_us ) { + hardware_reset( ASSERT ); // Minimum pulse width is 4us for PCU9669 + hw_wait_us( reset_pulse_width_us ); + hardware_reset( DEASSERT ); // deassert hardware /RESET sgnal + hw_wait_us( reset_recovery_us ); +} + +// Interface to Control hardware RESET signal + +void hardware_reset( char signal ) { + reset_port = signal; +} + +// Interface to Control hardware TRIGGER signal + +void hardware_trigger( char signal ) { +// trig_port = signal; +} + +// Single write cycle on (emulated) parallel bus + +void write_data( char addr, char data ) { + interrupt_disable(); // disable interrupt first + + addr_port = (addr << 19) | (addr << 15); // Address output + ctrl_port = 0x08; // Assert CS and WR signals + + if ( !prev_access_was_write ) // Data bus direction control + data_port.output(); + + prev_access_was_write = 1; + + data_port = data << 4; // Data output + ctrl_port = 0x38; // Deassert CS and WR + + interrupt_enable(); // enable interrupt again +} + + +char read_data( char addr ) { + volatile char tmp; + interrupt_disable(); // disable interrupt first + + if ( prev_access_was_write ) // Data bus direction control + data_port.input(); + + prev_access_was_write = 0; + + addr_port = (addr << 19) | (addr << 15); // Address output + ctrl_port = 0x10; // Assert CS and RD signals + ctrl_port = 0x10; // asserting CS and RD pulse twice (but those are kept LOW) to wait short time till actual read timing + tmp = (data_port >> 4) & 0xFF; // Read data bus into var + ctrl_port = 0x38; // Deassert CS and RD + + interrupt_enable(); // enable interrupt again + + return ( tmp ); +} + +// Wait for micro-seconds + +void hw_wait_us( int v ) { + wait_us( v ); +} + +// Wait for seconds + +void wait_sec( float f ) { + wait( f ); +} + +// Following part is an optionto accerelate bus access. +// If such trick is not required, undefine the "BURST_DATA_ACCESS" and don't touch it. +// +// Next two functions access single address with repeating read/write. +// The repeating read/write are used often for PCU9669 like SLATABLE, TRANCONFIG and DATA (buffer accesses). +// So this accerelation contributes saving MCU time. +// +// For the porting, it may be good idea to modify those routines to DMA access. + +#ifdef BURST_DATA_ACCESS + +void write_data_burst( char addr, char *data, char length ) { + int i; + + interrupt_disable(); // disable interrupt first + + addr_port = (addr << 19) | (addr << 15); // Address output + + if ( !prev_access_was_write ) // Data bus direction control + data_port.output(); + + prev_access_was_write = 1; + + for ( i = 0; i < length; i++ ) { // repeat data write access + ctrl_port = 0x08; + data_port = *(data + i) << 4; + ctrl_port = 0x38; + } + + interrupt_enable(); +} + +void read_data_burst( char addr, char *data, char length ) { + int i; + + interrupt_disable(); // disable interrupt first + + addr_port = (addr << 19) | (addr << 15); // Address output + + if ( prev_access_was_write ) // Data bus direction control + data_port.input(); + + prev_access_was_write = 0; + + for ( i = 0; i < length; i++ ) { // repeat data read access + ctrl_port = 0x10; + ctrl_port = 0x10; + + *(data + i) = (data_port >> 4) & 0xFF; + ctrl_port = 0x38; + } + interrupt_enable(); +} + +#endif +