1 /* 2 * Access various peripherals on the MIPS Creator CI20 board. 3 * 4 * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include "common.h" 23 #include "defs.h" 24 25 #include <l4/devices/dma.h> 26 #include <l4/devices/memory.h> 27 28 #include <l4/io/io.h> 29 #include <l4/re/env.h> 30 #include <l4/re/c/util/cap_alloc.h> 31 #include <l4/sys/cache.h> 32 #include <l4/sys/factory.h> 33 #include <l4/sys/icu.h> 34 #include <l4/sys/ipc.h> 35 #include <l4/sys/irq.h> 36 #include <l4/sys/rcv_endpoint.h> 37 #include <l4/vbus/vbus.h> 38 39 #include <stdio.h> 40 #include <unistd.h> 41 #include <stdint.h> 42 #include <stdlib.h> 43 #include <string.h> 44 45 46 47 /* Common configuration. */ 48 49 static l4_cap_idx_t icucap; 50 51 52 53 /* Device and resource discovery. */ 54 55 static long item_in_range(long start, long end, long index) 56 { 57 if (start < end) 58 return start + index; 59 else if (start > end) 60 return start - index; 61 else 62 return start; 63 } 64 65 66 67 /* Common functions. */ 68 69 static int init_irq(int num, l4_cap_idx_t irq, l4_uint32_t start, l4_uint32_t end) 70 { 71 /* Create interrupt object. */ 72 73 long err = l4_error(l4_factory_create_irq(l4re_global_env->factory, irq)); 74 75 if (err) 76 { 77 printf("Could not create IRQ object: %ld\n", err); 78 return 1; 79 } 80 81 /* Bind interrupt objects to IRQ numbers. */ 82 83 err = l4_error(l4_icu_bind(icucap, 84 item_in_range(start, end, num), 85 irq)); 86 87 if (err) 88 { 89 printf("Could not bind IRQ to the ICU: %ld\n", err); 90 return 1; 91 } 92 93 /* Attach ourselves to the interrupt handler. */ 94 95 err = l4_error(l4_rcv_ep_bind_thread(irq, l4re_env()->main_thread, num)); 96 97 if (err) 98 { 99 printf("Could not attach to IRQs: %ld\n", err); 100 return 1; 101 } 102 103 return 0; 104 } 105 106 static const char *delimiters = " \n"; 107 108 static char *read_token(const char *message) 109 { 110 char *token; 111 112 if ((token = strtok(NULL, delimiters)) == NULL) 113 { 114 if (message != NULL) 115 printf("%s?\n", message); 116 } 117 118 return token; 119 } 120 121 static int read_increment(const char *message, int *increment) 122 { 123 char *token = read_token(message); 124 125 if (token == NULL) 126 return 0; 127 128 *increment = !strncmp(token, "i", 1); 129 return 1; 130 } 131 132 static int read_encoded_number(const char *message, const char *format, unsigned int *num) 133 { 134 char *token = read_token(message); 135 136 if (token == NULL) 137 return 0; 138 139 sscanf(token, format, num); 140 return 1; 141 } 142 143 static int read_number(const char *message, unsigned int *num) 144 { 145 char *token = read_token(message); 146 147 if (token == NULL) 148 return 0; 149 150 if (!strncmp(token, "0x", 2) || !strncmp(token, "0X", 2)) 151 sscanf(token, "%x", num); 152 else 153 *num = atoi(token); 154 155 return 1; 156 } 157 158 static int get_resource_number(const char *type, unsigned int available) 159 { 160 unsigned int num; 161 162 if (!read_number(type, &num)) 163 return -1; 164 165 if (num >= available) 166 { 167 printf("%s number out of range.\n", type); 168 return -1; 169 } 170 171 return num; 172 } 173 174 static int get_channel_number(unsigned int available) 175 { 176 return get_resource_number("Channel", available); 177 } 178 179 static int get_region_number(unsigned int available) 180 { 181 return get_resource_number("Region", available); 182 } 183 184 static void *get_channel(int num_channels, void *channels[], int *num) 185 { 186 int n = get_channel_number(num_channels); 187 void *channel; 188 189 if (n < 0) 190 return NULL; 191 192 channel = channels[n]; 193 194 if (channel == NULL) 195 printf("Channel needs creating.\n"); 196 197 if (num != NULL) 198 *num = n; 199 200 return channel; 201 } 202 203 static void list_channels(int num_channels, void *channels[]) 204 { 205 int num; 206 void *channel; 207 208 for (num = 0; num < num_channels; num++) 209 { 210 printf("Channel %d: ", num); 211 212 channel = channels[num]; 213 214 if (channel == NULL) 215 printf("(inactive)\n"); 216 else 217 printf("active\n"); 218 } 219 } 220 221 222 223 /* AIC/I2S configuration. */ 224 225 static l4_uint32_t aic_irq_start = 0, aic_irq_end = 0; 226 227 /* AIC/I2S operations. */ 228 229 static void new_aic_channel(void *aic) 230 { 231 l4_cap_idx_t irqcap; 232 int num = get_channel_number(num_aic_channels); 233 void *channel; 234 235 if (num < 0) 236 return; 237 238 channel = get_channel(num_dma_channels, dma_channels, NULL); 239 240 if (channel == NULL) 241 return; 242 243 irqcap = l4re_util_cap_alloc(); 244 245 if (init_irq(num, irqcap, aic_irq_start, aic_irq_end)) 246 return; 247 248 aic_channels[num] = aic_get_channel(aic, num, channel); 249 aic_irqs[num] = irqcap; 250 } 251 252 static void set_aic_buffer(void) 253 { 254 char *token; 255 FILE *fp; 256 void *channel = get_channel(num_aic_channels, aic_channels, NULL); 257 unsigned int size; 258 l4_addr_t vaddr; 259 260 if (channel == NULL) 261 return; 262 263 if (!read_number("Buffer size", &size)) 264 return; 265 266 if (aic_get_buffer(channel, size, &vaddr)) 267 { 268 printf("Could not get buffer.\n"); 269 return; 270 } 271 272 memset((void *) vaddr, 0, size); 273 274 if ((token = read_token("Filename")) == NULL) 275 return; 276 277 /* Populate the region from the file. */ 278 279 fp = fopen(token, "r"); 280 281 if (fp == NULL) 282 { 283 printf("File not readable.\n"); 284 return; 285 } 286 287 fread((char *) vaddr, sizeof(char), size, fp); 288 fclose(fp); 289 290 l4_cache_flush_data(vaddr, vaddr + size); 291 } 292 293 static void aic_transfer_data(void) 294 { 295 void *channel = get_channel(num_aic_channels, aic_channels, NULL); 296 unsigned int count, rate, resolution, transferred; 297 298 if (channel == NULL) 299 return; 300 301 if (!read_number("Sample size", &count)) 302 return; 303 304 if (!read_number("Sample rate", &rate)) 305 return; 306 307 if (!read_number("Sample resolution", &resolution)) 308 return; 309 310 transferred = aic_transfer(channel, count, rate, resolution); 311 312 printf("Transferred: %d\n", transferred); 313 } 314 315 316 317 /* CPM operations. */ 318 319 static const char *clock_id(enum Clock_identifiers clock) 320 { 321 for (int i = 0; clocks[i].id != NULL; i++) 322 if (clock == clocks[i].clock) 323 return clocks[i].id; 324 325 return NULL; 326 } 327 328 static enum Clock_identifiers get_clock(char *id) 329 { 330 if (id != NULL) 331 { 332 for (int i = 0; clocks[i].id != NULL; i++) 333 if (!strcmp(id, clocks[i].id)) 334 return clocks[i].clock; 335 } 336 337 return Clock_undefined; 338 } 339 340 static const char list_clocks_separator[] = "--------------------------------"; 341 342 #define sep(x) (list_clocks_separator + sizeof(list_clocks_separator) - 1 - x) 343 344 static void list_clocks(void *cpm) 345 { 346 /* Read information from the clock and power management unit. */ 347 348 printf("%-5s %-10s %-7s %-6s %-12s %-12s %-24s %-12s %-3s\n" 349 "%-5s %-10s %-7s %-6s %-12s %-12s %-24s %-12s %-3s\n", 350 "Id", "Clock", "Type", "Source", "Source Clock", "Source Freq.", 351 "Parameters", "Frequency", "On", 352 sep(5), sep(10), sep(7), sep(6), sep(12), sep(12), 353 sep(24), sep(12), sep(3)); 354 355 for (int i = 0; clocks[i].id != NULL; i++) 356 { 357 uint32_t parameters[4]; 358 char parameter_str[25] = {0}; 359 const char *source_id = clock_id(cpm_get_source_clock(cpm, clocks[i].clock)); 360 int num_parameters = cpm_get_parameters(cpm, clocks[i].clock, parameters); 361 362 for (int p = 0, pos = 0; p < num_parameters; p++) 363 { 364 int result = sprintf(parameter_str + pos, "%-7d ", parameters[p]); 365 if (result < 0) 366 break; 367 pos += result; 368 } 369 370 printf("%-5s %-10s %-7s %-6d %-12s %-12lld %-24s %-12lld %-3s\n", 371 clocks[i].id, 372 clocks[i].name, 373 cpm_clock_type(cpm, clocks[i].clock), 374 cpm_get_source(cpm, clocks[i].clock), 375 source_id != NULL ? source_id : "...", 376 cpm_get_source_frequency(cpm, clocks[i].clock), 377 parameter_str, 378 cpm_get_frequency(cpm, clocks[i].clock), 379 cpm_have_clock(cpm, clocks[i].clock) ? "on" : "off"); 380 } 381 } 382 383 static enum Clock_identifiers get_clock_by_name(void) 384 { 385 char *token; 386 enum Clock_identifiers clock; 387 388 if ((token = read_token("Clock")) == NULL) 389 return Clock_undefined; 390 391 clock = get_clock(token); 392 393 if (clock == Clock_undefined) 394 { 395 printf("Unrecognised clock: %s\n", token); 396 return Clock_undefined; 397 } 398 399 return clock; 400 } 401 402 static void set_frequency(void *cpm) 403 { 404 enum Clock_identifiers clock; 405 unsigned int frequency; 406 407 clock = get_clock_by_name(); 408 409 if (clock == Clock_undefined) 410 return; 411 412 if (!read_number("Frequency", &frequency)) 413 return; 414 415 if (!cpm_set_frequency(cpm, clock, frequency)) 416 printf("Frequency not set.\n"); 417 } 418 419 static void set_parameters(void *cpm) 420 { 421 char *token; 422 enum Clock_identifiers clock; 423 uint32_t parameters[4]; 424 int num_parameters; 425 426 clock = get_clock_by_name(); 427 428 if (clock == Clock_undefined) 429 return; 430 431 for (num_parameters = 0; num_parameters < 4; num_parameters++) 432 { 433 if ((token = read_token(NULL)) == NULL) 434 break; 435 436 parameters[num_parameters] = atoi(token); 437 } 438 439 if (!num_parameters) 440 { 441 printf("Parameters?\n"); 442 return; 443 } 444 445 if (!cpm_set_parameters(cpm, clock, num_parameters, parameters)) 446 printf("Too few or invalid parameters.\n"); 447 } 448 449 static void set_source(void *cpm) 450 { 451 enum Clock_identifiers clock; 452 unsigned int source; 453 454 clock = get_clock_by_name(); 455 456 if (clock == Clock_undefined) 457 return; 458 459 if (!read_number("Source", &source)) 460 return; 461 462 cpm_set_source(cpm, clock, source); 463 } 464 465 static void start_clock(void *cpm) 466 { 467 enum Clock_identifiers clock; 468 469 clock = get_clock_by_name(); 470 471 if (clock == Clock_undefined) 472 return; 473 474 cpm_start_clock(cpm, clock); 475 } 476 477 static void stop_clock(void *cpm) 478 { 479 enum Clock_identifiers clock; 480 481 clock = get_clock_by_name(); 482 483 if (clock == Clock_undefined) 484 return; 485 486 cpm_stop_clock(cpm, clock); 487 } 488 489 490 491 /* DMA configuration. */ 492 493 static l4_uint32_t dma_irq_start = 0, dma_irq_end = 0; 494 495 /* DMA operations. */ 496 497 static int init_dma(void) 498 { 499 unsigned int i; 500 501 for (i = 0; i < num_dma_regions; i++) 502 dma_regions[i].mem = L4_INVALID_CAP; 503 504 /* Here, only one IRQ is used. */ 505 506 dma_irq = l4re_util_cap_alloc(); 507 return init_irq(0, dma_irq, dma_irq_start, dma_irq_end); 508 } 509 510 static struct dma_region *_get_dma_region(void) 511 { 512 int num = get_region_number(num_dma_regions); 513 514 if (num < 0) 515 return NULL; 516 517 return &dma_regions[num]; 518 } 519 520 static void list_dma_regions(void) 521 { 522 unsigned int num; 523 struct dma_region *region; 524 unsigned int i; 525 526 for (num = 0; num < num_dma_regions; num++) 527 { 528 printf("Region %d: ", num); 529 530 region = &dma_regions[num]; 531 532 if (l4_is_invalid_cap(region->mem)) 533 printf("(inactive)\n"); 534 else 535 { 536 printf("size = %d; align = %d; virtual = 0x%lx; physical = 0x%llx\ndata =", 537 region->size, region->align, region->vaddr, region->paddr); 538 539 for (i = 0; (i < region->size) && (i < 16); i++) 540 printf(" %02x", *((uint8_t *) region->vaddr + i)); 541 542 printf("\n"); 543 } 544 } 545 } 546 547 static void new_dma_channel(void *dma) 548 { 549 int num = get_channel_number(num_dma_channels); 550 551 if (num < 0) 552 return; 553 554 if (dma_channels[num] != NULL) 555 { 556 printf("Channel already defined.\n"); 557 return; 558 } 559 560 dma_channels[num] = dma_get_channel(dma, num, dma_irq); 561 } 562 563 static void new_dma_region(void) 564 { 565 struct dma_region *region = _get_dma_region(); 566 567 if (region == NULL) 568 { 569 list_dma_regions(); 570 return; 571 } 572 573 if (l4_is_valid_cap(region->mem)) 574 { 575 printf("Region already defined.\n"); 576 return; 577 } 578 579 if (!read_number("Size", ®ion->size)) 580 return; 581 582 if (!read_number("Alignment", ®ion->align)) 583 return; 584 585 if (get_dma_region(region->size, region->align, ®ion->vaddr, ®ion->paddr, ®ion->mem)) 586 printf("Could not allocate region.\n"); 587 } 588 589 static void set_dma_region(void) 590 { 591 char *token; 592 struct dma_region *region = _get_dma_region(); 593 FILE *fp; 594 595 if (region == NULL) 596 { 597 list_dma_regions(); 598 return; 599 } 600 601 if (l4_is_invalid_cap(region->mem)) 602 { 603 printf("Region needs creating.\n"); 604 return; 605 } 606 607 memset((void *) region->vaddr, 0, region->size); 608 609 if ((token = read_token("Filename")) == NULL) 610 return; 611 612 /* Populate the region from the file. */ 613 614 fp = fopen(token, "r"); 615 616 if (fp == NULL) 617 { 618 printf("File not readable.\n"); 619 return; 620 } 621 622 fread((char *) region->vaddr, sizeof(char), region->size, fp); 623 fclose(fp); 624 625 l4_cache_flush_data(region->vaddr, region->vaddr + region->size); 626 } 627 628 static void dma_transfer_data(void) 629 { 630 unsigned int count, to_transfer, transferred; 631 unsigned int source_address, destination_address, source_width, destination_width, 632 transfer_unit_size, request_type; 633 int source_increment, destination_increment; 634 void *channel = get_channel(num_dma_channels, dma_channels, NULL); 635 unsigned int i; 636 637 if (channel == NULL) 638 return; 639 640 if (!read_number("Source address", &source_address)) 641 return; 642 643 if (!read_number("Destination address", &destination_address)) 644 return; 645 646 if (!read_number("Transfer size", &count)) 647 return; 648 649 if (!read_increment("Source increment", &source_increment)) 650 return; 651 652 if (!read_increment("Destination increment", &destination_increment)) 653 return; 654 655 if (!read_number("Source width", &source_width)) 656 return; 657 658 if (!read_number("Destination width", &destination_width)) 659 return; 660 661 if (!read_number("Transfer unit size", &transfer_unit_size)) 662 return; 663 664 if (!read_number("Request type", &request_type)) 665 return; 666 667 /* Invalidate DMA region contents in case of transfers between regions. */ 668 669 for (i = 0; i < num_dma_regions; i++) 670 l4_cache_inv_data(dma_regions[i].vaddr, dma_regions[i].vaddr + dma_regions[i].size); 671 672 to_transfer = dma_transfer(channel, source_address, destination_address, 673 count, 674 source_increment, destination_increment, 675 source_width, destination_width, 676 transfer_unit_size, 677 request_type); 678 679 transferred = to_transfer ? count - dma_wait(channel) : 0; 680 681 printf("Transferred: %d\n", transferred); 682 } 683 684 685 686 /* GPIO operations. */ 687 688 static char get_gpio_dir_label(unsigned int value, unsigned int level) 689 { 690 return value == Fix_input ? (level ? 'I' : 'i') : (level ? 'O' : 'o'); 691 } 692 693 static char get_gpio_irq_label(unsigned int value) 694 { 695 switch (value) 696 { 697 case L4_IRQ_F_NEG_EDGE: return 'f'; 698 case L4_IRQ_F_POS_EDGE: return 'r'; 699 case L4_IRQ_F_LEVEL_LOW: return 'l'; 700 case L4_IRQ_F_LEVEL_HIGH: return 'h'; 701 default: return '?'; 702 } 703 } 704 705 static void list_gpios(void *gpio[]) 706 { 707 unsigned int port, pin; 708 unsigned int func, value, level; 709 710 printf("gpio: I = input high; i = input low; O = output high; o = output low\n" 711 "irq: h = high level; l = low level; r = rising edge; f = falling edge\n" 712 "alt: function number\n\n"); 713 714 /* Show pin numbering. */ 715 716 printf("Port/Pin "); 717 718 for (pin = 0; pin < 32; pin++) 719 { 720 if (!(pin % 10)) 721 printf(" %d", pin); 722 else 723 printf(" %d", pin % 10); 724 } 725 726 printf("\n"); 727 728 for (port = 0; port < num_gpio_ports; port++) 729 { 730 /* Show port and pin configuration. */ 731 732 printf("%c ", gpio_port_labels[port]); 733 734 for (pin = 0; pin < 32; pin++) 735 { 736 /* Pad below the first pin digit for multiples of ten other than zero. */ 737 738 if (pin && !(pin % 10)) 739 printf(" "); 740 741 gpio_config_pad_get(gpio[port], pin, &func, &value); 742 743 switch (func) 744 { 745 case Function_alt: printf(" %d", value); break; 746 case Function_irq: printf(" %c", get_gpio_irq_label(value)); break; 747 case Function_gpio: 748 { 749 level = gpio_get(gpio[port], pin); 750 printf(" %c", get_gpio_dir_label(value, level)); 751 break; 752 } 753 default: printf(" ?"); break; 754 } 755 } 756 757 printf("\n"); 758 } 759 } 760 761 static int get_port_and_pin(unsigned int *port, unsigned int *pin) 762 { 763 char *token; 764 765 if ((token = read_token("Port")) == NULL) 766 return 0; 767 768 if ((token[0] < 'A') || ((unsigned int) token[0] - (unsigned int) 'A' >= num_gpio_ports)) 769 { 770 printf("Bad port: %c\n", token[0]); 771 return 0; 772 } 773 774 *port = (unsigned int) token[0] - (unsigned int) 'A'; 775 776 if (!read_number("Pin", pin)) 777 return 0; 778 779 return 1; 780 } 781 782 static void set_gpio_alt_func(void *gpio[]) 783 { 784 unsigned int port, pin, value; 785 786 if (!get_port_and_pin(&port, &pin)) 787 return; 788 789 if (!read_number("Function", &value)) 790 return; 791 792 gpio_config_pad(gpio[port], pin, Function_alt, value); 793 } 794 795 static void set_gpio_pad(void *gpio[]) 796 { 797 char *token; 798 unsigned int port, pin, mode, value = 0; 799 800 if (!get_port_and_pin(&port, &pin)) 801 return; 802 803 if ((token = read_token("Mode")) == NULL) 804 return; 805 806 if (!strcmp(token, "in")) 807 mode = Fix_input; 808 else if (!strcmp(token, "irq")) 809 mode = Fix_irq; 810 else if (!strcmp(token, "out")) 811 { 812 mode = Fix_output; 813 814 if ((token = read_token(NULL)) != NULL) 815 value = atoi(token); 816 } 817 else 818 { 819 printf("Mode not recognised.\n"); 820 return; 821 } 822 823 gpio_setup(gpio[port], pin, mode, value); 824 } 825 826 static void set_gpio_pull(void *gpio[]) 827 { 828 char *token; 829 unsigned int port, pin, mode; 830 831 if (!get_port_and_pin(&port, &pin)) 832 return; 833 834 if ((token = read_token("Mode")) == NULL) 835 return; 836 837 if (!strcmp(token, "down")) 838 mode = Pull_down; 839 else if (!strcmp(token, "none")) 840 mode = Pull_none; 841 else if (!strcmp(token, "up")) 842 mode = Pull_up; 843 else 844 { 845 printf("Mode not recognised.\n"); 846 return; 847 } 848 849 gpio_config_pull(gpio[port], pin, mode); 850 } 851 852 853 854 /* I2C configuration. */ 855 856 static l4_uint32_t i2c_irq_start = 0, i2c_irq_end = 0; 857 858 /* I2C operations. */ 859 860 static int _i2c_read(void *channel, uint8_t *buf, unsigned length, 861 int stop, l4_cap_idx_t irqcap, unsigned timeout) 862 { 863 l4_msgtag_t tag; 864 865 i2c_start_read(channel, buf, length, stop); 866 867 while (!i2c_read_done(channel)) 868 { 869 tag = l4_irq_receive(irqcap, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4_timeout_from_us(timeout))); 870 871 // NOTE: Error not returned. 872 873 if (l4_ipc_error(tag, l4_utcb())) 874 break; 875 876 if (i2c_failed(channel)) 877 break; 878 879 i2c_read(channel); 880 } 881 882 if (stop) 883 i2c_stop(channel); 884 885 return i2c_have_read(channel); 886 } 887 888 static int _i2c_write(void *channel, uint8_t *buf, unsigned length, 889 int stop, l4_cap_idx_t irqcap, unsigned timeout) 890 { 891 l4_msgtag_t tag; 892 893 i2c_start_write(channel, buf, length, stop); 894 895 while (!i2c_write_done(channel)) 896 { 897 tag = l4_irq_receive(irqcap, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4_timeout_from_us(timeout))); 898 899 // NOTE: Error not returned. 900 901 if (l4_ipc_error(tag, l4_utcb())) 902 break; 903 904 if (i2c_failed(channel)) 905 break; 906 907 i2c_write(channel); 908 } 909 910 if (stop) 911 i2c_stop(channel); 912 913 return i2c_have_written(channel); 914 } 915 916 static void list_i2c_channels(void) 917 { 918 unsigned int num; 919 void *channel; 920 921 printf("i2c: channel\n\n"); 922 923 for (num = 0; num < num_i2c_channels; num++) 924 { 925 printf("Channel %d: ", num); 926 927 channel = i2c_channels[num]; 928 929 if (channel == NULL) 930 printf("(inactive)\n"); 931 else 932 printf("%d Hz\n", i2c_get_frequency(channel)); 933 } 934 } 935 936 static void new_i2c_channel(void *i2c) 937 { 938 l4_cap_idx_t irqcap; 939 int num = get_channel_number(num_i2c_channels); 940 941 if (num < 0) 942 return; 943 944 irqcap = l4re_util_cap_alloc(); 945 946 if (init_irq(num, irqcap, i2c_irq_start, i2c_irq_end)) 947 return; 948 949 i2c_channels[num] = i2c_get_channel(i2c, num); 950 i2c_irqs[num] = irqcap; 951 } 952 953 static void i2c_get(void) 954 { 955 void *channel; 956 int num; 957 uint8_t buffer[32]; 958 unsigned int address, reg, count; 959 int i, transferred; 960 961 channel = get_channel(num_i2c_channels, i2c_channels, &num); 962 963 if (channel == NULL) 964 return; 965 966 if (!read_encoded_number("Address", "%2x", &address)) 967 return; 968 969 if (address >= 0x80) 970 { 971 printf("Address must be less than 80.\n"); 972 return; 973 } 974 975 if (!read_encoded_number("Register", "%2x", ®)) 976 return; 977 978 if (!read_number(NULL, &count)) 979 count = 1; 980 981 buffer[0] = (uint8_t) (reg & 0xff); 982 983 i2c_set_target(channel, address); 984 985 if (!_i2c_write(channel, buffer, 1, 0, i2c_irqs[num], 1000000)) 986 { 987 printf("Register request failed.\n"); 988 return; 989 } 990 991 transferred = _i2c_read(channel, buffer, count, 1, i2c_irqs[num], 1000000); 992 993 if (!transferred) 994 { 995 printf("Register read failed.\n"); 996 return; 997 } 998 999 for (i = 0; i < transferred; i++) 1000 printf("%02x ", buffer[i]); 1001 printf("\n"); 1002 } 1003 1004 static void i2c_scan(void) 1005 { 1006 void *channel; 1007 unsigned int address; 1008 uint8_t buffer[1]; 1009 int num; 1010 1011 channel = get_channel(num_i2c_channels, i2c_channels, &num); 1012 1013 if (channel == NULL) 1014 return; 1015 1016 for (address = 0; address < 0x20; address++) 1017 printf("%02x ", address); 1018 printf("\n"); 1019 1020 for (address = 0; address < 0x20; address++) 1021 printf("-- "); 1022 1023 for (address = 0; address < 0x80; address++) 1024 { 1025 if ((address % 32) == 0) 1026 printf("\n"); 1027 1028 i2c_set_target(channel, address); 1029 1030 if (_i2c_read(channel, buffer, 1, 1, i2c_irqs[num], 1000)) 1031 printf("%02x ", address); 1032 else 1033 printf("-- "); 1034 } 1035 1036 printf("\n"); 1037 for (address = 0; address < 0x20; address++) 1038 printf("-- "); 1039 printf("\n\n"); 1040 } 1041 1042 1043 1044 /* SPI operations. */ 1045 1046 static void new_spi_channel(void *gpio[]) 1047 { 1048 unsigned int clock_port, clock_pin, data_port, data_pin, enable_port, enable_pin; 1049 int num = get_channel_number(num_spi_channels); 1050 uint32_t frequency; 1051 1052 if (num < 0) 1053 return; 1054 1055 if (!get_port_and_pin(&clock_port, &clock_pin)) 1056 return; 1057 1058 if (!get_port_and_pin(&data_port, &data_pin)) 1059 return; 1060 1061 if (!get_port_and_pin(&enable_port, &enable_pin)) 1062 return; 1063 1064 if (!read_number("Frequency", &frequency)) 1065 return; 1066 1067 spi_channels[num] = spi_get_channel(gpio[clock_port], clock_pin, 1068 gpio[data_port], data_pin, 1069 gpio[enable_port], enable_pin, 1070 frequency); 1071 } 1072 1073 static void spi_send_data(void) 1074 { 1075 void *channel = get_channel(num_spi_channels, spi_channels, NULL); 1076 int bytes; 1077 unsigned int byte; 1078 uint8_t buffer[256]; 1079 1080 bytes = 0; 1081 1082 while (read_encoded_number(NULL, "%2x", &byte)) 1083 { 1084 buffer[bytes] = (uint8_t) (byte & 0xff); 1085 bytes++; 1086 } 1087 1088 spi_send(channel, bytes, buffer); 1089 } 1090 1091 1092 1093 /* Command processing. */ 1094 1095 static void handle_aic(void *aic) 1096 { 1097 char *token; 1098 1099 if ((token = read_token(NULL)) != NULL) 1100 { 1101 if (!strcmp(token, "l") || !strcmp(token, "list")) 1102 list_channels(num_aic_channels, aic_channels); 1103 else if (!strcmp(token, "c") || !strcmp(token, "channel")) 1104 new_aic_channel(aic); 1105 else if (!strcmp(token, "s") || !strcmp(token, "set")) 1106 set_aic_buffer(); 1107 else if (!strcmp(token, "t") || !strcmp(token, "transfer")) 1108 aic_transfer_data(); 1109 else 1110 printf("aic channel | list | set | transfer\n"); 1111 } 1112 else 1113 list_channels(num_aic_channels, aic_channels); 1114 } 1115 1116 static void handle_cpm(void *cpm) 1117 { 1118 char *token; 1119 1120 if ((token = read_token(NULL)) != NULL) 1121 { 1122 if (!strcmp(token, "l") || !strcmp(token, "list")) 1123 list_clocks(cpm); 1124 else if (!strcmp(token, "f") || !strcmp(token, "frequency")) 1125 set_frequency(cpm); 1126 else if (!strcmp(token, "p") || !strcmp(token, "parameters")) 1127 set_parameters(cpm); 1128 else if (!strcmp(token, "s") || !strcmp(token, "source")) 1129 set_source(cpm); 1130 else if (!strcmp(token, "start")) 1131 start_clock(cpm); 1132 else if (!strcmp(token, "stop")) 1133 stop_clock(cpm); 1134 else 1135 printf("cpm list | frequency | parameters | source | start | stop\n"); 1136 } 1137 else 1138 list_clocks(cpm); 1139 } 1140 1141 static void handle_dma(void *dma) 1142 { 1143 char *token; 1144 1145 if ((token = read_token(NULL)) != NULL) 1146 { 1147 if (!strcmp(token, "l") || !strcmp(token, "list")) 1148 list_channels(num_dma_channels, dma_channels); 1149 else if (!strcmp(token, "c") || !strcmp(token, "channel")) 1150 new_dma_channel(dma); 1151 else if (!strcmp(token, "r") || !strcmp(token, "region")) 1152 new_dma_region(); 1153 else if (!strcmp(token, "s") || !strcmp(token, "set")) 1154 set_dma_region(); 1155 else if (!strcmp(token, "t") || !strcmp(token, "transfer")) 1156 dma_transfer_data(); 1157 else 1158 printf("dma channel | list | region | set | transfer\n"); 1159 } 1160 else 1161 list_channels(num_dma_channels, dma_channels); 1162 } 1163 1164 static void handle_gpio(void *gpio[]) 1165 { 1166 char *token; 1167 1168 if ((token = read_token(NULL)) != NULL) 1169 { 1170 if (!strcmp(token, "l") || !strcmp(token, "list")) 1171 list_gpios(gpio); 1172 else if (!strcmp(token, "a") || !strcmp(token, "alt")) 1173 set_gpio_alt_func(gpio); 1174 else if (!strcmp(token, "i") || !strcmp(token, "io")) 1175 set_gpio_pad(gpio); 1176 else if (!strcmp(token, "p") || !strcmp(token, "pull")) 1177 set_gpio_pull(gpio); 1178 else 1179 printf("gpio list | alt | io | pull\n"); 1180 } 1181 else 1182 list_gpios(gpio); 1183 } 1184 1185 static void handle_i2c(void *i2c) 1186 { 1187 char *token; 1188 1189 if ((token = read_token(NULL)) != NULL) 1190 { 1191 if (!strcmp(token, "l") || !strcmp(token, "list")) 1192 list_i2c_channels(); 1193 else if (!strcmp(token, "c") || !strcmp(token, "channel")) 1194 new_i2c_channel(i2c); 1195 else if (!strcmp(token, "g") || !strcmp(token, "get")) 1196 i2c_get(); 1197 else if (!strcmp(token, "s") || !strcmp(token, "scan")) 1198 i2c_scan(); 1199 else 1200 printf("i2c channel | get | list | scan\n"); 1201 } 1202 else 1203 list_i2c_channels(); 1204 } 1205 1206 static void handle_spi(void *gpio[]) 1207 { 1208 char *token; 1209 1210 if ((token = read_token(NULL)) != NULL) 1211 { 1212 if (!strcmp(token, "l") || !strcmp(token, "list")) 1213 list_channels(num_spi_channels, spi_channels); 1214 else if (!strcmp(token, "c") || !strcmp(token, "channel")) 1215 new_spi_channel(gpio); 1216 else if (!strcmp(token, "s") || !strcmp(token, "send")) 1217 spi_send_data(); 1218 else 1219 printf("spi channel | list | send\n"); 1220 } 1221 else 1222 list_channels(num_spi_channels, spi_channels); 1223 } 1224 1225 1226 1227 int main(void) 1228 { 1229 l4_addr_t aic_base = 0, aic_base_end = 0; 1230 l4_addr_t aic_phys_base = 0, aic_phys_base_end = 0; 1231 l4_addr_t cpm_base = 0, cpm_base_end = 0; 1232 l4_addr_t dma_base = 0, dma_base_end = 0; 1233 l4_addr_t gpio_base = 0, gpio_base_end = 0; 1234 l4_addr_t i2c_base = 0, i2c_base_end = 0; 1235 void *aic, *cpm, *dma, *gpio[num_gpio_ports], *i2c; 1236 int result = 0; 1237 unsigned int port; 1238 1239 icucap = l4re_env_get_cap("icu"); 1240 1241 /* Obtain resource details describing I/O memory. */ 1242 1243 printf("Access CPM...\n"); 1244 1245 if ((result = get_memory(memory_regions[CPM], &cpm_base, &cpm_base_end)) < 0) 1246 return 1; 1247 1248 printf("CPM at 0x%lx...0x%lx.\n", cpm_base, cpm_base_end); 1249 1250 cpm = cpm_init(cpm_base); 1251 1252 printf("Access DMA...\n"); 1253 1254 if ((result = get_memory(memory_regions[DMA], &dma_base, &dma_base_end)) < 0) 1255 return 1; 1256 1257 printf("DMA at 0x%lx...0x%lx.\n", dma_base, dma_base_end); 1258 1259 dma = dma_init(dma_base, dma_base_end, cpm); 1260 1261 if (get_irq(memory_regions[DMA], &dma_irq_start, &dma_irq_end) < 0) 1262 return 1; 1263 1264 printf("IRQ range at %d...%d.\n", dma_irq_start, dma_irq_end); 1265 1266 if (init_dma()) 1267 return 1; 1268 1269 dma_enable(dma); 1270 1271 printf("Access GPIO...\n"); 1272 1273 if ((result = get_memory(memory_regions[GPIO], &gpio_base, &gpio_base_end)) < 0) 1274 return 1; 1275 1276 printf("GPIO at 0x%lx...0x%lx.\n", gpio_base, gpio_base_end); 1277 1278 for (port = 0; port < num_gpio_ports; port++) 1279 gpio[port] = gpio_init(gpio_base + port * 0x100, gpio_base + (port + 1) * 0x100, 1280 32, gpio_ports[port].pull_ups, gpio_ports[port].pull_downs); 1281 1282 printf("Access I2C...\n"); 1283 1284 if ((result = get_memory(memory_regions[I2C], &i2c_base, &i2c_base_end)) < 0) 1285 return 1; 1286 1287 printf("I2C at 0x%lx...0x%lx.\n", i2c_base, i2c_base_end); 1288 1289 i2c = i2c_init(i2c_base, i2c_base_end, cpm, 100000); 1290 1291 if (get_irq(memory_regions[I2C], &i2c_irq_start, &i2c_irq_end) < 0) 1292 return 1; 1293 1294 printf("IRQ range at %d...%d.\n", i2c_irq_start, i2c_irq_end); 1295 1296 printf("Access AIC...\n"); 1297 1298 if ((result = get_memory_complete(memory_regions[AIC], &aic_base, &aic_base_end, 1299 &aic_phys_base, &aic_phys_base_end)) < 0) 1300 return 1; 1301 1302 printf("AIC at 0x%lx...0x%lx.\n", aic_base, aic_base_end); 1303 1304 aic = aic_init(aic_phys_base, aic_base, aic_base_end, cpm); 1305 1306 if (get_irq(memory_regions[AIC], &aic_irq_start, &aic_irq_end) < 0) 1307 return 1; 1308 1309 printf("IRQ range at %d...%d.\n", aic_irq_start, aic_irq_end); 1310 1311 /* Start the interactive session. */ 1312 1313 printf("aic, cpm, dma, gpio, i2c, spi\n"); 1314 1315 while (1) 1316 { 1317 char cmdline[256], *token; 1318 1319 printf("> "); 1320 1321 token = fgets(cmdline, 64, stdin); 1322 1323 if (token == NULL) 1324 break; 1325 1326 if ((token = strtok(cmdline, delimiters)) == NULL) 1327 continue; 1328 1329 /* AIC/I2S commands. */ 1330 1331 if (!strcmp(token, "a") || !strcmp(token, "aic") || !strcmp(token, "i2s")) 1332 handle_aic(aic); 1333 1334 /* CPM commands. */ 1335 1336 else if (!strcmp(token, "c") || !strcmp(token, "cpm")) 1337 handle_cpm(cpm); 1338 1339 /* DMA commands. */ 1340 1341 else if (!strcmp(token, "d") || !strcmp(token, "dma")) 1342 handle_dma(dma); 1343 1344 /* GPIO commands. */ 1345 1346 else if (!strcmp(token, "g") || !strcmp(token, "gpio")) 1347 handle_gpio(gpio); 1348 1349 /* I2C commands. */ 1350 1351 else if (!strcmp(token, "i") || !strcmp(token, "i2c")) 1352 handle_i2c(i2c); 1353 1354 /* SPI commands. */ 1355 1356 else if (!strcmp(token, "s") || !strcmp(token, "spi")) 1357 handle_spi(gpio); 1358 1359 else 1360 printf("Command?\n"); 1361 } 1362 1363 printf("End of session.\n"); 1364 return 0; 1365 }