Commit 7fdf8c10 authored by Daniel Kampert's avatar Daniel Kampert 👷

Remove old ATtiny0 family driver

parent 8f364b30
/*
* CPU.h
*
* Copyright (C) Daniel Kampert, 2018
* Website: www.kampis-elektroecke.de
* File info: Driver for XMega CPU.
GNU GENERAL PUBLIC LICENSE:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Errors and commissions should be reported to [email protected]
*/
/** @file Arch/AVR8/tinyAVR/CPU/CPU.h
* @brief Driver for XMega CPU.
*
* This file contains the prototypes and definitions for the XMega CPU driver.
*
* @author Daniel Kampert
* @bug No known bugs.
*/
#ifndef CPU_H_
#define CPU_H_
#include "Common/Common.h"
/** @brief Create a memory barrier so the compiler doesn't change the code execution order.
*/
#define Barrier() asm volatile("" ::: "memory")
/** @brief Global enable for interrupts.
*/
static inline void EnableGlobalInterrupts(void) __attribute__ ((always_inline));
static inline void EnableGlobalInterrupts(void)
{
sei();
}
/** @brief Global disable for interrupts.
*/
static inline void DisableGlobalInterrupts(void) __attribute__ ((always_inline));
static inline void DisableGlobalInterrupts(void)
{
cli();
}
/** @brief Save the CPU flags and disable interrupts.
* @return CPU flags
*/
static inline volatile uint8_t CPU_IRQSave(void) __attribute__ ((always_inline));
static inline volatile uint8_t CPU_IRQSave(void)
{
volatile uint8_t Flags = SREG;
DisableGlobalInterrupts();
return Flags;
}
/** @brief Restore the CPU flags.
* @param Flags CPU flags
*/
static inline void CPU_IRQRestore(volatile uint8_t Flags) __attribute__ ((always_inline));
static inline void CPU_IRQRestore(volatile uint8_t Flags)
{
Barrier();
SREG = Flags;
}
#endif /* CPU_H_ */
\ No newline at end of file
/*
* GPIO.h
*
* Copyright (C) Daniel Kampert, 2018
* Website: www.kampis-elektroecke.de
* File info: Driver for Atmel AVR8 tinyAVR GPIO interface.
GNU GENERAL PUBLIC LICENSE:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Errors and omissions should be reported to [email protected]
*/
/** @file Arch/AVR8/tinyAVR/GPIO/GPIO.h
* @brief Driver for Atmel AVR8 tinyAVR GPIO interface.
*
* This file contains the prototypes and definitions for the AVR8 tinyAVR GPIO driver.
*
* @author Daniel Kampert
* @bug - Event mode
*/
#ifndef GPIO_H_
#define GPIO_H_
#include "Common/Common.h"
/** @brief GPIO callback definition.
*/
typedef void (*GPIO_Callback_t)(void);
/** @brief GPIO output directions
*/
typedef enum
{
GPIO_DIRECTION_IN = 0x00, /**< Direction input */
GPIO_DIRECTION_OUT = 0x01, /**< Direction output */
} GPIO_Direction_t;
/** @brief Set the direction of an I/O port.
* @param Port Pointer to port object
* @param Mask Port mask
* @param Direction I/O Direction
*/
static inline void GPIO_SetPortDirection(PORT_t* Port, const uint8_t Mask, const GPIO_Direction_t Direction) __attribute__ ((always_inline));
static inline void GPIO_SetPortDirection(PORT_t* Port, const uint8_t Mask, const GPIO_Direction_t Direction)
{
if(Direction == GPIO_DIRECTION_IN)
{
Port->DIRCLR = Mask;
}
else if(Direction == GPIO_DIRECTION_OUT)
{
Port->DIRSET = Mask;
}
}
/** @brief Set the direction of an I/O pin.
* @param Port Pointer to port object
* @param Pin Pin number
* @param Direction I/O Direction
*/
static inline void GPIO_SetDirection(PORT_t* Port, const uint8_t Pin, const GPIO_Direction_t Direction) __attribute__ ((always_inline));
static inline void GPIO_SetDirection(PORT_t* Port, const uint8_t Pin, const GPIO_Direction_t Direction)
{
if(Direction == GPIO_DIRECTION_IN)
{
Port->DIRCLR = (0x01 << Pin);
}
else if(Direction == GPIO_DIRECTION_OUT)
{
Port->DIRSET = (0x01 << Pin);
}
}
/** @brief Set an I/O as output.
* @param Port Pointer to port object
* @param Pin Pin number
*/
static inline void GPIO_SetDir(PORT_t* Port, const uint8_t Pin) __attribute__ ((always_inline));
static inline void GPIO_SetDir(PORT_t* Port, const uint8_t Pin)
{
Port->DIRSET = 0x01 << Pin;
}
/** @brief Set an I/O as input.
* @param Port Pointer to port object
* @param Pin Pin number
*/
static inline void GPIO_ClearDir(PORT_t* Port, const uint8_t Pin) __attribute__ ((always_inline));
static inline void GPIO_ClearDir(PORT_t* Port, const uint8_t Pin)
{
Port->DIRCLR = 0x01 << Pin;
}
/** @brief Toggle the direction of an I/O.
* @param Port Pointer to port object
* @param Pin Pin number
*/
static inline void GPIO_ToggleDirection(PORT_t* Port, const uint8_t Pin) __attribute__ ((always_inline));
static inline void GPIO_ToggleDirection(PORT_t* Port, const uint8_t Pin)
{
Port->DIRTGL = 0x01 << Pin;
}
/** @brief Read the value of an I/O port.
* @param Port Pointer to port object
* @return I/O state of the port
*/
static inline const uint8_t GPIO_ReadPort(PORT_t* Port) __attribute__ ((always_inline));
static inline const uint8_t GPIO_ReadPort(PORT_t* Port)
{
return Port->IN;
}
/** @brief Read the value of an I/O.
* @param Port Pointer to port object
* @param Pin Pin number
* @return I/O state
*/
static inline const Bool_t GPIO_Read(PORT_t* Port, const uint8_t Pin) __attribute__ ((always_inline));
static inline const Bool_t GPIO_Read(PORT_t* Port, const uint8_t Pin)
{
return (Port->IN & (0x01 << Pin)) >> Pin;
}
/** @brief Apply a data mask to set the complete port.
* @param Port Pointer to port object
* @param Mask Data mask
*/
static inline void GPIO_SetPort(PORT_t* Port, const uint8_t Mask) __attribute__ ((always_inline));
static inline void GPIO_SetPort(PORT_t* Port, const uint8_t Mask)
{
Port->OUT |= Mask;
}
/** @brief Set an I/O to high state.
* @param Port Pointer to port object
* @param Pin Pin number
*/
static inline void GPIO_Set(PORT_t* Port, const uint8_t Pin) __attribute__ ((always_inline));
static inline void GPIO_Set(PORT_t* Port, const uint8_t Pin)
{
Port->OUTSET = 0x01 << Pin;
}
/** @brief Apply a data mask to clear the complete port.
* @param Port Pointer to port object
* @param Mask Data mask
*/
static inline void GPIO_ClearPort(PORT_t* Port, const uint8_t Mask) __attribute__ ((always_inline));
static inline void GPIO_ClearPort(PORT_t* Port, const uint8_t Mask)
{
Port->OUTCLR = Mask;
}
/** @brief Clear an I/O.
* @param Port Pointer to port object
* @param Pin Pin number
*/
static inline void GPIO_Clear(PORT_t* Port, const uint8_t Pin) __attribute__ ((always_inline));
static inline void GPIO_Clear(PORT_t* Port, const uint8_t Pin)
{
Port->OUTCLR = 0x01 << Pin;
}
/** @brief Toggle the output of an I/O pin.
* @param Port Pointer to port object
* @param Pin Pin number
*/
static inline void GPIO_Toggle(PORT_t* Port, const uint8_t Pin) __attribute__ ((always_inline));
static inline void GPIO_Toggle(PORT_t* Port, const uint8_t Pin)
{
Port->OUTTGL = 0x01 << Pin;
}
/** @brief Enable the output of the peripheral clock on Pin 7.
* @param Enable Enable/Disable
*/
static inline void GPIO_SwitchClockOutput(const Bool_t Enable) __attribute__ ((always_inline));
static inline void GPIO_SwitchClockOutput(const Bool_t Enable)
{
uint8_t Temp = CLKCTRL.MCLKCTRLA;
if(Enable)
{
Temp |= CLKCTRL_CLKOUT_bm;
}
else
{
Temp &= ~CLKCTRL_CLKOUT_bm;
}
asm volatile( "movw r30, %0" "\n\t"
"ldi r16, %2" "\n\t"
"out %3, r16" "\n\t"
"st Z, %1" "\n\t"
:: "r" (&CLKCTRL.MCLKCTRLB),
"r" (Temp),
"M" (CCP_IOREG_gc),
"i" (&CCP)
: "r16", "r30"
);
}
#endif /* GPIO_H_ */
\ No newline at end of file
/*
* USART.c
*
* Copyright (C) Daniel Kampert, 2018
* Website: www.kampis-elektroecke.de
* File info: Driver for Atmel AVR8 tiny0 USART module.
GNU GENERAL PUBLIC LICENSE:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Errors and omissions should be reported to [email protected]
*/
/** @file Arch/AVR8/tinyAVR/tiny0/USART/USART.c
* @brief Driver for Atmel AVR8 tiny0 USART module.
*
* This contains the implementation of the tiny0 USART driver.
*
* @author Daniel Kampert
*/
#include "Arch/AVR8/tinyAVR/tiny0/USART/USART.h"
/** @brief Tx ring buffer for each USART interface.
*/
static RingBuffer_t __USART_TxRingBuffer[USART_DEVICES];
/** @brief Data buffer for Tx ring buffer.
*/
static uint8_t __TxData[USART_DEVICES][USART_BUFFER_SIZE];
#ifndef DOXYGEN
/*
Object declaration
*/
USART_Message_t __USART_Messages[USART_DEVICES];
Bool_t __USART_Echo[USART_DEVICES];
struct
{
USART_Callback_t RxCallback;
USART_Callback_t TxCallback;
USART_Callback_t EmptyCallback;
USART_Callback_t StartCallback;
USART_Callback_t SyncFieldCallback;
} __USART_Callbacks[USART_DEVICES];
#endif
void USART_Init(USART_Config_t* Config)
{
PORT_t* Port = 0x00;
uint8_t RxPin = 0x00;
uint8_t TxPin = 0x00;
Port = &PORTB;
RxPin = USART_RX0_PIN;
TxPin = USART_TX0_PIN;
USART_SwitchEcho(Config->Device, Config->EnableEcho);
USART_SetBaudrate(Config->Device, Config->Baudrate, 16000000UL, Config->EnableDoubleSpeed);
USART_SetDirection(Config->Device, Config->Direction);
USART_SetDeviceMode(Config->Device, Config->DeviceMode);
USART_SetDataSize(Config->Device, Config->Size);
USART_SetStopbits(Config->Device, Config->Stop);
USART_SetParity(Config->Device, Config->Parity);
USART_SwitchOpenDrain(Config->Device, Config->EnableOpenDrain);
if(Config->Direction == USART_DIRECTION_BOTH)
{
GPIO_SetDirection(Port, RxPin, GPIO_DIRECTION_IN);
GPIO_SetDirection(Port, TxPin, GPIO_DIRECTION_OUT);
}
else if(Config->Direction == USART_DIRECTION_RX)
{
GPIO_SetDirection(Port, RxPin, GPIO_DIRECTION_IN);
}
else if(Config->Direction == USART_DIRECTION_TX)
{
GPIO_SetDirection(Port, TxPin, GPIO_DIRECTION_OUT);
}
}
void USART_InstallCallback(const USART_InterruptConfig_t* Config)
{
if(Config->Source & USART_DRE_INTERRUPT)
{
Config->Device->CTRLA = USART_DREIE_bm;
__USART_Callbacks[0].EmptyCallback = Config->Callback;
}
if(Config->Source & USART_TXC_INTERRUPT)
{
Config->Device->CTRLA = USART_TXEN_bm;
__USART_Callbacks[0].TxCallback = Config->Callback;
}
if(Config->Source & USART_RXC_INTERRUPT)
{
Config->Device->CTRLA = USART_RXCIE_bm;
__USART_Callbacks[0].RxCallback = Config->Callback;
}
if(Config->Source & USART_RXS_INTERRUPT)
{
Config->Device->CTRLA = USART_RXSIE_bm;
__USART_Callbacks[0].EmptyCallback = Config->Callback;
}
if(Config->Source & USART_ISF_INTERRUPT)
{
__USART_Callbacks[0].SyncFieldCallback = Config->Callback;
}
}
void USART_RemoveCallback(USART_t* Device, const USART_CallbackType_t Callback)
{
if(Callback & USART_DRE_INTERRUPT)
{
__USART_Callbacks[0].EmptyCallback = NULL;
}
if(Callback & USART_TXC_INTERRUPT)
{
__USART_Callbacks[0].TxCallback = NULL;
}
if(Callback & USART_RXC_INTERRUPT)
{
__USART_Callbacks[0].RxCallback = NULL;
}
if(Callback & USART_RXS_INTERRUPT)
{
__USART_Callbacks[0].StartCallback = NULL;
}
if(Callback & USART_ISF_INTERRUPT)
{
__USART_Callbacks[0].SyncFieldCallback = NULL;
}
}
void USART_SwitchEcho(USART_t* Device, const Bool_t Enable)
{
uint8_t USART = 0x00;
if(Device == &USART0)
{
USART = 0;
}
if(Enable == TRUE)
{
__USART_Echo[USART] = TRUE;
}
else
{
__USART_Echo[USART] = FALSE;
}
}
void USART_SetBaudrate(USART_t* Device, const uint32_t Baudrate, const uint32_t Clock, const Bool_t DoubleSpeed)
{
uint8_t S = 0x10 >> (DoubleSpeed & 0x01);
uint16_t Baud = (Clock << 0x06) / (S * Baudrate);
Device->CTRLB = (Device->CTRLB & ~(0x03 << 0x01)) | ((DoubleSpeed & 0x01) << 0x01);
Device->BAUD = Baud;
}
void USART_Write(USART_t* Device, const char* Data)
{
while(*Data)
{
USART_SendChar(Device, *Data++);
}
}
void USART_WriteDecimal(USART_t* Device, const uint32_t Value)
{
uint32_t Temp = Value / 10;
char Buffer[2];
if(Temp)
{
USART_WriteDecimal(Device, Temp);
}
Buffer[0] = 0x30 + (Value % 10);
Buffer[1] = '\0';
USART_Write(Device, Buffer);
}
void USART_WriteLine(USART_t* Device, const char* Data)
{
while(*Data)
{
USART_SendChar(Device, *Data++);
}
USART_SendChar(Device, LF);
USART_SendChar(Device, CR);
}
\ No newline at end of file
/*
* USART_Interrupt.c
*
* Created: 11.05.2017 21:28:03
* Author: Daniel Kampert
* Website: www.kampis-elektroecke.de
* File info: Interrupt driver for Atmel AVR8 tiny0 USART module.
GNU GENERAL PUBLIC LICENSE:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Errors and commissions should be reported to [email protected]
*/
/** @file Arch/AVR8/tinyAVR/tiny0/USART/USART_Interrupt.c
* @brief Interrupt driver for Atmel AVR8 tiny0 USART module.
*
* This file contains the implementation of the interrupt functions for the Atmel AVR8 tiny0 USART driver.
*
* @author Daniel Kampert
*/
#include "Arch/AVR8/tinyAVR/tiny0/USART/USART.h"
#ifndef DOXYGEN
extern struct
{
USART_Callback_t RxCallback;
USART_Callback_t TxCallback;
USART_Callback_t EmptyCallback;
USART_Callback_t StartCallback;
USART_Callback_t SyncFieldCallback;
} __USART_Callbacks[USART_DEVICES];
extern Bool_t __USART_Echo[USART_DEVICES];
extern USART_Message_t __USART_Messages[USART_DEVICES];
Bool_t __USART_IsSPI[USART_DEVICES];
#endif
/** @brief USART interrupt handler.
* @param Device Device ID
* @param Channel USART channel
* @param Callback Type of interrupt
*/
static void __USART_InterruptHandler(const uint8_t Device, const USART_CallbackType_t Callback)
{
if(__USART_IsSPI[Device] == TRUE)
{
if(Callback == USART_TXC_INTERRUPT)
{
}
else if(Callback == USART_RXC_INTERRUPT)
{
}
}
else
{
if(Callback == USART_DRE_INTERRUPT)
{
if (__USART_Callbacks[Device].EmptyCallback)
{
__USART_Callbacks[Device].EmptyCallback();
}
if(!(RingBuffer_IsEmpty(__USART_Messages[Device].Ptr_TxRingBuffer)))
{
__USART_Messages[Device].Device->TXDATAL = RingBuffer_Load(__USART_Messages[Device].Ptr_TxRingBuffer);
}
else
{
__USART_Messages[Device].Device->CTRLA &= ~0x03;
}
}
else if(Callback == USART_TXC_INTERRUPT)
{
if (__USART_Callbacks[Device].TxCallback)
{
__USART_Callbacks[Device].TxCallback();
}
}
else if(Callback == USART_RXC_INTERRUPT)
{
// Echo message when enabled
if(__USART_Echo[Device] == TRUE)
{
__USART_Messages[Device].Device->TXDATAL = __USART_Messages[Device].Device->RXDATAL;
__USART_Messages[Device].Device->TXDATAH = __USART_Messages[Device].Device->RXDATAH;
}
if (__USART_Callbacks[Device].RxCallback)
{
__USART_Callbacks[Device].RxCallback();
}
}
}
}
/*
Interrupt vectors
*/
#ifndef DOXYGEN
ISR(USART0_RXC_vect)
{
__USART_InterruptHandler(0, USART_RXC_INTERRUPT);
}
ISR(USART0_TXC_vect)
{
__USART_InterruptHandler(0, USART_TXC_INTERRUPT);
}
ISR(USART0_DRE_vect)
{
__USART_InterruptHandler(0, USART_DRE_INTERRUPT);
}
#endif
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment