<!-- Embedded C Code for Traffic Signal Control -->

#include <rtx51tny.h>
#include <reg51.h>

                          // For Direction 1
sbit  r1          = P1^0;             /* I/O Pin:  red    output        */
sbit  y1          = P1^1;             /* I/O Pin:  yellow output        */
sbit  g1          = P1^2;             /* I/O Pin:  green  output        */
sbit  stop1   = P1^3;             /* I/O Pin:  stop   output        */
sbit  walk1   = P1^4;             /* I/O Pin:  walk   output        */
sbit  Sensor1 = P1^5;             /* I/O Pin:  sensor input         */
                         // For Direction 2
sbit  r2          = P2^0;             /* I/O Pin:  red    output        */
sbit  y2          = P2^1;             /* I/O Pin:  yellow output        */
sbit  g2          = P2^2;             /* I/O Pin:  green  output        */
sbit  stop2   = P2^3;             /* I/O Pin:  stop   output        */
sbit  walk2   = P2^4;             /* I/O Pin:  walk   output        */
sbit  Sensor2 = P2^5;             /* I/O Pin:  sensor input         */

#define t_interval 1000000              /* predefined time duration             */

/********************************************************************/ 
/*                                      Input Controls                                                              */
/*                                                                                                                                  */
/*  'X'    - Button1 (Pedestrain walk request) - Serial Port                */      
/*  'Y'    - Button2 (Pedestrain walk request) - Serial Port                */
/*  P1.5   - Sensor1 (Car incoming) - IO Port                                               */
/*  P2.5   - Sensor2 (Car incoming) - IO Port                                               */
/********************************************************************/

unsigned char ch;                                   
long int i;                                             
bit flag1, flag2;                                   

unsigned char msg1[]  = "Sensor1 triggered\n";
unsigned char msg2[]  = "Sensor2 triggered\n";
unsigned char msg3[]  = "Button1 triggered\n";
unsigned char msg4[]  = "Button2 triggered\n";

void send(unsigned char c) {            // scom subroutine
    SBUF = c;                                               
    while(TI == 0);
    TI = 0;
}

void job0 (void) _task_ 0 {
    P1 = 0X00;
    P2 = 0X00;
    SCON = 0x50;                                        // scom config
    TMOD = 0x20;
    TH1 = 0xFA;
    TR1 = 1;
    
    r1=1; y1=0; g1=0;                               // initialization (idle state) 
    stop1=1; walk1=0; Sensor1=0;
    r2=1; y2=0; g2=0; 
    stop2=1; walk2=0;   Sensor2=0;
    
    os_create_task(1);                          // create task 1
    os_create_task(2);                          // create task 2
    os_create_task(3);                          // create task 3
    os_send_signal(0);
    
    while(1){
        os_wait(K_SIG, 0, 0);
        os_send_signal(1);                      // activate task 1
    }
}

void job1 (void) _task_ 1 {             // for direction 1
    while(1) {
        os_wait(K_SIG, 0, 0);
    
        if(!Sensor1)                                    // detecting rising edge (@sensor1)
            flag1=1;
        if(Sensor1 && flag1 && r2==1) {
            for(i=0; i<18; i++)                 // sending ack message
                send(msg1[i]);  
            
            flag1=0;                                        // handling signals
            r1=0; y1=1;                                 
            for(i=0; i<t_interval; i++);
            y1=0; g1=1; walk1=1; stop1=0;
            for(i=0; i<t_interval; i++);
            r1=1; g1=0; walk1=0; stop1=1;
        }
        os_send_signal(2);
    }
}

void job2 (void) _task_ 2 {             // for direction 2
    while(1) {
        os_wait(K_SIG, 0, 0);
    
        if(!Sensor2)
            flag2=1;
        if(Sensor2 && flag2 && r1==1) { 
            for(i=0; i<18; i++)
                send(msg2[i]);  
            
            flag2=0;
            r2=0; y2=1;
            for(i=0; i<t_interval; i++);
            y2=0; g2=1; walk2=1; stop2=0;
            for(i=0; i<t_interval; i++);
            r2=1; g2=0; walk2=0; stop2=1;
        }
        os_send_signal(3);
    }
}
        
void job3 (void) _task_ 3 {
    while(1) {
        os_wait(K_SIG, 0, 0);
    
        ch=0;
        if(RI==1) {                                 // checking for sensor signal
            ch=SBUF;
            RI=0;
            
            if(ch=='X' && r2==1) {      // Button 1
                    for(i=0; i<18; i++)
                        send(msg3[i]);
                
                    stop1=0; walk1=1;
                    for(i=0; i<t_interval; i++);
                    stop1=1; walk1=0;
            }
            
            if(ch=='Y' && r1==1) {      // Button 2
                    for(i=0; i<18; i++)
                        send(msg4[i]);
                
                    stop2=0; walk2=1;
                    for(i=0; i<t_interval; i++);
                    stop2=1; walk2=0;
            }
        }
        os_send_signal(0);      
    }
}