diff --git a/02-timers/main.c b/02-timers/main.c index ff2c808..eeab398 100644 --- a/02-timers/main.c +++ b/02-timers/main.c @@ -19,6 +19,11 @@ void message_callback(void *argument) } /* [TASK 3: insert your callback function here] */ +void led_callback(void *argument) +{ + (void) argument; + LED1_ON; +} int main(void) { @@ -31,16 +36,19 @@ int main(void) ztimer_set(ZTIMER_SEC, &timeout, 2); /* set the timer to trigger in 2 seconds */ /* [TASK 3: insert your timer here] */ + ztimer_t led_timeout; + led_timeout.callback = led_callback; + ztimer_set(ZTIMER_SEC, &led_timeout, 1); /* in parallel, we can perform other tasks on this thread */ /* get the current timer count */ ztimer_now_t start = ztimer_now(ZTIMER_MSEC); /* blink an LED for 10 seconds */ - while ((ztimer_now(ZTIMER_MSEC) - start) <= 10000) { + while ((ztimer_now(ZTIMER_MSEC) - start) <= 5000) { /* this blinks the LED twice a second */ LED0_TOGGLE; - ztimer_sleep(ZTIMER_MSEC, 500); + ztimer_sleep(ZTIMER_MSEC, 250); } puts("Done!"); diff --git a/03-shell/main.c b/03-shell/main.c index fcf166e..cff785c 100644 --- a/03-shell/main.c +++ b/03-shell/main.c @@ -10,8 +10,28 @@ #include #include "shell.h" +#include "board.h" +#include "stdlib.h" /* [TASK 2: add command handler here] */ +int toggle_command(int argc, char **argv) +{ + /* check that the command is called correctly (no extra arguments) */ + if (argc != 2) { + printf("usage: %s ", argv[0]); + return 1; + } + + /* toggle the LED */ + int number = atoi(argv[1]); + if (number == 0) { + LED0_TOGGLE; + } else if (number == 1) { + LED1_TOGGLE; + } + + return 0; +} int echo_command(int argc, char **argv) { @@ -30,6 +50,7 @@ int echo_command(int argc, char **argv) /* [TASK 2: register your new command here] */ SHELL_COMMAND(echo,"Echo a message",echo_command); +SHELL_COMMAND(toggle, "Toggle LED 0 or 1", toggle_command); int main(void) { diff --git a/04-saul/main.c b/04-saul/main.c index 503a3a3..95d273b 100644 --- a/04-saul/main.c +++ b/04-saul/main.c @@ -13,7 +13,10 @@ #include "saul_reg.h" #include "board.h" -#define TEMPERATURE_THRESHOLD 2600 /* factor of 10^-3 */ +#define TEMPERATURE_THRESHOLD 2700 /* factor of 10^-3 */ +#define ACCEL_TOP_THRESHOLD -1100 +#define ACCEL_BOTTOM_THRESHOLD -900 + int main(void) { @@ -29,7 +32,8 @@ int main(void) printf("Found temperature device: %s\n", temp_sensor->name); } - /* [TASK 3: find your device here] */ + /* [TASK 2: find your device here] */ + saul_reg_t *accel_sensor = saul_reg_find_type(SAUL_SENSE_ACCEL); /* record the starting time */ ztimer_now_t last_wakeup = ztimer_now(ZTIMER_MSEC); @@ -44,19 +48,36 @@ int main(void) } /* dump the read value to STDIO */ - phydat_dump(&temperature, dimensions); + /*phydat_dump(&temperature, dimensions);*/ + + /* [TASK 2: perform the acceleration read here ] */ + phydat_t acceleration; + int acc_dim = saul_reg_read(accel_sensor, &acceleration); + if (acc_dim < 1) { + puts("Error reading a value from the device"); + break; + } - /* [TASK 3: perform the acceleration read here ] */ + phydat_dump(&acceleration, acc_dim); + + /* check if board is flipped 180 degrees*/ + if ((ACCEL_TOP_THRESHOLD <= acceleration.val[2]) && (acceleration.val[2] <= ACCEL_BOTTOM_THRESHOLD)) + { + LED2_ON; + } + else { + LED2_OFF; + } /* check if the temperature value is above the threshold */ - if (temperature.val[0] >= TEMPERATURE_THRESHOLD) { + /* if (temperature.val[0] >= TEMPERATURE_THRESHOLD) { LED0_ON; LED1_OFF; } else { LED0_OFF; LED1_ON; - } + } */ /* wait for 500 ms */ ztimer_periodic_wakeup(ZTIMER_MSEC, &last_wakeup, 500); diff --git a/05-gpios/main.c b/05-gpios/main.c index cc50036..111a07f 100644 --- a/05-gpios/main.c +++ b/05-gpios/main.c @@ -10,13 +10,49 @@ #include "board.h" #include "ztimer.h" +#include "periph/gpio.h" /* [TASK 2: define button and led1 here] */ +/*Init LED0*/ +gpio_t led0 = GPIO_PIN(PORT_D, 6); +gpio_mode_t led0_mode = GPIO_OUT; + + +/*Init LED1*/ +gpio_t led1 = GPIO_PIN(PORT_D, 4); +gpio_mode_t led1_mode = GPIO_OUT; + + +/*Init S2 Button*/ +gpio_t button = GPIO_PIN(PORT_D, 1); + +void button_callback (void *arg) +{ + (void) arg; + if (!gpio_read(button)) { + gpio_clear(led1); + } + else { + gpio_set(led1); + } +} int main(void) { puts("GPIOs example."); + gpio_init(led0, led0_mode); + gpio_init(led1, led1_mode); + + gpio_set(led0); + + gpio_init_int(button, GPIO_IN_PU, GPIO_BOTH, button_callback, NULL); + + /* while (1) { + gpio_toggle(led0); + ztimer_sleep(ZTIMER_MSEC, 500); + } */ + return 0; } diff --git a/06-threads/main.c b/06-threads/main.c index 32d1194..af615c9 100644 --- a/06-threads/main.c +++ b/06-threads/main.c @@ -13,6 +13,24 @@ #include "thread.h" /* [TASK 1: create the thread handler and stack here] */ +char blinky_stack[THREAD_STACKSIZE_DEFAULT]; /* Stack for the thread */ + +void *blinky_handler(void *arg) +{ + (void) arg; /* argument not used */ + + /* get the current thread descriptor */ + thread_t * this_thread = thread_get_active(); + + /* get the thread name */ + const char *this_thread_name = thread_get_name(this_thread); + + while (1) { + printf("Thread %s\n", this_thread_name); + LED1_TOGGLE; + ztimer_sleep(ZTIMER_MSEC, 250); + } +} int main(void) { @@ -22,6 +40,15 @@ int main(void) const char *this_thread_name = thread_get_name(this_thread); /* [TASK 1: create the thread here] */ + thread_create( + blinky_stack, + sizeof(blinky_stack), + THREAD_PRIORITY_MAIN - 1, + THREAD_CREATE_STACKTEST, + blinky_handler, + NULL, + "blinky" + ); while (1) { printf("Thread %s\n", this_thread_name); diff --git a/07-events/main.c b/07-events/main.c index 520f51c..b9ecac4 100644 --- a/07-events/main.c +++ b/07-events/main.c @@ -15,16 +15,48 @@ #include "ztimer.h" /* [TASK 2: create event handler here] */ +void event_handler(event_t *event) +{ + (void) event; /* Not used */ + + ztimer_sleep(ZTIMER_MSEC, 2000); + LED0_TOGGLE; + puts("Done"); +} /* [TASK 2: instantiate queue and event here] */ +event_queue_t queue; +event_t event = { .handler = event_handler }; /* [TASK 2: create thread stack and handler here] */ +char thread_stack[THREAD_STACKSIZE_DEFAULT]; +void *thread_handler(void *arg) +{ + (void) arg; /* Not used */ + + /* initialize the event queue */ + event_queue_init(&queue); + + /* wait for events to be posted and serve them */ + event_loop(&queue); + return 0; +} void button_callback(void *arg) { (void) arg; /* Not used */ /* [TASK 1 and 2: implement interrupt routing here] */ + /* get the current time */ + // ztimer_now_t start = ztimer_now(ZTIMER_MSEC); + + /* wait until 2000 ms have passed */ + // while (ztimer_now(ZTIMER_MSEC) - start < 2000) { } + + // LED0_TOGGLE; + event_post(&queue, &event); + + puts("Done"); } int main(void) @@ -38,6 +70,15 @@ int main(void) } /* [TASK 2: create new thread here ] */ + thread_create( + thread_stack, + sizeof(thread_stack), + THREAD_PRIORITY_MAIN - 1, + THREAD_CREATE_STACKTEST, + thread_handler, + NULL, + "queue thread" + ); while (1) { puts("Main"); diff --git a/08-coap-basic/server.c b/08-coap-basic/server.c index 6a9e01c..8c1a6fd 100644 --- a/08-coap-basic/server.c +++ b/08-coap-basic/server.c @@ -24,12 +24,19 @@ static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); /* [TASK 2: add the prototype of your resource handler here] */ +static ssize_t _led_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx); /* [TASK 2: declare the array of LEDs here] */ +static const gpio_t leds[] = { + LED0_PIN, + LED1_PIN, + LED2_PIN, +}; /* CoAP resources. Must be sorted by path (ASCII order). */ static const coap_resource_t _resources[] = { /* [TASK 2: register your CoAP resource here] */ + { "/led/", COAP_GET | COAP_PUT | COAP_MATCH_SUBTREE, _led_handler, NULL }, { "/riot/board", COAP_GET, _riot_board_handler, NULL }, }; @@ -53,9 +60,79 @@ void server_init(void) gcoap_register_listener(&_listener); /* [TASK 2: initialize the GPIOs here] */ + /* initialize LEDs and turn them off */ + for (unsigned i = 0; i < ARRAY_SIZE(leds); i++) { + gpio_init(leds[i], GPIO_OUT); + gpio_set(leds[i]); + } } /* [TASK 2: implement the LED handler here] */ +static ssize_t _led_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx) +{ + (void) ctx; /* argument not used */ + /* implement your handler here */ + char uri[CONFIG_NANOCOAP_URI_MAX] = { 0 }; + /* get the request path, to know which LED is being requested */ + if (coap_get_uri_path(pdu, (uint8_t *)uri) <= 0) { + /* reply with an error if we could not parse the URI */ + return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST); + } + + /* find the LED number, the URI should be /led/ */ + char *led_str = uri + strlen("/led/"); + unsigned led_number = atoi(led_str); + + /* verify that the number is valid, respond with an error otherwise */ + if (led_number >= ARRAY_SIZE(leds)) { + return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST); + } + + ssize_t resp_len = 0; + int led_status = 0; + unsigned method = coap_method2flag(coap_get_code_detail(pdu)); + + switch (method) { + case COAP_PUT: /* on PUT, we set the status of the LED based on the payload */ + /* check if there is a payload with a LED status */ + if (pdu->payload_len) { + led_status = atoi((char *)pdu->payload); + } else { + return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST); + } + + if (led_status) { + gpio_clear(leds[led_number]); + } else { + gpio_set(leds[led_number]); + } + return gcoap_response(pdu, buf, len, COAP_CODE_CHANGED); + case COAP_GET: /* on GET, we return the status of the LED in plain text */ + /* initialize the CoAP response */ + gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); + + /* set the content format to plain text */ + coap_opt_add_format(pdu, COAP_FORMAT_TEXT); + + /* finish the options indicating that we will include a payload */ + resp_len = coap_opt_finish(pdu, COAP_OPT_FINISH_PAYLOAD); + + /* get the current status of the LED, which is the inverted value of the GPIO */ + led_status = !gpio_read(leds[led_number]); + + /* based on the status, write the value of the payload to send */ + if (led_status) { + pdu->payload[0] = '1'; + } else { + pdu->payload[0] = '0'; + } + resp_len++; + return resp_len; + } + + + return 0; +} /* * Server callback for /riot/board. Accepts only GET.