void spi_receive_block ( uint8_t *buff, /* Data buffer to store received data */ uint16_t byte_count /* Byte count (must be multiple of 4) */ ) { uint16_t hwtr, startcnt, i, rec; hwtr = byte_count/2; if ( byte_count < FIFO_ELEM ) { startcnt = hwtr; } else { startcnt = FIFO_ELEM; } pSPI->CR0 |= SSP_CR0_DSS(16); // DSS to 16 bit for ( i = startcnt; i; i-- ) { pSPI->DR = 0xffff; // fill TX FIFO } do { while ( !(pSPI->SR & SSP_SR_RNE ) ) { // wait for data in RX FIFO (RNE set) } rec = pSPI->DR; if ( i < ( hwtr - startcnt ) ) { pSPI->DR = 0xffff; } *buff++ = (uint8_t)(rec >> 8); *buff++ = (uint8_t)(rec); i++; } while ( i < hwtr ); pSPI->CR0 = ( pSPI->CR0 & ~SSP_CR0_DSS(16) ) | SSP_CR0_DSS(8); // DSS to 8 bit }
void spi_transmit_block ( const uint8_t *buff /* 512 byte data block to be transmitted */ ) { uint16_t cnt; int16_t data; pSPI->CR0 |= SSP_CR0_DSS(16); // DSS to 16 bit for ( cnt = 0; cnt < ( 512 / 2 ); cnt++ ) { while ( !( pSPI->SR & SSP_SR_TNF ) ) { ; // wait for TX FIFO not full (TNF) } data = (*buff++) << 8; data |= *buff++; pSPI->DR = data; } while ( pSPI->SR & SSP_SR_BSY ) { // wait for BSY gone } while ( pSPI->SR & SSP_SR_RNE ) { data = pSPI->DR; // drain receive FIFO } pSPI->CR0 = ( pSPI->CR0 & ~SSP_CR0_DSS(16) ) | SSP_CR0_DSS(8); // DSS to 8 bit }
/*********************************************************************** * * Function: ssp_configure * * Purpose: Configure SSP interface * * Processing: * Setup the general capabilities of the SSP controller. * * Parameters: * psspcfg : Pointer to an SSP_CONFIG_T structure * psspdrvdat: Pointer to driver data * * Outputs: None * * Returns: * _ERROR if the configuration setup failed, otherwise _NO_ERROR * * Notes: None * **********************************************************************/ static STATUS ssp_configure(SSP_CONFIG_T *psspcfg, SSP_DRVDAT_T *psspdrvdat) { UNS_32 tmp0, tmp1; STATUS setup = _NO_ERROR; SSP_REGS_T *psspregs = psspdrvdat->regptr; /* Setup CR0 word first */ tmp0 = 0; if ((psspcfg->databits >= 4) && (psspcfg->databits <= 16)) { tmp0 = SSP_CR0_DSS(psspcfg->databits); } else { setup = _ERROR; } if (psspcfg->databits <= 8) { psspdrvdat->dsize = 1; } else { psspdrvdat->dsize = 2; } /* Mode */ if (((psspcfg->mode & ~SSP_CR0_PRT_MSK) != 0) || (psspcfg->mode == (0x3 << 4))) { setup = _ERROR; } tmp0 |= psspcfg->mode; /* SPI clock control */ if (psspcfg->highclk_spi_frames == TRUE) { tmp0 |= SSP_CR0_CPOL(1); } if (psspcfg->usesecond_clk_spi == TRUE) { tmp0 |= SSP_CR0_CPHA(1); } /* Master/slave mode control */ tmp1 = 0; if (psspcfg->master_mode == FALSE) { tmp1 = SSP_CR1_MS; } /* Setup clock */ if (setup == _NO_ERROR) { psspregs->cr0 = tmp0; psspregs->cr1 = tmp1; setup = ssp_set_clock(psspdrvdat, psspcfg->ssp_clk); } return setup; }
/********************************************** ИНИЦИАЛИЗАЦИЯ СИСТЕМЫ ПРЕРЫВАНИЙ **********************************************/ 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()