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 static struct dma_region *_get_dma_region(void) 222 { 223 int num = get_region_number(num_dma_regions); 224 225 if (num < 0) 226 return NULL; 227 228 return &dma_regions[num]; 229 } 230 231 232 233 /* AIC/I2S operations. */ 234 235 static void new_aic_channel(void *aic) 236 { 237 int num = get_channel_number(num_aic_channels); 238 void *channel; 239 240 if (num < 0) 241 return; 242 243 channel = get_channel(num_dma_channels, dma_channels, NULL); 244 245 if (channel == NULL) 246 return; 247 248 aic_channels[num] = aic_get_channel(aic, num, channel); 249 } 250 251 static void aic_transfer_data(void) 252 { 253 void *channel = get_channel(num_aic_channels, aic_channels, NULL); 254 struct dma_region *region; 255 uint32_t count, rate, resolution, transferred; 256 257 if (channel == NULL) 258 return; 259 260 region = _get_dma_region(); 261 262 if (region == NULL) 263 return; 264 265 if (!read_number("Sample size", &count)) 266 return; 267 268 if (!read_number("Sample rate", &rate)) 269 return; 270 271 if (!read_number("Sample resolution", &resolution)) 272 return; 273 274 transferred = aic_transfer(channel, region->paddr, count, rate, resolution); 275 276 printf("Transferred: %d\n", transferred); 277 } 278 279 280 281 /* CPM operations. */ 282 283 static const char *clock_id(enum Clock_identifiers clock) 284 { 285 for (int i = 0; clocks[i].id != NULL; i++) 286 if (clock == clocks[i].clock) 287 return clocks[i].id; 288 289 return NULL; 290 } 291 292 static enum Clock_identifiers get_clock(char *id) 293 { 294 if (id != NULL) 295 { 296 for (int i = 0; clocks[i].id != NULL; i++) 297 if (!strcmp(id, clocks[i].id)) 298 return clocks[i].clock; 299 } 300 301 return Clock_undefined; 302 } 303 304 static const char list_clocks_separator[] = "--------------------------------"; 305 306 #define sep(x) (list_clocks_separator + sizeof(list_clocks_separator) - 1 - x) 307 308 static void list_clocks(void *cpm) 309 { 310 /* Read information from the clock and power management unit. */ 311 312 printf("%-5s %-10s %-7s %-6s %-12s %-12s %-24s %-12s %-3s\n" 313 "%-5s %-10s %-7s %-6s %-12s %-12s %-24s %-12s %-3s\n", 314 "Id", "Clock", "Type", "Source", "Source Clock", "Source Freq.", 315 "Parameters", "Frequency", "On", 316 sep(5), sep(10), sep(7), sep(6), sep(12), sep(12), 317 sep(24), sep(12), sep(3)); 318 319 for (int i = 0; clocks[i].id != NULL; i++) 320 { 321 uint32_t parameters[4]; 322 char parameter_str[25] = {0}; 323 const char *source_id = clock_id(cpm_get_source_clock(cpm, clocks[i].clock)); 324 int num_parameters = cpm_get_parameters(cpm, clocks[i].clock, parameters); 325 326 for (int p = 0, pos = 0; p < num_parameters; p++) 327 { 328 int result = sprintf(parameter_str + pos, "%-7d ", parameters[p]); 329 if (result < 0) 330 break; 331 pos += result; 332 } 333 334 printf("%-5s %-10s %-7s %-6d %-12s %-12lld %-24s %-12lld %-3s\n", 335 clocks[i].id, 336 clocks[i].name, 337 cpm_clock_type(cpm, clocks[i].clock), 338 cpm_get_source(cpm, clocks[i].clock), 339 source_id != NULL ? source_id : "...", 340 cpm_get_source_frequency(cpm, clocks[i].clock), 341 parameter_str, 342 cpm_get_frequency(cpm, clocks[i].clock), 343 cpm_have_clock(cpm, clocks[i].clock) ? "on" : "off"); 344 } 345 } 346 347 static enum Clock_identifiers get_clock_by_name(void) 348 { 349 char *token; 350 enum Clock_identifiers clock; 351 352 if ((token = read_token("Clock")) == NULL) 353 return Clock_undefined; 354 355 clock = get_clock(token); 356 357 if (clock == Clock_undefined) 358 { 359 printf("Unrecognised clock: %s\n", token); 360 return Clock_undefined; 361 } 362 363 return clock; 364 } 365 366 static void set_frequency(void *cpm) 367 { 368 enum Clock_identifiers clock; 369 unsigned int frequency; 370 371 clock = get_clock_by_name(); 372 373 if (clock == Clock_undefined) 374 return; 375 376 if (!read_number("Frequency", &frequency)) 377 return; 378 379 if (!cpm_set_frequency(cpm, clock, frequency)) 380 printf("Frequency not set.\n"); 381 } 382 383 static void set_parameters(void *cpm) 384 { 385 char *token; 386 enum Clock_identifiers clock; 387 uint32_t parameters[4]; 388 int num_parameters; 389 390 clock = get_clock_by_name(); 391 392 if (clock == Clock_undefined) 393 return; 394 395 for (num_parameters = 0; num_parameters < 4; num_parameters++) 396 { 397 if ((token = read_token(NULL)) == NULL) 398 break; 399 400 parameters[num_parameters] = atoi(token); 401 } 402 403 if (!num_parameters) 404 { 405 printf("Parameters?\n"); 406 return; 407 } 408 409 if (!cpm_set_parameters(cpm, clock, num_parameters, parameters)) 410 printf("Too few or invalid parameters.\n"); 411 } 412 413 static void set_source(void *cpm) 414 { 415 enum Clock_identifiers clock; 416 unsigned int source; 417 418 clock = get_clock_by_name(); 419 420 if (clock == Clock_undefined) 421 return; 422 423 if (!read_number("Source", &source)) 424 return; 425 426 cpm_set_source(cpm, clock, source); 427 } 428 429 static void start_clock(void *cpm) 430 { 431 enum Clock_identifiers clock; 432 433 clock = get_clock_by_name(); 434 435 if (clock == Clock_undefined) 436 return; 437 438 cpm_start_clock(cpm, clock); 439 } 440 441 static void stop_clock(void *cpm) 442 { 443 enum Clock_identifiers clock; 444 445 clock = get_clock_by_name(); 446 447 if (clock == Clock_undefined) 448 return; 449 450 cpm_stop_clock(cpm, clock); 451 } 452 453 454 455 /* DMA configuration. */ 456 457 static l4_uint32_t dma_irq_start = 0, dma_irq_end = 0; 458 459 /* DMA operations. */ 460 461 static int init_dma(void) 462 { 463 unsigned int i; 464 465 for (i = 0; i < num_dma_regions; i++) 466 dma_regions[i].mem = L4_INVALID_CAP; 467 468 /* Here, only one IRQ is used. */ 469 470 dma_irq = l4re_util_cap_alloc(); 471 return init_irq(0, dma_irq, dma_irq_start, dma_irq_end); 472 } 473 474 static void list_dma_regions(void) 475 { 476 unsigned int num; 477 struct dma_region *region; 478 unsigned int i; 479 480 for (num = 0; num < num_dma_regions; num++) 481 { 482 printf("Region %d: ", num); 483 484 region = &dma_regions[num]; 485 486 if (l4_is_invalid_cap(region->mem)) 487 printf("(inactive)\n"); 488 else 489 { 490 printf("size = %d; align = %d; virtual = 0x%lx; physical = 0x%llx\ndata =", 491 region->size, region->align, region->vaddr, region->paddr); 492 493 for (i = 0; (i < region->size) && (i < 16); i++) 494 printf(" %02x", *((uint8_t *) region->vaddr + i)); 495 496 printf("\n"); 497 } 498 } 499 } 500 501 static void new_dma_channel(void *dma) 502 { 503 int num = get_channel_number(num_dma_channels); 504 505 if (num < 0) 506 return; 507 508 if (dma_channels[num] != NULL) 509 { 510 printf("Channel already defined.\n"); 511 return; 512 } 513 514 dma_channels[num] = dma_get_channel(dma, num, dma_irq); 515 } 516 517 static void new_dma_region(void) 518 { 519 struct dma_region *region = _get_dma_region(); 520 521 if (region == NULL) 522 { 523 list_dma_regions(); 524 return; 525 } 526 527 if (l4_is_valid_cap(region->mem)) 528 { 529 printf("Region already defined.\n"); 530 return; 531 } 532 533 if (!read_number("Size", ®ion->size)) 534 return; 535 536 if (!read_number("Alignment", ®ion->align)) 537 return; 538 539 if (get_dma_region(region->size, region->align, ®ion->vaddr, ®ion->paddr, ®ion->mem)) 540 printf("Could not allocate region.\n"); 541 } 542 543 static void set_dma_region(void) 544 { 545 char *token; 546 struct dma_region *region = _get_dma_region(); 547 FILE *fp; 548 549 if (region == NULL) 550 { 551 list_dma_regions(); 552 return; 553 } 554 555 if (l4_is_invalid_cap(region->mem)) 556 { 557 printf("Region needs creating.\n"); 558 return; 559 } 560 561 memset((void *) region->vaddr, 0, region->size); 562 563 if ((token = read_token("Filename")) == NULL) 564 return; 565 566 /* Populate the region from the file. */ 567 568 fp = fopen(token, "r"); 569 570 if (fp == NULL) 571 { 572 printf("File not readable.\n"); 573 return; 574 } 575 576 fread((char *) region->vaddr, sizeof(char), region->size, fp); 577 fclose(fp); 578 579 l4_cache_flush_data(region->vaddr, region->vaddr + region->size); 580 } 581 582 static void dma_transfer_data(void) 583 { 584 uint32_t count, to_transfer, transferred; 585 unsigned int source_address, destination_address, source_width, destination_width, 586 transfer_unit_size, request_type; 587 int source_increment, destination_increment; 588 void *channel = get_channel(num_dma_channels, dma_channels, NULL); 589 unsigned int i; 590 591 if (channel == NULL) 592 return; 593 594 if (!read_number("Source address", &source_address)) 595 return; 596 597 if (!read_number("Destination address", &destination_address)) 598 return; 599 600 if (!read_number("Transfer size", &count)) 601 return; 602 603 if (!read_increment("Source increment", &source_increment)) 604 return; 605 606 if (!read_increment("Destination increment", &destination_increment)) 607 return; 608 609 if (!read_number("Source width", &source_width)) 610 return; 611 612 if (!read_number("Destination width", &destination_width)) 613 return; 614 615 if (!read_number("Transfer unit size", &transfer_unit_size)) 616 return; 617 618 if (!read_number("Request type", &request_type)) 619 return; 620 621 /* Invalidate DMA region contents in case of transfers between regions. */ 622 623 for (i = 0; i < num_dma_regions; i++) 624 l4_cache_inv_data(dma_regions[i].vaddr, dma_regions[i].vaddr + dma_regions[i].size); 625 626 to_transfer = dma_transfer(channel, source_address, destination_address, 627 count, 628 source_increment, destination_increment, 629 source_width, destination_width, 630 transfer_unit_size, 631 request_type); 632 633 transferred = to_transfer ? count - dma_wait(channel) : 0; 634 635 printf("Transferred: %d\n", transferred); 636 } 637 638 639 640 /* GPIO operations. */ 641 642 static char get_gpio_dir_label(unsigned int value, unsigned int level) 643 { 644 return value == Fix_input ? (level ? 'I' : 'i') : (level ? 'O' : 'o'); 645 } 646 647 static char get_gpio_irq_label(unsigned int value) 648 { 649 switch (value) 650 { 651 case L4_IRQ_F_NEG_EDGE: return 'f'; 652 case L4_IRQ_F_POS_EDGE: return 'r'; 653 case L4_IRQ_F_LEVEL_LOW: return 'l'; 654 case L4_IRQ_F_LEVEL_HIGH: return 'h'; 655 default: return '?'; 656 } 657 } 658 659 static void list_gpios(void *gpio[]) 660 { 661 unsigned int port, pin; 662 unsigned int func, value, level; 663 664 printf("gpio: I = input high; i = input low; O = output high; o = output low\n" 665 "irq: h = high level; l = low level; r = rising edge; f = falling edge\n" 666 "alt: function number\n\n"); 667 668 /* Show pin numbering. */ 669 670 printf("Port/Pin "); 671 672 for (pin = 0; pin < 32; pin++) 673 { 674 if (!(pin % 10)) 675 printf(" %d", pin); 676 else 677 printf(" %d", pin % 10); 678 } 679 680 printf("\n"); 681 682 for (port = 0; port < num_gpio_ports; port++) 683 { 684 /* Show port and pin configuration. */ 685 686 printf("%c ", gpio_port_labels[port]); 687 688 for (pin = 0; pin < 32; pin++) 689 { 690 /* Pad below the first pin digit for multiples of ten other than zero. */ 691 692 if (pin && !(pin % 10)) 693 printf(" "); 694 695 gpio_config_pad_get(gpio[port], pin, &func, &value); 696 697 switch (func) 698 { 699 case Function_alt: printf(" %d", value); break; 700 case Function_irq: printf(" %c", get_gpio_irq_label(value)); break; 701 case Function_gpio: 702 { 703 level = gpio_get(gpio[port], pin); 704 printf(" %c", get_gpio_dir_label(value, level)); 705 break; 706 } 707 default: printf(" ?"); break; 708 } 709 } 710 711 printf("\n"); 712 } 713 } 714 715 static int get_port_and_pin(unsigned int *port, unsigned int *pin) 716 { 717 char *token; 718 719 if ((token = read_token("Port")) == NULL) 720 return 0; 721 722 if ((token[0] < 'A') || ((unsigned int) token[0] - (unsigned int) 'A' >= num_gpio_ports)) 723 { 724 printf("Bad port: %c\n", token[0]); 725 return 0; 726 } 727 728 *port = (unsigned int) token[0] - (unsigned int) 'A'; 729 730 if (!read_number("Pin", pin)) 731 return 0; 732 733 return 1; 734 } 735 736 static void set_gpio_alt_func(void *gpio[]) 737 { 738 unsigned int port, pin, value; 739 740 if (!get_port_and_pin(&port, &pin)) 741 return; 742 743 if (!read_number("Function", &value)) 744 return; 745 746 gpio_config_pad(gpio[port], pin, Function_alt, value); 747 } 748 749 static void set_gpio_pad(void *gpio[]) 750 { 751 char *token; 752 unsigned int port, pin, mode, value = 0; 753 754 if (!get_port_and_pin(&port, &pin)) 755 return; 756 757 if ((token = read_token("Mode")) == NULL) 758 return; 759 760 if (!strcmp(token, "in")) 761 mode = Fix_input; 762 else if (!strcmp(token, "irq")) 763 mode = Fix_irq; 764 else if (!strcmp(token, "out")) 765 { 766 mode = Fix_output; 767 768 if ((token = read_token(NULL)) != NULL) 769 value = atoi(token); 770 } 771 else 772 { 773 printf("Mode not recognised.\n"); 774 return; 775 } 776 777 gpio_setup(gpio[port], pin, mode, value); 778 } 779 780 static void set_gpio_pull(void *gpio[]) 781 { 782 char *token; 783 unsigned int port, pin, mode; 784 785 if (!get_port_and_pin(&port, &pin)) 786 return; 787 788 if ((token = read_token("Mode")) == NULL) 789 return; 790 791 if (!strcmp(token, "down")) 792 mode = Pull_down; 793 else if (!strcmp(token, "none")) 794 mode = Pull_none; 795 else if (!strcmp(token, "up")) 796 mode = Pull_up; 797 else 798 { 799 printf("Mode not recognised.\n"); 800 return; 801 } 802 803 gpio_config_pull(gpio[port], pin, mode); 804 } 805 806 807 808 /* I2C configuration. */ 809 810 static l4_uint32_t i2c_irq_start = 0, i2c_irq_end = 0; 811 812 /* I2C operations. */ 813 814 static int _i2c_read(void *channel, uint8_t *buf, unsigned length, 815 int stop, l4_cap_idx_t irqcap, unsigned timeout) 816 { 817 l4_msgtag_t tag; 818 819 i2c_start_read(channel, buf, length, stop); 820 821 while (!i2c_read_done(channel)) 822 { 823 tag = l4_irq_receive(irqcap, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4_timeout_from_us(timeout))); 824 825 // NOTE: Error not returned. 826 827 if (l4_ipc_error(tag, l4_utcb())) 828 break; 829 830 if (i2c_failed(channel)) 831 break; 832 833 i2c_read(channel); 834 } 835 836 if (stop) 837 i2c_stop(channel); 838 839 return i2c_have_read(channel); 840 } 841 842 static int _i2c_write(void *channel, uint8_t *buf, unsigned length, 843 int stop, l4_cap_idx_t irqcap, unsigned timeout) 844 { 845 l4_msgtag_t tag; 846 847 i2c_start_write(channel, buf, length, stop); 848 849 while (!i2c_write_done(channel)) 850 { 851 tag = l4_irq_receive(irqcap, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4_timeout_from_us(timeout))); 852 853 // NOTE: Error not returned. 854 855 if (l4_ipc_error(tag, l4_utcb())) 856 break; 857 858 if (i2c_failed(channel)) 859 break; 860 861 i2c_write(channel); 862 } 863 864 if (stop) 865 i2c_stop(channel); 866 867 return i2c_have_written(channel); 868 } 869 870 static void list_i2c_channels(void) 871 { 872 unsigned int num; 873 void *channel; 874 875 printf("i2c: channel\n\n"); 876 877 for (num = 0; num < num_i2c_channels; num++) 878 { 879 printf("Channel %d: ", num); 880 881 channel = i2c_channels[num]; 882 883 if (channel == NULL) 884 printf("(inactive)\n"); 885 else 886 printf("%d Hz\n", i2c_get_frequency(channel)); 887 } 888 } 889 890 static void new_i2c_channel(void *i2c) 891 { 892 l4_cap_idx_t irqcap; 893 int num = get_channel_number(num_i2c_channels); 894 895 if (num < 0) 896 return; 897 898 irqcap = l4re_util_cap_alloc(); 899 900 if (init_irq(num, irqcap, i2c_irq_start, i2c_irq_end)) 901 return; 902 903 i2c_channels[num] = i2c_get_channel(i2c, num); 904 i2c_irqs[num] = irqcap; 905 } 906 907 static void i2c_get(void) 908 { 909 void *channel; 910 int num; 911 uint8_t buffer[32]; 912 unsigned int address, reg, count; 913 int i, transferred; 914 915 channel = get_channel(num_i2c_channels, i2c_channels, &num); 916 917 if (channel == NULL) 918 return; 919 920 if (!read_encoded_number("Address", "%2x", &address)) 921 return; 922 923 if (address >= 0x80) 924 { 925 printf("Address must be less than 80.\n"); 926 return; 927 } 928 929 if (!read_encoded_number("Register", "%2x", ®)) 930 return; 931 932 if (!read_number(NULL, &count)) 933 count = 1; 934 935 buffer[0] = (uint8_t) (reg & 0xff); 936 937 i2c_set_target(channel, address); 938 939 if (!_i2c_write(channel, buffer, 1, 0, i2c_irqs[num], 1000000)) 940 { 941 printf("Register request failed.\n"); 942 return; 943 } 944 945 transferred = _i2c_read(channel, buffer, count, 1, i2c_irqs[num], 1000000); 946 947 if (!transferred) 948 { 949 printf("Register read failed.\n"); 950 return; 951 } 952 953 for (i = 0; i < transferred; i++) 954 printf("%02x ", buffer[i]); 955 printf("\n"); 956 } 957 958 static void i2c_scan(void) 959 { 960 void *channel; 961 unsigned int address; 962 uint8_t buffer[1]; 963 int num; 964 965 channel = get_channel(num_i2c_channels, i2c_channels, &num); 966 967 if (channel == NULL) 968 return; 969 970 for (address = 0; address < 0x20; address++) 971 printf("%02x ", address); 972 printf("\n"); 973 974 for (address = 0; address < 0x20; address++) 975 printf("-- "); 976 977 for (address = 0; address < 0x80; address++) 978 { 979 if ((address % 32) == 0) 980 printf("\n"); 981 982 i2c_set_target(channel, address); 983 984 if (_i2c_read(channel, buffer, 1, 1, i2c_irqs[num], 1000)) 985 printf("%02x ", address); 986 else 987 printf("-- "); 988 } 989 990 printf("\n"); 991 for (address = 0; address < 0x20; address++) 992 printf("-- "); 993 printf("\n\n"); 994 } 995 996 997 998 /* SPI operations. */ 999 1000 static void new_spi_channel(void *spi, void *gpio[]) 1001 { 1002 unsigned int control_port, control_pin, control_alt_func_input; 1003 int control_alt_func; 1004 void *control_chip; 1005 int num = get_channel_number(num_spi_channels); 1006 void *channel; 1007 uint32_t frequency; 1008 1009 if (num < 0) 1010 return; 1011 1012 channel = get_channel(num_dma_channels, dma_channels, NULL); 1013 1014 if (channel == NULL) 1015 return; 1016 1017 if (!read_number("Frequency", &frequency)) 1018 return; 1019 1020 if (!get_port_and_pin(&control_port, &control_pin)) 1021 control_chip = NULL; 1022 else 1023 control_chip = gpio[control_port]; 1024 1025 if (!read_number("Function", &control_alt_func_input)) 1026 control_alt_func = -1; 1027 else 1028 control_alt_func = control_alt_func_input; 1029 1030 spi_channels[num] = spi_get_channel(spi, num, channel, frequency, 1031 control_chip, control_pin, 1032 control_alt_func); 1033 } 1034 1035 static void new_spi_channel_gpio(void *gpio[]) 1036 { 1037 unsigned int clock_port, clock_pin, data_port, data_pin, enable_port, 1038 enable_pin, control_port, control_pin; 1039 void *control_chip; 1040 int num = get_channel_number(num_spi_channels); 1041 uint32_t frequency; 1042 1043 if (num < 0) 1044 return; 1045 1046 if (!read_number("Frequency", &frequency)) 1047 return; 1048 1049 if (!get_port_and_pin(&clock_port, &clock_pin)) 1050 return; 1051 1052 if (!get_port_and_pin(&data_port, &data_pin)) 1053 return; 1054 1055 if (!get_port_and_pin(&enable_port, &enable_pin)) 1056 return; 1057 1058 if (!get_port_and_pin(&control_port, &control_pin)) 1059 control_chip = NULL; 1060 else 1061 control_chip = gpio[control_port]; 1062 1063 spi_channels[num] = spi_get_channel_gpio(frequency, 1064 gpio[clock_port], clock_pin, 1065 gpio[data_port], data_pin, 1066 gpio[enable_port], enable_pin, 1067 control_chip, control_pin); 1068 } 1069 1070 static void spi_control(int acquire) 1071 { 1072 unsigned int level; 1073 void *channel = get_channel(num_spi_channels, spi_channels, NULL); 1074 1075 if (acquire) 1076 { 1077 if (!read_number("Level", &level)) 1078 return; 1079 1080 spi_acquire_control(channel, level); 1081 } 1082 else 1083 spi_release_control(channel); 1084 } 1085 1086 static void spi_send_data_gpio(void) 1087 { 1088 void *channel = get_channel(num_spi_channels, spi_channels, NULL); 1089 int bytes; 1090 unsigned int byte; 1091 uint8_t buffer[256]; 1092 1093 bytes = 0; 1094 1095 while (read_encoded_number(NULL, "%2x", &byte)) 1096 { 1097 buffer[bytes] = (uint8_t) (byte & 0xff); 1098 bytes++; 1099 } 1100 1101 spi_send_gpio(channel, bytes, buffer); 1102 } 1103 1104 static void spi_send_data_units(void) 1105 { 1106 void *channel = get_channel(num_spi_channels, spi_channels, NULL); 1107 unsigned int char_size, unit_size, value; 1108 uint8_t buffer[256]; 1109 int byte = 0; 1110 1111 if (!read_number("Unit size", &unit_size)) 1112 return; 1113 1114 if (!read_number("Character size", &char_size)) 1115 return; 1116 1117 /* Read hex digits for bytes. Multiple bytes make up each unit and are read 1118 from most to least significant. Where the unit size exceeds the character 1119 size, the last bit before the character indicates the GPC bit. */ 1120 1121 while ((byte < 256) && read_encoded_number(NULL, "%2x", &value)) 1122 buffer[byte++] = value; 1123 1124 spi_send_units(channel, byte, (uint8_t *) buffer, unit_size, char_size); 1125 } 1126 1127 static void spi_transfer_data(void) 1128 { 1129 void *channel = get_channel(num_spi_channels, spi_channels, NULL); 1130 struct dma_region *region, *desc_region; 1131 unsigned int char_size, unit_size; 1132 uint32_t count, transferred; 1133 1134 if (channel == NULL) 1135 return; 1136 1137 region = _get_dma_region(); 1138 1139 if (region == NULL) 1140 return; 1141 1142 if (!read_number("Transfer size", &count)) 1143 return; 1144 1145 if (!read_number("Unit size", &unit_size)) 1146 return; 1147 1148 if (!read_number("Character size", &char_size)) 1149 return; 1150 1151 desc_region = _get_dma_region(); 1152 1153 transferred = spi_transfer(channel, region->paddr, count, unit_size, char_size, 1154 desc_region != NULL ? desc_region->vaddr : 0, 1155 desc_region != NULL ? desc_region->paddr : 0); 1156 1157 printf("Transferred: %d\n", transferred); 1158 } 1159 1160 1161 1162 /* Command processing. */ 1163 1164 static void handle_aic(void *aic) 1165 { 1166 char *token; 1167 1168 if ((token = read_token(NULL)) != NULL) 1169 { 1170 if (!strcmp(token, "l") || !strcmp(token, "list")) 1171 list_channels(num_aic_channels, aic_channels); 1172 else if (!strcmp(token, "c") || !strcmp(token, "channel")) 1173 new_aic_channel(aic); 1174 else if (!strcmp(token, "t") || !strcmp(token, "transfer")) 1175 aic_transfer_data(); 1176 else 1177 printf("aic channel | list | set | transfer\n"); 1178 } 1179 else 1180 list_channels(num_aic_channels, aic_channels); 1181 } 1182 1183 static void handle_cpm(void *cpm) 1184 { 1185 char *token; 1186 1187 if ((token = read_token(NULL)) != NULL) 1188 { 1189 if (!strcmp(token, "l") || !strcmp(token, "list")) 1190 list_clocks(cpm); 1191 else if (!strcmp(token, "f") || !strcmp(token, "frequency")) 1192 set_frequency(cpm); 1193 else if (!strcmp(token, "p") || !strcmp(token, "parameters")) 1194 set_parameters(cpm); 1195 else if (!strcmp(token, "s") || !strcmp(token, "source")) 1196 set_source(cpm); 1197 else if (!strcmp(token, "start")) 1198 start_clock(cpm); 1199 else if (!strcmp(token, "stop")) 1200 stop_clock(cpm); 1201 else 1202 printf("cpm list | frequency | parameters | source | start | stop\n"); 1203 } 1204 else 1205 list_clocks(cpm); 1206 } 1207 1208 static void handle_dma(void *dma) 1209 { 1210 char *token; 1211 1212 if ((token = read_token(NULL)) != NULL) 1213 { 1214 if (!strcmp(token, "l") || !strcmp(token, "list")) 1215 list_channels(num_dma_channels, dma_channels); 1216 else if (!strcmp(token, "c") || !strcmp(token, "channel")) 1217 new_dma_channel(dma); 1218 else if (!strcmp(token, "r") || !strcmp(token, "region")) 1219 new_dma_region(); 1220 else if (!strcmp(token, "s") || !strcmp(token, "set")) 1221 set_dma_region(); 1222 else if (!strcmp(token, "t") || !strcmp(token, "transfer")) 1223 dma_transfer_data(); 1224 else 1225 printf("dma channel | list | region | set | transfer\n"); 1226 } 1227 else 1228 list_channels(num_dma_channels, dma_channels); 1229 } 1230 1231 static void handle_gpio(void *gpio[]) 1232 { 1233 char *token; 1234 1235 if ((token = read_token(NULL)) != NULL) 1236 { 1237 if (!strcmp(token, "l") || !strcmp(token, "list")) 1238 list_gpios(gpio); 1239 else if (!strcmp(token, "a") || !strcmp(token, "alt")) 1240 set_gpio_alt_func(gpio); 1241 else if (!strcmp(token, "i") || !strcmp(token, "io")) 1242 set_gpio_pad(gpio); 1243 else if (!strcmp(token, "p") || !strcmp(token, "pull")) 1244 set_gpio_pull(gpio); 1245 else 1246 printf("gpio list | alt | io | pull\n"); 1247 } 1248 else 1249 list_gpios(gpio); 1250 } 1251 1252 static void handle_i2c(void *i2c) 1253 { 1254 char *token; 1255 1256 if ((token = read_token(NULL)) != NULL) 1257 { 1258 if (!strcmp(token, "l") || !strcmp(token, "list")) 1259 list_i2c_channels(); 1260 else if (!strcmp(token, "c") || !strcmp(token, "channel")) 1261 new_i2c_channel(i2c); 1262 else if (!strcmp(token, "g") || !strcmp(token, "get")) 1263 i2c_get(); 1264 else if (!strcmp(token, "s") || !strcmp(token, "scan")) 1265 i2c_scan(); 1266 else 1267 printf("i2c channel | get | list | scan\n"); 1268 } 1269 else 1270 list_i2c_channels(); 1271 } 1272 1273 static void handle_spi(void *spi, void *gpio[]) 1274 { 1275 char *token; 1276 1277 if ((token = read_token(NULL)) != NULL) 1278 { 1279 if (!strcmp(token, "l") || !strcmp(token, "list")) 1280 list_channels(num_spi_channels, spi_channels); 1281 else if (!strcmp(token, "a") || !strcmp(token, "control-acquire")) 1282 spi_control(1); 1283 else if (!strcmp(token, "r") || !strcmp(token, "control-release")) 1284 spi_control(0); 1285 else if (!strcmp(token, "c") || !strcmp(token, "channel")) 1286 new_spi_channel(spi, gpio); 1287 else if (!strcmp(token, "g") || !strcmp(token, "gpio") || !strcmp(token, "gpio-channel")) 1288 new_spi_channel_gpio(gpio); 1289 else if (!strcmp(token, "s") || !strcmp(token, "send")) 1290 spi_send_data_gpio(); 1291 else if (!strcmp(token, "S") || !strcmp(token, "send-units")) 1292 spi_send_data_units(); 1293 else if (!strcmp(token, "t") || !strcmp(token, "transfer")) 1294 spi_transfer_data(); 1295 else 1296 printf("spi channel | control-acquire | control-release | gpio-channel | list | send | send-units | transfer\n"); 1297 } 1298 else 1299 list_channels(num_spi_channels, spi_channels); 1300 } 1301 1302 1303 1304 int main(void) 1305 { 1306 l4_addr_t aic_base = 0, aic_base_end = 0; 1307 l4_addr_t aic_phys_base = 0, aic_phys_base_end = 0; 1308 l4_addr_t cpm_base = 0, cpm_base_end = 0; 1309 l4_addr_t dma_base = 0, dma_base_end = 0; 1310 l4_addr_t gpio_base = 0, gpio_base_end = 0; 1311 l4_addr_t i2c_base = 0, i2c_base_end = 0; 1312 l4_addr_t ssi_base = 0, ssi_base_end = 0; 1313 l4_addr_t ssi_phys_base = 0, ssi_phys_base_end = 0; 1314 void *aic, *cpm, *dma, *gpio[num_gpio_ports], *i2c, *spi; 1315 int result = 0; 1316 unsigned int port; 1317 1318 icucap = l4re_env_get_cap("icu"); 1319 1320 /* Obtain resource details describing I/O memory. */ 1321 1322 printf("Access CPM...\n"); 1323 1324 if ((result = get_memory(memory_regions[CPM], &cpm_base, &cpm_base_end)) < 0) 1325 return 1; 1326 1327 printf("CPM at 0x%lx...0x%lx.\n", cpm_base, cpm_base_end); 1328 1329 cpm = cpm_init(cpm_base); 1330 1331 printf("Access DMA...\n"); 1332 1333 if ((result = get_memory(memory_regions[DMA], &dma_base, &dma_base_end)) < 0) 1334 return 1; 1335 1336 printf("DMA at 0x%lx...0x%lx.\n", dma_base, dma_base_end); 1337 1338 dma = dma_init(dma_base, dma_base_end, cpm); 1339 1340 if (get_irq(memory_regions[DMA], &dma_irq_start, &dma_irq_end) < 0) 1341 return 1; 1342 1343 printf("IRQ range at %d...%d.\n", dma_irq_start, dma_irq_end); 1344 1345 if (init_dma()) 1346 return 1; 1347 1348 dma_enable(dma); 1349 1350 printf("Access GPIO...\n"); 1351 1352 if ((result = get_memory(memory_regions[GPIO], &gpio_base, &gpio_base_end)) < 0) 1353 return 1; 1354 1355 printf("GPIO at 0x%lx...0x%lx.\n", gpio_base, gpio_base_end); 1356 1357 for (port = 0; port < num_gpio_ports; port++) 1358 gpio[port] = gpio_init(gpio_base + port * 0x100, gpio_base + (port + 1) * 0x100, 1359 32, gpio_ports[port].pull_ups, gpio_ports[port].pull_downs); 1360 1361 printf("Access I2C...\n"); 1362 1363 if ((result = get_memory(memory_regions[I2C], &i2c_base, &i2c_base_end)) < 0) 1364 return 1; 1365 1366 printf("I2C at 0x%lx...0x%lx.\n", i2c_base, i2c_base_end); 1367 1368 i2c = i2c_init(i2c_base, i2c_base_end, cpm, 100000); 1369 1370 if (get_irq(memory_regions[I2C], &i2c_irq_start, &i2c_irq_end) < 0) 1371 return 1; 1372 1373 printf("IRQ range at %d...%d.\n", i2c_irq_start, i2c_irq_end); 1374 1375 printf("Access AIC...\n"); 1376 1377 if ((result = get_memory_complete(memory_regions[AIC], &aic_base, &aic_base_end, 1378 &aic_phys_base, &aic_phys_base_end)) < 0) 1379 return 1; 1380 1381 printf("AIC at 0x%lx...0x%lx.\n", aic_base, aic_base_end); 1382 1383 aic = aic_init(aic_phys_base, aic_base, aic_base_end, cpm); 1384 1385 printf("Access SSI...\n"); 1386 1387 if ((result = get_memory_complete(memory_regions[SSI], &ssi_base, &ssi_base_end, 1388 &ssi_phys_base, &ssi_phys_base_end)) < 0) 1389 return 1; 1390 1391 printf("SSI at 0x%lx...0x%lx.\n", ssi_base, ssi_base_end); 1392 1393 spi = spi_init(ssi_phys_base, ssi_base, ssi_base_end, cpm); 1394 1395 /* Start the interactive session. */ 1396 1397 printf("aic, cpm, dma, gpio, i2c, spi\n"); 1398 1399 while (1) 1400 { 1401 char cmdline[256], *token; 1402 1403 printf("> "); 1404 1405 token = fgets(cmdline, 256, stdin); 1406 1407 if (token == NULL) 1408 break; 1409 1410 if ((token = strtok(cmdline, delimiters)) == NULL) 1411 continue; 1412 1413 /* AIC/I2S commands. */ 1414 1415 if (!strcmp(token, "a") || !strcmp(token, "aic") || !strcmp(token, "i2s")) 1416 handle_aic(aic); 1417 1418 /* CPM commands. */ 1419 1420 else if (!strcmp(token, "c") || !strcmp(token, "cpm")) 1421 handle_cpm(cpm); 1422 1423 /* DMA commands. */ 1424 1425 else if (!strcmp(token, "d") || !strcmp(token, "dma")) 1426 handle_dma(dma); 1427 1428 /* GPIO commands. */ 1429 1430 else if (!strcmp(token, "g") || !strcmp(token, "gpio")) 1431 handle_gpio(gpio); 1432 1433 /* I2C commands. */ 1434 1435 else if (!strcmp(token, "i") || !strcmp(token, "i2c")) 1436 handle_i2c(i2c); 1437 1438 /* SPI commands. */ 1439 1440 else if (!strcmp(token, "s") || !strcmp(token, "spi")) 1441 handle_spi(spi, gpio); 1442 1443 /* Comments and blank lines. */ 1444 1445 else if (strncmp(token, "#", 1) && strlen(token)) 1446 printf("Command?\n"); 1447 } 1448 1449 printf("End of session.\n"); 1450 return 0; 1451 }