Hello Vikram I am not sure how much of the other tasks being active is required to cause the issue to occur. I haven't cut my code back to a minimum to see at what point it will operate correctly and at what point it will fail. Below is the function call that locks up and freezes waiting for the SPI_Transfer to complete. If I set the transferTimeout to say 1000 I will see intermittent 1000ms pauses in my animation. This task that is freezing is simply updating the LCD write buffer and writing that to the display. This gives me animated icons for the operator, so it is easy to see the freezing. If I leave transferTimeout at 0 the LCD task will just halt and the other tasks all run fine. I am not using the callback function for transfer complete. When the task halts it will be waiting for the transfer complete mutex. Below is how I initialise the SPI and how I call it and all my SPI initialisation tables in my board definition. Whilst I setup for 3 possible SSI only the serial flash and the LCD are used. The serial flash only runs a few times at start up to check the flash is present as I haven't finished the flash code yet. LCD runs continuously on a 50ms update. //***************************************************************************** // LCD SPI interface items //***************************************************************************** static SPI_Handle LCD_SPI; static SPI_Transaction lcdTransaction; static UChar lcdRxBuffer[MAX_LCD_WR]; UInt lcdTransferOK; #ifdef ST7565_DIRTY_PAGES uint8_t ST7565_dirty_pages; #endif //***************************************************************************** // Writes a data word to the LCD. //***************************************************************************** static void WriteBLock ( UChar * ui8Data, UChar Size) { // Address HIGH - DATA SetLCD_A0; // Limit to size of buffer if (Size > MAX_LCD_WR) Size = MAX_LCD_WR; // Initialise LCD SPI transaction structure lcdTransaction. count = Size; lcdTransaction. txBuf = ( Ptr )ui8Data; lcdTransaction. rxBuf = ( Ptr )lcdRxBuffer; // Initiate SPI transfer lcdTransferOK = SPI_transfer (LCD_SPI, &lcdTransaction); } //***************************************************************************** // Writes a command byte to the LCD. //***************************************************************************** static void WriteCommand ( uint8_t ui8Data) { // Address LOW - COMMAND ClrLCD_A0; // Initialise LCD SPI transaction structure lcdTransaction. count = 1; lcdTransaction. txBuf = ( Ptr )&ui8Data; lcdTransaction. rxBuf = ( Ptr )lcdRxBuffer; // Initiate SPI transfer lcdTransferOK = SPI_transfer (LCD_SPI, &lcdTransaction); } // =========================================================== // ST7565_init - Initialises the LCD interface using SPI3 // =========================================================== void ST7565_init ( char StartSpi) { uint32_t ui32ClockMS; SPI_Params lcdSpiParams; if (StartSpi) { // Initialise SPI handle with Master mode SPI_Params_init (&lcdSpiParams); lcdSpiParams. mode = SPI_MASTER ; lcdSpiParams. frameFormat = SPI_POL1_PHA1 ; // clock high in idle, clock on rising edge lcdSpiParams. transferMode = SPI_MODE_BLOCKING ; // lcdSpiParams.transferTimeout = 250; // BAZ: Sanity timer added in 2.12 because SPI was freezing lcdSpiParams. transferTimeout = 10; // BAZ: Sanity timer added in 2.12 because SPI was freezing lcdSpiParams. dataSize = 8; lcdSpiParams. bitRate = 1000000; // 1MHz clocking lcdSpiParams. transferCallbackFxn = NULL; LCD_SPI = SPI_open (Board_SPI3, &lcdSpiParams); if (LCD_SPI != NULL) { System_printf( "LCD SPI initialised\n" ); System_flush(); } } // Determine the number of system clock cycles in 1mS ui32ClockMS = CYCLES_FROM_TIME_US(ui32SysClock, 1000); // Divide by 3 to get the number of SysCtlDelay loops in 1mS. ui32ClockMS /= 3; SetLCD_A0; // Address line high SysCtlDelay (10 * ui32ClockMS); // Delay for 10ms. ClrLCD_RST; // Activate LCD RESET SysCtlDelay (250 * ui32ClockMS); // Delay for 250ms SetLCD_RST; // RESET OFF SysCtlDelay (250 * ui32ClockMS); // Delay for 250ms WriteCommand(ST7565_CMD_BIAS_9); // Set LCD Bias WriteCommand(ST7565_CMD_VERTICAL_REVERSE); // Common Direction Select, bit3=1,reverse direction=0,normal WriteCommand(ST7565_CMD_POWER_CONTROL | ST7565_PWR_INTERNAL_CONV); SysCtlDelay (20 * ui32ClockMS); // Delay for 20ms. WriteCommand(ST7565_CMD_POWER_CONTROL | ST7565_PWR_INTERNAL_CONV | ST7565_PWR_INTERNAL_REG); SysCtlDelay (20 * ui32ClockMS); // Delay for 20ms. WriteCommand(ST7565_CMD_POWER_CONTROL | ST7565_PWR_INTERNAL_CONV | ST7565_PWR_INTERNAL_REG | ST7565_PWR_INTERNAL_FOL); SysCtlDelay (20 * ui32ClockMS); // Delay for 20ms. WriteCommand(ST7565_CMD_RESISTOR | 0x04); // Set ra/rb 0x25 WriteCommand(ST7565_CMD_VOLUME_MODE); // Set Contrast WriteCommand(39); // Contrast = 39 (Range 0..63) WriteCommand(ST7565_CMD_DISPLAY_ON); // Display ON ST7565_blank(); // Blank the display ST7565_flip_screen(1); // set the screen orientation to suit standard ASE position SetLCD_BL; // turn on the LCD backlight } /* SPI objects */ SPITivaDMA_Object spiTivaDMAobjects[ A30307P26_SPICOUNT ]; #if defined(__TI_COMPILER_VERSION__) #pragma DATA_ALIGN(spiTivaDMAscratchBuf, 32) #elif defined(__IAR_SYSTEMS_ICC__) #pragma data_alignment=32 #elif defined(__GNUC__) __attribute__ ((aligned (32))) #endif uint32_t spiTivaDMAscratchBuf[ A30307P26_SPICOUNT ]; /* SPI configuration structure, describing which pins are to be used */ const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[ A30307P26_SPICOUNT ] = { { SSI0_BASE, INT_SSI0, (~0), &spiTivaDMAscratchBuf[0], 0xFFFFFFFF, UDMA_CHANNEL_SSI0RX, UDMA_CHANNEL_SSI0TX, uDMAChannelAssign , UDMA_CH10_SSI0RX, UDMA_CH11_SSI0TX }, { SSI1_BASE, INT_SSI1, (~0), &spiTivaDMAscratchBuf[1], 0, UDMA_CHANNEL_SSI1RX, UDMA_CHANNEL_SSI1TX, uDMAChannelAssign , UDMA_CH24_SSI1RX, UDMA_CH25_SSI1TX }, { SSI3_BASE, INT_SSI3, (~0), &spiTivaDMAscratchBuf[2], 0, UDMA_SEC_CHANNEL_TMR2A_14, UDMA_SEC_CHANNEL_TMR2B_15, uDMAChannelAssign , UDMA_CH14_SSI3RX, UDMA_CH15_SSI3TX } }; const SPI_Config SPI_config[] = { {&SPITivaDMA_fxnTable, &spiTivaDMAobjects[0], &spiTivaDMAHWAttrs[0]}, {&SPITivaDMA_fxnTable, &spiTivaDMAobjects[1], &spiTivaDMAHWAttrs[1]}, {&SPITivaDMA_fxnTable, &spiTivaDMAobjects[2], &spiTivaDMAHWAttrs[2]}, {NULL, NULL, NULL}, }; /* * ======== A30307P26_initSPI ======== */ Void A30307P26_initSPI (Void) { // SSI0 - MicroSD SysCtlPeripheralEnable (SYSCTL_PERIPH_SSI0); GPIOPinConfigure (GPIO_PA2_SSI0CLK); GPIOPinConfigure (GPIO_PA3_SSI0FSS); GPIOPinConfigure (GPIO_PA4_SSI0XDAT0); GPIOPinConfigure (GPIO_PA5_SSI0XDAT1); GPIOPinTypeSSI (GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5); // SSI1 - Serial Flash SysCtlPeripheralEnable (SYSCTL_PERIPH_SSI1); GPIOPinConfigure (GPIO_PB5_SSI1CLK); GPIOPinConfigure (GPIO_PB4_SSI1FSS); GPIOPinConfigure (GPIO_PE4_SSI1XDAT0); GPIOPinConfigure (GPIO_PE5_SSI1XDAT1); GPIOPinTypeSSI (GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5); GPIOPinTypeSSI (GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5); // SPI3 - The Mono LCD SPI Port SysCtlPeripheralEnable (SYSCTL_PERIPH_SSI3); GPIOPinConfigure (GPIO_PQ0_SSI3CLK); GPIOPinConfigure (GPIO_PQ1_SSI3FSS); // Hardware control of CS GPIOPinConfigure (GPIO_PQ2_SSI3XDAT0); GPIOPinConfigure (GPIO_PQ3_SSI3XDAT1); GPIOPinTypeSSI (GPIO_PORTQ_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); A30307P26_initDMA(); SPI_init (); }
↧