📄 phy_spi.c
字号:
/************************************************************************************
* This file contains necessary functions to access the SPI from Phy to Abel.
*
* Author(s):
*
* (c) Copyright 2004, Freescale, Inc. All rights reserved.
*
* Freescale Confidential Proprietary
* Digianswer Confidential
*
* No part of this document must be reproduced in any form - including copied,
* transcribed, printed or by any electronic means - without specific written
* permission from Freescale.
*
* Last Inspected: 19-aug-2003
* Last Tested:
*
* Revision history:
* date Author Comments
* ------ ------ --------
* 200803 FFJ Created
* 271003 TRL Optimized phy_read_spi_1 and phy_write_spi_1
* 200904 JT Optimized functions for Speed, Space and readability
* 261004 JT/FFJ Fixed BDM/SPI issue. (BDM is now allowed to cycle steal, while SPI is running) Optimized as well
************************************************************************************/
#include "gb60_io.h"
#include "DigiType.h"
#include "abelreg.h"
#include "phy_spi.h"
#include "Target.h"
/************************************************************************************
* Local defines
************************************************************************************/
#define AssertCE PTED &= ~0x04;
#define DeAssertCE PTED |= 0x04;
#define WaitSPITxHoldingEmpty while (!(SPIS & 0x20)); //Check if it is legal to write into TX Double buffer register
#define WaitSPITransferDone Wait_8_BitClks(); SPIS; //__asm nop; while (!(SPIS & 0x80)); //Using RXDone flag to check all transfer done (tx followed by rx)
#define WaitSPITransmitterEmpty WaitSPITxHoldingEmpty; \
Wait_6_BitClks(); SPIS; SPID;
void Wait_8_BitClks(void);
/************************************************************************************
* Local macros
************************************************************************************/
/*
*** Easy to read versions (slow and safe) for read core macros ***
#define SPIDummyWrite __asm STA 0x2D ! {}, {};
#define phy_read_spi_int_core_macro(addr, pb) \
AssertCE \
\
SPID = addr; \
WaitSPITransferDone \
SPID; \
\
SPIDummyWrite \
WaitSPITransferDone \
pb[0] = SPID; \
\
SPIDummyWrite \
WaitSPITransferDone \
pb[1] = SPID; \
\
DeAssertCE
*/
/*
#define phy_read_spi_int_core_macro(addr, pb) \
\
AssertCE \
\
SPID = addr; \
WaitSPITransferDone \
SPID=SPID; \
\
WaitSPITransferDone \
tmpAccum = SPID; \
SPID = tmpAccum; \
pb[0] = tmpAccum; \
\
WaitSPITransferDone \
pb[1] = SPID; \
DeAssertCE
*/
/************************************************************************************
* Local macros
************************************************************************************/
#define phy_read_spi_int_core_macro() \
{ asm BSR Wait_8_BitClks; \
asm LDA 43; \
asm MOV 45,45; \
asm BSR Wait_8_BitClks; \
asm LDA 43; \
asm LDA 45; \
asm STA 45; \
asm STA ,X; \
asm BSR Wait_6_BitClks; \
asm LDA 43; \
asm LDA 45; \
asm STA 1,X; \
}
#define phy_read_spi_int_core_swap_macro() \
{ asm BSR Wait_8_BitClks; \
asm LDA 43; \
asm MOV 45,45; \
asm BSR Wait_8_BitClks; \
asm LDA 43; \
asm LDA 45; \
asm STA 45; \
asm STA 1,X; \
asm BSR Wait_6_BitClks; \
asm LDA 43; \
asm LDA 45; \
asm STA ,X; \
}
/*************************************************************************
* HardCore HCS08 Delay Helper Functions *
*************************************************************************/
void Wait_6_BitClks(void) // Duration : BRA/BSR/JSR to here: 3/5/6 mcuCycles
{ // 2xNOP+RTS : 8 mcuCycles
__asm nop;
__asm nop;
}
void Wait_8_BitClks(void)
{ // Duration : BSR/JSR to here: 5/6 mcuCycles
Wait_6_BitClks(); // Uses BRA (3 mcuCyc) to above function (so it really only takes 5,5 bitclks)
}
/*************************************************************************
* SPI Read functions *
*************************************************************************/
/*****************************************************************
* This function reads 1 16bit Abel Register at address "addr" *
* This read may be called from anywhere. (Async and sync context)*
*****************************************************************/
void phy_read_spi(uint8_t addr, uint8_t *pb)
{
uint8_t CCR;
uint8_t *dummy=pb;
STOREINTERRUPTS(CCR)
DISABLE_ALL_INTERRUPTS;
AssertCE
SPID=addr;
phy_read_spi_int_core_macro(); // Macro
DeAssertCE
RESTOREINTERRUPTS(CCR)
}
/****************************************************************
* This function reads 1 16bit Abel Register at address "addr" *
* This read is only to be used from Abel interrupt context *
****************************************************************/
void phy_read_spi_int(uint8_t addr, uint8_t * pb)
{
uint8_t *dummy=pb;
DISABLE_ALL_INTERRUPTS;
AssertCE
SPID=addr;
phy_read_spi_int_core_macro(); // Macro
DeAssertCE
ENABLE_ALL_INTERRUPTS;
}
/****************************************************************
* This function reads 1 16bit Abel Register at address "addr" *
* This read is only to be used from Abel interrupt context *
* Note: Reversed Endianess! *
****************************************************************/
void phy_read_spi_int_swap(uint8_t addr, uint8_t *pb)
{
uint8_t *dummy=pb;
DISABLE_ALL_INTERRUPTS;
AssertCE
SPID=addr;
phy_read_spi_int_core_swap_macro(); // Macro
DeAssertCE
ENABLE_ALL_INTERRUPTS;
}
/*************************************************************************
* SPI Write functions *
*************************************************************************/
#pragma INLINE_NEXT_FUNCTION
/********************************************************************
* Write one 16bit data-location into Abel at address "addr" *
* without monitoring SPSCR. Data is transferred to this routine *
* over the stack. *
* Unprotected - only to be called with disabled interrupts *
* Function inlined in below functions *
********************************************************************/
void phy_write_spi_int_core(uint8_t addr, uint16_t pb)
{
AssertCE
SPID = addr; // Write Addr byte
WaitSPITxHoldingEmpty // Wait for room in holding register
SPID =(uint8_t)(pb>>8); // Write MSB data byte
WaitSPITxHoldingEmpty // Wait for room in holding register
SPID = (uint8_t) pb; // Write LSB data byte
WaitSPITransmitterEmpty // Wait for transmit queue empty
DeAssertCE
}
#pragma DISABLE_WARNING(InlineFunctionCall_c)
/********************************************************************
* Write one 16bit data-location into Abel at address "addr" *
* without monitoring SPSCR. *
* This write is only to be used from Abel interrupt context *
* Protected! *
********************************************************************/
void phy_write_spi_int(uint8_t addr, uint16_t content)
{
DISABLE_ALL_INTERRUPTS;
phy_write_spi_int_core(addr, content); // Inline Expansion
ENABLE_ALL_INTERRUPTS;
}
/********************************************************************
* Write one 16bit data-location into Abel at address "addr" *
* without monitoring SPSCR. *
* This write is only to be used from Abel interrupt context *
* Not Protected! *
********************************************************************/
void phy_write_spi_int_fast(uint8_t addr, uint16_t content)
{
phy_write_spi_int_core(addr, content); // Inline Expansion
}
#pragma RESTORE_WARNING(InlineFunctionCall_c)
/********************************************************************
* Write one 16bit data-location into Abel at address "addr" *
* without monitoring SPSCR. Data is transferred to this routine *
* over the stack. *
********************************************************************/
void phy_write_spi(uint8_t addr, uint16_t content){
uint8_t CCR;
STOREINTERRUPTS(CCR)
DISABLE_ALL_INTERRUPTS;
phy_write_spi_int_fast(addr, content); // Normal Function call
RESTOREINTERRUPTS(CCR)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -