📄 hal.h
字号:
*****************************************************************************
************* SPI Master functions/macros *************
*****************************************************************************
****************************************************************************/
//----------------------------------------------------------------------------
// defines which make SPCR (SPI control register) assignments more legible
#define SPI_SPM_ENABLED 0x40 // Enable or disable special purpose
#define SPI_SPM_DISABLED 0x00 // mode (as opposed to regular SPI)
#define SPI_ENABLE 0x20 // Enable SPI
#define SPI_DISABLE 0x00 // Disable SPI.
#define SPI_MSB_FIRST 0x10 // Transmit data MSB first
#define SPI_LSB_FIRST 0x00 // Transmit data LSB first
#define SPI_NEGEDGE_IDLE0 0x04 // 0 when idle, sample on neg. edge, shift on pos. edge
#define SPI_POSEDGE_IDLE0 0x00 // 0 when idle, sample on pos. edge, shift on neg. edge
#define SPI_NEGEDGE_IDLE1 0x08 // 1 when idle, sample on neg. edge, shift on pos. edge
#define SPI_POSEDGE_IDLE1 0x0c // 1 when idle, sample on pos. edge, shift on neg. edge
#define SPI_CLK_DIV_8 0x00 // SCK frequency = XOSC frequency / 8
#define SPI_CLK_DIV_16 0x01 // SCK frequency = XOSC frequency / 16
#define SPI_CLK_DIV_32 0x02 // SCK frequency = XOSC frequency / 32
#define SPI_CLK_DIV_64 0x03 // SCK frequency = XOSC frequency / 64
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Macro for SPI control (use the constants defined above):
// Example of usage:
// SPI_CONTROL( SPI_ENABLE | SPI_MSB_FIRST | SPI_POSEDGE_IDLE0 | SPI_CLK_DIV_8 );
//----------------------------------------------------------------------------
#define SPI_CONTROL(x) (SPCR = (x))
//----------------------------------------------------------------------------
// Macro for controlling output of MOSI pin. Should be set as MOSI_OE(TRUE)
// for normal three-wire SPI interfaces. For use with a two-wire SPI interface
// with a bidirectional data line MOSI_OE must be toggled when the direction
// of the data line should be changed.
// Usage example:
// SPI_CONTROL( SPI_ENABLE | SPI_MSB_FIRST | SPI_POSEDGE_IDLE0 | SPI_CLK_DIV_8 );
// MOSI_OE(TRUE); // Master to slave first
// for (i=0; i<4; i++) { // Send four bytes
// SPI_DATA=data_out[i]; while (SPI_IS_ACTIVE);
// }
// MOSI_OE(FALSE); // Slave to master
// for (i=0; i<4; i++) { // Receive four bytes
// SPI_DATA=0; // Write bogus byte to produce SCLK
// while (SPI_IS_ACTIVE);
// data_in[i]=SPI_DATA;
// }
//----------------------------------------------------------------------------
#define MOSI_OE(x) (P0DIR=(x) ? (P0DIR&~0x02) : (P0DIR|0x02))
//----------------------------------------------------------------------------
// Macro for reading and writing to the SPI data register. Usage example:
// data_in=SPI_DATA;
// SPI_DATA=data_out;
//----------------------------------------------------------------------------
#define SPI_DATA SPDR
//----------------------------------------------------------------------------
// Macro used for testing if the SPI interface is in the middle of receiving/
// transmitting a byte at then current time. For maximum transmission
// speeds in a block transfer use the macro SPI_READ_WRITE in a loop.
// Usage example:
// for (i=0; i<4; i++) {
// SPI_DATA=spi_out_buf[i];
// while (SPI_IS_ACTIVE);
// SPI_DATA=spi_in_buf[i]
// }
//----------------------------------------------------------------------------
#define SPI_IS_ACTIVE (!!(SPSR&0x02))
//----------------------------------------------------------------------------
// Macro for performing an SPI read/write operation in the fastest possible way.
// Useful when reading/writing a block of data. _din_ receives the incoming data
// byte and _dout_ should contain the data byte to transmit. _din_ and _dout_
// can point to the same address as data is transmitted before it is received.
// Usage example:
// for (i=0; i<4; i++)
// SPI_READ_WRITE(spi_in_buf[i], spi_out_buf[i]);
//----------------------------------------------------------------------------
#define SPI_READ_WRITE(din, dout) \
do { \
do SPDR=(dout); while(SPSR&0x01); while(SPI_IS_ACTIVE); (din)=SPDR; \
} while(0)
//----------------------------------------------------------------------------
// void halSpiTransferBlock(...)
//
// Description:
// Transfers _length_ bytes of the data block pointed to by _inoutBuffer_
// over the SPI interface. It is assumed that the SPI interface has
// already been correctly configured. If _read_ is TRUE the incoming
// data on the SPI interface will be stored in place in _inoutBuffer_,
// (overwriting the data that is transmitted), otherwise the received
// data is ignored.
//
// Arguments:
// byte* inoutBuffer
// Pointer to a block of data that is to be transmitted. If _read_ is
// TRUE the received data will overwrite this data.
// word length
// The number of bytes to receive/transmit.
// bool enableRead
// Overwrite the data transmitted with the received data (TRUE) or
// ignore received data (FALSE).
//
// Return value:
// void
//----------------------------------------------------------------------------
void halSpiTransferBlock(byte* inoutBuffer, word length, bool enableRead);
/*****************************************************************************
*****************************************************************************
************* FLASH programming functions *************
*****************************************************************************
****************************************************************************/
//----------------------------------------------------------------------------
// bool halFlashWritePage(...)
//
// Description:
// Writes into the flash page pointed to by _flashPage_ 128 bytes of
// data pointed to by _ramBuffer_. The addresses of both _flashPage_ and
// _ramBuffer_ must be an integer multiple of 128, i.e adr mod 128=0.
// _clkFreq_ must be the XOSC frequency in kHz and is used to calculate
// the correct erasure and programming times.
// If these conditions are not met the function does not perform any
// programming and returns FALSE. A verification of the data written is
// performed after programming - if this verification fails for some reason
// (flash page is write locked, or flash programming failure) the function
// also returns FALSE.
// All interrupts are turned off while this function executes.
//
// Arguments:
// byte code* flashPage
// Pointer to the destination of the write in code memory space.
// Address must be an integer multiple of 128 bytes.
// byte xdata* ramBuffer
// Pointer to the data source in RAM for the write in XDATA memory
// space. Address must be an integer multiple of 128 bytes.
// word clkFreq
// The XOSC clock frequency in kHz.
//
// Return value:
// bool
// TRUE if the write was successful. False if programming/verification
// failed or supplied arguments were invalid.
//----------------------------------------------------------------------------
bool halFlashWritePage(byte code* flashPage, byte xdata* ramBuffer, word clkFreq);
//----------------------------------------------------------------------------
// bool halCopy2Flash(...)
//
// Description:
// Copies _length_ bytes from the memory area pointed to by _src_ (in any
// memory space) to the memory area in CODE memory space pointed to by
// _flashPtr_. A 128 byte temporary buffer in the XDATA memory space must
// be pointed to by _ramBuffer_. None of the pointers (_flashPtr_, _src_
// or _ramBuffer_) need to be page-aligned (address mod 128=0) as with
// halFlashWritePage(...), neither does _length_ have to be a multiple of
// 128 bytes -- it can in fact be between 1 and 32768 bytes, although it
// goes without saying that it is unwise to overwrite the memory occupied
// by the code for this function. The result is undefined if the memory
// areas occupied by [_src_, _src_+_length_-1] and [_ramBuffer_,
// _ramBuffer+127] overlap.
// A verification of the data written is performed after programming - if
// this verification fails for some reason (flash page is write locked,
// flash programming failure) or some of the supplied arguments are
// invalid the function returns FALSE.
// All interrupts are turned off while this function executes.
//
// Arguments:
// byte code* flashPtr
// Pointer to the destination of the write in code memory space.
// byte* src
// Pointer to the data source.
// word length
// The number of bytes to copy.
// byte xdata* ramBuffer
// A pointer to a 128 byte big buffer in XDATA memory space used to
// hold temporary data.
// word clkFreq
// The XOSC clock frequency in kHz.
//
// Return value:
// bool
// TRUE if the write was successful. False if programming/verification
// failed or the supplied arguments were invalid.
//----------------------------------------------------------------------------
bool halCopy2Flash(byte code* flashPtr, byte* src, word length, byte xdata* ramBuffer, word clkFreq);
//---------------------------------------------------------------------------
// Macro used to disable any wait states on XDATA memory accesses. Should
// always be run at the start of programs.
#define MEM_NO_WAIT_STATES() (CKCON&=~0x07)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Macro used to set the FLASH module's power mode. _pm_ must be one of the
// constants defined below. This macro is used to define
#define FLASH_SET_POWER_MODE(pm) (FLCON= (FLCON&~0x60)|(pm&0x60))
#define FLASH_ALWAYS_ON 0x00
#define FLASH_STANDBY_DURING_IDLE_AND_STOP 0x20
#define FLASH_STANDBY_BETWEEN_READS 0x40
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Macro used to start a manually configured flash write. The macro is
// compatible with the CC1010 serial debugger. Usage example:
// Setup write parameters...
// FLASH_WRITE();
// Continue program...
#define FLASH_WRITE() do { \
CY=EA; \
EA=0; \
FLCON |= 0x10; \
RESERVED |= 0x80; \
PCON|=0x01; \
EA=CY; \
} while(0)
//----------------------------------------------------------------------------
/*****************************************************************************
*****************************************************************************
************* Power and clock management *************
*****************************************************************************
****************************************************************************/
//----------------------------------------------------------------------------
// Macro used to put the CC1010 in the low-power idle mode. (Processor stops,
// all peripherals run as normal.) The processor continues execution in an ISR
// as soon as an interrupt request comes from an interrupt source which is
// enabled.
#define ENTER_IDLE_MODE() (PCON|=0x01)
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Macro used to put the CC1010 in the very-low-power stop mode. (processor and
// peripherals stopped, main clock tree is gated. Only the ADC and its threshold
// logic is active.) A reset is necessary to continue execution (from the start
// of program memory.) Unless the ADC is enabled and using the main oscillator as
// clock source, the main clock oscillator should be disabled by the
// halMainOscillatorEnable(...) function.
#define ENTER_SLEEP_MODE() do { \
FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS); \
PCON|=0x02; \
} while (0)
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Macro used for switching between clock sources for the main clock tree.
#define MAIN_CLOCK_SET_SOURCE(cs) ( X32CON=(X32CON&~0x01)|(cs) )
//The clock source must be one of the below defined constants.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -