tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/ws2812/ws2812-asm_cortexm.go (about) 1 //go:build cortexm 2 3 package ws2812 4 5 // Warning: autogenerated file. Instead of modifying this file, change 6 // gen-ws2812.go and run "go generate". 7 8 import "runtime/interrupt" 9 import "unsafe" 10 11 /* 12 #include <stdint.h> 13 14 __attribute__((always_inline)) 15 void ws2812_writeByte16(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) { 16 // Timings: 17 // T0H: 6 - 8 cycles or 375.0ns - 500.0ns 18 // T1H: 17 - 19 cycles or 1062.5ns - 1187.5ns 19 // TLD: 19 - cycles or 1187.5ns - 20 uint32_t value = (uint32_t)c << 24; 21 char i = 8; 22 __asm__ __volatile__( 23 "1: @ send_bit\n" 24 "\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n" 25 "\t nop\n" 26 "\t nop\n" 27 "\t lsls %[value], #1 @ [1]\n" 28 "\t bcs.n 2f @ [1/3] skip_store\n" 29 "\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n" 30 "\t2: @ skip_store\n" 31 "\t nop\n" 32 "\t nop\n" 33 "\t nop\n" 34 "\t nop\n" 35 "\t nop\n" 36 "\t nop\n" 37 "\t nop\n" 38 "\t nop\n" 39 "\t nop\n" 40 "\t nop\n" 41 "\t nop\n" 42 "\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n" 43 "\t nop\n" 44 "\t nop\n" 45 "\t nop\n" 46 "\t nop\n" 47 "\t nop\n" 48 "\t nop\n" 49 "\t nop\n" 50 "\t nop\n" 51 "\t nop\n" 52 "\t nop\n" 53 "\t nop\n" 54 "\t nop\n" 55 "\t nop\n" 56 "\t nop\n" 57 "\t subs %[i], #1 @ [1]\n" 58 "\t beq.n 3f @ [1/3] end\n" 59 "\t b 1b @ [1/3] send_bit\n" 60 "\t3: @ end\n" 61 : [value]"+r"(value), 62 [i]"+r"(i) 63 : [maskSet]"r"(maskSet), 64 [portSet]"m"(*portSet), 65 [maskClear]"r"(maskClear), 66 [portClear]"m"(*portClear)); 67 } 68 69 __attribute__((always_inline)) 70 void ws2812_writeByte48(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) { 71 // Timings: 72 // T0H: 17 - 19 cycles or 354.2ns - 395.8ns 73 // T1H: 51 - 53 cycles or 1062.5ns - 1104.2ns 74 // TLD: 56 - cycles or 1166.7ns - 75 uint32_t value = (uint32_t)c << 24; 76 char i = 8; 77 __asm__ __volatile__( 78 "1: @ send_bit\n" 79 "\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n" 80 "\t nop\n" 81 "\t nop\n" 82 "\t nop\n" 83 "\t nop\n" 84 "\t nop\n" 85 "\t nop\n" 86 "\t nop\n" 87 "\t nop\n" 88 "\t nop\n" 89 "\t nop\n" 90 "\t nop\n" 91 "\t nop\n" 92 "\t nop\n" 93 "\t lsls %[value], #1 @ [1]\n" 94 "\t bcs.n 2f @ [1/3] skip_store\n" 95 "\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n" 96 "\t2: @ skip_store\n" 97 "\t nop\n" 98 "\t nop\n" 99 "\t nop\n" 100 "\t nop\n" 101 "\t nop\n" 102 "\t nop\n" 103 "\t nop\n" 104 "\t nop\n" 105 "\t nop\n" 106 "\t nop\n" 107 "\t nop\n" 108 "\t nop\n" 109 "\t nop\n" 110 "\t nop\n" 111 "\t nop\n" 112 "\t nop\n" 113 "\t nop\n" 114 "\t nop\n" 115 "\t nop\n" 116 "\t nop\n" 117 "\t nop\n" 118 "\t nop\n" 119 "\t nop\n" 120 "\t nop\n" 121 "\t nop\n" 122 "\t nop\n" 123 "\t nop\n" 124 "\t nop\n" 125 "\t nop\n" 126 "\t nop\n" 127 "\t nop\n" 128 "\t nop\n" 129 "\t nop\n" 130 "\t nop\n" 131 "\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n" 132 "\t nop\n" 133 "\t nop\n" 134 "\t nop\n" 135 "\t nop\n" 136 "\t nop\n" 137 "\t nop\n" 138 "\t nop\n" 139 "\t nop\n" 140 "\t nop\n" 141 "\t nop\n" 142 "\t nop\n" 143 "\t nop\n" 144 "\t nop\n" 145 "\t nop\n" 146 "\t nop\n" 147 "\t nop\n" 148 "\t nop\n" 149 "\t nop\n" 150 "\t nop\n" 151 "\t nop\n" 152 "\t nop\n" 153 "\t nop\n" 154 "\t nop\n" 155 "\t nop\n" 156 "\t nop\n" 157 "\t nop\n" 158 "\t nop\n" 159 "\t nop\n" 160 "\t nop\n" 161 "\t nop\n" 162 "\t nop\n" 163 "\t nop\n" 164 "\t nop\n" 165 "\t nop\n" 166 "\t nop\n" 167 "\t nop\n" 168 "\t nop\n" 169 "\t nop\n" 170 "\t nop\n" 171 "\t nop\n" 172 "\t nop\n" 173 "\t nop\n" 174 "\t nop\n" 175 "\t nop\n" 176 "\t nop\n" 177 "\t nop\n" 178 "\t nop\n" 179 "\t nop\n" 180 "\t nop\n" 181 "\t nop\n" 182 "\t nop\n" 183 "\t subs %[i], #1 @ [1]\n" 184 "\t beq.n 3f @ [1/3] end\n" 185 "\t b 1b @ [1/3] send_bit\n" 186 "\t3: @ end\n" 187 : [value]"+r"(value), 188 [i]"+r"(i) 189 : [maskSet]"r"(maskSet), 190 [portSet]"m"(*portSet), 191 [maskClear]"r"(maskClear), 192 [portClear]"m"(*portClear)); 193 } 194 195 __attribute__((always_inline)) 196 void ws2812_writeByte64(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) { 197 // Timings: 198 // T0H: 23 - 25 cycles or 359.4ns - 390.6ns 199 // T1H: 68 - 70 cycles or 1062.5ns - 1093.8ns 200 // TLD: 74 - cycles or 1156.2ns - 201 uint32_t value = (uint32_t)c << 24; 202 char i = 8; 203 __asm__ __volatile__( 204 "1: @ send_bit\n" 205 "\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n" 206 "\t nop\n" 207 "\t nop\n" 208 "\t nop\n" 209 "\t nop\n" 210 "\t nop\n" 211 "\t nop\n" 212 "\t nop\n" 213 "\t nop\n" 214 "\t nop\n" 215 "\t nop\n" 216 "\t nop\n" 217 "\t nop\n" 218 "\t nop\n" 219 "\t nop\n" 220 "\t nop\n" 221 "\t nop\n" 222 "\t nop\n" 223 "\t nop\n" 224 "\t nop\n" 225 "\t lsls %[value], #1 @ [1]\n" 226 "\t bcs.n 2f @ [1/3] skip_store\n" 227 "\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n" 228 "\t2: @ skip_store\n" 229 "\t nop\n" 230 "\t nop\n" 231 "\t nop\n" 232 "\t nop\n" 233 "\t nop\n" 234 "\t nop\n" 235 "\t nop\n" 236 "\t nop\n" 237 "\t nop\n" 238 "\t nop\n" 239 "\t nop\n" 240 "\t nop\n" 241 "\t nop\n" 242 "\t nop\n" 243 "\t nop\n" 244 "\t nop\n" 245 "\t nop\n" 246 "\t nop\n" 247 "\t nop\n" 248 "\t nop\n" 249 "\t nop\n" 250 "\t nop\n" 251 "\t nop\n" 252 "\t nop\n" 253 "\t nop\n" 254 "\t nop\n" 255 "\t nop\n" 256 "\t nop\n" 257 "\t nop\n" 258 "\t nop\n" 259 "\t nop\n" 260 "\t nop\n" 261 "\t nop\n" 262 "\t nop\n" 263 "\t nop\n" 264 "\t nop\n" 265 "\t nop\n" 266 "\t nop\n" 267 "\t nop\n" 268 "\t nop\n" 269 "\t nop\n" 270 "\t nop\n" 271 "\t nop\n" 272 "\t nop\n" 273 "\t nop\n" 274 "\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n" 275 "\t nop\n" 276 "\t nop\n" 277 "\t nop\n" 278 "\t nop\n" 279 "\t nop\n" 280 "\t nop\n" 281 "\t nop\n" 282 "\t nop\n" 283 "\t nop\n" 284 "\t nop\n" 285 "\t nop\n" 286 "\t nop\n" 287 "\t nop\n" 288 "\t nop\n" 289 "\t nop\n" 290 "\t nop\n" 291 "\t nop\n" 292 "\t nop\n" 293 "\t nop\n" 294 "\t nop\n" 295 "\t nop\n" 296 "\t nop\n" 297 "\t nop\n" 298 "\t nop\n" 299 "\t nop\n" 300 "\t nop\n" 301 "\t nop\n" 302 "\t nop\n" 303 "\t nop\n" 304 "\t nop\n" 305 "\t nop\n" 306 "\t nop\n" 307 "\t nop\n" 308 "\t nop\n" 309 "\t nop\n" 310 "\t nop\n" 311 "\t nop\n" 312 "\t nop\n" 313 "\t nop\n" 314 "\t nop\n" 315 "\t nop\n" 316 "\t nop\n" 317 "\t nop\n" 318 "\t nop\n" 319 "\t nop\n" 320 "\t nop\n" 321 "\t nop\n" 322 "\t nop\n" 323 "\t nop\n" 324 "\t nop\n" 325 "\t nop\n" 326 "\t nop\n" 327 "\t nop\n" 328 "\t nop\n" 329 "\t nop\n" 330 "\t nop\n" 331 "\t nop\n" 332 "\t nop\n" 333 "\t nop\n" 334 "\t nop\n" 335 "\t nop\n" 336 "\t nop\n" 337 "\t nop\n" 338 "\t nop\n" 339 "\t nop\n" 340 "\t nop\n" 341 "\t nop\n" 342 "\t nop\n" 343 "\t nop\n" 344 "\t subs %[i], #1 @ [1]\n" 345 "\t beq.n 3f @ [1/3] end\n" 346 "\t b 1b @ [1/3] send_bit\n" 347 "\t3: @ end\n" 348 : [value]"+r"(value), 349 [i]"+r"(i) 350 : [maskSet]"r"(maskSet), 351 [portSet]"m"(*portSet), 352 [maskClear]"r"(maskClear), 353 [portClear]"m"(*portClear)); 354 } 355 356 __attribute__((always_inline)) 357 void ws2812_writeByte120(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) { 358 // Timings: 359 // T0H: 42 - 44 cycles or 350.0ns - 366.7ns 360 // T1H: 126 - 128 cycles or 1050.0ns - 1066.7ns 361 // TLD: 138 - cycles or 1150.0ns - 362 uint32_t value = (uint32_t)c << 24; 363 char i = 8; 364 __asm__ __volatile__( 365 "1: @ send_bit\n" 366 "\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n" 367 "\t nop\n" 368 "\t nop\n" 369 "\t nop\n" 370 "\t nop\n" 371 "\t nop\n" 372 "\t nop\n" 373 "\t nop\n" 374 "\t nop\n" 375 "\t nop\n" 376 "\t nop\n" 377 "\t nop\n" 378 "\t nop\n" 379 "\t nop\n" 380 "\t nop\n" 381 "\t nop\n" 382 "\t nop\n" 383 "\t nop\n" 384 "\t nop\n" 385 "\t nop\n" 386 "\t nop\n" 387 "\t nop\n" 388 "\t nop\n" 389 "\t nop\n" 390 "\t nop\n" 391 "\t nop\n" 392 "\t nop\n" 393 "\t nop\n" 394 "\t nop\n" 395 "\t nop\n" 396 "\t nop\n" 397 "\t nop\n" 398 "\t nop\n" 399 "\t nop\n" 400 "\t nop\n" 401 "\t nop\n" 402 "\t nop\n" 403 "\t nop\n" 404 "\t nop\n" 405 "\t lsls %[value], #1 @ [1]\n" 406 "\t bcs.n 2f @ [1/3] skip_store\n" 407 "\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n" 408 "\t2: @ skip_store\n" 409 "\t nop\n" 410 "\t nop\n" 411 "\t nop\n" 412 "\t nop\n" 413 "\t nop\n" 414 "\t nop\n" 415 "\t nop\n" 416 "\t nop\n" 417 "\t nop\n" 418 "\t nop\n" 419 "\t nop\n" 420 "\t nop\n" 421 "\t nop\n" 422 "\t nop\n" 423 "\t nop\n" 424 "\t nop\n" 425 "\t nop\n" 426 "\t nop\n" 427 "\t nop\n" 428 "\t nop\n" 429 "\t nop\n" 430 "\t nop\n" 431 "\t nop\n" 432 "\t nop\n" 433 "\t nop\n" 434 "\t nop\n" 435 "\t nop\n" 436 "\t nop\n" 437 "\t nop\n" 438 "\t nop\n" 439 "\t nop\n" 440 "\t nop\n" 441 "\t nop\n" 442 "\t nop\n" 443 "\t nop\n" 444 "\t nop\n" 445 "\t nop\n" 446 "\t nop\n" 447 "\t nop\n" 448 "\t nop\n" 449 "\t nop\n" 450 "\t nop\n" 451 "\t nop\n" 452 "\t nop\n" 453 "\t nop\n" 454 "\t nop\n" 455 "\t nop\n" 456 "\t nop\n" 457 "\t nop\n" 458 "\t nop\n" 459 "\t nop\n" 460 "\t nop\n" 461 "\t nop\n" 462 "\t nop\n" 463 "\t nop\n" 464 "\t nop\n" 465 "\t nop\n" 466 "\t nop\n" 467 "\t nop\n" 468 "\t nop\n" 469 "\t nop\n" 470 "\t nop\n" 471 "\t nop\n" 472 "\t nop\n" 473 "\t nop\n" 474 "\t nop\n" 475 "\t nop\n" 476 "\t nop\n" 477 "\t nop\n" 478 "\t nop\n" 479 "\t nop\n" 480 "\t nop\n" 481 "\t nop\n" 482 "\t nop\n" 483 "\t nop\n" 484 "\t nop\n" 485 "\t nop\n" 486 "\t nop\n" 487 "\t nop\n" 488 "\t nop\n" 489 "\t nop\n" 490 "\t nop\n" 491 "\t nop\n" 492 "\t nop\n" 493 "\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n" 494 "\t nop\n" 495 "\t nop\n" 496 "\t nop\n" 497 "\t nop\n" 498 "\t nop\n" 499 "\t nop\n" 500 "\t nop\n" 501 "\t nop\n" 502 "\t nop\n" 503 "\t nop\n" 504 "\t nop\n" 505 "\t nop\n" 506 "\t nop\n" 507 "\t nop\n" 508 "\t nop\n" 509 "\t nop\n" 510 "\t nop\n" 511 "\t nop\n" 512 "\t nop\n" 513 "\t nop\n" 514 "\t nop\n" 515 "\t nop\n" 516 "\t nop\n" 517 "\t nop\n" 518 "\t nop\n" 519 "\t nop\n" 520 "\t nop\n" 521 "\t nop\n" 522 "\t nop\n" 523 "\t nop\n" 524 "\t nop\n" 525 "\t nop\n" 526 "\t nop\n" 527 "\t nop\n" 528 "\t nop\n" 529 "\t nop\n" 530 "\t nop\n" 531 "\t nop\n" 532 "\t nop\n" 533 "\t nop\n" 534 "\t nop\n" 535 "\t nop\n" 536 "\t nop\n" 537 "\t nop\n" 538 "\t nop\n" 539 "\t nop\n" 540 "\t nop\n" 541 "\t nop\n" 542 "\t nop\n" 543 "\t nop\n" 544 "\t nop\n" 545 "\t nop\n" 546 "\t nop\n" 547 "\t nop\n" 548 "\t nop\n" 549 "\t nop\n" 550 "\t nop\n" 551 "\t nop\n" 552 "\t nop\n" 553 "\t nop\n" 554 "\t nop\n" 555 "\t nop\n" 556 "\t nop\n" 557 "\t nop\n" 558 "\t nop\n" 559 "\t nop\n" 560 "\t nop\n" 561 "\t nop\n" 562 "\t nop\n" 563 "\t nop\n" 564 "\t nop\n" 565 "\t nop\n" 566 "\t nop\n" 567 "\t nop\n" 568 "\t nop\n" 569 "\t nop\n" 570 "\t nop\n" 571 "\t nop\n" 572 "\t nop\n" 573 "\t nop\n" 574 "\t nop\n" 575 "\t nop\n" 576 "\t nop\n" 577 "\t nop\n" 578 "\t nop\n" 579 "\t nop\n" 580 "\t nop\n" 581 "\t nop\n" 582 "\t nop\n" 583 "\t nop\n" 584 "\t nop\n" 585 "\t nop\n" 586 "\t nop\n" 587 "\t nop\n" 588 "\t nop\n" 589 "\t nop\n" 590 "\t nop\n" 591 "\t nop\n" 592 "\t nop\n" 593 "\t nop\n" 594 "\t nop\n" 595 "\t nop\n" 596 "\t nop\n" 597 "\t nop\n" 598 "\t nop\n" 599 "\t nop\n" 600 "\t nop\n" 601 "\t nop\n" 602 "\t nop\n" 603 "\t nop\n" 604 "\t nop\n" 605 "\t nop\n" 606 "\t nop\n" 607 "\t nop\n" 608 "\t nop\n" 609 "\t nop\n" 610 "\t nop\n" 611 "\t nop\n" 612 "\t nop\n" 613 "\t nop\n" 614 "\t nop\n" 615 "\t nop\n" 616 "\t nop\n" 617 "\t nop\n" 618 "\t nop\n" 619 "\t nop\n" 620 "\t nop\n" 621 "\t nop\n" 622 "\t nop\n" 623 "\t nop\n" 624 "\t nop\n" 625 "\t nop\n" 626 "\t nop\n" 627 "\t subs %[i], #1 @ [1]\n" 628 "\t beq.n 3f @ [1/3] end\n" 629 "\t b 1b @ [1/3] send_bit\n" 630 "\t3: @ end\n" 631 : [value]"+r"(value), 632 [i]"+r"(i) 633 : [maskSet]"r"(maskSet), 634 [portSet]"m"(*portSet), 635 [maskClear]"r"(maskClear), 636 [portClear]"m"(*portClear)); 637 } 638 639 __attribute__((always_inline)) 640 void ws2812_writeByte125(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) { 641 // Timings: 642 // T0H: 44 - 46 cycles or 352.0ns - 368.0ns 643 // T1H: 132 - 134 cycles or 1056.0ns - 1072.0ns 644 // TLD: 144 - cycles or 1152.0ns - 645 uint32_t value = (uint32_t)c << 24; 646 char i = 8; 647 __asm__ __volatile__( 648 "1: @ send_bit\n" 649 "\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n" 650 "\t nop\n" 651 "\t nop\n" 652 "\t nop\n" 653 "\t nop\n" 654 "\t nop\n" 655 "\t nop\n" 656 "\t nop\n" 657 "\t nop\n" 658 "\t nop\n" 659 "\t nop\n" 660 "\t nop\n" 661 "\t nop\n" 662 "\t nop\n" 663 "\t nop\n" 664 "\t nop\n" 665 "\t nop\n" 666 "\t nop\n" 667 "\t nop\n" 668 "\t nop\n" 669 "\t nop\n" 670 "\t nop\n" 671 "\t nop\n" 672 "\t nop\n" 673 "\t nop\n" 674 "\t nop\n" 675 "\t nop\n" 676 "\t nop\n" 677 "\t nop\n" 678 "\t nop\n" 679 "\t nop\n" 680 "\t nop\n" 681 "\t nop\n" 682 "\t nop\n" 683 "\t nop\n" 684 "\t nop\n" 685 "\t nop\n" 686 "\t nop\n" 687 "\t nop\n" 688 "\t nop\n" 689 "\t nop\n" 690 "\t lsls %[value], #1 @ [1]\n" 691 "\t bcs.n 2f @ [1/3] skip_store\n" 692 "\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n" 693 "\t2: @ skip_store\n" 694 "\t nop\n" 695 "\t nop\n" 696 "\t nop\n" 697 "\t nop\n" 698 "\t nop\n" 699 "\t nop\n" 700 "\t nop\n" 701 "\t nop\n" 702 "\t nop\n" 703 "\t nop\n" 704 "\t nop\n" 705 "\t nop\n" 706 "\t nop\n" 707 "\t nop\n" 708 "\t nop\n" 709 "\t nop\n" 710 "\t nop\n" 711 "\t nop\n" 712 "\t nop\n" 713 "\t nop\n" 714 "\t nop\n" 715 "\t nop\n" 716 "\t nop\n" 717 "\t nop\n" 718 "\t nop\n" 719 "\t nop\n" 720 "\t nop\n" 721 "\t nop\n" 722 "\t nop\n" 723 "\t nop\n" 724 "\t nop\n" 725 "\t nop\n" 726 "\t nop\n" 727 "\t nop\n" 728 "\t nop\n" 729 "\t nop\n" 730 "\t nop\n" 731 "\t nop\n" 732 "\t nop\n" 733 "\t nop\n" 734 "\t nop\n" 735 "\t nop\n" 736 "\t nop\n" 737 "\t nop\n" 738 "\t nop\n" 739 "\t nop\n" 740 "\t nop\n" 741 "\t nop\n" 742 "\t nop\n" 743 "\t nop\n" 744 "\t nop\n" 745 "\t nop\n" 746 "\t nop\n" 747 "\t nop\n" 748 "\t nop\n" 749 "\t nop\n" 750 "\t nop\n" 751 "\t nop\n" 752 "\t nop\n" 753 "\t nop\n" 754 "\t nop\n" 755 "\t nop\n" 756 "\t nop\n" 757 "\t nop\n" 758 "\t nop\n" 759 "\t nop\n" 760 "\t nop\n" 761 "\t nop\n" 762 "\t nop\n" 763 "\t nop\n" 764 "\t nop\n" 765 "\t nop\n" 766 "\t nop\n" 767 "\t nop\n" 768 "\t nop\n" 769 "\t nop\n" 770 "\t nop\n" 771 "\t nop\n" 772 "\t nop\n" 773 "\t nop\n" 774 "\t nop\n" 775 "\t nop\n" 776 "\t nop\n" 777 "\t nop\n" 778 "\t nop\n" 779 "\t nop\n" 780 "\t nop\n" 781 "\t nop\n" 782 "\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n" 783 "\t nop\n" 784 "\t nop\n" 785 "\t nop\n" 786 "\t nop\n" 787 "\t nop\n" 788 "\t nop\n" 789 "\t nop\n" 790 "\t nop\n" 791 "\t nop\n" 792 "\t nop\n" 793 "\t nop\n" 794 "\t nop\n" 795 "\t nop\n" 796 "\t nop\n" 797 "\t nop\n" 798 "\t nop\n" 799 "\t nop\n" 800 "\t nop\n" 801 "\t nop\n" 802 "\t nop\n" 803 "\t nop\n" 804 "\t nop\n" 805 "\t nop\n" 806 "\t nop\n" 807 "\t nop\n" 808 "\t nop\n" 809 "\t nop\n" 810 "\t nop\n" 811 "\t nop\n" 812 "\t nop\n" 813 "\t nop\n" 814 "\t nop\n" 815 "\t nop\n" 816 "\t nop\n" 817 "\t nop\n" 818 "\t nop\n" 819 "\t nop\n" 820 "\t nop\n" 821 "\t nop\n" 822 "\t nop\n" 823 "\t nop\n" 824 "\t nop\n" 825 "\t nop\n" 826 "\t nop\n" 827 "\t nop\n" 828 "\t nop\n" 829 "\t nop\n" 830 "\t nop\n" 831 "\t nop\n" 832 "\t nop\n" 833 "\t nop\n" 834 "\t nop\n" 835 "\t nop\n" 836 "\t nop\n" 837 "\t nop\n" 838 "\t nop\n" 839 "\t nop\n" 840 "\t nop\n" 841 "\t nop\n" 842 "\t nop\n" 843 "\t nop\n" 844 "\t nop\n" 845 "\t nop\n" 846 "\t nop\n" 847 "\t nop\n" 848 "\t nop\n" 849 "\t nop\n" 850 "\t nop\n" 851 "\t nop\n" 852 "\t nop\n" 853 "\t nop\n" 854 "\t nop\n" 855 "\t nop\n" 856 "\t nop\n" 857 "\t nop\n" 858 "\t nop\n" 859 "\t nop\n" 860 "\t nop\n" 861 "\t nop\n" 862 "\t nop\n" 863 "\t nop\n" 864 "\t nop\n" 865 "\t nop\n" 866 "\t nop\n" 867 "\t nop\n" 868 "\t nop\n" 869 "\t nop\n" 870 "\t nop\n" 871 "\t nop\n" 872 "\t nop\n" 873 "\t nop\n" 874 "\t nop\n" 875 "\t nop\n" 876 "\t nop\n" 877 "\t nop\n" 878 "\t nop\n" 879 "\t nop\n" 880 "\t nop\n" 881 "\t nop\n" 882 "\t nop\n" 883 "\t nop\n" 884 "\t nop\n" 885 "\t nop\n" 886 "\t nop\n" 887 "\t nop\n" 888 "\t nop\n" 889 "\t nop\n" 890 "\t nop\n" 891 "\t nop\n" 892 "\t nop\n" 893 "\t nop\n" 894 "\t nop\n" 895 "\t nop\n" 896 "\t nop\n" 897 "\t nop\n" 898 "\t nop\n" 899 "\t nop\n" 900 "\t nop\n" 901 "\t nop\n" 902 "\t nop\n" 903 "\t nop\n" 904 "\t nop\n" 905 "\t nop\n" 906 "\t nop\n" 907 "\t nop\n" 908 "\t nop\n" 909 "\t nop\n" 910 "\t nop\n" 911 "\t nop\n" 912 "\t nop\n" 913 "\t nop\n" 914 "\t nop\n" 915 "\t nop\n" 916 "\t nop\n" 917 "\t nop\n" 918 "\t nop\n" 919 "\t nop\n" 920 "\t nop\n" 921 "\t nop\n" 922 "\t subs %[i], #1 @ [1]\n" 923 "\t beq.n 3f @ [1/3] end\n" 924 "\t b 1b @ [1/3] send_bit\n" 925 "\t3: @ end\n" 926 : [value]"+r"(value), 927 [i]"+r"(i) 928 : [maskSet]"r"(maskSet), 929 [portSet]"m"(*portSet), 930 [maskClear]"r"(maskClear), 931 [portClear]"m"(*portClear)); 932 } 933 934 __attribute__((always_inline)) 935 void ws2812_writeByte168(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) { 936 // Timings: 937 // T0H: 59 - 61 cycles or 351.2ns - 363.1ns 938 // T1H: 177 - 179 cycles or 1053.6ns - 1065.5ns 939 // TLD: 194 - cycles or 1154.8ns - 940 uint32_t value = (uint32_t)c << 24; 941 char i = 8; 942 __asm__ __volatile__( 943 "1: @ send_bit\n" 944 "\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n" 945 "\t nop\n" 946 "\t nop\n" 947 "\t nop\n" 948 "\t nop\n" 949 "\t nop\n" 950 "\t nop\n" 951 "\t nop\n" 952 "\t nop\n" 953 "\t nop\n" 954 "\t nop\n" 955 "\t nop\n" 956 "\t nop\n" 957 "\t nop\n" 958 "\t nop\n" 959 "\t nop\n" 960 "\t nop\n" 961 "\t nop\n" 962 "\t nop\n" 963 "\t nop\n" 964 "\t nop\n" 965 "\t nop\n" 966 "\t nop\n" 967 "\t nop\n" 968 "\t nop\n" 969 "\t nop\n" 970 "\t nop\n" 971 "\t nop\n" 972 "\t nop\n" 973 "\t nop\n" 974 "\t nop\n" 975 "\t nop\n" 976 "\t nop\n" 977 "\t nop\n" 978 "\t nop\n" 979 "\t nop\n" 980 "\t nop\n" 981 "\t nop\n" 982 "\t nop\n" 983 "\t nop\n" 984 "\t nop\n" 985 "\t nop\n" 986 "\t nop\n" 987 "\t nop\n" 988 "\t nop\n" 989 "\t nop\n" 990 "\t nop\n" 991 "\t nop\n" 992 "\t nop\n" 993 "\t nop\n" 994 "\t nop\n" 995 "\t nop\n" 996 "\t nop\n" 997 "\t nop\n" 998 "\t nop\n" 999 "\t nop\n" 1000 "\t lsls %[value], #1 @ [1]\n" 1001 "\t bcs.n 2f @ [1/3] skip_store\n" 1002 "\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n" 1003 "\t2: @ skip_store\n" 1004 "\t nop\n" 1005 "\t nop\n" 1006 "\t nop\n" 1007 "\t nop\n" 1008 "\t nop\n" 1009 "\t nop\n" 1010 "\t nop\n" 1011 "\t nop\n" 1012 "\t nop\n" 1013 "\t nop\n" 1014 "\t nop\n" 1015 "\t nop\n" 1016 "\t nop\n" 1017 "\t nop\n" 1018 "\t nop\n" 1019 "\t nop\n" 1020 "\t nop\n" 1021 "\t nop\n" 1022 "\t nop\n" 1023 "\t nop\n" 1024 "\t nop\n" 1025 "\t nop\n" 1026 "\t nop\n" 1027 "\t nop\n" 1028 "\t nop\n" 1029 "\t nop\n" 1030 "\t nop\n" 1031 "\t nop\n" 1032 "\t nop\n" 1033 "\t nop\n" 1034 "\t nop\n" 1035 "\t nop\n" 1036 "\t nop\n" 1037 "\t nop\n" 1038 "\t nop\n" 1039 "\t nop\n" 1040 "\t nop\n" 1041 "\t nop\n" 1042 "\t nop\n" 1043 "\t nop\n" 1044 "\t nop\n" 1045 "\t nop\n" 1046 "\t nop\n" 1047 "\t nop\n" 1048 "\t nop\n" 1049 "\t nop\n" 1050 "\t nop\n" 1051 "\t nop\n" 1052 "\t nop\n" 1053 "\t nop\n" 1054 "\t nop\n" 1055 "\t nop\n" 1056 "\t nop\n" 1057 "\t nop\n" 1058 "\t nop\n" 1059 "\t nop\n" 1060 "\t nop\n" 1061 "\t nop\n" 1062 "\t nop\n" 1063 "\t nop\n" 1064 "\t nop\n" 1065 "\t nop\n" 1066 "\t nop\n" 1067 "\t nop\n" 1068 "\t nop\n" 1069 "\t nop\n" 1070 "\t nop\n" 1071 "\t nop\n" 1072 "\t nop\n" 1073 "\t nop\n" 1074 "\t nop\n" 1075 "\t nop\n" 1076 "\t nop\n" 1077 "\t nop\n" 1078 "\t nop\n" 1079 "\t nop\n" 1080 "\t nop\n" 1081 "\t nop\n" 1082 "\t nop\n" 1083 "\t nop\n" 1084 "\t nop\n" 1085 "\t nop\n" 1086 "\t nop\n" 1087 "\t nop\n" 1088 "\t nop\n" 1089 "\t nop\n" 1090 "\t nop\n" 1091 "\t nop\n" 1092 "\t nop\n" 1093 "\t nop\n" 1094 "\t nop\n" 1095 "\t nop\n" 1096 "\t nop\n" 1097 "\t nop\n" 1098 "\t nop\n" 1099 "\t nop\n" 1100 "\t nop\n" 1101 "\t nop\n" 1102 "\t nop\n" 1103 "\t nop\n" 1104 "\t nop\n" 1105 "\t nop\n" 1106 "\t nop\n" 1107 "\t nop\n" 1108 "\t nop\n" 1109 "\t nop\n" 1110 "\t nop\n" 1111 "\t nop\n" 1112 "\t nop\n" 1113 "\t nop\n" 1114 "\t nop\n" 1115 "\t nop\n" 1116 "\t nop\n" 1117 "\t nop\n" 1118 "\t nop\n" 1119 "\t nop\n" 1120 "\t nop\n" 1121 "\t nop\n" 1122 "\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n" 1123 "\t nop\n" 1124 "\t nop\n" 1125 "\t nop\n" 1126 "\t nop\n" 1127 "\t nop\n" 1128 "\t nop\n" 1129 "\t nop\n" 1130 "\t nop\n" 1131 "\t nop\n" 1132 "\t nop\n" 1133 "\t nop\n" 1134 "\t nop\n" 1135 "\t nop\n" 1136 "\t nop\n" 1137 "\t nop\n" 1138 "\t nop\n" 1139 "\t nop\n" 1140 "\t nop\n" 1141 "\t nop\n" 1142 "\t nop\n" 1143 "\t nop\n" 1144 "\t nop\n" 1145 "\t nop\n" 1146 "\t nop\n" 1147 "\t nop\n" 1148 "\t nop\n" 1149 "\t nop\n" 1150 "\t nop\n" 1151 "\t nop\n" 1152 "\t nop\n" 1153 "\t nop\n" 1154 "\t nop\n" 1155 "\t nop\n" 1156 "\t nop\n" 1157 "\t nop\n" 1158 "\t nop\n" 1159 "\t nop\n" 1160 "\t nop\n" 1161 "\t nop\n" 1162 "\t nop\n" 1163 "\t nop\n" 1164 "\t nop\n" 1165 "\t nop\n" 1166 "\t nop\n" 1167 "\t nop\n" 1168 "\t nop\n" 1169 "\t nop\n" 1170 "\t nop\n" 1171 "\t nop\n" 1172 "\t nop\n" 1173 "\t nop\n" 1174 "\t nop\n" 1175 "\t nop\n" 1176 "\t nop\n" 1177 "\t nop\n" 1178 "\t nop\n" 1179 "\t nop\n" 1180 "\t nop\n" 1181 "\t nop\n" 1182 "\t nop\n" 1183 "\t nop\n" 1184 "\t nop\n" 1185 "\t nop\n" 1186 "\t nop\n" 1187 "\t nop\n" 1188 "\t nop\n" 1189 "\t nop\n" 1190 "\t nop\n" 1191 "\t nop\n" 1192 "\t nop\n" 1193 "\t nop\n" 1194 "\t nop\n" 1195 "\t nop\n" 1196 "\t nop\n" 1197 "\t nop\n" 1198 "\t nop\n" 1199 "\t nop\n" 1200 "\t nop\n" 1201 "\t nop\n" 1202 "\t nop\n" 1203 "\t nop\n" 1204 "\t nop\n" 1205 "\t nop\n" 1206 "\t nop\n" 1207 "\t nop\n" 1208 "\t nop\n" 1209 "\t nop\n" 1210 "\t nop\n" 1211 "\t nop\n" 1212 "\t nop\n" 1213 "\t nop\n" 1214 "\t nop\n" 1215 "\t nop\n" 1216 "\t nop\n" 1217 "\t nop\n" 1218 "\t nop\n" 1219 "\t nop\n" 1220 "\t nop\n" 1221 "\t nop\n" 1222 "\t nop\n" 1223 "\t nop\n" 1224 "\t nop\n" 1225 "\t nop\n" 1226 "\t nop\n" 1227 "\t nop\n" 1228 "\t nop\n" 1229 "\t nop\n" 1230 "\t nop\n" 1231 "\t nop\n" 1232 "\t nop\n" 1233 "\t nop\n" 1234 "\t nop\n" 1235 "\t nop\n" 1236 "\t nop\n" 1237 "\t nop\n" 1238 "\t nop\n" 1239 "\t nop\n" 1240 "\t nop\n" 1241 "\t nop\n" 1242 "\t nop\n" 1243 "\t nop\n" 1244 "\t nop\n" 1245 "\t nop\n" 1246 "\t nop\n" 1247 "\t nop\n" 1248 "\t nop\n" 1249 "\t nop\n" 1250 "\t nop\n" 1251 "\t nop\n" 1252 "\t nop\n" 1253 "\t nop\n" 1254 "\t nop\n" 1255 "\t nop\n" 1256 "\t nop\n" 1257 "\t nop\n" 1258 "\t nop\n" 1259 "\t nop\n" 1260 "\t nop\n" 1261 "\t nop\n" 1262 "\t nop\n" 1263 "\t nop\n" 1264 "\t nop\n" 1265 "\t nop\n" 1266 "\t nop\n" 1267 "\t nop\n" 1268 "\t nop\n" 1269 "\t nop\n" 1270 "\t nop\n" 1271 "\t nop\n" 1272 "\t nop\n" 1273 "\t nop\n" 1274 "\t nop\n" 1275 "\t nop\n" 1276 "\t nop\n" 1277 "\t nop\n" 1278 "\t nop\n" 1279 "\t nop\n" 1280 "\t nop\n" 1281 "\t nop\n" 1282 "\t nop\n" 1283 "\t nop\n" 1284 "\t nop\n" 1285 "\t nop\n" 1286 "\t nop\n" 1287 "\t nop\n" 1288 "\t nop\n" 1289 "\t nop\n" 1290 "\t nop\n" 1291 "\t nop\n" 1292 "\t nop\n" 1293 "\t nop\n" 1294 "\t nop\n" 1295 "\t nop\n" 1296 "\t nop\n" 1297 "\t nop\n" 1298 "\t nop\n" 1299 "\t nop\n" 1300 "\t nop\n" 1301 "\t nop\n" 1302 "\t nop\n" 1303 "\t nop\n" 1304 "\t nop\n" 1305 "\t nop\n" 1306 "\t nop\n" 1307 "\t nop\n" 1308 "\t nop\n" 1309 "\t nop\n" 1310 "\t nop\n" 1311 "\t nop\n" 1312 "\t subs %[i], #1 @ [1]\n" 1313 "\t beq.n 3f @ [1/3] end\n" 1314 "\t b 1b @ [1/3] send_bit\n" 1315 "\t3: @ end\n" 1316 : [value]"+r"(value), 1317 [i]"+r"(i) 1318 : [maskSet]"r"(maskSet), 1319 [portSet]"m"(*portSet), 1320 [maskClear]"r"(maskClear), 1321 [portClear]"m"(*portClear)); 1322 } 1323 */ 1324 import "C" 1325 1326 func (d Device) writeByte16(c byte) { 1327 portSet, maskSet := d.Pin.PortMaskSet() 1328 portClear, maskClear := d.Pin.PortMaskClear() 1329 1330 mask := interrupt.Disable() 1331 C.ws2812_writeByte16(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear)) 1332 1333 interrupt.Restore(mask) 1334 } 1335 1336 func (d Device) writeByte48(c byte) { 1337 portSet, maskSet := d.Pin.PortMaskSet() 1338 portClear, maskClear := d.Pin.PortMaskClear() 1339 1340 mask := interrupt.Disable() 1341 C.ws2812_writeByte48(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear)) 1342 1343 interrupt.Restore(mask) 1344 } 1345 1346 func (d Device) writeByte64(c byte) { 1347 portSet, maskSet := d.Pin.PortMaskSet() 1348 portClear, maskClear := d.Pin.PortMaskClear() 1349 1350 mask := interrupt.Disable() 1351 C.ws2812_writeByte64(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear)) 1352 1353 interrupt.Restore(mask) 1354 } 1355 1356 func (d Device) writeByte120(c byte) { 1357 portSet, maskSet := d.Pin.PortMaskSet() 1358 portClear, maskClear := d.Pin.PortMaskClear() 1359 1360 mask := interrupt.Disable() 1361 C.ws2812_writeByte120(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear)) 1362 1363 interrupt.Restore(mask) 1364 } 1365 1366 func (d Device) writeByte125(c byte) { 1367 portSet, maskSet := d.Pin.PortMaskSet() 1368 portClear, maskClear := d.Pin.PortMaskClear() 1369 1370 mask := interrupt.Disable() 1371 C.ws2812_writeByte125(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear)) 1372 1373 interrupt.Restore(mask) 1374 } 1375 1376 func (d Device) writeByte168(c byte) { 1377 portSet, maskSet := d.Pin.PortMaskSet() 1378 portClear, maskClear := d.Pin.PortMaskClear() 1379 1380 mask := interrupt.Disable() 1381 C.ws2812_writeByte168(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear)) 1382 1383 interrupt.Restore(mask) 1384 }