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.

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "DMAChannel.h"
  2. #if defined(KINETISK)
  3. // The channel allocation bitmask is accessible from "C" namespace,
  4. // so C-only code can reserve DMA channels
  5. uint16_t dma_channel_allocated_mask = 0;
  6. void DMAChannel::begin(bool force_initialization)
  7. {
  8. uint32_t ch = 0;
  9. __disable_irq();
  10. if (!force_initialization && TCD && channel < DMA_NUM_CHANNELS
  11. && (dma_channel_allocated_mask & (1 << channel))
  12. && (uint32_t)TCD == (uint32_t)(0x40009000 + channel * 32)) {
  13. // DMA channel already allocated
  14. __enable_irq();
  15. return;
  16. }
  17. while (1) {
  18. if (!(dma_channel_allocated_mask & (1 << ch))) {
  19. dma_channel_allocated_mask |= (1 << ch);
  20. __enable_irq();
  21. break;
  22. }
  23. if (++ch >= DMA_NUM_CHANNELS) {
  24. __enable_irq();
  25. TCD = (TCD_t *)0;
  26. channel = DMA_NUM_CHANNELS;
  27. return; // no more channels available
  28. // attempts to use this object will hardfault
  29. }
  30. }
  31. channel = ch;
  32. SIM_SCGC7 |= SIM_SCGC7_DMA;
  33. SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
  34. DMA_CR = DMA_CR_EMLM | DMA_CR_EDBG ; // minor loop mapping is available
  35. DMA_CERQ = ch;
  36. DMA_CERR = ch;
  37. DMA_CEEI = ch;
  38. DMA_CINT = ch;
  39. TCD = (TCD_t *)(0x40009000 + ch * 32);
  40. uint32_t *p = (uint32_t *)TCD;
  41. *p++ = 0;
  42. *p++ = 0;
  43. *p++ = 0;
  44. *p++ = 0;
  45. *p++ = 0;
  46. *p++ = 0;
  47. *p++ = 0;
  48. *p++ = 0;
  49. }
  50. void DMAChannel::release(void)
  51. {
  52. if (channel >= DMA_NUM_CHANNELS) return;
  53. DMA_CERQ = channel;
  54. __disable_irq();
  55. dma_channel_allocated_mask &= ~(1 << channel);
  56. __enable_irq();
  57. channel = 16;
  58. TCD = (TCD_t *)0;
  59. }
  60. static uint32_t priority(const DMAChannel &c)
  61. {
  62. uint32_t n;
  63. n = *(uint32_t *)((uint32_t)&DMA_DCHPRI3 + (c.channel & 0xFC));
  64. n = __builtin_bswap32(n);
  65. return (n >> ((c.channel & 0x03) << 3)) & 0x0F;
  66. }
  67. static void swap(DMAChannel &c1, DMAChannel &c2)
  68. {
  69. uint8_t c;
  70. DMABaseClass::TCD_t *t;
  71. c = c1.channel;
  72. c1.channel = c2.channel;
  73. c2.channel = c;
  74. t = c1.TCD;
  75. c1.TCD = c2.TCD;
  76. c2.TCD = t;
  77. }
  78. void DMAPriorityOrder(DMAChannel &ch1, DMAChannel &ch2)
  79. {
  80. if (priority(ch1) < priority(ch2)) swap(ch1, ch2);
  81. }
  82. void DMAPriorityOrder(DMAChannel &ch1, DMAChannel &ch2, DMAChannel &ch3)
  83. {
  84. if (priority(ch2) < priority(ch3)) swap(ch2, ch3);
  85. if (priority(ch1) < priority(ch2)) swap(ch1, ch2);
  86. if (priority(ch2) < priority(ch3)) swap(ch2, ch3);
  87. }
  88. void DMAPriorityOrder(DMAChannel &ch1, DMAChannel &ch2, DMAChannel &ch3, DMAChannel &ch4)
  89. {
  90. if (priority(ch3) < priority(ch4)) swap(ch3, ch4);
  91. if (priority(ch2) < priority(ch3)) swap(ch2, ch3);
  92. if (priority(ch1) < priority(ch2)) swap(ch1, ch2);
  93. if (priority(ch3) < priority(ch4)) swap(ch2, ch3);
  94. if (priority(ch2) < priority(ch3)) swap(ch1, ch2);
  95. if (priority(ch3) < priority(ch4)) swap(ch2, ch3);
  96. }
  97. #endif