Advice for Beginner PSoC user required

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
StEm_4525871
Level 1
Level 1

Hello,

I am entirely new to programming in any language and have purchased a CY8CKIT-042 Pioneer Kit. I have went through PSoC 101 lessons 1-9.

I have some questions from each lesson that may seem trivial but please humour me.

Lesson 1- Question 1

Parallel programming, after the lesson was finished Alan said you should try something new, for me I flashed different LED's, red then green, then blue. I had the idea to make this sequence.

pastedImage_0.png

Each LED would be flashing on off at a different rate, using the firmware, to do this I would need parallel programming where it would, execute all programs at the same time. I am pretty sure this is possible but cannot find anywhere that shows how it is done. Could you please assist?

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Although you were talking about parallel programming,

my previous samples were quite single-task style.

So today I tried to imitate some parallel programming flavors.

At first I separated doLEDs() function into individual LED handler

do_red(), do_green(), do_blue().

Then I changed the timer to 1ms timer to imitate "tick."

004-schematic.JPG

And for each "tick", I let each handlers take care of their business.

======================

    for(;;) {

        if (pit_flag) {

            do_red(count) ;

            do_green(count) ;

            do_blue(count) ;

            count = (count + 1) % TIMER_PERIOD ;            

            pit_flag = 0 ;

        }

    }

======================

=== led_test_191114A ===

main.c

===============

#include "project.h"

#define LED_ON  (0u)

#define LED_OFF (1u)

#define TIMER_PERIOD 1000

#define RED_PERIOD   1000

#define GREEN_PERIOD  500

#define BLUE_PERIOD   250

volatile int     pit_flag = 0 ;

CY_ISR(timer_isr)

{

    Timer_1ms_ClearInterrupt(Timer_1ms_INTR_MASK_TC) ;

    pit_flag = 1 ;

}

void do_red(int count)

{

    if ((count % RED_PERIOD) < (RED_PERIOD/2)) {

        LED_R_Write(LED_OFF) ;

    } else {

        LED_R_Write(LED_ON) ;

    }

}

void do_green(int count)

{

    if ((count % GREEN_PERIOD) < (GREEN_PERIOD/2)) {

        LED_G_Write(LED_OFF) ;

    } else {

        LED_G_Write(LED_ON) ;

    }

}

void do_blue(int count)

{

    if ((count % BLUE_PERIOD) < (BLUE_PERIOD/2)) {

        LED_B_Write(LED_OFF) ;

    } else {

        LED_B_Write(LED_ON) ;

    }

}

int main(void)

{

    int count = 0 ;

   

    isr_1ms_StartEx(timer_isr) ; /* set isr to the interrupt */

    Timer_1ms_Start() ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

    for(;;) {

        if (pit_flag) {

            do_red(count) ;

            do_green(count) ;

            do_blue(count) ;

            count = (count + 1) % TIMER_PERIOD ;            

            pit_flag = 0 ;

        }

    }

}

===============

=== led_test_191114B ===

But with this approach all handlers were called at once,

so I changed the main()  to slice the timing,

so that each task will be called at different tick timing.

Now task(handlers) are called round-robin style.

main loop of led_test_19114B

=======================

    for(;;) {

        if (pit_flag) {

            switch(task) {

            case 0:

                do_red(count) ;

                task = 1 ;

                break ;

            case 1:

                do_green(count) ;

                task = 2 ;

                break ;

            case 2:

                do_blue(count) ;

                task = 0 ;

                break ;

            default:

                task = 0 ;

                break ;

            }

            count = (count + 1) % TIMER_PERIOD ;            

            pit_flag = 0 ;

        }

    }

=======================

=== led_test_191114C ===

Since I came this far,

I introduced a type "task_type" so that main() can call each member of task_type array.

With this, conceptually any numbers of tasks could be handled,

so this can be a very primitive multi task.

typedef void (*task_type)(int count) ;

main() of led_test_191114C

========================

int main(void)

{

    int count = 0 ;

    int task_no = 0 ;

    task_type task[] = { do_red, do_green, do_blue } ;

    int num_task = sizeof(task) / sizeof(task_type) ;

   

    isr_1ms_StartEx(timer_isr) ; /* set isr to the interrupt */

    Timer_1ms_Start() ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

    for(;;) {

        if (pit_flag) {

            task[task_no](count) ;

            task_no = (task_no + 1) % num_task ;

            count = (count + 1) % TIMER_PERIOD ;            

            pit_flag = 0 ;

        }

    }

}

========================

main.c (led_test_191114C)

==========================

#include "project.h"

#define LED_ON  (0u)

#define LED_OFF (1u)

#define TIMER_PERIOD 1000

#define RED_PERIOD   1000

#define GREEN_PERIOD  500

#define BLUE_PERIOD   250

volatile int     pit_flag = 0 ;

typedef void (*task_type)(int count) ;

CY_ISR(timer_isr)

{

    Timer_1ms_ClearInterrupt(Timer_1ms_INTR_MASK_TC) ;

    pit_flag = 1 ;

}

void do_red(int count)

{

    if ((count % RED_PERIOD) < (RED_PERIOD/2)) {

        LED_R_Write(LED_OFF) ;

    } else {

        LED_R_Write(LED_ON) ;

    }

}

void do_green(int count)

{

    if ((count % GREEN_PERIOD) < (GREEN_PERIOD/2)) {

        LED_G_Write(LED_OFF) ;

    } else {

        LED_G_Write(LED_ON) ;

    }

}

void do_blue(int count)

{

    if ((count % BLUE_PERIOD) < (BLUE_PERIOD/2)) {

        LED_B_Write(LED_OFF) ;

    } else {

        LED_B_Write(LED_ON) ;

    }

}

int main(void)

{

    int count = 0 ;

    int task_no = 0 ;

    task_type task[] = { do_red, do_green, do_blue } ;

    int num_task = sizeof(task) / sizeof(task_type) ;

   

    isr_1ms_StartEx(timer_isr) ; /* set isr to the interrupt */

    Timer_1ms_Start() ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

    for(;;) {

        if (pit_flag) {

            task[task_no](count) ;

            task_no = (task_no + 1) % num_task ;

            count = (count + 1) % TIMER_PERIOD ;            

            pit_flag = 0 ;

        }

    }

}

==========================

If you want to go further, you may want to refer and study Bob-san's master piece,

Real-tiime OS "ARTS"

moto

View solution in original post

0 Likes
4 Replies