📄 common.c
字号:
#include "common.h"
// *****************************************************
// variables
_u32 cclk = 0;
_u32 pclk = 0;
volatile _u8 uart0_rxBuf[128];
volatile _u16 uart0_rxWr = 0;
volatile _u16 uart0_rxRd = 0;
// *****************************************************
// misc
void delay_us(_u32 us)
{
volatile _u32 clk = (_s32)(((_u64)cclk * us) / 10000000);
while (clk-- > 0);
}
bool delay_ms(_u16 ms)
{ // sit n wait for a number of milliseconds
if (ms < 1) return false; // safe guard + wots the point?
if (PCONP & PCONP_PCTIM1) return false; // the timer is already in use
// if (T1TCR & T1TCR_Counter_Enable) return false; // the timer is already in use
//
PCONP |= PCONP_PCTIM1; // power up timer 1
//
T1TCR = T1TCR_Counter_Reset; // stop & reset the timer counter
T1TCR = 0; //
T1TC = 0; //
T1PC = 0; //
T1EMR = 0; //
T1CCR = 0; //
T1PR = 0; //
T1MR0 = (_u32)(((_u64)pclk * ms) / 1000) - 1; // Set timer match register value
T1IR = 0xFF; // Clear the timer interrupt flags
T1MCR = T1MCR_MR0S; // stop timer on match
T1TCR = T1TCR_Counter_Enable; // Start timer
while (T1TCR & T1TCR_Counter_Enable); // wait until delay time has elapsed
//
PCONP &= ~PCONP_PCTIM1; // power down timer 1
//
return true; //
}
// *****************************************************
bool start_test_timer(void)
{ // start timer 1 so we can do sum speed testing or such like
if (PCONP & PCONP_PCTIM1) return false; // the timer is already in use
//
PCONP |= PCONP_PCTIM1; // power up timer 1
//
T1TCR = T1TCR_Counter_Reset; // stop & reset the timer counter
T1TCR = 0; //
T1TC = 0; //
T1PC = 0; //
T1EMR = 0; //
T1CCR = 0; //
T1PR = 0; //
T1MR0 = 0xffffffff; // Set timer match register value
T1IR = 0xFF; // Clear the timer interrupt flags
T1MCR = T1MCR_MR0S; // stop timer on match
T1TCR = T1TCR_Counter_Enable; // Start timer
//
return true; //
}
_u32 stop_test_timer(void)
{
_u32 result;
if (!(PCONP & PCONP_PCTIM1)) return 0; // the timer isunt running :(
if (!(T1TCR & T1TCR_Counter_Enable)) return 0; // the timer isunt enabled :(
T1TCR &= ~T1TCR_Counter_Enable; // Stop timer
result = T1TC; // get the counter value
T1TCR = 0; // Stop timer
PCONP &= ~PCONP_PCTIM1; // power down timer 1
return result; // return the counter value
}
// *****************************************************
// spi routines
_u32 SPI0_Initialize(_u32 freq, bool master, bool clk_edge_2, bool sclk_active_low, bool lsb_1st, bool use_SSEL, bool set_pins, CTL_ISR_FN_t isr)
{
_u8 b;
PCONP |= PCONP_PCSPI0; // power up SPI0
S0SPCR = 0; // start a fresh
_u32 div = pclk / freq; // spi sclk freq
if (div < 8) div = 8; // the internal hardware has speed limits
else
if (div > 254) div = 254; // yes it does!
div &= ~Bit0; // clear bit-0 - divider value must always be even
S0SPCCR = (_u8)div; // set the spi clock rate
if (clk_edge_2) S0SPCR |= S0SPCR_CPHA; // Data sampled on the second clock edge of the SCK
if (sclk_active_low) S0SPCR |= S0SPCR_CPOL; // SCK is active low
if (master) S0SPCR |= S0SPCR_MSTR; // master
if (lsb_1st) S0SPCR |= S0SPCR_LSBF; // lsb 1st
b = S0SPDR; // clear the Rx FIFO
b = S0SPSR; // clear status flags
S0SPINT = Bit0; // clear interrupt flag
if (set_pins)
{
// set the SCLK, MOSI & MISO pins as an SCLK, MOSI & MISO
PINSEL0 &= ~(Bit13 | Bit11 | Bit9);
PINSEL0 |= Bit12 | Bit10 | Bit8;
if (use_SSEL)
{ // set the SSEL pin as a SSEL
PINSEL0 &= ~Bit15;
PINSEL0 |= Bit14;
}
}
if (isr)
{ // add int vector & enable int
ctl_set_isr(SPI0_INT, SPI0_Int_Priority, CTL_ISR_TRIGGER_FIXED, isr, 0);
ctl_unmask_isr(SPI0_INT);
S0SPCR |= Bit7; // enable spi interrupt
}
else
{ // remove any int vector there might be
ctl_mask_isr(SPI0_INT);
ctl_set_isr(SPI0_INT, SPI0_Int_Priority, 0, 0, 0);
}
return (pclk / S0SPCCR); // return the actual speed we managed to set the sclk freq too
}
void SPI0_Deinitialize(void)
{
S0SPCR = 0; // Disable spi interrupt
ctl_mask_isr(SPI0_INT);
ctl_set_isr(SPI0_INT, SPI0_Int_Priority, 0, 0, 0);
// set the SCLK, MOSI & MISO pins back to normal IO mode
PINSEL0 &= ~(Bit13|Bit12 | Bit11|Bit10 | Bit9|Bit8);
// set the SSEL pin back to normal IO mode
PINSEL0 &= ~(Bit15|Bit14);
PCONP &= ~PCONP_PCSPI0; // power down SPI0
}
void SPI0_SendByte(_u8 b)
{
S0SPDR = b; // send byte
}
_u8 SPI0_GetByte(_u8 b)
{
return S0SPDR; // return rx'ed byte
}
int SPI0_WaitForTx(void)
{ // wait for tx byte to be sent
register _u8 stat;
volatile _u32 i = cclk >> 13; // timeout value
while (!((stat = S0SPSR) & S0SPSR_SPIF)) // wait for byte to be sent
{
if (i-- == 0) return -1; // time-out
}
return 0; // byte sent
}
_u8 SPI0_WaitForTxGetRx(void)
{ // wait for tx byte to be sent & return rx'ed byte
register _u8 stat;
volatile _u32 i = cclk >> 13; // timeout value
while (!((stat = S0SPSR) & S0SPSR_SPIF)) // wait for byte to be sent
{
if (i-- == 0) return 0xff; // time-out
}
return S0SPDR; // return the byte rx'ed
}
_u8 SPI0_8(_u8 b)
{ // tx a byte & rx one back over the SPI-0 line
SPI0_SendByte(b); // send byte
return SPI0_WaitForTxGetRx(); // wait for byte to finish being sent
}
_u16 SPI0_16(_u16 w)
{ // tx a word & rx one back over the SPI-0 line
register _u16 r;
SPI0_SendByte(w >> 8); // send MS-Byte
r = (_u16)SPI0_WaitForTxGetRx() << 8; // wait for byte to finish being sent and get rx'ed byte
SPI0_SendByte(w); // send LS-Byte
r |= (_u16)SPI0_WaitForTxGetRx(); // wait for byte to finish being sent and get rx'ed byte
return r; // return the rx'ed word
}
// *****************************************************
// uart routines
_u32 UART0_Initialize(unsigned int baud, _u8 fifo_size, CTL_ISR_FN_t isr)
{ // Configure UART
PCONP |= PCONP_PCUART0; // power up uart-0
_u32 br_div = pclk / ((_u32)baud << 4); // work out the baud rate divider value
U0IER = 0; // disable all interrupts
U0IIR = 0; // clear interrupt ID register
U0LSR = 0; // clear line status register
U0FCR = 0; // no fifo
U0LCR |= U0LCR_Divisor_Latch_Access_Bit; // Enable DLAB access
U0DLL = br_div & 0xFF; //
U0DLM = (br_div >> 8) & 0xFF; //
U0LCR &= ~U0LCR_Divisor_Latch_Access_Bit; // Disable DLAB access
U0LCR = 0; // default to 5-bit, 1-stop bit, odd-parity, no break tx, no DLAB access
// U0LCR |= Bit0; // change to 6 bit
// U0LCR |= Bit1; // change to 7 bit
U0LCR |= Bit1 | Bit0; // change to 8 bit
// U0LCR |= Bit2; // change to 2-stop bits
// U0LCR |= Bit3; // change to even-parity generation & checking
// U0LCR |= Bit4; // change to even-parity
// U0LCR |= Bit5; // change to force '1' sticky parity
// U0LCR |= Bit5 | Bit4; // change to force '0' sticky parity
// U0LCR |= Bit6; // change to enable break tx
// set the TxD pin as TxD
PINSEL0 &= ~Bit1; //
PINSEL0 |= Bit0; //
// set the RxD pin as RxD
PINSEL0 &= ~Bit3; //
PINSEL0 |= Bit2; //
if (fifo_size > 0)
{ // enable the chips uart Tx & Rx FIFO buffers
if (fifo_size <= 1) U0FCR = 0; // FIFO trigger = 1 byte
else
if (fifo_size <= 4) U0FCR = Bit6; // FIFO trigger = 4 bytes
else
if (fifo_size <= 8) U0FCR = Bit7; // FIFO trigger = 8 bytes
else
if (fifo_size <= 14) U0FCR = Bit7 | Bit6; // FIFO trigger = 14 bytes
else
U0FCR = Bit7; // FIFO trigger = 8 bytes
U0FCR |= U0FCR_FIFO_Enable; // enable the fifo's
U0FCR |= U0FCR_Tx_FIFO_Reset | U0FCR_Rx_FIFO_Reset; // clear the TX & RX fifo's
}
// Setup UART RX interrupt
if (isr)
{
ctl_set_isr(UART0_INT, UART0_Int_Priority, CTL_ISR_TRIGGER_FIXED, isr, 0); // add a vector int entry
ctl_unmask_isr(UART0_INT); // enable the interrupt
// enable desired interrupt triggers
U0IER = U0IER_RBR_Interrupt_Enable; // Rx byte interrupt
// U0IER |= U0IER_THRE_Interrupt_Enable; // THRE interrupt (tx holding register)
U0IER |= U0IER_Rx_Line_Status_Interrupt_Enable; // Rx line status interrupt
}
return ((pclk / br_div) << 4); // return the actual speed we managed to set the baud rate too
}
void UART0_Deinitialize(void)
{
if (PCONP & PCONP_PCUART0)
{
U0IER = 0; // disable ints
U0IIR = 0; // clear interrupt ID register
}
ctl_mask_isr(UART0_INT); // stop ints
ctl_set_isr(UART0_INT, UART0_Int_Priority, 0, 0, 0); // clear int vector
PCONP &= ~PCONP_PCUART0; // power down uart-0
}
void ClearRxUartFIFO(int uart)
{
switch (uart)
{
case 0 : if (PCONP & PCONP_PCUART0) U0FCR |= U0FCR_Rx_FIFO_Reset; // clear the RX fifo
break;
case 1 : if (PCONP & PCONP_PCUART1) U1FCR |= U1FCR_Rx_FIFO_Reset; // clear the RX fifo
break;
}
}
void ClearTxUartFIFO(int uart)
{
switch (uart)
{
case 0 : if (PCONP & PCONP_PCUART0) U0FCR |= U0FCR_Tx_FIFO_Reset; // clear the TX fifo
break;
case 1 : if (PCONP & PCONP_PCUART1) U1FCR |= U1FCR_Tx_FIFO_Reset; // clear the TX fifo
break;
}
}
bool WriteByte_uart0(_u8 ch, _s32 timeout)
{
register _s32 i = timeout;
if (!(PCONP & PCONP_PCUART0)) return false; // the uart is not powered up
while (!(U0LSR & U0LSR_THRE)) // wait for tx to be ready for new byte
{
if (--i <= 0) return false; // time-out
}
U0THR = ch; // tx byte
return true;
}
void WriteStr_uart0(char *s)
{
if (!(PCONP & PCONP_PCUART0)) return; // the uart is not powered up
while (*s != 0) WriteByte_uart0(*s++, 1000000); // send each byte of the string
}
// ****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -