⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uwrdio.c

📁 TDK 6521 SOC 芯片 DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
 * This code and information is provided "as is" without warranty of any   *
 * kind, either expressed or implied, including but not limited to the     *
 * implied warranties of merchantability and/or fitness for a particular   *
 * purpose.                                                                *
 *                                                                         *
 * Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved.    *
 ***************************************************************************/
//**************************************************************************
//    
//  DESCRIPTION: 71M651x POWER METER - Serial EEPROM Routines. 
// 
//  AUTHOR:  RGV
//
//  HISTORY: See end of file
//
//**************************************************************************
//               
// File: UWRDIO.C
// This implements a Microwire/half-duplex SPI bus master using DIO_4 and DIO_5,
// with a third DIO pin as the select (usually DIO_8). By default, it simulates
// the 6520's Microwire EEPROM access hardware in software.
//
// The addressing function, uwr_select(), may have to be modified for your
// project.  If clock polarities change for different devices, this routine
// should select the clock polarities automatically.
//
// This code is provided because the 6520's hardware microwire interface 
// does not address certain issues that could affect some customers.
//
// This implementation can port to a different set of DIOs if DIO_4 or 5 are
// needed for other purposes.
//
// This code provides microwire for the 6511 and 6513 meter chips, 
// which lack a hardware controller.
//
// It provides a compatible API to access devices that require clock 
// polarities other than Microwire standard (set SPI_POLARITIES to 1)
//
// Some clocked serial devices do not place their output in a high impedance 
// state while receiving data.  With this code, one can disassociate the input 
// and output pins by redefining the macros that access them.
//
// At a 4.9MHz MPU clock, this implementation was measured at a 260KHz 
// clock rate, not bad, but substantially slower than the 500KHz rate of 6520
// Microwire hardware.               
//**************************************************************************
// SPI API.
//
#include "options.h"
#if UWR_SW
#include "oscope.h"
#include "uwr.h"

// compilation switches
#define SPI_POLARITIES 0

// application symbols
#define BUSY_WAIT_MODE 128
#define LEADING_OUT 1
static uint8_t mode = 1;
static uint8_t last_cs_index = 1;
#define HALF_SECOND 5000 // assumes a call of delay_clks (3), 3/32768 secs

// change this stuff for new hardware
// SCL, serial clock, is attached to DIO_4 in both M6510 and M6520
#define SCL DIO_4
#define SCL_POWERED DIR0 |= 0x10
#define SCL_UNPOWERED DIR0 &= ~0x10
#define SCL_ONE SCL = 1
#define SCL_ZERO SCL = 0

// SDO, serial data out, is attached to DIO_5
#define SDO DIO_5
#define SDO_POWERED DIR0 |= 0x20
#define SDO_UNPOWERED DIR0 &= ~0x20
#define SDO_ONE SDO = 1
#define SDO_ZERO SDO = 0

// SDI, serial data in, is attached to DIO_5, so
// the software emulates the 652X's half-duplex uwire hardware.
// Half duplex is all that's needed to control most devices.
// For a full duplex SPI, assign this to a different pin,
// and change the bit write macros to read the input on
// the opposite phase.
#define SDI DIO_5
#define SDI_POWERED DIR0 |= 0x20
#define SDI_UNPOWERED DIR0 &= ~0x20
#define SDI_ONE SDI = 1
#define SDI_ZERO SDI = 0

// CS, chip select, is attached to DIO_8 on the Eval PCB; modify this 
// for your PCB
#define CS DIO_8
#define CS_POWERED DIR1 |= 0x01
#define CS_UNPOWERED DIR1 &= ~0x01
#define CS_ONE CS = 1
#define CS_ZERO CS = 0

// Clock polarity routines are not public because they can and should
// be set by the addressing logic in uwr_select().
// rising edge of leading clock edge is data to device,
// Used on microwire eeproms, and this is the default
static void uwr_leading_rising (void) small reentrant;
#if SPI_POLARITIES
// falling edge of leading clock edge is data to device,
static void uwr_leading_falling (void) small reentrant;
// rising edge of trailing clock edge is data to device,
static void uwr_trailing_rising (void) small reentrant;
// falling edge of trailing clock edge is data to device,
static void uwr_trailing_falling (void) small reentrant;
#endif

// initialize the microwire system
#pragma save
#pragma NOAREGS
void uwr_init(void) small reentrant
{
    EX_EEPROM  = FALSE;        // Disable EEPROM non-busy interrupt.
    DIO &= ~DIO_EEX;           // DIO_4 and DIO_5 become DIOs

    #if TRACE10 | M6520
    if ((LCDX & LCD_NUM) > 16) // DIO_4 and DIO_5 are not LCD segments
    {
        LCDX = 16 | (LCDX & ~LCD_NUM);
    }
    #elif M6530
    LCD_MAP[ DIO4_11 ] &= ~(SEG24_DIO4 | SEG25_DIO5);
    #else
    #error unknown device
    #endif

    // Change the default polarities and edges for your devices.
    // select nothing
    uwr_select (UWR_NO_DEVICE);

    // power up the interface
    CS_POWERED;
    SCL_POWERED;
    SDI_UNPOWERED;
    SDO_POWERED;
}
#pragma restore

// select a chip; 0 = none
// The clock polarity should be selected before the device is selected.
// Rewrite this to select the polarity and address the devices on your PCB
#pragma save
#pragma NOAREGS
void uwr_select (uint8_t cs_index) small reentrant
{
    uwr_leading_rising (); // set default polarity
    last_cs_index = cs_index;
    CS = cs_index;
}
#pragma restore

// start of portable code

// LR: leading/rising, the default clock polarity and edge for microwire.
// leading edge is output to device, leading edge is rising
// Put a bit out
#define PUT_BIT_LR(_b_,_bit_) \
    if (0 == (_b_ & _bit_)) \
    { \
        SDO_ZERO; \
    } \
    else \
    { \
        SDO_ONE; \
    } \
    SCL_ONE; \
    SCL_ZERO

// put a bit out, with hi-z
#define PUT_BIT_HIZ_LR(_b_,_bit_) \
    if (0 == (_b_ & _bit_)) \
    { \
        SDO_ZERO; \
    } \
    else \
    { \
        SDO_ONE; \
    } \
    SCL_ONE; \
    SDI_UNPOWERED; \
    SCL_ZERO

// The loops are unrolled in these macros to get the best possible speed.
#define PUT_BYTE_LR(_b_) \
    PUT_BIT_LR(_b_,128); \
    PUT_BIT_LR(_b_,64); \
    PUT_BIT_LR(_b_,32); \
    PUT_BIT_LR(_b_,16); \
    PUT_BIT_LR(_b_,8); \
    PUT_BIT_LR(_b_,4); \
    PUT_BIT_LR(_b_,2); \
    PUT_BIT_LR(_b_,1)

// The loops are unrolled in these macros to get the best possible speed.
#define PUT_BYTE_HIZ_LR(_b_) \
    PUT_BIT_LR(_b_,128); \
    PUT_BIT_LR(_b_,64); \
    PUT_BIT_LR(_b_,32); \
    PUT_BIT_LR(_b_,16); \
    PUT_BIT_LR(_b_,8); \
    PUT_BIT_LR(_b_,4); \
    PUT_BIT_LR(_b_,2); \
    PUT_BIT_HIZ_LR(_b_,1)

#define GET_BIT_LR(_b_,_bit_) \
    SCL_ONE; \
    SCL_ZERO; \
    if (SDI != 0) \
    { \
        _b_ |= _bit_; \
    }

// The loops are unrolled in these macros to get the best possible speed.
#define GET_BYTE_LR(_b_) \
    GET_BIT_LR(_b_,128); \
    GET_BIT_LR(_b_,64); \
    GET_BIT_LR(_b_,32); \
    GET_BIT_LR(_b_,16); \
    GET_BIT_LR(_b_,8); \
    GET_BIT_LR(_b_,4); \
    GET_BIT_LR(_b_,2); \
    GET_BIT_LR(_b_,1)

// LF: leading/falling, a different polarity, often used by Japanese chips
// leading edge is output to device, leading edge is falling 
// The loops are unrolled in these macros to get the best possible speed.
// Put a bit out
#define PUT_BIT_LF(_b_,_bit_) \
    if (0 == (_b_ & _bit_)) \
    { \
        SDO_ZERO; \
    } \
    else \
    { \
        SDO_ONE; \
    } \
    SCL_ZERO; \
    SCL_ONE;

// put a bit out, with hi-z
#define PUT_BIT_HIZ_LF(_b_,_bit_) \
    if (0 == (_b_ & _bit_)) \
    { \
        SDO_ZERO; \
    } \
    else \
    { \
        SDO_ONE; \
    } \
    SCL_ZERO; \
    SDI_UNPOWERED; \
    SCL_ONE;

// The loops are unrolled in these macros to get the best possible speed.
#define PUT_BYTE_LF(_b_) \
    PUT_BIT_LF(_b_,128); \
    PUT_BIT_LF(_b_,64); \
    PUT_BIT_LF(_b_,32); \
    PUT_BIT_LF(_b_,16); \
    PUT_BIT_LF(_b_,8); \
    PUT_BIT_LF(_b_,4); \
    PUT_BIT_LF(_b_,2); \
    PUT_BIT_LF(_b_,1)

// The loops are unrolled in these macros to get the best possible speed.
#define PUT_BYTE_HIZ_LF(_b_) \
    PUT_BIT_LF(_b_,128); \
    PUT_BIT_LF(_b_,64); \
    PUT_BIT_LF(_b_,32); \
    PUT_BIT_LF(_b_,16); \
    PUT_BIT_LF(_b_,8); \
    PUT_BIT_LF(_b_,4); \
    PUT_BIT_LF(_b_,2); \
    PUT_BIT_HIZ_LF(_b_,1)

#define GET_BIT_LF(_b_,_bit_) \
    SCL_ZERO; \
    if (SDI != 0) \
    { \
        _b_ |= _bit_; \
    } \
    SCL_ONE

// The loops are unrolled in these macros to get the best possible speed.
#define GET_BYTE_LF(_b_) \
    GET_BIT_LF(_b_,128); \
    GET_BIT_LF(_b_,64); \
    GET_BIT_LF(_b_,32); \
    GET_BIT_LF(_b_,16); \
    GET_BIT_LF(_b_,8); \
    GET_BIT_LF(_b_,4); \
    GET_BIT_LF(_b_,2); \
    GET_BIT_LF(_b_,1)

// TR: trailing/rising, a different polarity, used in unusual devices
// trailing edge is output to device, trailing edge is rising 
// The loops are unrolled in these macros to get the best possible speed.
// Put a bit out
#define PUT_BIT_TR(_b_,_bit_) \
    SCL_ZERO; \
    if (0 == (_b_ & _bit_)) \
    { \
        SDO_ZERO; \
    } \
    else \
    { \
        SDO_ONE; \
    } \
    SCL_ONE;

// put a bit out, with hi-z
#define PUT_BIT_HIZ_TR(_b_,_bit_) \
    SCL_ZERO; \
    if (0 == (_b_ & _bit_)) \
    { \
        SDO_ZERO; \
    } \
    else \
    { \
        SDO_ONE; \
    } \
    SCL_ONE; \
    SDI_UNPOWERED; \

// The loops are unrolled in these macros to get the best possible speed.
#define PUT_BYTE_TR(_b_) \
    PUT_BIT_TR(_b_,128); \
    PUT_BIT_TR(_b_,64); \
    PUT_BIT_TR(_b_,32); \
    PUT_BIT_TR(_b_,16); \
    PUT_BIT_TR(_b_,8); \
    PUT_BIT_TR(_b_,4); \
    PUT_BIT_TR(_b_,2); \
    PUT_BIT_TR(_b_,1)

// The loops are unrolled in these macros to get the best possible speed.
#define PUT_BYTE_HIZ_TR(_b_) \
    PUT_BIT_TR(_b_,128); \
    PUT_BIT_TR(_b_,64); \
    PUT_BIT_TR(_b_,32); \
    PUT_BIT_TR(_b_,16); \
    PUT_BIT_TR(_b_,8); \
    PUT_BIT_TR(_b_,4); \
    PUT_BIT_TR(_b_,2); \
    PUT_BIT_HIZ_TR(_b_,1)

#define GET_BIT_TR(_b_,_bit_) \
    SCL_ZERO; \
    SCL_ONE; \
    if (SDI != 0) \
    { \
        _b_ |= _bit_; \
    }

// The loops are unrolled in these macros to get the best possible speed.
#define GET_BYTE_TR(_b_) \
    GET_BIT_TR(_b_,128); \
    GET_BIT_TR(_b_,64); \
    GET_BIT_TR(_b_,32); \
    GET_BIT_TR(_b_,16); \
    GET_BIT_TR(_b_,8); \
    GET_BIT_TR(_b_,4); \
    GET_BIT_TR(_b_,2); \
    GET_BIT_TR(_b_,1)

// TF: trailing/falling, a different polarity, used in unusual devices
// trailing edge is output to device, trailing edge is falling
// The loops are unrolled in these macros to get the best possible speed.
// Put a bit out
#define PUT_BIT_TF(_b_,_bit_) \
    SCL_ONE; \
    if (0 == (_b_ & _bit_)) \
    { \
        SDO_ZERO; \
    } \
    else \
    { \
        SDO_ONE; \
    } \
    SCL_ZERO;

// put a bit out, with hi-z
#define PUT_BIT_HIZ_TF(_b_,_bit_) \
    SCL_ONE; \
    if (0 == (_b_ & _bit_)) \
    { \
        SDO_ZERO; \
    } \
    else \
    { \
        SDO_ONE; \
    } \
    SCL_ZERO; \
    SDI_UNPOWERED; \

// The loops are unrolled in these macros to get the best possible speed.
#define PUT_BYTE_TF(_b_) \
    PUT_BIT_TF(_b_,128); \
    PUT_BIT_TF(_b_,64); \
    PUT_BIT_TF(_b_,32); \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -