mirror of https://github.com/ARMmbed/mbed-os.git
SiLabs Pearl: LDMA fixes for serial
LDMA now functional for both RX/TX. One hack remains - need to check if TXC interrupt check can be removed from older platforms, or if flagging is necessary.pull/1501/head
parent
fc49b0e2ac
commit
6095a67b95
|
|
@ -76,7 +76,6 @@ void dma_init(void)
|
||||||
DMA_Init(&dmaInit);
|
DMA_Init(&dmaInit);
|
||||||
|
|
||||||
#elif defined LDMA_PRESENT
|
#elif defined LDMA_PRESENT
|
||||||
CMU_ClockEnable(cmuClock_BUS, true);
|
|
||||||
CMU_ClockEnable(cmuClock_LDMA, true);
|
CMU_ClockEnable(cmuClock_LDMA, true);
|
||||||
|
|
||||||
LDMA_Init_t ldmaInit;
|
LDMA_Init_t ldmaInit;
|
||||||
|
|
|
||||||
|
|
@ -1195,19 +1195,33 @@ static void serial_dmaActivate(serial_t *obj, void* cb, void* buffer, int length
|
||||||
|
|
||||||
static void serial_dmaSetupChannel(serial_t *obj, bool tx_nrx)
|
static void serial_dmaSetupChannel(serial_t *obj, bool tx_nrx)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serial_dmaActivate(serial_t *obj, void* cb, void* buffer, int length, bool tx_nrx)
|
static void serial_dmaActivate(serial_t *obj, void* cb, void* buffer, int length, bool tx_nrx)
|
||||||
{
|
{
|
||||||
uint32_t dma_periph;
|
LDMA_PeripheralSignal_t dma_periph;
|
||||||
|
|
||||||
obj->serial.dmaOptionsRX.dmaCallback.userPtr = cb;
|
obj->serial.dmaOptionsRX.dmaCallback.userPtr = cb;
|
||||||
|
|
||||||
if( tx_nrx ) {
|
if( tx_nrx ) {
|
||||||
|
volatile void *target_addr;
|
||||||
|
|
||||||
switch((uint32_t)(obj->serial.periph.uart)) {
|
switch((uint32_t)(obj->serial.periph.uart)) {
|
||||||
case USART_0: dma_periph = DMAREQ_USART0_TXBL; break;
|
case USART_0:
|
||||||
case USART_1: dma_periph = DMAREQ_USART1_TXBL; break;
|
dma_periph = ldmaPeripheralSignal_USART0_TXBL;
|
||||||
case LEUART_0: dma_periph = DMAREQ_LEUART0_TXBL; break;
|
target_addr = &USART0->TXDATA;
|
||||||
|
obj->serial.periph.uart->CMD = USART_CMD_TXEN | USART_CMD_CLEARTX;
|
||||||
|
break;
|
||||||
|
case USART_1:
|
||||||
|
dma_periph = ldmaPeripheralSignal_USART1_TXBL;
|
||||||
|
target_addr = &USART1->TXDATA;
|
||||||
|
obj->serial.periph.uart->CMD = USART_CMD_TXEN | USART_CMD_CLEARTX;
|
||||||
|
break;
|
||||||
|
case LEUART_0:
|
||||||
|
dma_periph = ldmaPeripheralSignal_LEUART0_TXBL;
|
||||||
|
target_addr = &LEUART0->TXDATA;
|
||||||
|
obj->serial.periph.leuart->CMD = LEUART_CMD_TXEN;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
EFM_ASSERT(0);
|
EFM_ASSERT(0);
|
||||||
while(1);
|
while(1);
|
||||||
|
|
@ -1215,14 +1229,28 @@ static void serial_dmaActivate(serial_t *obj, void* cb, void* buffer, int length
|
||||||
}
|
}
|
||||||
|
|
||||||
LDMA_TransferCfg_t xferConf = LDMA_TRANSFER_CFG_PERIPHERAL(dma_periph);
|
LDMA_TransferCfg_t xferConf = LDMA_TRANSFER_CFG_PERIPHERAL(dma_periph);
|
||||||
LDMA_Descriptor_t desc = LDMA_DESCRIPTOR_SINGLE_M2P_BYTE(buffer, dma_periph, length);
|
LDMA_Descriptor_t desc = LDMA_DESCRIPTOR_SINGLE_M2P_BYTE(buffer, target_addr, length);
|
||||||
LDMA_StartTransfer(obj->serial.dmaOptionsTX.dmaChannel, &xferConf, &desc, serial_dmaTransferComplete, cb);
|
LDMA_StartTransfer(obj->serial.dmaOptionsTX.dmaChannel, &xferConf, &desc, serial_dmaTransferComplete, cb);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
volatile const void *source_addr;
|
||||||
|
|
||||||
switch((uint32_t)(obj->serial.periph.uart)) {
|
switch((uint32_t)(obj->serial.periph.uart)) {
|
||||||
case USART_0: dma_periph = DMAREQ_USART0_RXDATAV; break;
|
case USART_0:
|
||||||
case USART_1: dma_periph = DMAREQ_USART1_RXDATAV; break;
|
dma_periph = ldmaPeripheralSignal_USART0_RXDATAV;
|
||||||
case LEUART_0: dma_periph = DMAREQ_LEUART0_RXDATAV; break;
|
source_addr = &USART0->RXDATA;
|
||||||
|
obj->serial.periph.uart->CMD = USART_CMD_RXEN | USART_CMD_CLEARRX;
|
||||||
|
break;
|
||||||
|
case USART_1:
|
||||||
|
dma_periph = ldmaPeripheralSignal_USART1_RXDATAV;
|
||||||
|
source_addr = &USART1->RXDATA;
|
||||||
|
obj->serial.periph.uart->CMD = USART_CMD_RXEN | USART_CMD_CLEARRX;
|
||||||
|
break;
|
||||||
|
case LEUART_0:
|
||||||
|
dma_periph = ldmaPeripheralSignal_LEUART0_RXDATAV;
|
||||||
|
source_addr = &LEUART0->RXDATA;
|
||||||
|
obj->serial.periph.leuart->CMD = LEUART_CMD_RXEN | LEUART_CMD_CLEARRX;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
EFM_ASSERT(0);
|
EFM_ASSERT(0);
|
||||||
while(1);
|
while(1);
|
||||||
|
|
@ -1230,7 +1258,7 @@ static void serial_dmaActivate(serial_t *obj, void* cb, void* buffer, int length
|
||||||
}
|
}
|
||||||
|
|
||||||
LDMA_TransferCfg_t xferConf = LDMA_TRANSFER_CFG_PERIPHERAL(dma_periph);
|
LDMA_TransferCfg_t xferConf = LDMA_TRANSFER_CFG_PERIPHERAL(dma_periph);
|
||||||
LDMA_Descriptor_t desc = LDMA_DESCRIPTOR_SINGLE_P2M_BYTE(dma_periph, buffer, length);
|
LDMA_Descriptor_t desc = LDMA_DESCRIPTOR_SINGLE_P2M_BYTE(source_addr, buffer, length);
|
||||||
LDMA_StartTransfer(obj->serial.dmaOptionsRX.dmaChannel, &xferConf, &desc, serial_dmaTransferComplete, cb);
|
LDMA_StartTransfer(obj->serial.dmaOptionsRX.dmaChannel, &xferConf, &desc, serial_dmaTransferComplete, cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1778,16 +1806,17 @@ int serial_irq_handler_asynch(serial_t *obj)
|
||||||
LEUART_IntEnable(obj->serial.periph.leuart,LEUART_IEN_TXC);
|
LEUART_IntEnable(obj->serial.periph.leuart,LEUART_IEN_TXC);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(obj->serial.periph.uart->IEN & USART_IEN_TXC){
|
// HACK
|
||||||
USART_IntDisable(obj->serial.periph.uart,USART_IEN_TXC);
|
//if(obj->serial.periph.uart->IEN & USART_IEN_TXC){
|
||||||
|
// USART_IntDisable(obj->serial.periph.uart,USART_IEN_TXC);
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
serial_dma_irq_fired[obj->serial.dmaOptionsTX.dmaChannel] = false;
|
serial_dma_irq_fired[obj->serial.dmaOptionsTX.dmaChannel] = false;
|
||||||
serial_tx_abort_asynch(obj);
|
serial_tx_abort_asynch(obj);
|
||||||
/* Notify CPP land of completion */
|
/* Notify CPP land of completion */
|
||||||
return SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
|
return SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
|
||||||
}else{
|
//}else{
|
||||||
USART_IntEnable(obj->serial.periph.uart,USART_IEN_TXC);
|
// USART_IntEnable(obj->serial.periph.uart,USART_IEN_TXC);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Check the NVIC to see which interrupt we're running from
|
/* Check the NVIC to see which interrupt we're running from
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue