diff --git a/micro/Makefile b/micro/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c10a21b7ea0b1ee904374b83d007ed7bdc303b41 --- /dev/null +++ b/micro/Makefile @@ -0,0 +1,59 @@ +PROJECT=head_face +######################################################## +# afegir tots els fitxers que s'han de compilar aquà +######################################################## +SOURCES=src/main.c src/dyn_slave.c src/mem.c src/dyn_common.c src/leds.c + +OBJS=$(SOURCES:.c=.o) +SRC_DIR=./src/ +INCLUDE_DIR=./include/ +BUILD_DIR=./build/ +BIN_DIR=./bin/ +CC=avr-gcc +OBJCOPY=avr-objcopy +MMCU=atmega16a + +CFLAGS=-mmcu=$(MMCU) -Wall -Os $(defines) -DF_CPU=16000000UL -gdwarf-2 -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wstrict-prototypes + +LDFLAGS=-mmcu=$(MMCU) -Wl,-Map=$(PROJECT).map -DF_CPU=16000000UL +#LDFLAGS=-mmcu=$(MMCU) -Wl,-Map=$(PROJECT).map,--section-start,.eeprom=810000 -DF_CPU=16000000UL + +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature +HEX_EEPROM_FLAGS = -j .eeprom --change-section-lma .eeprom=0 + +.PHONY: all + +all: $(PROJECT).hex $(PROJECT)_eeprom.hex + +$(PROJECT).hex: $(PROJECT).elf + $(OBJCOPY) -O ihex $(HEX_FLASH_FLAGS) $< $@ +$(PROJECT)_eeprom.hex: $(PROJECT).elf + $(OBJCOPY) -O ihex $(HEX_EEPROM_FLAGS) $< $@ +$(PROJECT).elf: $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) $(LIB_DIRS) $(LIBS) -o $(PROJECT).elf +%.o:%.c + $(CC) -c $(CFLAGS) -I$(INCLUDE_DIR) -o $@ $< + +download: $(MAIN_OUT_HEX) + avrdude -c avr109 -V -P /dev/ttyUSB0 -p m16 -b 9600 -U flash:w:$(PROJECT).hex + avrdude -c avr109 -V -P /dev/ttyUSB0 -p m16 -b 9600 -U eeprom:w:$(PROJECT)_eeprom.hex + +bootloader: bootloader_hex + $(MAKE) -C remote-controlled-socket/uc/avrprog_boot_v0_85/ program + rm -rf remote-controller-socket + +bootloader_hex: + @if [ ! -d "./remote-controlled-socket" ] ; then \ + echo "AVR bootloader not found"; \ + hg clone https://bitbucket.org/befi/remote-controlled-socket; \ + patch remote-controlled-socket/uc/avrprog_boot_v0_85/main.c < patches/main.c.patch; \ + patch remote-controlled-socket/uc/avrprog_boot_v0_85/makefile < patches/makefile.patch; \ + fi + $(MAKE) -C remote-controlled-socket/uc/avrprog_boot_v0_85/ + +clean: + -rm $(PROJECT).* + -rm $(PROJECT)_eeprom.* + -rm $(OBJS) + -rm src/*.lst + -rm -rf remote-controlled-socket diff --git a/micro/avrlibdefs.h b/micro/avrlibdefs.h deleted file mode 100755 index a8dea50342b2dd159ebb5035ae658f9b79816c97..0000000000000000000000000000000000000000 --- a/micro/avrlibdefs.h +++ /dev/null @@ -1,83 +0,0 @@ -/*! \file avrlibdefs.h \brief AVRlib global defines and macros. */ -//***************************************************************************** -// -// File Name : 'avrlibdefs.h' -// Title : AVRlib global defines and macros include file -// Author : Pascal Stang -// Created : 7/12/2001 -// Revised : 9/30/2002 -// Version : 1.1 -// Target MCU : Atmel AVR series -// Editor Tabs : 4 -// -// Description : This include file is designed to contain items useful to all -// code files and projects, regardless of specific implementation. -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - - -#ifndef AVRLIBDEFS_H -#define AVRLIBDEFS_H - -// Code compatibility to new AVR-libc -// outb(), inb(), inw(), outw(), BV(), sbi(), cbi(), sei(), cli() -#ifndef outb - #define outb(addr, data) addr = (data) -#endif -#ifndef inb - #define inb(addr) (addr) -#endif -#ifndef outw - #define outw(addr, data) addr = (data) -#endif -#ifndef inw - #define inw(addr) (addr) -#endif -#ifndef BV - #define BV(bit) (1<<(bit)) -#endif -#ifndef cbi - #define cbi(reg,bit) reg &= ~(BV(bit)) -#endif -#ifndef sbi - #define sbi(reg,bit) reg |= (BV(bit)) -#endif -#ifndef cli - #define cli() __asm__ __volatile__ ("cli" ::) -#endif -#ifndef sei - #define sei() __asm__ __volatile__ ("sei" ::) -#endif - -// support for individual port pin naming in the mega128 -// see port128.h for details -#ifdef __AVR_ATmega128__ -// not currently necessary due to inclusion -// of these defines in newest AVR-GCC -// do a quick test to see if include is needed -#ifndef PD0 - #include "port128.h" -#endif -#endif - -// use this for packed structures -// (this is seldom necessary on an 8-bit architecture like AVR, -// but can assist in code portability to AVR) -#define GNUC_PACKED __attribute__((packed)) - -// port address helpers -#define DDR(x) ((x)-1) // address of data direction register of port x -#define PIN(x) ((x)-2) // address of input register of port x - -// MIN/MAX/ABS macros -#define MIN(a,b) ((a<b)?(a):(b)) -#define MAX(a,b) ((a>b)?(a):(b)) -#define ABS(x) ((x>0)?(x):(-x)) - -// constants -#define PI 3.14159265359 - -#endif diff --git a/micro/avrlibtypes.h b/micro/avrlibtypes.h deleted file mode 100755 index 4d44ac56223bd8fb421a64ef3cab79779c376b7d..0000000000000000000000000000000000000000 --- a/micro/avrlibtypes.h +++ /dev/null @@ -1,84 +0,0 @@ -/*! \file avrlibtypes.h \brief AVRlib global types and typedefines. */ -//***************************************************************************** -// -// File Name : 'avrlibtypes.h' -// Title : AVRlib global types and typedefines include file -// Author : Pascal Stang -// Created : 7/12/2001 -// Revised : 9/30/2002 -// Version : 1.0 -// Target MCU : Atmel AVR series -// Editor Tabs : 4 -// -// Description : Type-defines required and used by AVRlib. Most types are also -// generally useful. -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - - -#ifndef AVRLIBTYPES_H -#define AVRLIBTYPES_H - -#ifndef WIN32 - // true/false defines - #define FALSE 0 - #define TRUE -1 -#endif - -// datatype definitions macros -typedef unsigned char u08; -typedef signed char s08; -typedef unsigned short u16; -typedef signed short s16; -typedef unsigned long u32; -typedef signed long s32; -typedef unsigned long long u64; -typedef signed long long s64; - -/* use inttypes.h instead -// C99 standard integer type definitions -typedef unsigned char uint8_t; -typedef signed char int8_t; -typedef unsigned short uint16_t; -typedef signed short int16_t; -typedef unsigned long uint32_t; -typedef signed long int32_t; -typedef unsigned long uint64_t; -typedef signed long int64_t; -*/ -// maximum value that can be held -// by unsigned data types (8,16,32bits) -#define MAX_U08 255 -#define MAX_U16 65535 -#define MAX_U32 4294967295 - -// maximum values that can be held -// by signed data types (8,16,32bits) -#define MIN_S08 -128 -#define MAX_S08 127 -#define MIN_S16 -32768 -#define MAX_S16 32767 -#define MIN_S32 -2147483648 -#define MAX_S32 2147483647 - -#ifndef WIN32 - // more type redefinitions - typedef unsigned char BOOL; - typedef unsigned char BYTE; - typedef unsigned int WORD; - typedef unsigned long DWORD; - - typedef unsigned char UCHAR; - typedef unsigned int UINT; - typedef unsigned short USHORT; - typedef unsigned long ULONG; - - typedef char CHAR; - typedef int INT; - typedef long LONG; -#endif - -#endif diff --git a/micro/include/dyn_common.h b/micro/include/dyn_common.h new file mode 100644 index 0000000000000000000000000000000000000000..72a1d88b6af832cdedef82e3592c680ebc0288f6 --- /dev/null +++ b/micro/include/dyn_common.h @@ -0,0 +1,32 @@ +#ifndef _DYN_COMMON_H +#define _DYN_COMMON_H + +#include <avr/io.h> +#include <avr/interrupt.h> + +// Instruction identifiers +#define INST_PING 0x01 +#define INST_READ 0x02 +#define INST_WRITE 0x03 +#define INST_REG_WRITE 0x04 +#define INST_ACTION 0x05 +#define INST_RESET 0x06 +#define INST_SYNC_READ 0x82 +#define INST_SYNC_WRITE 0x83 +#define INST_BULK_READ 0x92 +#define INST_BULK_WRITE 0x93 + +// bus errors +#define INSTRUCTION_ERROR 0x40 +#define OVERLOAD_ERROR 0x20 +#define CHECKSUM_ERROR 0x10 +#define RANGE_ERROR 0x08 +#define OVERHEATING_ERROR 0x04 +#define ANGLE_LIMIT_ERROR 0x02 +#define VOLTAGE_ERROR 0x01 +#define NO_ERROR 0x00 + +uint8_t do_write(uint8_t address,uint8_t length,uint8_t *data); +uint8_t do_read(uint8_t address,uint8_t length,uint8_t **data); + +#endif diff --git a/micro/include/dyn_slave.h b/micro/include/dyn_slave.h new file mode 100644 index 0000000000000000000000000000000000000000..4f84dd4d5fdb3084405bbbf70a4faab1c554854b --- /dev/null +++ b/micro/include/dyn_slave.h @@ -0,0 +1,15 @@ +#ifndef DYN_SLAVE_H +#define DYN_SLAVE_H + +#include <avr/interrupt.h> +#include <avr/io.h> +#include "dyn_common.h" + +void dyn_slave_init(uint8_t baudrate,uint8_t id); +void dyn_slave_set_baudrate(uint8_t baudrate); +void dyn_slave_set_id(uint8_t id); +void dyn_slave_loop(void); +void dyn_slave_set_error(uint8_t error); +void dyn_slave_clear_error(void); + +#endif diff --git a/micro/include/leds.h b/micro/include/leds.h new file mode 100644 index 0000000000000000000000000000000000000000..fcfba4fa59efbc4f7caccb669a7f48387fda0f71 --- /dev/null +++ b/micro/include/leds.h @@ -0,0 +1,27 @@ +#ifndef _LEDS_H +#define _LEDS_H + +typedef struct +{ + unsigned char reg; + unsigned char *desired_port; + unsigned char bit_mask; +}TLedSegment; + +void leds_init(void); +void set_brightness(unsigned char brightness_level); +unsigned char get_brightness(void); +void turn_on_segment(unsigned char segment); +void turn_off_segment(unsigned char segment); +unsigned char is_segment_on(unsigned char segment); +void standby_conf(void); +void happiness_conf(void); +void sadness_conf(void); +void angry_conf(void); +void confused_conf(void); +void shyness_conf(void); +void ashamed_conf(void); +void speak1_conf(void); +void speak2_conf(void); + +#endif diff --git a/micro/include/mem.h b/micro/include/mem.h new file mode 100644 index 0000000000000000000000000000000000000000..54b80f57597cd23ac26771d68bf74139cbc6cfb6 --- /dev/null +++ b/micro/include/mem.h @@ -0,0 +1,13 @@ +#ifndef _MEM_H +#define _MEM_H + +#include <avr/io.h> +#include "memory_map.h" + +extern uint8_t ram_data[RAM_SIZE]; + +void ram_init(void); +uint8_t ram_read(uint8_t address, uint8_t length, uint8_t **data); +uint8_t ram_write(uint8_t address, uint8_t length, uint8_t *data); + +#endif diff --git a/micro/include/memory_map.h b/micro/include/memory_map.h new file mode 100644 index 0000000000000000000000000000000000000000..40a9325f6258801bf67a388ea4fd76e8e458aebb --- /dev/null +++ b/micro/include/memory_map.h @@ -0,0 +1,57 @@ +#ifndef _MEMORY_MAP_H +#define _MEMORY_MAP_H + +// Register Id EEPROM - declared in dynamixel +#define Model_Number_L 0X00 //0 - 0X0C R - Lowest byte of model number +#define Model_Number_H 0X01 //1 - 0X00 R - Highest byte of model number +#define Version_Firmware 0X02 //2 - 0X00 R - Information on the version of firmware +#define ID 0X03 //3 - 0X03 R/W - ID of Dynamixel +#define Baud_Rate 0X04 //4 - 0X01 R/W - Baud Rate of Dynamixel +#define Return_Delay_Time 0X05 //5 - 0XFA R/W - Return Delay Time (value*2us) currently not implemented +#define Hardware_available 0x06 //6 - 0x06 R - Peripherals available with the current configuration + // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // uart_usb uart_ttl DAC PWM +#define Status_Return_Level 0X10 //16 - 0x10 R/W - Level os reply information +// EEPROM end at 0x1F +// RAM starts at 0x20 +#define brightness 0x20 // R/W brightness value +#define left_eyebrow_left 0x21 // R/W left eyebrow left segment state +#define left_eyebrow_center 0x22 // R/W left eyebrow center segment state +#define left_eyebrow_right 0x23 // R/W left eyebrow right segment state +#define left_cheek_inner 0x24 // R/W left cheek inner segment state +#define left_cheek_outer 0x25 // R/W left check outer segment state +#define lip_upper_left 0x26 // R/W lip upper left segment state +#define lip_bottom_left 0x27 // R/W lip bottom left segment state +#define lip_upper_center 0x28 // R/W lip upper center segment state +#define lip_center 0x29 // R/W lip center segment state +#define right_eyebrow_center 0x2A // R/W right eyebrow center segment state +#define right_eyebrow_left 0x2B // R/W right eyebrow left segment state +#define right_eyebrow_right 0x2C // R/W right eyebrow right segment state +#define right_cheek_outer 0x2D // R/W right cheek outer segment state +#define right_cheek_inner 0x2E // R/W right check inner segment state +#define lip_bottom_center 0x2F // R/W lip bottom center segment state +#define lip_bottom_right 0x30 // R/W lip bottom right segment state +#define lip_upper_right 0x31 // R/W lip upper right segment state +#define extra1 0x32 // R/W additional segment state +#define extra2 0x33 // R/W additional segment state +#define extra3 0x34 // R/W additional segment state +#define extra4 0x35 // R/W additional segment state +#define extra5 0x36 // R/W additional segment state +#define extra6 0x37 // R/W additional segment state +#define extra7 0x38 // R/W additional segment state +#define extra8 0x39 // R/W additional segment state +#define all_segments 0x3a // R/W all segments state + +#define standby 0x40 // R/W standby configuration +#define hapiness 0x41 // R/W hapiness configuration +#define sadness 0x42 // R/W satness configuration +#define angry 0x43 // R/W angry configuration +#define confused 0x44 // R/W confused configuration +#define shyness 0x45 // R/W shyness configuration +#define ashamed 0x46 // R/W ashamed configuration +#define speak1 0x47 // R/W speak1 configuration +#define speak2 0x48 // R/W speak2 configuration + +#define RAM_SIZE 73 + +#endif diff --git a/micro/include/segments.h b/micro/include/segments.h new file mode 100644 index 0000000000000000000000000000000000000000..55ce5f67081926a9af9f478b2d502dc11396869f --- /dev/null +++ b/micro/include/segments.h @@ -0,0 +1,80 @@ +#ifndef _SEGMENTS_H +#define _SEGMENTS_H + +#include "memory_map.h" +#include <avr/io.h> + +#define num_segments 25 + +#define brightness_reg brightness +#define segments_offset 0x20 + +#define l_eyebrow_l_reg (left_eyebrow_left-segments_offset) +#define l_eyebrow_l_port PC2 +#define l_eyebrow_c_reg (left_eyebrow_center-segments_offset) +#define l_eyebrow_c_port PC1 +#define l_eyebrow_r_reg (left_eyebrow_right-segments_offset) +#define l_eyebrow_r_port PC0 +#define l_cheek_i_reg (left_cheek_inner-segments_offset) +#define l_cheek_i_port PC4 +#define l_cheek_o_reg (left_cheek_outer-segments_offset) +#define l_cheek_o_port PC3 + +#define r_eyebrow_l_reg (right_eyebrow_left-segments_offset) +#define r_eyebrow_l_port PA0 +#define r_eyebrow_c_reg (right_eyebrow_center-segments_offset) +#define r_eyebrow_c_port PA1 +#define r_eyebrow_r_reg (right_eyebrow_right-segments_offset) +#define r_eyebrow_r_port PA2 +#define r_cheek_i_reg (right_cheek_inner-segments_offset) +#define r_cheek_i_port PA3 +#define r_cheek_o_reg (right_cheek_outer-segments_offset) +#define r_cheek_o_port PA4 + +#define lip_ue_reg (lip_upper_left-segments_offset) +#define lip_ue_port PC5 +#define lip_uc_reg (lip_bottom_left-segments_offset) +#define lip_uc_port PC6 +#define lip_bc_reg (lip_upper_center-segments_offset) +#define lip_bc_port PC7 +#define lip_nu_reg (lip_center-segments_offset) +#define lip_nu_port PB0 +#define lip_c_reg (lip_bottom_center-segments_offset) +#define lip_c_port PA7 +#define lip_be_reg (lip_bottom_right-segments_offset) +#define lip_be_port PA5 +#define lip_ce_reg (lip_upper_right-segments_offset) +#define lip_ce_port PA6 + +#define extra_segment1_reg (extra1-segments_offset) +#define extra_segment1_port PB1 +#define extra_segment2_reg (extra2-segments_offset) +#define extra_segment2_port PB2 +#define extra_segment3_reg (extra3-segments_offset) +#define extra_segment3_port PB3 +#define extra_segment4_reg (extra4-segments_offset) +#define extra_segment4_port PB4 +#define extra_segment5_reg (extra5-segments_offset) +#define extra_segment5_port PD2 +#define extra_segment6_reg (extra6-segments_offset) +#define extra_segment6_port PD3 +#define extra_segment7_reg (extra7-segments_offset) +#define extra_segment7_port PD4 +#define extra_segment8_reg (extra8-segments_offset) +#define extra_segment8_port PD5 + +#define all_segment_reg (all_segments-segments_offset) + +#define expression_offset 0x40 + +#define standby_reg standby +#define happiness_reg hapiness +#define sadness_reg satnes +#define angry_reg angry +#define confused_reg confused +#define shyness_reg shyness +#define ashamed_reg ashamed +#define speak1_reg speak1 +#define speak2_reg speak2 + +#endif diff --git a/micro/led_segments.h b/micro/led_segments.h deleted file mode 100755 index 4742d1d32c0ea450c7cc8da9703029c369807229..0000000000000000000000000000000000000000 --- a/micro/led_segments.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef _LED_SEGMENTS_H -#define _LED_SEGMENTS_H - -#include <avr/io.h> - -/* - -Memory map table - -Address access function - -0x00 R/W brightness value -0x01 R/W left eyebrow left segment state -0x02 R/W left eyebrow center segment state -0x03 R/W left eyebrow right segment state -0x04 R/W left cheek inner segment state -0x05 R/W left check outer segment state -0x06 R/W lip upper left segment state -0x07 R/W lip bottom left segment state -0x08 R/W lip upper center segment state -0x09 R/W lip center segment state -0x0A R/W right eyebrow center segment state -0x0B R/W right eyebrow left segment state -0x0C R/W right eyebrow right segment state -0x0D R/W right cheek outer segment state -0x0E R/W right check inner segment state -0x0F R/W lip bottom center segment state -0x10 R/W lip bottom right segment state -0x11 R/W lip upper right segment state -0x12 R/W additional segment state -0x13 R/W additional segment state -0x14 R/W additional segment state -0x15 R/W additional segment state -0x16 R/W additional segment state -0x17 R/W additional segment state -0x18 R/W additional segment state -0x19 R/W additional segment state -0x1a R/W all segments state - -0x20 R/W standby configuration -0x21 R/W hapiness configuration -0x22 R/W satness configuration -0x23 R/W angry configuration -0x24 R/W confused configuration -0x25 R/W shyness configuration - -*/ - -// number of LED segments -#define num_segments 25 - -#define brightness_reg 0x00 - -#define l_eyebrow_l_reg 0x01 -#define l_eyebrow_l_port PC2 -#define l_eyebrow_c_reg 0x02 -#define l_eyebrow_c_port PC1 -#define l_eyebrow_r_reg 0x03 -#define l_eyebrow_r_port PC0 -#define l_cheek_i_reg 0x04 -#define l_cheek_i_port PC4 -#define l_cheek_o_reg 0x05 -#define l_cheek_o_port PC3 - -#define r_eyebrow_l_reg 0x0B -#define r_eyebrow_l_port PA0 -#define r_eyebrow_c_reg 0x0A -#define r_eyebrow_c_port PA1 -#define r_eyebrow_r_reg 0x0C -#define r_eyebrow_r_port PA2 -#define r_cheek_i_reg 0x0E -#define r_cheek_i_port PA3 -#define r_cheek_o_reg 0x0D -#define r_cheek_o_port PA4 - -#define lip_ue_reg 0x06 -#define lip_ue_port PC5 -#define lip_uc_reg 0x07 -#define lip_uc_port PC6 -#define lip_bc_reg 0x08 -#define lip_bc_port PC7 -#define lip_nu_reg 0x09 -#define lip_nu_port PB0 -#define lip_c_reg 0x0F -#define lip_c_port PA7 -#define lip_be_reg 0x10 -#define lip_be_port PA5 -#define lip_ce_reg 0x11 -#define lip_ce_port PA6 - -#define extra_segment1_reg 0x12 -#define extra_segment1_port PB1 -#define extra_segment2_reg 0x13 -#define extra_segment2_port PB2 -#define extra_segment3_reg 0x14 -#define extra_segment3_port PB3 -#define extra_segment4_reg 0x15 -#define extra_segment4_port PB4 -#define extra_segment5_reg 0x16 -#define extra_segment5_port PD2 -#define extra_segment6_reg 0x17 -#define extra_segment6_port PD3 -#define extra_segment7_reg 0x18 -#define extra_segment7_port PD4 -#define extra_segment8_reg 0x19 -#define extra_segment8_port PD5 - -#define all_segment_reg 0x1a - -#define standby_reg 0x20 -#define happiness_reg 0x21 -#define sadness_reg 0x22 -#define angry_reg 0x23 -#define confused_reg 0x24 -#define shyness_reg 0x25 -#define ashamed_reg 0x26 -#define speak1_reg 0x27 -#define speak2_reg 0x28 - -typedef struct -{ - unsigned char reg; - unsigned char *desired_port; - unsigned char bit_mask; -}TLedSegment; - -extern volatile unsigned char desired_PORTA_value; -extern volatile unsigned char desired_PORTB_value; -extern volatile unsigned char desired_PORTC_value; -extern volatile unsigned char desired_PORTD_value; - -void turn_on_segment(unsigned char segment); -void turn_off_segment(unsigned char segment); -unsigned char is_segment_on(unsigned char segment); -void standby_conf(void); -void happiness_conf(void); -void sadness_conf(void); -void angry_conf(void); -void confused_conf(void); -void shyness_conf(void); -void ashamed_conf(void); -void speak1_conf(void); -void speak2_conf(void); - -#endif diff --git a/micro/leds_tibi.aps b/micro/leds_tibi.aps deleted file mode 100755 index 2189e86e8f6f00c594b9f71c2b27c911d414835d..0000000000000000000000000000000000000000 --- a/micro/leds_tibi.aps +++ /dev/null @@ -1 +0,0 @@ -<AVRStudio><MANAGEMENT><ProjectName>leds_tibi</ProjectName><Created>28-Dec-2010 12:17:14</Created><LastEdit>20-Jun-2011 10:00:32</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>28-Dec-2010 12:17:14</Created><Version>4</Version><Build>4, 18, 0, 685</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\leds_tibi.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART></CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>leds_tibi.c</SOURCEFILE><SOURCEFILE>robotis_protocol.c</SOURCEFILE><SOURCEFILE>timer.c</SOURCEFILE><SOURCEFILE>led_segments.c</SOURCEFILE><HEADERFILE>robotis.h</HEADERFILE><HEADERFILE>timer.h</HEADERFILE><HEADERFILE>led_segments.h</HEADERFILE><HEADERFILE>avrlibdefs.h</HEADERFILE><HEADERFILE>avrlibtypes.h</HEADERFILE><OTHERFILE>default\leds_tibi.lss</OTHERFILE><OTHERFILE>default\leds_tibi.map</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega16</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>leds_tibi.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>0</ISDIRTY><OPTIONS><OPTION><FILE>led_segments.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>leds_tibi.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>robotis_protocol.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>timer.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\WinAVR-20100110\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\WinAVR-20100110\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><ProjectFiles><Files><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\robotis.h</Name><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\timer.h</Name><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\led_segments.h</Name><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\avrlibdefs.h</Name><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\avrlibtypes.h</Name><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\leds_tibi.c</Name><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\robotis_protocol.c</Name><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\timer.c</Name><Name>F:\Work\iri\pas\Robots\tibi_dabo\leds\leds_tibi\led_segments.c</Name></Files></ProjectFiles><IOView><usergroups/><sort sorted="0" column="0" ordername="0" orderaddress="0" ordergroup="0"/></IOView><Files><File00000><FileId>00000</FileId><FileName>led_segments.c</FileName><Status>1</Status></File00000><File00001><FileId>00001</FileId><FileName>led_segments.h</FileName><Status>1</Status></File00001><File00002><FileId>00002</FileId><FileName>leds_tibi.c</FileName><Status>1</Status></File00002><File00003><FileId>00003</FileId><FileName>timer.h</FileName><Status>1</Status></File00003><File00004><FileId>00004</FileId><FileName>timer.c</FileName><Status>1</Status></File00004><File00005><FileId>00005</FileId><FileName>robotis_protocol.c</FileName><Status>1</Status></File00005><File00006><FileId>00006</FileId><FileName>robotis.h</FileName><Status>1</Status></File00006><File00007><FileId>00007</FileId><FileName>avrlibdefs.h</FileName><Status>1</Status></File00007></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio> diff --git a/micro/leds_tibi.c b/micro/leds_tibi.c deleted file mode 100755 index 23c923fc2e12f9ebabac601e4dbf7c623ef9f103..0000000000000000000000000000000000000000 --- a/micro/leds_tibi.c +++ /dev/null @@ -1,213 +0,0 @@ -#include <inttypes.h> -#include <avr/io.h> -#include <avr/interrupt.h> -#include <avr/sleep.h> - -#include "robotis.h" - -#include "timer.h" - -#include "led_segments.h" - -// board identifier on the bus -#define IO_BOARD_ID 5 - -// desired output port values -volatile unsigned char desired_PORTA_value=0x00; -volatile unsigned char desired_PORTB_value=0x00; -volatile unsigned char desired_PORTC_value=0x00; -volatile unsigned char desired_PORTD_value=0x00; - -volatile unsigned char brightness=10; - -void timer_0_int(void) -{ - static char counts=0; - - counts++; - if(counts<brightness) - { - PORTA=desired_PORTA_value; - PORTB=desired_PORTB_value; - PORTC=desired_PORTC_value; - PORTD=PIND|(desired_PORTD_value&0x3C); - } - else - { - PORTA=0x00; - PORTB=0x00; - PORTC=0x00; - PORTD=PIND&0xC3; - } -} - -void init_head(void) -{ - // configure default ouptut value - PORTA = 0x00; - PORTB = 0x00; - PORTC = 0x00; - PORTD = 0x00; - - // configure GPIO direction - DDRA = 0xFF; - DDRB = 0x1F;// the most significant bits are used by the programmer - DDRC = 0xFF; - DDRD = 0B11111110; // 6 (Rx gate),7 (Tx Gate), 1 (Rx) - - //set timer 0 to interrupt every 3.9us - //256 different duty cycles at 1kHz - timer0Init();// initialize timer 0 - timerAttach(TIMER0OVERFLOW_INT,timer_0_int);// attach the duty cycle generation function - timer0SetPrescaler(TIMER_CLK_DIV1);// set the prescaler to 1 - outb(TCNT0,193);// set the start count value - - // prepare to receive commands from master - SET_RS485_RXD; -} - -void init_rs485(byte Interrupt) -{ - - UCSRA = 0;// Single (not double) the USART transmission speed - UBRRH = 0; - - UBRRL = 0;// BAUD = 1000000bps at U2X=0, Fosc=16MHz => UBRR=0 - UCSRB = 0x18; // Receiver and Transmitter enable - UCSRC = 0x86; // 8 bit data, no parity (and URSEL must be 1) - // The UBRRH Register shares the same I/O location as the UCSRC Register. - // When doing a write access of this I/O location, the high bit of the - // value written, the USART Register Select (URSEL) bit, controls - // which one of the two registers that will be written. If URSEL is - // zero during a write operation, the UBRRH value will be updated. - // If URSEL is one, the UCSRC setting will be updated. - - if(Interrupt) sbi(UCSRB,7); // RxD interrupt enable - //UDR = 0xFF; // puts a value in the buffer (dont know why?) - //SET_TXRS485_FINISH; // Note. set 1, then 0 is read - if(Interrupt) - sei(); -} - -int main (void) -{ - byte *p; - byte data,i; - - init_head();// configure the peripherals - init_rs485(0);// initialize the RS485 serial communication - sei(); - - while (1) - { - if(CHECK_RXRS485_READY) - { - if ((p = RxRS485Packet(IO_BOARD_ID))) - { - /* The 'Packet' is for us, analyse it. */ - switch (p[4]) - { - case INST_PING: TxRS485Packet(IO_BOARD_ID, 0, 0, 0) ; - break; - case INST_READ: if(p[6]!=1) - { - TxRS485Packet(IO_BOARD_ID,0x40,0,0); - } - else - { - if(p[5]==brightness_reg) - { - data=brightness; - TxRS485Packet(IO_BOARD_ID,0x00,1,&data); - } - else if(p[5]>=l_eyebrow_l_reg && p[5]<=extra_segment8_reg) - { - data=is_segment_on(p[5]); - TxRS485Packet(IO_BOARD_ID,0x00,1,&data); - } - else if(p[5]==all_segment_reg) - { - for(i=l_eyebrow_l_reg;i<extra_segment8_reg;i++) - { - if(!is_segment_on(i)) - { - data=0x00; - TxRS485Packet(IO_BOARD_ID,0x00,1,&data); - } - } - data=0x01; - TxRS485Packet(IO_BOARD_ID,0x00,1,&data); - } - else - { - TxRS485Packet(IO_BOARD_ID,0x40,0,0); - } - } - break; - case INST_WRITE: if(p[3]!=4) - TxRS485Packet(IO_BOARD_ID,0x40,0,0); - else - { - if(p[5]==brightness_reg) - { - brightness=p[6]; - TxRS485Packet(IO_BOARD_ID,0,0,0); - } - else if(p[5]>=l_eyebrow_l_reg && p[5]<=extra_segment8_reg) - { - if(p[6]==0x00) - { - turn_off_segment(p[5]); - TxRS485Packet(IO_BOARD_ID,0,0,0); - } - else - { - turn_on_segment(p[5]); - TxRS485Packet(IO_BOARD_ID,0,0,0); - } - } - else if(p[5]==all_segment_reg) - { - for(i=l_eyebrow_l_reg;i<extra_segment8_reg;i++) - { - if(p[6]==0x00) - turn_off_segment(i); - else - turn_on_segment(i); - } - TxRS485Packet(IO_BOARD_ID,0,0,0); - } - else - { - switch(p[5]) - { - case standby_reg: standby_conf(); - break; - case happiness_reg: happiness_conf(); - break; - case sadness_reg: sadness_conf(); - break; - case angry_reg: angry_conf(); - break; - case confused_reg: confused_conf(); - break; - case shyness_reg: shyness_conf(); - break; - case ashamed_reg: ashamed_conf(); - break; - case speak1_reg: speak1_conf(); - break; - case speak2_reg: speak2_conf(); - break; - } - TxRS485Packet(IO_BOARD_ID,0,0,0); - } - } - break; - default: TxRS485Packet(IO_BOARD_ID,0,0,0); - break; - } - } - } - } -} diff --git a/micro/patches/main.c.patch b/micro/patches/main.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..8b186c0e98520a448e77640ffe6cad3f0716053d --- /dev/null +++ b/micro/patches/main.c.patch @@ -0,0 +1,274 @@ +diff -r 407d6aac41dc uc/avrprog_boot_v0_85/main.c +--- a/uc/avrprog_boot_v0_85/main.c Sun Apr 01 13:47:42 2012 +0200 ++++ b/uc/avrprog_boot_v0_85/main.c Wed Oct 21 08:31:52 2015 +0200 +@@ -51,7 +51,8 @@ + #endif + + /* UART Baudrate */ +- #define BAUDRATE 19200 ++#define BAUDRATE 9600 ++// #define BAUDRATE 19200 + // #define BAUDRATE 19200 + //#define BAUDRATE 115200 + +@@ -178,6 +179,12 @@ + void __vector_default(void) { ; } + #endif + ++static void waitTXDone(void) ++{ ++ UART_STATUS|=(1<<TXC); ++ while (!(UART_STATUS & (1<<TXC))); ++} ++ + static void sendchar(uint8_t data) + { + while (!(UART_STATUS & (1<<UART_TXREADY))); +@@ -255,6 +262,7 @@ + uint32_t baddr = (uint32_t)waddr<<1; + uint16_t data; + ++ PORTD |= 0xC0; + do { + #ifndef READ_PROTECT_BOOTLOADER + #warning "Bootloader not read-protected" +@@ -281,17 +289,22 @@ + baddr += 2; // Select next word in memory + size -= 2; // Subtract two bytes from number of bytes to read + } while (size); // Repeat until block has been read ++ waitTXDone(); ++ PORTD &= 0x3F; + + return baddr>>1; + } + + static inline uint16_t readEEpromPage(uint16_t address, pagebuf_t size) + { ++ PORTD |= 0xC0; + do { + sendchar( eeprom_read_byte( (uint8_t*)address ) ); + address++; + size--; // Decrease number of bytes to read + } while (size); // Repeat until block has been read ++ waitTXDone(); ++ PORTD &= 0x3F; + + return address; + } +@@ -320,6 +333,7 @@ + + static void send_boot(void) + { ++ PORTD |= 0xC0; + sendchar('A'); + sendchar('V'); + sendchar('R'); +@@ -327,6 +341,8 @@ + sendchar('O'); + sendchar('O'); + sendchar('T'); ++ waitTXDone(); ++ PORTD &= 0x3F; + } + + static void (*jump_to_app)(void) = 0x0000; +@@ -353,6 +369,8 @@ + + BLDDR &= ~(1<<BLPNUM); // set as Input + BLPORT |= (1<<BLPNUM); // Enable pullup ++ DDRD |= 0xC0; ++ PORTD &= 0x3F; + + // Set baud rate + UART_BAUD_HIGH = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF; +@@ -427,7 +445,7 @@ + + _delay_ms(10); + } +- send_boot(); ++ send_boot(); + + #elif defined(START_BOOTICE) + #warning "BOOTICE mode - no startup-condition" +@@ -440,19 +458,27 @@ + val = recvchar(); + // Autoincrement? + if (val == 'a') { ++ PORTD |= 0xC0; + sendchar('Y'); // Autoincrement is quicker +- ++ waitTXDone(); ++ PORTD &= 0x3F; + //write address + } else if (val == 'A') { + address = recvchar(); //read address 8 MSB + address = (address<<8) | recvchar(); ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // Buffer load support + } else if (val == 'b') { ++ PORTD |= 0xC0; + sendchar('Y'); // Report buffer load supported + sendchar((sizeof(gBuffer) >> 8) & 0xFF); // Report buffer size in bytes + sendchar(sizeof(gBuffer) & 0xFF); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // Start buffer load + } else if (val == 'B') { +@@ -468,9 +494,15 @@ + } else if (val == 'E') { + address = writeEEpromPage(address, size); + } ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + } else { +- sendchar(0); ++ PORTD |= 0xC0; ++ sendchar(0); ++ waitTXDone(); ++ PORTD &= 0x3F; + } + + // Block read +@@ -491,12 +523,18 @@ + if (device == DEVTYPE) { + eraseFlash(); + } ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // Exit upgrade + } else if (val == 'E') { + wdt_enable(EXIT_WDT_TIME); // Enable Watchdog Timer to give reset ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + + #ifdef WRITELOCKBITS + #warning "Extension 'WriteLockBits' enabled" +@@ -508,53 +546,86 @@ + boot_lock_bits_set(recvchar()); // boot.h takes care of mask + boot_spm_busy_wait(); + } ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + #endif + // Enter programming mode + } else if (val == 'P') { ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // Leave programming mode + } else if (val == 'L') { ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // return programmer type + } else if (val == 'p') { ++ PORTD |= 0xC0; + sendchar('S'); // always serial programmer ++ waitTXDone(); ++ PORTD &= 0x3F; + + #ifdef ENABLEREADFUSELOCK + #warning "Extension 'ReadFuseLock' enabled" + // read "low" fuse bits + } else if (val == 'F') { ++ PORTD |= 0xC0; + sendchar(read_fuse_lock(GET_LOW_FUSE_BITS)); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // read lock bits + } else if (val == 'r') { ++ PORTD |= 0xC0; + sendchar(read_fuse_lock(GET_LOCK_BITS)); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // read high fuse bits + } else if (val == 'N') { ++ PORTD |= 0xC0; + sendchar(read_fuse_lock(GET_HIGH_FUSE_BITS)); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // read extended fuse bits + } else if (val == 'Q') { ++ PORTD |= 0xC0; + sendchar(read_fuse_lock(GET_EXTENDED_FUSE_BITS)); ++ waitTXDone(); ++ PORTD &= 0x3F; + #endif + + // Return device type + } else if (val == 't') { ++ PORTD |= 0xC0; + sendchar(DEVTYPE); + sendchar(0); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // clear and set LED ignored + } else if ((val == 'x') || (val == 'y')) { + recvchar(); ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // set device + } else if (val == 'T') { + device = recvchar(); ++ PORTD |= 0xC0; + sendchar('\r'); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // Return software identifier + } else if (val == 'S') { +@@ -562,20 +633,28 @@ + + // Return Software Version + } else if (val == 'V') { ++ PORTD |= 0xC0; + sendchar(VERSION_HIGH); + sendchar(VERSION_LOW); ++ waitTXDone(); ++ PORTD &= 0x3F; + + // Return Signature Bytes (it seems that + // AVRProg expects the "Atmel-byte" 0x1E last + // but shows it first in the dialog-window) + } else if (val == 's') { ++ PORTD |= 0xC0; + sendchar(SIG_BYTE3); + sendchar(SIG_BYTE2); + sendchar(SIG_BYTE1); +- ++ waitTXDone(); ++ PORTD &= 0x3F; + /* ESC */ + } else if(val != 0x1b) { ++ PORTD |= 0xC0; + sendchar('?'); ++ waitTXDone(); ++ PORTD &= 0x3F; + } + } + return 0; diff --git a/micro/patches/makefile.patch b/micro/patches/makefile.patch new file mode 100644 index 0000000000000000000000000000000000000000..f8722c600528412cdf39231f21e00a876ed491c0 --- /dev/null +++ b/micro/patches/makefile.patch @@ -0,0 +1,32 @@ +diff -r 407d6aac41dc uc/avrprog_boot_v0_85/makefile +--- a/uc/avrprog_boot_v0_85/makefile Sun Apr 01 13:47:42 2012 +0200 ++++ b/uc/avrprog_boot_v0_85/makefile Wed Oct 21 08:32:01 2015 +0200 +@@ -37,8 +37,8 @@ + # user defined values + + # MCU name +-MCU = atmega8 +-## MCU = atmega16 ++## MCU = atmega8 ++MCU = atmega16 + ## MCU = atmega162 + ## MCU = atmega169 + ## MCU = atmega32 +@@ -59,8 +59,8 @@ + #/* Select Boot Size in Words (select one, comment out the others) */ + ## NO! BOOTSIZE=128 + ## NO! BOOTSIZE=256 +-BOOTSIZE=512 +-##BOOTSIZE=1024 ++## BOOTSIZE=512 ++BOOTSIZE=1024 + ## BOOTSIZE=2048 + + # /* Select if bootloader should include the inverrupt-vectors +@@ -405,7 +405,7 @@ + AVRDUDE_PORT = usb # programmer connected to serial device + #AVRDUDE_PORT = /dev/ttyS0 # programmer connected to serial device + +-AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -U lfuse:w:0xe4:m -U hfuse:w:0xda:m ++AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -U lfuse:w:0xef:m -U hfuse:w:0xd8:m + #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep diff --git a/micro/robotis.h b/micro/robotis.h deleted file mode 100755 index db22c40bf2c9fae863d3d3972418a24d5f81a0fd..0000000000000000000000000000000000000000 --- a/micro/robotis.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _ROBOTIS_H -#define _ROBOTIS_H - -#define cbi(REG8,BITNUM) REG8 &= ~(_BV(BITNUM)) -#define sbi(REG8,BITNUM) REG8 |= _BV(BITNUM) - -typedef unsigned char byte; -typedef unsigned int word; - -void TxRS485Packet(byte ID, byte Instruction, byte ParameterLength, byte *Parameter) ; -byte *RxRS485Packet(byte ID) ; -byte *RxRS485PacketIntr(byte ID); - -//--- Instruction --- -#define INST_PING 0x01 -#define INST_READ 0x02 -#define INST_WRITE 0x03 -#define INST_REG_WRITE 0x04 -#define INST_ACTION 0x05 -#define INST_RESET 0x06 -#define INST_DIGITAL_RESET 0x07 -#define INST_SYSTEM_READ 0x0C -#define INST_SYSTEM_WRITE 0x0D -#define INST_SYNC_WRITE 0x83 -#define INST_SYNC_REG_WRITE 0x84 - -#define DEFAULT_RETURN_PACKET_SIZE 6 -#define BROADCASTING_ID 0xfe // used in conjuction with PING and SYNC_WRITE - -#define SET_RS485_TXD PORTD |= _BV(PD6),PORTD |= _BV(PD7) // 485 transmit mode -#define SET_RS485_RXD PORTD &= ~_BV(PD7),PORTD &= ~_BV(PD6) // 485 receive mode - -#define CHECK_TXRS485_READY bit_is_set(UCSRA,5) -#define CHECK_RXRS485_READY bit_is_set(UCSRA,7) -#define CHECK_TXRS485_FINISH bit_is_set(UCSRA,6) -#define TXRS485_DATA (UDR) -#define RXRS485_DATA (UDR) -#define SET_TXRS485_FINISH sbi(UCSRA,6) // reads 0 after this operation, may create interrupt -#define RESET_TXRS485_FINISH cbi(UCSRA,6) - - - -#endif diff --git a/micro/robotis_protocol.c b/micro/robotis_protocol.c deleted file mode 100755 index 1f3c403ec3a1755f0b11006f2109745f7932abed..0000000000000000000000000000000000000000 --- a/micro/robotis_protocol.c +++ /dev/null @@ -1,171 +0,0 @@ -#include <inttypes.h> -#include <avr/io.h> -#include <avr/interrupt.h> -#include <avr/sleep.h> - -#include "robotis.h" - -volatile byte iBuffer[256]; // in interrupt UART read mode, giBuffer[giBufferPointer++] will continously take new read values -volatile byte oBuffer[32]; -volatile byte iBufferPointer=0; - -/* - * SIGNAL() Rx Interrupt - write data to buffer (used with CM5's RS485) - * When a byte (8bit + parity + stop) has been read by the Atmega, it issues an interrupt - * RxiBufferPointer goes back to 0 after 255, RxPacket doesn't need it to reset it to 0 - * - * The reason for using an interrupt driven Rx is because the CM5 has 2 serials. - * you can't poll two Rx because the other one may need attention during poll. - */ -SIGNAL (SIG_UART0_RECV) -{ - iBuffer[iBufferPointer++] = RXRS485_DATA; -} - -/* - * TxRS485() write byte to Robotis bus - */ -static void TxRS485(byte Data) -{ - while(!CHECK_TXRS485_READY); - TXRS485_DATA = Data; -} - -/* - * RxRS485() read byte from Robotis bus (CM5 is normally interrupt Rx so doesnt use this routine) - */ -static byte RxRS485(void) -{ - - while(!CHECK_RXRS485_READY); - return(RXRS485_DATA); -} - -unsigned long Timer(byte mode) -{ - static unsigned long prescaler=0; - byte h, l; - - if (mode) { - TCCR1B |= mode; - TCNT1H = 0; // 0 is put in temporary storage - TCNT1L = 0; // and now both H and L are actually put into TCNT1 - // It took 2 weeks to discover why all kinds of cosmic unexplainables occured - TCCR1A = 0; - prescaler = 1<<(3*(mode-1)); - //return (prescaler*((((unsigned long)TCNT1H)<<8) | TCNT1L))>>4; - return ((((unsigned long)TCNT1H)<<8) | TCNT1L); - } - else{ - l= TCNT1L; - h= TCNT1H; - - //return (prescaler*((((unsigned long)h)<<8) | l))>>4; - return ((((unsigned long)h)<<8) | l); - } - // always returns same units of 1/1,000,000th of a second - // regardless of prescaler - //return (prescaler*((((unsigned long)TCNT1H)<<8) | TCNT1L))>>4; - //return ((((unsigned long)TCNT1H)<<8) | TCNT1L); -} - -/* -TxRS485Packet() send Robotis package to RS485. -Similar format packet is sent by master and by slave (5th byte differs) -ID - My ID -Instruction - Master: PING, READ etc. Slave: Error bitmask -ParameterLength - number of parameters sent in iBuffer -Parameter - will be coppied to iBuffer[5]..iBuffer[5+ParameterLength-1] -*/ -void TxRS485Packet(byte ID, byte Instruction, byte ParameterLength, byte *Parameter) -{ - byte i, CheckSum, PacketLength; - - iBuffer[0] = 0xff; - iBuffer[1] = 0xff; - iBuffer[2] = ID; - iBuffer[3] = ParameterLength+2; //Length(Paramter,Instruction,Checksum) - iBuffer[4] = Instruction; - for (i=0; i< ParameterLength;i++) - iBuffer[5+i] = Parameter[i]; - - CheckSum = 0; - PacketLength = ParameterLength+4+2; - for(i = 2; i < PacketLength-1; i++) //except 0xff,checksum - { - CheckSum += iBuffer[i]; - } - iBuffer[i] = ~CheckSum; //Writing Checksum with Bit Inversion - - SET_RS485_TXD; - for(i = 0; i < PacketLength; i++) - { - SET_TXRS485_FINISH; // ? this only clears bit6. triggers interrupt if interrupt flag is set - TxRS485(iBuffer[i]); - } - while(!CHECK_TXRS485_FINISH); // Wait until (bit6) TXD Shift register empty - SET_RS485_RXD; - - iBufferPointer=0; // Response packet instantanous. Interrupt Rx relies on buffer being filled from 0 -} - -/* - * RxRS485Packet() receive Robotis instruction packet through RS485. - * This is is the non-interrupt version of the read-packet designed for a sensor board. - * The full protocol implementation of the protocol is needed only by Robotis servos - * returns the packet pointer if the packet is intended for me otherwise null -*/ -byte *RxRS485Packet(byte ID) -{ - byte i; - - PORTD ^= 1<<2; //debug - - iBuffer[0] = RxRS485(); // 0xff; - iBuffer[1] = RxRS485(); // 0xff; - iBuffer[2] = RxRS485(); // ID; - iBuffer[3] = RxRS485(); // ParameterLength+2; // Length(Paramter,Instruction,Checksum) - iBuffer[4] = RxRS485(); // Instruction; - for (i=0; i<iBuffer[3]-2; i++) - iBuffer[5+i] = RxRS485(); // Parameters.. - iBuffer[5+i] = RxRS485(); // Checksum; - - // not performing any error checking. assumning that robotis cables are ok. - - return (iBuffer[2] == ID)? iBuffer: (byte *)0; - -} - -/* - * RxRS485PacketIntr() receive Robotis (response) packet through RS485. - * This is is the interrupt-driven version of the read-packet designed for CM5 - * Just waits for the buffer to fill up by the interrupt routine - * - * The reason for using an interrupt driven Rx is because the CM5 has 2 serials. - * you can't poll two Rx because the other one may need attention during poll. -*/ - -byte *RxRS485PacketIntr(byte ID) -{ - Timer(5); - - while (iBufferPointer < 4) - if (Timer(0)>20) { - iBufferPointer=0; - return (byte *)0; - } - - Timer(5); - - while (iBufferPointer < 4+iBuffer[3]) - if (Timer(0)>20) { - iBufferPointer=0; - return (byte *)0; - } - - iBufferPointer=0; - return (iBuffer[2] == ID)? iBuffer: (byte *)0; - -} - - diff --git a/micro/src/dyn_common.c b/micro/src/dyn_common.c new file mode 100644 index 0000000000000000000000000000000000000000..7710bbe845f44d7557415daea03a1d43bac6d065 --- /dev/null +++ b/micro/src/dyn_common.c @@ -0,0 +1,64 @@ +#include "dyn_common.h" +#include "dyn_slave.h" +#include "mem.h" +#include "leds.h" +#include "segments.h" + +uint8_t do_write(uint8_t address,uint8_t length,uint8_t *data) +{ + uint8_t i,j,num=0; + + for(i=address;i<address+length;i++) + { + /* dynamixel interface */ + if(i==ID) + dyn_slave_set_id(data[num]); + else if(i==Baud_Rate) + dyn_slave_set_baudrate(data[num]); + else if(i==brightness) + set_brightness(data[num]); + else if(i>=left_eyebrow_left && i<=extra8) + { + if(data[num]==0x00) + turn_off_segment(i-segments_offset); + else + turn_on_segment(i-segments_offset); + } + else if(i==all_segments) + { + for(j=0;j<num_segments;j++) + { + if(data[num]==0x00) + turn_off_segment(j); + else + turn_on_segment(j); + } + } + else if(i==standby) + standby_conf(); + else if(i==hapiness) + happiness_conf(); + else if(i==sadness) + sadness_conf(); + else if(i==angry) + angry_conf(); + else if(i==confused) + confused_conf(); + else if(i==shyness) + shyness_conf(); + else if(i==ashamed) + ashamed_conf(); + else if(i==speak1) + speak1_conf(); + else if(i==speak2) + speak2_conf(); + num++; + } + + return 0x01; +} + +uint8_t do_read(uint8_t address,uint8_t length,uint8_t **data) +{ + return ram_read(address,length,data); +} diff --git a/micro/src/dyn_slave.c b/micro/src/dyn_slave.c new file mode 100644 index 0000000000000000000000000000000000000000..18cc97bff54d9e210ac647695627b4547987c8c3 --- /dev/null +++ b/micro/src/dyn_slave.c @@ -0,0 +1,433 @@ +#include <avr/interrupt.h> +#include <avr/io.h> +#include "dyn_slave.h" +#include "mem.h" + +#ifndef DYN_SLAVE_SE_BUFFER_LEN + #define DYN_SLAVE_SE_BUFFER_LEN 128 +#endif + +/* private variables */ +uint8_t dyn_slave_id; +uint8_t dyn_slave_data[DYN_SLAVE_SE_BUFFER_LEN]; +uint8_t dyn_slave_num_rx_bytes; +uint8_t dyn_slave_num_tx_bytes; +uint8_t dyn_slave_packet_ready; +uint8_t dyn_slave_send_done; +uint8_t dyn_slave_error; +uint8_t dyn_slave_tmp_data[RAM_SIZE]; +uint8_t dyn_slave_tmp_address; +uint8_t dyn_slave_tmp_length; +uint8_t dyn_slave_reg_pending; +uint8_t dyn_slave_sync_read_pending; +uint8_t dyn_slave_sync_read_previous; +uint8_t dyn_slave_bulk_read_pending; +uint8_t dyn_slave_bulk_read_previous; + +inline void dyn_slave_set_rx(void) +{ + PORTD &= 0x3F; +} + +inline void dyn_slave_set_tx(void) +{ + PORTD |= 0xC0; +} + +/* interrupt handlers */ +ISR(USART_TXC_vect) +{ + if(dyn_slave_num_tx_bytes==dyn_slave_data[3]+4) + { + dyn_slave_set_rx(); + dyn_slave_send_done=1; + } + else + { + UDR=dyn_slave_data[dyn_slave_num_tx_bytes]; + dyn_slave_num_tx_bytes++; + } +} + +ISR(USART_RXC_vect) +{ + static uint8_t length; + + cli();// disable any other interrupt + dyn_slave_data[dyn_slave_num_rx_bytes]=UDR; + switch(dyn_slave_num_rx_bytes) + { + case 0: if(dyn_slave_data[dyn_slave_num_rx_bytes]==0xFF) + dyn_slave_num_rx_bytes++; + break; + case 1: if(dyn_slave_data[dyn_slave_num_rx_bytes]==0xFF) + dyn_slave_num_rx_bytes++; + else + dyn_slave_num_rx_bytes--; + break; + case 2: dyn_slave_num_rx_bytes++; + break; + case 3: length=dyn_slave_data[dyn_slave_num_rx_bytes]+3; + dyn_slave_num_rx_bytes++; + break; + default: if(dyn_slave_num_rx_bytes==length) + { + dyn_slave_num_rx_bytes=0; + dyn_slave_packet_ready=1; + } + else + dyn_slave_num_rx_bytes++; + break; + } + sei();// enable all interrutps +} + +/* private functions */ +uint8_t dyn_slave_is_packet_ready(void) +{ + if(dyn_slave_packet_ready==0x01) + { + dyn_slave_packet_ready=0x00; + return 0x01; + } + else + return 0x00; +} + +uint8_t dyn_slave_check_id(void) +{ + if(dyn_slave_id==dyn_slave_data[2] || dyn_slave_data[2]==0xFE) + return 0x01; + else + { + dyn_slave_num_rx_bytes=0; + return 0x00; + } +} + +uint8_t dyn_slave_check_checksum(void) +{ + uint8_t i,cs=0x00; + + for(i=2;i<dyn_slave_data[3]+4;i++) + cs+=dyn_slave_data[i]; + if(cs==0xFF) + return 0x01; + else + return 0x00; +} + +inline uint8_t dyn_slave_get_instruction(void) +{ + return dyn_slave_data[4]; +} + +inline uint8_t dyn_slave_get_received_id(void) +{ + return dyn_slave_data[2]; +} + +// read operation +inline uint8_t dyn_slave_get_address(void) +{ + return dyn_slave_data[5]; +} + +inline uint8_t dyn_slave_get_read_length(void) +{ + return dyn_slave_data[6]; +} + +// write operation +inline uint8_t dyn_slave_get_write_length(void) +{ + return dyn_slave_data[3]-3; +} + +inline uint8_t *dyn_slave_get_write_data(void) +{ + return &dyn_slave_data[6]; +} + +// sync read operation +uint8_t dyn_slave_sync_read_id_present(void) +{ + uint8_t i,num; + + num=dyn_slave_data[3]-4; + for(i=0;i<num;i++) + { + if(dyn_slave_data[7+i]==dyn_slave_id) + { + if(i==0) + return 0x00; + else + return dyn_slave_data[6+i]; + } + } + return 0xFF; +} + +// sync write operation +uint8_t dyn_slave_sync_write_id_present(uint8_t **data) +{ + uint8_t i,num; + + num=(dyn_slave_data[3]-4)/(dyn_slave_data[6]+1); + for(i=0;i<num;i++) + { + if(dyn_slave_data[7+i*(dyn_slave_data[6]+1)]==dyn_slave_id) + { + (*data)=&dyn_slave_data[7+i*(dyn_slave_data[6]+1)+1]; + return 0x01; + } + } + return 0x00; +} + +// bulk read operation +uint8_t dyn_slave_bulk_read_id_present(uint8_t *address,uint8_t *length) +{ + uint8_t i,num; + + num=(dyn_slave_data[3]-2)/3; + for(i=0;i<num;i++) + { + if(dyn_slave_data[5+i*3]==dyn_slave_id) + { + (*address)=dyn_slave_data[6+i*3]; + (*length)=dyn_slave_data[7+i*3]; + if(i==0) + return 0x00; + else + return dyn_slave_data[5+(i-1)*3]; + } + } + return 0xFF; +} + +// bulk write operation +uint8_t dyn_slave_bulk_write_id_present(uint8_t *address,uint8_t *length,uint8_t **data) +{ + uint8_t i,num; + + num=dyn_slave_data[3]+4; + for(i=5;i<num;) + { + if(dyn_slave_data[i]==dyn_slave_id) + { + (*address)=dyn_slave_data[i+1]; + (*length)=dyn_slave_data[i+2]; + (*data)=&dyn_slave_data[i+3]; + return 0x01; + } + else + i+=dyn_slave_data[i+2]+3; + } + return 0x00; +} + +void dyn_slave_send_status(uint8_t error,uint8_t length, uint8_t *data) +{ + uint8_t i,cs=0; + + if(dyn_slave_data[2]!=0xFE) + { + if(dyn_slave_data[4]==INST_PING || ((dyn_slave_data[4]==INST_READ || + dyn_slave_data[4]==INST_SYNC_READ || dyn_slave_data[4]==INST_BULK_READ) && + ram_data[Status_Return_Level]!=0x00) || ram_data[Status_Return_Level]==0x02) + dyn_slave_data[0]=0xFF; + dyn_slave_data[1]=0xFF; + dyn_slave_data[2]=dyn_slave_id; + cs+=dyn_slave_id; + dyn_slave_data[3]=length+2; + cs+=length+2; + dyn_slave_data[4]=error; + cs+=error; + for(i=0;i<length;i++) + { + dyn_slave_data[5+i]=data[i]; + cs+=data[i]; + } + dyn_slave_data[5+i]=~cs; + // set in tex mode + dyn_slave_set_tx(); + // start transmission + dyn_slave_num_tx_bytes=1; + UDR=dyn_slave_data[0]; + } +} + +inline uint8_t dyn_slave_is_send_done(void) +{ + return dyn_slave_send_done; +} + +/* public functions */ +void dyn_slave_init(uint8_t baudrate,uint8_t id) +{ + // DDRD - Port D Data Direction Register + DDRD=DDRD|0xC2;// RX_en (6), TX_en (7), TX (1) are outputs 0xC2=11000010 + DDRD=DDRD&0xFE;// RX(0) is an input 0xFE=11111110 + + // configure the ports to receive data + dyn_slave_set_rx(); + + // initialize the rs485 ports + UCSRA = (1<<U2X);// double USART transmission speed + dyn_slave_set_baudrate(baudrate); + UCSRA|=0x40;// clear any pending interrupt + UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE); + UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<< UCSZ0);// 8 bit data, no parity, 1 stop bit + + dyn_slave_set_id(id); + // initialize private variables + dyn_slave_num_tx_bytes=0; + dyn_slave_num_rx_bytes=0; + dyn_slave_packet_ready=0; + dyn_slave_send_done=0; + dyn_slave_error=NO_ERROR; + dyn_slave_tmp_address=0x00; + dyn_slave_tmp_length=0x00; + dyn_slave_reg_pending=0x00; + dyn_slave_sync_read_pending=0x00; + dyn_slave_bulk_read_pending=0x00; +} + +void dyn_slave_set_baudrate(uint8_t baudrate) +{ + UBRRH = 0; + UBRRL = baudrate; + ram_data[Baud_Rate]=baudrate; +} + +void dyn_slave_set_id(uint8_t id) +{ + dyn_slave_id=id; + ram_data[ID]=id; +} + +void dyn_slave_loop(void) +{ + static uint8_t *data,i; + + if(dyn_slave_is_packet_ready()) + { + if(dyn_slave_check_id()) + { + if(dyn_slave_check_checksum()) + { + switch(dyn_slave_get_instruction()) + { + case INST_PING: dyn_slave_send_status(dyn_slave_error|NO_ERROR,0x00,0x00000000); + break; + case INST_READ: if(do_read(dyn_slave_get_address(),dyn_slave_get_read_length(),&data)) + dyn_slave_send_status(dyn_slave_error|NO_ERROR,dyn_slave_get_read_length(),data); + else + dyn_slave_send_status(dyn_slave_error|INSTRUCTION_ERROR,0x00,0x00000000); + break; + case INST_WRITE: if(do_write(dyn_slave_get_address(),dyn_slave_get_write_length(),dyn_slave_get_write_data())) + dyn_slave_send_status(dyn_slave_error|NO_ERROR,0x00,0x00000000); + else + dyn_slave_send_status(dyn_slave_error|INSTRUCTION_ERROR,0x00,0x00000000); + break; + case INST_REG_WRITE: dyn_slave_tmp_address=dyn_slave_get_address(); + dyn_slave_tmp_length=dyn_slave_get_write_length(); + data=dyn_slave_get_write_data(); + for(i=0;i<dyn_slave_tmp_length;i++) + dyn_slave_tmp_data[i]=data[i]; + dyn_slave_reg_pending=0x01; + dyn_slave_send_status(dyn_slave_error|NO_ERROR,0x00,0x00000000); + break; + case INST_ACTION: if(dyn_slave_reg_pending) + { + if(do_write(dyn_slave_tmp_address,dyn_slave_tmp_length,dyn_slave_tmp_data)) + dyn_slave_send_status(dyn_slave_error|NO_ERROR,0x00,0x00000000); + } + else + dyn_slave_send_status(dyn_slave_error|INSTRUCTION_ERROR,0x00,0x00000000); + break; + case INST_RESET: + break; + case INST_SYNC_READ: dyn_slave_sync_read_previous=dyn_slave_sync_read_id_present(); + if(dyn_slave_sync_read_previous!=0xFF) + { + if(dyn_slave_sync_read_previous==0x00)// first device on the list + { + if(do_read(dyn_slave_get_address(),dyn_slave_get_read_length(),&data)) + dyn_slave_send_status(dyn_slave_error|NO_ERROR,dyn_slave_get_read_length(),data); + else + dyn_slave_send_status(dyn_slave_error|INSTRUCTION_ERROR,0x00,0x00000000); + } + else// sync read pending + { + dyn_slave_tmp_address=dyn_slave_get_address(); + dyn_slave_tmp_length=dyn_slave_get_read_length(); + dyn_slave_sync_read_pending=0x01; + } + } + break; + case INST_SYNC_WRITE: if(dyn_slave_sync_write_id_present(&data)) + do_write(dyn_slave_get_address(),dyn_slave_get_read_length(),data); + break; + case INST_BULK_READ: dyn_slave_bulk_read_previous=dyn_slave_bulk_read_id_present(&dyn_slave_tmp_address,&dyn_slave_tmp_length); + if(dyn_slave_bulk_read_previous!=0xFF) + { + if(dyn_slave_bulk_read_previous==0x00)// first device on the list + { + if(do_read(dyn_slave_tmp_address,dyn_slave_tmp_length,&data)) + dyn_slave_send_status(dyn_slave_error|NO_ERROR,dyn_slave_tmp_length,data); + else + dyn_slave_send_status(dyn_slave_error|INSTRUCTION_ERROR,0x00,0x00000000); + } + else// sync read pending + dyn_slave_bulk_read_pending=0x01; + } + break; + case INST_BULK_WRITE: if(dyn_slave_bulk_write_id_present(&dyn_slave_tmp_address,&dyn_slave_tmp_length,&data)) + do_write(dyn_slave_tmp_address,dyn_slave_tmp_length,data); + break; + default: dyn_slave_send_status(dyn_slave_error|INSTRUCTION_ERROR,0x00,0x00000000); + break; + } + } + else + dyn_slave_send_status(dyn_slave_error|CHECKSUM_ERROR,0x00,0x00000000); + } + else + { + if(dyn_slave_sync_read_pending) + { + if(dyn_slave_get_received_id()==dyn_slave_sync_read_previous) + { + dyn_slave_sync_read_pending=0x00; + if(do_read(dyn_slave_tmp_address,dyn_slave_tmp_length,&data)) + dyn_slave_send_status(dyn_slave_error|NO_ERROR,dyn_slave_tmp_length,data); + else + dyn_slave_send_status(dyn_slave_error|INSTRUCTION_ERROR,0x00,0x00000000); + } + } + if(dyn_slave_bulk_read_pending) + { + if(dyn_slave_get_received_id()==dyn_slave_bulk_read_previous) + { + dyn_slave_bulk_read_pending=0x00; + if(do_read(dyn_slave_tmp_address,dyn_slave_tmp_length,&data)) + dyn_slave_send_status(dyn_slave_error|NO_ERROR,dyn_slave_tmp_length,data); + else + dyn_slave_send_status(dyn_slave_error|INSTRUCTION_ERROR,0x00,0x00000000); + } + } + } + } +} + +void dyn_slave_set_error(uint8_t error) +{ + dyn_slave_error|=error; +} + +void dyn_slave_clear_error(void) +{ + dyn_slave_error=NO_ERROR; +} diff --git a/micro/led_segments.c b/micro/src/leds.c old mode 100755 new mode 100644 similarity index 67% rename from micro/led_segments.c rename to micro/src/leds.c index 7a7b55c2a97f63a918e3355b84492b48a3a13e5f..c1f4d064882670e5c4b004167a67c86de98e04e0 --- a/micro/led_segments.c +++ b/micro/src/leds.c @@ -1,312 +1,386 @@ -#include "led_segments.h" - -// global AVRLIB defines -#include "avrlibdefs.h" -// global AVRLIB types definitions -#include "avrlibtypes.h" - - -const TLedSegment segments[num_segments]={{l_eyebrow_l_reg,&desired_PORTC_value,_BV(l_eyebrow_l_port)}, - {l_eyebrow_c_reg,&desired_PORTC_value,_BV(l_eyebrow_c_port)}, - {l_eyebrow_r_reg,&desired_PORTC_value,_BV(l_eyebrow_r_port)}, - {l_cheek_i_reg,&desired_PORTC_value,_BV(l_cheek_i_port)}, - {l_cheek_o_reg,&desired_PORTC_value,_BV(l_cheek_o_port)}, - {lip_ue_reg,&desired_PORTC_value,_BV(lip_ue_port)}, - {lip_uc_reg,&desired_PORTC_value,_BV(lip_uc_port)}, - {lip_bc_reg,&desired_PORTC_value,_BV(lip_bc_port)}, - {lip_nu_reg,&desired_PORTB_value,_BV(lip_nu_port)}, - {r_eyebrow_c_reg,&desired_PORTA_value,_BV(r_eyebrow_c_port)}, - {r_eyebrow_l_reg,&desired_PORTA_value,_BV(r_eyebrow_l_port)}, - {r_eyebrow_r_reg,&desired_PORTA_value,_BV(r_eyebrow_r_port)}, - {r_cheek_o_reg,&desired_PORTA_value,_BV(r_cheek_o_port)}, - {r_cheek_i_reg,&desired_PORTA_value,_BV(r_cheek_i_port)}, - {lip_c_reg,&desired_PORTA_value,_BV(lip_c_port)}, - {lip_be_reg,&desired_PORTA_value,_BV(lip_be_port)}, - {lip_ce_reg,&desired_PORTA_value,_BV(lip_ce_port)}, - {extra_segment1_reg,&desired_PORTB_value,_BV(extra_segment1_port)}, - {extra_segment2_reg,&desired_PORTB_value,_BV(extra_segment2_port)}, - {extra_segment3_reg,&desired_PORTB_value,_BV(extra_segment3_port)}, - {extra_segment4_reg,&desired_PORTB_value,_BV(extra_segment4_port)}, - {extra_segment5_reg,&desired_PORTD_value,_BV(extra_segment5_port)}, - {extra_segment6_reg,&desired_PORTD_value,_BV(extra_segment6_port)}, - {extra_segment7_reg,&desired_PORTD_value,_BV(extra_segment7_port)}, - {extra_segment8_reg,&desired_PORTD_value,_BV(extra_segment8_port)}}; - -void turn_on_segment(unsigned char segment) -{ - (*(segments[segment-1].desired_port))=(*(segments[segment-1].desired_port))|segments[segment-1].bit_mask; -} - -void turn_off_segment(unsigned char segment) -{ - (*(segments[segment-1].desired_port))=(*(segments[segment-1].desired_port))&~segments[segment-1].bit_mask; -} - -unsigned char is_segment_on(unsigned char segment) -{ - if((*(segments[segment-1].desired_port))&segments[segment-1].bit_mask) - return 0x01; - else - return 0x00; -} - -void standby_conf(void) -{ - turn_off_segment(l_eyebrow_l_reg); - turn_on_segment(l_eyebrow_c_reg); - turn_off_segment(l_eyebrow_r_reg); - turn_off_segment(l_cheek_i_reg); - turn_off_segment(l_cheek_o_reg); - turn_off_segment(r_eyebrow_l_reg); - turn_on_segment(r_eyebrow_c_reg); - turn_off_segment(r_eyebrow_r_reg); - turn_off_segment(r_cheek_i_reg); - turn_off_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_off_segment(lip_uc_reg); - turn_on_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_off_segment(lip_c_reg); - turn_off_segment(lip_be_reg); - turn_off_segment(lip_ce_reg); - turn_off_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} - -void happiness_conf(void) -{ - turn_off_segment(l_eyebrow_l_reg); - turn_on_segment(l_eyebrow_c_reg); - turn_off_segment(l_eyebrow_r_reg); - turn_off_segment(l_cheek_i_reg); - turn_off_segment(l_cheek_o_reg); - turn_off_segment(r_eyebrow_l_reg); - turn_on_segment(r_eyebrow_c_reg); - turn_off_segment(r_eyebrow_r_reg); - turn_off_segment(r_cheek_i_reg); - turn_off_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_off_segment(lip_uc_reg); - turn_on_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_off_segment(lip_c_reg); - turn_off_segment(lip_be_reg); - turn_on_segment(lip_ce_reg); - turn_on_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} - -void sadness_conf(void) -{ - turn_on_segment(l_eyebrow_l_reg); - turn_on_segment(l_eyebrow_c_reg); - turn_off_segment(l_eyebrow_r_reg); - turn_off_segment(l_cheek_i_reg); - turn_off_segment(l_cheek_o_reg); - turn_off_segment(r_eyebrow_l_reg); - turn_on_segment(r_eyebrow_c_reg); - turn_on_segment(r_eyebrow_r_reg); - turn_off_segment(r_cheek_i_reg); - turn_off_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_on_segment(lip_uc_reg); - turn_off_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_off_segment(lip_c_reg); - turn_on_segment(lip_be_reg); - turn_on_segment(lip_ce_reg); - turn_off_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} - -void angry_conf(void) -{ - turn_off_segment(l_eyebrow_l_reg); - turn_off_segment(l_eyebrow_c_reg); - turn_on_segment(l_eyebrow_r_reg); - turn_off_segment(l_cheek_i_reg); - turn_off_segment(l_cheek_o_reg); - turn_on_segment(r_eyebrow_l_reg); - turn_off_segment(r_eyebrow_c_reg); - turn_off_segment(r_eyebrow_r_reg); - turn_off_segment(r_cheek_i_reg); - turn_off_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_on_segment(lip_uc_reg); - turn_off_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_off_segment(lip_c_reg); - turn_off_segment(lip_be_reg); - turn_on_segment(lip_ce_reg); - turn_off_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} - -void confused_conf(void) -{ - turn_on_segment(l_eyebrow_l_reg); - turn_off_segment(l_eyebrow_c_reg); - turn_off_segment(l_eyebrow_r_reg); - turn_off_segment(l_cheek_i_reg); - turn_off_segment(l_cheek_o_reg); - turn_off_segment(r_eyebrow_l_reg); - turn_off_segment(r_eyebrow_c_reg); - turn_on_segment(r_eyebrow_r_reg); - turn_off_segment(r_cheek_i_reg); - turn_off_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_off_segment(lip_uc_reg); - turn_off_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_on_segment(lip_c_reg); - turn_off_segment(lip_be_reg); - turn_off_segment(lip_ce_reg); - turn_off_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} - -void shyness_conf(void) -{ - turn_off_segment(l_eyebrow_l_reg); - turn_off_segment(l_eyebrow_c_reg); - turn_off_segment(l_eyebrow_r_reg); - turn_on_segment(l_cheek_i_reg); - turn_on_segment(l_cheek_o_reg); - turn_off_segment(r_eyebrow_l_reg); - turn_off_segment(r_eyebrow_c_reg); - turn_off_segment(r_eyebrow_r_reg); - turn_on_segment(r_cheek_i_reg); - turn_on_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_off_segment(lip_uc_reg); - turn_on_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_off_segment(lip_c_reg); - turn_off_segment(lip_be_reg); - turn_on_segment(lip_ce_reg); - turn_off_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} - -void ashamed_conf(void) -{ - turn_off_segment(l_eyebrow_l_reg); - turn_off_segment(l_eyebrow_c_reg); - turn_off_segment(l_eyebrow_r_reg); - turn_on_segment(l_cheek_i_reg); - turn_on_segment(l_cheek_o_reg); - turn_off_segment(r_eyebrow_l_reg); - turn_off_segment(r_eyebrow_c_reg); - turn_off_segment(r_eyebrow_r_reg); - turn_on_segment(r_cheek_i_reg); - turn_on_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_on_segment(lip_uc_reg); - turn_off_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_off_segment(lip_c_reg); - turn_off_segment(lip_be_reg); - turn_on_segment(lip_ce_reg); - turn_off_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} - -void speak1_conf(void) -{ - turn_off_segment(l_eyebrow_l_reg); - turn_on_segment(l_eyebrow_c_reg); - turn_off_segment(l_eyebrow_r_reg); - turn_off_segment(l_cheek_i_reg); - turn_off_segment(l_cheek_o_reg); - turn_off_segment(r_eyebrow_l_reg); - turn_on_segment(r_eyebrow_c_reg); - turn_off_segment(r_eyebrow_r_reg); - turn_off_segment(r_cheek_i_reg); - turn_off_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_on_segment(lip_uc_reg); - turn_off_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_on_segment(lip_c_reg); - turn_off_segment(lip_be_reg); - turn_off_segment(lip_ce_reg); - turn_off_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} - -void speak2_conf(void) -{ - turn_off_segment(l_eyebrow_l_reg); - turn_on_segment(l_eyebrow_c_reg); - turn_off_segment(l_eyebrow_r_reg); - turn_off_segment(l_cheek_i_reg); - turn_off_segment(l_cheek_o_reg); - turn_off_segment(r_eyebrow_l_reg); - turn_on_segment(r_eyebrow_c_reg); - turn_off_segment(r_eyebrow_r_reg); - turn_off_segment(r_cheek_i_reg); - turn_off_segment(r_cheek_o_reg); - turn_off_segment(lip_ue_reg); - turn_on_segment(lip_uc_reg); - turn_on_segment(lip_bc_reg); - turn_off_segment(lip_nu_reg); - turn_off_segment(lip_c_reg); - turn_off_segment(lip_be_reg); - turn_on_segment(lip_ce_reg); - turn_off_segment(extra_segment1_reg); - turn_off_segment(extra_segment2_reg); - turn_off_segment(extra_segment3_reg); - turn_off_segment(extra_segment4_reg); - turn_off_segment(extra_segment5_reg); - turn_off_segment(extra_segment6_reg); - turn_off_segment(extra_segment7_reg); - turn_off_segment(extra_segment8_reg); -} +#include "leds.h" +#include "segments.h" +#include "mem.h" +#include <avr/io.h> +#include <avr/interrupt.h> + +// desired output port values +unsigned char desired_PORTA_value; +unsigned char desired_PORTB_value; +unsigned char desired_PORTC_value; +unsigned char desired_PORTD_value; +unsigned char brightness_value; + +const TLedSegment segments[num_segments]={{l_eyebrow_l_reg,&desired_PORTC_value,(1<<l_eyebrow_l_port)}, + {l_eyebrow_c_reg,&desired_PORTC_value,(1<<l_eyebrow_c_port)}, + {l_eyebrow_r_reg,&desired_PORTC_value,(1<<l_eyebrow_r_port)}, + {l_cheek_i_reg,&desired_PORTC_value,(1<<l_cheek_i_port)}, + {l_cheek_o_reg,&desired_PORTC_value,(1<<l_cheek_o_port)}, + {lip_ue_reg,&desired_PORTC_value,(1<<lip_ue_port)}, + {lip_uc_reg,&desired_PORTC_value,(1<<lip_uc_port)}, + {lip_bc_reg,&desired_PORTC_value,(1<<lip_bc_port)}, + {lip_nu_reg,&desired_PORTB_value,(1<<lip_nu_port)}, + {r_eyebrow_c_reg,&desired_PORTA_value,(1<<r_eyebrow_c_port)}, + {r_eyebrow_l_reg,&desired_PORTA_value,(1<<r_eyebrow_l_port)}, + {r_eyebrow_r_reg,&desired_PORTA_value,(1<<r_eyebrow_r_port)}, + {r_cheek_o_reg,&desired_PORTA_value,(1<<r_cheek_o_port)}, + {r_cheek_i_reg,&desired_PORTA_value,(1<<r_cheek_i_port)}, + {lip_c_reg,&desired_PORTA_value,(1<<lip_c_port)}, + {lip_be_reg,&desired_PORTA_value,(1<<lip_be_port)}, + {lip_ce_reg,&desired_PORTA_value,(1<<lip_ce_port)}, + {extra_segment1_reg,&desired_PORTB_value,(1<<extra_segment1_port)}, + {extra_segment2_reg,&desired_PORTB_value,(1<<extra_segment2_port)}, + {extra_segment3_reg,&desired_PORTB_value,(1<<extra_segment3_port)}, + {extra_segment4_reg,&desired_PORTB_value,(1<<extra_segment4_port)}, + {extra_segment5_reg,&desired_PORTD_value,(1<<extra_segment5_port)}, + {extra_segment6_reg,&desired_PORTD_value,(1<<extra_segment6_port)}, + {extra_segment7_reg,&desired_PORTD_value,(1<<extra_segment7_port)}, + {extra_segment8_reg,&desired_PORTD_value,(1<<extra_segment8_port)}}; + +// interruopt handlers +ISR(TIMER0_OVF_vect) +{ + static char counts=0; + + counts++; + if(counts<brightness_value) + { + PORTA=desired_PORTA_value; + PORTB=desired_PORTB_value; + PORTC=desired_PORTC_value; + PORTD=PIND|(desired_PORTD_value&0x3C); + } + else + { + PORTA=0x00; + PORTB=0x00; + PORTC=0x00; + PORTD=PIND&0xC3; + } +} + +// public functions +void leds_init(void) +{ + /* initialize internal variables */ + desired_PORTA_value=0x00; + desired_PORTB_value=0x00; + desired_PORTC_value=0x00; + desired_PORTD_value=0x00; + brightness_value=10; + + /* configure IO ports */ + DDRA=0xFF;// all outputs + DDRB=0x1F;// the most significant bits are used by the programmer + DDRC=0xFF;// all outputs + DDRD|=0x3C;// exclude configuration of the UART pins + + /* configure the timer (interrupt every 3.9 us) */ + TCNT0=0x00;// reset TCNT0 + TIMSK|=(1<<TOIE0);// enable TCNT0 overflow interrupt + TCCR0&=0xF8; + TCCR0|=0x01; + TCNT0=193;// set the start count value +} + +void set_brightness(unsigned char brightness_level) +{ + brightness_value=brightness_level; + ram_data[brightness]=brightness_level; +} + +unsigned char get_brightness(void) +{ + return brightness_value; +} + +void turn_on_segment(unsigned char segment) +{ + (*(segments[segment-1].desired_port))=(*(segments[segment-1].desired_port))|segments[segment-1].bit_mask; + ram_data[segment+segments_offset]=0x01; +} + +void turn_off_segment(unsigned char segment) +{ + (*(segments[segment-1].desired_port))=(*(segments[segment-1].desired_port))&~segments[segment-1].bit_mask; + ram_data[segment+segments_offset]=0x00; +} + +unsigned char is_segment_on(unsigned char segment) +{ + if((*(segments[segment-1].desired_port))&segments[segment-1].bit_mask) + return 0x01; + else + return 0x00; +} + +void standby_conf(void) +{ + turn_off_segment(l_eyebrow_l_reg); + turn_on_segment(l_eyebrow_c_reg); + turn_off_segment(l_eyebrow_r_reg); + turn_off_segment(l_cheek_i_reg); + turn_off_segment(l_cheek_o_reg); + turn_off_segment(r_eyebrow_l_reg); + turn_on_segment(r_eyebrow_c_reg); + turn_off_segment(r_eyebrow_r_reg); + turn_off_segment(r_cheek_i_reg); + turn_off_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_off_segment(lip_uc_reg); + turn_on_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_off_segment(lip_c_reg); + turn_off_segment(lip_be_reg); + turn_off_segment(lip_ce_reg); + turn_off_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); + ram_data[standby]=0x00; + ram_data[hapiness]=0x00; + ram_data[sadness]=0x00; + ram_data[angry]=0x00; + ram_data[confused]=0x00; + ram_data[shyness]=0x00; + ram_data[ashamed]=0x00; + ram_data[speak1]=0x00; + ram_data[speak2]=0x00; +} + +void happiness_conf(void) +{ + turn_off_segment(l_eyebrow_l_reg); + turn_on_segment(l_eyebrow_c_reg); + turn_off_segment(l_eyebrow_r_reg); + turn_off_segment(l_cheek_i_reg); + turn_off_segment(l_cheek_o_reg); + turn_off_segment(r_eyebrow_l_reg); + turn_on_segment(r_eyebrow_c_reg); + turn_off_segment(r_eyebrow_r_reg); + turn_off_segment(r_cheek_i_reg); + turn_off_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_off_segment(lip_uc_reg); + turn_on_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_off_segment(lip_c_reg); + turn_off_segment(lip_be_reg); + turn_on_segment(lip_ce_reg); + turn_on_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); +} + +void sadness_conf(void) +{ + turn_on_segment(l_eyebrow_l_reg); + turn_on_segment(l_eyebrow_c_reg); + turn_off_segment(l_eyebrow_r_reg); + turn_off_segment(l_cheek_i_reg); + turn_off_segment(l_cheek_o_reg); + turn_off_segment(r_eyebrow_l_reg); + turn_on_segment(r_eyebrow_c_reg); + turn_on_segment(r_eyebrow_r_reg); + turn_off_segment(r_cheek_i_reg); + turn_off_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_on_segment(lip_uc_reg); + turn_off_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_off_segment(lip_c_reg); + turn_on_segment(lip_be_reg); + turn_on_segment(lip_ce_reg); + turn_off_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); +} + +void angry_conf(void) +{ + turn_off_segment(l_eyebrow_l_reg); + turn_off_segment(l_eyebrow_c_reg); + turn_on_segment(l_eyebrow_r_reg); + turn_off_segment(l_cheek_i_reg); + turn_off_segment(l_cheek_o_reg); + turn_on_segment(r_eyebrow_l_reg); + turn_off_segment(r_eyebrow_c_reg); + turn_off_segment(r_eyebrow_r_reg); + turn_off_segment(r_cheek_i_reg); + turn_off_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_on_segment(lip_uc_reg); + turn_off_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_off_segment(lip_c_reg); + turn_off_segment(lip_be_reg); + turn_on_segment(lip_ce_reg); + turn_off_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); +} + +void confused_conf(void) +{ + turn_on_segment(l_eyebrow_l_reg); + turn_off_segment(l_eyebrow_c_reg); + turn_off_segment(l_eyebrow_r_reg); + turn_off_segment(l_cheek_i_reg); + turn_off_segment(l_cheek_o_reg); + turn_off_segment(r_eyebrow_l_reg); + turn_off_segment(r_eyebrow_c_reg); + turn_on_segment(r_eyebrow_r_reg); + turn_off_segment(r_cheek_i_reg); + turn_off_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_off_segment(lip_uc_reg); + turn_off_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_on_segment(lip_c_reg); + turn_off_segment(lip_be_reg); + turn_off_segment(lip_ce_reg); + turn_off_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); +} + +void shyness_conf(void) +{ + turn_off_segment(l_eyebrow_l_reg); + turn_off_segment(l_eyebrow_c_reg); + turn_off_segment(l_eyebrow_r_reg); + turn_on_segment(l_cheek_i_reg); + turn_on_segment(l_cheek_o_reg); + turn_off_segment(r_eyebrow_l_reg); + turn_off_segment(r_eyebrow_c_reg); + turn_off_segment(r_eyebrow_r_reg); + turn_on_segment(r_cheek_i_reg); + turn_on_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_off_segment(lip_uc_reg); + turn_on_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_off_segment(lip_c_reg); + turn_off_segment(lip_be_reg); + turn_on_segment(lip_ce_reg); + turn_off_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); +} + +void ashamed_conf(void) +{ + turn_off_segment(l_eyebrow_l_reg); + turn_off_segment(l_eyebrow_c_reg); + turn_off_segment(l_eyebrow_r_reg); + turn_on_segment(l_cheek_i_reg); + turn_on_segment(l_cheek_o_reg); + turn_off_segment(r_eyebrow_l_reg); + turn_off_segment(r_eyebrow_c_reg); + turn_off_segment(r_eyebrow_r_reg); + turn_on_segment(r_cheek_i_reg); + turn_on_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_on_segment(lip_uc_reg); + turn_off_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_off_segment(lip_c_reg); + turn_off_segment(lip_be_reg); + turn_on_segment(lip_ce_reg); + turn_off_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); +} + +void speak1_conf(void) +{ + turn_off_segment(l_eyebrow_l_reg); + turn_on_segment(l_eyebrow_c_reg); + turn_off_segment(l_eyebrow_r_reg); + turn_off_segment(l_cheek_i_reg); + turn_off_segment(l_cheek_o_reg); + turn_off_segment(r_eyebrow_l_reg); + turn_on_segment(r_eyebrow_c_reg); + turn_off_segment(r_eyebrow_r_reg); + turn_off_segment(r_cheek_i_reg); + turn_off_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_on_segment(lip_uc_reg); + turn_off_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_on_segment(lip_c_reg); + turn_off_segment(lip_be_reg); + turn_off_segment(lip_ce_reg); + turn_off_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); +} + +void speak2_conf(void) +{ + turn_off_segment(l_eyebrow_l_reg); + turn_on_segment(l_eyebrow_c_reg); + turn_off_segment(l_eyebrow_r_reg); + turn_off_segment(l_cheek_i_reg); + turn_off_segment(l_cheek_o_reg); + turn_off_segment(r_eyebrow_l_reg); + turn_on_segment(r_eyebrow_c_reg); + turn_off_segment(r_eyebrow_r_reg); + turn_off_segment(r_cheek_i_reg); + turn_off_segment(r_cheek_o_reg); + turn_off_segment(lip_ue_reg); + turn_on_segment(lip_uc_reg); + turn_on_segment(lip_bc_reg); + turn_off_segment(lip_nu_reg); + turn_off_segment(lip_c_reg); + turn_off_segment(lip_be_reg); + turn_on_segment(lip_ce_reg); + turn_off_segment(extra_segment1_reg); + turn_off_segment(extra_segment2_reg); + turn_off_segment(extra_segment3_reg); + turn_off_segment(extra_segment4_reg); + turn_off_segment(extra_segment5_reg); + turn_off_segment(extra_segment6_reg); + turn_off_segment(extra_segment7_reg); + turn_off_segment(extra_segment8_reg); +} + diff --git a/micro/src/main.c b/micro/src/main.c new file mode 100755 index 0000000000000000000000000000000000000000..21a9bdb1d81357a742df4351a01f97438be85bb6 --- /dev/null +++ b/micro/src/main.c @@ -0,0 +1,19 @@ +#include <avr/io.h> +#include <util/delay.h> +#include <avr/interrupt.h> +#include "dyn_slave.h" +#include "mem.h" +#include "leds.h" + +int16_t main(void) +{ + ram_init(); + dyn_slave_init(ram_data[Baud_Rate],ram_data[ID]); + leds_init(); + sei(); + + while (1) + { + dyn_slave_loop(); + } +} diff --git a/micro/src/mem.c b/micro/src/mem.c new file mode 100644 index 0000000000000000000000000000000000000000..edfdfbf9b50047c254318fc99739643c26bfaf8c --- /dev/null +++ b/micro/src/mem.c @@ -0,0 +1,49 @@ +#include "mem.h" +#include <avr/eeprom.h> + +// dynamixel RAM variables +uint8_t ram_data[RAM_SIZE]; + +// Dynamixel EEPROM variables ID baud +uint8_t EEMEM eeprom_data[17]={0xFF,0x00,0x00,0x05,0x10,0xFA,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}; + +void ram_init(void) +{ + uint8_t i; + + for(i=0;i<=Status_Return_Level;i++) + ram_data[i]=eeprom_read_byte(&eeprom_data[i]); + for(;i<RAM_SIZE;i++) + ram_data[i]=0x00; + ram_data[brightness]=10; +} + +uint8_t ram_read(uint8_t address, uint8_t length, uint8_t **data) +{ + if((address+length)>RAM_SIZE) + return 0x00; + else + { + (*data)=&ram_data[address]; + return 0x01; + } +} + +uint8_t ram_write(uint8_t address, uint8_t length, uint8_t *data) +{ + uint8_t i,num=0; + + if((address+length)>RAM_SIZE) + return 0x00; + else + { + for(i=address;i<address+length;i++) + { + if(i<=Return_Delay_Time) + eeprom_write_byte(&eeprom_data[i],data[num]); + ram_data[i]=data[num]; + num++; + } + return 0x01; + } +} diff --git a/micro/timer.c b/micro/timer.c deleted file mode 100755 index a041899fa76e8e5b70afc73efea1fb2f4fc48acc..0000000000000000000000000000000000000000 --- a/micro/timer.c +++ /dev/null @@ -1,466 +0,0 @@ -/*! \file timer.c \brief System Timer function library. */ -//***************************************************************************** -// -// File Name : 'timer.c' -// Title : System Timer function library -// Author : Pascal Stang - Copyright (C) 2000-2002 -// Created : 11/22/2000 -// Revised : 07/09/2003 -// Version : 1.1 -// Target MCU : Atmel AVR Series -// Editor Tabs : 4 -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - -#include <avr/io.h> -#include <avr/interrupt.h> -#include <avr/pgmspace.h> -#include <avr/sleep.h> - -#include "timer.h" - -// Program ROM constants -// the prescale division values stored in order of timer control register index -// STOP, CLK, CLK/8, CLK/64, CLK/256, CLK/1024 -unsigned short __attribute__ ((progmem)) TimerPrescaleFactor[] = {0,1,8,64,256,1024}; -// the prescale division values stored in order of timer control register index -// STOP, CLK, CLK/8, CLK/32, CLK/64, CLK/128, CLK/256, CLK/1024 -unsigned short __attribute__ ((progmem)) TimerRTCPrescaleFactor[] = {0,1,8,32,64,128,256,1024}; - -// Global variables -// time registers -volatile unsigned long TimerPauseReg; -volatile unsigned long Timer0Reg0; -volatile unsigned long Timer2Reg0; - -typedef void (*voidFuncPtr)(void); -volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS]; - -// delay for a minimum of <us> microseconds -// the time resolution is dependent on the time the loop takes -// e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us -void delay_us(unsigned short time_us) -{ - unsigned short delay_loops; - register unsigned short i; - - delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) - - // one loop takes 5 cpu cycles - for (i=0; i < delay_loops; i++) {}; -} -/* -void delay_ms(unsigned char time_ms) -{ - unsigned short delay_count = F_CPU / 4000; - - unsigned short cnt; - asm volatile ("\n" - "L_dl1%=:\n\t" - "mov %A0, %A2\n\t" - "mov %B0, %B2\n" - "L_dl2%=:\n\t" - "sbiw %A0, 1\n\t" - "brne L_dl2%=\n\t" - "dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt) - :"r"(time_ms), "r"((unsigned short) (delay_count)) - ); -} -*/ -void timerInit(void) -{ - u08 intNum; - // detach all user functions from interrupts - for(intNum=0; intNum<TIMER_NUM_INTERRUPTS; intNum++) - timerDetach(intNum); - - // initialize all timers - timer0Init(); - timer1Init(); - #ifdef TCNT2 // support timer2 only if it exists - timer2Init(); - #endif - // enable interrupts - sei(); -} - -void timer0Init() -{ - // initialize timer 0 - timer0SetPrescaler( TIMER0PRESCALE ); // set prescaler - outb(TCNT0, 0); // reset TCNT0 - sbi(TIMSK, TOIE0); // enable TCNT0 overflow interrupt - - timer0ClearOverflowCount(); // initialize time registers -} - -void timer1Init(void) -{ - // initialize timer 1 - timer1SetPrescaler( TIMER1PRESCALE ); // set prescaler - outb(TCNT1H, 0); // reset TCNT1 - outb(TCNT1L, 0); - sbi(TIMSK, TOIE1); // enable TCNT1 overflow -} - -#ifdef TCNT2 // support timer2 only if it exists -void timer2Init(void) -{ - // initialize timer 2 - timer2SetPrescaler( TIMER2PRESCALE ); // set prescaler - outb(TCNT2, 0); // reset TCNT2 - sbi(TIMSK, TOIE2); // enable TCNT2 overflow - - timer2ClearOverflowCount(); // initialize time registers -} -#endif - -void timer0SetPrescaler(u08 prescale) -{ - // set prescaler on timer 0 - outb(TCCR0, (inb(TCCR0) & ~TIMER_PRESCALE_MASK) | prescale); -} - -void timer1SetPrescaler(u08 prescale) -{ - // set prescaler on timer 1 - outb(TCCR1B, (inb(TCCR1B) & ~TIMER_PRESCALE_MASK) | prescale); -} - -#ifdef TCNT2 // support timer2 only if it exists -void timer2SetPrescaler(u08 prescale) -{ - // set prescaler on timer 2 - outb(TCCR2, (inb(TCCR2) & ~TIMER_PRESCALE_MASK) | prescale); -} -#endif - -u16 timer0GetPrescaler(void) -{ - // get the current prescaler setting - return (pgm_read_word(TimerPrescaleFactor+(inb(TCCR0) & TIMER_PRESCALE_MASK))); -} - -u16 timer1GetPrescaler(void) -{ - // get the current prescaler setting - return (pgm_read_word(TimerPrescaleFactor+(inb(TCCR1B) & TIMER_PRESCALE_MASK))); -} - -#ifdef TCNT2 // support timer2 only if it exists -u16 timer2GetPrescaler(void) -{ - //TODO: can we assume for all 3-timer AVR processors, - // that timer2 is the RTC timer? - - // get the current prescaler setting - return (pgm_read_word(TimerRTCPrescaleFactor+(inb(TCCR2) & TIMER_PRESCALE_MASK))); -} -#endif - -void timerAttach(u08 interruptNum, void (*userFunc)(void) ) -{ - // make sure the interrupt number is within bounds - if(interruptNum < TIMER_NUM_INTERRUPTS) - { - // set the interrupt function to run - // the supplied user's function - TimerIntFunc[interruptNum] = userFunc; - } -} - -void timerDetach(u08 interruptNum) -{ - // make sure the interrupt number is within bounds - if(interruptNum < TIMER_NUM_INTERRUPTS) - { - // set the interrupt function to run nothing - TimerIntFunc[interruptNum] = 0; - } -} -/* -u32 timerMsToTics(u16 ms) -{ - // calculate the prescaler division rate - u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))); - // calculate the number of timer tics in x milliseconds - return (ms*(F_CPU/(prescaleDiv*256)))/1000; -} - -u16 timerTicsToMs(u32 tics) -{ - // calculate the prescaler division rate - u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))); - // calculate the number of milliseconds in x timer tics - return (tics*1000*(prescaleDiv*256))/F_CPU; -} -*/ -void timerPause(unsigned short pause_ms) -{ - // pauses for exactly <pause_ms> number of milliseconds - u08 timerThres; - u32 ticRateHz; - u32 pause; - - // capture current pause timer value - timerThres = inb(TCNT0); - // reset pause timer overflow count - TimerPauseReg = 0; - // calculate delay for [pause_ms] milliseconds - // prescaler division = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))) - ticRateHz = F_CPU/timer0GetPrescaler(); - // precision management - // prevent overflow and precision underflow - // -could add more conditions to improve accuracy - if( ((ticRateHz < 429497) && (pause_ms <= 10000)) ) - pause = (pause_ms*ticRateHz)/1000; - else - pause = pause_ms*(ticRateHz/1000); - - // loop until time expires - while( ((TimerPauseReg<<8) | inb(TCNT0)) < (pause+timerThres) ) - { - if( TimerPauseReg < (pause>>8)); - { - // save power by idling the processor - set_sleep_mode(SLEEP_MODE_IDLE); - sleep_mode(); - } - } - - /* old inaccurate code, for reference - - // calculate delay for [pause_ms] milliseconds - u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))); - u32 pause = (pause_ms*(F_CPU/(prescaleDiv*256)))/1000; - - TimerPauseReg = 0; - while(TimerPauseReg < pause); - - */ -} - -void timer0ClearOverflowCount(void) -{ - // clear the timer overflow counter registers - Timer0Reg0 = 0; // initialize time registers -} - -long timer0GetOverflowCount(void) -{ - // return the current timer overflow count - // (this is since the last timer0ClearOverflowCount() command was called) - return Timer0Reg0; -} - -#ifdef TCNT2 // support timer2 only if it exists -void timer2ClearOverflowCount(void) -{ - // clear the timer overflow counter registers - Timer2Reg0 = 0; // initialize time registers -} - -long timer2GetOverflowCount(void) -{ - // return the current timer overflow count - // (this is since the last timer2ClearOverflowCount() command was called) - return Timer2Reg0; -} -#endif - -void timer1PWMInit(u08 bitRes) -{ - // configures timer1 for use with PWM output - // on OC1A and OC1B pins - - // enable timer1 as 8,9,10bit PWM - if(bitRes == 9) - { // 9bit mode - sbi(TCCR1A,PWM11); - cbi(TCCR1A,PWM10); - } - else if( bitRes == 10 ) - { // 10bit mode - sbi(TCCR1A,PWM11); - sbi(TCCR1A,PWM10); - } - else - { // default 8bit mode - cbi(TCCR1A,PWM11); - sbi(TCCR1A,PWM10); - } - - // clear output compare value A - outb(OCR1AH, 0); - outb(OCR1AL, 0); - // clear output compare value B - outb(OCR1BH, 0); - outb(OCR1BL, 0); -} - -#ifdef WGM10 -// include support for arbitrary top-count PWM -// on new AVR processors that support it -void timer1PWMInitICR(u16 topcount) -{ - // set PWM mode with ICR top-count - cbi(TCCR1A,WGM10); - sbi(TCCR1A,WGM11); - sbi(TCCR1B,WGM12); - sbi(TCCR1B,WGM13); - - // set top count value - ICR1 = topcount; - - // clear output compare value A - OCR1A = 0; - // clear output compare value B - OCR1B = 0; - -} -#endif - -void timer1PWMOff(void) -{ - // turn off timer1 PWM mode - cbi(TCCR1A,PWM11); - cbi(TCCR1A,PWM10); - // set PWM1A/B (OutputCompare action) to none - timer1PWMAOff(); - timer1PWMBOff(); -} - -void timer1PWMAOn(void) -{ - // turn on channel A (OC1A) PWM output - // set OC1A as non-inverted PWM - sbi(TCCR1A,COM1A1); - cbi(TCCR1A,COM1A0); -} - -void timer1PWMBOn(void) -{ - // turn on channel B (OC1B) PWM output - // set OC1B as non-inverted PWM - sbi(TCCR1A,COM1B1); - cbi(TCCR1A,COM1B0); -} - -void timer1PWMAOff(void) -{ - // turn off channel A (OC1A) PWM output - // set OC1A (OutputCompare action) to none - cbi(TCCR1A,COM1A1); - cbi(TCCR1A,COM1A0); -} - -void timer1PWMBOff(void) -{ - // turn off channel B (OC1B) PWM output - // set OC1B (OutputCompare action) to none - cbi(TCCR1A,COM1B1); - cbi(TCCR1A,COM1B0); -} - -void timer1PWMASet(u16 pwmDuty) -{ - // set PWM (output compare) duty for channel A - // this PWM output is generated on OC1A pin - // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM - // pwmDuty should be in the range 0-511 for 9bit PWM - // pwmDuty should be in the range 0-1023 for 10bit PWM - //outp( (pwmDuty>>8), OCR1AH); // set the high 8bits of OCR1A - //outp( (pwmDuty&0x00FF), OCR1AL); // set the low 8bits of OCR1A - OCR1A = pwmDuty; -} - -void timer1PWMBSet(u16 pwmDuty) -{ - // set PWM (output compare) duty for channel B - // this PWM output is generated on OC1B pin - // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM - // pwmDuty should be in the range 0-511 for 9bit PWM - // pwmDuty should be in the range 0-1023 for 10bit PWM - //outp( (pwmDuty>>8), OCR1BH); // set the high 8bits of OCR1B - //outp( (pwmDuty&0x00FF), OCR1BL); // set the low 8bits of OCR1B - OCR1B = pwmDuty; -} - -//! Interrupt handler for tcnt0 overflow interrupt -TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW0) -{ - Timer0Reg0++; // increment low-order counter - - // increment pause counter - TimerPauseReg++; - - // if a user function is defined, execute it too - if(TimerIntFunc[TIMER0OVERFLOW_INT]) - TimerIntFunc[TIMER0OVERFLOW_INT](); -} - -//! Interrupt handler for tcnt1 overflow interrupt -TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) -{ - // if a user function is defined, execute it - if(TimerIntFunc[TIMER1OVERFLOW_INT]) - TimerIntFunc[TIMER1OVERFLOW_INT](); -} - -#ifdef TCNT2 // support timer2 only if it exists -//! Interrupt handler for tcnt2 overflow interrupt -TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW2) -{ - Timer2Reg0++; // increment low-order counter - - // if a user function is defined, execute it - if(TimerIntFunc[TIMER2OVERFLOW_INT]) - TimerIntFunc[TIMER2OVERFLOW_INT](); -} -#endif - -#ifdef OCR0 -// include support for Output Compare 0 for new AVR processors that support it -//! Interrupt handler for OutputCompare0 match (OC0) interrupt -TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE0) -{ - // if a user function is defined, execute it - if(TimerIntFunc[TIMER0OUTCOMPARE_INT]) - TimerIntFunc[TIMER0OUTCOMPARE_INT](); -} -#endif - -//! Interrupt handler for CutputCompare1A match (OC1A) interrupt -TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1A) -{ - // if a user function is defined, execute it - if(TimerIntFunc[TIMER1OUTCOMPAREA_INT]) - TimerIntFunc[TIMER1OUTCOMPAREA_INT](); -} - -//! Interrupt handler for OutputCompare1B match (OC1B) interrupt -TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1B) -{ - // if a user function is defined, execute it - if(TimerIntFunc[TIMER1OUTCOMPAREB_INT]) - TimerIntFunc[TIMER1OUTCOMPAREB_INT](); -} - -//! Interrupt handler for InputCapture1 (IC1) interrupt -TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE1) -{ - // if a user function is defined, execute it - if(TimerIntFunc[TIMER1INPUTCAPTURE_INT]) - TimerIntFunc[TIMER1INPUTCAPTURE_INT](); -} - -//! Interrupt handler for OutputCompare2 match (OC2) interrupt -TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE2) -{ - // if a user function is defined, execute it - if(TimerIntFunc[TIMER2OUTCOMPARE_INT]) - TimerIntFunc[TIMER2OUTCOMPARE_INT](); -} diff --git a/micro/timer.h b/micro/timer.h deleted file mode 100755 index 4013631c5ec2fe76e5307680075fbcb3d2d19c8a..0000000000000000000000000000000000000000 --- a/micro/timer.h +++ /dev/null @@ -1,319 +0,0 @@ -/*! \file timer.h \brief System Timer function library. */ -//***************************************************************************** -// -// File Name : 'timer.h' -// Title : System Timer function library -// Author : Pascal Stang - Copyright (C) 2000-2002 -// Created : 11/22/2000 -// Revised : 02/10/2003 -// Version : 1.1 -// Target MCU : Atmel AVR Series -// Editor Tabs : 4 -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -/// \ingroup driver_avr -/// \defgroup timer Timer Function Library (timer.c) -/// \code #include "timer.h" \endcode -/// \par Overview -/// This library provides functions for use with the timers internal -/// to the AVR processors. Functions include initialization, set prescaler, -/// calibrated pause function (in milliseconds), attaching and detaching of -/// user functions to interrupts, overflow counters, PWM. Arbitrary -/// frequency generation has been moved to the Pulse Library. -/// -/// \par About Timers -/// The Atmel AVR-series processors each contain at least one -/// hardware timer/counter. Many of the processors contain 2 or 3 -/// timers. Generally speaking, a timer is a hardware counter inside -/// the processor which counts at a rate related to the main CPU clock -/// frequency. Because the counter value increasing (counting up) at -/// a precise rate, we can use it as a timer to create or measure -/// precise delays, schedule events, or generate signals of a certain -/// frequency or pulse-width. -/// \par -/// As an example, the ATmega163 processor has 3 timer/counters. -/// Timer0, Timer1, and Timer2 are 8, 16, and 8 bits wide respectively. -/// This means that they overflow, or roll over back to zero, at a -/// count value of 256 for 8bits or 65536 for 16bits. A prescaler is -/// avaiable for each timer, and the prescaler allows you to pre-divide -/// the main CPU clock rate down to a slower speed before feeding it to -/// the counting input of a timer. For example, if the CPU clock -/// frequency is 3.69MHz, and Timer0's prescaler is set to divide-by-8, -/// then Timer0 will "tic" at 3690000/8 = 461250Hz. Because Timer0 is -/// an 8bit timer, it will count to 256 in just 256/461250Hz = 0.555ms. -/// In fact, when it hits 255, it will overflow and start again at -/// zero. In this case, Timer0 will overflow 461250/256 = 1801.76 -/// times per second. -/// \par -/// Timer0 can be used a number of ways simultaneously. First, the -/// value of the timer can be read by accessing the CPU register \c TCNT0. -/// We could, for example, figure out how long it takes to execute a -/// C command by recording the value of \c TCNT0 before and after -/// execution, then subtract (after-before) = time elapsed. Or we can -/// enable the overflow interrupt which goes off every time T0 -/// overflows and count out longer delays (multiple overflows), or -/// execute a special periodic function at every overflow. -/// \par -/// The other timers (Timer1 and Timer2) offer all the abilities of -/// Timer0 and many more features. Both T1 and T2 can operate as -/// general-purpose timers, but T1 has special hardware allowing it to -/// generate PWM signals, while T2 is specially designed to help count -/// out real time (like hours, minutes, seconds). See the -/// Timer/Counter section of the processor datasheet for more info. -/// -//***************************************************************************** -//@{ - -#ifndef TIMER_H -#define TIMER_H - -// global AVRLIB defines -#include "avrlibdefs.h" -// global AVRLIB types definitions -#include "avrlibtypes.h" - -#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond - -// constants/macros/typdefs - -// processor compatibility fixes -#ifdef __AVR_ATmega323__ - // redefinition for the Mega323 - #define CTC1 CTC10 -#endif -#ifndef PWM10 - // mega128 PWM bits - #define PWM10 WGM10 - #define PWM11 WGM11 -#endif - - -// Timer/clock prescaler values and timer overflow rates -// tics = rate at which the timer counts up -// 8bitoverflow = rate at which the timer overflows 8bits (or reaches 256) -// 16bit [overflow] = rate at which the timer overflows 16bits (65536) -// -// overflows can be used to generate periodic interrupts -// -// for 8MHz crystal -// 0 = STOP (Timer not counting) -// 1 = CLOCK tics= 8MHz 8bitoverflow= 31250Hz 16bit= 122.070Hz -// 2 = CLOCK/8 tics= 1MHz 8bitoverflow= 3906.25Hz 16bit= 15.259Hz -// 3 = CLOCK/64 tics= 125kHz 8bitoverflow= 488.28Hz 16bit= 1.907Hz -// 4 = CLOCK/256 tics= 31250Hz 8bitoverflow= 122.07Hz 16bit= 0.477Hz -// 5 = CLOCK/1024 tics= 7812.5Hz 8bitoverflow= 30.52Hz 16bit= 0.119Hz -// 6 = External Clock on T(x) pin (falling edge) -// 7 = External Clock on T(x) pin (rising edge) - -// for 4MHz crystal -// 0 = STOP (Timer not counting) -// 1 = CLOCK tics= 4MHz 8bitoverflow= 15625Hz 16bit= 61.035Hz -// 2 = CLOCK/8 tics= 500kHz 8bitoverflow= 1953.125Hz 16bit= 7.629Hz -// 3 = CLOCK/64 tics= 62500Hz 8bitoverflow= 244.141Hz 16bit= 0.954Hz -// 4 = CLOCK/256 tics= 15625Hz 8bitoverflow= 61.035Hz 16bit= 0.238Hz -// 5 = CLOCK/1024 tics= 3906.25Hz 8bitoverflow= 15.259Hz 16bit= 0.060Hz -// 6 = External Clock on T(x) pin (falling edge) -// 7 = External Clock on T(x) pin (rising edge) - -// for 3.69MHz crystal -// 0 = STOP (Timer not counting) -// 1 = CLOCK tics= 3.69MHz 8bitoverflow= 14414Hz 16bit= 56.304Hz -// 2 = CLOCK/8 tics= 461250Hz 8bitoverflow= 1801.758Hz 16bit= 7.038Hz -// 3 = CLOCK/64 tics= 57625.25Hz 8bitoverflow= 225.220Hz 16bit= 0.880Hz -// 4 = CLOCK/256 tics= 14414.063Hz 8bitoverflow= 56.305Hz 16bit= 0.220Hz -// 5 = CLOCK/1024 tics= 3603.516Hz 8bitoverflow= 14.076Hz 16bit= 0.055Hz -// 6 = External Clock on T(x) pin (falling edge) -// 7 = External Clock on T(x) pin (rising edge) - -// for 32.768KHz crystal on timer 2 (use for real-time clock) -// 0 = STOP -// 1 = CLOCK tics= 32.768kHz 8bitoverflow= 128Hz -// 2 = CLOCK/8 tics= 4096kHz 8bitoverflow= 16Hz -// 3 = CLOCK/32 tics= 1024kHz 8bitoverflow= 4Hz -// 4 = CLOCK/64 tics= 512Hz 8bitoverflow= 2Hz -// 5 = CLOCK/128 tics= 256Hz 8bitoverflow= 1Hz -// 6 = CLOCK/256 tics= 128Hz 8bitoverflow= 0.5Hz -// 7 = CLOCK/1024 tics= 32Hz 8bitoverflow= 0.125Hz - -#define TIMER_CLK_STOP 0x00 ///< Timer Stopped -#define TIMER_CLK_DIV1 0x01 ///< Timer clocked at F_CPU -#define TIMER_CLK_DIV8 0x02 ///< Timer clocked at F_CPU/8 -#define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64 -#define TIMER_CLK_DIV256 0x04 ///< Timer clocked at F_CPU/256 -#define TIMER_CLK_DIV1024 0x05 ///< Timer clocked at F_CPU/1024 -#define TIMER_CLK_T_FALL 0x06 ///< Timer clocked at T falling edge -#define TIMER_CLK_T_RISE 0x07 ///< Timer clocked at T rising edge -#define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask - -#define TIMERRTC_CLK_STOP 0x00 ///< RTC Timer Stopped -#define TIMERRTC_CLK_DIV1 0x01 ///< RTC Timer clocked at F_CPU -#define TIMERRTC_CLK_DIV8 0x02 ///< RTC Timer clocked at F_CPU/8 -#define TIMERRTC_CLK_DIV32 0x03 ///< RTC Timer clocked at F_CPU/32 -#define TIMERRTC_CLK_DIV64 0x04 ///< RTC Timer clocked at F_CPU/64 -#define TIMERRTC_CLK_DIV128 0x05 ///< RTC Timer clocked at F_CPU/128 -#define TIMERRTC_CLK_DIV256 0x06 ///< RTC Timer clocked at F_CPU/256 -#define TIMERRTC_CLK_DIV1024 0x07 ///< RTC Timer clocked at F_CPU/1024 -#define TIMERRTC_PRESCALE_MASK 0x07 ///< RTC Timer Prescaler Bit-Mask - -// default prescale settings for the timers -// these settings are applied when you call -// timerInit or any of the timer<x>Init -#define TIMER0PRESCALE TIMER_CLK_DIV8 ///< timer 0 prescaler default -#define TIMER1PRESCALE TIMER_CLK_DIV64 ///< timer 1 prescaler default -#define TIMER2PRESCALE TIMERRTC_CLK_DIV64 ///< timer 2 prescaler default - -// interrupt macros for attaching user functions to timer interrupts -// use these with timerAttach( intNum, function ) -#define TIMER0OVERFLOW_INT 0 -#define TIMER1OVERFLOW_INT 1 -#define TIMER1OUTCOMPAREA_INT 2 -#define TIMER1OUTCOMPAREB_INT 3 -#define TIMER1INPUTCAPTURE_INT 4 -#define TIMER2OVERFLOW_INT 5 -#define TIMER2OUTCOMPARE_INT 6 -#ifdef OCR0 // for processors that support output compare on Timer0 -#define TIMER0OUTCOMPARE_INT 7 -#define TIMER_NUM_INTERRUPTS 8 -#else -#define TIMER_NUM_INTERRUPTS 7 -#endif - -// default type of interrupt handler to use for timers -// *do not change unless you know what you're doing -// Value may be SIGNAL or INTERRUPT -#ifndef TIMER_INTERRUPT_HANDLER -#define TIMER_INTERRUPT_HANDLER SIGNAL -#endif - -// functions -#define delay delay_us -#define delay_ms timerPause -void delay_us(unsigned short time_us); - -//! initializes timing system (all timers) -// runs all timer init functions -// sets all timers to default prescale values #defined in systimer.c -void timerInit(void); - -// default initialization routines for each timer -void timer0Init(void); ///< initialize timer0 -void timer1Init(void); ///< initialize timer1 -#ifdef TCNT2 // support timer2 only if it exists -void timer2Init(void); ///< initialize timer2 -#endif - -// Clock prescaler set/get commands for each timer/counter -// For setting the prescaler, you should use one of the #defines -// above like TIMER_CLK_DIVx, where [x] is the division rate -// you want. -// When getting the current prescaler setting, the return value -// will be the [x] division value currently set. -void timer0SetPrescaler(u08 prescale); ///< set timer0 prescaler -u16 timer0GetPrescaler(void); ///< get timer0 prescaler -void timer1SetPrescaler(u08 prescale); ///< set timer1 prescaler -u16 timer1GetPrescaler(void); ///< get timer0 prescaler -#ifdef TCNT2 // support timer2 only if it exists -void timer2SetPrescaler(u08 prescale); ///< set timer2 prescaler -u16 timer2GetPrescaler(void); ///< get timer2 prescaler -#endif - - -// TimerAttach and Detach commands -// These functions allow the attachment (or detachment) of any user function -// to a timer interrupt. "Attaching" one of your own functions to a timer -// interrupt means that it will be called whenever that interrupt happens. -// Using attach is better than rewriting the actual INTERRUPT() function -// because your code will still work and be compatible if the timer library -// is updated. Also, using Attach allows your code and any predefined timer -// code to work together and at the same time. (ie. "attaching" your own -// function to the timer0 overflow doesn't prevent timerPause from working, -// but rather allows you to share the interrupt.) -// -// timerAttach(TIMER1OVERFLOW_INT, myOverflowFunction); -// timerDetach(TIMER1OVERFLOW_INT) -// -// timerAttach causes the myOverflowFunction() to be attached, and therefore -// execute, whenever an overflow on timer1 occurs. timerDetach removes the -// association and executes no user function when the interrupt occurs. -// myOverflowFunction must be defined with no return value and no arguments: -// -// void myOverflowFunction(void) { ... } - -//! Attach a user function to a timer interrupt -void timerAttach(u08 interruptNum, void (*userFunc)(void) ); -//! Detach a user function from a timer interrupt -void timerDetach(u08 interruptNum); - - -// timing commands -/// A timer-based delay/pause function -/// @param pause_ms Number of integer milliseconds to wait. -void timerPause(unsigned short pause_ms); - -// overflow counters -void timer0ClearOverflowCount(void); ///< Clear timer0's overflow counter. -long timer0GetOverflowCount(void); ///< read timer0's overflow counter -#ifdef TCNT2 // support timer2 only if it exists -void timer2ClearOverflowCount(void); ///< clear timer2's overflow counter -long timer2GetOverflowCount(void); ///< read timer0's overflow counter -#endif - -/// @defgroup timerpwm Timer PWM Commands -/// @ingroup timer -/// These commands control PWM functionality on timer1 -// PWM initialization and set commands for timer1 -// timer1PWMInit() -// configures the timer1 hardware for PWM mode on pins OC1A and OC1B. -// bitRes should be 8,9,or 10 for 8,9,or 10bit PWM resolution -// -// timer1PWMOff() -// turns off all timer1 PWM output and set timer mode to normal state -// -// timer1PWMAOn() and timer1PWMBOn() -// turn on output of PWM signals to OC1A or OC1B pins -// NOTE: Until you define the OC1A and OC1B pins as outputs, and run -// this "on" command, no PWM output will be output -// -// timer1PWMAOff() and timer1PWMBOff() -// turn off output of PWM signals to OC1A or OC1B pins -// -// timer1PWMASet() and timer1PWMBSet() -// sets the PWM duty cycle for each channel -// NOTE: <pwmDuty> should be in the range 0-255 for 8bit PWM -// <pwmDuty> should be in the range 0-511 for 9bit PWM -// <pwmDuty> should be in the range 0-1023 for 10bit PWM -// NOTE: the PWM frequency can be controlled in increments by setting the -// prescaler for timer1 -//@{ - - -/// Enter standard PWM Mode on timer1. -/// \param bitRes indicates the period/resolution to use for PWM output in timer bits. -/// Must be either 8, 9, or 10 bits corresponding to PWM periods of 256, 512, or 1024 timer tics. -void timer1PWMInit(u08 bitRes); - -/// Enter PWM Mode on timer1 with a specific top-count value. -/// \param topcount indicates the desired PWM period in timer tics. -/// Can be a number between 1 and 65535 (16-bit). -void timer1PWMInitICR(u16 topcount); - -/// Turn off all timer1 PWM output and set timer mode to normal. -void timer1PWMOff(void); - -/// Turn on/off Timer1 PWM outputs. -void timer1PWMAOn(void); ///< Turn on timer1 Channel A (OC1A) PWM output. -void timer1PWMBOn(void); ///< Turn on timer1 Channel B (OC1B) PWM output. -void timer1PWMAOff(void); ///< turn off timer1 Channel A (OC1A) PWM output -void timer1PWMBOff(void); ///< turn off timer1 Channel B (OC1B) PWM output - -void timer1PWMASet(u16 pwmDuty); ///< set duty of timer1 Channel A (OC1A) PWM output -void timer1PWMBSet(u16 pwmDuty); ///< set duty of timer1 Channel B (OC1B) PWM output - -//@} -//@} - -// Pulse generation commands have been moved to the pulse.c library - -#endif