Browse Source

add more drivers

Signed-off-by: surenyi <surenyi82@163.com>
master
surenyi 6 years ago
parent
commit
925fcdece7
  1. 45
      packages/vsky/libdsp/driver/ckdef.h
  2. 143
      packages/vsky/libdsp/driver/emif.c
  3. 89
      packages/vsky/libdsp/driver/emif.h
  4. 84
      packages/vsky/libdsp/driver/gpio.c
  5. 515
      packages/vsky/libdsp/driver/i2c.c
  6. 29
      packages/vsky/libdsp/driver/power_ctrl.c
  7. 14
      packages/vsky/libdsp/driver/power_ctrl.h
  8. 215
      packages/vsky/libdsp/driver/sgmii.c
  9. 175
      packages/vsky/libdsp/driver/spi.c
  10. 45
      packages/vsky/libdsp/driver/tsc.c
  11. 13
      packages/vsky/libdsp/inc/gpio.h
  12. 42
      packages/vsky/libdsp/inc/i2c.h
  13. 74
      packages/vsky/libdsp/inc/sgmii.h
  14. 41
      packages/vsky/libdsp/inc/spi.h
  15. 25
      packages/vsky/libdsp/inc/tsc.h
  16. 5
      packages/vsky/libdsp/package.bld

45
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 <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ti/csl/csl_types.h>
#include <ti/csl/csl_chip.h>
#include <ti/csl/csl_chipAux.h>
#include <ti/csl/csl_bootcfg.h>
#include <ti/csl/csl_bootcfgAux.h>
#include <ti/csl/csl_psc.h>
#include <ti/csl/csl_pscAux.h>
#include <ti/csl/csl_semAux.h>
#include <ti/csl/csl_gpio.h>
#include <ti/csl/csl_gpioAux.h>
#include <ti/csl/cslr_uart.h>
#include <ti/csl/cslr_i2c.h>
#include <ti/csl/cslr_spi.h>
#include <ti/csl/cslr_emif16.h>
#include <ti/csl/csl_cpsgmii.h>
#include <ti/csl/csl_cpsgmiiAux.h>
#include <ti/csl/csl_mdio.h>
#include <ti/csl/csl_mdioAux.h>
#define SEMAPHORE_FOR_I2C 31
#define SEMAPHORE_FOR_SPI 30
#define DSP_CORE_FREQ_FAULT 1000000000
#endif /* CKDEF_H_ */

143
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<<CSL_EMIF16_A0CR_WSETUP_SHIFT) & (~CSL_EMIF16_A0CR_WSETUP_MASK))
{
puts("write setup timing value is too large");
continue;
}
if((ceCfg->wrStrobe<<CSL_EMIF16_A0CR_WSTROBE_SHIFT) & (~CSL_EMIF16_A0CR_WSTROBE_MASK))
{
puts("write strobe timing value is too large");
continue;
}
if((ceCfg->wrHold<<CSL_EMIF16_A0CR_WHOLD_SHIFT) & (~CSL_EMIF16_A0CR_WHOLD_MASK))
{
puts("write hold timing value is too large");
continue;
}
if((ceCfg->rdSetup<<CSL_EMIF16_A0CR_RSETUP_SHIFT) & (~CSL_EMIF16_A0CR_RSETUP_MASK))
{
puts("read setup timing value is too large");
continue;
}
if((ceCfg->rdStrobe<<CSL_EMIF16_A0CR_RSTROBE_SHIFT) & (~CSL_EMIF16_A0CR_RSTROBE_MASK))
{
puts("read strobe timing value is too large");
continue;
}
if((ceCfg->rdHold<<CSL_EMIF16_A0CR_RHOLD_SHIFT) & (~CSL_EMIF16_A0CR_RHOLD_MASK))
{
puts("read hold timing value is too large");
continue;
}
if((ceCfg->turnAroundCycles<<CSL_EMIF16_A0CR_TA_SHIFT) & (~CSL_EMIF16_A0CR_TA_MASK))
{
puts("turn around timing value is too large");
continue;
}
/*Async Config Register*/
regVal= ((ceCfg->strobeMode<<CSL_EMIF16_A0CR_SS_SHIFT) & CSL_EMIF16_A0CR_SS_MASK)
|((ceCfg->wrSetup<<CSL_EMIF16_A0CR_WSETUP_SHIFT) & CSL_EMIF16_A0CR_WSETUP_MASK)
|((ceCfg->wrStrobe<<CSL_EMIF16_A0CR_WSTROBE_SHIFT) & CSL_EMIF16_A0CR_WSTROBE_MASK)
|((ceCfg->wrHold<<CSL_EMIF16_A0CR_WHOLD_SHIFT) & CSL_EMIF16_A0CR_WHOLD_MASK)
|((ceCfg->rdSetup<<CSL_EMIF16_A0CR_RSETUP_SHIFT) & CSL_EMIF16_A0CR_RSETUP_MASK)
|((ceCfg->rdStrobe<<CSL_EMIF16_A0CR_RSTROBE_SHIFT) & CSL_EMIF16_A0CR_RSTROBE_MASK)
|((ceCfg->rdHold<<CSL_EMIF16_A0CR_RHOLD_SHIFT) & CSL_EMIF16_A0CR_RHOLD_MASK)
|((ceCfg->turnAroundCycles<<CSL_EMIF16_A0CR_TA_SHIFT) & CSL_EMIF16_A0CR_TA_MASK)
|((ceCfg->busWidth<<CSL_EMIF16_A0CR_ASIZE_SHIFT)&CSL_EMIF16_A0CR_ASIZE_MASK);
if(EMIF_WAIT_NONE!=ceCfg->waitMode)
{
regVal |= ((1<<CSL_EMIF16_A0CR_EW_SHIFT) & CSL_EMIF16_A0CR_EW_MASK);
AWCCR |= (((ceCfg->waitMode<<CSL_EMIF16_AWCCR_CE0WAIT_SHIFT)&CSL_EMIF16_AWCCR_CE0WAIT_MASK)<<(i*2));
}
ACR[i]= regVal;
/*Page Mode Control Register*/
if(ceCfg->nor_pg_Cfg)
{
regVal = ((ceCfg->nor_pg_Cfg->pageDelay<<CSL_EMIF16_PMCR_CE0PGDEL_SHIFT)&CSL_EMIF16_PMCR_CE0PGDEL_MASK)
|((ceCfg->nor_pg_Cfg->pageSize<<CSL_EMIF16_PMCR_CE0PGSIZE_SHIFT)&CSL_EMIF16_PMCR_CE0PGSIZE_MASK)
|((1<<CSL_EMIF16_PMCR_CE0PGMDEN_SHIFT)&CSL_EMIF16_PMCR_CE0PGMDEN_MASK);
PMCR |= (regVal<<(i*8));
}
/*NAND Flash Control Register*/
if(NAND_MODE==ceCfg->opMode)
NANDFCR |= (((1<<CSL_EMIF16_NANDFCTL_CE0NAND_SHIFT)&CSL_EMIF16_NANDFCTL_CE0NAND_MASK)<<i);
}
/*Async Wait Cycle Config Register*/
AWCCR |= (((pEmif16Cfg->maxWait<<CSL_EMIF16_AWCCR_MAXEXTWAIT_SHIFT)&CSL_EMIF16_AWCCR_MAXEXTWAIT_MASK)
|((pEmif16Cfg->wait0Polarity<<CSL_EMIF16_AWCCR_WP0_SHIFT)&CSL_EMIF16_AWCCR_WP0_MASK)
|((pEmif16Cfg->wait1Polarity<<CSL_EMIF16_AWCCR_WP1_SHIFT)&CSL_EMIF16_AWCCR_WP1_MASK));
EMIF16_Regs->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));
}

89
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_ */

84
packages/vsky/libdsp/driver/gpio.c

@ -1,62 +1,104 @@
#include <stdio.h>
#include <c6x.h>
#include <ti/csl/cslr_gpio.h>
#include <ti/csl/csl_bootcfgAux.h>
#include <ti/csl/csl_gpio.h>
#include <ti/csl/csl_gpioAux.h>
#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);
}
}

515
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<<CSL_I2C_ICMDR_MST_SHIFT)|
(1<<CSL_I2C_ICMDR_FREE_SHIFT);
/*Take I2C controller out of reset:
enable I2C controller (set IRS bit = 1 in ICMDR).*/
gpI2C_regs->ICMDR= gpI2C_regs->ICMDR|
(1<<CSL_I2C_ICMDR_IRS_SHIFT);
}
/*I2C read/write operations can not re-enter, so before any I2C operation,
this function should be called to block other I2C operations*/
void I2C_block()
{
while(0==CSL_semAcquireDirect(SEMAPHORE_FOR_I2C));
/*in real system indirect request may be used and then switch to ohter tasks
when the I2C is occupied by other module. And interrupt may be used to
switch back to this task.*/
}
/*after complete an I2C operation, free I2C for other operations*/
void I2C_free()
{
CSL_semReleaseSemaphore(SEMAPHORE_FOR_I2C);
}
/*wait a flag in ICSTR,
retun 1 when the ICSTR&flag_mask=expect, return 0 when timeout*/
Int32 I2C_wait_flag(Uint32 flag_mask, Uint32 expect)
{
Uint32 startTSC;
Uint32 delay;
Uint32 theoryCycleForOneByte;
volatile Uint32 flag;
startTSC= TSCL;
theoryCycleForOneByte= (g_dsp_corefreq/1000/I2C_speed_KHz)*9;
flag= gpI2C_regs->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<<CSL_I2C_ICMDR_FREE_SHIFT)|
(1<<CSL_I2C_ICMDR_MST_SHIFT);
/*Take I2C controller out of reset: enable I2C controller (set IRS bit = 1 in ICMDR).*/
gpI2C_regs->ICMDR= gpI2C_regs->ICMDR|
(1<<CSL_I2C_ICMDR_IRS_SHIFT);
gpI2C_regs->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<<CSL_I2C_ICMDR_STT_SHIFT)|
(1<<CSL_I2C_ICMDR_STP_SHIFT);
if(I2C_NOWAIT==wait) {
/*exits after programmation of the control registers,
interrupt service routine should be used to handle the data.*/
return 0;
}
for(i= 0; i< uiByteCount; i++) {
if(0==I2C_read_one_byte(&ucBuffer[i]))
return 0;
}
/*Wait until bus busy bit is cleared (BB = 0 in ICSTR).*/
if(0==I2C_wait_flag(CSL_I2C_ICSTR_BB_MASK, 0))
uiByteCount= 0;
/*after complete an I2C operation, free I2C for other operations*/
I2C_free();
return uiByteCount;
}
/*transfer "uiByteCount" data from "ucBuffer" to I2C device with address
"slaveAddress". if "wait", polling until data trasfer complete, otherwise,
let interrupt handle the data.
return number of bytes transfered.*/
Uint32 i2c_master_write( 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 Transmiter (TRX = 1)*/
gpI2C_regs->ICMDR=
(1<<CSL_I2C_ICMDR_FREE_SHIFT)|
(1<<CSL_I2C_ICMDR_TRX_SHIFT)|
(1<<CSL_I2C_ICMDR_MST_SHIFT);
/*Take I2C controller out of reset: enable I2C controller (set IRS bit = 1 in ICMDR).*/
gpI2C_regs->ICMDR= gpI2C_regs->ICMDR|
(1<<CSL_I2C_ICMDR_IRS_SHIFT);
gpI2C_regs->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<<CSL_I2C_ICMDR_STT_SHIFT)|
(1<<CSL_I2C_ICMDR_STP_SHIFT);
if(I2C_NOWAIT==wait) {
/*exits after programmation of the control registers,
interrupt service routine should be used to handle the data.*/
return 0;
}
for(i= 1; i< uiByteCount; i++) {
if(0==I2C_write_one_byte(ucBuffer[i]))
return 0;
}
/*Wait until bus busy bit is cleared (BB = 0 in ICSTR).*/
if(0==I2C_wait_flag(CSL_I2C_ICSTR_BB_MASK, 0))
uiByteCount= 0;
/*after complete an I2C operation, free I2C for other operations*/
I2C_free();
return uiByteCount;
}
/*******************************************************************************************************************/
/*******************************************************************************************************************/
/**************** I2C Slave Mode ********************************/
/*******************************************************************************************************************/
/* The I2C operate status */
typedef enum {
I2C_IDLE = 0, /*idle */
I2C_START = 1, /*start */
I2C_R_START = 2, /*re start */
I2C_D_REV = 3, /*data recving */
I2C_D_TRA = 4 /*data training */
}opSts;
/* The interrupt events : receive-data-ready interrupt */
#define REV_DATA_READY_INT (0x4)
/* The interrupt events : transmit-data-ready interrupt */
#define TRA_DATA_READY_INT (0x5)
/* The interrupt events : stop condition detected interrupt */
#define STOP_CONDITION_DETECTED_INT (0x6)
/* The interrupt events : address-as-slave interrupt */
#define ADDRESS_AS_SLAVE_INT (0x7)
/* I2C module registers */
#define I2CR ((CSL_I2cRegs*)CSL_I2C_DATA_CONTROL_REGS)
typedef struct i2c_slave_obj {
opSts opStatus;
uint8_t *recv_buf;
uint32_t recv_buf_len;
uint32_t recv_pos;
void *recv_param;
int (*recv_cb)(void *param, uint32_t len);
uint8_t *send_data;
uint32_t send_data_len;
uint32_t send_pos;
void *send_param;
int (*send_start_cb)(uint8_t **wait_send_data, uint32_t *len);
int (*send_end_cb)(void *param, int retlen);
}i2c_slave_s;
static i2c_slave_s g_i2c_slave;
int i2c_slave_init(uint8_t slaveAddress)
{
/*Place I2C in reset (clear IRS = 0 in ICMDR). */
gpI2C_regs->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);
}
}

29
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));
}

14
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_ */

215
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<<CSL_MDIO_CONTROL_REG_CLKDIV_SHIFT);
//port link setup
if(mc->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<<CSL_MDIO_USER_PHY_SEL_REG_PHYADR_MON_SHIFT);
/*The MDIO module powers up in an idle state before it is enabled.
wait for it is not idle (really enabled)*/
while(gpMDIO_regs->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;
}

175
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;
}

45
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);
}

13
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.
*

42
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_ */

74
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_ */

41
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_ */

25
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_ */

5
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",
];

Loading…
Cancel
Save