?? uwrdio.c
字號:
/***************************************************************************
* 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 + -