diff --git a/packages/vsky/libdsp/driver/ckdef.h b/packages/vsky/libdsp/driver/ckdef.h new file mode 100644 index 0000000..7471304 --- /dev/null +++ b/packages/vsky/libdsp/driver/ckdef.h @@ -0,0 +1,45 @@ +/* + * ckdef.h + * + * Created on: 2018-9-26 + * Author: Administrator + */ + +#ifndef CKDEF_H_ +#define CKDEF_H_ + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#define SEMAPHORE_FOR_I2C 31 +#define SEMAPHORE_FOR_SPI 30 + +#define DSP_CORE_FREQ_FAULT 1000000000 +#endif /* CKDEF_H_ */ diff --git a/packages/vsky/libdsp/driver/emif.c b/packages/vsky/libdsp/driver/emif.c new file mode 100644 index 0000000..b61d9c8 --- /dev/null +++ b/packages/vsky/libdsp/driver/emif.c @@ -0,0 +1,143 @@ +/* + * emif.c + * + * Created on: 2018-9-30 + * Author: Administrator + */ +#include "ckdef.h" +#include "emif.h" + +void emif16_param_init_default(emif16_cfg_s *pEmif16Cfg) +{ + int i; + emif16_ce_cfg_s *ce_cfg = NULL; + if (pEmif16Cfg) { + pEmif16Cfg->wait0Polarity= EMIF_LOW_WAIT; + pEmif16Cfg->wait1Polarity= EMIF_LOW_WAIT; + pEmif16Cfg->maxWait = CSL_EMIF16_AWCCR_MAXEXTWAIT_RESETVAL; + + for (i = 0; i < 4; ++i) { + ce_cfg = pEmif16Cfg->ceCfg[i]; + if (ce_cfg) { + ce_cfg->busWidth= EMIF_BUS_16BIT; + ce_cfg->opMode = NOR_ASRAM_MODE; + ce_cfg->strobeMode = SS_STROBE; + ce_cfg->waitMode = EMIF_WAIT_NONE; + ce_cfg->wrSetup = CSL_EMIF16_A0CR_WSETUP_RESETVAL; + ce_cfg->wrStrobe = CSL_EMIF16_A0CR_WSTROBE_RESETVAL; + ce_cfg->wrHold= CSL_EMIF16_A0CR_WHOLD_RESETVAL; + ce_cfg->rdSetup= CSL_EMIF16_A0CR_RSETUP_RESETVAL; + ce_cfg->rdStrobe= CSL_EMIF16_A0CR_RSTROBE_RESETVAL; + ce_cfg->rdHold= CSL_EMIF16_A0CR_RHOLD_RESETVAL; + ce_cfg->turnAroundCycles= CSL_EMIF16_A0CR_TA_RESETVAL; + ce_cfg->nor_pg_Cfg= NULL; + } + } + } +} + +void emif16_init(emif16_cfg_s *pEmif16Cfg) +{ + int i; + Uint32 regVal; + volatile Uint32 *ACR= &EMIF16_Regs->A0CR; + volatile Uint32 PMCR= 0; + volatile Uint32 AWCCR= 0; + volatile Uint32 NANDFCR= 0; + emif16_ce_cfg_s * ceCfg; + + for(i=0; i<4; i++) /*4 CEs*/ + { + if(NULL == pEmif16Cfg->ceCfg[i]) + continue; + + ceCfg= pEmif16Cfg->ceCfg[i]; + + /*timing parameter check*/ + if((ceCfg->wrSetup<wrStrobe<wrHold<rdSetup<rdStrobe<rdHold<turnAroundCycles<strobeMode<wrSetup<wrStrobe<wrHold<rdSetup<rdStrobe<rdHold<turnAroundCycles<busWidth<waitMode) + { + regVal |= ((1<waitMode<nor_pg_Cfg) + { + regVal = ((ceCfg->nor_pg_Cfg->pageDelay<nor_pg_Cfg->pageSize<opMode) + NANDFCR |= (((1<maxWait<wait0Polarity<wait1Polarity<AWCCR= AWCCR; + + EMIF16_Regs->PMCR = PMCR; + EMIF16_Regs->NANDFCTL= NANDFCR; + + /*Although it supports only asynchronous mode operation on all KeyStone©\I + devices, the EMIF16 module has a legacy ¡®synchronous mode¡¯ feature that + is enabled by default.*/ + *(Uint32*) 0x20C00008 |= 0x80000000; //Disable synchronous mode feature + +} + +unsigned int emif16_get_addr_bass(uint8_t ce) +{ + return (unsigned int)(0x70000000 + (0x4000000 * ce)); +} diff --git a/packages/vsky/libdsp/driver/emif.h b/packages/vsky/libdsp/driver/emif.h new file mode 100644 index 0000000..7db7580 --- /dev/null +++ b/packages/vsky/libdsp/driver/emif.h @@ -0,0 +1,89 @@ +/* + * emif.h + * + * Created on: 2018-9-30 + * Author: Administrator + */ + +#ifndef EMIF_H_ +#define EMIF_H_ + +typedef enum { + NOR_ASRAM_MODE = 0, + NAND_MODE = 1 +}EMIF16_OP_MODE; + +typedef enum { + WE_STROBE = 0, + SS_STROBE = 1 +}EMIF16_STROBE_MODE; + +typedef enum { + EMIF_WAIT_NONE = -1, + EMIF_WAIT0 = 0, + EMIF_WAIT1 = 1 +}EMIF16_WAIT_MODE; + +typedef enum { + EMIF_LOW_WAIT = 0, + EMIF_HIGH_WAIT = 1 +}EMIF16_WAIT_POLARITY; + +typedef enum { + EMIF_BUS_8BIT = 0, + EMIF_BUS_16BIT = 1 +}EMIF16_BUS_WIDTH; + +typedef enum { + EMIF16_4_WORDS_NOR_PAGE = 0, + EMIF16_8_WORDS_NOR_PAGE = 1 +}EMIF16_NOR_PAGE_MODE_SIZE; + +typedef struct{ + EMIF16_NOR_PAGE_MODE_SIZE pageSize; + Uint8 pageDelay; +}EMIF16_NOR_PG_CFG; + +typedef struct { + + /* Asynchronous Memory Bus Width */ + EMIF16_BUS_WIDTH busWidth; //note: if use emif16_param_init_default and after uesr should select one mode + /* Nor/ASRAM or Nand */ + EMIF16_OP_MODE opMode; //note: if use emif16_param_init_default and after uesr should select one mode + /* WE strobe or SS */ + EMIF16_STROBE_MODE strobeMode; + /* extend wait mode */ + EMIF16_WAIT_MODE waitMode; + /* write timing parameter */ + uint8_t wrSetup; /*unsigned 4 bit, expected value -1*/ + uint8_t wrStrobe; /*unsigned 6 bit, expected value -1*/ + uint8_t wrHold; /*unsigned 3 bit, expected value -1*/ + /* Read timing parameter */ + uint8_t rdSetup; /*unsigned 4 bit, expected value -1*/ + uint8_t rdStrobe; /*unsigned 6 bit, expected value -1*/ + uint8_t rdHold; /*unsigned 3 bit, expected value -1*/ + /*Turn Around cycles*/ + uint8_t turnAroundCycles; /*unsigned 2 bit, expected value -1*/ + /* NOR flash page mode configuration */ + EMIF16_NOR_PG_CFG * nor_pg_Cfg; + +} emif16_ce_cfg_s; + +typedef struct { + + /*polarity of wait pins*/ + EMIF16_WAIT_POLARITY wait0Polarity; + EMIF16_WAIT_POLARITY wait1Polarity; + /*Maximum extended wait cycles. + EMIF16 will actually wait for (MAX_EXT_WAIT + 1) x 16 cycles*/ + Uint8 maxWait; + emif16_ce_cfg_s * ceCfg[4]; + +} emif16_cfg_s; + +extern CSL_Emif16Regs * EMIF16_Regs; + +void emif16_param_init_default(emif16_cfg_s *pEmif16Cfg); +void emif16_init(emif16_cfg_s *pEmif16Cfg); +unsigned int emif16_get_addr_bass(uint8_t ce/*0,1,2,3*/); +#endif /* EMIF_H_ */ diff --git a/packages/vsky/libdsp/driver/gpio.c b/packages/vsky/libdsp/driver/gpio.c index 5240780..01e46e1 100644 --- a/packages/vsky/libdsp/driver/gpio.c +++ b/packages/vsky/libdsp/driver/gpio.c @@ -1,62 +1,104 @@ #include #include #include -#include +#include +#include #include "gpio.h" #define GPIO_BANK (0) -#define hGPIORegs ((volatile CSL_GpioRegs *)CSL_GPIO_REGS) -#define hGPIOBankRegs ((volatile CSL_GpioBank_registersRegs *)&hGPIORegs->BANK_REGISTERS[GPIO_BANK]) + +int gpio_init(int gpio, int dir/*0-out, 1-in*/) +{ + CSL_GpioHandle hGpio; + + hGpio = CSL_GPIO_open (GPIO_BANK); + switch (dir) { + case GPIOF_OUT: + CSL_GPIO_setPinDirOutput(hGpio, gpio); // Set to OUTPUT + break; + case GPIOF_IN: + CSL_GPIO_setPinDirInput (hGpio, gpio); // Set to INPUT + break; + default: + return -1; + } + return 0; +} void gpio_direction_input(int gpio) { - hGPIOBankRegs->DIR |= (1 << gpio); + CSL_GpioHandle hGpio; + + hGpio = CSL_GPIO_open (GPIO_BANK); + CSL_GPIO_setPinDirInput (hGpio, gpio); // Set to INPUT } void gpio_direction_output(int gpio) { - uint32_t value = hGPIOBankRegs->DIR; - value &= ~(1 << gpio); - hGPIOBankRegs->DIR = value; + CSL_GpioHandle hGpio; + + hGpio = CSL_GPIO_open (GPIO_BANK); + CSL_GPIO_setPinDirOutput(hGpio, gpio); // Set to OUTPUT } void gpio_set_value(int gpio, int value) { - if (value) { - hGPIOBankRegs->SET_DATA = (1 << gpio); - } else { - hGPIOBankRegs->CLR_DATA = (1 << gpio); - } + CSL_GpioHandle hGpio; + + // Open the CSL GPIO Module 0 + hGpio = CSL_GPIO_open (GPIO_BANK); + + if (value) + CSL_GPIO_setOutputData(hGpio, gpio); + else + CSL_GPIO_clearOutputData(hGpio, gpio); + } int gpio_get_value(int gpio) { - if ((hGPIOBankRegs->IN_DATA) & (1 << gpio)) { - return 1; - } - return 0; + CSL_GpioHandle hGpio; + Uint8 data; + + // Open the CSL GPIO Module 0 + hGpio = CSL_GPIO_open (GPIO_BANK); + CSL_GPIO_getInputData(hGpio, gpio, &data); + + return data; } void gpio_bank_interrupt(int bank, int en) { - hGPIORegs->BINTEN = ((1 << bank) & en); + CSL_GpioHandle hGpio; + hGpio = CSL_GPIO_open (GPIO_BANK); + if (en) { + CSL_GPIO_bankInterruptEnable(hGpio, bank); + } else { + CSL_GPIO_bankInterruptDisable(hGpio, bank); + } } void gpio_set_rising_edge_interrupt(int gpio, int set) { + CSL_GpioHandle hGpio; + hGpio = CSL_GPIO_open (GPIO_BANK); + if (set) { - hGPIOBankRegs->SET_RIS_TRIG = (1 << gpio); + CSL_GPIO_setRisingEdgeDetect(hGpio, gpio); } else { - hGPIOBankRegs->CLR_RIS_TRIG = (1 << gpio); + CSL_GPIO_clearRisingEdgeDetect(hGpio, gpio); } } void gpio_set_falling_edge_interrupt(int gpio, int set) { + CSL_GpioHandle hGpio; + hGpio = CSL_GPIO_open (GPIO_BANK); + if (set) { - hGPIOBankRegs->SET_FAL_TRIG = (1 << gpio); + CSL_GPIO_setFallingEdgeDetect(hGpio, gpio); } else { - hGPIOBankRegs->CLR_FAL_TRIG = (1 << gpio); + CSL_GPIO_clearFallingEdgeDetect(hGpio, gpio); } } diff --git a/packages/vsky/libdsp/driver/i2c.c b/packages/vsky/libdsp/driver/i2c.c new file mode 100644 index 0000000..c709b19 --- /dev/null +++ b/packages/vsky/libdsp/driver/i2c.c @@ -0,0 +1,515 @@ +/* + * i2c.c + * + * Created on: 2018-9-27 + * Author: Administrator + */ + +#include "ckdef.h" +#include "tsc.h" +#include "i2c.h" + +CSL_I2cRegs * gpI2C_regs = (CSL_I2cRegs *)CSL_I2C_DATA_CONTROL_REGS; + +/*I2C output clock <= 400 KHz*/ +Uint32 I2C_speed_KHz= 400; + +/*Initialize I2C as master*/ +void i2c_master_init(Uint32 i2c_speed_KHz) +{ + Uint32 module_speed_Hz, clk_div, actualSpeed_KHz; + if(i2c_speed_KHz>400) + { + puts("ERROR: I2C speed can not be higher than 400KHz!"); + return; + } + + /*Place I2C in reset (clear IRS = 0 in ICMDR). + The prescaler must be initialized only while the I2C module is in the reset state*/ + gpI2C_regs->ICMDR= 0; + + I2C_speed_KHz= i2c_speed_KHz; + + /*I2C internal input clock is (DSP core clock)/6, + it should be Prescale to 7~12MHz for I2C internal working clock*/ + gpI2C_regs->ICPSC= g_dsp_corefreq/6/(1000*I2C_MODULE_FREQ_KHZ)+1; + + module_speed_Hz= g_dsp_corefreq/6/gpI2C_regs->ICPSC; + clk_div= module_speed_Hz/(i2c_speed_KHz*1000)+1; + actualSpeed_KHz= module_speed_Hz/clk_div/1000; + if(actualSpeed_KHz!=i2c_speed_KHz) + printf("I2C expected speed = %dKHz, effective speed = %dKHz\n", + i2c_speed_KHz, actualSpeed_KHz); + + /*I2C output clock <= 400 KHz*/ + gpI2C_regs->ICCLKL= clk_div/2-6; + gpI2C_regs->ICCLKH= (clk_div-clk_div/2)-6; + + /*Master mode. The I2C is a master and generates the serial clock on the SCL pin.*/ + gpI2C_regs->ICMDR= gpI2C_regs->ICMDR| + (1<ICMDR= gpI2C_regs->ICMDR| + (1<ICSTR&flag_mask; + + /*Wait until I2C flag= expect value*/ + while(flag!= expect) + { + /*if wait time is much larger than theoretical transfer time of + a byte, then it is looked as timeout.*/ + delay= tsc_get_delay(startTSC); + if(delay> 100*theoryCycleForOneByte) + { + /*reset and reinitialize I2C when timeout happens*/ + gpI2C_regs->ICMDR= 0; + i2c_master_init(I2C_speed_KHz); + return 0; + } + flag= gpI2C_regs->ICSTR&flag_mask; + + }; + + return 1; +} + +/*read one byte "data" from I2C*/ +Uint32 I2C_read_one_byte(Uint8 * dataPointer) +{ + /*Wait until data is received (ICRRDY = 1 in ICSTR).*/ + if(0==I2C_wait_flag(CSL_I2C_ICSTR_ICRRDY_MASK, CSL_I2C_ICSTR_ICRRDY_MASK)) + { + /*after complete an I2C operation, free I2C for other operations*/ + I2C_free(); + return 0; + } + + /*read data from ICDRR.*/ + *dataPointer=gpI2C_regs->ICDRR; + + return 1; +} + +/*write one byte "data" to I2C*/ +Uint32 I2C_write_one_byte( Uint8 data) +{ + /*Wait until transmit is ready (ICXRDY = 1 in ICSTR).*/ + if(0==I2C_wait_flag(CSL_I2C_ICSTR_ICXRDY_MASK, CSL_I2C_ICSTR_ICXRDY_MASK)) + { + /*I2C operation timeout, free I2C for other operations*/ + I2C_free(); + return 0; + } + + /*transmit data to ICDXR.*/ + gpI2C_regs->ICDXR= data; + + return 1; +} +/*read "uiByteCount" data from I2C device with "slaveAddress", +data save in buffer pointed by "ucBuffer". +if "wait", polling until data trasfer complete, otherwise, let interrupt +handle the data. +return number of bytes received.*/ +Uint32 i2c_master_read( Uint32 slaveAddress, Uint32 uiByteCount, + Uint8 * ucBuffer, I2C_Wait wait) +{ + int i; + + /*I2C read/write operations can not re-enter, so before any I2C operation, + this function should be called to block other I2C operations*/ + I2C_block(); + + /*Place I2C in reset (clear IRS = 0 in ICMDR)*/ + gpI2C_regs->ICMDR= 0; + + /*Configure I2C as Master (MST = 1) + Data Receiver (TRX = 0)*/ + gpI2C_regs->ICMDR= + (1<ICMDR= gpI2C_regs->ICMDR| + (1<ICCNT= uiByteCount; + gpI2C_regs->ICSAR= slaveAddress; + + /*Make sure the interrupt status register (ICSTR) is cleared*/ + /*Read ICSTR and write it back (write 1 to clear) ICSTR = ICSTR*/ + gpI2C_regs->ICSTR= gpI2C_regs->ICSTR; + /*Read ICIVR until it is zero*/ + while(gpI2C_regs->ICIVR); + + /*Wait until bus busy bit is cleared (BB = 0 in ICSTR).*/ + if(0==I2C_wait_flag(CSL_I2C_ICSTR_BB_MASK, 0)) + { + /*after complete an I2C operation, free I2C for other operations*/ + I2C_free(); + return 0; + } + /*Generate a START event(set STT = 1 in ICMDR).*/ + /*End transfer/release bus when transfer is done. + Generate a STOP event (set STP = 1 in ICMDR).*/ + gpI2C_regs->ICMDR= gpI2C_regs->ICMDR| + (1<ICMDR= 0; + + /*Configure I2C as Master (MST = 1) + Data Transmiter (TRX = 1)*/ + gpI2C_regs->ICMDR= + (1<ICMDR= gpI2C_regs->ICMDR| + (1<ICCNT= uiByteCount; + gpI2C_regs->ICSAR= slaveAddress; + + /*Make sure the interrupt status register (ICSTR) is cleared*/ + /*Read ICSTR and write it back (write 1 to clear) ICSTR = ICSTR*/ + gpI2C_regs->ICSTR= gpI2C_regs->ICSTR; + /*Read ICIVR until it is zero*/ + while(gpI2C_regs->ICIVR); + + + /*Wait until bus busy bit is cleared (BB = 0 in ICSTR).*/ + if(0==I2C_wait_flag(CSL_I2C_ICSTR_BB_MASK, 0)) { + /*after complete an I2C operation, free I2C for other operations*/ + I2C_free(); + return 0; + } + + /*write the first byte to ICDXR.*/ + gpI2C_regs->ICDXR= ucBuffer[0]; + + /*Generate a START event(set STT = 1 in ICMDR).*/ + /*End transfer/release bus when transfer is done. + Generate a STOP event (set STP = 1 in ICMDR).*/ + gpI2C_regs->ICMDR= gpI2C_regs->ICMDR| + (1<ICMDR &= (~CSL_I2C_ICMDR_IRS_MASK); + + /* Set Own Address */ + gpI2C_regs->ICOAR = slaveAddress; + + /* Slaver mode, receiver mode, 7-bit addressing mode, I2C module enable */ + gpI2C_regs->ICMDR |= CSL_I2C_ICMDR_IRS_MASK | CSL_I2C_ICMDR_STT_MASK; + + /*Make sure the interrupt status register (ICSTR) is cleared*/ + /*Read ICSTR and write it back (write 1 to clear) ICSTR = ICSTR*/ + gpI2C_regs->ICSTR = gpI2C_regs->ICSTR; + + /* Read ICIVR until it is zero. */ + while (0 != gpI2C_regs->ICIVR); + + /* Address-as-slave interrupt enable, Stop condition detected interrupt enable + * Receive-data-ready interrupt enable. */ + gpI2C_regs->ICIMR = CSL_I2C_ICIMR_AAS_MASK | CSL_I2C_ICIMR_SCD_MASK | + CSL_I2C_ICIMR_ICRRDY_MASK; + + memset(&g_i2c_slave, 0, sizeof g_i2c_slave); + g_i2c_slave.opStatus = I2C_IDLE; + + return 0; +} + +/*i2c master w to slave*/ +void i2c_slave_set_recv_cb(uint8_t *recvbuf, uint32_t buflen, void *param, int (*recv_cb)(void *param, uint32_t len)) +{ + g_i2c_slave.recv_buf = recvbuf; + g_i2c_slave.recv_buf_len = buflen; + g_i2c_slave.recv_pos = 0; + g_i2c_slave.recv_cb = recv_cb; + g_i2c_slave.recv_param = param; +} + +/*i2c master r from slave*/ +void i2c_slave_set_send_cb(void *param, int (*send_start_cb)(uint8_t **wait_send_data, uint32_t *len), int (*send_end_cb)(void *param, int retlen)) +{ + g_i2c_slave.send_data = NULL; + g_i2c_slave.send_data_len = 0; + g_i2c_slave.send_pos = 0; + g_i2c_slave.send_param = param; + g_i2c_slave.send_start_cb = send_start_cb; + g_i2c_slave.send_end_cb = send_end_cb; +} + +/*i2c slave intrrupt handle func */ +void i2c_slave_isr(void ) +{ + uint32_t intStatus = 0; + + uint32_t timeOutCnt = 0xfffe795f; + + intStatus = I2CR->ICIVR & CSL_I2C_ICIVR_INTCODE_MASK; + + /* The I2C interrupt events (Address-as-slave interrupt ) */ + if (ADDRESS_AS_SLAVE_INT == intStatus) { + if (I2C_IDLE == g_i2c_slave.opStatus || + I2C_D_REV == g_i2c_slave.opStatus || + I2C_D_TRA == g_i2c_slave.opStatus) { + + if (I2C_IDLE == g_i2c_slave.opStatus) + g_i2c_slave.opStatus = I2C_START; + else + g_i2c_slave.opStatus = I2C_R_START; + + /*slave direction bit + * 0 - slave receiver + * 1 - slave transmitter + * */ + if (0 == (I2CR->ICSTR & CSL_I2C_ICSTR_SDIR_MASK)) { + /* The I2C slaver receiver mode */ + I2CR->ICMDR &= (~CSL_I2C_ICMDR_TRX_MASK); + + /* Transmit-data-ready interrupt disable */ + I2CR->ICIMR &= (~CSL_I2C_ICIMR_ICXRDY_MASK); + + /* Restore recieve buffer setoff */ + g_i2c_slave.recv_pos = 0; + } else { + /* The I2C slaver transmitter mode */ + I2CR->ICMDR |= CSL_I2C_ICMDR_TRX_MASK; + + /* Transmit-data-ready interrupt enable */ + I2CR->ICIMR |= CSL_I2C_ICIMR_ICXRDY_MASK; + + /*get user need send data*/ + if (g_i2c_slave.send_start_cb) + g_i2c_slave.send_start_cb(&g_i2c_slave.send_data, &g_i2c_slave.send_data_len); + + /* Restore transmit buffer setoff */ + g_i2c_slave.send_pos = 0; + + /* Write first data to ICDXR */ + if (g_i2c_slave.send_data && g_i2c_slave.send_pos < g_i2c_slave.send_data_len) { + I2CR->ICDXR = g_i2c_slave.send_data[g_i2c_slave.send_pos]; + g_i2c_slave.send_pos++; + } + } + } + } + + /* The I2C interrupt events (receive-data-ready interrupt ) */ + if (REV_DATA_READY_INT == intStatus) + { + /* Set up the I2C operate status */ + if ((I2C_START == g_i2c_slave.opStatus) || + (I2C_R_START == g_i2c_slave.opStatus) || + (I2C_D_REV == g_i2c_slave.opStatus)) + { + g_i2c_slave.opStatus = I2C_D_REV; + + /* Read data from ICDRR. */ + if (g_i2c_slave.recv_buf && g_i2c_slave.recv_pos < g_i2c_slave.recv_buf_len) { + g_i2c_slave.recv_buf[g_i2c_slave.recv_pos++] = I2CR->ICDRR; + + /* Receive buffer is full, cb user */ + if ((g_i2c_slave.recv_pos == g_i2c_slave.recv_buf_len) && g_i2c_slave.recv_cb) { + g_i2c_slave.recv_cb(g_i2c_slave.recv_param, g_i2c_slave.recv_pos); + g_i2c_slave.recv_pos = 0; + } + } + } + } + + /* The I2C interrupt events (transmit-data-ready interrupt ) */ + if (TRA_DATA_READY_INT == intStatus) + { + if ((I2C_START == g_i2c_slave.opStatus) || + (I2C_R_START == g_i2c_slave.opStatus) || + (I2C_D_TRA == g_i2c_slave.opStatus)) + { + g_i2c_slave.opStatus = I2C_D_TRA; + + /* Wait master reading data over */ + timeOutCnt = 0xf0000000; + while ((0 == (I2CR->ICSTR & CSL_I2C_ICSTR_ICXRDY_MASK)) && + (0 != ++ timeOutCnt) && (0 == (I2CR->ICSTR & CSL_I2C_ICSTR_SCD_MASK))); + if (0 != timeOutCnt) + { + /* Write first data to ICDXR */ + if (g_i2c_slave.send_data && g_i2c_slave.send_pos < g_i2c_slave.send_data_len) { + I2CR->ICDXR = g_i2c_slave.send_data[g_i2c_slave.send_pos]; + g_i2c_slave.send_pos++; + } + } + else + { + asm(" NOP 6"); + } + } + } + + /* The I2C interrupt events (stop condition detected interrupt ) */ + if (STOP_CONDITION_DETECTED_INT == intStatus) + { + /* Recieve datas from master over */ + if (I2C_D_REV == g_i2c_slave.opStatus) { + if (g_i2c_slave.recv_cb) + g_i2c_slave.recv_cb(g_i2c_slave.recv_buf, g_i2c_slave.recv_pos); + } + + /* Transmit datas to master over */ + if (I2C_D_TRA == g_i2c_slave.opStatus) { + if (g_i2c_slave.send_end_cb) + g_i2c_slave.send_end_cb(g_i2c_slave.send_param, g_i2c_slave.send_pos); + } + + g_i2c_slave.opStatus = I2C_IDLE; + + /* The I2C slaver receiver mode */ + I2CR->ICMDR &= (~CSL_I2C_ICMDR_TRX_MASK); + + /* Transmit-data-ready interrupt disable */ + I2CR->ICIMR &= (~CSL_I2C_ICIMR_ICXRDY_MASK); + } + +} diff --git a/packages/vsky/libdsp/driver/power_ctrl.c b/packages/vsky/libdsp/driver/power_ctrl.c new file mode 100644 index 0000000..d1c0117 --- /dev/null +++ b/packages/vsky/libdsp/driver/power_ctrl.c @@ -0,0 +1,29 @@ +/* + * power_ctrl.c + * + * Created on: 2018-9-27 + * Author: Administrator + */ +#include "ckdef.h" + +void power_pass_on(void ) +{ + /* PASS power domain is turned OFF by default. It needs to be turned on before doing any + * PASS device register access. This not required for the simulator. */ + + /* Set PASS Power domain to ON */ + CSL_PSC_enablePowerDomain (CSL_PSC_PD_PASS); + + /* Enable the clocks for PASS modules */ + CSL_PSC_setModuleNextState (CSL_PSC_LPSC_PKTPROC, PSC_MODSTATE_ENABLE); + CSL_PSC_setModuleNextState (CSL_PSC_LPSC_CPGMAC, PSC_MODSTATE_ENABLE); + CSL_PSC_setModuleNextState (CSL_PSC_LPSC_Crypto, PSC_MODSTATE_ENABLE); + + /* Start the state transition */ + CSL_PSC_startStateTransition (CSL_PSC_PD_PASS); + + /* Wait until the state transition process is completed. */ + while (!CSL_PSC_isStateTransitionDone (CSL_PSC_PD_PASS)); +} + + diff --git a/packages/vsky/libdsp/driver/power_ctrl.h b/packages/vsky/libdsp/driver/power_ctrl.h new file mode 100644 index 0000000..46f627f --- /dev/null +++ b/packages/vsky/libdsp/driver/power_ctrl.h @@ -0,0 +1,14 @@ +/* + * power_ctrl.h + * + * Created on: 2018-9-27 + * Author: Administrator + */ + +#ifndef POWER_CTRL_H_ +#define POWER_CTRL_H_ + +void power_pass_on(void ); + + +#endif /* POWER_CTRL_H_ */ diff --git a/packages/vsky/libdsp/driver/sgmii.c b/packages/vsky/libdsp/driver/sgmii.c new file mode 100644 index 0000000..4271fc7 --- /dev/null +++ b/packages/vsky/libdsp/driver/sgmii.c @@ -0,0 +1,215 @@ +/* + * sgmii.c + * + * Created on: 2018-9-26 + * Author: Administrator + */ +#include "ckdef.h" +#include "sgmii.h" +#include "tsc.h" + +void sgmii_serdes_init(void ) +{ + CSL_SGMII_STATUS sgmii_status; + + /* Unlock the chip configuration registers to allow SGMII SERDES registers to + * be written */ + CSL_BootCfgUnlockKicker(); + + /* Configure the SERDES */ + /* Multiply to be 8 with Quarter Rate in the Rx registers */ + CSL_BootCfgSetSGMIIConfigPLL (0x00000041); + + tsc_delay_cycles(100); + + //31:25 Reserved 0000000 + //23:24 LOOPBACK 00 + // 22 ENOC 1 + //21:18 EQ 0001 + //17:15 CDR 001 -- first order threshold of 17 + //14:12 LOS 000 -- tie off + //11:10 ALIGN 01 -- Comma Aligned + //09:07 TERM 100 -- tie off (100) + // 06 INVPAIR 0 + //05:04 RATE 01 -- tie off (10) //00 = Full Rate, 01 = Half Rate (*0.5), 10 = Quarter Rate (*0.25) + //03:01 BUSWIDTH 000 -- tie off + // 00 ENRX 1 + // 0000 0000 0100 0100 0000 0010 0001 0001 = 0x0044_0211 -- My estimated value + // 0000 0000 0100 0100 0000 0100 0001 0001 = 0x0044_0411 -- New DV value + // 0000 0000 0000 1000 0000 1000 0100 0001 = 0x0008_0841 -- Original DV value + + CSL_BootCfgSetSGMIIRxConfig (0, 0x00700621); + CSL_BootCfgSetSGMIIRxConfig (1, 0x00700621); + + //31:22 Reserved 0 + //21:20 LOOPBACK 00 + //19:18 RDTCT 00 -- tie off + // 17 ENIDL 0 -- tie off + // 16 MYSNC 1 -- tie off + //15:12 DEMPHASIS ???? - 0001 Lets give some de-emphasis + //11:08 SWING ???? + // 07 CM 1 -- tie off + // 06 INVPAIR 0 + //05:04 RATE 01 -- tie off + //03:01 BUSWIDTH 000 -- tie off + // 00 ENTX 1 + // 0000 0000 0011 0001 ???? ???? 1001 0001 = 0x0031_1E91 -- My estimated value + // 0000 0000 0000 0001 0000 1111 0001 0001 = 0x0001_0F11 -- New DV value + // 0000 0000 0100 0000 0001 1110 0100 0001 = 0x0040_1e41 -- Original DV value + CSL_BootCfgSetSGMIITxConfig (0, 0x000108A1); + CSL_BootCfgSetSGMIITxConfig (1, 0x000108A1); + + /* Poll the SGMII0 lock bit to confirm that the sgmii module has recognized + that the SERDES PLL has locked */ + do + { + CSL_SGMII_getStatus(0, &sgmii_status); + } while (sgmii_status.bIsLocked != 1); + + /* Poll the SGMII1 lock bit to confirm that the sgmii module has recognized + that the SERDES PLL has locked */ + do + { + CSL_SGMII_getStatus(1, &sgmii_status); + } while (sgmii_status.bIsLocked != 1); + + /* All done with configuration. Return Now. */ + return; +} + +void sgmii_mdio_init(uint32_t phyAddr[2]) +{ + CSL_MDIO_isStateMachineEnabled(); + CSL_MDIO_isFaultDetected(); + CSL_MDIO_isFaultDetectEnabled(); + CSL_MDIO_setClkDivVal(350); + + CSL_MDIO_enableLinkStatusChangeInterrupt(0, phyAddr[0]); + CSL_MDIO_enableLinkStatusChangeInterrupt(1, phyAddr[1]); + + while(CSL_MDIO_isStateMachineIdle()); +} + +int sgmii_init(int port, SGMII_PORT_MODE mode) +{ + CSL_SGMII_ADVABILITY sgmiiCfg; + CSL_SGMII_STATUS sgmiiStatus; + + /* Reset the port before configuring it */ + CSL_SGMII_doSoftReset (port); + while (CSL_SGMII_getSoftResetStatus (port) != 0); + + if ((mode == SGMII_PORT_MODE_AUTO_SLAVE) || (mode == SGMII_PORT_MODE_AUTO_MASTER)) { + /* Hold the port in soft reset and set up + * the SGMII control register: + * (1) Disable Master Mode (default) + * (2) Enable Auto-negotiation + */ + CSL_SGMII_startRxTxSoftReset (port); + if (mode == SGMII_PORT_MODE_AUTO_SLAVE) + CSL_SGMII_disableMasterMode (port); + else + CSL_SGMII_enableMasterMode (port); + /* Setup the Advertised Ability register for this port: + * (1) Enable Full duplex mode + * (2) Enable Auto Negotiation + */ + sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS; + sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX; + sgmiiCfg.bLinkUp = 1; + CSL_SGMII_setAdvAbility (port, &sgmiiCfg); + + CSL_SGMII_enableAutoNegotiation (port); + CSL_SGMII_endRxTxSoftReset (port); + + /* Wait for SGMII Link */ + do + { + CSL_SGMII_getStatus(port, &sgmiiStatus); + } while (sgmiiStatus.bIsLinkUp != 1); + + /* Wait for SGMII Autonegotiation to complete without error */ + do + { + CSL_SGMII_getStatus(port, &sgmiiStatus); + if (sgmiiStatus.bIsAutoNegError != 0) + return -1; + } while (sgmiiStatus.bIsAutoNegComplete != 1); + + /* + * May need to wait some more time for the external PHY to be ready to transmit packets reliabily. + * It is possible to access the PHY status register through the MDIO interface to check when + * the PHY is ready. + * To avoid platform-dependent code, we just introduce about 2ms wait here + */ + tsc_delay_cycles(200000); + } else { + /* Hold the port in soft reset and set up + * the SGMII control register: + * (1) Disable Master Mode (default) + * (2) Enable Auto-negotiation + */ + CSL_SGMII_startRxTxSoftReset (port); + CSL_SGMII_enableMasterMode (port); + /* Setup the Advertised Ability register for this port: + * (1) Enable Full duplex mode + * (2) Enable Auto Negotiation + */ + if (mode == SGMII_PORT_MODE_10M_FULLDUPLEX) + sgmiiCfg.linkSpeed = CSL_SGMII_10_MBPS; + else if (mode == SGMII_PORT_MODE_100M_FULLDUPLEX) + sgmiiCfg.linkSpeed = CSL_SGMII_100_MBPS; + else + sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS; + sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX; + sgmiiCfg.bLinkUp = 1; + CSL_SGMII_setAdvAbility (port, &sgmiiCfg); + + CSL_SGMII_disableAutoNegotiation (port); + CSL_SGMII_endRxTxSoftReset (port); + + /* Wait for SGMII Link */ + do + { + CSL_SGMII_getStatus(port, &sgmiiStatus); + } while (sgmiiStatus.bIsLinkUp != 1); + } + + return 0; +} + +CSL_Mdio_Regs *gpMDIO_regs = ((CSL_Mdio_Regs *) (CSL_PA_SS_CFG_REGS + 0x00090300)); + +void mdio_init(int port, mdio_cfg_s mc) +{ +#if 0 + if(NULL == mc) + return; + + gpMDIO_regs->CONTROL_REG= CSL_MDIO_CONTROL_REG_ENABLE_MASK + |CSL_MDIO_CONTROL_REG_FAULT_MASK /*write 1 to clear this bit*/ + |CSL_MDIO_CONTROL_REG_FAULT_DETECT_ENABLE_MASK + |(mc->clock_div<link_INT0_PHY_select<=MDIO_INT_SELECT_PHY_31) + gpMDIO_regs->USER_GROUP[port].USER_PHY_SEL_REG= + CSL_MDIO_USER_PHY_SEL_REG_LINKINT_ENABLE_MASK + |(mc->link_phy_select<CONTROL_REG&CSL_MDIO_CONTROL_REG_IDLE_MASK); +#endif +} + +int mdio_phy_set_reg(int port, uint32_t phyAddr, uint32_t regNum, uint16_t val) +{ + + return 0; +} + +int mdio_phy_get_reg(int port, uint32_t phyAddr, uint32_t regNum, uint16_t *val) +{ + return 0; +} diff --git a/packages/vsky/libdsp/driver/spi.c b/packages/vsky/libdsp/driver/spi.c new file mode 100644 index 0000000..3f4505a --- /dev/null +++ b/packages/vsky/libdsp/driver/spi.c @@ -0,0 +1,175 @@ +/* + * spi.c + * + * Created on: 2018-9-29 + * Author: Administrator + */ +#include "ckdef.h" +#include "spi.h" +#include "tsc.h" + +struct spi { + int bus; + uint32_t mode_clk; + eSPI_PIN_MODE pins; + uint32_t wordbits[SYS_SPI_CS_MAX_NUM]; + CSL_SpiRegs * SPI_regs; +}; + +static struct spi g_spi[SYS_SPI_MAX_NUM]; + +static void __delay( uint32_t delay ) +{ + volatile uint32_t i; + for ( i = 0 ; i < delay; i++ ) + ; +} +static void __spi_init(spi_t s) +{ + CSL_SpiRegs *SPI_regs = s->SPI_regs; + + /*1. Reset the SPI by clearing the RESET bit in the SPI global control register 0 + (SPIGCR0) to 0.*/ + SPI_regs->SPIGCR0 = CSL_SPI_SPIGCR0_RESET_IN_RESET; + __delay(2000); + + /*2. Take the SPI out of reset by setting SPIGCR0.RESET to 1.*/ + SPI_regs->SPIGCR0 = CSL_SPI_SPIGCR0_RESET_OUT_OF_RESET; + + /*3. Configure the SPI for master mode by configuring the CLKMOD and MASTER + * bits in the SPI global control register 1 (SPIGCR1).*/ + SPI_regs->SPIGCR1 = (CSL_SPI_SPIGCR1_MASTER_MASTER << CSL_SPI_SPIGCR1_MASTER_SHIFT) | + (CSL_SPI_SPIGCR1_CLKMOD_INTERNAL << CSL_SPI_SPIGCR1_CLKMOD_SHIFT); + + /*4. Configure the SPI for 3-pin or 4-pin with chip select mode by configuring the SPI + pin control register 0 (SPIPC0).*/ + SPI_regs->SPIPC0 = CSL_SPI_SPIPC0_SOMIFUN_MASK | CSL_SPI_SPIPC0_SIMOFUN_MASK|CSL_SPI_SPIPC0_CLKFUN_MASK; + if(s->pins == SPI_PIN_MODE_4) + SPI_regs->SPIPC0 |= CSL_SPI_SPIPC0_SCS0FUN0_MASK; + + + /*7. In master mode, configure the master delay options using the SPI delay register(SPIDELAY).*/ + SPI_regs->SPIDELAY= (8 << CSL_SPI_SPIDELAY_C2TDELAY_SHIFT) | (8 << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT); + /*the CS_polarity is defined as invert of the register field*/ + SPI_regs->SPIDEF = 0xFF; + + /*8. Select the error interrupt notifications by configuring the SPI interrupt register + (SPIINT0) and the SPI interrupt level register (SPILVL).*/ + /*on interrupts*/ + SPI_regs->SPIINT0 = CSL_SPI_SPIINT0_RESETVAL; + SPI_regs->SPILVL = CSL_SPI_SPILVL_RESETVAL; + + /*9. Enable the SPI communication by setting the SPIGCR1.ENABLE to 1.*/ + SPI_regs->SPIGCR1 |= (CSL_SPI_SPIGCR1_ENABLE_ENABLE << CSL_SPI_SPIGCR1_ENABLE_SHIFT); +} + +spi_t spi_init(int bus, uint32_t spi_mode_clk, eSPI_PIN_MODE pins) +{ + spi_t s = NULL; + if (bus < SYS_SPI_MAX_NUM) { + s = &g_spi[bus]; + s->bus = bus; + s->mode_clk = spi_mode_clk; + s->pins = pins; + s->SPI_regs = (CSL_SpiRegs *)CSL_SPI_REGS; + __spi_init(s); + } + + return s; +} + +void spi_close(spi_t s) +{ + return; +} + +int spi_config(spi_t s, int cs, spi_cs_cfg_s *cfg) +{ + uint32_t scalar; + uint8_t polarity, phase; + CSL_SpiRegs *SPI_regs = s->SPI_regs; + + //Disable the SPI communication + SPI_regs->SPIGCR1 &= ~(CSL_SPI_SPIGCR1_ENABLE_ENABLE << CSL_SPI_SPIGCR1_ENABLE_SHIFT); + + /*5. Choose the SPI data formate register n(SPIFMTn) to be used by configuring the DESEL bit in the SPI + * transmit data register(SPIDAT1).*/ + //no thing + + /*6. Configure the SPI data rate, character length, shift direction, phase, polarity and + other format options using SPIFMTn selected in step 5.*/ + scalar = ((s->mode_clk / cfg->speed) - 1) & 0xFF; + if (cfg->mode == SPI_CLK_MODE_0) {polarity = 0; phase = 0;} + else if (cfg->mode == SPI_CLK_MODE_1) {polarity = 0; phase = 1;} + else if (cfg->mode == SPI_CLK_MODE_2) {polarity = 1; phase = 0;} + else if (cfg->mode == SPI_CLK_MODE_3) {polarity = 1; phase = 1;} + + SPI_regs->SPIFMT[cs] = (cfg->bits << CSL_SPI_SPIFMT_CHARLEN_SHIFT) | + (scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT) | + ((polarity & 0x1) << CSL_SPI_SPIFMT_PHASE_SHIFT) | + ((phase & 0x1) << CSL_SPI_SPIFMT_POLARITY_SHIFT) | + ((cfg->endian & 0x1) << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT); + + /*9. Enable the SPI communication by setting the SPIGCR1.ENABLE to 1.*/ + SPI_regs->SPIGCR1 |= (CSL_SPI_SPIGCR1_ENABLE_ENABLE << CSL_SPI_SPIGCR1_ENABLE_SHIFT); + + s->wordbits[cs] = cfg->bits; + return 0; +} + +int spi_xfer(spi_t s, int cs, uint32_t elms, const void *out, void *in) +{ + uint32_t i; + uint32_t dataFormat; + uint32_t txData, rxData; + CSL_SpiRegs *SPI_regs = s->SPI_regs; + uint8_t* tx_ptr_8 = (uint8_t *)out; + uint8_t* rx_ptr_8 = (uint8_t *)in; + uint16_t* tx_ptr_16 = (uint16_t *)out; + uint16_t* rx_ptr_16 = (uint16_t *)in; + + /*init spidat1 same flag bits*/ + dataFormat = (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) | + (CSL_SPI_SPIDAT1_WDEL_DISABLE << CSL_SPI_SPIDAT1_WDEL_SHIFT) | + (cs << CSL_SPI_SPIDAT1_DFSEL_SHIFT) | + ((~(0x1 << cs)) << CSL_SPI_SPIDAT1_CSNR_SHIFT); + dataFormat &= ~CSL_SPI_SPIDAT1_TXDATA_MASK; + + for (i = 0; i < elms; ++i) { + /* Wait untill TX buffer is not full */ + while( SPI_regs->SPIBUF & CSL_SPI_SPIBUF_TXFULL_MASK ); + + /* Set the TX data to SPIDAT1 */ + //last a elm, Release the CS at the end of the transfer + if (i == (elms -1)) + dataFormat &= ~(CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT); + + //structure a spidat1 val; + if (out) { + if (s->wordbits[cs] == 8) + txData = dataFormat | (tx_ptr_8[i] & 0xFF); + else + txData = dataFormat | (tx_ptr_16[i] & 0xFFFF); + } else { + txData = dataFormat; + } + + //updata spidata1 val; + SPI_regs->SPIDAT1 = txData; + + /* Read SPIBUF, wait untill the RX buffer is not empty */ + while ( SPI_regs->SPIBUF & ( CSL_SPI_SPIBUF_RXEMPTY_MASK ) ); + + /* Read one byte data */ + rxData = SPI_regs->SPIBUF; + + if (in) { + if (s->wordbits[cs] == 8) + rx_ptr_8[i] = rxData & 0xFF; + else + rx_ptr_16[i] = rxData & 0xFFFF; + } + } + + return elms; +} diff --git a/packages/vsky/libdsp/driver/tsc.c b/packages/vsky/libdsp/driver/tsc.c new file mode 100644 index 0000000..70c3c28 --- /dev/null +++ b/packages/vsky/libdsp/driver/tsc.c @@ -0,0 +1,45 @@ +/* + * tsc.c + * + * Created on: 2018-9-26 + * Author: Administrator + */ +#include "ckdef.h" +#include "tsc.h" + +unsigned int g_dsp_corefreq = DSP_CORE_FREQ_FAULT; + +void tsc_init(uint32_t core_speed_hz) +{ + g_dsp_corefreq = core_speed_hz; +} + +void tsc_delay(uint32_t usecs) +{ + volatile unsigned long long startTSC, currentTSC; + unsigned long long delay_cycles; + + delay_cycles = ((unsigned long long) usecs * g_dsp_corefreq / 1000000); + tsc_delay_cycles(delay_cycles); +} + +void tsc_delay_cycles(uint32_t cycles) +{ + volatile unsigned long long startTSC, currentTSC; + uint32_t tscl, tsch; + + tscl = CSL_chipReadTSCL(); + tsch = CSL_chipReadTSCH(); + startTSC = _itoll(tsch, tscl); + + do { + tscl = CSL_chipReadTSCL(); + tsch = CSL_chipReadTSCH(); + currentTSC = _itoll(tsch, tscl); + } while((currentTSC - startTSC) < cycles); +} + +uint32_t tsc_get_delay(uint32_t start) +{ + return ((unsigned int)((0xFFFFFFFFl + CSL_chipReadTSCL())- (unsigned long long)start)+ 1); +} diff --git a/packages/vsky/libdsp/inc/gpio.h b/packages/vsky/libdsp/inc/gpio.h index 81d4140..7a1b046 100644 --- a/packages/vsky/libdsp/inc/gpio.h +++ b/packages/vsky/libdsp/inc/gpio.h @@ -4,6 +4,19 @@ extern "C" { #endif +#define GPIOF_OUT (0) +#define GPIOF_IN (1) + +/* + * init gpio. + * + * gpio: gpio number. [ 0, 15 ] for C6678. + * dir: GPIOF_DIR_OUT or GPIOF_DIR_IN. + * + * return: 0 on success, < 0 on failure. + */ +int gpio_init(int gpio, int dir/*0-out, 1-in*/); + /* * set gpio direction to in. * diff --git a/packages/vsky/libdsp/inc/i2c.h b/packages/vsky/libdsp/inc/i2c.h new file mode 100644 index 0000000..5336fc0 --- /dev/null +++ b/packages/vsky/libdsp/inc/i2c.h @@ -0,0 +1,42 @@ +/* + * i2c.h + * + * Created on: 2018-9-27 + * Author: Administrator + */ + +#ifndef __I2C_H_ +#define __I2C_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*I2C internal clock should be 7~12MHz*/ +#define I2C_MODULE_FREQ_KHZ 10000 + +typedef enum { + I2C_NOWAIT = 0, + I2C_WAIT = 1 +}I2C_Wait; + +void i2c_master_init(uint32_t i2c_speed_KHz); +uint32_t i2c_master_read(uint32_t slaveAddress, uint32_t uiByteCount, uint8_t * ucBuffer, I2C_Wait wait); +uint32_t i2c_master_write( uint32_t slaveAddress, uint32_t uiByteCount, uint8_t * ucBuffer, I2C_Wait wait); + +/*i2c slave init*/ +int i2c_slave_init(uint8_t slaveAddress); + +/*i2c master w to slave*/ +void i2c_slave_set_recv_cb(uint8_t *recvbuf, uint32_t buflen, void *param, int (*recv_cb)(void *param, uint32_t len)); + +/*i2c master r from slave*/ +void i2c_slave_set_send_cb(void *param, int (*send_start_cb)(uint8_t **wait_send_data, uint32_t *len), int (*send_end_cb)(void *param, int retlen)); + +/*i2c slave intrrupt handle func */ +void i2c_slave_isr(void ); + +#ifdef __cplusplus +} +#endif +#endif /* I2C_H_ */ diff --git a/packages/vsky/libdsp/inc/sgmii.h b/packages/vsky/libdsp/inc/sgmii.h new file mode 100644 index 0000000..9a2db7d --- /dev/null +++ b/packages/vsky/libdsp/inc/sgmii.h @@ -0,0 +1,74 @@ +/* + * sgmii.h + * + * Created on: 2018-9-26 + * Author: Administrator + */ + +#ifndef SGMII_H_ +#define SGMII_H_ + +typedef enum { + SGMII_PORT_MODE_AUTO_SLAVE = 0, + SGMII_PORT_MODE_AUTO_MASTER, + SGMII_PORT_MODE_10M_FULLDUPLEX, + SGMII_PORT_MODE_100M_FULLDUPLEX, + SGMII_PORT_MODE_1000M_FULLDUPLEX +}SGMII_PORT_MODE; + +void sgmii_serdes_init(void ); +int sgmii_init(int port, SGMII_PORT_MODE mode); + +/*PHY selected to trigger MDIO link interrupt*/ +typedef enum +{ + MDIO_INT_SELECT_PHY_0= 0, + MDIO_INT_SELECT_PHY_1 , + MDIO_INT_SELECT_PHY_2 , + MDIO_INT_SELECT_PHY_3 , + MDIO_INT_SELECT_PHY_4 , + MDIO_INT_SELECT_PHY_5 , + MDIO_INT_SELECT_PHY_6 , + MDIO_INT_SELECT_PHY_7 , + MDIO_INT_SELECT_PHY_8 , + MDIO_INT_SELECT_PHY_9 , + MDIO_INT_SELECT_PHY_10, + MDIO_INT_SELECT_PHY_11, + MDIO_INT_SELECT_PHY_12, + MDIO_INT_SELECT_PHY_13, + MDIO_INT_SELECT_PHY_14, + MDIO_INT_SELECT_PHY_15, + MDIO_INT_SELECT_PHY_16, + MDIO_INT_SELECT_PHY_17, + MDIO_INT_SELECT_PHY_18, + MDIO_INT_SELECT_PHY_19, + MDIO_INT_SELECT_PHY_20, + MDIO_INT_SELECT_PHY_21, + MDIO_INT_SELECT_PHY_22, + MDIO_INT_SELECT_PHY_23, + MDIO_INT_SELECT_PHY_24, + MDIO_INT_SELECT_PHY_25, + MDIO_INT_SELECT_PHY_26, + MDIO_INT_SELECT_PHY_27, + MDIO_INT_SELECT_PHY_28, + MDIO_INT_SELECT_PHY_29, + MDIO_INT_SELECT_PHY_30, + MDIO_INT_SELECT_PHY_31, + MDIO_INT_SELECT_PHY_NONE +}MDIO_Link_INT_PHY_Select; + +/* + * return: + * 0 - success; + * 1 - timeout; + * -1 - fail; + * */ +typedef struct mdio_cfg { + uint16_t clock_div; + MDIO_Link_INT_PHY_Select link_phy_select; +}mdio_cfg_s; + +void mdio_init(int port, mdio_cfg_s mc); +int mdio_phy_set_reg(int port, uint32_t phyAddr, uint32_t regNum, uint16_t val); +int mdio_phy_get_reg(int port, uint32_t phyAddr, uint32_t regNum, uint16_t *val); +#endif /* SGMII_H_ */ diff --git a/packages/vsky/libdsp/inc/spi.h b/packages/vsky/libdsp/inc/spi.h new file mode 100644 index 0000000..39a5291 --- /dev/null +++ b/packages/vsky/libdsp/inc/spi.h @@ -0,0 +1,41 @@ +/* + * spi.h + * + * Created on: 2018-9-28 + * Author: Administrator + */ + +#ifndef SPI_H_ +#define SPI_H_ + +#define SYS_SPI_MAX_NUM 1 //for 6678 spi module only 1 +#define SYS_SPI_CS_MAX_NUM 2 // spi support cs0 and cs1 + +typedef enum { + SPI_PIN_MODE_3 = 3, /*3-pin Option*/ + SPI_PIN_MODE_4, /*4-pin Option*/ + SPI_PIN_MODE_UNK +}eSPI_PIN_MODE; + +typedef enum { + SPI_CLK_MODE_0 = 0, /*Clock Mode with Polarity = 0 and Phase = 0*/ + SPI_CLK_MODE_1, /*Clock Mode with Polarity = 0 and Phase = 1*/ + SPI_CLK_MODE_2, /*Clock Mode with Polarity = 1 and Phase = 0*/ + SPI_CLK_MODE_3, /*Clock Mode with Polarity = 1 and Phase = 1*/ + SPI_CLK_MODE_UNK +}eSPI_CLK_MODE; + +typedef struct spi_cfg{ + eSPI_CLK_MODE mode; /*Clock Phase and Polarity mode*/ + uint32_t speed; /*speed eg: 25000000- 25 M*/ + uint32_t bits; /*bits, eg: 8-8bits or 16-16bits*/ + uint32_t endian; /*0-Most significant bit is shifed out first*/ +}spi_cs_cfg_s; + +typedef struct spi *spi_t; + +spi_t spi_init(int bus, uint32_t spi_mode_clk, eSPI_PIN_MODE pins); +void spi_close(spi_t s); +int spi_config(spi_t s, int cs /*0-cs0, 1-cs1*/, spi_cs_cfg_s *cfg); +int spi_xfer(spi_t s, int cs, uint32_t elms, const void *out, void *in); +#endif /* SPI_H_ */ diff --git a/packages/vsky/libdsp/inc/tsc.h b/packages/vsky/libdsp/inc/tsc.h new file mode 100644 index 0000000..ae0b351 --- /dev/null +++ b/packages/vsky/libdsp/inc/tsc.h @@ -0,0 +1,25 @@ +/* + * tsc.h + * + * Created on: 2018-9-26 + * Author: Administrator + */ + +#ifndef TSC_H_ +#define TSC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern unsigned int g_dsp_corefreq; + +void tsc_init(uint32_t core_speed_hz); +void tsc_delay(uint32_t usecs); +void tsc_delay_cycles(uint32_t cycles); +uint32_t tsc_get_delay(uint32_t start); + +#ifdef __cplusplus +} +#endif +#endif /* DELAY_H_ */ diff --git a/packages/vsky/libdsp/package.bld b/packages/vsky/libdsp/package.bld index 868cbd6..4e9f80f 100644 --- a/packages/vsky/libdsp/package.bld +++ b/packages/vsky/libdsp/package.bld @@ -14,6 +14,11 @@ var objFiles = [ "driver/uart.cpp", "driver/gpio.c", "driver/semaphore2.c", + "driver/emif.c", + "driver/i2c.c", + "driver/tsc.c", + "driver/sgmii.c", + "driver/power_ctrl.c", "Uart.c", "SerialSystem.c", ];