1.1 --- a/pkg/landfall-examples/hw_info/Makefile Thu Feb 01 22:41:30 2024 +0100
1.2 +++ b/pkg/landfall-examples/hw_info/Makefile Thu Feb 01 22:42:56 2024 +0100
1.3 @@ -7,6 +7,7 @@
1.4 REQUIRES_LIBS = \
1.5 libio l4re_c-util libdrivers-aic libdrivers-cpm \
1.6 libdrivers-dma libdrivers-gpio libdrivers-i2c \
1.7 - libdrivers-rtc libdrivers-spi libdevice-util
1.8 + libdrivers-rtc libdrivers-spi libdrivers-tcu \
1.9 + libdevice-util
1.10
1.11 include $(L4DIR)/mk/prog.mk
2.1 --- a/pkg/landfall-examples/hw_info/common.h Thu Feb 01 22:41:30 2024 +0100
2.2 +++ b/pkg/landfall-examples/hw_info/common.h Thu Feb 01 22:42:56 2024 +0100
2.3 @@ -1,7 +1,8 @@
2.4 /*
2.5 - * Access various peripherals on a board.
2.6 + * Common definitions and adapter function signatures for access to
2.7 + * board-specific functionality.
2.8 *
2.9 - * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
2.10 + * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk>
2.11 *
2.12 * This program is free software; you can redistribute it and/or
2.13 * modify it under the terms of the GNU General Public License as
2.14 @@ -222,11 +223,61 @@
2.15
2.16
2.17
2.18 +/* TCU adapter functions. */
2.19 +
2.20 +void *tcu_init(l4_addr_t start, l4_addr_t end);
2.21 +
2.22 +void *tcu_get_channel(void *tcu, uint8_t channel, l4_cap_idx_t irq);
2.23 +
2.24 +void tcu_disable(void *tcu_channel);
2.25 +
2.26 +void tcu_enable(void *tcu_channel);
2.27 +
2.28 +int tcu_is_enabled(void *tcu_channel);
2.29 +
2.30 +uint8_t tcu_get_clock(void *tcu_channel);
2.31 +
2.32 +void tcu_set_clock(void *tcu_channel, uint8_t clock);
2.33 +
2.34 +uint32_t tcu_get_prescale(void *tcu_channel);
2.35 +
2.36 +void tcu_set_prescale(void *tcu_channel, uint32_t prescale);
2.37 +
2.38 +uint32_t tcu_get_counter(void *tcu_channel);
2.39 +
2.40 +void tcu_set_counter(void *tcu_channel, uint32_t value);
2.41 +
2.42 +uint8_t tcu_get_count_mode(void *tcu_channel);
2.43 +
2.44 +void tcu_set_count_mode(void *tcu_channel, uint8_t mode);
2.45 +
2.46 +uint32_t tcu_get_full_data_value(void *tcu_channel);
2.47 +
2.48 +void tcu_set_full_data_value(void *tcu_channel, uint32_t value);
2.49 +
2.50 +uint32_t tcu_get_half_data_value(void *tcu_channel);
2.51 +
2.52 +void tcu_set_half_data_value(void *tcu_channel, uint32_t value);
2.53 +
2.54 +int tcu_get_full_data_mask(void *tcu_channel);
2.55 +
2.56 +void tcu_set_full_data_mask(void *tcu_channel, int masked);
2.57 +
2.58 +int tcu_get_half_data_mask(void *tcu_channel);
2.59 +
2.60 +void tcu_set_half_data_mask(void *tcu_channel, int masked);
2.61 +
2.62 +int tcu_have_interrupt(void *tcu_channel);
2.63 +
2.64 +int tcu_wait_for_irq(void *tcu_channel, uint32_t timeout);
2.65 +
2.66 +
2.67 +
2.68 /* Memory regions. */
2.69
2.70 enum memory_regions
2.71 {
2.72 - AIC, CPM, DMA, GPIO, I2C, RTC, SSI
2.73 + AIC, CPM, DMA, GPIO, I2C, RTC, SSI, TCU
2.74 };
2.75
2.76
3.1 --- a/pkg/landfall-examples/hw_info/defs.h Thu Feb 01 22:41:30 2024 +0100
3.2 +++ b/pkg/landfall-examples/hw_info/defs.h Thu Feb 01 22:42:56 2024 +0100
3.3 @@ -1,7 +1,7 @@
3.4 /*
3.5 * Common declarations for chip-specific definitions.
3.6 *
3.7 - * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
3.8 + * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk>
3.9 *
3.10 * This program is free software; you can redistribute it and/or
3.11 * modify it under the terms of the GNU General Public License as
3.12 @@ -86,3 +86,13 @@
3.13 extern void *spi_channels[];
3.14
3.15 extern const unsigned int num_spi_channels;
3.16 +
3.17 +
3.18 +
3.19 +/* TCU definitions. */
3.20 +
3.21 +extern void *tcu_channels[];
3.22 +
3.23 +extern const unsigned int num_tcu_channels;
3.24 +
3.25 +extern l4_cap_idx_t tcu_irq;
4.1 --- a/pkg/landfall-examples/hw_info/hw_info.c Thu Feb 01 22:41:30 2024 +0100
4.2 +++ b/pkg/landfall-examples/hw_info/hw_info.c Thu Feb 01 22:42:56 2024 +0100
4.3 @@ -1,7 +1,7 @@
4.4 /*
4.5 * Access various peripherals on the MIPS Creator CI20 board.
4.6 *
4.7 - * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
4.8 + * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk>
4.9 *
4.10 * This program is free software; you can redistribute it and/or
4.11 * modify it under the terms of the GNU General Public License as
4.12 @@ -248,9 +248,10 @@
4.13
4.14 static int get_memory_region(unsigned int size, l4_addr_t *addr)
4.15 {
4.16 - *addr = (l4_addr_t) calloc(size, sizeof(char));
4.17 -
4.18 - return !(*addr);
4.19 + void *a = calloc(size, sizeof(char));
4.20 +
4.21 + *addr = (l4_addr_t) a;
4.22 + return a == NULL ? 1 : 0;
4.23 }
4.24
4.25
4.26 @@ -897,8 +898,6 @@
4.27 unsigned int num;
4.28 void *channel;
4.29
4.30 - printf("i2c: channel\n\n");
4.31 -
4.32 for (num = 0; num < num_i2c_channels; num++)
4.33 {
4.34 printf("Channel %d: ", num);
4.35 @@ -1325,6 +1324,233 @@
4.36
4.37
4.38
4.39 +/* TCU configuration. */
4.40 +
4.41 +static l4_uint32_t tcu_irq_start = 0, tcu_irq_end = 0;
4.42 +
4.43 +/* TCU operations. */
4.44 +
4.45 +static int init_tcu(void)
4.46 +{
4.47 + /* Here, only one IRQ is used. */
4.48 +
4.49 + tcu_irq = l4re_util_cap_alloc();
4.50 + return init_irq(0, tcu_irq, tcu_irq_start, tcu_irq_end);
4.51 +}
4.52 +
4.53 +static void disable_tcu_counter(void)
4.54 +{
4.55 + int num = get_channel_number(num_tcu_channels);
4.56 + void *channel;
4.57 +
4.58 + if (num < 0)
4.59 + return;
4.60 +
4.61 + channel = tcu_channels[num];
4.62 +
4.63 + if (channel == NULL)
4.64 + return;
4.65 +
4.66 + tcu_disable(channel);
4.67 +}
4.68 +
4.69 +static void enable_tcu_counter(void)
4.70 +{
4.71 + int num = get_channel_number(num_tcu_channels);
4.72 + void *channel;
4.73 +
4.74 + if (num < 0)
4.75 + return;
4.76 +
4.77 + channel = tcu_channels[num];
4.78 +
4.79 + if (channel == NULL)
4.80 + return;
4.81 +
4.82 + tcu_enable(channel);
4.83 +}
4.84 +
4.85 +static void new_tcu_channel(void *tcu)
4.86 +{
4.87 + int num = get_channel_number(num_tcu_channels);
4.88 +
4.89 + if (num < 0)
4.90 + return;
4.91 +
4.92 + tcu_channels[num] = tcu_get_channel(tcu, num, tcu_irq);
4.93 +}
4.94 +
4.95 +static void list_tcu_channels(void)
4.96 +{
4.97 + unsigned int num;
4.98 + void *channel;
4.99 +
4.100 + printf(" Clock.. Counter......... Mask..............\n");
4.101 + printf("Channel Status C Pre Cnt Half Full Half Full Int\n");
4.102 +
4.103 + for (num = 0; num < num_tcu_channels; num++)
4.104 + {
4.105 + printf("%d ", num);
4.106 +
4.107 + channel = tcu_channels[num];
4.108 +
4.109 + if (channel == NULL)
4.110 + printf("inactive\n");
4.111 + else
4.112 + printf("%s %d %4d %04x %04x %04x %s %s %s\n",
4.113 + tcu_is_enabled(channel) ? "enabled " : "disabled",
4.114 + tcu_get_clock(channel),
4.115 + tcu_get_prescale(channel),
4.116 + tcu_get_counter(channel),
4.117 + tcu_get_half_data_value(channel),
4.118 + tcu_get_full_data_value(channel),
4.119 + tcu_get_half_data_mask(channel) ? "masked " : "unmasked",
4.120 + tcu_get_full_data_mask(channel) ? "masked " : "unmasked",
4.121 + tcu_have_interrupt(channel) ? "!" : "_");
4.122 + }
4.123 +}
4.124 +
4.125 +static void set_tcu_counter(void)
4.126 +{
4.127 + int num = get_channel_number(num_tcu_channels);
4.128 + void *channel;
4.129 + uint32_t counter;
4.130 +
4.131 + if (num < 0)
4.132 + return;
4.133 +
4.134 + channel = tcu_channels[num];
4.135 +
4.136 + if (channel == NULL)
4.137 + return;
4.138 +
4.139 + if (!read_number("Value", &counter))
4.140 + return;
4.141 +
4.142 + tcu_set_counter(channel, counter);
4.143 +}
4.144 +
4.145 +static void set_tcu_clock(void)
4.146 +{
4.147 + int num = get_channel_number(num_tcu_channels);
4.148 + void *channel;
4.149 + uint32_t clock;
4.150 +
4.151 + if (num < 0)
4.152 + return;
4.153 +
4.154 + channel = tcu_channels[num];
4.155 +
4.156 + if (channel == NULL)
4.157 + return;
4.158 +
4.159 + if (!read_number("Clock", &clock))
4.160 + return;
4.161 +
4.162 + tcu_set_clock(channel, clock);
4.163 +}
4.164 +
4.165 +static void set_tcu_full(void)
4.166 +{
4.167 + int num = get_channel_number(num_tcu_channels);
4.168 + void *channel;
4.169 + uint32_t value;
4.170 +
4.171 + if (num < 0)
4.172 + return;
4.173 +
4.174 + channel = tcu_channels[num];
4.175 +
4.176 + if (channel == NULL)
4.177 + return;
4.178 +
4.179 + if (!read_number("Full value", &value))
4.180 + return;
4.181 +
4.182 + tcu_set_full_data_value(channel, value);
4.183 +}
4.184 +
4.185 +static void set_tcu_half(void)
4.186 +{
4.187 + int num = get_channel_number(num_tcu_channels);
4.188 + void *channel;
4.189 + uint32_t value;
4.190 +
4.191 + if (num < 0)
4.192 + return;
4.193 +
4.194 + channel = tcu_channels[num];
4.195 +
4.196 + if (channel == NULL)
4.197 + return;
4.198 +
4.199 + if (!read_number("Half value", &value))
4.200 + return;
4.201 +
4.202 + tcu_set_half_data_value(channel, value);
4.203 +}
4.204 +
4.205 +static void set_tcu_mask(int full_mask, int masked)
4.206 +{
4.207 + int num = get_channel_number(num_tcu_channels);
4.208 + void *channel;
4.209 +
4.210 + if (num < 0)
4.211 + return;
4.212 +
4.213 + channel = tcu_channels[num];
4.214 +
4.215 + if (channel == NULL)
4.216 + return;
4.217 +
4.218 + if (full_mask)
4.219 + tcu_set_full_data_mask(channel, masked);
4.220 + else
4.221 + tcu_set_half_data_mask(channel, masked);
4.222 +}
4.223 +
4.224 +static void set_tcu_prescale(void)
4.225 +{
4.226 + int num = get_channel_number(num_tcu_channels);
4.227 + void *channel;
4.228 + uint32_t prescale;
4.229 +
4.230 + if (num < 0)
4.231 + return;
4.232 +
4.233 + channel = tcu_channels[num];
4.234 +
4.235 + if (channel == NULL)
4.236 + return;
4.237 +
4.238 + if (!read_number("Prescale", &prescale))
4.239 + return;
4.240 +
4.241 + tcu_set_prescale(channel, prescale);
4.242 +}
4.243 +
4.244 +static void tcu_wait(void)
4.245 +{
4.246 + int num = get_channel_number(num_tcu_channels);
4.247 + void *channel;
4.248 + uint32_t timeout;
4.249 +
4.250 + if (num < 0)
4.251 + return;
4.252 +
4.253 + channel = tcu_channels[num];
4.254 +
4.255 + if (channel == NULL)
4.256 + return;
4.257 +
4.258 + if (!read_number("Timeout", &timeout))
4.259 + return;
4.260 +
4.261 + printf("IRQ received: %s\n", tcu_wait_for_irq(channel, timeout) ? "yes" : "no");
4.262 +}
4.263 +
4.264 +
4.265 +
4.266 /* Command processing. */
4.267
4.268 static void handle_aic(void *aic)
4.269 @@ -1511,6 +1737,49 @@
4.270 list_channels(num_spi_channels, spi_channels);
4.271 }
4.272
4.273 +static void handle_tcu(void *tcu)
4.274 +{
4.275 + char *token;
4.276 +
4.277 + if ((token = read_token(NULL)) != NULL)
4.278 + {
4.279 + if (!strcmp(token, "l") || !strcmp(token, "list"))
4.280 + list_tcu_channels();
4.281 + else if (!strcmp(token, "c") || !strcmp(token, "channel"))
4.282 + new_tcu_channel(tcu);
4.283 + else if (!strcmp(token, "C") || !strcmp(token, "clock"))
4.284 + set_tcu_clock();
4.285 + else if (!strcmp(token, "d") || !strcmp(token, "disable"))
4.286 + disable_tcu_counter();
4.287 + else if (!strcmp(token, "e") || !strcmp(token, "enable"))
4.288 + enable_tcu_counter();
4.289 + else if (!strcmp(token, "f") || !strcmp(token, "full"))
4.290 + set_tcu_full();
4.291 + else if (!strcmp(token, "fm") || !strcmp(token, "full-mask"))
4.292 + set_tcu_mask(1, 1);
4.293 + else if (!strcmp(token, "fu") || !strcmp(token, "full-unmask"))
4.294 + set_tcu_mask(1, 0);
4.295 + else if (!strcmp(token, "h") || !strcmp(token, "half"))
4.296 + set_tcu_half();
4.297 + else if (!strcmp(token, "hm") || !strcmp(token, "half-mask"))
4.298 + set_tcu_mask(0, 1);
4.299 + else if (!strcmp(token, "hu") || !strcmp(token, "half-unmask"))
4.300 + set_tcu_mask(0, 0);
4.301 + else if (!strcmp(token, "p") || !strcmp(token, "prescale"))
4.302 + set_tcu_prescale();
4.303 + else if (!strcmp(token, "s") || !strcmp(token, "set"))
4.304 + set_tcu_counter();
4.305 + else if (!strcmp(token, "w") || !strcmp(token, "wait"))
4.306 + tcu_wait();
4.307 + else
4.308 + printf("tcu channel | clock | disable | enable | full | full-mask | " \
4.309 + "full-unmask | half | half-mask | half-unmask | list | mask | " \
4.310 + "prescale | set | unmask | wait\n");
4.311 + }
4.312 + else
4.313 + list_tcu_channels();
4.314 +}
4.315 +
4.316
4.317
4.318 int main(void)
4.319 @@ -1524,7 +1793,8 @@
4.320 l4_addr_t rtc_base = 0, rtc_base_end = 0;
4.321 l4_addr_t ssi_base = 0, ssi_base_end = 0;
4.322 l4_addr_t ssi_phys_base = 0, ssi_phys_base_end = 0;
4.323 - void *aic, *cpm, *dma, *gpio[num_gpio_ports], *i2c, *rtc, *spi;
4.324 + l4_addr_t tcu_base = 0, tcu_base_end = 0;
4.325 + void *aic, *cpm, *dma, *gpio[num_gpio_ports], *i2c, *rtc, *spi, *tcu;
4.326 int result = 0;
4.327 unsigned int port;
4.328
4.329 @@ -1614,9 +1884,26 @@
4.330
4.331 spi = spi_init(ssi_phys_base, ssi_base, ssi_base_end, cpm);
4.332
4.333 + printf("Access TCU...\n");
4.334 +
4.335 + if ((result = get_memory(io_memory_regions[TCU], &tcu_base, &tcu_base_end)) < 0)
4.336 + return 1;
4.337 +
4.338 + printf("TCU at 0x%lx...0x%lx.\n", tcu_base, tcu_base_end);
4.339 +
4.340 + tcu = tcu_init(tcu_base, tcu_base_end);
4.341 +
4.342 + if (get_irq(io_memory_regions[TCU], &tcu_irq_start, &tcu_irq_end) < 0)
4.343 + return 1;
4.344 +
4.345 + printf("IRQ range at %d...%d.\n", tcu_irq_start, tcu_irq_end);
4.346 +
4.347 + if (init_tcu())
4.348 + return 1;
4.349 +
4.350 /* Start the interactive session. */
4.351
4.352 - printf("aic, cpm, dma, gpio, i2c, rtc, spi\n");
4.353 + printf("aic, cpm, dma, gpio, i2c, rtc, spi, tcu\n");
4.354
4.355 while (1)
4.356 {
4.357 @@ -1672,6 +1959,11 @@
4.358 else if (!strcmp(token, "s") || !strcmp(token, "spi"))
4.359 handle_spi(spi, gpio);
4.360
4.361 + /* TCU commands. */
4.362 +
4.363 + else if (!strcmp(token, "t") || !strcmp(token, "tcu"))
4.364 + handle_tcu(tcu);
4.365 +
4.366 /* Comments and blank lines. */
4.367
4.368 else if (strncmp(token, "#", 1) && strlen(token))
5.1 --- a/pkg/landfall-examples/hw_info/jz4780.c Thu Feb 01 22:41:30 2024 +0100
5.2 +++ b/pkg/landfall-examples/hw_info/jz4780.c Thu Feb 01 22:42:56 2024 +0100
5.3 @@ -39,6 +39,7 @@
5.4 #include <l4/devices/spi-gpio.h>
5.5 #include <l4/devices/spi-hybrid.h>
5.6 #include <l4/devices/spi-jz4780.h>
5.7 +#include <l4/devices/tcu-jz4780.h>
5.8 #include "common.h"
5.9
5.10
5.11 @@ -462,6 +463,125 @@
5.12
5.13
5.14
5.15 +/* TCU adapter functions. */
5.16 +
5.17 +void *tcu_init(l4_addr_t start, l4_addr_t end)
5.18 +{
5.19 + return jz4780_tcu_init(start, end);
5.20 +}
5.21 +
5.22 +void *tcu_get_channel(void *tcu, uint8_t channel, l4_cap_idx_t irq)
5.23 +{
5.24 + return jz4780_tcu_get_channel(tcu, channel, irq);
5.25 +}
5.26 +
5.27 +void tcu_disable(void *tcu_channel)
5.28 +{
5.29 + jz4780_tcu_disable(tcu_channel);
5.30 +}
5.31 +
5.32 +void tcu_enable(void *tcu_channel)
5.33 +{
5.34 + jz4780_tcu_enable(tcu_channel);
5.35 +}
5.36 +
5.37 +int tcu_is_enabled(void *tcu_channel)
5.38 +{
5.39 + return jz4780_tcu_is_enabled(tcu_channel);
5.40 +}
5.41 +
5.42 +uint8_t tcu_get_clock(void *tcu_channel)
5.43 +{
5.44 + return jz4780_tcu_get_clock(tcu_channel);
5.45 +}
5.46 +
5.47 +void tcu_set_clock(void *tcu_channel, uint8_t clock)
5.48 +{
5.49 + jz4780_tcu_set_clock(tcu_channel, clock);
5.50 +}
5.51 +
5.52 +uint32_t tcu_get_prescale(void *tcu_channel)
5.53 +{
5.54 + return jz4780_tcu_get_prescale(tcu_channel);
5.55 +}
5.56 +
5.57 +void tcu_set_prescale(void *tcu_channel, uint32_t prescale)
5.58 +{
5.59 + jz4780_tcu_set_prescale(tcu_channel, prescale);
5.60 +}
5.61 +
5.62 +uint32_t tcu_get_counter(void *tcu_channel)
5.63 +{
5.64 + return jz4780_tcu_get_counter(tcu_channel);
5.65 +}
5.66 +
5.67 +void tcu_set_counter(void *tcu_channel, uint32_t value)
5.68 +{
5.69 + jz4780_tcu_set_counter(tcu_channel, value);
5.70 +}
5.71 +
5.72 +uint8_t tcu_get_count_mode(void *tcu_channel)
5.73 +{
5.74 + return jz4780_tcu_get_count_mode(tcu_channel);
5.75 +}
5.76 +
5.77 +void tcu_set_count_mode(void *tcu_channel, uint8_t mode)
5.78 +{
5.79 + jz4780_tcu_set_count_mode(tcu_channel, mode);
5.80 +}
5.81 +
5.82 +uint32_t tcu_get_full_data_value(void *tcu_channel)
5.83 +{
5.84 + return jz4780_tcu_get_full_data_value(tcu_channel);
5.85 +}
5.86 +
5.87 +void tcu_set_full_data_value(void *tcu_channel, uint32_t value)
5.88 +{
5.89 + jz4780_tcu_set_full_data_value(tcu_channel, value);
5.90 +}
5.91 +
5.92 +uint32_t tcu_get_half_data_value(void *tcu_channel)
5.93 +{
5.94 + return jz4780_tcu_get_half_data_value(tcu_channel);
5.95 +}
5.96 +
5.97 +void tcu_set_half_data_value(void *tcu_channel, uint32_t value)
5.98 +{
5.99 + jz4780_tcu_set_half_data_value(tcu_channel, value);
5.100 +}
5.101 +
5.102 +int tcu_get_full_data_mask(void *tcu_channel)
5.103 +{
5.104 + return jz4780_tcu_get_full_data_mask(tcu_channel);
5.105 +}
5.106 +
5.107 +void tcu_set_full_data_mask(void *tcu_channel, int masked)
5.108 +{
5.109 + jz4780_tcu_set_full_data_mask(tcu_channel, masked);
5.110 +}
5.111 +
5.112 +int tcu_get_half_data_mask(void *tcu_channel)
5.113 +{
5.114 + return jz4780_tcu_get_half_data_mask(tcu_channel);
5.115 +}
5.116 +
5.117 +void tcu_set_half_data_mask(void *tcu_channel, int masked)
5.118 +{
5.119 + jz4780_tcu_set_half_data_mask(tcu_channel, masked);
5.120 +}
5.121 +
5.122 +int tcu_have_interrupt(void *tcu_channel)
5.123 +{
5.124 + return jz4780_tcu_have_interrupt(tcu_channel);
5.125 +}
5.126 +
5.127 +int tcu_wait_for_irq(void *tcu_channel, uint32_t timeout)
5.128 +{
5.129 + return jz4780_tcu_wait_for_irq(tcu_channel, timeout);
5.130 +}
5.131 +
5.132 +
5.133 +
5.134 /* Memory regions. */
5.135
5.136 const char *io_memory_regions[] = {
5.137 @@ -472,6 +592,7 @@
5.138 [I2C] = "jz4780-i2c",
5.139 [RTC] = "jz4780-rtc",
5.140 [SSI] = "jz4780-ssi",
5.141 + [TCU] = "jz4780-tcu",
5.142 };
5.143
5.144
5.145 @@ -583,3 +704,13 @@
5.146 void *spi_channels[] = {NULL, NULL};
5.147
5.148 const unsigned int num_spi_channels = 2;
5.149 +
5.150 +
5.151 +
5.152 +/* TCU definitions. */
5.153 +
5.154 +void *tcu_channels[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
5.155 +
5.156 +const unsigned int num_tcu_channels = 8;
5.157 +
5.158 +l4_cap_idx_t tcu_irq = L4_INVALID_CAP;
6.1 --- a/pkg/landfall-examples/hw_info/x1600.c Thu Feb 01 22:41:30 2024 +0100
6.2 +++ b/pkg/landfall-examples/hw_info/x1600.c Thu Feb 01 22:42:56 2024 +0100
6.3 @@ -1,7 +1,7 @@
6.4 /*
6.5 * Access various peripherals on a board using the X1600.
6.6 *
6.7 - * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
6.8 + * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk>
6.9 *
6.10 * This program is free software; you can redistribute it and/or
6.11 * modify it under the terms of the GNU General Public License as
6.12 @@ -28,6 +28,7 @@
6.13 #include <l4/devices/spi-gpio.h>
6.14 #include <l4/devices/spi-hybrid.h>
6.15 #include <l4/devices/spi-jz4780.h>
6.16 +#include <l4/devices/tcu-x1600.h>
6.17 #include "common.h"
6.18
6.19
6.20 @@ -448,6 +449,125 @@
6.21
6.22
6.23
6.24 +/* TCU adapter functions. */
6.25 +
6.26 +void *tcu_init(l4_addr_t start, l4_addr_t end)
6.27 +{
6.28 + return x1600_tcu_init(start, end);
6.29 +}
6.30 +
6.31 +void *tcu_get_channel(void *tcu, uint8_t channel, l4_cap_idx_t irq)
6.32 +{
6.33 + return x1600_tcu_get_channel(tcu, channel, irq);
6.34 +}
6.35 +
6.36 +void tcu_disable(void *tcu_channel)
6.37 +{
6.38 + x1600_tcu_disable(tcu_channel);
6.39 +}
6.40 +
6.41 +void tcu_enable(void *tcu_channel)
6.42 +{
6.43 + x1600_tcu_enable(tcu_channel);
6.44 +}
6.45 +
6.46 +int tcu_is_enabled(void *tcu_channel)
6.47 +{
6.48 + return x1600_tcu_is_enabled(tcu_channel);
6.49 +}
6.50 +
6.51 +uint8_t tcu_get_clock(void *tcu_channel)
6.52 +{
6.53 + return x1600_tcu_get_clock(tcu_channel);
6.54 +}
6.55 +
6.56 +void tcu_set_clock(void *tcu_channel, uint8_t clock)
6.57 +{
6.58 + x1600_tcu_set_clock(tcu_channel, clock);
6.59 +}
6.60 +
6.61 +uint32_t tcu_get_prescale(void *tcu_channel)
6.62 +{
6.63 + return x1600_tcu_get_prescale(tcu_channel);
6.64 +}
6.65 +
6.66 +void tcu_set_prescale(void *tcu_channel, uint32_t prescale)
6.67 +{
6.68 + x1600_tcu_set_prescale(tcu_channel, prescale);
6.69 +}
6.70 +
6.71 +uint32_t tcu_get_counter(void *tcu_channel)
6.72 +{
6.73 + return x1600_tcu_get_counter(tcu_channel);
6.74 +}
6.75 +
6.76 +void tcu_set_counter(void *tcu_channel, uint32_t value)
6.77 +{
6.78 + x1600_tcu_set_counter(tcu_channel, value);
6.79 +}
6.80 +
6.81 +uint8_t tcu_get_count_mode(void *tcu_channel)
6.82 +{
6.83 + return x1600_tcu_get_count_mode(tcu_channel);
6.84 +}
6.85 +
6.86 +void tcu_set_count_mode(void *tcu_channel, uint8_t mode)
6.87 +{
6.88 + x1600_tcu_set_count_mode(tcu_channel, mode);
6.89 +}
6.90 +
6.91 +uint32_t tcu_get_full_data_value(void *tcu_channel)
6.92 +{
6.93 + return x1600_tcu_get_full_data_value(tcu_channel);
6.94 +}
6.95 +
6.96 +void tcu_set_full_data_value(void *tcu_channel, uint32_t value)
6.97 +{
6.98 + x1600_tcu_set_full_data_value(tcu_channel, value);
6.99 +}
6.100 +
6.101 +uint32_t tcu_get_half_data_value(void *tcu_channel)
6.102 +{
6.103 + return x1600_tcu_get_half_data_value(tcu_channel);
6.104 +}
6.105 +
6.106 +void tcu_set_half_data_value(void *tcu_channel, uint32_t value)
6.107 +{
6.108 + x1600_tcu_set_half_data_value(tcu_channel, value);
6.109 +}
6.110 +
6.111 +int tcu_get_full_data_mask(void *tcu_channel)
6.112 +{
6.113 + return x1600_tcu_get_full_data_mask(tcu_channel);
6.114 +}
6.115 +
6.116 +void tcu_set_full_data_mask(void *tcu_channel, int masked)
6.117 +{
6.118 + x1600_tcu_set_full_data_mask(tcu_channel, masked);
6.119 +}
6.120 +
6.121 +int tcu_get_half_data_mask(void *tcu_channel)
6.122 +{
6.123 + return x1600_tcu_get_half_data_mask(tcu_channel);
6.124 +}
6.125 +
6.126 +void tcu_set_half_data_mask(void *tcu_channel, int masked)
6.127 +{
6.128 + x1600_tcu_set_half_data_mask(tcu_channel, masked);
6.129 +}
6.130 +
6.131 +int tcu_have_interrupt(void *tcu_channel)
6.132 +{
6.133 + return x1600_tcu_have_interrupt(tcu_channel);
6.134 +}
6.135 +
6.136 +int tcu_wait_for_irq(void *tcu_channel, uint32_t timeout)
6.137 +{
6.138 + return x1600_tcu_wait_for_irq(tcu_channel, timeout);
6.139 +}
6.140 +
6.141 +
6.142 +
6.143 /* Memory regions. */
6.144
6.145 const char *io_memory_regions[] = {
6.146 @@ -458,6 +578,7 @@
6.147 [I2C] = "x1600-i2c",
6.148 [RTC] = "x1600-rtc",
6.149 [SSI] = "x1600-ssi",
6.150 + [TCU] = "x1600-tcu",
6.151 };
6.152
6.153
6.154 @@ -555,3 +676,13 @@
6.155 void *spi_channels[] = {NULL};
6.156
6.157 const unsigned int num_spi_channels = 1;
6.158 +
6.159 +
6.160 +
6.161 +/* TCU definitions. */
6.162 +
6.163 +void *tcu_channels[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
6.164 +
6.165 +const unsigned int num_tcu_channels = 8;
6.166 +
6.167 +l4_cap_idx_t tcu_irq = L4_INVALID_CAP;