161 lines
5.8 KiB
C
161 lines
5.8 KiB
C
/*
|
|
Driver Register Cache Word (RCW) operation header file.
|
|
|
|
Driver Register Cache Word (RCW) operation header file.
|
|
The macros defined in this header file is used to simply the register
|
|
bit field read and write. By adapting this way of register access,
|
|
it shall provide more error-proof and more readable way to write
|
|
drivers. It also does register access in load/store way which allow
|
|
one to accurately control the number of counts the register read and
|
|
write is proceeded from code writing.
|
|
|
|
@file RCWMacro.h
|
|
@ingroup mIDriver
|
|
@note Nothing.
|
|
|
|
Copyright Novatek Microelectronics Corp. 2010. All rights reserved.
|
|
*/
|
|
|
|
#ifndef __ASM_ARCH_NVT_IVOT_RCW_MACRO_H
|
|
#define __ASM_ARCH_NVT_IVOT_RCW_MACRO_H
|
|
#if defined(__FREERTOS)
|
|
#include <stdint.h>
|
|
#elif defined(__KERNEL__)
|
|
#include <linux/types.h>
|
|
#endif
|
|
/**
|
|
@addtogroup mIDriver
|
|
*/
|
|
//@{
|
|
|
|
//
|
|
// Register word value type
|
|
//
|
|
// The size in bits of this type should match the RCW type
|
|
#define REGVALUE uint32_t
|
|
|
|
#define UBITFIELD unsigned int /* Unsigned bit field */
|
|
#define BITFIELD signed int /* Signed bit field */
|
|
|
|
|
|
#define FALSE 0
|
|
#define TRUE 1
|
|
|
|
/**
|
|
@name Assert macros
|
|
*/
|
|
//@{
|
|
#define ASSERT_CONCAT_(a, b) a##b
|
|
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
|
|
|
|
#if defined(__COUNTER__)
|
|
|
|
#define STATIC_ASSERT(expr) \
|
|
enum { ASSERT_CONCAT(FAILED_STATIC_ASSERT_, __COUNTER__) = 1/(expr) }
|
|
|
|
#else
|
|
|
|
// This might cause compile error when writing STATIC_ASSERT at the same line
|
|
// in two (or more) files and one file include another one.
|
|
#define STATIC_ASSERT(expr) \
|
|
enum { ASSERT_CONCAT(FAILED_STATIC_ASSERT_, __LINE__) = 1/(expr) }
|
|
|
|
#endif
|
|
|
|
#define OUTW(addr,value) (*(REGVALUE volatile *)(addr) = (REGVALUE)(value))
|
|
#define INW(addr) (*(REGVALUE volatile *)(addr))
|
|
|
|
|
|
//
|
|
// Macros for Register Cache Word (RCW) type definition
|
|
//
|
|
// Each RCW type should be exactly the same size with REGVALUE type
|
|
// For example, to declare a Register Cache Word type:
|
|
//
|
|
// #define rcwname_OFS 0x00 /* the name of RCW corresponding register address offset
|
|
// should be in specific format with "_OFS" appended */
|
|
// REGDEF_BEGIN(rcwname)
|
|
// REGDEF_BIT(field1, 8) /* declare field1 as 8 bits width */
|
|
// REGDEF_BIT(field2, 8) /* declare field1 as 8 bits width */
|
|
// REGDEF_BIT(, 16) /* pad reserved (not-used) bits to fill RCW type same as REGVALUE size */
|
|
// REGDEF_END(rcwname)
|
|
//
|
|
// Register Cache Word type defintion header
|
|
#define REGDEF_BEGIN(name) \
|
|
typedef union \
|
|
{ \
|
|
REGVALUE reg; \
|
|
struct \
|
|
{
|
|
|
|
// Register Cache Word bit defintion
|
|
#define REGDEF_BIT(field, bits) \
|
|
UBITFIELD field : bits;
|
|
|
|
// Register Cache Word type defintion trailer
|
|
#define REGDEF_END(name) \
|
|
} bit; \
|
|
} T_##name; \
|
|
STATIC_ASSERT(sizeof(T_##name) == sizeof(REGVALUE));
|
|
|
|
// Macro to define register offset
|
|
#define REGDEF_OFFSET(name, ofs) static const uint32_t name##_OFS=(ofs);
|
|
|
|
//
|
|
// Macros for prerequisite stuff initialization for Register Cache Word
|
|
// operations
|
|
//
|
|
// Macro to set register base address for current module
|
|
// One must call this macro somewhere to set register I/O base address for
|
|
// current module, either globally or locally before any RCW operations is
|
|
// invoked
|
|
// What this macro set is only effective in current C file
|
|
#define REGDEF_SETIOBASE(base) static const uint32_t _REGIOBASE=(base)
|
|
|
|
// Macro to set register repeat group offset address in byte
|
|
// This macro is optional and only used where register with repeat group exist,
|
|
// only one repeat group is allowed in one file
|
|
// If registers with repeat group exist, then one only have to define the RCW type
|
|
// for the first group, respective group of registers can be accessed through
|
|
// RCW_LD2, RCW_ST2, RCW_LD2OF macros
|
|
// What this macro set is only effective in current C file
|
|
#define REGDEF_SETGRPOFS(grpofs) static const uint32_t _REGGRPOFS=(grpofs)
|
|
|
|
//
|
|
// Macros for Register Cache Word (RCW) operations
|
|
//
|
|
// These RCW operations are most likely to be used inside C functions
|
|
// It is not recommended to use RCW_DEF(RCW) in global scope which
|
|
// declare RCW as global variable
|
|
// RCW_LD/RCW_ST/RCW_LDOF pair is for normal single register access while
|
|
// RCW_LD2/RCW_ST2/RCW_LD2OF pair is for repeat group register access
|
|
// Beware that the RCW_LD/RCW_ST/RCW_LDOF and RCW_LD2/RCW_ST2/RCW_LD2OF
|
|
// must not be mixed used. e.g. use RCW_LD then RCW_ST2 or use RCW_LD2 then RCW_ST
|
|
//
|
|
// Register Cache Word declaration
|
|
#define RCW_DEF(RCW) T##_##RCW t##RCW
|
|
// Register Cache Word read from I/O
|
|
#define RCW_LD(RCW) t##RCW.reg = INW(_REGIOBASE+RCW##_OFS)
|
|
// Register Cache Word repeat from I/O for group read
|
|
#define RCW_LD2(RCW, grpidx) t##RCW.reg = INW(_REGIOBASE+RCW##_OFS+(grpidx)*_REGGRPOFS)
|
|
// Register Cache Word bit reference
|
|
#define RCW_OF(RCW) t##RCW.bit
|
|
// Register Cache Word reference
|
|
#define RCW_VAL(RCW) t##RCW.reg
|
|
// Register Cache Word write to I/O
|
|
#define RCW_ST(RCW) OUTW(_REGIOBASE+RCW##_OFS, t##RCW.reg)
|
|
// Register Cache Word write to I/O for repeat group
|
|
#define RCW_ST2(RCW, grpidx) OUTW(_REGIOBASE+RCW##_OFS+(grpidx)*_REGGRPOFS, t##RCW.reg)
|
|
// Register Cache Word read and reference to register cache word bit
|
|
// !!!need to check for compiler if support for this syntax
|
|
#define RCW_LDOF(RCW) ((T##_##RCW)(RCW_LD(RCW))).bit
|
|
// Register Cache Word read and reference to register cache word bit for repeat group
|
|
// !!!need to check for compiler if support for this syntax
|
|
#define RCW_LD2OF(RCW, grpidx) ((T##_##RCW)(RCW_LD2(RCW, grpidx))).bit
|
|
|
|
#define rcw_get_phy_addr(addr) ((addr) & 0x1FFFFFFF)
|
|
|
|
//@}
|
|
|
|
#endif /* __ASM_ARCH_NVT_IVOT_RCW_MACRO_H */
|