This code is from project: IR remote emulator with attiny45
USI_TWI_Slave.h
// This file has been prepared for Doxygen automatic documentation generation.
/*! \file ********************************************************************
*
* Atmel Corporation
*
* File : USI_TWI_Slave.h
* Compiler : IAR EWAAVR 4.11A
* Revision : $Revision: 1.14 $
* Date : $Date: Friday, December 09, 2005 17:25:38 UTC $
* Updated by : $Author: jtyssoe $
*
* Support mail : avr@atmel.com
*
* Supported devices : All device with USI module can be used.
* The example is written for the ATmega169, ATtiny26 & ATtiny2313
*
* AppNote : AVR312 - Using the USI module as a TWI slave
*
* Description : Header file for USI_TWI driver
*
*
*
****************************************************************************/
#include <avr/io.h> // HC-ADDED
#include <avr/interrupt.h> // HC-ADDED
//! Prototypes
void USI_TWI_Slave_Initialise( unsigned char );
void USI_TWI_Transmit_Byte( unsigned char );
unsigned char USI_TWI_Receive_Byte( void );
unsigned char USI_TWI_Data_In_Receive_Buffer( void );
void Timer_Init(void);
#define TRUE 1
#define FALSE 0
typedef unsigned char uint8_t;
//////////////////////////////////////////////////////////////////
///////////////// Driver Buffer Definitions //////////////////////
//////////////////////////////////////////////////////////////////
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
#define TWI_RX_BUFFER_SIZE (16)
#define TWI_RX_BUFFER_MASK ( TWI_RX_BUFFER_SIZE - 1 )
#if ( TWI_RX_BUFFER_SIZE & TWI_RX_BUFFER_MASK )
#error TWI RX buffer size is not a power of 2
#endif
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
#define TWI_TX_BUFFER_SIZE (16)
#define TWI_TX_BUFFER_MASK ( TWI_TX_BUFFER_SIZE - 1 )
#if ( TWI_TX_BUFFER_SIZE & TWI_TX_BUFFER_MASK )
#error TWI TX buffer size is not a power of 2
#endif
#define USI_SLAVE_CHECK_ADDRESS (0x00)
#define USI_SLAVE_SEND_DATA (0x01)
#define USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA (0x02)
#define USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA (0x03)
#define USI_SLAVE_REQUEST_DATA (0x04)
#define USI_SLAVE_GET_DATA_AND_SEND_ACK (0x05)
//! Device dependent defines
#if defined(__AT90tiny26__) | defined(__ATtiny26__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB0
#define PORT_USI_SCL PORTB2
#define PIN_USI_SDA PINB0
#define PIN_USI_SCL PINB2
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_STRT_vect
#define USI_OVERFLOW_VECTOR USI_OVF_vect
#endif
#if defined(__AT90Tiny2313__) | defined(__ATtiny2313__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB5
#define PORT_USI_SCL PORTB7
#define PIN_USI_SDA PINB5
#define PIN_USI_SCL PINB7
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_STRT_vect
#define USI_OVERFLOW_VECTOR USI_OVF_vect
#endif
#if defined(__ATtiny25__) | defined(__ATtiny45__) | defined(__ATtiny85__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB0
#define PORT_USI_SCL PORTB2
#define PIN_USI_SDA PINB0
#define PIN_USI_SCL PINB2
// #define USI_START_COND_INT USICIF
#define USI_START_COND_INT USISIF // HC-CHANGED
#define USI_START_VECTOR USI_START_vect
#define USI_OVERFLOW_VECTOR USI_OVF_vect
#endif
#if defined(__AT90Mega165__) | defined(__ATmega165__) | \
defined(__ATmega325__) | defined(__ATmega3250__) | \
defined(__ATmega645__) | defined(__ATmega6450__) | \
defined(__ATmega329__) | defined(__ATmega3290__) | \
defined(__ATmega649__) | defined(__ATmega6490__)
#define DDR_USI DDRE
#define PORT_USI PORTE
#define PIN_USI PINE
#define PORT_USI_SDA PORTE5
#define PORT_USI_SCL PORTE4
#define PIN_USI_SDA PINE5
#define PIN_USI_SCL PINE4
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_START_vect
#define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
#endif
#if defined(__AT90Mega169__) | defined(__ATmega169__)
#define DDR_USI DDRE
#define PORT_USI PORTE
#define PIN_USI PINE
#define PORT_USI_SDA PORTE5
#define PORT_USI_SCL PORTE4
#define PIN_USI_SDA PINE5
#define PIN_USI_SCL PINE4
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_STRT_vect
#define USI_OVERFLOW_VECTOR USI_OVF_vect
#endif
//! Functions implemented as macros
#define SET_USI_TO_SEND_ACK() \
{ \
USIDR = 0; /* Prepare ACK */ \
DDR_USI |= (1<<PORT_USI_SDA); /* Set SDA as output */ \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0E<<USICNT0); /* set USI counter to shift 1 bit. */ \
}
#define SET_USI_TO_READ_ACK() \
{ \
DDR_USI &= ~(1<<PORT_USI_SDA); /* Set SDA as intput */ \
USIDR = 0; /* Prepare ACK */ \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0E<<USICNT0); /* set USI counter to shift 1 bit. */ \
}
#define SET_USI_TO_TWI_START_CONDITION_MODE() \
{ \
USICR = (1<<USISIE)|(0<<USIOIE)| /* Enable Start Condition Interrupt. Disable Overflow Interrupt.*/ \
(1<<USIWM1)|(0<<USIWM0)| /* Set USI in Two-wire mode. No USI Counter overflow hold. */ \
(1<<USICS1)|(0<<USICS0)|(0<<USICLK)| /* Shift Register Clock Source = External, positive edge */ \
(0<<USITC); \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0<<USICNT0); \
}
#define SET_USI_TO_SEND_DATA() \
{ \
DDR_USI |= (1<<PORT_USI_SDA); /* Set SDA as output */ \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0<<USICNT0); /* set USI to shift out 8 bits */ \
}
#define SET_USI_TO_READ_DATA() \
{ \
DDR_USI &= ~(1<<PORT_USI_SDA); /* Set SDA as input */ \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0<<USICNT0); /* set USI to shift out 8 bits */ \
}
USI_TWI_Slave.c
// This file has been prepared for Doxygen automatic documentation generation.
/*! \file ********************************************************************
*
* Atmel Corporation
*
* File : USI_TWI_Slave.c
* Compiler : IAR EWAAVR 4.11A
* Revision : $Revision: 1.14 $
* Date : $Date: Friday, December 09, 2005 17:25:38 UTC $
* Updated by : $Author: jtyssoe $
*
* Support mail : avr@atmel.com
*
* Supported devices : All device with USI module can be used.
*
* AppNote : AVR312 - Using the USI module as a I2C slave
*
* Description : Functions for USI_TWI_receiver and USI_TWI_transmitter.
*
*
****************************************************************************/
// #include <ioavr.h> // HC-REMOVED
// #include <inavr.h> // HC-REMOVED
#include "USI_TWI_Slave.h"
/*! Static Variables
*/
static unsigned char TWI_slaveAddress;
static volatile unsigned char USI_TWI_Overflow_State;
/*! Local variables
*/
static uint8_t TWI_RxBuf[TWI_RX_BUFFER_SIZE];
static volatile uint8_t TWI_RxHead;
static volatile uint8_t TWI_RxTail;
static uint8_t TWI_TxBuf[TWI_TX_BUFFER_SIZE];
static volatile uint8_t TWI_TxHead;
static volatile uint8_t TWI_TxTail;
/*! \brief Flushes the TWI buffers
*/
void Flush_TWI_Buffers(void)
{
TWI_RxTail = 0;
TWI_RxHead = 0;
TWI_TxTail = 0;
TWI_TxHead = 0;
}
//********** USI_TWI functions **********//
/*! \brief
* Initialise USI for TWI Slave mode.
*/
void USI_TWI_Slave_Initialise( unsigned char TWI_ownAddress )
{
Flush_TWI_Buffers();
TWI_slaveAddress = TWI_ownAddress;
PORT_USI |= (1<<PORT_USI_SCL); // Set SCL high
PORT_USI |= (1<<PORT_USI_SDA); // Set SDA high
DDR_USI |= (1<<PORT_USI_SCL); // Set SCL as output
DDR_USI &= ~(1<<PORT_USI_SDA); // Set SDA as input
USICR = (1<<USISIE)|(0<<USIOIE)| // Enable Start Condition Interrupt. Disable Overflow Interrupt.
(1<<USIWM1)|(0<<USIWM0)| // Set USI in Two-wire mode. No USI Counter overflow prior
// to first Start Condition (potentail failure)
(1<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = External, positive edge
(0<<USITC);
USISR = 0xF0; // Clear all flags and reset overflow counter
}
/*! \brief Puts data in the transmission buffer, Waits if buffer is full.
*/
void USI_TWI_Transmit_Byte( unsigned char data )
{
unsigned char tmphead;
tmphead = ( TWI_TxHead + 1 ) & TWI_TX_BUFFER_MASK; // Calculate buffer index.
while ( tmphead == TWI_TxTail ); // Wait for free space in buffer.
TWI_TxBuf[tmphead] = data; // Store data in buffer.
TWI_TxHead = tmphead; // Store new index.
}
/*! \brief Returns a byte from the receive buffer. Waits if buffer is empty.
*/
unsigned char USI_TWI_Receive_Byte( void )
{
unsigned char tmptail;
unsigned char tmpRxTail; // Temporary variable to store volatile
tmpRxTail = TWI_RxTail; // Not necessary, but prevents warnings
while ( TWI_RxHead == tmpRxTail );
tmptail = ( TWI_RxTail + 1 ) & TWI_RX_BUFFER_MASK; // Calculate buffer index
TWI_RxTail = tmptail; // Store new index
return TWI_RxBuf[tmptail]; // Return data from the buffer.
}
/*! \brief Check if there is data in the receive buffer.
*/
unsigned char USI_TWI_Data_In_Receive_Buffer( void )
{
unsigned char tmpRxTail; // Temporary variable to store volatile
tmpRxTail = TWI_RxTail; // Not necessary, but prevents warnings
return ( TWI_RxHead != tmpRxTail ); // Return 0 (FALSE) if the receive buffer is empty.
}
/*! \brief Usi start condition ISR
* Detects the USI_TWI Start Condition and intialises the USI
* for reception of the "TWI Address" packet.
*/
// HC-REMOVED
// #pragma vector=USI_START_VECTOR
// __interrupt void USI_Start_Condition_ISR(void)
SIGNAL(SIG_USI_START)
{
unsigned char tmpUSISR; // Temporary variable to store volatile
tmpUSISR = USISR; // Not necessary, but prevents warnings
// Set default starting conditions for new TWI package
USI_TWI_Overflow_State = USI_SLAVE_CHECK_ADDRESS;
DDR_USI &= ~(1<<PORT_USI_SDA); // Set SDA as input
while ( (PIN_USI & (1<<PORT_USI_SCL)) & !(tmpUSISR & (1<<USIPF)) ); // Wait for SCL to go low to ensure the "Start Condition" has completed.
// If a Stop condition arises then leave the interrupt to prevent waiting forever.
USICR = (1<<USISIE)|(1<<USIOIE)| // Enable Overflow and Start Condition Interrupt. (Keep StartCondInt to detect RESTART)
(1<<USIWM1)|(1<<USIWM0)| // Set USI in Two-wire mode.
(1<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = External, positive edge
(0<<USITC);
USISR = (1<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Clear flags
(0x0<<USICNT0); // Set USI to sample 8 bits i.e. count 16 external pin toggles.
}
/*! \brief USI counter overflow ISR
* Handels all the comunication. Is disabled only when waiting
* for new Start Condition.
*/
// HC-REMOVED
// #pragma vector=USI_OVERFLOW_VECTOR
// __interrupt void USI_Counter_Overflow_ISR(void)
SIGNAL(SIG_USI_OVERFLOW)
{
unsigned char tmpTxTail; // Temporary variables to store volatiles
unsigned char tmpUSIDR;
switch (USI_TWI_Overflow_State)
{
// ---------- Address mode ----------
// Check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK, else reset USI.
case USI_SLAVE_CHECK_ADDRESS:
if ((USIDR == 0) || (( USIDR>>1 ) == TWI_slaveAddress))
{
if ( USIDR & 0x01 )
USI_TWI_Overflow_State = USI_SLAVE_SEND_DATA;
else
{
USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA;
SET_USI_TO_SEND_ACK();
}
}
else
{
SET_USI_TO_TWI_START_CONDITION_MODE();
}
break;
// ----- Master write data mode ------
// Check reply and goto USI_SLAVE_SEND_DATA if OK, else reset USI.
case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:
if ( USIDR ) // If NACK, the master does not want more data.
{
SET_USI_TO_TWI_START_CONDITION_MODE();
return;
}
// From here we just drop straight into USI_SLAVE_SEND_DATA if the master sent an ACK
// Copy data from buffer to USIDR and set USI to shift byte. Next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA
case USI_SLAVE_SEND_DATA:
// Get data from Buffer
tmpTxTail = TWI_TxTail; // Not necessary, but prevents warnings
if ( TWI_TxHead != tmpTxTail )
{
TWI_TxTail = ( TWI_TxTail + 1 ) & TWI_TX_BUFFER_MASK;
USIDR = TWI_TxBuf[TWI_TxTail];
}
else // If the buffer is empty then:
{
SET_USI_TO_TWI_START_CONDITION_MODE();
return;
}
USI_TWI_Overflow_State = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;
SET_USI_TO_SEND_DATA();
break;
// Set USI to sample reply from master. Next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA
case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:
USI_TWI_Overflow_State = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA;
SET_USI_TO_READ_ACK();
break;
// ----- Master read data mode ------
// Set USI to sample data from master. Next USI_SLAVE_GET_DATA_AND_SEND_ACK.
case USI_SLAVE_REQUEST_DATA:
USI_TWI_Overflow_State = USI_SLAVE_GET_DATA_AND_SEND_ACK;
SET_USI_TO_READ_DATA();
break;
// Copy data from USIDR and send ACK. Next USI_SLAVE_REQUEST_DATA
case USI_SLAVE_GET_DATA_AND_SEND_ACK:
// Put data into Buffer
tmpUSIDR = USIDR; // Not necessary, but prevents warnings
TWI_RxHead = ( TWI_RxHead + 1 ) & TWI_RX_BUFFER_MASK;
TWI_RxBuf[TWI_RxHead] = tmpUSIDR;
USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA;
SET_USI_TO_SEND_ACK();
break;
}
}
delay.h
#ifndef _H_DELAY_
#define _H_DELAY_
#define nop() __asm__ __volatile__("nop")
void delay_ms(unsigned short ms);
void delay_us(unsigned short us);
#endif
delay.c
#include "main.h"
#include <util/delay.h>
#include "delay.h"
/****************************************************************************/
/* It is better to put a delay in the loop than provide high value to */
/* standard function, because the code will be smaller, */
/****************************************************************************/
void delay_ms(unsigned short ms) {
while ( ms ) {
ms--;
_delay_ms(1);
}
}
void delay_us(unsigned short us) {
while ( us ) {
us--;
_delay_us(1);
}
}
main.h
#ifndef _H_MAIN_H #define _H_MAIN_H // define CPU speed #define F_CPU 8000000L // some usefeuul macros #define H(a,b) a |=(1<<(b)) #define L(a,b) a &=~(1<<(b)) #define IS(a,b) bit_is_set(a,b) #define BS(a,b) (a & (1<<(b))) #endif
main.c
#include "main.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "delay.h"
#include "USI_TWI_Slave.h"
// command array size
#define COMM_COUNT 18
// init data with device code
const unsigned char init[] = { 0b11111111, 0b11111111, 0b00000000, 0b10101010, 0b00100010, 0b00100010, 0b10001000, 0b10001010, 0b10101000 };
// commands
const unsigned char on[] = { 0b10001000, 0b10001000, 0b10101010, 0b10101010, 0b10001000, 0b10001000, 0b10000000 };
const unsigned char mute[] = { 0b10101000, 0b10001000, 0b10101000, 0b10001000, 0b10101010, 0b00100010, 0b10000000 };
const unsigned char volUp[] = { 0b10100010, 0b00100010, 0b00101010, 0b10001010, 0b10101000, 0b10001000, 0b10000000 };
const unsigned char volDown[] = { 0b10001000, 0b10001000, 0b10001010, 0b10101010, 0b10101000, 0b10001000, 0b10000000 };
const unsigned char play[] = { 0b10100010, 0b10101010, 0b10100010, 0b10001000, 0b10001000, 0b10001000, 0b10000000 };
const unsigned char next[] = { 0b10001000, 0b10101010, 0b10101010, 0b10001000, 0b10001000, 0b10001000, 0b10000000 };
const unsigned char prev[] = { 0b10101000, 0b10101010, 0b10100010, 0b00101000, 0b10001000, 0b10001000, 0b10000000 };
const unsigned char stop[] = { 0b10001010, 0b10101010, 0b10101000, 0b10001000, 0b10001000, 0b10001000, 0b10000000 };
const unsigned char portable[] = { 0b10001000, 0b10001000, 0b10001010, 0b00100010, 0b10101010, 0b10001010, 0b10000000 };
const unsigned char cd[] = { 0b10100010, 0b10001010, 0b10001010, 0b00101000, 0b10100010, 0b00101000, 0b10000000 };
const unsigned char tuner[] = { 0b10001000, 0b10100010, 0b10100010, 0b10101000, 0b10100010, 0b00101000, 0b10000000 };
const unsigned char usb[] = { 0b10001010, 0b10001010, 0b00101010, 0b10001000, 0b10100010, 0b10001000, 0b10000000 };
const unsigned char pre_left[] = { 0b10101000, 0b10001000, 0b10101010, 0b00100010, 0b10101000, 0b10001000, 0b10000000 };
const unsigned char pre_right[] = { 0b10001000, 0b10100010, 0b00101010, 0b10101000, 0b10101000, 0b10001000, 0b10000000 };
const unsigned char fldr_up[] = { 0b10001000, 0b10001010, 0b10001010, 0b10101010, 0b00100010, 0b10001000, 0b10000000 };
const unsigned char fldr_down[] = { 0b10101010, 0b00101000, 0b10101000, 0b10001000, 0b10100010, 0b10001000, 0b10000000 };
const unsigned char shuffle[] = { 0b10001000, 0b10001010, 0b10101010, 0b10101000, 0b10001000, 0b10001000, 0b10000000 };
const unsigned char repeat[] = { 0b10101000, 0b10001010, 0b10101000, 0b10001010, 0b10001000, 0b10001000, 0b10000000 };
// commands array
// commands received by I2C are indexes from this table
const unsigned char *cmd_arr[COMM_COUNT] = { mute, volUp, volDown, on, play, next, prev, stop, portable, cd, usb, tuner, pre_left, pre_right, fldr_up, fldr_down, shuffle, repeat };
/****************************************************************************/
/* This function enables/disables interrupt generating ~36-38kHz square */
/* wave on pin PB1. On/Off sequence is from byte (function parameter). */
/****************************************************************************/
void sendOneByte(const unsigned char *byte) {
unsigned char e = 7;
do {
if ( (*byte & (1<<e)) == (1<<e) ) {
H(TIMSK, TOIE0);
}
else {
L(TIMSK, TOIE0);
L(PORTB, PB1);
}
// delay_us(410);
delay_us(300); // time on my attiny45 runs slower, maybe
// I have broken crystal resonator, I don't know
// normally there should be 400-410 us
} while(e--);
}
/****************************************************************************/
/* Function generate init sequence from init array. */
/****************************************************************************/
void initSequence() {
unsigned char i = 0;
for(i=0; i < 9; i++)
sendOneByte(&init[i]);
}
/****************************************************************************/
/* Function sends IR command to device. */
/****************************************************************************/
void command(const unsigned char *comm) {
unsigned char i = 0;
initSequence();
for(i=0; i < 7; i++)
sendOneByte(&comm[i]);
}
/****************************************************************************/
/* On every SIG_OVERFLOW0 there is a change on pin PB1. This generates */
/* 36-38kHz square wave. */
/****************************************************************************/
SIGNAL(SIG_OVERFLOW0) {
TCNT0 = 0xAC;
PORTB^=(1<<PB1);
return;
}
/****************************************************************************/
/* This is the main loop, it's not complicated, because we work on */
/* interrupts. */
/****************************************************************************/
int main()
{
unsigned char byte;
// set device I2C address to 0x10
USI_TWI_Slave_Initialise(0x10);
// configure out pin for driving IR diode
H(DDRB, PB1);
L(PORTB, PB1);
// configure timer
L(TCCR0A, COM0A0);
L(TCCR0A, COM0A1);
H(TCCR0A, WGM01);
H(TCCR0B, CS00);
TCNT0 = 0xAC;
// enable interrupts
sei();
while(1) {
// something was received
if( USI_TWI_Data_In_Receive_Buffer() ) {
// get command code
byte = USI_TWI_Receive_Byte();
// check range (unsigned byte always > 0)
if (byte < COMM_COUNT)
command(cmd_arr[byte]); // send IR command
}
}
}
Makefile
CPU=attiny45 GCC=avr-gcc CFLAGS= -Os -mmcu=$(CPU) -Wall -fpack-struct -fshort-enums -funsigned-bitfields -Wl,--relax -fno-move-loop-invariants -funsigned-char -fno-inline-small-functions -fdata-sections -fno-tree-loop-optimize -lprintf_min INCLUDES= LIBS= OBJCPY=avr-objcopy OBJECTS=main.o delay.o USI_TWI_Slave.o PROJECT_NAME=infrared HEX_FILE=$(PROJECT_NAME).hex HEX_FILE_DUMP=$(PROJECT_NAME)_dump.hex # this line shoud be replaced by your programmator # I use simplest ISP by parallel port and bunch of # wires and resistors. PROG=uisp PROG_FLAGS=-dprog=dapa -dpart=attiny26 all: cls $(PROJECT_NAME) obj size #upload $(PROJECT_NAME): $(OBJECTS) $(GCC) -o $(PROJECT_NAME) $(OBJECTS) $(CFLAGS) $(LIBS) $(INCLUDES) main.o: main.c main.h $(GCC) $(CFLAGS) $(INCLUDES) -c main.c delay.o: delay.c delay.h $(GCC) $(CFLAGS) $(INCLUDES) -c delay.c USI_TWI_Slave.o: USI_TWI_Slave.c USI_TWI_Slave.h $(GCC) $(CFLAGS) $(INCLUDES) -c USI_TWI_Slave.c -D__ATtiny45__ obj: $(OBJECTS) $(OBJCPY) -O ihex $(PROJECT_NAME) $(HEX_FILE) clean: rm -f $(PROJECT_NAME) $(OBJECTS) $(HEX_FILE) cls: clear size: du -b $(HEX_FILE) upload: all $(HEX_FILE) $(PROG) $(PROG_FLAGS) --erase --upload if=$(HEX_FILE) download: $(PROG) $(PROG_FLAGS) --download of=$(HEX_FILE_DUMP)
No comments:
Post a Comment