#include //I-O registers #include #include //_delay_ms #define NB_TICK 104 //1563 #define CPU_FREQ 16000000L //Frequence du CPU #define QUANTUM_ms 10 #define SAVE_CONTEXT() \ asm volatile ( \ "push r0 \n\t" \ "in r0, __SREG__ \n\t" \ "cli \n\t" \ "push r0 \n\t" \ "push r1 \n\t" \ "clr r1 \n\t" \ "push r2 \n\t" \ "push r3 \n\t" \ "push r4 \n\t" \ "push r5 \n\t" \ "push r6 \n\t" \ "push r7 \n\t" \ "push r8 \n\t" \ "push r9 \n\t" \ "push r10 \n\t" \ "push r11 \n\t" \ "push r12 \n\t" \ "push r13 \n\t" \ "push r14 \n\t" \ "push r15 \n\t" \ "push r16 \n\t" \ "push r17 \n\t" \ "push r18 \n\t" \ "push r19 \n\t" \ "push r20 \n\t" \ "push r21 \n\t" \ "push r22 \n\t" \ "push r23 \n\t" \ "push r24 \n\t" \ "push r25 \n\t" \ "push r26 \n\t" \ "push r27 \n\t" \ "push r28 \n\t" \ "push r29 \n\t" \ "push r30 \n\t" \ "push r31 \n\t" \ ); #define RESTORE_CONTEXT() \ asm volatile ( \ "pop r31 \n\t" \ "pop r30 \n\t" \ "pop r29 \n\t" \ "pop r28 \n\t" \ "pop r27 \n\t" \ "pop r26 \n\t" \ "pop r25 \n\t" \ "pop r24 \n\t" \ "pop r23 \n\t" \ "pop r22 \n\t" \ "pop r21 \n\t" \ "pop r20 \n\t" \ "pop r19 \n\t" \ "pop r18 \n\t" \ "pop r17 \n\t" \ "pop r16 \n\t" \ "pop r15 \n\t" \ "pop r14 \n\t" \ "pop r13 \n\t" \ "pop r12 \n\t" \ "pop r11 \n\t" \ "pop r10 \n\t" \ "pop r9 \n\t" \ "pop r8 \n\t" \ "pop r7 \n\t" \ "pop r6 \n\t" \ "pop r5 \n\t" \ "pop r4 \n\t" \ "pop r3 \n\t" \ "pop r2 \n\t" \ "pop r1 \n\t" \ "pop r0 \n\t" \ "out __SREG__, r0 \n\t" \ "pop r0 \n\t" \ ); /* protocole de communication choisi 16u2 vers 328p (led) -> 1 bit = état d'une led 328p vers 16u2 (boutons + joysticks) -> enfonction du bit 7 : à 0 : boutons puis un bit = état du bouton à 1 : joysticks -> bit 6 = direction x ou y puis le reste, la valeur sur 6 bits */ struct task{ uint16_t sp_vise; uint8_t state; }; uint8_t cpt = 0; uint8_t premier_lancement = 0; struct task lecture_boutons = {0x300, 0}; struct task lecture_joystick = {0x0500, 0}; struct task affiche_led = {0x0700, 0}; //debug void init_debug(void)//permet de detecter un reboot { DDRB |= 0x1F; PORTB |= 0xFF; _delay_ms(300); PORTB &= 0x00; } //gestion de la liaison serie void init_serial(int speed) { UBRR0 = CPU_FREQ/(((unsigned long int)speed)<<4)-1;//Set baud rate UCSR0B = (1< CLK/1024 prescaler TCCR1B |= _BV(CS10); OCR1A = NB_TICK; TIMSK1 |= _BV(OCIE1A); } //gestion de l'initialisation des differentes taches void init_tasks(void) { DDRD |= 0x00; PORTD |= 0xFF; DDRB |= 0b00111111; } //gestion de l'execution des differentes taches void task_lecture_boutons(void) { uint8_t tmp = 0x00; uint8_t tmp2; while(1){ tmp2 = 0x00; if((PIND&(1<<2)) == 0) tmp2 |= 0b00000001; if((PIND&(1<<3)) == 0) tmp2 |= 0b00000010; if((PIND&(1<<4)) == 0) tmp2 |= 0b00000100; if((PIND&(1<<5)) == 0) tmp2 |= 0b00001000; if((PIND&(1<<6)) == 0) tmp2 |= 0b00010000; if(tmp2 != tmp) { send_serial(tmp2); tmp = tmp2; } _delay_ms(QUANTUM_ms); } } void task_lecture_joystick(void) { uint8_t tmp = ADC_read(0)>>4;//code sur 6 bits (2 bits de descriptions necessaires) uint8_t tmp2 = ADC_read(1)>>4; uint8_t test = 0; uint8_t tmp3; uint8_t tmp4; while(1){ tmp3 = ADC_read(0)>>4; tmp4 = ADC_read(1)>>4; if(test == 0 && tmp3 != tmp) { send_serial(tmp3 | 0b10000000); tmp = tmp3; } else if(test == 1 && tmp4 != tmp2) { send_serial(tmp4 | 0b11000000); tmp2 = tmp4; } if(test == 0) test = 1; else test = 0; _delay_ms(QUANTUM_ms); } } void task_affiche_led(void) { while(1){ PORTB = get_serial(); _delay_ms(QUANTUM_ms); } } //gestion du contexte ISR(TIMER1_COMPA_vect) { if(premier_lancement==0) { premier_lancement+= 1; sei(); SP = affiche_led.sp_vise; task_affiche_led(); } else if(premier_lancement==1) { SAVE_CONTEXT(); affiche_led.sp_vise = SP; premier_lancement+=1; sei(); SP = lecture_joystick.sp_vise; task_lecture_joystick(); } else if(premier_lancement==2) { SAVE_CONTEXT(); lecture_joystick.sp_vise = SP; premier_lancement+=1; sei(); SP = lecture_boutons.sp_vise; task_lecture_boutons(); } else { if(cpt==0) { SAVE_CONTEXT(); lecture_boutons.sp_vise = SP; SP = affiche_led.sp_vise; RESTORE_CONTEXT(); cpt++; } else if(cpt==1) { SAVE_CONTEXT(); affiche_led.sp_vise = SP; SP = lecture_joystick.sp_vise; RESTORE_CONTEXT(); cpt++; } else if(cpt==2) { SAVE_CONTEXT(); lecture_joystick.sp_vise = SP; SP = lecture_boutons.sp_vise; RESTORE_CONTEXT(); cpt = 0; } } sei(); } int main(void) { init_debug();//allume toutes les leds au reset init_serial(9600); init_ADC(); init_timer(); init_tasks(); sei(); while(1) {} return 0; }