PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
5.1KB

  1. /*
  2. This example was adapted from ugfx http://ugfx.org
  3. It's a great example of many 2d objects in a 3d space (matrix transformations)
  4. and show the capabilities of RA8875 chip.
  5. Tested and worked with:
  6. Teensy3,Teensy3.1,Arduino UNO,Arduino YUN,Arduino Leonardo,Stellaris
  7. Works with Arduino 1.0.6 IDE, Arduino 1.5.8 IDE, Energia 0013 IDE
  8. */
  9. #ifdef __AVR__
  10. #define sinf sin
  11. #endif
  12. #define NDOTS 512 // Number of dots
  13. #define SCALE 4096
  14. #define INCREMENT 512
  15. #define PI2 6.283185307179586476925286766559
  16. #define RED_COLORS (32)
  17. #define GREEN_COLORS (64)
  18. #define BLUE_COLORS (32)
  19. #include <SPI.h>
  20. #include <RA8875.h>
  21. /*
  22. Teensy3.x and Arduino's
  23. You are using 4 wire SPI here, so:
  24. MOSI: 11//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
  25. MISO: 12//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
  26. SCK: 13//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
  27. the rest of pin below:
  28. */
  29. #define RA8875_INT 2 //any pin
  30. #define RA8875_CS 10 //see below...
  31. /*
  32. Teensy 3.x can use: 2,6,9,10,15,20,21,22,23
  33. Arduino's 8 bit: any
  34. DUE: should be any but not sure
  35. */
  36. #define RA8875_RESET 9//any pin or nothing!
  37. #if defined(NEEDS_SET_MODULE)//Energia, this case is for stellaris/tiva
  38. RA8875 tft = RA8875(3);//select SPI module 3
  39. /*
  40. for module 3 (stellaris)
  41. SCLK: PD_0
  42. MOSI: PD_3
  43. MISO: PD_2
  44. SS: PD_1
  45. */
  46. #else
  47. RA8875 tft = RA8875(RA8875_CS,RA8875_RESET);//Teensy3/arduino's
  48. #endif
  49. int16_t sine[SCALE+(SCALE/4)];
  50. int16_t *cosi = &sine[SCALE/4];
  51. int16_t angleX = 0, angleY = 0, angleZ = 0;
  52. int16_t speedX = 0, speedY = 0, speedZ = 0;
  53. int16_t xyz[3][NDOTS];
  54. uint16_t col[NDOTS];
  55. int pass = 0;
  56. void initialize (void){
  57. uint16_t i;
  58. /* if you change the SCALE*1.25 back to SCALE, the program will
  59. * occassionally overrun the cosi array -- however this actually
  60. * produces some interesting effects as the BUBBLES LOSE CONTROL!!!!
  61. */
  62. for (i = 0; i < SCALE+(SCALE/4); i++)
  63. //sine[i] = (-SCALE/2) + (int)(sinf(PI2 * i / SCALE) * sinf(PI2 * i / SCALE) * SCALE);
  64. sine[i] = (int)(sinf(PI2 * i / SCALE) * SCALE);
  65. }
  66. void setup()
  67. {
  68. Serial.begin(9600);
  69. //while (!Serial) {;}
  70. Serial.println("RA8875 start");
  71. tft.begin(RA8875_480x272);
  72. initialize();
  73. }
  74. void matrix (int16_t xyz[3][NDOTS], uint16_t col[NDOTS]){
  75. static uint32_t t = 0;
  76. int16_t x = -SCALE, y = -SCALE;
  77. uint16_t i, s, d;
  78. uint8_t red,grn,blu;
  79. for (i = 0; i < NDOTS; i++)
  80. {
  81. xyz[0][i] = x;
  82. xyz[1][i] = y;
  83. d = sqrt(x * x + y * y); /* originally a fastsqrt() call */
  84. s = sine[(t * 30) % SCALE] + SCALE;
  85. xyz[2][i] = sine[(d + s) % SCALE] * sine[(t * 10) % SCALE] / SCALE / 2;
  86. red = (cosi[xyz[2][i] + SCALE / 2] + SCALE) * (RED_COLORS - 1) / SCALE / 2;
  87. grn = (cosi[(xyz[2][i] + SCALE / 2 + 2 * SCALE / 3) % SCALE] + SCALE) * (GREEN_COLORS - 1) / SCALE / 2;
  88. blu = (cosi[(xyz[2][i] + SCALE / 2 + SCALE / 3) % SCALE] + SCALE) * (BLUE_COLORS - 1) / SCALE / 2;
  89. col[i] = ((red << 11) + (grn << 5) + blu);
  90. x += INCREMENT;
  91. if (x >= SCALE) x = -SCALE, y += INCREMENT;
  92. }
  93. t++;
  94. }
  95. void rotate (int16_t xyz[3][NDOTS], uint16_t angleX, uint16_t angleY, uint16_t angleZ){
  96. uint16_t i;
  97. int16_t tmpX, tmpY;
  98. int16_t sinx = sine[angleX], cosx = cosi[angleX];
  99. int16_t siny = sine[angleY], cosy = cosi[angleY];
  100. int16_t sinz = sine[angleZ], cosz = cosi[angleZ];
  101. for (i = 0; i < NDOTS; i++)
  102. {
  103. tmpX = (xyz[0][i] * cosx - xyz[2][i] * sinx) / SCALE;
  104. xyz[2][i] = (xyz[0][i] * sinx + xyz[2][i] * cosx) / SCALE;
  105. xyz[0][i] = tmpX;
  106. tmpY = (xyz[1][i] * cosy - xyz[2][i] * siny) / SCALE;
  107. xyz[2][i] = (xyz[1][i] * siny + xyz[2][i] * cosy) / SCALE;
  108. xyz[1][i] = tmpY;
  109. tmpX = (xyz[0][i] * cosz - xyz[1][i] * sinz) / SCALE;
  110. xyz[1][i] = (xyz[0][i] * sinz + xyz[1][i] * cosz) / SCALE;
  111. xyz[0][i] = tmpX;
  112. }
  113. }
  114. void draw(int16_t xyz[3][NDOTS], uint16_t col[NDOTS]){
  115. static uint16_t oldProjX[NDOTS] = { 0 };
  116. static uint16_t oldProjY[NDOTS] = { 0 };
  117. static uint8_t oldDotSize[NDOTS] = { 0 };
  118. uint16_t i, projX, projY, projZ, dotSize;
  119. for (i = 0; i < NDOTS; i++)
  120. {
  121. projZ = SCALE - (xyz[2][i] + SCALE) / 4;
  122. projX = tft.width() / 2 + (xyz[0][i] * projZ / SCALE) / 25;
  123. projY = tft.height() / 2 + (xyz[1][i] * projZ / SCALE) / 25;
  124. dotSize = 3 - (xyz[2][i] + SCALE) * 2 / SCALE;
  125. tft.drawCircle (oldProjX[i], oldProjY[i], oldDotSize[i], RA8875_BLACK);
  126. if (projX > dotSize && projY > dotSize && projX < tft.width() - dotSize && projY < tft.height() - dotSize)
  127. {
  128. tft.drawCircle (projX, projY, dotSize, col[i]);
  129. oldProjX[i] = projX;
  130. oldProjY[i] = projY;
  131. oldDotSize[i] = dotSize;
  132. }
  133. }
  134. }
  135. void loop()
  136. {
  137. matrix(xyz, col);
  138. rotate(xyz, angleX, angleY, angleZ);
  139. draw(xyz, col);
  140. angleX += speedX;
  141. angleY += speedY;
  142. angleZ += speedZ;
  143. if (pass > 400) speedY = 1;
  144. if (pass > 800) speedX = 1;
  145. if (pass > 1200) speedZ = 1;
  146. pass++;
  147. if (angleX >= SCALE) {
  148. angleX -= SCALE;
  149. }
  150. else if (angleX < 0) {
  151. angleX += SCALE;
  152. }
  153. if (angleY >= SCALE) {
  154. angleY -= SCALE;
  155. }
  156. else if (angleY < 0) {
  157. angleY += SCALE;
  158. }
  159. if (angleZ >= SCALE) {
  160. angleZ -= SCALE;
  161. }
  162. else if (angleZ < 0) {
  163. angleZ += SCALE;
  164. }
  165. }