/*
 * A simple library for implementing preemptive threads for AVR.
 *
 * (C)2026 St(u)dio of Computer Games
 * Alexander Ozumenko <scg@stdio.ru>
 */

#ifndef AVR_THREAD_H_INCLUDED
#define AVR_THREAD_H_INCLUDED



#include <avr/io.h>
#include <avr/interrupt.h>

#include <stdint.h>
#include <stdbool.h>
#include <setjmp.h>



/*** Defines */

#define ALIVE_PERIOD            60000           // 60s * 1000ucs

#define TH_MAX             		7
#define TH_STACK_SIZE         	512

#define TH_TIMER_PRESCALER    	(256L * 128)
#define TH_MSEC_TO_TICKS(ms)  	(((ms) * (F_CPU / TH_TIMER_PRESCALER)) / 1000)
#define TH_SEC_TO_TICKS(s)    	((s) * (F_CPU / TH_TIMER_PRESCALER))



/*** Types declarations */

typedef struct period_s {
    uint16_t start;
    uint16_t end;
} period_t;

typedef void (* volatile  th_proc)(void);

typedef enum th_state_e {
    TH_STATE_STOP = 0,
    TH_STATE_RUN,
    TH_STATE_DELAY,
    TH_STATE_SLEEP,
} th_state_t;

typedef struct {
    uint8_t stack[TH_STACK_SIZE];
    jmp_buf env;
    th_proc proc;
    th_state_t state;
    period_t period;
} th_ctx_t;



/*** Functions for measuring periods */

inline void period_start(period_t *period, uint16_t ticks);
inline bool period_expired(period_t *period);
inline uint16_t period_left(period_t *period);


/*** Interface functions */

void th_init();
int8_t th_spawn(th_proc proc);
void th_sched();
void th_wakeup(int th_id);

void th_yield();
void th_delay(uint16_t ticks);
void th_sleep();



#endif // AVR_THREAD_H_INCLUDED
