From f7416f39c9a001b9a29ff581a32f5f1c2cc4c933 Mon Sep 17 00:00:00 2001 From: manu Date: Tue, 24 Dec 2013 11:54:50 +0000 Subject: [PATCH] arduino --- dmx512_v2_ino/dmx512_v2_ino.ino | 344 ++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 dmx512_v2_ino/dmx512_v2_ino.ino diff --git a/dmx512_v2_ino/dmx512_v2_ino.ino b/dmx512_v2_ino/dmx512_v2_ino.ino new file mode 100644 index 0000000..ed6d17a --- /dev/null +++ b/dmx512_v2_ino/dmx512_v2_ino.ino @@ -0,0 +1,344 @@ + + +// definition des fonction cbi sbi idem assembleur +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +// déclaration des tableaux de données +byte tab_input_pc[1026]; // venant du pc +byte tab_input_dmx[534]; // données venant de l'extérieur : les 512 premiers DMX; les 20 suivant 4x8 bp + 16 analogique 8bits ; 1 octet d'etat +// reception +volatile int index_input_pc=0; // entrée serial 0 +volatile int index_output_pc=0; // sortie serial 0 +volatile int index_input_dmx=513; // entrée dmx +volatile int index_output_dmx=0; //sortie dmx -2 en attente de fin de transmission; -1 break; 0 à 512 transmission +volatile int index_output_dmx2=0; //sortie dmx -2 en attente de fin de transmission; -1 break; 0 à 512 transmission +volatile int etat_input_pc=0; // 0 raz ; 1 esc reçu ; 2 D reçu : pret à recevoir ; 3 prèt à emmetre +volatile int start_code_rec=-1; +char key; // caractère reçu serial 0 +int cpt_ana = 0; +int ledPin = 13; // led interne +int tx1pin = 18; // pin DMX serial 1 +int tx2pin = 16; // pin DMX serial 2 + +byte brk_timer_start=181; // def : 150us +byte mab_timer_start=231; //def : 50us +int nb_circuits=512; +int flag_merge1=1; +int flag_merge2=1; + + + +// vecteur d'inéruption pour reception pc + +ISR(USART0_RX_vect) +{ + char c,r; + byte *pb, *pe; + r = UCSR0A; + c = UDR0; + switch (etat_input_pc) { + + case 0: + // on attend un 'esc' pour commencer + if (c==27) { etat_input_pc=1; digitalWrite(ledPin, LOW);break;} + + break; + + case 1: + // on attend 'D' pour recevoir + if (c==68) { + etat_input_pc=2; + index_input_pc=1; + tab_input_dmx[533]=68; + index_output_pc=1; // on init l'index d'emmission vers le pc ( le 0 n'est pas emit => start code) + sbi(UCSR0B, UDRIE0); // activation de l'intéruption registre emmission + } + // Esc 'C' réinit + if (c==67) { + etat_input_pc=0; + + pe=tab_input_pc+1026; + for(pb=tab_input_pc;pb 1024) {// on se prépare à emmetre vers le pc + etat_input_pc=0; + digitalWrite(ledPin, HIGH); + + } + break; + + case 10: // 1er parametre : nb de circuits / 2 - 1 ( de 2 a 512 ) + etat_input_pc++; + //nb_circuits= ((int)c)*2 + 2; + break; + + case 11: // 2nd parametre : duree du break en us + etat_input_pc++; + //brk_timer_start = 255 - (c/2) +1; + break; + + case 12: // 3eme parametre : duree du mab en us + etat_input_pc++; + //mab_timer_start = 255 - (c/2) +1; + break; + + case 13: // 4eme parametre : merge + etat_input_pc=0; + flag_merge1 = c & 1; + flag_merge2 = c/2 & 1; + // on a tout recu, on reponds + tab_input_dmx[533]=66; + index_output_pc=533; // on init l'index d'emmission vers le pc ( uniquement etat : 66 'B' ) + sbi(UCSR0B, UDRIE0); + + break; + default: + // on fait rien + break; + } + +} + + +// vecteur d'intéruption pour reception dmx +ISR(USART1_RX_vect) +{ + char c,r; + r = UCSR1A; + c = UDR1; + if (r & (1< break + if(index_output_dmx==-4) + index_output_dmx=-1; +} +// vecteur : USART 1 transmission registre vide +ISR(USART1_UDRE_vect) +{ + if (index_output_dmx>=0) { //si index >=0 caratère suivant + if (flag_merge1==1) {UDR1 = max(tab_input_pc[index_output_dmx],tab_input_dmx[index_output_dmx]);} + else {UDR1 = tab_input_pc[index_output_dmx];} + index_output_dmx++; + } + // si 512 transmits => mise en attente de fin de transmission + // desactivation de l'intéruption sur le registre + if (index_output_dmx>nb_circuits) {index_output_dmx=-4;cbi(UCSR1B, UDRIE1);} + +} + +// vecteur d'intéruption pour transmission DMX sur serial 2 +// vecteur : USART 1 transmission buffer vide +ISR(USART2_TX_vect) +{ + // si l'USART 2 est vide => break + if(index_output_dmx2==-4) + index_output_dmx2=-1; +} +// vecteur : USART 2 transmission registre vide +ISR(USART2_UDRE_vect) +{ + if (index_output_dmx2>=0) { //si index >=0 caratère suivant + if (flag_merge2==1) {UDR2 = max(tab_input_pc[index_output_dmx2+512],tab_input_dmx[index_output_dmx2]);} + else {UDR2 = tab_input_pc[index_output_dmx2+512];} + index_output_dmx2++; + } + // si 512 transmits => mise en attente de fin de transmission + // desactivation de l'intéruption sur le registre + if (index_output_dmx2>nb_circuits) {index_output_dmx2=-4;cbi(UCSR2B, UDRIE2);} + +} +// vecteur d'intéruption pour transmission vers le pc sur serial 0 +// vecteur registre de transmission +ISR(USART0_UDRE_vect) +{ + //caratère suivant + UDR0 = tab_input_dmx[index_output_pc]; + index_output_pc++; + if (index_output_pc>532) { + cbi(UCSR0B, UDRIE0); + } +} + +ISR(TIMER2_OVF_vect) { + if (index_output_dmx==-2 ) { + digitalWrite(tx1pin, HIGH); // on met la broche 18 à 1 pendant 10 µs + digitalWrite(tx2pin, HIGH); // on met la broche 16 à 1 pendant 10 µs + //digitalWrite(ledPin, HIGH); + index_output_dmx=-3; + index_output_dmx2=-3; + TCNT2 = mab_timer_start ;// RAZ compteur timer + TIFR2 = 0 ; //Clear Flags timer + return; + } + if (index_output_dmx==-3 ) { + sbi(UCSR1B, TXEN1); // on redémarre la transmission + index_output_dmx=0; // on se prépare à émmettre à partir du stat code ( 513 octets ) + sbi(UCSR1B, UDRIE1); // on réactive l'intéruption du registre + + sbi(UCSR2B, TXEN2); // on redémarre la transmission + index_output_dmx2=0; // on se prépare à émmettre à partir du stat code ( 513 octets ) + sbi(UCSR2B, UDRIE2); // on réactive l'intéruption du registre + + TIMSK2 = 0 ; //desactivation intéruption A &B + TCCR2B = 0; + } +} + + +void setup() { + // initialisation du stat code à 0 + tab_input_pc[0]=0; + + // initialisation de la liaison série pc à 0,5MB/s + //Serial.begin(460800); + UCSR0A = 1 << U2X0; + UBRR0H=0; + UBRR0L = 3; + UCSR0C = 6; + + + // initialisation à 250k de serial 1 + // baudrate + UCSR1A = 1 << U2X1; + UBRR1H=0; + UBRR1L = 7; + + // 2 bit de stop; pas de parité; 8 bits de données + UCSR1C = 14; + + + // initialisation à 250k de serial 2 + // baudrate + UCSR2A = 1 << U2X2; + UBRR2H=0; + UBRR2L = 7; + + // 2 bit de stop; pas de parité; 8 bits de données + UCSR2C = 14; + + // activation transmission et intéruption serial 1 + sbi(UCSR1B, RXEN1); //Reception + sbi(UCSR1B, TXEN1); //Transmission + sbi(UCSR1B, RXCIE1); //Interruption sur reception + sbi(UCSR1B, TXCIE1); //Interruption pour fin de transmission + + // activation transmission et intéruption serial 2 + sbi(UCSR2B, TXEN2); //Transmission + sbi(UCSR2B, TXCIE2); //Interruption pour fin de transmission + + sbi(UCSR0B, RXEN0); //Reception + sbi(UCSR0B, RXCIE0); //Interruption sur reception + sbi(UCSR0B, TXEN0); //Transmission + + + // Init convertion analogique pour le premier canal pin0 + ADCSRB = (ADCSRB & ~(1 << MUX5)); + ADMUX = 96; //01100000 reférence sur le 5v et alignement pour lecture sur 8 bits + sbi(ADCSRA, ADSC); + + // init timer break + TIMSK2 = 0; + TCCR2B = 0; + TCCR2A = 0; // 00000000 + ASSR &= ~(1< 2µs + } // fin du break + + // suite du code + tab_input_dmx[513]= PINA; + tab_input_dmx[514]= PINC; + tab_input_dmx[515]=0; + tab_input_dmx[516]=0; + if ( ! bit_is_set(ADCSRA, ADSC)) { + //digitalWrite(ledPin, HIGH); + tab_input_dmx[517+cpt_ana++]=ADCH; + if (cpt_ana>15) cpt_ana=0; + ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((cpt_ana >> 3) & 0x01) << MUX5); + ADMUX = 96 | (cpt_ana & 0x07); + sbi(ADCSRA, ADSC); + } +} + +