/*Set up output clocks per bit for SSP bus*/
void Chip_SSP_SetClockRate(LPC_SSP_T *pSSP, uint32_t clk_rate, uint32_t prescale)
{
	uint32_t temp;
	temp = pSSP->CR0 & (~(SSP_CR0_SCR(0xFF)));
	pSSP->CR0 = temp | (SSP_CR0_SCR(clk_rate));
	pSSP->CPSR = prescale;
}
/*********************************************************************//**
 * @brief 		Setup clock rate for SSP device
 * @param[in] 	SSPx	SSP peripheral definition, should be:
 * 						- LPC_SSP0: SSP0 peripheral
 * 						- LPC_SSP1: SSP1 peripheral
 * @param[in]	target_clock : clock of SSP (Hz)
 * @return 		None
 ***********************************************************************/
static void setSSPclock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock)
{
    uint32_t prescale, cr0_div, cmp_clk, ssp_clk;
    ssp_clk = CLKPWR_GetCLK (CLKPWR_CLKTYPE_PER);

	/* Find closest divider to get at or under the target frequency.
	   Use smallest prescale possible and rely on the divider to get
	   the closest target frequency */
	cr0_div = 0;
	cmp_clk = 0xFFFFFFFF;
	prescale = 2;
	while (cmp_clk > target_clock)
	{
		cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
		if (cmp_clk > target_clock)
		{
			cr0_div++;
			if (cr0_div > 0xFF)
			{
				cr0_div = 0;
				prescale += 2;
			}
		}
	}

    /* Write computed prescaler and divider back to register */
    SSPx->CR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK;
    SSPx->CR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK;
    SSPx->CPSR = prescale & SSP_CPSR_BITMASK;
}
Ejemplo n.º 3
0
/********************************************************************//**
 * @brief		Initializes the SSPx peripheral according to the specified
 *              parameters in the SSP_ConfigStruct.
 * @param[in]	SSPx SSP peripheral selected, should be:
 * 				 	- LPC_SSP0	:SSP0 peripheral
 * 					- LPC_SSP1	:SSP1 peripheral
 * @param[in]	SSP_ConfigStruct Pointer to a SSP_CFG_Type structure that
 * 				contains the configuration information for the specified
 * 				SSP peripheral.
 * @return 		None
 *********************************************************************/
void SSP_Init(LPC_SSPn_Type *SSPx, SSP_CFG_Type *SSP_ConfigStruct)
{
	uint32_t tmp;
	uint32_t prescale, cr0_div, cmp_clk;
	uint64_t ssp_clk;

	CHECK_PARAM(PARAM_SSPx(SSPx));

	if(SSPx == LPC_SSP0) {
		/* Set up clock and power for SSP0 module */
		//LPC_CGU->BASE_SSP0_CLK = (SRC_PL160M_0<<24) | (1<<11);
		CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_SSP0);
	} else if(SSPx == LPC_SSP1) {
		/* Set up clock and power for SSP1 module */
		//LPC_CGU->BASE_SSP1_CLK = (SRC_PL160M_0<<24) | (1<<11);
		CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_SSP1);
	} else {
		return;
	}

	/* Configure SSP, interrupt is disable, LoopBack mode is disable,
	 * SSP is disable, Slave output is disable as default
	 */
	tmp = ((SSP_ConfigStruct->CPHA) | (SSP_ConfigStruct->CPOL) \
		| (SSP_ConfigStruct->FrameFormat) | (SSP_ConfigStruct->Databit))
		& SSP_CR0_BITMASK;
	// write back to SSP control register
	SSPx->CR0 = tmp;

	tmp = SSP_ConfigStruct->Mode & SSP_CR1_BITMASK;
	// Write back to CR1
	SSPx->CR1 = tmp;

	// Set clock rate for SSP peripheral
	if(SSPx == LPC_SSP0)
		ssp_clk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_SSP0);
	else
		ssp_clk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_SSP1);
	cr0_div = 0;
	cmp_clk = 0xFFFFFFFF;
	prescale = 2;
	while (cmp_clk > SSP_ConfigStruct->ClockRate)
	{
		cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
		if (cmp_clk > SSP_ConfigStruct->ClockRate)
		{
			cr0_div++;
			if (cr0_div > 0xFF)
			{
				cr0_div = 0;
				prescale += 2;
			}
		}
	}

    /* Write computed prescaler and divider back to register */
    SSPx->CR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK;
    SSPx->CR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK;
    SSPx->CPSR = prescale & SSP_CPSR_BITMASK;
}
/***********************************************************************
 *
 * Function: ssp_set_clock
 *
 * Purpose: Sets or resets the serial clock rate of the SSP interface
 *          (in Hz)
 *
 * Processing:
 *     Determine the best dividers to generate the closest possible
 *     target clock rate for the SSP.
 *
 * Parameters:
 *     psspdrvdat   : Pointer to driver data
 *     target_clock : The value in Hz for the new SSP serial clock
 *
 * Outputs: None
 *
 * Returns: _ERROR if the configuration setup failed, otherwise _NO_ERROR
 *
 * Notes: None
 *
 **********************************************************************/
static STATUS ssp_set_clock(SSP_DRVDAT_T *psspdrvdat,
                            UNS_32 target_clock)
{
  UNS_32 control, prescale, cr0_div, cmp_clk, ssp_clk;

  /* The SSP clock is derived from the (main system oscillator / 2),
     so compute the best divider from that clock */
  ssp_clk = clkpwr_get_clock_rate(sspclks [psspdrvdat->thisdev]);

  /* Find closest divider to get at or under the target frequency.
     Use smallest prescaler possible and rely on the divider to get
     the closest target frequency */
  cr0_div = 0;
  cmp_clk = 0xFFFFFFFF;
  prescale = 2;
  while (cmp_clk > target_clock)
  {
    cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
    if (cmp_clk > target_clock)
    {
      cr0_div++;
      if (cr0_div > 0xFF)
      {
        cr0_div = 0;
        prescale += 2;
      }
    }
  }

  /* Write computed prescaler and divider back to register */
  control = psspdrvdat->regptr->cr0 &= ~(SSP_CR0_SCR(0xFF));
  psspdrvdat->regptr->cr0 = control | SSP_CR0_SCR(cr0_div - 1);
  psspdrvdat->regptr->cpsr = prescale;

  return _NO_ERROR;
}
Ejemplo n.º 5
0
/********************************************************************//**
 * @brief        Initializes the LPC_SSP0 peripheral according to the specified
*                 parameters in the SSP_ConfigStruct.
 * @param[in]    None
 * @return       None
 *********************************************************************/
void SSP_Init(void)
{
    uint32_t tmp;

    // initialize pinsel for SSP0
    /* MISO0: P0.8 */
    LPC_IOCON->PIO0_8 = PINSEL_PIO_FUNC(1) | PINSEL_PIO_MODE(2);
    /* MOSI0: P0.9 */
    LPC_IOCON->PIO0_9 = PINSEL_PIO_FUNC(1) | PINSEL_PIO_MODE(2);

    /* P0.6 function 2 is SSP clock, need to combined with IOCONSCKLOC register setting */
    LPC_IOCON->SCK_LOC = 0x02;
    LPC_IOCON->PIO0_6 = PINSEL_PIO_FUNC(2) | PINSEL_PIO_MODE(2);

#if USE_CS
    LPC_IOCON->PIO0_2 &= ~0x1F;
    LPC_IOCON->PIO0_2 |= PINSEL_PIO_FUNC(1) | PINSEL_PIO_MODE(2);        /* SSP SSEL */
#else
    /* Enable AHB clock to the GPIO domain. */
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);  
#endif
    /* Reset SSP0 peripheral */
    LPC_SYSCON->PRESETCTRL |= (0x1<<0);
    /* Enable clock for SSP0 */
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11);
    LPC_SYSCON->SSP0CLKDIV = 0x02;
    

    /* Configure SSP, interrupt is disable, LoopBack mode is disable,
     * SSP is disable, Slave output is disable as default
     */
    tmp = ((SSP_CPHA_USED) | (SSP_CPOL_USED) \
            | (SSP_FRAME_SPI) | (SSP_DATA_BIT_USED))
            & SSP_CR0_BITMASK;
    // write back to SSP control register
    LPC_SSP0->CR0 = tmp;
    
    // Write back to CR1
    LPC_SSP0->CR1 = SSP_MASTER_MODE;

    // Set clock rate for SSP peripheral
    LPC_SSP0->CR0 &= (~ SSP_CR0_SCR (0xFF)) & SSP_CR0_BITMASK;
    LPC_SSP0->CR0 |= (SSP_CR0_SCR(0x05)) & SSP_CR0_BITMASK;
    LPC_SSP0->CPSR = 0x02 & SSP_CPSR_BITMASK;

    // SSP Enable
    LPC_SSP0->CR1 |= SSP_CR1_SSP_EN;
}
Ejemplo n.º 6
0
/*********************************************************************//**
 * @brief 		Setup clock rate for SSP device
 * @param[in] 	SSPx	SSP peripheral definition, should be:
 * 						- LPC_SSP0: SSP0 peripheral
 * 						- LPC_SSP1: SSP1 peripheral
 * @param[in]	target_clock : clock of SSP (Hz)
 * @return 		None
 ***********************************************************************/
static void setSSPclock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock)
{
    uint32_t prescale, cr0_div, cmp_clk, ssp_clk;

    CHECK_PARAM(PARAM_SSPx(SSPx));

    /* The SSP clock is derived from the (main system oscillator / 2),
       so compute the best divider from that clock */
    if (SSPx == LPC_SSP0){
    	ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP0);
    } else if (SSPx == LPC_SSP1) {
    	ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP1);
    } else {
    	return;
    }

	/* Find closest divider to get at or under the target frequency.
	   Use smallest prescale possible and rely on the divider to get
	   the closest target frequency */
	cr0_div = 0;
	cmp_clk = 0xFFFFFFFF;
	prescale = 2;
	while (cmp_clk > target_clock)
	{
		cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
		if (cmp_clk > target_clock)
		{
			cr0_div++;
			if (cr0_div > 0xFF)
			{
				cr0_div = 0;
				prescale += 2;
			}
		}
	}

    /* Write computed prescaler and divider back to register */
    SSPx->CR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK;
    SSPx->CR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK;
    SSPx->CPSR = prescale & SSP_CPSR_BITMASK;
}
/***********************************************************************
 *
 * Function: ssp_ioctl
 *
 * Purpose: SSP configuration block
 *
 * Processing:
 *     This function is a large case block. Based on the passed function
 *     and option values, set or get the appropriate SSP parameter.
 *
 * Parameters:
 *     devid: Pointer to SSP config structure
 *     cmd:   ioctl command
 *     arg:   ioctl argument
 *
 * Outputs: None
 *
 * Returns: The status of the ioctl operation
 *
 * Notes: None
 *
 **********************************************************************/
STATUS ssp_ioctl(INT_32 devid,
                 INT_32 cmd,
                 INT_32 arg)
{
  SSP_REGS_T *sspregs;
  SSP_CBS_T *psspcb;
  UNS_32 sspclk, tmp, tmp2;
  SSP_DRVDAT_T *sspdrvdat = (SSP_DRVDAT_T *) devid;
  STATUS status = _ERROR;

  if (sspdrvdat->init == TRUE)
  {
    status = _NO_ERROR;
    sspregs = sspdrvdat->regptr;

    switch (cmd)
    {
      case SSP_ENABLE:
        if (arg == 1)
        {
          /* Enable SSP */
          sspregs->cr1 |= SSP_CR1_SSP_ENABLE;
        }
        else
        {
          /* Disable SSP */
          sspregs->cr1 &= ~SSP_CR1_SSP_ENABLE;
        }
        break;

      case SSP_CONFIG:
        status = ssp_configure((SSP_CONFIG_T *) arg,
                               sspdrvdat);
        break;

      case SSP_ENABLE_LOOPB:
        /* Enable or disable loopback mode */
        if (arg == 1)
        {
          /* Enable SSP loopback mode */
          sspregs->cr1 |= SSP_CR1_LBM;
        }
        else
        {
          /* Disable SSP loopback mode */
          sspregs->cr1 &= ~SSP_CR1_LBM;
        }
        break;

      case SSP_SO_DISABLE:
        /* Slave output disable */
        if (arg != 0)
        {
          sspregs->cr1 |= SSP_CR1_SOD;
        }
        else
        {
          sspregs->cr1 &= ~SSP_CR1_SOD;
        }
        break;

      case SSP_SET_CALLBACKS:
        psspcb = (SSP_CBS_T *) arg;
        sspdrvdat->cbs.txcb = psspcb->txcb;
        sspdrvdat->cbs.rxcb = psspcb->rxcb;
        break;

      case SSP_CLEAR_INTS:
        sspregs->icr = ((UNS_32) arg) &
                       (SSP_ICR_RORIC | SSP_ICR_RTIC);
        break;

      case SSP_GET_STATUS:
        /* Return an SSP status */
        switch (arg)
        {
          case SSP_CLOCK_ST:
            /* Return clock speed of SSP interface */
            tmp = (sspregs->cr0 & SSP_CR0_SCR(0xFF)) >> 8;
            tmp2 = sspregs->cpsr;
            if (tmp2 < 1)
            {
              /* Not a valid value, so use a divider of 1 */
              tmp2 = 1;
            }

            /* Compute SSP bit clock rate */
            sspclk = clkpwr_get_clock_rate(
                       sspclks [sspdrvdat->thisdev]);
            status = sspclk / (tmp2 * (tmp + 1));
            break;

          case SSP_PENDING_INTS_ST:
            status = sspregs->mis;
            break;

          case SSP_RAW_INTS_ST:
            status = sspregs->ris;
            break;

          default:
            /* Unsupported parameter */
            status = LPC_BAD_PARAMS;
            break;
        }
        break;

      default:
        /* Unsupported parameter */
        status = LPC_BAD_PARAMS;
    }
  }
Ejemplo n.º 8
0
/**********************************************
ИНИЦИАЛИЗАЦИЯ СИСТЕМЫ ПРЕРЫВАНИЙ
**********************************************/
void  InitializeInterruptSystem()
{
  /* Initialize interrupt system */
  int_initialize(0xFFFFFFFF);

  /* Install standard IRQ dispatcher at ARM IRQ vector */
  int_install_arm_vec_handler(IRQ_VEC, (PFV) lpc32xx_irq_handler);
  /* Install standard FIQ dispatcher at ARM IRQ vector */
  int_install_arm_vec_handler(FIQ_VEC, (PFV) lpc32xx_fiq_handler);

//---------------------HSTIMER------------------------------------
  /* Install HSTIMER interrupt handler as a IRQ interrupts */
  int_install_irq_handler(IRQ_HSTIMER,
                          (PFV) hstimer_user_interrupt);


  // Save address of register block
  hst_regptr  = HSTIMER;
  gpio_regptr = GPIO;

  // LEDs off
  //gpio_regptr->p3_outp_clr = LED1 | LED2;
  //gpio_regptr->p1_dir_set = LED3;

  // Enable timer system clock
  clkpwr_clk_en_dis(CLKPWR_HSTIMER_CLK, 1);

  // Disable high speed timer and match timers
  hst_regptr->hstim_ctrl = HSTIM_CTRL_RESET_COUNT;
  hst_regptr->hstim_mctrl = 0;
  hst_regptr->hstim_ctrl = 0;

  // Clear pending interrupts
  hst_regptr->hstim_int = (HSTIM_MATCH0_INT |
                           HSTIM_MATCH1_INT | HSTIM_MATCH2_INT |
                           HSTIM_GPI_06_INT | HSTIM_RTC_TICK_INT);

  hst_regptr->hstim_mctrl = HSTIM_CNTR_MCR_MTCH(0) | HSTIM_CNTR_MCR_RESET(0);
  hst_regptr->hstim_pmatch = 13-1;
  hst_regptr->hstim_match[0] = 1000;//1ms 000;

  hst_regptr->hstim_ctrl = HSTIM_CTRL_COUNT_ENAB;//start hstimer

  // Enable interrupt in the interrupt controller
  int_enable(IRQ_HSTIMER);

//---------------------SSP1------------------------------------
  ssp1_regptr = SSP1; // Pointer to SSP1 registers
  // Enable ssp1 system clock
  clkpwr_clk_en_dis(CLKPWR_SSP1_CLK, 1);
  //конфигурация IO
  gpio_regptr->p2_mux_clr = P2_GPIO04_SSEL1;
  gpio_regptr->p2_dir_set = P2_DIR_GPIO(4);
  gpio_regptr->p3_outp_set = P3_STATE_GPIO(4);

  /* The MISO, MOSI, and SCK signals are controlled by the SSP1 */
  gpio_regptr->p_mux_set = (P_SPI2DATAIO_MOSI1 |
                            P_SPI2DATAIN_MISO1 | P_SPI2CLK_SCK1);

  ssp1_regptr->cpsr = SSP_CPSR_CPDVSR(16);//8);//4);//4);//prescale
  //ssp_clk / ((cr0_div + 1) * prescale);
  //prescale = 16; SCR = 4 - 1.25MGz
  ssp1_regptr->cr0 = SSP_CR0_DSS(8) |//data size 8 bit
                     SSP_CR0_FRF_SPI |//Motorola SPI mode
                     SSP_CR0_SCR(4);//serial clock rate

  // Default Master mode
  // Disable SSP1
  ssp1_regptr->cr1 &= ~SSP_CR1_SSP_ENABLE;

  // interr handler SSP1 IRQ
  //int_install_irq_handler(IRQ_SSP1, (PFV) ssp1_user_interrupt);

  // Enable interrupt in the interrupt controller
  //int_enable(IRQ_SSP1);
  // Clear interrupt in the interrupt controller
  //int_clear(IRQ_SSP1);

  // Enable SSP1
  ssp1_regptr->cr1 |= SSP_CR1_SSP_ENABLE;

}//InitializeInterruptSystem()