?? pmbus
字號(hào):
#elif F_CPU == 4000000X /* divide-by-2 */X CLKPR = _BV(CLKPCE);X CLKPR = 1;#elif F_CPU == 2000000X /* divide-by-4 */X CLKPR = _BV(CLKPCE);X CLKPR = 2;#elif F_CPU == 1000000X /* we're all set */#else#error Unsupported clock rate F_CPU Hz#endifXX /* Port A:X * - PA0 = ... DEBUG/J2.3 (bicolor led drive; RED or GREEN)X * - PA1 = voltage divider (revision, bits 2..0)X * - PA2 = voltage divider (revision, bits 5..3)X * - PA3 = voltage divider (1V8)X * - PA4 = I2C SCLX * - PA5 = ... DEBUG (unused; OC1B)X * - PA6 = I2C SDAX * - PA7 = voltage divider (3V3)X *X * Only the two I2C pins need digital (input) buffers.X * PA4/PA5/PA6 are also used for ISP (with PB3/nRST).X */X DIDR0 = _BV(PA7) | _BV(PA5) | _BV(PA3)X | _BV(PA2) | _BV(PA1) | _BV(PA0);X#ifdef LEDSX DDRA |= _BV(PA0);X PORTA |= _BV(PA0);#endifXX /* Port B:X * - PB0 = ... DEBUG/J2.5 (active-high orange led)X * - PB1 = ... DEBUG/J2.1 (bicolor led drive)X * - PB2 = SMBUSALERT#X * - PB3 = nRST/dWX *X * Enable pullups on everything except nRST, which is usedX * for ISP as well as DebugWire.X *X * NOTE that the NGW schematics don't quite reflect realityX * on the ATtiny page ... R27 isn't populated. That meansX * the AVR32 can't trigger hard resets by GPIO (or thus,X * recover fully from watchdog resets).X *X * Also: to use DebugWire you've got to remove R28, so theX * capacitor on the MCU reset line doesn't interfere.X */X PORTB = _BV(PB2) | _BV(PB1) | _BV(PB0);#ifdef LEDSX DDRB = _BV(PB1) | _BV(PB0);#endifXX /* TIMER1 -- CTC mode, prescaler divides by 1024, tick ~2 HzX * Oddly enough, this 16-bit timer is documented as using lessX * power than the 8-bit timer0.X *X * We want periodic ticks to pet the watchdog. Doing it withX * a timer has a downside that we can't enter powerdown mode.X * Spending 0.25 mA (extra cost of idle mode at 4 MHz) seemsX * OK for now. It makes debugging easier than using watchdogX * IRQs and switching between idle (when the ADC is active)X * and powerdown sleep modes.X */X OCR1A = (F_CPU / 1024) / (2 /* HZ */);X TCCR1A = 0;X TCCR1B = _BV(WGM12) | _BV(CS12) | _BV(CS10);XX /* turn off unused modules */X ACSR = _BV(ACD);#ifndef DEBUGX PRR |= _BV(PRTIM0);#endif}X/*-------------------------------------------------------------------------*/X#define ADPS_DIV2 (_BV(ADPS0))#define ADPS_DIV4 (_BV(ADPS1))#define ADPS_DIV8 (_BV(ADPS1)|_BV(ADPS0))#define ADPS_DIV16 (_BV(ADPS2))#define ADPS_DIV32 (_BV(ADPS2)|_BV(ADPS0))#define ADPS_DIV64 (_BV(ADPS2)|_BV(ADPS1))#define ADPS_DIV128 (_BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0))X/* ADC sample frequency should be between 50-200 KHz. Pick the fastestX * sample frequency (smallest divisor) we can use ... we know that theX * lowest clock is 200 KHz (for I2C), so we can never fail here.X */static inline u8 adc_ps(void){X u8 div = (u8) (F_CPU/200000);XX if (div <= 2)X return ADPS_DIV2;X else if (div > 2 && div <= 4)X return ADPS_DIV4;X else if (div > 4 && div <= 8)X return ADPS_DIV8;X else if (div > 8 && div <= 16)X return ADPS_DIV16;X else if (div > 16 && div <= 32)X return ADPS_DIV32;X else if (div > 32 && div <= 64)X return ADPS_DIV64;X elseX return ADPS_DIV128;}X/* Resistor ladder values:X * DIGIT R(gnd), R(3v3) 8bit ADCX * 0 10k, 470 0x0bX * 1 10k, 1k 0x17X * 2 10k, 1k5 0x21X * 3 10k, 2k7 0x36X * 4 10k, 5k6 0x5bX * 5 10k, 10k 0x80X * 6 4k2, 10k 0xb4X * 7 470, 10k 0xf4X *X * Since the resistors are imperfect, we'll match each digit withX * ADC measurements up to half the way to the next ladder.X */static u8 cvt[7] PROGMEM = {X 0x11, 0x1c, 0x2b, 0x48, 0x6d, 0x9a, 0xd4,};X/* GCC 4.3.0 wrongly wants to inline this at "-Os" ... */static u8 rcode(u8 value) __attribute__((noinline));Xstatic u8 rcode(u8 value){X prog_uint8_t *vp;X u8 code, v;XX for (code = 0, vp = cvt; code < 7; code++) {X v = pgm_read_byte(vp++);X if (value < v)X break;X }X return code;}Xstatic inline void adc_setup(void){X u8 sr = _BV(ADEN) | _BV(ADSC) | adc_ps();X u8 r;XX /* 8-bit samples are enough to see board revision */X ADCSRB = _BV(ADLAR);XX /* first/long conversion for low 3 bits (ADC1) vs Vcc */X ADMUX = 1;X ADCSRA = sr;X while (ADCSRA & _BV(ADSC))X continue;X r = rcode(ADCH);XX /* shorter conversion for next 3 bits (ADC2) vs Vcc */X ADMUX = 2;X ADCSRA = sr;X while (ADCSRA & _BV(ADSC))X continue;X board_revision = r | (rcode(ADCH) << 3);XX /* use 10-bit samples from now on; prime pump with aX * temperature sample (against 1.1V ref, it's ready now).X */X ADCSRB = 0;X ADMUX = _BV(REFS1) | 0x22;X ADCSRA = sr | _BV(ADIE);}X/*-------------------------------------------------------------------------*/Xstatic u8 adc_index;XISR(ADC_vect){X u16 sample = ADC;XX switch (adc_index) {X case 0:X adc_temp = sample;X /* next is ADC7/3v3, against 1v1 */X ADMUX = _BV(REFS1) | 7;X break;#if 0X case 1:X adc_3v3 = sample;X /* next is ADC3/1v8, against 1v1 */X ADMUX = _BV(REFS1) | 3;X break;X default:X adc_1v8 = sample;#elseX default:X adc_3v3 = sample;#endifX /* REVISIT to save power, turn off ADC and make timer1X * restart it (and vREF) for the next set of samples;X * OR drive it by watchdog IRQ, and enter power-down.X */XX /* next is ADC8/temp, against 1v1 */X ADMUX = _BV(REFS1) | 0x22;X adc_index = 0;X return;X }X adc_index++;}X/*-------------------------------------------------------------------------*/XISR(TIM1_COMPA_vect, ISR_NAKED){#ifndef DEBUGX wdt_reset();#endif#ifdef LEDSX PINB = _BV(PB0); /* toggle orange led */#endifX reti();}X/*-------------------------------------------------------------------------*/Xint main(void)X /* should be void and noreturn ... */X __attribute__ ((naked));Xint main(void){X u16 offset;XX /* Use per-chip temperature offset data, if we have it ... else useX * offset computed from "typical" values in datasheet (table 16-2).X */X offset = eeprom_read_word(&ee_temp_offset);X if (!offset || ((u16)offset) == 0xffff)X offset = 300 - 25;X temp_offset = offset;XX /* setup I2C */X usi_i2c_slave();XX /* read board revision; prime the ADC conversion pump */X adc_setup();XX /* listen to timer1 ticking (at 2+ Hz) */X TIMSK1 = _BV(OCIE1A);X#ifndef DEBUGX /* maybe enable watchdog resets after a second ... */X WDTCSR = _BV(WDE) | _BV(WDP2) | _BV(WDP1);#endifXX sei();XX /* Normally, sleep in idle ... we need to wake from sleep on USIX * "start". ATtinyX4 docs are confused on that point; USI wakesX * only from idle per the PM docs, but also from power-down perX * the USI docs (start detect).X *X * We kick in ADC "Noise Cancelation" mode here in most cases; anX * ADC conversion will start as soon as we sleep, and with lessX * noise coming from the CPU core.X */X MCUCR = _BV(SE);X for (;;) {X sleep_cpu();X }}SHAR_EOF (set 20 08 04 25 02 03 02 'main.c'; eval "$shar_touch") && chmod 0644 'main.c' || $echo 'restore of' 'main.c' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'main.c:' 'MD5 check failed'a87fac952454779ada749451348d4875 main.cSHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'main.c'`" test 11893 -eq "$shar_count" || $echo 'main.c:' 'original size' '11893,' 'current size' "$shar_count!" fifi# ============= pmbus.c ==============if test -f 'pmbus.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'pmbus.c' '(file already exists)'else $echo 'x -' extracting 'pmbus.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'pmbus.c' &&/*X * pmbus.c - protocol logic for AVR8 PMBus 1.1 slaveX * Part of PMBus device firmwareX *X * Copyright (C) 2008 David BrownellX *X * This program is free software: you can redistribute it and/or modifyX * it under the terms of the GNU General Public License as published byX * the Free Software Foundation, either version 3 of the License, orX * (at your option) any later version.X *X * This program is distributed in the hope that it will be useful,X * but WITHOUT ANY WARRANTY; without even the implied warranty ofX * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theX * GNU General Public License for more details.X *X * You should have received a copy of the GNU General Public LicenseX * along with this program. If not, see <http://www.gnu.org/licenses/>.X */#include <string.h>X#include <avr/io.h>#include <avr/eeprom.h>#include <avr/pgmspace.h>X#include <ut
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -