diff --git a/01-hello-world/main.c b/01-hello-world/main.c index f51bf8c..16a7243 100644 --- a/01-hello-world/main.c +++ b/01-hello-world/main.c @@ -24,7 +24,6 @@ int main(void) { puts("Hello World!"); - printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); printf("This board features a(n) %s MCU.\n", RIOT_MCU); diff --git a/02-timers/Makefile b/02-timers/Makefile index c6494df..eb3c03d 100644 --- a/02-timers/Makefile +++ b/02-timers/Makefile @@ -9,9 +9,9 @@ RIOTBASE ?= $(CURDIR)/../RIOT # required modules USEMODULE += ztimer -USEMODULE += ztimer_msec -USEMODULE += ztimer_sec - +USEMODULE += ztimer_usec # microsecond precision +USEMODULE += ztimer_msec # millisecond precision +USEMODULE += ztimer_sec # second precision # Comment this out to disable code in RIOT that does safety checking # which is not needed in a production environment but helps in the # development process: diff --git a/02-timers/main.c b/02-timers/main.c index ff2c808..8c48aa7 100644 --- a/02-timers/main.c +++ b/02-timers/main.c @@ -12,12 +12,15 @@ /* needed to manipulate the LEDs */ #include "board.h" -void message_callback(void *argument) -{ +void message_callback(void *argument){ char *message = (char *)argument; puts(message); } +void led_callback(void *argument){ + (void) argument; /* we don't use the argument */ + LED1_ON; /* turn LED 1 on */ +} /* [TASK 3: insert your callback function here] */ int main(void) @@ -31,16 +34,20 @@ 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; /* create a new timer */ + led_timeout.callback = led_callback; /* set the function to execute */ + /* set the timer to trigger in 1 seconds */ + 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..c3b7694 100644 --- a/03-shell/main.c +++ b/03-shell/main.c @@ -8,13 +8,14 @@ #include #include +#include +#include "board.h" #include "shell.h" /* [TASK 2: add command handler here] */ -int echo_command(int argc, char **argv) -{ +int echo_command(int argc, char **argv) { /* check that the command is called correctly */ if (argc != 2) { puts("usage: echo "); @@ -28,11 +29,29 @@ int echo_command(int argc, char **argv) return 0; } +int toggle_command(int argc, char **argv) { + /* check that the command is called correctly (no extra arguments) */ + if (argc != 2) { + printf("usage: %s \n", argv[0]); + return 1; + } + int number = atoi(argv[1]); + /* toggle the LED */ + if (number == 0) + LED0_TOGGLE; + else if (number == 1) + LED1_TOGGLE; + else + return 2; + + return 0; +} + /* [TASK 2: register your new command here] */ -SHELL_COMMAND(echo,"Echo a message",echo_command); +SHELL_COMMAND(echo, "Echo a message", echo_command); +SHELL_COMMAND(toggle, "Toggle LED 0 or 1", toggle_command); -int main(void) -{ +int main(void) { /* buffer to read commands */ char line_buf[SHELL_DEFAULT_BUFSIZE]; diff --git a/04-saul/main.c b/04-saul/main.c index 503a3a3..157607a 100644 --- a/04-saul/main.c +++ b/04-saul/main.c @@ -13,10 +13,15 @@ #include "saul_reg.h" #include "board.h" -#define TEMPERATURE_THRESHOLD 2600 /* factor of 10^-3 */ +#define TEMPERATURE_THRESHOLD 2700 /* factor of 10^-3 */ -int main(void) -{ +//typedef struct { +// int16_t val[PHYDAT_DIM]; /**< the 3 generic dimensions of data */ +// uint8_t unit; /**< the (physical) unit of the data */ +// int8_t scale; /**< the scale factor, 10^*scale* */ +//} phydat_t; + +int main(void) { puts("SAUL example application"); /* start by finding a temperature sensor in the system */ @@ -24,10 +29,15 @@ int main(void) if (!temp_sensor) { puts("No temperature sensor present"); return 1; - } - else { + } else { printf("Found temperature device: %s\n", temp_sensor->name); } + saul_reg_t *accel_sensor = saul_reg_find_type(SAUL_SENSE_ACCEL); + if (!accel_sensor) { + puts("No accelerometer sensor present"); + } else { + printf("Found accelerometer device: %s\n", accel_sensor->name); + } /* [TASK 3: find your device here] */ @@ -46,14 +56,26 @@ int main(void) /* dump the read value to STDIO */ phydat_dump(&temperature, dimensions); - /* [TASK 3: perform the acceleration read here ] */ + /* read an acceleration value from the sensor */ + 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; + } + + phydat_dump(&acceleration, acc_dim); + if (acceleration.val[2] <= 0) { + LED2_ON; + } else { + LED2_OFF; + } /* check if the temperature value is above the threshold */ if (temperature.val[0] >= TEMPERATURE_THRESHOLD) { LED0_ON; LED1_OFF; - } - else { + } else { LED0_OFF; LED1_ON; } diff --git a/05-gpios/main.c b/05-gpios/main.c index cc50036..4039cb8 100644 --- a/05-gpios/main.c +++ b/05-gpios/main.c @@ -8,15 +8,36 @@ #include +#include "periph/gpio.h" #include "board.h" #include "ztimer.h" - /* [TASK 2: define button and led1 here] */ - +/* [TASK 2: define button and led1 here] */ +void button_callback(void *arg) { + (void) arg; /* the argument is not used */ + if (!gpio_read(button)) { + gpio_clear(led1); + } else { + gpio_set(led1); + } +} -int main(void) -{ +int main(void) { puts("GPIOs example."); + gpio_t led0 = GPIO_PIN(PORT_D, 6); + gpio_mode_t led0_mode = GPIO_OUT; + + gpio_init(led0, led0_mode); + gpio_set(led0); + + + /* define button outside the main function, as we will use it later */ + gpio_t button = GPIO_PIN(PORT_D, 1); + 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/08-coap-basic/server.c b/08-coap-basic/server.c index 6a9e01c..f72fb27 100644 --- a/08-coap-basic/server.c +++ b/08-coap-basic/server.c @@ -21,16 +21,23 @@ #include "periph/gpio.h" #include "board.h" -static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +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] */ - { "/riot/board", COAP_GET, _riot_board_handler, NULL }, + /* [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}, }; /* a gcoap listener is a collection of resources. Additionally we can specify @@ -40,31 +47,100 @@ static const coap_resource_t _resources[] = { * comparison is the default) */ static gcoap_listener_t _listener = { - _resources, - ARRAY_SIZE(_resources), - GCOAP_SOCKET_TYPE_UDP, - NULL, - NULL, - NULL + _resources, + ARRAY_SIZE(_resources), + GCOAP_SOCKET_TYPE_UDP, + NULL, + NULL, + NULL }; -void server_init(void) -{ +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]); + } } +// coap put 2001:db8::2a6c:5e62:9bf:52be 5683 /led/0 1 +// coap put fe80::2a6c:5e62:9bf:52be 5683 /led/0 1 +//> coap get 2001:db8::5d0f:7b9d:ae49:3ee6 5683 /.well-known/core /* [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. * * GET: Returns the name of the board in plain text */ -static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx) -{ - (void)ctx; +static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx) { + (void) ctx; /* initialize a new coap response */ gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); @@ -81,8 +157,7 @@ static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, vo if (pdu->payload_len >= strlen(RIOT_BOARD)) { memcpy(pdu->payload, RIOT_BOARD, strlen(RIOT_BOARD)); return resp_len + strlen(RIOT_BOARD); - } - else { + } else { /* in this case we use a simple convenience function to create the * response, it only allows to set a payload and a response code. */ puts("gcoap_cli: msg buffer too small");