📄 hardware.c
字号:
/* File : hardware.c Author : Sergiy Uvarov - Copyright (C) 2001 Description : simulatoin of the hardware devices. Copyright notice: avr_simulator - A GNU/Linux simulator for the Atmel AVR series of microcontrollers. Copyright (C) 2001 Sergey Uvarov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Sergiy Uvarov E-mail : colonel@ff.dsu.dp.ua*/#define CK1 1<<0#define CK8 1<<1#define CK32 1<<2#define CK64 1<<3 #define CK128 1<<4#define CK256 1<<5#define CK1024 1<<6 #define _(x) gettext(x)#include <stdio.h>#include <string.h>#include <pthread.h>#include <signal.h>#include <libintl.h>#include <Xm/XmAll.h>#include <inttypes.h>#include "types.h"#include "global.h"#include "hardware.h"void set_flag(int f);void clear_flag(int f);int get_flag(int f);int check_mask_and_flag(int m,int f);int get_pin(int p);void set_pin(int p);void clear_pin(int p);uint8_t add_port(int p,uint8_t add);uint8_t get_port(int port);void set_port(int p,uint8_t value);void set_port16(int low,int hi,uint16_t value);uint16_t get_port16(int low,int hi);uint16_t add_port16(int low,int hi,uint16_t value);void set_sreg_flag(int f);void clear_sreg_flag(int f);int get_sreg_flag(int f);static void compare_set_pin(int mode,int pin);static void pwm_compare_set_pin(int mode,int pin,int add);static void fpwm_compare_match_set_pin(int mode,int pin);static void fpwm_compare_top_set_pin(int mode,int pin);static void set_icr1(void);static void set_icr3(void);int reset_int();int int0_int();int int1_int(); int int2_int();int int3_int();int int4_int();int int5_int();int int6_int();int int7_int();int pcint0_int();int pcint1_int();int timer3_capt_int();int timer3_compa_int();int timer3_compb_int();int timer3_compc_int();int timer3_ovf_int();int timer2_comp_int();int timer2_ovf_int();int timer1_capt_int();int timer1_compa_int();int timer1_compb_int();int timer1_compc_int();int timer1_ovf_int();int timer0_comp_int();int timer0_ovf_int();int spi_stc_int();int uart0_rx_int();int uart0_udre_int();int uart0_tx_int();int uart1_rx_int();int uart1_udre_int();int uart1_tx_int();int adc_int();int ee_ready_int();int analog_comp_int();int twsi_int();int spm_rdy_int();typedef int (*Func_int)(int) ;Func_int func_int[MAX_CODE_INT]={ reset_int, int0_int, int1_int, int2_int, int3_int, int4_int, int5_int, int6_int, int7_int, pcint0_int, pcint1_int, timer3_capt_int, timer3_compa_int, timer3_compb_int, timer3_compc_int, timer3_ovf_int, timer2_comp_int, timer2_ovf_int, timer1_capt_int, timer1_compa_int, timer1_compb_int, timer1_compc_int, timer1_ovf_int, timer0_comp_int, timer0_ovf_int, spi_stc_int, uart0_rx_int, uart0_udre_int, uart0_tx_int, uart1_rx_int, uart1_udre_int, uart1_tx_int, adc_int, ee_ready_int, analog_comp_int, twsi_int, spm_rdy_int};int prescaler_value0,prescaler_result0,prescaler_value1,prescaler_result1, prescaler_value2,prescaler_result2,prescaler_value3,prescaler_result3, watchdog_prescaler=1,wtd_freq=1000000,wacthdog_timeout=UNPROGRAMMED;double eeprom_wat=0.0025; /* EERROM write access time in Sec. */int ex_ifr; /* hardware external interrupt flag register */static Pin *pin;static IO_port *io_port;static Flag *flag;Ports ports[6];/* clean SRAM and EEPROM */void clean_memory(void){ int n; memset(gpr_pointer,0,controllers[type_micro].size_gpr+ controllers[type_micro].size_io_reg+ controllers[type_micro].size_sram); memset(eeprom_pointer,0,controllers[type_micro].size_eeprom); for(n=0;controllers[type_micro].io_registers[n].code!=-1;n++) io_pointer[controllers[type_micro].io_registers[n].address]= controllers[type_micro].io_registers[n].init_value;}void prescaler0(void){ prescaler_result0=0; if(ISFLAG(PSR10_FLAG)) if(get_flag(PSR10_FLAG)) {prescaler_value0=prescaler_value1=0;clear_flag(PSR10_FLAG);} if(ISFLAG(PSR0_FLAG)) if(get_flag(PSR0_FLAG)) {prescaler_value0=0;clear_flag(PSR0_FLAG);} if(ISFLAG(PSR310_FLAG)) if(get_flag(PSR310_FLAG)) { prescaler_value0=prescaler_value1=prescaler_value3=0; clear_flag(PSR310_FLAG); } prescaler_value0++; prescaler_result0|=CK1; if(prescaler_value0%8) return; prescaler_result0|=CK8; if(prescaler_value0%32) return; prescaler_result0|=CK32; if(prescaler_value0%64) return; prescaler_result0|=CK64; if(prescaler_value0%128) return; prescaler_result0|=CK128; if(prescaler_value0%256) return; prescaler_result0|=CK256; if(prescaler_value0%1024) return; prescaler_result0|=CK1024; prescaler_value0=0; }void timer_counter0(void){ int cs=0,prescaler_changed=0,com=0,pwm_mode=0,bottom,max,port; static int t0_pin=0,clear_tcnt=0,add=1,ocr=0; if(!clocks) {t0_pin=clear_tcnt=0;add=1;} if(!ISPORT(TCCR0)) return; if(get_flag(CS00_FLAG)) cs|=1<<0; if(get_flag(CS01_FLAG)) cs|=1<<1; if(get_flag(CS02_FLAG)) cs|=1<<2; switch(cs) { case 0: return; case 1: prescaler_changed=prescaler_result0&CK1; break; case 2: prescaler_changed=prescaler_result0&CK8; break; case 3: if(ISPIN(T0_PIN)) prescaler_changed=prescaler_result0&CK64; else prescaler_changed=prescaler_result0&CK32; break; case 4: if(ISPIN(T0_PIN)) prescaler_changed=prescaler_result0&CK256; else prescaler_changed=prescaler_result0&CK64; break; case 5: if(ISPIN(T0_PIN)) prescaler_changed=prescaler_result0&CK1024; else prescaler_changed=prescaler_result0&CK128; break; case 6: if(ISPIN(T0_PIN)) { if(t0_pin&&!get_pin(T0_PIN)) prescaler_changed=1; t0_pin=get_pin(T0_PIN); } else prescaler_changed=prescaler_result0&CK256; break; case 7: if(ISPIN(T0_PIN)) { if(!t0_pin&&get_pin(T0_PIN)) prescaler_changed=1; t0_pin=get_pin(T0_PIN); } else prescaler_changed=prescaler_result0&CK1024; break; } if(!ISPORT(OCR0)) goto exit; /* get Compare mode */ if(get_flag(COM00_FLAG)) com|=1<<0; if(get_flag(COM01_FLAG)) com|=1<<1; /* get PWM mode */ if(ISFLAG(WGM00_FLAG)&&ISFLAG(WGM01_FLAG)) { if(get_flag(WGM00_FLAG)) pwm_mode|=1<<0; if(get_flag(WGM01_FLAG)) pwm_mode|=1<<1; } else { if(ISFLAG(PWM0_FLAG)) if(get_flag(PWM0_FLAG)) pwm_mode|=1<<0; if(ISFLAG(CTC0_FLAG)) if(get_flag(CTC0_FLAG)) pwm_mode|=1<<1; } port=get_port(TCNT0); max=(port==0xFF); bottom=(port==0); switch(pwm_mode){ case 2: /* CTC mode */ ocr=get_port(OCR0); if(prescaler_changed&&port==ocr) {clear_tcnt=1;set_flag(OCF0_FLAG);} goto normal_mode; case 0: /* Normal mode */ ocr=get_port(OCR0); normal_mode: add=1; if(prescaler_changed) { if(port==ocr) {compare_set_pin(com,OC0_PIN);set_flag(OCF0_FLAG);} if(max) set_flag(TOV0_FLAG); } else { if(ISFLAG(FOC0_FLAG)) if(get_flag(FOC0_FLAG)) {clear_flag(FOC0_FLAG);compare_set_pin(com,OC0_PIN);} } break; case 1: /* PWM, Phase correct */ if(prescaler_changed) { if(port==ocr) {set_flag(OCF0_FLAG);pwm_compare_set_pin(com,OC0_PIN,add);} if(max) {add=-1;ocr=get_port(OCR0);} if(bottom) {add=1;set_flag(TOV0_FLAG);} } break; case 3: /* Fast PWM Mode */ add=1; if(prescaler_changed) { if(bottom) fpwm_compare_top_set_pin(com,OC0_PIN); if(port==ocr) {set_flag(OCF0_FLAG);fpwm_compare_match_set_pin(com,OC0_PIN);} if(max) {ocr=get_port(OCR0);set_flag(TOV0_FLAG);} } } exit: if(prescaler_changed) { if(clear_tcnt) {set_port(TCNT0,0);clear_tcnt=0;} else add_port(TCNT0,add); }}void prescaler2(void){ prescaler_result2=0; prescaler_value2++; prescaler_result2|=CK1; if(prescaler_value2%8) return; prescaler_result2|=CK8; if(prescaler_value2%32) return; prescaler_result2|=CK32; if(prescaler_value2%64) return; prescaler_result2|=CK64; if(prescaler_value2%128) return; prescaler_result2|=CK128; if(prescaler_value2%256) return; prescaler_result2|=CK256; if(prescaler_value2%1024) return; prescaler_result2|=CK1024; prescaler_value2=0; }void timer_counter2(void){ int cs=0,prescaler_changed=0,com=0,pwm_mode=0,bottom,max,port; static int t2_pin=0,clear_tcnt=0,add=1,ocr=0; if(!clocks) {t2_pin=clear_tcnt=0;add=1;} if(!ISPORT(TCCR2)) return; if(get_flag(CS20_FLAG)) cs|=1<<0; if(get_flag(CS21_FLAG)) cs|=1<<1; if(get_flag(CS22_FLAG)) cs|=1<<2; switch(cs) { case 0: return; case 1: prescaler_changed=prescaler_result2&CK1; break; case 2: prescaler_changed=prescaler_result2&CK8; break; case 3: if(ISPIN(T2_PIN)) prescaler_changed=prescaler_result2&CK64; else prescaler_changed=prescaler_result2&CK32; break; case 4: if(ISPIN(T2_PIN)) prescaler_changed=prescaler_result2&CK256; else prescaler_changed=prescaler_result2&CK64; break; case 5: if(ISPIN(T2_PIN)) prescaler_changed=prescaler_result2&CK1024; else prescaler_changed=prescaler_result2&CK128; break; case 6: if(ISPIN(T2_PIN)) { if(t2_pin&&!get_pin(T2_PIN)) prescaler_changed=1; t2_pin=get_pin(T2_PIN); } else prescaler_changed=prescaler_result2&CK256; break; case 7: if(ISPIN(T2_PIN)) { if(!t2_pin&&get_pin(T2_PIN)) prescaler_changed=1; t2_pin=get_pin(T2_PIN); } else prescaler_changed=prescaler_result2&CK1024; break; } if(!ISPORT(OCR2)) goto exit; /* get Compare mode */ if(get_flag(COM20_FLAG)) com|=1<<0; if(get_flag(COM21_FLAG)) com|=1<<1; /* get PWM mode */ if(ISFLAG(WGM20_FLAG)&&ISFLAG(WGM21_FLAG)) { if(get_flag(WGM20_FLAG)) pwm_mode|=1<<0; if(get_flag(WGM21_FLAG)) pwm_mode|=1<<1; } else { if(ISFLAG(PWM2_FLAG)) if(get_flag(PWM2_FLAG)) pwm_mode|=1<<0; if(ISFLAG(CTC2_FLAG)) if(get_flag(CTC2_FLAG)) pwm_mode|=1<<1; } port=get_port(TCNT2); max=(port==0xFF); bottom=(port==0); switch(pwm_mode){ case 2: /* CTC mode */ ocr=get_port(OCR2); if(prescaler_changed&&port==ocr) {clear_tcnt=1;set_flag(OCF2_FLAG);} goto normal_mode; case 0: /* Normal mode */ ocr=get_port(OCR2); normal_mode: add=1; if(prescaler_changed) { if(port==ocr) {compare_set_pin(com,OC2_PIN);set_flag(OCF2_FLAG);} if(max) set_flag(TOV2_FLAG); } else { if(ISFLAG(FOC2_FLAG)) if(get_flag(FOC2_FLAG)) {clear_flag(FOC2_FLAG);compare_set_pin(com,OC2_PIN);} } break; case 1: /* PWM, Phase correct */ if(prescaler_changed) { if(port==ocr) {set_flag(OCF2_FLAG);pwm_compare_set_pin(com,OC2_PIN,add);} if(max) {add=-1;ocr=get_port(OCR2);} if(bottom) {add=1;set_flag(TOV2_FLAG);} } break; case 3: /* Fast PWM Mode */ add=1; if(prescaler_changed) { if(bottom) fpwm_compare_top_set_pin(com,OC2_PIN); if(port==ocr) {set_flag(OCF2_FLAG);fpwm_compare_match_set_pin(com,OC2_PIN);} if(max) {ocr=get_port(OCR2);set_flag(TOV2_FLAG);} } } exit: if(prescaler_changed) { if(clear_tcnt) {set_port(TCNT2,0);clear_tcnt=0;} else add_port(TCNT2,add); }}void prescaler1(void){ prescaler_result1=0; prescaler_value1++; prescaler_result1|=CK1; if(prescaler_value1%8) return; prescaler_result1|=CK8; if(prescaler_value1%32) return; prescaler_result1|=CK32; if(prescaler_value1%64) return; prescaler_result1|=CK64; if(prescaler_value1%128) return; prescaler_result1|=CK128; if(prescaler_value1%256) return; prescaler_result1|=CK256; if(prescaler_value1%1024) return; prescaler_result1|=CK1024; prescaler_value1=0; }void timer_counter1(void){ int cs=0,prescaler_changed=0,coma=0,comb=0,comc=0,pwm_mode=0, bottom,top,max,port; static int t1_pin=0,clear_tcnt=0,add=1; static uint16_t ocr1a,ocr1b,ocr1c; if(!clocks) {t1_pin=clear_tcnt=0;add=1;} if(!ISPORT(TCCR1A)) return; if(get_flag(CS10_FLAG)) cs|=1<<0; if(get_flag(CS11_FLAG)) cs|=1<<1; if(get_flag(CS12_FLAG)) cs|=1<<2; switch(cs) { case 0: return; case 1: prescaler_changed=prescaler_result1&CK1; break; case 2: prescaler_changed=prescaler_result1&CK8; break; case 3: prescaler_changed=prescaler_result1&CK64;break; case 4: prescaler_changed=prescaler_result1&CK256;break; case 5: prescaler_changed=prescaler_result1&CK1024;break; case 6: if(ISPIN(T1_PIN)) { if(t1_pin&&!get_pin(T1_PIN)) prescaler_changed=1; t1_pin=get_pin(T1_PIN); } break; case 7: if(ISPIN(T1_PIN)) { if(!t1_pin&&get_pin(T1_PIN)) prescaler_changed=1; t1_pin=get_pin(T1_PIN); } break; } port=get_port16(TCNT1L,TCNT1H); max=(port==0xFFFF); bottom=(port==0); /* get PWM mode */ if(ISFLAG(WGM10_FLAG)) if(get_flag(WGM10_FLAG)) pwm_mode|=1<<0; if(ISFLAG(WGM11_FLAG)) if(get_flag(WGM11_FLAG)) pwm_mode|=1<<1; if(ISFLAG(WGM12_FLAG)) if(get_flag(WGM12_FLAG)) pwm_mode|=1<<2; if(ISFLAG(WGM13_FLAG)) if(get_flag(WGM13_FLAG)) pwm_mode|=1<<3; if(ISFLAG(PWM10_FLAG)) if(get_flag(PWM10_FLAG)) pwm_mode|=1<<0; if(ISFLAG(PWM11_FLAG)) if(get_flag(PWM11_FLAG)) pwm_mode|=1<<1; if(ISFLAG(CTC1_FLAG)) if(get_flag(CTC1_FLAG)&&!pwm_mode) pwm_mode|=1<<2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -