This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

cc2650 use udma controller sample data by ssi bus

1.//ssi config is right because CPU can read and write ssi bus through the 'board_spi_write'and 'board_spi_read'

void
board_spi_open(uint32_t bit_rate, uint32_t clk_pin)

udma-sample.c
/*---------------------------------------------------------------------------*/

#include "ti-lib.h"
#include "udma-sample.h"
#include "board.h"

#include <stdbool.h>
/*---------------------------------------------------------------------------*/
#define delay_ms(i)      (ti_lib_cpu_delay(1172 * (i)))




//Note:The channel of software (channel 0 ) is success 
#if 0
#define TRAN_DATA_LEN	11

static int8_t MySourceBuf[20]={20,100,120,-40,59,60,70,80,90,10,1};
static int8_t MyDestBuf[20];


static unsigned long ucDMAControlTable[1024];


//使能时钟	
static void dmaui_clock_enable()
{
	PRCMLoadSet();
	PRCMPeripheralRunEnable(PRCM_PERIPH_UDMA);
	PRCMLoadSet();
}
//udma done init
void udma_int_isr(void)
{

	uint32_t mask=uDMAIntStatus(UDMA0_BASE); 

	printf("udma done isr : %d\r\n",mask);

	uDMAIntClear(UDMA0_BASE,mask);
}
void udma_int_err_isr(void)
{
	uint32_t mask=uDMAIntStatus(UDMA0_BASE); 

	printf("udma err isr : %d\r\n",mask);

	uDMAIntClear(UDMA0_BASE,mask);
}

void udma_int_init(void)
{
	ti_lib_int_master_disable();
	
	uDMAIntRegister(UDMA0_BASE, INT_DMA_DONE_COMB, udma_int_isr);
	uDMAIntRegister(UDMA0_BASE, INT_DMA_ERR, udma_int_err_isr);
	
	uDMAIntSwEventEnable(UDMA0_BASE,UDMA_CHAN_SW_EVT0);

	ti_lib_int_master_enable();
}
//初始化

//ssi init
void ssi_int_done_isr(void)
{
	uint32_t mark = SSIIntStatus(SSI0_BASE, 1);
	printf("ssi done isr : %d \r\n",mark);
	SSIIntClear(SSI0_BASE, mark);
}

void ssi_int_init(void)
{
	SSIIntRegister(SSI0_BASE,ssi_int_done_isr);

	SSIIntEnable(SSI0_BASE,SSI_RXTO|SSI_RXOR);
}
void dma_dup_init()
{
	ssi_int_init();
	//enable clock 
	dmaui_clock_enable();
	//! This function enables the uDMA controller. The uDMA controller must be
	//! enabled before it can be configured and used.

	//uDMAControlBaseSet(UDMA0_BASE, MyTaskList);
	uDMAControlBaseSet(UDMA0_BASE, &ucDMAControlTable[0]);

	uDMAEnable(UDMA0_BASE);
	
	uDMAChannelAttributeDisable(UDMA0_BASE, 
								UDMA_CHAN_SW_EVT0,
								UDMA_ATTR_USEBURST|
								UDMA_ATTR_ALTSELECT|UDMA_ATTR_HIGH_PRIORITY|
								UDMA_ATTR_REQMASK);
	
	uDMAChannelAttributeEnable(UDMA0_BASE,
								UDMA_CHAN_SW_EVT0,
								//UDMA_ATTR_USEBURST|
								UDMA_ATTR_HIGH_PRIORITY);

	//uDMAChannelControlSet(UDMA0_BASE,UDMA_PRI_SELECT,UDMA_SIZE_8);
	uDMAChannelControlSet(UDMA0_BASE,
						 UDMA_PRI_SELECT,
						 UDMA_SIZE_8|
						 UDMA_SRC_INC_8|
						 UDMA_DST_INC_8|
						 UDMA_ARB_4);
	
	uDMAChannelTransferSet(UDMA0_BASE,
							UDMA_PRI_SELECT ,
							UDMA_MODE_AUTO, 
							(void *)MySourceBuf,
							(void *)MyDestBuf,
							TRAN_DATA_LEN);
	
	uDMAChannelPrioritySet(UDMA0_BASE, UDMA_CHAN_SW_EVT0);

	//添加通道使能
	//uDMAChannelEnable(UDMA0_BASE,UDMA_CHAN_SW_EVT0);
	//使能中断
	//uDMAIntSwEventEnable(UDMA0_BASE,UDMA_CHAN_SW_EVT0);	
	ti_lib_int_master_disable();
	
	uDMAIntRegister(UDMA0_BASE, INT_DMA_DONE_COMB, udma_int_isr);
	uDMAIntRegister(UDMA0_BASE, INT_DMA_ERR, udma_int_err_isr);
	
	uDMAIntSwEventEnable(UDMA0_BASE,UDMA_CHAN_SW_EVT0);

	ti_lib_int_master_enable();
	
	//查看通道有没有被使能
	//uDMAChannelIsEnabled(uint32_t ui32Base, uint32_t ui32ChannelNum)(uint32_t ui32Base, uint32_t ui32ChannelNum)
}


void dma_dup_send_cmd()
{
	static uint32_t err_value;

	//check channel 

	uDMAChannelTransferSet(UDMA0_BASE,
							UDMA_PRI_SELECT ,
							UDMA_MODE_AUTO, 
							(void *)MySourceBuf,
							(void *)MyDestBuf,
							TRAN_DATA_LEN);
	
	if((err_value = uDMAErrorStatusGet(UDMA0_BASE)))
	{		
		printf("error code %d \r\n",err_value);		
		uDMAErrorStatusClear(UDMA0_BASE);
	}
	
	uDMAChannelEnable(UDMA0_BASE, UDMA_CHAN_SW_EVT0);
	//enable ,to start 

	printf("channel :%s \r\n ",uDMAChannelIsEnabled(UDMA0_BASE, UDMA_CHAN_SW_EVT0)?"TRUE":"FALSE");

	uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_SW_EVT0);

	delay_ms(1000*10);

	int i =0;
	for(i =0;i<20;i++)
	{
		printf("%d ",MyDestBuf[i]);				
	}
	printf("\r\n");	

	for(i =0;i<10;i++)
	{
		MyDestBuf[i]=0;
	}
	
}
#else

//the use of ssi has a problem??????

#define TRAN_DATA_LEN	2

static uint8_t MySourceBuf[10]={0x28,0x29,0x2A,0x2B,0x2C,0x2D};
static uint8_t MyDestBuf[10];


static unsigned long ucDMAControlTable[1024];


//使能时钟	
static void dmaui_clock_enable()
{
	PRCMLoadSet();
	PRCMPeripheralRunEnable(PRCM_PERIPH_UDMA);
    PRCMLoadSet();
}



//udma done isr
void udma_int_isr(void)
{

	uint32_t mask=uDMAIntStatus(UDMA0_BASE); 

	printf("udma done isr : %d\r\n",mask);

	uDMAIntClear(UDMA0_BASE,mask);
}
void udma_int_err_isr(void)
{
	uint32_t mask=uDMAIntStatus(UDMA0_BASE); 

	printf("udma err isr : %d\r\n",mask);

	uDMAIntClear(UDMA0_BASE,mask);
}

//udma done init
void udma_int_init(void)
{
	//ti_lib_int_master_disable();
	
	uDMAIntRegister(UDMA0_BASE, INT_DMA_DONE_COMB, udma_int_isr);
	uDMAIntRegister(UDMA0_BASE, INT_DMA_ERR, udma_int_err_isr);
	
	//uDMAIntSwEventEnable(UDMA0_BASE,UDMA_CHAN_SSI0_RX);

	//ti_lib_int_master_enable();
}


//ssi init
void ssi_int_done_isr(void)
{
	uint32_t mark = SSIIntStatus(SSI0_BASE, 1);
	printf("ssi done isr : %d \r\n",mark);
	SSIIntClear(SSI0_BASE, mark);
}

void ssi_int_init(void)
{
	ti_lib_int_master_disable();
	SSIIntEnable(SSI0_BASE,SSI_RXOR|SSI_RXTO);
	SSIIntRegister(SSI0_BASE,ssi_int_done_isr);
/*
//! - \ref SSI_TXFF
//! - \ref SSI_RXFF
//! - \ref SSI_RXTO
//! - \ref SSI_RXOR
	*/
	ti_lib_int_master_enable();
	printf("ssi init mark : %d \r\n",SSIIntStatus(SSI0_BASE, 1));
}


//ssi cpu 控制
static bool
accessible(void)
{
  /* First, check the PD */
  if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
     != PRCM_DOMAIN_POWER_ON) {
    return false;
  }

  /* Then check the 'run mode' clock gate */
  if(!(HWREG(PRCM_BASE + PRCM_O_SSICLKGR) & PRCM_SSICLKGR_CLK_EN_SSI0)) {
    return false;
  }

  return true;
}

static bool
spiread_value(uint8_t *buf, size_t len)
{
  if(accessible() == false) {
    return false;
  }

  while(len > 0) {
    uint32_t ul;

    if(!ti_lib_rom_ssi_data_put_non_blocking(SSI0_BASE, 0)) {
      /* Error */
		printf("false 2\r\n");
	  return false;
    }
    ti_lib_rom_ssi_data_get(SSI0_BASE, &ul);
    *buf = (uint8_t)ul;
    len--;
    buf++;
  }
  printf("ok \r\n");
  return true;
}

static bool
board_spi_write(const uint8_t *buf, size_t len)
{
  if(accessible() == false) {
    return false;
  }

  while(len > 0) {
    uint32_t ul;

    ti_lib_ssi_data_put(SSI0_BASE, *buf);
    ti_lib_rom_ssi_data_get(SSI0_BASE, &ul);
    len--;
    buf++;
  }

  return true;
}

static void
select_on_bus(void)
{
  ti_lib_gpio_pin_write(BOARD_LIS3DH_CS, 0);
}

static void
deselect(void)
{
   ti_lib_gpio_pin_write(BOARD_LIS3DH_CS, 1);
}

void ssi_test_one()
{
	
#if 1
  uint8_t wbuf[1];

  wbuf[0] = (0x28|0x80)&0xbf;
  
  select_on_bus();	
  if(0 == board_spi_write(wbuf,sizeof(wbuf)))
  {
	deselect();
	return 0;
  }
  uint8_t Data;
 spiread_value(&Data,1); 
  deselect();
	printf("Data : %d \r\n",Data);
#endif 
}
//init 
void dma_dup_init()
{
#if 1 
	//enable dma clock 
	dmaui_clock_enable();
	
	//UDMA_O_CFG
	uDMAEnable(UDMA0_BASE);


	//配置参数之前先关闭通道
	uDMAChannelDisable(UDMA0_BASE,UDMA_CHAN_SSI0_RX);
	uDMAChannelDisable(UDMA0_BASE,UDMA_CHAN_SSI0_TX);
	
	//tx config
	//uDMAControlBaseSet(UDMA0_BASE, MyTaskList);
	//UDMA_O_CTRL
	uDMAControlBaseSet(UDMA0_BASE, (void*)0x20000400);

	uDMAChannelAttributeDisable(UDMA0_BASE, 
								UDMA_CHAN_SSI0_TX,
								UDMA_ATTR_USEBURST|
								UDMA_ATTR_ALTSELECT|
								UDMA_ATTR_REQMASK);
	
	uDMAChannelAttributeEnable(UDMA0_BASE,
								UDMA_CHAN_SSI0_TX,
								//UDMA_ATTR_USEBURST|
								UDMA_ATTR_HIGH_PRIORITY);

	//uDMAChannelControlSet(UDMA0_BASE,UDMA_PRI_SELECT,UDMA_SIZE_8);
	//UDMA_O_CTRL
	uDMAChannelControlSet(UDMA0_BASE,
						 UDMA_PRI_SELECT,
						 UDMA_SIZE_8|
						 UDMA_SRC_INC_8|
						 UDMA_DST_INC_NONE|
						 UDMA_ARB_8);
	
	uDMAChannelTransferSet(UDMA0_BASE,
							UDMA_PRI_SELECT,
							UDMA_MODE_BASIC, 
							(void *)MySourceBuf,
							(void *)(SSI0_BASE + SSI_O_DR),
							TRAN_DATA_LEN);
	
	uDMAChannelPrioritySet(UDMA0_BASE, UDMA_CHAN_SSI0_TX);
	
	//添加TX通道使能
	uDMAChannelEnable(UDMA0_BASE,UDMA_CHAN_SSI0_TX);
#endif 
	
	#if 1
	//rx config 
	
	uDMAChannelAttributeDisable(UDMA0_BASE, 
								UDMA_CHAN_SSI0_RX,
								UDMA_ATTR_USEBURST|
								UDMA_ATTR_ALTSELECT|
								UDMA_ATTR_REQMASK);
	
	uDMAChannelAttributeEnable(UDMA0_BASE,
								UDMA_CHAN_SSI0_RX,
								UDMA_ATTR_HIGH_PRIORITY);

	//uDMAChannelControlSet(UDMA0_BASE,UDMA_PRI_SELECT,UDMA_SIZE_8);
	uDMAChannelControlSet(UDMA0_BASE,
						 UDMA_PRI_SELECT,
						 UDMA_SIZE_8|
						 UDMA_SRC_INC_NONE|
						 UDMA_DST_INC_8|
						 UDMA_ARB_4);
	
	uDMAChannelTransferSet(UDMA0_BASE,
							UDMA_PRI_SELECT ,
							UDMA_MODE_BASIC, 
							(void *)(SSI0_BASE + SSI_O_DR),
							(void *)MyDestBuf,
							TRAN_DATA_LEN);
	
	uDMAChannelPrioritySet(UDMA0_BASE, UDMA_CHAN_SSI0_RX);
	
	//添加RX通道使能
	uDMAChannelEnable(UDMA0_BASE,UDMA_CHAN_SSI0_RX);

	#endif 

	//ssi init 
	//ssi_int_init();

	//dma int init 
	//udma_int_init();
	
	//ssi dma enable 
	SSIDMAEnable(SSI0_BASE,SSI_DMA_TX|SSI_DMA_RX);

	//IntEable(INT_UDMA);
	
	//HWREG(SSI0_BASE + SSI_O_CR1) |= SSI_CR1_LBM;

}


void dma_dup_send_cmd()
{
	uint32_t err_value;
#if 1
	if((err_value = uDMAErrorStatusGet(UDMA0_BASE)))
	{		
		printf("error code %d \r\n",err_value);		
		uDMAErrorStatusClear(UDMA0_BASE);
	}
	else
	{
		printf("state success  \r\n");
	}

	
	//enable cs 
	select_on_bus();

	#if 1
	//tx 	
		
	uDMAChannelTransferSet(UDMA0_BASE,
							UDMA_PRI_SELECT ,
							UDMA_MODE_BASIC, 
							(void *)MySourceBuf,
							(void *)(SSI0_BASE+SSI_O_DR),
							TRAN_DATA_LEN);

	//UDMA_O_SETCHANNELEN
	uDMAChannelEnable(UDMA0_BASE, UDMA_CHAN_SSI0_TX);
									
	//check channel 
	printf("channel tx :%s \r\n",uDMAChannelIsEnabled(UDMA0_BASE, UDMA_CHAN_SSI0_TX)?"TRUE":"FALSE");
#if 1 

	//SSIDMAEnable(UDMA0_BASE,SSI_DMA_TX|SSI_DMA_RX);
	SSIDMAEnable(SSI0_BASE,SSI_DMA_TX|SSI_DMA_RX);
	//ssi init 
	
	
	//UDMA_O_SOFTREQ					
	//uDMAChannelRequest(SSI0_BASE, UDMA_CHAN_SSI0_TX);
	#endif 
#endif 
	
	
	#if 1
	delay_ms(1000*10);
	
	uDMAChannelTransferSet(UDMA0_BASE,
							UDMA_PRI_SELECT ,
							UDMA_MODE_BASIC, 
							(void *)(SSI0_BASE + SSI_O_DR),
							(void *)MyDestBuf,
							TRAN_DATA_LEN);

	//rx 
	uDMAChannelEnable(UDMA0_BASE, UDMA_CHAN_SSI0_RX);
		
	//check channel 
	printf("channel rx :%s \r\n ",uDMAChannelIsEnabled(UDMA0_BASE, UDMA_CHAN_SSI0_RX)?"TRUE":"FALSE");

	SSIDMAEnable(SSI0_BASE,SSI_DMA_TX|SSI_DMA_RX);

	//uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_SSI0_RX);
	#endif 
	
#endif 
	
	int i =0;
	for(i =0;i<10;i++)
	{
		//printf("%d ",MyDestBuf[i]);
		//MyDestBuf[i]=0;
	}
	
	delay_ms(1000);
	deselect();

	for(i =0;i<10;i++)
	{
		//MyDestBuf[i]=0;
		printf("%d ",MyDestBuf[i]);	
	}
	printf("\r\n");

}


#endif 


{
  uint32_t buf;

  /* First, make sure the SERIAL PD is on */
  ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL);
  while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
        != PRCM_DOMAIN_POWER_ON));

  /* Enable clock in active mode */
  ti_lib_rom_prcm_peripheral_run_enable(PRCM_PERIPH_SSI0);
  ti_lib_prcm_load_set();
  while(!ti_lib_prcm_load_get());

  /* SPI configuration */
  ti_lib_ssi_int_disable(SSI0_BASE, SSI_RXOR | SSI_RXFF | SSI_RXTO | SSI_TXFF);
  ti_lib_ssi_int_clear(SSI0_BASE, SSI_RXOR | SSI_RXTO);
  ti_lib_rom_ssi_config_set_exp_clk(SSI0_BASE, ti_lib_sys_ctrl_clock_get(),
                                    SSI_FRF_MOTO_MODE_3,
                                    SSI_MODE_MASTER, bit_rate, 8);
  ti_lib_rom_ioc_pin_type_ssi_master(SSI0_BASE, BOARD_IOID_SPI_MISO,
                                     BOARD_IOID_SPI_MOSI, IOID_UNUSED, clk_pin);
  ti_lib_ssi_enable(SSI0_BASE);

  /* Get rid of residual data from SSI port */
  while(ti_lib_ssi_data_get_non_blocking(SSI0_BASE, &buf));
}

2.udma config file in the attachment.

The files used in the configuration process are udma.c udma.h ssi.c ssi.h

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

The file 'udma-sample ' config channel 0 and ssi0 tx-rx , the software channel is success,but the ssi has a question .

ssi interrupt  and dma interrupt are no configed successfully.

Help me .Thank you !