[Solved]Attiny13 MicroCore analog read 8 bit and wdt problem

Because the Arduino 1.8.5 did not accept the fuse settings in the boards.txt included in
the attiny13 core from Core13 download | SourceForge.net, I decided to try MicroCode.
No problem setting the fuses: 9.6Mhz, B.O.D 1.8v on the attiny13a.
Also compiling the sketch worked without errors.

However, the adc function I used to read an 8 bit value just returned a fixed value...

After a lot of tests, I did find a solution, but wonder why there is a difference.

Here is a test program which works using the attiny13 core.
When I uncomment the delay(1) just after the while(1) it also works using MicroCore.

Am I missing something?

#define DEBUG

#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>    // Power management
#include <avr/interrupt.h>
#include <avr/wdt.h>      // Watchdog timer
#include <stdlib.h>
#ifdef DEBUG
#include <BasicSerial.h>    //Pin 5 = tx, 115200
#endif

#include <avr/io.h>

#define VOUTPIN  PINB1  

#define wdt_reset()  __asm__ __volatile__ ("wdr")

const uint8_t wt8sec = (1<<WDP3 )|(0<<WDP2 )|(0<<WDP1)|(1<<WDP0);
const uint8_t wt4sec = (1<<WDP3 )|(0<<WDP2 )|(0<<WDP1)|(0<<WDP0);
const uint8_t wt2sec = (0<<WDP3 )|(1<<WDP2 )|(1<<WDP1)|(1<<WDP0);
const uint8_t wt1sec = (0<<WDP3 )|(1<<WDP2 )|(1<<WDP1)|(0<<WDP0);

#ifdef DEBUG
void serOut(const char* str)
{
   while (*str) TxByte (*str++);
}
#endif


// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {
  sleep_enable();
  ADCSRA &= ~(1<<ADEN);                // switch Analog to Digitalconverter OFF
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  power_all_disable();
  sleep_mode();                        // System actually sleeps here
  sleep_disable();
  power_all_enable();
  ADCSRA |= (1<<ADEN);                 // switch Analog to Digitalconverter ON
}


 //Change WDT timeout. Parameter is bit pattern
void wdt_setup(uint8_t wdttime )
{
  cli();
  wdt_reset();
  
   // Start timed sequence 
  WDTCR = (0<<WDTIF) | (0<<WDTIE) |(0<<WDP3) | (1<<WDCE) | (1<<WDE) | (0<<WDP2) | (0<<WDP1) | (0<<WDP0);
  // prescale timer to timeval so we can measure voltage
  // Enable watchdog timer interrupts
  WDTCR = (1<<WDTIF) | (1<<WDTIE) | wdttime | (0<<WDCE) | (0<<WDE);
 
  sei(); // Enable global interrupts
}


void adc_setup (void)
{
    // Set the ADC input to PB2/ADC1, 8 bit only, ref vcc
    ADMUX = (1 << MUX0);
    ADMUX |= (1 << ADLAR);
 
    // Set the prescaler to clock/32 & enable ADC
    // See ATtiny13 datasheet, Table 14.4.
    ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN); 
}

// returns 0 - 255
int adc_read (void)
{
    // Start the conversion
    ADCSRA |= (1 << ADSC);
  
    // Wait for it to finish. 
    while (ADCSRA & (1 << ADSC));

    return ADCH;
}

int main (void)
{
    uint8_t adc_val;

#ifdef DEBUG     
    char buf[8];
#endif
    
    DDRB |= (1<<VOUTPIN);    // set output pin to output mode
    PORTB &= ~(1<<VOUTPIN); // turn on output, low
    DDRB &= ~(1 << PB2);      //Set PB2 as input
    
    adc_setup();

    wdt_setup(wt1sec); 
    
    while(1) {
        //delay(1);               //<-- MicroCode needs this?
        adc_val = adc_read();
#ifdef DEBUG  
        itoa(adc_val,buf,10); 
        serOut("ADC = ");
        serOut(buf);
        serOut(" \n");
#endif
        system_sleep();
    }
    return 0;
}

Hmm, that's strange. Try replacing delay() with _delay_ms()

Maybe I have not expressed myself clearly enough:
When using the MicroCode core, the delay(1) is needed.
When using the attiny13 core it is not needed.

It seems that the adc needs some extra time/action in order to function after a wdt controlled sleep when using the MicroCore.

If a delay(1000) is used in place of the wdt 1 second sleep it also works, probably because the adc is not shutdown in between.

What version of Arduino IDE and what version of avr-gcc are you using with core13?
Have you tried compiling with MicroCore with and without LTO enabled?

Since you're not inializing using void setup() and void loop(), none of the "Arduino functionality" is initialized. My therory is that this may be caused by the compiler or avr-libc, not the MicroCore source code (because you don't make use of it).

The Arduino IDE is 1.8.5 and the avr-gcc version:

~$ avr-gcc -v
Using built-in specs.
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/4.8.2/lto-wrapper
Target: avr
Configured with: ../src/configure -v --enable-languages=c,c++ --prefix=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --bindir=/usr/bin --libexecdir=/usr/lib --libdir=/usr/lib --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-libssp --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=avr
Thread model: single
gcc version 4.8.2 (GCC)

The only change during the tests is the core library used for the attiny13.
And I have tried with and without the LTO. Same results.

The OS is Kubuntu Trusty(14.04). Maybe too old?

Just did a quick test on Kubuntu 17.10 using gcc-version 5.4.0 (GCC).
Same ide version.
Same result using the MicroCore. Only works when using the delay(1).

Solved, had forgotten to add EMPTY_INTERRUPT (WDT_vect);

Adding the delay(1) and after a night sleep, it dawned on me that the attiny13 delay() uses the wdt.
The comment from hansibull about __delay_ms() also helped in getting me on the track.
Indeed, just adding the above ISR and leaving the delay() in place showed a conflict:

wiring.c.o (symbol from plugin): In function `yield':
(.text+0x0): multiple definition of `__vector_8'
/tmp/arduino_build_982341/sketch/attiny13-adc-test.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

Another error 40 solved!