/* Copyright © 2020 tyrolyean * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "avr.h" #include "dac.h" #include "structures.h" #include uint8_t dac_mode = DAC_MODE_SINE; int16_t dac_frequency_deviation = 0; void write_to_dac(uint8_t addr, uint8_t data){ set_addr(addr); DATA_DDR_REG = 0xFF; DATA_REG = data; CTRL_REG &= ~(1< the frequency made lower from baseline */ static int16_t freq_delay_cnt = 0x00; switch(dac_mode){ default: case DAC_MODE_SILENT: for(uint8_t i = 0; i < 0xFF; i++){ write_to_dac(i%2, 0); } break; case DAC_MODE_SINE: /* Generates a sine from a predetermined sine table in program * space */ for(uint8_t i = 0; i < (0xFF/2); i++){ write_to_dac(1, pgm_read_byte(&sine_table[threash])); write_to_dac(0, pgm_read_byte(&sine_table[threash])); if(dac_frequency_deviation >=0){ freq_delay_cnt++; if(freq_delay_cnt >= dac_frequency_deviation){ freq_delay_cnt = 0; threash++; } }else{ threash -= dac_frequency_deviation; } } break; case DAC_MODE_SQUARE: /* Generates a square wave tone */ for(uint8_t i = 0; i < (0xFF/2); i++){ if(threash > (0xFF/2)){ write_to_dac(0, 0xFF); write_to_dac(1, 0xFF); }else{ write_to_dac(0, 0); write_to_dac(1, 0); } if(dac_frequency_deviation >=0){ freq_delay_cnt++; if(freq_delay_cnt >= dac_frequency_deviation){ freq_delay_cnt = 0; threash++; } }else{ threash -= dac_frequency_deviation; } } break; case DAC_MODE_SAW: /* Generates a saw wave tone */ for(uint8_t i = 0; i < (0xFF/2); i++){ write_to_dac(0, threash); write_to_dac(1, threash); if(dac_frequency_deviation >=0){ freq_delay_cnt++; if(freq_delay_cnt >= dac_frequency_deviation){ freq_delay_cnt = 0; threash++; } }else{ threash -= dac_frequency_deviation; } } break; case DAC_MODE_NOISE: /* Generates white noise from a predetermined LUT */ for(uint8_t i = 0; i < (0xFF/2); i++){ static uint16_t noise_cnt = 0; write_to_dac(1, pgm_read_byte(&noise_table[noise_cnt])); write_to_dac(0, pgm_read_byte(&noise_table[noise_cnt])); noise_cnt++; /* Doesn't have frequency diversion */ if(noise_cnt >= 1024){ noise_cnt = 0; } } break; case DAC_MODE_TRIANGLE: /* Generates a triangle wave tone */ for(uint8_t i = 0; i < (0xFF/2); i++){ static int8_t direction = 1; if((threash == 0xFF) | !threash){ direction = -direction; } write_to_dac(0, threash); write_to_dac(1, threash); if(dac_frequency_deviation >=0){ freq_delay_cnt++; if(freq_delay_cnt >= dac_frequency_deviation){ freq_delay_cnt = 0; threash += direction; } }else{ if((dac_frequency_deviation * direction) > (0xFF - threash)){ threash = 0xFF; continue; } threash = (dac_frequency_deviation * direction); } } break; } return; } void routine_dac(){ uint8_t received = read_from_dac(0x00); if(!(received & (0x01<<0))){ feed_dac(); } return; }