This is the code I have developed so far:
#include "board.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
#define SCT_PWM LPC_SCT
#define SCT_PWM_PIN_OUT 4 /* COUT4 Generate square wave */
#define SCT_PWM_OUT 1 /* Index of OUT PWM */
#define SCT_PWM_RATE 51200 /* PWM frequency 51.2 KHz */
#define SCT_PWM_CHANNEL 0 // Definir el canal del SCT para el PWM
#define SIZE_SINE_TABLE (sizeof(sine_table) / sizeof(sine_table[0]))
volatile bool dmaDone;
// LED_W
#define LED_W_PORT 0
#define LED_W_PIN 19
#define LED_W_OUT LPC_GPIO->DIR[LED_W_PORT] |= (1UL << LED_W_PIN)
#define LED_W_HI LPC_GPIO->B[LED_W_PORT][LED_W_PIN] = true
#define LED_W_LO LPC_GPIO->B[LED_W_PORT][LED_W_PIN] = false
#define LED_W_INP LPC_GPIO->DIR[LED_W_PORT] &= ~(1UL << LED_W_PIN)
#define LED_W_IN LPC_GPIO->B[LED_W_PORT][LED_W_PIN]
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
#define TABLE_SIZE 20
uint16_t sine_table[TABLE_SIZE] = {488,647,788,897,962,975,935,848,721,569,408,256,129,41,2,15,80,188,330,488};
/*****************************************************************************
* Private functions
****************************************************************************/
/* Setup board specific pin muxing */
static void app_setup_pin(void)
{
Chip_IOCON_PinMuxSet(LPC_IOCON, 1, 1, IOCON_FUNC3 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 19, IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN);
}
/*****************************************************************************
* Public functions
****************************************************************************/
void update_pwm()
{
static uint16_t index = 0;
static uint8_t counter = 0;
if(counter == 0) {
LPC_SCT->MATCHREL[1].L = sine_table[index] ;
index = (index + 1) % TABLE_SIZE;
}
counter = (counter + 1) % 5;
LED_W_INP;
}
void SCT0_IRQHandler(void)
{
if (LPC_SCT->EVFLAG & (1 << 0))
{
update_pwm();
LPC_SCT->EVFLAG = (1 << 0); // clear flag of event 0
}
}
void STC0_Init(void)
{
/* Initialize the SCT as PWM and set frequency */
Chip_SCTPWM_Init(SCT_PWM);
NVIC_EnableIRQ(SCT0_IRQn);
Chip_SCTPWM_SetRate(SCT_PWM, SCT_PWM_RATE);
LPC_SCT->EVENT[1].STATE = 0xFFFFFFFF; // valid event on all states
LPC_SCT->EVENT[1].CTRL = (1 << 0) | (1 << 12); // MATCH[1].L and match event
LPC_SCT->EVFLAG = (1 << 0); // clear flag of event 0
LPC_SCT->EVEN = (1 << 0); // enable interrupt for event 0
LPC_SCT->DMAREQ0 |= (1 << 1);
}
void DMA_IRQHandler(void)
{
if ((Chip_DMA_GetIntStatus(LPC_DMA) & DMA_INTSTAT_ACTIVEERRINT) != 0) {
Chip_DMA_DisableChannel(LPC_DMA, DMA_CH21);
while ((Chip_DMA_GetBusyChannels(LPC_DMA) & (1 << DMA_CH21)) != 0) {}
Chip_DMA_AbortChannel(LPC_DMA, DMA_CH21);
Chip_DMA_ClearErrorIntChannel(LPC_DMA, DMA_CH21);
Chip_DMA_EnableChannel(LPC_DMA, DMA_CH21);
}
Chip_DMA_ClearActiveIntAChannel(LPC_DMA, DMA_CH21);
dmaDone = true;
}
int main(void)
{
int loop = 1; /* Prevents the unreachable statement warning */
DMA_CHDESC_T sct_pwm_dma_descriptor;
/* Generic Initialization */
SystemCoreClockUpdate();
Board_Init();
STC0_Init();
/* Setup Board specific output pin */
app_setup_pin();
/* Use SCT0_OUT1 pin */
//LED_W_OUT;
Chip_SCTPWM_SetOutPin(SCT_PWM, SCT_PWM_OUT, SCT_PWM_PIN_OUT);
Chip_SCTPWM_Start(SCT_PWM);
Chip_DMA_Init(LPC_DMA);
Chip_DMA_Enable(LPC_DMA);
Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));
// Configura el canal de DMA
Chip_DMA_EnableChannel(LPC_DMA, DMA_CH21);
Chip_DMA_EnableIntChannel(LPC_DMA, DMA_CH21);
Chip_DMA_SetupChannelConfig(LPC_DMA, DMA_CH21,
(DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGTYPE_EDGE | DMA_CFG_TRIGPOL_HIGH |
DMA_CFG_BURSTPOWER_16 | DMA_CFG_CHPRIORITY(0)));
sct_pwm_dma_descriptor.source = DMA_ADDR(&sine_table[SIZE_SINE_TABLE]);
sct_pwm_dma_descriptor.dest = DMA_ADDR(&(LPC_SCT->MATCHREL[1].L));
sct_pwm_dma_descriptor.next = DMA_ADDR(&sine_table[SIZE_SINE_TABLE]);
NVIC_EnableIRQ(DMA_IRQn);
while (loop) {
__WFI();
// Configura el descriptor de transferencia y válida el canal
Chip_DMA_SetupTranChannel(LPC_DMA, DMA_CH21, &sct_pwm_dma_descriptor);
Chip_DMA_SetValidChannel(LPC_DMA, DMA_CH21);
// Configura la transferencia de datos y dispara el DMA
Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH21,
(DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA | DMA_XFERCFG_SWTRIG | DMA_XFERCFG_RELOAD|
DMA_XFERCFG_WIDTH_16 | DMA_XFERCFG_SRCINC_1 | DMA_XFERCFG_DSTINC_0 |
DMA_XFERCFG_XFERCOUNT(SIZE_SINE_TABLE)));
while (dmaDone == false) {}; // Espera a que se complete la transferencia DMA
}
return 0;
}
I see on debug mode that on register DAMREQ0 and bit DRQ0 is set, the description says if I can see this bit set there's probably some issue with the configuration on the DMA side.
would you be able to help me catch the mistake on the configuration of the DMA side ???
I am complete newbie with DMA.
thanks.