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
Revision 10:47974d9e6a5f, committed 2012-07-06
- Comitter:
- nxp_ip
- Date:
- Fri Jul 06 08:30:10 2012 +0000
- Parent:
- 9:7a7d4292dfe9
- Child:
- 11:c906afc20aa3
- Child:
- 12:da04417f8739
- Commit message:
- bug of "PCU9669_BURST_DATA_ACCESS" has been fixed
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mini_board_libs/PCU9669/.lib Fri Jul 06 08:30:10 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/nxp_ip/libraries/PCU9669/m7k5x2 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mini_board_libs/PCU9669/PCU9669_access.c Fri Jul 06 08:30:10 2012 +0000 @@ -0,0 +1,130 @@ +/** A sample code for "mini board PCU9669/PCA9665" + * + * @author Akifumi (Tedd) OKANO, NXP Semiconductors + * @version 1.0 + * @date 26-Mar-2012 + * + * 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 + * Un-comment the target name what you want to target. + */ + +/* + * "PCU9669_access" module abstracts PCU9669 register and data buffer access. + * This gives simple interface to the bus controller. + * All this interface works on "hardware_abs" module. + */ + +#include "PCU9669_access.h" // PCU9669 chip access interface +#include "hardware_abs.h" // Using hardware abstraction interface + +// +// prototypes (module private function prototypes) +// + +int is_bus_controller_ready( void ); +int check_device_ID( char target_id ); +void registers_initialize( void ); + +// variables + +char device_id_code; // keeps CHIP_ID value +char ch_ofst[] = { OFFSET_CH0, OFFSET_CH1, OFFSET_CH2 }; // Address offsets of channel registers + +// Channel register writing function + +void write_ch_register( char ch, char reg, char val ) { + write_data( ch_ofst[ ch ] + reg, val ); +} + +// Channel register reading function + +char read_ch_register( char ch, char reg ) { + return( read_data( ch_ofst[ ch ] + reg ) ); +} + +// Start routine: It checks the bus controller can be accessed, chip-ID value and initializes registers. + +int start_bus_controller( char target_id ) { + if ( is_bus_controller_ready() ) + return 1; + + if ( check_device_ID( target_id ) ) + return 2; + + registers_initialize(); + + return 0; +} + +// (module private finction, called by start_bus_controller) +// checks if the bus controller can be accessed + +int is_bus_controller_ready( void ) { + return ( read_data( CTRLRDY ) ); +} + +// (module private finction, called by start_bus_controller) +// checks if chip-ID value is same as expected. The "TARGET_BUS_CONTROLLER" value can be modified in "PCU9669_access.h" + +int check_device_ID( char target_id ) { + device_id_code = read_data( DEVICE_ID ); +// printf( "Target chip: PC%c96%02X, ID register value = 0x%02X\r\n", device_id_code & 0x80 ? 'U' : 'A', device_id_code & 0x7F, device_id_code ); + + return ( target_id == device_id_code ) ? 0 : -1; +} + +// (module private finction, called by start_bus_controller) +// register initializations. + +void registers_initialize( void ) { + + // The PCU9669 does not require any specical register initializations. + // It can start data transfer with default register settings. + // + // Or, if you need to have specific settings modify this function like following sample. + +#if 0 + write_ch_register( CH_UFM1, SCLPER, 32 ); + write_ch_register( CH_UFM1, SDADLY, 2 ); + write_ch_register( CH_UFM2, SCLPER, 32 ); + write_ch_register( CH_UFM2, SDADLY, 2 ); +#endif +} + +// Next functions are option. +// if the BURST_DATA_ACCESS is defined in "hardware_abs.h", it is propagated to define "PCU9669_BURST_DATA_ACCESS" +// These interface may be useful for table and buffer access + +#ifdef PCU9669_BURST_DATA_ACCESS + +void write_ch_register_burst( char ch, char reg, char *vp, char length ) { + write_data_burst( ch_ofst[ ch ] + reg, vp, length ); +} + +void read_ch_register_burst( char ch, char reg, char *vp, char length ) { + read_data_burst( ch_ofst[ ch ] + reg, vp, length ); +} + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mini_board_libs/PCU9669/PCU9669_access.h Fri Jul 06 08:30:10 2012 +0000 @@ -0,0 +1,192 @@ +/** A sample code for "mini board PCU9669/PCA9665" + * + * @author Akifumi (Tedd) OKANO, NXP Semiconductors + * @version 1.0 + * @date 26-Mar-2012 + * + * 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 + * Un-comment the target name what you want to target. + */ + +/** PCU9669 abstraction layer module + * + * Common access method is abstracted in this module. + * Each channel's registers, global registers and buffer access can be through these interface. + * This module works on top of hardware abstraction layer. + */ + +#ifndef __PCU9669_ACCESS__ +#define __PCU9669_ACCESS__ + +#include "hardware_abs.h" + +/** @def PCU9669_ID / PCA9663_ID / TARGET_BUS_CONTROLLER + * + * Device IDs which can be read from DEVICE_ID register. + * This value may need to be checked before the operation start. + */ +#define PCU9669_ID 0xE9 +#define PCA9663_ID 0x63 +//#define TARGET_BUS_CONTROLLER PCA9663_ID + +/** @def CH_FM_PLUS / CH_UFM1 / CH_UFM2 + * + * Channel number abstracted by its characters. + */ +#define CH_FM_PLUS 0 +#define CH_UFM1 1 +#define CH_UFM2 2 + +#define CH_0 0 +#define CH_1 1 +#define CH_2 2 + +/** @var Register names + * + * PCU9669/9663 internal register name and addesses + */ +typedef enum { + + // channel registers + + CONTROL = 0x00, // These are register offsets. offset base CH0=0xC0, CH1=0xD0, CH2=0xE0 + CHSTATUS, + INTMSK, + SLATABLE, + TRANCONFIG, + DATA, + TRANSEL, + TRANOFS, + BYTECOUNT, + FRAMECNT, + REFRATE, + SCLL, + SCLH, + MODE, + TIMEOUT, + PRESET, + + SCLPER = 0x0B, + SDADLY = 0x0C, + RESERVED = 0x0E, + + // global registers + + CTRLSTATUS = 0xF0, + CTRLINTMSK, + DEVICE_ID = 0xF6, + CTRLPRESET, + CTRLRDY = 0xFF, + + OFFSET_CH0 = 0xC0, + OFFSET_CH1 = 0xD0, + OFFSET_CH2 = 0xE0, + +} RegisterName; + + +/** @var Devide ID code + * + * Keeps the value which is read from DEVICE_ID register + */ +extern char device_id_code; + + +/** Write channel register + * + * Writing 8 bit data into register in specified channel. + * Register address offset of each channels is added in this function. + * + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @param reg target channel register: RegisterName + * @param val target of channel: 8 bit value + * @see read_ch_register() + */ +void write_ch_register( char ch, char reg, char val ); + +/** Read channel register + * + * Read 8 bit data from register in specified channel. + * Register address offset of each channels is added in this function. + * + * @return 8 bit value from the register + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @param reg target channel register: RegisterName + * @see write_ch_register() + */ +char read_ch_register( char ch, char reg ); + +/** Starting the bus controller (i.e. PCU9669) + * + * Checks the bus controller get ready, and ChipID is correct + * Then neccesary register initializations are done. + * In this reference code, no register initialization done. + * But if user need to do some, edit a module-private function "registers_initialize()" in "PCU9669_access.cpp" + * + * @return ZERO for no error, 1 for PCU9669 couldn't get ready after reset, 2 for ChipID was not match. + */ +int start_bus_controller( char target_id ); + + +/** BURST_DATA_ACCESS option code + * + * Following code is enabled only when BURST_DATA_ACCESS is defined in "hardware_abs.h" + */ +#ifdef BURST_DATA_ACCESS + +/** @def PCU9669_BURST_DATA_ACCESS + * + * PCU9669_BURST_DATA_ACCESS is defied to let upper layer know the burst access is available. + * This happens onlny BURST_DATA_ACCESS is defined in "hardware_abs.h" + */ +#define PCU9669_BURST_DATA_ACCESS + +/** Write channel register + * + * Write multiple bytes into a register in specified channel. + * Register address offset of each channels is added in this function. + * + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @param reg target channel register: RegisterName + * @param *vp a pointer to char array. The data in the array will be written. + * @param length length of the data (bytes) + * @see read_ch_register_burst() + */ +void write_ch_register_burst( char ch, char reg, char *vp, char length ); + +/** Read channel register + * + * Read multiple bytes from a register in specified channel. + * Register address offset of each channels is added in this function. + * + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @param reg target channel register: RegisterName + * @param *vp a pointer to char array. The data will be read into this. + * @param length length of the data (bytes) + * @see write_ch_register_burst() + */ +void read_ch_register_burst( char ch, char reg, char *vp, char length ); + +#endif // BURST_DATA_ACCESS + +#endif // __PCU9669_ACCESS__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mini_board_libs/PCU9669/transfer_manager.c Fri Jul 06 08:30:10 2012 +0000 @@ -0,0 +1,179 @@ +/** A sample code for "mini board PCU9669/PCA9665" + * + * @author Akifumi (Tedd) OKANO, NXP Semiconductors + * @version 1.0 + * @date 26-Mar-2012 + * + * 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 + * Un-comment the target name what you want to target. + */ + +/* + * "transfer_manager" is a module to manage I2C bus transfers. + * In this sample code, single slave access (from START or RESTART condition to STOP or next RESTART + * condition) is called transaction. + * + * In this software, the transaction is a struct (the struct is defined in "transfer_manager.h") + * + * typedef struct transaction_st { + * char i2c_address __attribute__((packed)); + * char *data __attribute__((packed)); + * char length __attribute__((packed)); + * } + * transaction; + * + * The transaction has target I2C slave address pointer to the data array and the data length. + * Read/write drection is maneged by LSB of the i2c_address. + * + * For the reading, in this version, a dummy data array can be used but it need to have actual data + * because it will be accessed for buffer filling. + * And transfer manager doesn't readback the buffer. So user need to readback by "buffer_read()" + * function after transaction executed. + * + * A transfer can be represented by array of transaction, i.e... + * + * transaction a_sample_of_transfer[]; + * + * This array_of_transaction: "transfer" is used for the setting of the registers and buffers. + * + * See "main.cpp" for the actual sample of those transfer/transaction usage + */ + +#include "transfer_manager.h" +#include "PCU9669_access.h" // PCU9669 chip access interface + +void setup_transfer( char ch, transaction *t, char n_of_transaction ) { + int i; +#ifdef PCU9669_BURST_DATA_ACCESS +#else + int j; +#endif + + write_ch_register( ch, CONTROL, 0x02 ); // AIPTRRST : AutoIncrementPointerReset (for SLATABLE TRANCONFIG and DATA) + + for ( i = 0; i < n_of_transaction; i++ ) + write_ch_register( ch, SLATABLE, (t + i)->i2c_address ); // + + write_ch_register( ch, TRANCONFIG, n_of_transaction ); // first byte of TRANCONFIG sets to # of transactions + write_ch_register( ch, TRANSEL, 0 ); // select #0 transaction + + for ( i = 0; i < n_of_transaction; i++ ) + write_ch_register( ch, TRANCONFIG, (t + i)->length ); + + +#ifdef PCU9669_BURST_DATA_ACCESS + for ( i = 0; i < n_of_transaction; i++ ) + write_ch_register_burst( ch, DATA, ((t + i)->data), (t + i)->length ); + +#else + for ( i = 0; i < n_of_transaction; i++ ) + for ( j = 0; j < (t + i)->length; j++ ) + write_ch_register( ch, DATA, *(((t + i)->data) + j) ); +#endif +} + + +void set_n_of_transaction( char ch, char n_of_transaction ) +{ + write_ch_register( ch, CONTROL, 0x02 ); // AIPTRRST : AutoIncrementPointerReset (for SLATABLE TRANCONFIG and DATA) + write_ch_register( ch, TRANCONFIG, n_of_transaction ); // first byte of TRANCONFIG sets to # of transactions +} + + +void buffer_overwrite( char ch, char transaction_number, char offset, char *data, char length ) { +#ifdef PCU9669_BURST_DATA_ACCESS +#else + int i; +#endif + + write_ch_register( ch, TRANSEL, transaction_number ); + write_ch_register( ch, TRANOFS, offset ); + +#ifdef PCU9669_BURST_DATA_ACCESS + write_ch_register_burst( ch, DATA, data, length ); +#else + for ( i = 0; i < length; i++ ) + write_ch_register( ch, DATA, *data++ ); +#endif +} + +void buffer_read( char ch, char transaction_number, char offset, char *data, char length ) { +#ifdef PCU9669_BURST_DATA_ACCESS +#else + int i; +#endif + + write_ch_register( ch, TRANSEL, transaction_number ); + write_ch_register( ch, TRANOFS, offset ); + +#ifdef PCU9669_BURST_DATA_ACCESS + read_ch_register_burst( ch, DATA, data, length ); +#else + for ( i = 0; i < length; i++ ) + *data++ = read_ch_register( ch, DATA ); +#endif +} + +void start( char ch ) { + write_ch_register( ch, CONTROL, 0x40 ); +} + +void start_by_trigger( char ch, char polarity ) { + write_ch_register( ch, CONTROL, 0x48 | (polarity ? 0x10 : 0x00 ) ); +} + +void stop( char ch ) { + write_ch_register( ch, CONTROL, 0x20 ); // set STO bit +} + +/* for test of register access order variation */ +/* +void setup_transfer( char ch, transaction *t, char n_of_transaction ) { + int i; + int j; + + write_ch_register( ch, CONTROL, 0x02 ); // AIPTRRST : AutoIncrementPointerReset (for SLATABLE TRANCONFIG and DATA) + write_ch_register( ch, TRANCONFIG, n_of_transaction ); // first byte of TRANCONFIG sets to # of transactions + write_ch_register( ch, TRANSEL, 0 ); // select #0 transaction + + for ( i = 0; i < n_of_transaction; i++ ) { + write_ch_register( ch, SLATABLE, (t + i)->i2c_address ); // + write_ch_register( ch, TRANCONFIG, (t + i)->length ); + write_ch_register_burst( ch, DATA, ((t + i)->data), (t + i)->length ); + } +} +*/ + +/* +void single_transaction_buffer_fill( char ch, char slot, transaction *tp ) { + int i; + + write_ch_register( ch, CONTROL, 0x02 ); // AIPTRRST : AutoIncrementPointerReset (for SLATABLE TRANCONFIG and DATA) + write_ch_register( ch, TRANSEL, slot ); // select #0 transfer + write_ch_register( ch, TRANCONFIG, 1 ); // first byte of TRANCONFIG sets to # of transactions + write_ch_register( ch, TRANCONFIG, tp->length ); // length of first transaction + write_ch_register( ch, SLATABLE, tp->i2c_address ); // + + for ( i = 0; i < length; i++ ) + write_ch_register( ch, DATA, *data++ ); // +} +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mini_board_libs/PCU9669/transfer_manager.h Fri Jul 06 08:30:10 2012 +0000 @@ -0,0 +1,132 @@ +/** A sample code for "mini board PCU9669/PCA9665" + * + * @author Akifumi (Tedd) OKANO, NXP Semiconductors + * @version 1.0 + * @date 26-Mar-2012 + * + * 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 + * Un-comment the target name what you want to target. + */ + +/** Data transfer is abstracted on this layer + * + * The transer can be managed by a struct and some functions + */ +#ifndef __TRANSFER_MANAGER__ +#define __TRANSFER_MANAGER__ + +#define TRIGGER_BY_RISING_EDGE 0 +#define TRIGGER_BY_FALLING_EDGE 1 + +/** @typedef transaction + * + * A transaction (single data read/write access to the slave) is managed by this structure + * An array of the transaction makes a transfer. + * The sample of the transfer management can be found in "main.cpp". + */ +typedef struct transaction_st { + char i2c_address __attribute__((packed)); + char *data __attribute__((packed)); + char length __attribute__((packed)); +} +transaction; + +/** Setup transfer + * + * A transfer (consists multiple transactions) will be set into the buffer. + * This function only sets the data. + * + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @param *t a pointer to transaction array. This array represents a transfer. + * @param n_of_transaction number of transactions (how many transactions in this transfer) + * @see setup_transfer() + * @see buffer_overwrite() + * @see buffer_read() + * @see start() + */ +void setup_transfer( char ch, transaction *t, char n_of_transaction ); + +/** Set N of transaction + * + * To modify the N_OF_TRANSACTION + * This can be used to ignore transactions after specified transaction + * + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @param n_of_transaction number of transactions (how many transactions in this transfer) + * @see setup_transfer() + * @see buffer_overwrite() + * @see buffer_read() + * @see start() + */ +void set_n_of_transaction( char ch, char n_of_transaction ); + +/** Buffer overwrite (in a transaction) + * + * Buffer contents in a transaction can be overwritten. + * + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @param transaction_number points the target transaction by number. + * @param offset offset of overwriting start byte + * @param *data pointer to char array, this contents will be written + * @param length number of bytes to overwrite + * @see setup_transfer() + * @see buffer_overwrite() + * @see buffer_read() + * @see start() + */ +void buffer_overwrite( char ch, char transaction_number, char offset, char *data, char length ); + +/** Buffer read (in a transaction) + * + * Buffer read interface. + * + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @param transaction_number points the target transaction by number. + * @param offset offset of reading start byte + * @param *data pointer to char array, the data will be written here + * @param length number of bytes to read + * @see setup_transfer() + * @see buffer_overwrite() + * @see buffer_read() + * @see start() + */ +void buffer_read( char ch, char transaction_number, char offset, char *data, char length ); + +/** Start transfer + * + * Starts the transfer of specified channel + * + * @param ch target of channel: CH_FM_PLUS | CH_UFM1 | CH_UFM2 + * @see setup_transfer() + * @see buffer_overwrite() + * @see buffer_read() + * @see start() + */ +void start( char ch ); +void start_by_trigger( char ch, char polarity ); +void stop( char ch ); + +// void single_transaction_buffer_fill( char ch, char *data, char length ); + + +#endif // __TRANSFER_MANAGER__ +