Page MenuHomec4science

register.h
No OneTemporary

File Metadata

Created
Tue, Mar 4, 23:14

register.h

/*
File: register.h
Author: tuleu
Created on May 22, 2012, 1:37 PM
*/
#ifndef SBCP_UC_REGISTER_H_
#define SBCP_UC_REGISTER_H_
#include "sbcp-uc_config.h"
#include "sbcp_common.h"
#include "DEE_Emulation_16-bit.h"
#if SBCP_REG_TABLE_SIZE > 255
#error "SBCP_REG_TABLE_SIZE should be <= 255"
#endif
/**
* \defgroup sbcp_register_m SBCP register
*
* \brief module to manipulate SBCP register
*
* An SBCP device have a table of register. Some of them are standard
* (sbcp_std_registers ) and most of them are device specific. These one are
* specified by the user using sbcp_add_register() function inside a
* sbcp_init_device_registers_fptr user defined function.
*
* Registers are always R/W from the device. From the host point of view they
* could be SBCP_REG_WRITABLE or SBCP_REG_READABLE.
* They are some time SBCP_REG_PERSISTENT, it means that if they are set
* externally there value will be written in EEPROM.
*
* You can define some sbcp_reg_host_wr_callback for a register, i.e. a callback
* that will be called every time the register is externally written.
*
* \ingroup sbcp_m
*
*/
/**
* adress of a sbcp_register. A device could have up to 256 registers
* \ingroup sbcp_register_m
*/
typedef uint8_t sbcp_reg_address;
/**
* Value of a register. A register is always a 16 bits value
* \ingroup sbcp_register_m
*/
typedef union sbcp_reg_val {
/// as 16 bit signed int
int16_t i;
/// as 16 bit unsigned int
uint16_t u;
/// as an array of char
uint8_t c[2];
///litlle endian architecure
struct {
/// MSB byte
uint8_t lsb;
///LSB byte
uint8_t msb;
};
} sbcp_reg_val;
/**
* Write callback of a register. This callback will be called every time the
* register is *externally* written. At the time it is called, the register is
* not already written, therefore you could access the old value inside the
* register.
* \ingroup sbcp_register_m
* \param address : the address of the written register
* \param value : a pointer to the new value that will be written in the
* register after the call to the callback. You may change the
* value.
* \return an sbcp_error code if there is any error. In that case an error
* message will be sent to the host
*/
typedef sbcp_error (*sbcp_reg_host_wr_callback)(sbcp_reg_address address,sbcp_reg_val * new_value);
/**
* Initialization callback. During a call to sbcp_init() this user providen
* callback will be called. User should register the device specific register
* using call to sbcp_add_register() and sbcp_add_register_no_callback(). User
* should also defines the low latency in and out register using.
* sbcp_append_low_latency_in_register() and
* sbcp_append_low_latency_out_register()
* \ingroup sbcp_register_m
*/
typedef void(*sbcp_init_device_registers_fptr)();
/**
* Available flags for sbcp_register. They should be passed to
* sbcp_add_register() and sbcp_add_register_no_callback()
* \ingroup sbcp_register_m
*/
typedef enum sbcp_reg_flags {
SBCP_REG_UNIMPLEMENTED = 0, //!< SBCP_REG_UNIMPLEMENTED flags for a non existing sbcp_register
SBCP_REG_WRITABLE = 1 << 0, //!< SBCP_REG_WRITABLE specify an externally writable register
SBCP_REG_READABLE = 1 << 1, //!< SBCP_REG_READABLE specify an externally readable register
SBCP_REG_PERSISTENT = 1 << 2, //!< SBCP_REG_PERSISTENT specify an EEPROM persistent register
SBCP_REG_UNLOCKED = 1 << 3, //!< SBCP_REG_PROTECTED specify a protected register (unimplemented)
} sbcp_reg_flags;
#define SBCP_REG_USER_SETABLE_FLAGS (SBCP_REG_WRITABLE | SBCP_REG_READABLE | SBCP_REG_PERSISTENT)
/**
* Control parameter of a register
*/
typedef struct sbcp_reg_ctrl_params {
///flags of the register
sbcp_reg_flags flags;
///callback of the register
sbcp_reg_host_wr_callback callback;
} sbcp_reg_ctrl_params;
#define SBCP_MY_ID sbcp_reg_lsb(SBCP_REG_ID)
#define SBCP_MY_CLASS sbcp_reg_lsb(SBCP_REG_CLASS)
#define SBCP_REG_NO_CALLBACK ((void*)0)
/**
* \name register value accessor
*
* Use this accessor to access the sbcp_register.
* \ingroup sbcp_register_m
*/
///@{
/**
* Register as an 16 bits signed int.
* \param adr the sbcp_reg_address of the register
*/
#define sbcp_reg_int(adr) (sbcp_reg_table[(adr)].i)
/**
* Register as an 16 bits unsigned int.
* \param adr the sbcp_reg_address of the register
*/
#define sbcp_reg_uint(adr) (sbcp_reg_table[(adr)].u)
/**
* MSB byte of the register
* \param adr the sbcp_reg_address of the register
*/
#define sbcp_reg_msb(adr) (sbcp_reg_table[(adr)].msb)
/**
* LSB byte of the register
* \param adr the sbcp_reg_address of the register
*/
#define sbcp_reg_lsb(adr) (sbcp_reg_table[(adr)].lsb)
/**
* sbcp_register_flags of the sbcp_register
* \param adr the sbcp_reg_address of the register
*/
#define sbcp_reg_flags(adr) (sbcp_reg_params[(adr)].flags)
/**
* sbcp_reg_host_wr_callback of the sbcp_register
* \param adr the sbcp_reg_address of the register
*/
#define sbcp_reg_clbck(adr) (sbcp_reg_params[(adr)].callback)
///@}
/**
* Inits the registers
* \internal
* @param klass
* @param id
* @param version
* @param device_specific_init
*/
void sbcp_init_registers(sbcp_class klass,
sbcp_id id,
sbcp_fw_version version,
sbcp_init_device_registers_fptr device_specific_init);
/**
* Adds a new registers to the list of the device register.
* \warning Should be called *only* in user register initialization callback
* sbcp_init_device_register_fptr
* \ingroup sbcp_register_m
* @param address the address of the new register
* @param value default value of the register at device startup
* @param flags a '|' comnination of sbcp_register_flags
* @param clb sbcp_reg_host_wr_callback for this register
*/
void sbcp_add_register(sbcp_reg_address address,
uint16_t value,
sbcp_reg_flags flags,
sbcp_reg_host_wr_callback clb);
/**
* Adds a new registers to the list of the device register, whithout callback.
* \warning Should be called *only* in user register initialization callback
* sbcp_init_device_register_fptr
* \ingroup sbcp_register_m
* @param address the address of the new register
* @param value default value of the register at device startup
* @param flags a '|' comnination of sbcp_register_flags
*
*/
void sbcp_add_register_no_callback(sbcp_reg_address address,
uint16_t value,
sbcp_reg_flags flags);
/**
* Safely sets a register to a value. If the register is persistent, it also
* be saved in EEPROM.
* \ingroup sbcp_register_m
*/
#define sbcp_safe_set_register(address,value) do{\
if(sbcp_reg_flags(address) & SBCP_REG_PERSISTENT){\
DataEEWrite(value,address);\
}\
sbcp_reg_uint(address) = value;\
}while(0)
/*intern data representation, not part of API*/
extern sbcp_reg_val sbcp_reg_table [SBCP_REG_TABLE_SIZE];
extern sbcp_reg_ctrl_params sbcp_reg_params[SBCP_REG_TABLE_SIZE];
#endif // SBCP_REGISTER_H_

Event Timeline