BOOL LPC24XX_SPI_Driver::Xaction_Stop( const SPI_CONFIGURATION& Configuration ) { if(g_LPC24XX_SPI_Driver.m_Enabled[Configuration.SPI_mod]) { if(Configuration.CS_Hold_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Hold_uSecs ); } // next, bring the CS to the proper inactive state if(Configuration.DeviceCS != LPC24XX_GPIO::c_Pin_None) { CPU_GPIO_SetPinState( Configuration.DeviceCS, !Configuration.CS_Active ); } g_LPC24XX_SPI_Driver.m_Enabled[Configuration.SPI_mod] = FALSE; } else { lcd_printf("\fSPI Collision 4\r\n"); HARD_BREAKPOINT(); return FALSE; } return TRUE; }
BOOL CPU_SPI_Xaction_Start(const SPI_CONFIGURATION& Configuration) { if (Configuration.SPI_mod >= TOTAL_SPI_PORT) return FALSE; LPC_SSP_T *spi = SPI_REG(Configuration.SPI_mod); int Bits, Mode; // Configure options and clock Bits = (Configuration.MD_16bits) ? 16 : 8; Mode = (Configuration.MSK_IDLE) ? 2 : 0; // ToDo: Check Mode |= (!Configuration.MSK_SampleEdge) ? 1 : 0; SPI_Config(spi, Bits, Mode, 0); SPI_Frequency(spi, (1000 * Configuration.Clock_RateKHz)); // I/O setup GPIO_PIN msk, miso, mosi; CPU_SPI_GetPins(Configuration.SPI_mod, msk, miso, mosi); UINT32 alternate = 0x252; // AF5 = SPI1/SPI2 if (Configuration.SPI_mod == 2) alternate = 0x262; // AF6 = SPI3, speed = 2 (50MHz) CPU_GPIO_DisablePin(msk, RESISTOR_DISABLED, 1, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin(miso, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin(mosi, RESISTOR_DISABLED, 1, (GPIO_ALT_MODE)alternate); // CS setup CPU_GPIO_EnableOutputPin(Configuration.DeviceCS, Configuration.CS_Active); if(Configuration.CS_Setup_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled(Configuration.CS_Setup_uSecs); } return TRUE; }
BOOL SD_GetStatus_WithTimeOut(int timeout) { //while(SD_GetStatus() != SD_TRANSFER_OK); for (;timeout>0; timeout--) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled(1); if (SD_GetStatus() == SD_TRANSFER_OK) return TRUE; } return FALSE; }
BOOL MC9328MXL_LCD_Driver::Uninitialize() { NATIVE_PROFILE_HAL_PROCESSOR_LCD(); HAL_Time_Sleep_MicroSeconds_InterruptEnabled( MC9328_LCD_TIME_POWER_STABLE ); // Wait for LCD charge pumps to shut down CPU_INTC_DeactivateInterrupt( MC9328MXL_AITC::c_IRQ_INDEX_LCDC_INT ); // Turn off LCDC MC9328MXL::LCDC().RMCR = MC9328MXL_LCDC::RMCR__LCDC_EN__DISABLE << MC9328MXL_LCDC::RMCR__LCDC_EN_shift; return TRUE; }
UINT16 AD7466_Driver::Read( INT32 Channel ) { AD7466_CONFIG* Config = &g_AD7466_Config; UINT16 ADC_Value; UINT16 Write16; // select the NO3 on MAX4704 CPU_GPIO_SetPinState( Config->ADMUX_A0_GPIO_PIN, Config->ADMUX_Address[Channel].A0 ); CPU_GPIO_SetPinState( Config->ADMUX_A1_GPIO_PIN, Config->ADMUX_Address[Channel].A1 ); // data that is written is ignored, but reduce energy by keeping output high Write16 = 0xffff; CPU_GPIO_SetPinState( Config->ADMUX_EN_L_GPIO_PIN, FALSE ); // bring enable active (low) // delay 5 uSecs per RAY after enabling MUX to allow inrush current to settle and voltage to stabilize HAL_Time_Sleep_MicroSeconds_InterruptEnabled( 5 ); { // we must ensure a radio operation ISR doesn't intervene - keep this short! GLOBAL_LOCK(irq); // W // R CPU_SPI_Xaction_Start( Config->SPI_Config ); { SPI_XACTION_16 Transaction; Transaction.Read16 = &ADC_Value; Transaction.ReadCount = 1; Transaction.ReadStartOffset = 1-1; Transaction.Write16 = &Write16; Transaction.WriteCount = 1; CPU_SPI_Xaction_nWrite16_nRead16( Transaction ); } CPU_SPI_Xaction_Stop( Config->SPI_Config ); } CPU_GPIO_SetPinState( Config->ADMUX_EN_L_GPIO_PIN, TRUE ); // bring enable inactive (high) // scale down by 1 bit, since this is how it returns the result ADC_Value >>= 1; return ADC_Value; }
BOOL CPU_SPI_Xaction_Start( const SPI_CONFIGURATION& Configuration ) { NATIVE_PROFILE_HAL_PROCESSOR_SPI(); if (Configuration.SPI_mod >= STM32F4_SPI_MODS) return FALSE; // CS setup CPU_GPIO_EnableOutputPin( Configuration.DeviceCS, Configuration.CS_Active ); if(Configuration.CS_Setup_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Setup_uSecs ); } // I/O setup GPIO_PIN msk, miso, mosi; CPU_SPI_GetPins(Configuration.SPI_mod, msk, miso, mosi); UINT32 alternate = 0x252; // AF5 = SPI1/SPI2 if (Configuration.SPI_mod == 2) alternate = 0x262; // AF6 = SPI3, speed = 2 (50MHz) CPU_GPIO_DisablePin( msk, RESISTOR_DISABLED, 1, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin( miso, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin( mosi, RESISTOR_DISABLED, 1, (GPIO_ALT_MODE)alternate); switch (Configuration.SPI_mod) { case 0: RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; break; // enable SPI1 clock case 1: RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; break; // enable SPI2 clock case 2: RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; break; // enable SPI3 clock } ptr_SPI_TypeDef spi = g_STM32_Spi_Port[Configuration.SPI_mod]; // set mode bits UINT32 cr1 = SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_MSTR | SPI_CR1_SPE; if (Configuration.MD_16bits) cr1 |= SPI_CR1_DFF; if (Configuration.MSK_IDLE) cr1 |= SPI_CR1_CPOL | SPI_CR1_CPHA; if (!Configuration.MSK_SampleEdge) cr1 ^= SPI_CR1_CPHA; // toggle phase // set clock prescaler UINT32 clock = SYSTEM_APB2_CLOCK_HZ / 2000; // SPI1 on APB2 if (Configuration.SPI_mod != 0) clock = SYSTEM_APB1_CLOCK_HZ / 2000; // SPI2/3 on APB1 if (clock > Configuration.Clock_RateKHz << 3) { clock >>= 4; cr1 |= SPI_CR1_BR_2; }
BOOL CPU_SPI_Xaction_Stop(const SPI_CONFIGURATION& Configuration) { LPC_SSP_T *spi = SPI_REG(Configuration.SPI_mod); while (SPI_Busy(spi)); // wait for completion if(Configuration.CS_Hold_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled(Configuration.CS_Hold_uSecs); } CPU_GPIO_SetPinState(Configuration.DeviceCS, !Configuration.CS_Active); GPIO_RESISTOR res = RESISTOR_PULLDOWN; if (Configuration.MSK_IDLE) res = RESISTOR_PULLUP; GPIO_PIN msk, miso, mosi; CPU_SPI_GetPins(Configuration.SPI_mod, msk, miso, mosi); CPU_GPIO_EnableInputPin(msk, FALSE, NULL, GPIO_INT_NONE, res); CPU_GPIO_EnableInputPin(miso, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLDOWN); CPU_GPIO_EnableInputPin(mosi, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLDOWN); SPI_Disable(spi); // Disable SPI return TRUE; }
INT32 AT91_Analog_Driver::Read( ANALOG_CHANNEL channel ) { INT32 total = 0; unsigned long arrayValuesToSort[MAX_AVERAGE_AMOUNT]; unsigned long valueToStoreInArray; // get the values for(int i = 0; i < MAX_AVERAGE_AMOUNT; i++) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled(5); //return *Analog_DataRegister[channel]; //total += *Analog_DataRegister[channel]; valueToStoreInArray = *Analog_DataRegister[channel]; arrayValuesToSort[i] = valueToStoreInArray; } sortArray(arrayValuesToSort); return averageMiddleThreeValues(arrayValuesToSort); //total /= MAX_AVERAGE_AMOUNT; //return total; }
BOOL LPC24XX_SPI_Driver::Xaction_Start( const SPI_CONFIGURATION& Configuration ) { if(!g_LPC24XX_SPI_Driver.m_Enabled[Configuration.SPI_mod]) { g_LPC24XX_SPI_Driver.m_Enabled[Configuration.SPI_mod] = TRUE; UINT32 index = Configuration.SPI_mod; LPC24XX_SPI & SPI = LPC24XX::SPI(index); // first build the mode register SPI.SPCR = LPC24XX_SPI::ConfigurationToMode( Configuration ); // Set SPI Clock SPI.SPCCR = LPC24XX_SPI::c_SPI_Clk_KHz / (Configuration.Clock_RateKHz); // first set CS active as soon as clock and data pins are in proper initial state if(Configuration.DeviceCS != LPC24XX_GPIO::c_Pin_None) { CPU_GPIO_EnableOutputPin( Configuration.DeviceCS, Configuration.CS_Active ); } if(Configuration.CS_Setup_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Setup_uSecs ); } } else { lcd_printf( "\fSPI Collision 3\r\n" ); HARD_BREAKPOINT(); return FALSE; } return TRUE; }
BOOL MC9328MXL_SPI_Driver::Xaction_Stop( const SPI_CONFIGURATION& Configuration ) { NATIVE_PROFILE_HAL_PROCESSOR_SPI(); if(g_MC9328MXL_SPI_Driver.m_Enabled[Configuration.SPI_mod]) { UINT32 index = Configuration.SPI_mod; MC9328MXL_SPI & SPI = MC9328MXL::SPI(index); // we should have cleared the last TBF on the last RBF true setting // we should never bring CS inactive with the shifter busy ASSERT( SPI.TransmitBufferEmpty()); ASSERT( SPI.ReceiveBufferEmpty ()); ASSERT( SPI.ShiftBufferEmpty ()); if(Configuration.CS_Hold_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Hold_uSecs ); } // avoid noise drawing excess power on a floating line by putting this in pulldown #if defined(PLATFORM_ARM_MC9328MXS) CPU_GPIO_EnableInputPin( MC9328MXL_SPI::c_SPI1_MISO, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLUP ); #else if (index == MC9328MXL_SPI::c_SPI1) { CPU_GPIO_EnableInputPin( MC9328MXL_SPI::c_SPI1_MISO, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLUP ); } else { CPU_GPIO_EnableInputPin( MC9328MXL_SPI::c_SPI2_MISO, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLUP ); } #endif // next, bring the CS to the proper inactive state if((Configuration.DeviceCS != MC9328MXL_GPIO::c_Pin_None) && (Configuration.DeviceCS != MC9328MXL_SPI::c_SPI1_SS)) { CPU_GPIO_SetPinState( Configuration.DeviceCS, !Configuration.CS_Active ); } // make sure that we don't trigger the SS pin for LCD on the iMXS board, this may change if Freescale change their circuitry // can remove if not use on imxs platform // be safe, as LCD SPI access will use this function as well, set it back to Output #if (HARDWARE_BOARD_TYPE >= HARDWARE_BOARD_i_MXS_DEMO_REV_V1_2) CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_SS, TRUE ); #endif // put pins in output low state when not in use to avoid noise since clock stop and reset will cause these to become inputs #if defined(PLATFORM_ARM_MC9328MXS) CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_SCLK, FALSE ); CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_MOSI, FALSE ); #else if (index == MC9328MXL_SPI::c_SPI1) { CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_SCLK, FALSE ); CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_MOSI, FALSE ); } else { CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI2_SCLK, FALSE ); CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI2_MOSI, FALSE ); } #endif // off SPI module SPI.CONTROLREG &= ~SPI.CONTROLREG_SPIEN; g_MC9328MXL_SPI_Driver.m_Enabled[Configuration.SPI_mod] = FALSE; } else { lcd_printf("\fSPI Collision 4\r\n"); HARD_BREAKPOINT(); return FALSE; } return TRUE; }
BOOL MC9328MXL_SPI_Driver::Xaction_Start( const SPI_CONFIGURATION& Configuration ) { NATIVE_PROFILE_HAL_PROCESSOR_SPI(); if(!g_MC9328MXL_SPI_Driver.m_Enabled[Configuration.SPI_mod]) { g_MC9328MXL_SPI_Driver.m_Enabled[Configuration.SPI_mod] = TRUE; UINT32 index = Configuration.SPI_mod; MC9328MXL_SPI & SPI = MC9328MXL::SPI(index); // make sure we didn't start one in the middle of an existing transaction if( SPI.CONTROLREG & SPI.CONTROLREG_SPIEN ) { lcd_printf("\fSPI Collision 1\r\n"); hal_printf("\fSPI Collision 1\r\n"); HARD_BREAKPOINT(); return FALSE; } // first build the mode register SPI.CONTROLREG = MC9328MXL_SPI::ConfigurationToMode( Configuration ); // LCD Controller needs to have Pulse mode enabled #if (HARDWARE_BOARD_TYPE >= HARDWARE_BOARD_i_MXS_DEMO_REV_V1_2) if(Configuration.DeviceCS == MC9328MXL_SPI::c_SPI1_SS) { SPI.PERIODREG = 2; SPI.CONTROLREG |= MC9328MXL_SPI::CONTROLREG_SSCTL_PULSE; // Pulse SS between bursts // set the SSPOL to active lo as it is force at the ConfigurationMOde to not trigger SS for other SPI operation SPI.CONTROLREG &= (~MC9328MXL_SPI::CONTROLREG_SSPOL_HIGH); // Pulse SS between bursts CPU_GPIO_DisablePin( MC9328MXL_SPI::c_SPI1_SS,RESISTOR_DISABLED, 0, GPIO_ALT_PRIMARY); } #endif SPI.CONTROLREG |= MC9328MXL_SPI::CONTROLREG_SPIEN; #if (SPI_LOOP_BACK) // for spi testing SPI.TESTREG |= SPI.TESTREG_LBC; #endif // everything should be clean and idle ASSERT( SPI.TransmitBufferEmpty()); ASSERT( SPI.ReceiveBufferEmpty()); ASSERT( SPI.ShiftBufferEmpty ()); // make sure not trigger the SS pin for the LCD when doing any SPI activity. // but we can have LCD SPI activity, if so, we want the SS be able to drive #if (HARDWARE_BOARD_TYPE >= HARDWARE_BOARD_i_MXS_DEMO_REV_V1_2) if(Configuration.DeviceCS != MC9328MXL_SPI::c_SPI1_SS) { CPU_GPIO_EnableInputPin( MC9328MXL_SPI::c_SPI1_SS, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLUP ); } #endif #if defined(PLATFORM_ARM_MC9328MXS) // make sure that we don't trigger the SS pin for LCD CPU_GPIO_DisablePin( MC9328MXL_SPI::c_SPI1_SCLK, RESISTOR_DISABLED, 0, GPIO_ALT_PRIMARY); CPU_GPIO_DisablePin( MC9328MXL_SPI::c_SPI1_MOSI, RESISTOR_DISABLED, 0, GPIO_ALT_PRIMARY); #else // MC9328MXL if (index == MC9328MXL_SPI::c_SPI1) { // allow peripheral control of pins CPU_GPIO_DisablePin( MC9328MXL_SPI::c_SPI1_SCLK, RESISTOR_DISABLED, 0, GPIO_ALT_PRIMARY); CPU_GPIO_DisablePin( MC9328MXL_SPI::c_SPI1_MOSI, RESISTOR_DISABLED, 0, GPIO_ALT_PRIMARY); } else { // SPI2 need to set to Alternate function - AIN CPU_GPIO_DisablePin(MC9328MXL_SPI::c_SPI2_SCLK, RESISTOR_DISABLED, MC9328MXL_GPIO::DDIR__OUT, GPIO_ALT_MODE_1); CPU_GPIO_DisablePin(MC9328MXL_SPI::c_SPI2_MOSI, RESISTOR_DISABLED, MC9328MXL_GPIO::DDIR__OUT, GPIO_ALT_MODE_1); } #endif // first set CS active as soon as clock and data pins are in proper initial state if((Configuration.DeviceCS != MC9328MXL_GPIO::c_Pin_None) && (Configuration.DeviceCS != MC9328MXL_SPI::c_SPI1_SS)) { CPU_GPIO_EnableOutputPin( Configuration.DeviceCS, Configuration.CS_Active ); } #if defined(PLATFORM_ARM_MC9328MXS) CPU_GPIO_DisablePin( MC9328MXL_SPI::c_SPI1_MISO, RESISTOR_DISABLED, 0, GPIO_ALT_PRIMARY ); #else if (index == MC9328MXL_SPI::c_SPI1) { CPU_GPIO_DisablePin( MC9328MXL_SPI::c_SPI1_MISO, RESISTOR_DISABLED, 0, GPIO_ALT_PRIMARY ); } else { // set AOUT mode for MISO for SPI 2 CPU_GPIO_DisablePin(MC9328MXL_SPI::c_SPI2_MISO, RESISTOR_DISABLED,MC9328MXL_GPIO::DDIR__IN ,GPIO_ALT_MODE_4); MC9328MXL::SC().FMCR |= MC9328MXL_SC::FMCR__SPI2_RXD_SEL; } #endif if(Configuration.CS_Setup_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Setup_uSecs ); } } else { lcd_printf( "\fSPI Collision 3\r\n" ); HARD_BREAKPOINT(); return FALSE; } return TRUE; }
BOOL PXA271_SPI_Driver::Xaction_Stop( const SPI_CONFIGURATION& Configuration ) { if(g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].m_Enabled) { PXA271_SPI& SPI = PXA271::SPI(Configuration.SPI_mod); // we should have cleared the last TBF on the last RBF true setting // we should never bring CS inactive with the shifter busy ASSERT(!SPI.TransmitFifoNotEmpty()); ASSERT( SPI.ReceiveFifoEmpty()); ASSERT( SPI.ShiftBufferEmpty()); if(Configuration.CS_Hold_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Hold_uSecs ); } // avoid noise drawing excess power on a floating line by putting this in pulldown if(Configuration.SPI_mod ==0) CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].RXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_IN,GPIO_ALT_MODE_1); else if(Configuration.SPI_mod ==1) CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].RXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_IN,GPIO_ALT_MODE_2); else CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].RXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_IN,GPIO_ALT_MODE_3); // next, bring the CS to the proper inactive state if(Configuration.DeviceCS != PXA271_GPIO::c_Pin_None) { CPU_GPIO_EnableOutputPin(Configuration.DeviceCS, !Configuration.CS_Active); } // put pins in output low state when not in use to avoid noise since clock stop and reset will cause these to become inputs if(Configuration.SPI_mod ==0) { //allow peripheral control of pins; CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].CLK_pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_2); CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].TXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_2); } else if(Configuration.SPI_mod ==1) { //allow peripheral control of pins; CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].CLK_pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_2); CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].TXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_2); } else { //allow peripheral control of pins; CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].CLK_pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_3); CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].TXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_3); } // disable spi bus so no new operations start SPI.SSP_SSCR0 = 0; SPI.SSP_SSCR1 = 0; PXA271::CLKMNGR().CKEN &= ~g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].ClockIndex; g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].m_Enabled = FALSE; } else { lcd_printf("\fSPI Collision 4\r\n"); HARD_BREAKPOINT(); return FALSE; } return TRUE; }
BOOL PXA271_SPI_Driver::Xaction_Start( const SPI_CONFIGURATION& Configuration ) { if(!g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].m_Enabled) { g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].m_Enabled= TRUE; // enable the Periperal clock for this device PXA271::CLKMNGR().CKEN |= g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].ClockIndex; PXA271_SPI& SPI = PXA271::SPI(Configuration.SPI_mod); // make sure we didn't start one in the middle of an existing transaction if((0 != SPI.SSP_SSCR0)||(0 != SPI.SSP_SSCR1)) { lcd_printf("\fSPI Collision 1\r\n"); HARD_BREAKPOINT(); return FALSE; } SPI.SSP_SSCR0= PXA271_SPI::ConfigurationControlReg0( Configuration ); SPI.SSP_SSCR1= PXA271_SPI::ConfigurationControlReg1( Configuration ); #ifdef SPI_LOOP_BACK_PXA271 SPI.SSP_SSCR1|= SPI_LOOPBACK; #endif SPI.SSP_SSCR0|= SPI.SSP_SSCR0__SSE; //everything should be clean and idle ASSERT(!SPI.TransmitFifoNotEmpty()); ASSERT( SPI.ReceiveFifoEmpty()); ASSERT( SPI.ShiftBufferEmpty()); if(Configuration.SPI_mod ==0) { //allow peripheral control of pins; CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].CLK_pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_2); CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].TXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_2); } else if(Configuration.SPI_mod ==1) { //allow peripheral control of pins; CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].CLK_pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_2); CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].TXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_2); } else { //allow peripheral control of pins; CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].CLK_pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_3); CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].TXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_OUT,GPIO_ALT_MODE_3); } // first set CS active as soon as clock and data pins are in proper initial state if(Configuration.DeviceCS != PXA271_GPIO::c_Pin_None) { CPU_GPIO_EnableOutputPin(Configuration.DeviceCS, Configuration.CS_Active); } if(Configuration.SPI_mod ==0) CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].RXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_IN,GPIO_ALT_MODE_1); else if(Configuration.SPI_mod ==1) CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].RXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_IN,GPIO_ALT_MODE_2); else CPU_GPIO_DisablePin( g_PXA271_SPI_Driver.s_All_SPI_port[Configuration.SPI_mod].RXD_Pin, RESISTOR_DISABLED, PXA271_GPIO::GPDR__DIR_IN,GPIO_ALT_MODE_3); if(Configuration.CS_Setup_uSecs) { HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Setup_uSecs ); } } else { lcd_printf( "\fSPI Collision 3\r\n" ); HARD_BREAKPOINT(); return FALSE; } return TRUE; }
BOOL USART_Driver::Flush( int ComPortNum ) { NATIVE_PROFILE_PAL_COM(); if((ComPortNum < 0) || (ComPortNum >= TOTAL_USART_PORT)) {ASSERT(FALSE); return FALSE;} HAL_USART_STATE& State = Hal_Usart_State[ComPortNum]; if ( IS_POWERSAVE_ENABLED(State) || (!IS_USART_INITIALIZED(State))) return TRUE; UINT32 IrqId = USART_TX_IRQ_INDEX(ComPortNum); if ((USART_FLAG_STATE(State, HAL_USART_STATE::c_TX_SWFLOW_CTRL) && (!USART_FLAG_STATE(State, HAL_USART_STATE::c_TX_XON_STATE))) || !CPU_USART_TxHandshakeEnabledState(ComPortNum)) { return FALSE; } // 3 cases: IRQs off, IRQs on and TXINT off, IRQs on and TXINT on // treat first 2 as same (it kills ISR latency when the buffer is full) { GLOBAL_LOCK(irq); if(irq.WasDisabled() || !CPU_USART_TxBufferEmptyInterruptState( ComPortNum ) || 0 == CPU_INTC_InterruptEnableState( IrqId )) { while(State.TxQueue.IsEmpty() == false) { char c; // this could happen while we are spinning, if so drop everything and return if (IS_POWERSAVE_ENABLED(State) || !CPU_USART_TxHandshakeEnabledState(ComPortNum)) { return FALSE; } // wait for a place to put the character while(!CPU_USART_TxBufferEmpty( ComPortNum )) { // The TxBuffer will never be empty as long as the handshake is preventing // the character from being sent if(!CPU_USART_TxHandshakeEnabledState(ComPortNum)) return FALSE; } // get next character RemoveCharFromTxBuffer( ComPortNum, c ); // ok, put in Transmit holding register CPU_USART_WriteCharToTxBuffer( ComPortNum, c ); // this loop waits ~100uS per character out at 115200 baud, // so it can take a long time to clear the whole queue irq.Probe(); } } else { // all requisite interrupts on, just wait for the buffer to empty naturally while(State.TxQueue.IsEmpty() == false) { // this could happen while we are spinning, if so drop everything and return if(IS_POWERSAVE_ENABLED(State) || !CPU_USART_TxHandshakeEnabledState(ComPortNum)) { return FALSE; } irq.Release(); // 1mSec time should be plenty = 1 characters at 9600 baud // 9600 bps / (8bits * 1000ms/s) HAL_Time_Sleep_MicroSeconds_InterruptEnabled(1000); // critical section queue irq.Acquire(); } } } if(IS_POWERSAVE_ENABLED(State)) { return FALSE; } // wait for the holding register to empty while(!CPU_USART_TxBufferEmpty( ComPortNum ) && CPU_USART_TxHandshakeEnabledState(ComPortNum)); // also wait for shift register to empty while(!CPU_USART_TxShiftRegisterEmpty( ComPortNum ) && CPU_USART_TxHandshakeEnabledState(ComPortNum)); // now, all characters have been transmitted return TRUE; }
void ApplicationEntryPoint() { #if defined(TEST_DAC) UINT32 FramesNum = g_LPC24XX_DAC_Driver.GetBufferFrameCapacity(); if (DAC_FRAME_BUFFERS_NUM!=FramesNum) { debug_printf( "Error, BufferFrameCapacity != DAC_FRAME_BUFFERS_NUM: %d != %d.\r\n", FramesNum, DAC_FRAME_BUFFERS_NUM ); } UINT32 nextInFrameOffset=0; UINT16 frameLength = MAX_DECODED_FRAME_SIZE/2; short* frameSignedStart = NULL; LPC24XX_VIC& VIC = LPC24XX::VIC(); /*debug_printf("VIC INTRSEL = 0x%08x\r\n", VIC.INTRSEL); VIC.INTRSEL |= 1 << LPC24XX_TIMER::getIntNo(LPC24XX_DAC::Timer); debug_printf("new VIC INTRSEL = 0x%08x\r\n", VIC.INTRSEL);*/ VIC.VECTPRIORITY[LPC24XX_TIMER::getIntNo(LPC24XX_DAC::Timer)] = 0; for(int i= 0; i< 32; i++) { debug_printf("PRIO INTR%02d = %d \r\n", i,VIC.VECTPRIORITY[i]); } debug_printf( "Init DAC, 8kHz output.\r\n" ); g_LPC24XX_DAC_Driver.Initialize(OUT_FREQ); debug_printf( "BUFFER PRE-FILL TEST.\r\n" ); debug_printf( "Adding frames to the DAC driver buffer: " ); debug_printf("total frames to be added = %d\r\n", TEST_SAMPLES_NUM/MAX_DECODED_FRAME_SIZE-CUTOUT); debug_printf("DAC frame buffers available = %d\r\n", DAC_FRAME_BUFFERS_NUM); if(DAC_FRAME_BUFFERS_NUM<(TEST_SAMPLES_NUM/MAX_DECODED_FRAME_SIZE-CUTOUT)) debug_printf("ONLY THE FIRST %d FRAMES OF THE SAMPLE WILL BE PLAYED.\r\n", DAC_FRAME_BUFFERS_NUM); while(nextInFrameOffset+(MAX_DECODED_FRAME_SIZE*CUTOUT) < TEST_SAMPLES_NUM) { //if(i%(1024*256)) continue; frameSignedStart = (short*)(bin_data+nextInFrameOffset); if(g_LPC24XX_DAC_Driver.AddFrame(frameSignedStart, frameLength)) { debug_printf( " done.\r\n" ); nextInFrameOffset+=MAX_DECODED_FRAME_SIZE; } else { debug_printf( "Buffer full, starting playout.\r\n"); break; } } resetDACISRTiming(); debug_printf( "DAC.On() in 2 seconds\r\n"); Events_WaitForEvents( 0, 2000 ); if(!hijackISRs()) return; if(g_LPC24XX_DAC_Driver.On()) { //debug_printf( "Done. 2sec wait.\r\n" ); don't output to avoid adding serial activity during the test } else { debug_printf( "FAILED.\r\n" ); } while(g_LPC24XX_DAC_Driver.GetBufferLevel()>0) { //debug_printf("Samples left: %d\r\n", g_LPC24XX_DAC_Driver.GetBufferLevel()); //debug_printf("Frames left: %d\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); } //stop logging interrupts before starting to output again int finalIrqCount = irq_count; irq_count = 8192; Events_WaitForEvents( 0, 5000 ); if(!restoreISRs()) return; debug_printf("%d frames left.\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); debug_printf("Final IRQ count = %u\r\n", finalIrqCount); debug_printf( "BUFFER PRE-FILL TEST OVER.\r\n"); displayRunTestResults(); debug_printf("CSV DATA OUTPUT FOLLOWS\r\n"); //csvRunTestResults(); debug_printf("\r\nPARALLEL BUFFER FILL TEST\r\n" ); Events_WaitForEvents( 0, 3000 ); debug_printf( "DAC.Off()\r\n"); if(g_LPC24XX_DAC_Driver.Off()) { debug_printf( "Done.\r\n" ); } else { debug_printf( "FAILED.\r\n" ); } debug_printf( "Uninit DAC\r\n"); g_LPC24XX_DAC_Driver.Uninitialize(); debug_printf( "Done.\r\n"); debug_printf( "Init DAC, 8kHz output.\r\n" ); g_LPC24XX_DAC_Driver.Initialize(OUT_FREQ); resetDACISRTiming(); debug_printf( "DAC.On() in 2 seconds\r\n"); Events_WaitForEvents( 0, 2000 ); if(g_LPC24XX_DAC_Driver.On()) { //debug_printf( "Done.\r\n" ); } else { debug_printf( "FAILED.\r\n" ); } debug_printf( "Adding frames to the DAC driver buffer: " ); nextInFrameOffset=0; debug_printf("total frames to be added = %d\r\n", TEST_SAMPLES_NUM/MAX_DECODED_FRAME_SIZE-CUTOUT); //FILL JUST ONCE while(nextInFrameOffset+(MAX_DECODED_FRAME_SIZE*CUTOUT) < TEST_SAMPLES_NUM) { //if(i%(1024*256)) continue; frameSignedStart = (short*)(bin_data+nextInFrameOffset); if(g_LPC24XX_DAC_Driver.AddFrame(frameSignedStart, frameLength)) { debug_printf( " done.\r\n" ); nextInFrameOffset+=MAX_DECODED_FRAME_SIZE; } else { //debug_printf( "FAIL.\r\n"); } } while(g_LPC24XX_DAC_Driver.GetBufferLevel()>0) { //debug_printf("Samples left: %d\r\n", g_LPC24XX_DAC_Driver.GetBufferLevel()); //debug_printf("Frames left: %d\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); } Events_WaitForEvents( 0, 3000 ); displayRunTestResults(); debug_printf("CSV DATA OUTPUT FOLLOWS\r\n"); csvRunTestResults(); /*CONTINUOUS REFILL with samples while(true) { //if(i%(1024*256)) continue; frameSignedStart = (short*)(bin_data+nextInFrameOffset); if(g_LPC24XX_DAC_Driver.AddFrame(frameSignedStart, frameLength)) { //debug_printf( " done.\r\n" ); nextInFrameOffset+=MAX_DECODED_FRAME_SIZE; if(nextInFrameOffset+(MAX_DECODED_FRAME_SIZE*CUTOUT)>=TEST_SAMPLES_NUM) nextInFrameOffset = 0; } else { //debug_printf( "FAIL.\r\n"); } debug_printf("Samples left: %d\r\n", g_LPC24XX_DAC_Driver.GetBufferLevel()); debug_printf("Frames left: %d\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); }*///end continuous refill debug_printf("%d frames left.\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); debug_printf( "PARALLEL BUFFER FILL TEST OVER.\r\n\r\n" ); //Events_WaitForEvents( 0, 10000 ); debug_printf( "DAC.Off()\r\n"); if(g_LPC24XX_DAC_Driver.Off()) { debug_printf( "Done.\r\n" ); } else { debug_printf( "FAILED.\r\n" ); } debug_printf( "Uninit DAC()\r\n"); g_LPC24XX_DAC_Driver.Uninitialize(); debug_printf( "Done.\r\n"); #endif #if defined(TEST_JOYSTICK) extern LPC24XX_GPIO_Driver g_LPC24XX_GPIO_Driver; wait_joystick = true; for(UINT32 pin = LPC24XX_GPIO::c_P2_22; pin < LPC24XX_GPIO::c_P2_28; pin++) { if(pin == LPC24XX_GPIO::c_P2_24) continue; if(!g_LPC24XX_GPIO_Driver.EnableInputPin( pin, false, joystickISR, NULL, GPIO_INT_EDGE_HIGH, (GPIO_RESISTOR)2 )) { debug_printf("Cannot enable pin %u as INPUT pin.\r\n", pin); exit(1); } debug_printf("Enabled pin %u as INPUT pin.\r\n", pin); } while(wait_joystick) {}; #endif #if defined(TEST_SST39WF) while(1) { lcd_printf ( "Hello, world from the LCD!\r\n" ); hal_printf ( "Hello, world from the HAL!\r\n" ); debug_printf( "Hello, world from the debug intf!\r\n" ); if(BlockStorageList::GetNumDevices() != 1) { debug_printf( "%d Block Devices present!\r\n", BlockStorageList::GetNumDevices() ); break; } BlockStorageDevice* SST = BlockStorageList::GetFirstDevice(); if(SST == NULL) { debug_printf( "GetFirstDevice failed.\r\n" ); break; } const BlockDeviceInfo* SSTInfo = SST->GetDeviceInfo(); if(SSTInfo == NULL) { debug_printf( "GetDeviceInfo failed.\r\n" ); break; } debug_printf( "NumRegions in BSDevice: %d\r\n", SSTInfo->NumRegions); ByteAddress PhyAddress = (ByteAddress) 0xC0FFEEEE; SectorAddress SectAddress = 0xC0FFEEEE; UINT32 RangeIndex; UINT32 RegionIndex; const BlockRegionInfo *pBlockRegionInfo; SST->FindForBlockUsage( /*UINT32*/ BlockRange::BLOCKTYPE_DEPLOYMENT , PhyAddress , RegionIndex, RangeIndex ); if(PhyAddress == 0xC0FFEEEE) { debug_printf( "FindForBlockUsage failed.\r\n" ); break; } debug_printf( "Sector 0x%08x physical address: 0x%08x\r\n", SectAddress, PhyAddress); BYTE pSectorBuf[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; //ERASE before writing! if(!SST->IsBlockErased(PhyAddress, 0x1000)) { debug_printf( "Erasing block " ); if(!SST->EraseBlock(SectAddress)) { debug_printf( "failed.\r\n" ); break; } debug_printf( "successful.\r\n" ); } if(SST->Write(/*UINT32*/ PhyAddress, /*UINT32 NumOfBytes*/ 16, /*BYTE* */ pSectorBuf, /*SectorMetadata* */ FALSE)) debug_printf( "Correctly written 16 bytes to Sector 0x%08x\r\n", SectAddress); Events_WaitForEvents( 0, 2000 ); } #endif //TEST_SST39WF #if defined(TEST_PWM) PWM_Initialize(PWM_CHANNEL_0); // NOTE: on the EA_LPC2478 board the first pin we will return is the 11th pin on the left side from the top of the J1 connector GPIO_PIN pin = PWM_GetPinForChannel( PWM_CHANNEL_0 ); // from 90% to 2/3, to 50%, to 1/3 to 10% float dc[5] = { 0.9, 0.666, 0.5, 0.333, 0.1 }; UINT32 period1 = 1000; // 1Kxz for(UINT32 idx = 0; idx < 5; ++idx) { UINT32 duration1 = (UINT32)((float)period1 * dc[idx]); PWM_ApplyConfiguration( PWM_CHANNEL_0, pin, period1, duration1, FALSE); PWM_Start ( PWM_CHANNEL_0, pin ); // 2 secs, then change HAL_Time_Sleep_MicroSeconds_InterruptEnabled(1 * 1000 * 1000); //Events_WaitForEvents( 0, 2 * 1000); PWM_Stop ( PWM_CHANNEL_0, pin ); } // from 10Khz to 1Khz, 50% duty cycle for(UINT32 period = 10000; period >= 1000; period -= 1000) { UINT32 duration = period / 2; PWM_ApplyConfiguration( PWM_CHANNEL_0, pin, period, duration, FALSE); PWM_Start ( PWM_CHANNEL_0, pin ); // 2 secs, then change HAL_Time_Sleep_MicroSeconds_InterruptEnabled(1 * 1000 * 1000); //Events_WaitForEvents( 0, 2 * 1000); PWM_Stop ( PWM_CHANNEL_0, pin ); } PWM_Uninitialize(PWM_CHANNEL_0); #endif // TEST_PWM while(1) { lcd_printf ( "Hello, world!\r\n" ); hal_printf ( "Hello, world!\r\n" ); debug_printf( "Hello, world!\r\n" ); Events_WaitForEvents( 0, 1000 ); } }