You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
7.5 KiB

1 year ago
#include "USART0.h"
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ISR(USART0_TX_vect){
if (USART0STR.TxSendedCount == USART0STR.TxBufCount){
*USART0STR.USART->UCRSB&=~((1<<TXCIE0)|(1<<TXEN0));
USART0STR.TxSendedCount = 0;
USART0STR.TxBufCount = 0;
USART0STR.TxComplete = 1;
} else {
*USART0STR.USART->UDR=USART0STR.TX_BUF[USART0STR.TxSendedCount];
USART0STR.TxSendedCount++;
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ISR(USART0_RX_vect){
TIMSK4=0; TCNT4=0; // Timeout Timer4 On, clkI/O/8 (From prescaller)
TCCR4B=2; TIMSK4=1<<OCIE4A;
if (USART0STR.RxBufCount < USART0_BUF_SIZE){
USART0STR.RX_BUF[USART0STR.RxBufCount] = *USART0STR.USART->UDR;
USART0STR.RxBufCount++;
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ISR(TIMER4_COMPA_vect) {
TCCR4B=0; TCNT4=0; TIMSK4=0; // Timeout TIMER3 off
*USART0STR.USART->UCRSB&=~((1<<RXCIE1)|(1<<RXEN1)); // RX off
USART0STR.RxComplete = 1; // RX data ready
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void USART0_Init(void) {
//USART0STR.USART = USART0_PERIPH_POINTER;
//USART0STR.DMATX = USART0_DMA_TX_STREAM;
USART0_ADR.UCRSA = &UCSR0A;
USART0_ADR.UCRSB = &UCSR0B;
USART0_ADR.UCRSC = &UCSR0C;
USART0_ADR.UDR = &UDR0;
USART0_ADR.UBRR = &UBRR0;
USART0STR.USART = &USART0_ADR;
USART0STR.RX_BUF = USART0_RX_BUF;
USART0STR.TX_BUF = USART0_TX_BUF;
USART0STR.TxBufCount = 0;
USART0STR.TxSendedCount = 0;
USART0STR.RxBufCount = 0;
USART0STR.RxComplete = 0;
USART0STR.TxComplete = 1;
USART0STR.InterFrameTimeoutTicks = 0;
USART0_INTERFACE.SetNewBaudrate = USART0_SetBaudrate;
USART0_INTERFACE.SendTxBuf = USART0_SendTxBuf;
USART0_INTERFACE.SendByteBuf = USART0_SendByteBuf;
USART0_INTERFACE.IsNewRxMessage = USART0_IsNewRxMessage;
USART0_INTERFACE.IsTxActive = USART0_IsTxActive;
USART0_INTERFACE.IsRxError = USART0_IsRxError;
USART0_INTERFACE.getRxBufSize = USART0_getRxBufSize;
USART0_INTERFACE.copyRxBuf = USART0_copyRxBuf;
USART0_INTERFACE.getRxBuf = USART0_getRxBuf;
USART0_INTERFACE.getTxBuf = USART0_getTxBuf;
USART0_INTERFACE.RxTransferRestart = USART0_RxTransferRestart;
/*
USART0_IDIBUS.SetIdiBusBoudrate = USART0_SetIdiBusBoudrate;
USART0_IDIBUS.RxAlarmFrameStart = USART0_RxAlarmFrameStart;
USART0_IDIBUS.ResponseTimeoutComplete = 0;
USART0_IDIBUS.AlarmTimeoutUS = 0;
USART0_IDIBUS.ResponseTimeoutUS = 0;
USART0_IDIBUS.TimerMode = IDIBUS_TIMER_MODE_RX_TIMEOUT;
*/
USART0_TX_DDR&=~(1<<USART0_TX_BIT); USART0_TX_PORT|=1<<USART0_TX_BIT; // TXD -> Z
USART0_RX_DDR&=~(1<<USART0_RX_BIT); USART0_RX_PORT|=1<<USART0_RX_BIT; // RXD -> Z
*USART0STR.USART->UCRSA=0;
*USART0STR.USART->UCRSB=(1<<RXCIE0)|(1<<RXEN0); // RX enable
*USART0STR.USART->UCRSC=(1<<UCSZ00)|(1<<UCSZ01)|(1<<USBS0); // 8 bit, 2 stop
TCCR4B=0; TCNT4=0; TIMSK4=0; // Timeout TIMER3 off
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void USART0_SetBaudrate(uint32_t Baudrate){
*USART0STR.USART->UBRR = (F_CPU/16UL)/Baudrate-1;
OCR4A = 4015;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint8_t USART0_IsNewRxMessage(void) { return USART0STR.RxComplete; }
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint8_t USART0_IsRxError(void) { return USART0STR.RxError; }
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint16_t USART0_getRxBufSize(void) { return USART0STR.RxBufCount; }
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
volatile uint8_t *USART0_getRxBuf(void) { return &USART0STR.RX_BUF[0]; }
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
volatile uint8_t *USART0_getTxBuf(void) { return &USART0STR.TX_BUF[0]; }
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void USART0_copyRxBuf(uint8_t *Dst, uint16_t StartPos, uint16_t Count) { memcpy(Dst, &USART0STR.RX_BUF[StartPos], Count); }
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint8_t USART0_IsTxActive(void){
if (USART0STR.TxComplete) return 0;
else return 1;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void USART0_SendByteBuf(uint8_t *Buf, uint16_t Count){
if ( (!USART0STR.TxComplete) || (Count == 0) || (Count > USART0_BUF_SIZE) ) { return; }
memcpy(USART0STR.TX_BUF, Buf, Count);
USART0_TX_DDR|=1<<USART0_TX_BIT; USART0_TX_PORT|=1<<USART0_TX_BIT; // TXD -> out
USART0STR.TxComplete = 0;
USART0STR.TxBufCount = Count;
USART0STR.TxSendedCount = 1;
*USART0STR.USART->UCRSB|=(1<<TXCIE0)|(1<<TXEN0);
*USART0STR.USART->UDR = USART0STR.TX_BUF[0];
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void USART0_SendTxBuf(uint16_t Count){
if ( (!USART0STR.TxComplete) || (Count == 0) || (Count > USART0_BUF_SIZE) ) { return; }
USART0_TX_DDR|=1<<USART0_TX_BIT; USART0_TX_PORT|=1<<USART0_TX_BIT; // TXD -> out
USART0STR.TxComplete = 0;
USART0STR.TxBufCount = Count;
USART0STR.TxSendedCount = 1;
*USART0STR.USART->UCRSB|=(1<<TXCIE0)|(1<<TXEN0);
*USART0STR.USART->UDR = USART0STR.TX_BUF[0];
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void USART0_RxTransferRestart(void){
//USART0_RX_TIMER_STOP(); //We are already doing this in IRQ
//(void) USART0STR.USART->SR;
//(void) USART0STR.USART->DR;
*USART0STR.USART->UCRSB|=(1<<RXCIE0)|(1<<RXEN0);
USART0STR.RxBufCount = 0;
USART0STR.RxComplete = 0;
USART0STR.RxError = 0;
USART0_IDIBUS.TimerMode = IDIBUS_TIMER_MODE_RX_TIMEOUT;
//USART0_RX_TIMER_SET_TIMEOUT(USART0STR.InterFrameTimeoutUS);
OCR4A = USART0STR.InterFrameTimeoutTicks; //Not necessary but why not
//USART0STR.USART->CR1 |= (1U<<USART_CR1_RE_Pos);
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------