Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Fri Feb 26 18:42:03 2016 +0000
Revision:
48:058ace2aed1d
Parent:
47:df7a88cd249c
Child:
54:fd77a6b2f76c
New plunger processing 1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 45:c42166b2878c 1 #if defined TARGET_KL25Z || defined TARGET_KL46Z
mjr 45:c42166b2878c 2 #include "SimpleDMA.h"
mjr 45:c42166b2878c 3
mjr 45:c42166b2878c 4
mjr 45:c42166b2878c 5
mjr 45:c42166b2878c 6 SimpleDMA *SimpleDMA::irq_owner[4] = {NULL};
mjr 45:c42166b2878c 7
mjr 48:058ace2aed1d 8 void SimpleDMA::class_init()
mjr 48:058ace2aed1d 9 {
mjr 48:058ace2aed1d 10 static bool inited = false;
mjr 48:058ace2aed1d 11 if (!inited)
mjr 48:058ace2aed1d 12 {
mjr 48:058ace2aed1d 13 NVIC_SetVector(DMA0_IRQn, (uint32_t)&irq_handler0);
mjr 48:058ace2aed1d 14 NVIC_SetVector(DMA1_IRQn, (uint32_t)&irq_handler1);
mjr 48:058ace2aed1d 15 NVIC_SetVector(DMA2_IRQn, (uint32_t)&irq_handler2);
mjr 48:058ace2aed1d 16 NVIC_SetVector(DMA3_IRQn, (uint32_t)&irq_handler3);
mjr 48:058ace2aed1d 17 NVIC_EnableIRQ(DMA0_IRQn);
mjr 48:058ace2aed1d 18 NVIC_EnableIRQ(DMA1_IRQn);
mjr 48:058ace2aed1d 19 NVIC_EnableIRQ(DMA2_IRQn);
mjr 48:058ace2aed1d 20 NVIC_EnableIRQ(DMA3_IRQn);
mjr 48:058ace2aed1d 21 inited = true;
mjr 48:058ace2aed1d 22 }
mjr 48:058ace2aed1d 23 }
mjr 48:058ace2aed1d 24
mjr 47:df7a88cd249c 25 SimpleDMA::SimpleDMA(int channel)
mjr 47:df7a88cd249c 26 {
mjr 48:058ace2aed1d 27 class_init();
mjr 48:058ace2aed1d 28
mjr 45:c42166b2878c 29 this->channel(channel);
mjr 45:c42166b2878c 30
mjr 45:c42166b2878c 31 //Enable DMA
mjr 45:c42166b2878c 32 SIM->SCGC6 |= 1<<1; //Enable clock to DMA mux
mjr 45:c42166b2878c 33 SIM->SCGC7 |= 1<<8; //Enable clock to DMA
mjr 45:c42166b2878c 34
mjr 45:c42166b2878c 35 trigger(Trigger_ALWAYS);
mjr 45:c42166b2878c 36
mjr 47:df7a88cd249c 37 // presume no link channels
mjr 47:df7a88cd249c 38 linkMode = 0;
mjr 47:df7a88cd249c 39 linkChannel1 = 0;
mjr 47:df7a88cd249c 40 linkChannel2 = 0;
mjr 45:c42166b2878c 41 }
mjr 45:c42166b2878c 42
mjr 47:df7a88cd249c 43 int SimpleDMA::start(uint32_t length)
mjr 48:058ace2aed1d 44 {
mjr 45:c42166b2878c 45 if (auto_channel)
mjr 45:c42166b2878c 46 _channel = getFreeChannel();
mjr 45:c42166b2878c 47 else
mjr 45:c42166b2878c 48 while(isBusy());
mjr 45:c42166b2878c 49
mjr 45:c42166b2878c 50 if (length > DMA_DSR_BCR_BCR_MASK)
mjr 45:c42166b2878c 51 return -1;
mjr 45:c42166b2878c 52
mjr 45:c42166b2878c 53 irq_owner[_channel] = this;
mjr 48:058ace2aed1d 54
mjr 48:058ace2aed1d 55 // disable the channel while we're setting it up
mjr 48:058ace2aed1d 56 DMAMUX0->CHCFG[_channel] = 0;
mjr 48:058ace2aed1d 57
mjr 45:c42166b2878c 58 uint32_t config =
mjr 45:c42166b2878c 59 DMA_DCR_EINT_MASK
mjr 45:c42166b2878c 60 | DMA_DCR_ERQ_MASK
mjr 48:058ace2aed1d 61 | DMA_DCR_CS_MASK
mjr 45:c42166b2878c 62 | (source_inc << DMA_DCR_SINC_SHIFT)
mjr 45:c42166b2878c 63 | (destination_inc << DMA_DCR_DINC_SHIFT)
mjr 47:df7a88cd249c 64 | ((linkChannel1 & 3) << DMA_DCR_LCH1_SHIFT)
mjr 47:df7a88cd249c 65 | ((linkChannel2 & 3) << DMA_DCR_LCH2_SHIFT)
mjr 47:df7a88cd249c 66 | ((linkMode & 3) << DMA_DCR_LINKCC_SHIFT);
mjr 47:df7a88cd249c 67
mjr 45:c42166b2878c 68 switch (source_size) {
mjr 45:c42166b2878c 69 case 8:
mjr 45:c42166b2878c 70 config |= 1 << DMA_DCR_SSIZE_SHIFT;
mjr 45:c42166b2878c 71 break;
mjr 45:c42166b2878c 72 case 16:
mjr 45:c42166b2878c 73 config |= 2 << DMA_DCR_SSIZE_SHIFT;
mjr 45:c42166b2878c 74 break;
mjr 45:c42166b2878c 75 }
mjr 45:c42166b2878c 76 switch (destination_size) {
mjr 45:c42166b2878c 77 case 8:
mjr 45:c42166b2878c 78 config |= 1 << DMA_DCR_DSIZE_SHIFT;
mjr 45:c42166b2878c 79 break;
mjr 45:c42166b2878c 80 case 16:
mjr 45:c42166b2878c 81 config |= 2 << DMA_DCR_DSIZE_SHIFT;
mjr 45:c42166b2878c 82 break;
mjr 45:c42166b2878c 83 }
mjr 45:c42166b2878c 84
mjr 45:c42166b2878c 85 DMA0->DMA[_channel].DCR = config;
mjr 48:058ace2aed1d 86 DMA0->DMA[_channel].SAR = _source;
mjr 48:058ace2aed1d 87 DMA0->DMA[_channel].DAR = _destination;
mjr 48:058ace2aed1d 88 DMAMUX0->CHCFG[_channel] = _trigger;
mjr 48:058ace2aed1d 89 DMA0->DMA[_channel].DSR_BCR = length;
mjr 47:df7a88cd249c 90
mjr 47:df7a88cd249c 91 //$$$
mjr 48:058ace2aed1d 92 // static int iii; if (_channel != 0 && iii++ < 3)
mjr 48:058ace2aed1d 93 // printf("DMA channel %d: mode %04x, source %08lx, dest %08lx, trigger %d, len %d\r\n", _channel, config, _source, _destination, _trigger, length);
mjr 45:c42166b2878c 94
mjr 47:df7a88cd249c 95 //Start - set ENBL bit in the DMAMUX channel config register
mjr 45:c42166b2878c 96 DMAMUX0->CHCFG[_channel] |= 1<<7;
mjr 45:c42166b2878c 97
mjr 45:c42166b2878c 98 return 0;
mjr 45:c42166b2878c 99 }
mjr 45:c42166b2878c 100
mjr 47:df7a88cd249c 101 void SimpleDMA::link(SimpleDMA &dest, bool all)
mjr 47:df7a88cd249c 102 {
mjr 47:df7a88cd249c 103 linkChannel1 = dest._channel;
mjr 47:df7a88cd249c 104 linkChannel2 = 0;
mjr 47:df7a88cd249c 105 linkMode = all ? 3 : 2;
mjr 47:df7a88cd249c 106 }
mjr 47:df7a88cd249c 107
mjr 47:df7a88cd249c 108 void SimpleDMA::link(SimpleDMA &dest1, SimpleDMA &dest2)
mjr 47:df7a88cd249c 109 {
mjr 47:df7a88cd249c 110 linkChannel1 = dest1._channel;
mjr 47:df7a88cd249c 111 linkChannel2 = dest2._channel;
mjr 47:df7a88cd249c 112 linkMode = 1;
mjr 47:df7a88cd249c 113 }
mjr 47:df7a88cd249c 114
mjr 47:df7a88cd249c 115
mjr 45:c42166b2878c 116 int SimpleDMA::restart(uint32_t length)
mjr 45:c42166b2878c 117 {
mjr 45:c42166b2878c 118 DMA0->DMA[_channel].SAR = _source;
mjr 45:c42166b2878c 119 DMA0->DMA[_channel].DAR = _destination;
mjr 45:c42166b2878c 120 DMA0->DMA[_channel].DSR_BCR = length;
mjr 45:c42166b2878c 121 DMAMUX0->CHCFG[_channel] |= 1<<7;
mjr 45:c42166b2878c 122 return 0;
mjr 45:c42166b2878c 123 }
mjr 45:c42166b2878c 124
mjr 47:df7a88cd249c 125 bool SimpleDMA::isBusy( int channel )
mjr 47:df7a88cd249c 126 {
mjr 45:c42166b2878c 127 //Busy bit doesn't work as I expect it to do, so just check if counter is at zero
mjr 45:c42166b2878c 128 //return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25);
mjr 45:c42166b2878c 129 if (channel == -1)
mjr 45:c42166b2878c 130 channel = _channel;
mjr 45:c42166b2878c 131
mjr 45:c42166b2878c 132 return (DMA0->DMA[channel].DSR_BCR & 0xFFFFF);
mjr 45:c42166b2878c 133 }
mjr 45:c42166b2878c 134
mjr 45:c42166b2878c 135 /*****************************************************************/
mjr 45:c42166b2878c 136 uint32_t SimpleDMA::remaining(int channel)
mjr 45:c42166b2878c 137 {
mjr 45:c42166b2878c 138 // note that the BCR register always reads with binary 1110
mjr 45:c42166b2878c 139 // (if the configuration is correct) or 1111 (if there's an
mjr 45:c42166b2878c 140 // error in the configuration) in bits 23-20, so we need
mjr 45:c42166b2878c 141 // to mask these out - only keep bits 19-0 (low-order 20
mjr 45:c42166b2878c 142 // bits = 0xFFFFF)
mjr 45:c42166b2878c 143 return (DMA0->DMA[channel < 0 ? _channel : channel].DSR_BCR & 0xFFFFF);
mjr 45:c42166b2878c 144 }
mjr 45:c42166b2878c 145
mjr 45:c42166b2878c 146 /*****************************************************************/
mjr 47:df7a88cd249c 147 void SimpleDMA::irq_handler(void)
mjr 47:df7a88cd249c 148 {
mjr 45:c42166b2878c 149 DMAMUX0->CHCFG[_channel] = 0;
mjr 45:c42166b2878c 150 DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ;
mjr 45:c42166b2878c 151 _callback.call();
mjr 45:c42166b2878c 152 }
mjr 45:c42166b2878c 153
mjr 47:df7a88cd249c 154 void SimpleDMA::irq_handler0( void )
mjr 47:df7a88cd249c 155 {
mjr 45:c42166b2878c 156 if (irq_owner[0]!=NULL)
mjr 45:c42166b2878c 157 irq_owner[0]->irq_handler();
mjr 45:c42166b2878c 158 }
mjr 45:c42166b2878c 159
mjr 47:df7a88cd249c 160 void SimpleDMA::irq_handler1( void )
mjr 47:df7a88cd249c 161 {
mjr 45:c42166b2878c 162 if (irq_owner[1]!=NULL)
mjr 45:c42166b2878c 163 irq_owner[1]->irq_handler();
mjr 45:c42166b2878c 164 }
mjr 45:c42166b2878c 165
mjr 47:df7a88cd249c 166 void SimpleDMA::irq_handler2( void )
mjr 47:df7a88cd249c 167 {
mjr 45:c42166b2878c 168 if (irq_owner[2]!=NULL)
mjr 45:c42166b2878c 169 irq_owner[2]->irq_handler();
mjr 45:c42166b2878c 170 }
mjr 45:c42166b2878c 171
mjr 47:df7a88cd249c 172 void SimpleDMA::irq_handler3( void )
mjr 47:df7a88cd249c 173 {
mjr 45:c42166b2878c 174 if (irq_owner[3]!=NULL)
mjr 45:c42166b2878c 175 irq_owner[3]->irq_handler();
mjr 45:c42166b2878c 176 }
mjr 45:c42166b2878c 177 #endif