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)
/*---------------------------------------------------------------------------*/ #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 !