+++ /dev/null
-/*\r
- FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.\r
-\r
- ***************************************************************************\r
- * *\r
- * If you are: *\r
- * *\r
- * + New to FreeRTOS, *\r
- * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
- * + Looking for basic training, *\r
- * + Wanting to improve your FreeRTOS skills and productivity *\r
- * *\r
- * then take a look at the FreeRTOS eBook *\r
- * *\r
- * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- * A pdf reference manual is also available. Both are usually delivered *\r
- * to your inbox within 20 minutes to two hours when purchased between 8am *\r
- * and 8pm GMT (although please allow up to 24 hours in case of *\r
- * exceptional circumstances). Thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- ***NOTE*** The exception to the GPL is included to allow you to distribute\r
- a combined work that includes FreeRTOS without being obliged to provide the\r
- source code for proprietary components outside of the FreeRTOS kernel.\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public \r
- License and the FreeRTOS license exception along with FreeRTOS; if not it \r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#include <string.h>\r
-\r
-#include "FreeRTOS.h"\r
-#include "CircularBuffer.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* See the header file for function information. */\r
-void vInitialiseCircularBuffer( xCircularBuffer *pxBuffer,\r
- unsigned char *pucDataBuffer,\r
- unsigned long ulBufferSizeInBytes,\r
- unsigned long ulDataSizeInBytes,\r
- void *pvTag\r
- )\r
-{\r
- pxBuffer->pucDataBuffer = pucDataBuffer;\r
- pxBuffer->ulBufferSizeInBytes = ulBufferSizeInBytes;\r
- pxBuffer->pucNextByteToRead = pucDataBuffer;\r
- pxBuffer->pucNextByteToWrite = pucDataBuffer;\r
- pxBuffer->ulDataSizeInBytes = ulDataSizeInBytes;\r
- pxBuffer->pvTag = pvTag;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/* See the header file for function information. */\r
-unsigned long ulBytesInCircularBuffer( const xCircularBuffer * const pxBuffer )\r
-{\r
-unsigned char *pucNextByteToWrite;\r
-unsigned long ulReturn;\r
-\r
- if( pxBuffer->pvTag != NULL )\r
- {\r
- /* Locate the position that the DMA will next write to. */\r
- pucNextByteToWrite = ( unsigned char * ) *( ( unsigned long * ) pxBuffer->pvTag );\r
- }\r
- else\r
- {\r
- /* Locate the position the application will next write to. */\r
- pucNextByteToWrite = pxBuffer->pucNextByteToWrite;\r
- }\r
- \r
- /* Has the write pointer wrapped back to the start of the buffer\r
- compared to our read pointer? */\r
- if( ( unsigned long ) pucNextByteToWrite >= ( unsigned long ) pxBuffer->pucNextByteToRead )\r
- {\r
- /* The write pointer is still ahead of us in the buffer. The amount of\r
- data available is simple the gap between the two pointers. */\r
- ulReturn = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucNextByteToRead;\r
- }\r
- else\r
- {\r
- /* The write pointer has wrapped back to the start. The amount of data\r
- available is equal to the data between the read pointer and the end of\r
- the buffer...*/\r
- ulReturn = ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) - ( unsigned long ) pxBuffer->pucNextByteToRead;\r
-\r
- /*... plus the data between the start of the buffer and the write\r
- pointer. */\r
- ulReturn += ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucDataBuffer;\r
- }\r
-\r
- return ulReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-unsigned long ulCopyReceivedBytes( xCircularBuffer *pxBuffer, unsigned char * pucBuffer, unsigned long ulWantedBytes )\r
-{\r
-unsigned char *pucNextByteToWrite;\r
-unsigned long ulNumberOfBytesRead = 0, ulNumberOfBytesAvailable;\r
-\r
- if( pxBuffer->pvTag != NULL )\r
- {\r
- /* Locate the position that the DMA will next write to. */\r
- pucNextByteToWrite = ( unsigned char * ) *( ( unsigned long * ) pxBuffer->pvTag );\r
- }\r
- else\r
- {\r
- /* Locate the position that the application will next write to. */\r
- pucNextByteToWrite = pxBuffer->pucNextByteToWrite;\r
- }\r
- \r
- if( ( unsigned long ) pucNextByteToWrite >= ( unsigned long ) pxBuffer->pucNextByteToRead )\r
- {\r
- /* The write pointer has not wrapped around from our read pointer.\r
- \r
- Clip the number of bytes to read to the number available if the number\r
- available is less than that wanted. */\r
- ulNumberOfBytesAvailable = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) ( pxBuffer->pucNextByteToRead );\r
- \r
- if( ulNumberOfBytesAvailable < ulWantedBytes )\r
- {\r
- ulWantedBytes = ulNumberOfBytesAvailable;\r
- }\r
- \r
- /* Copy the data from ulRxBuffer into the application buffer. */\r
- memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes );\r
-\r
- /* Move up our read buffer. */\r
- pxBuffer->pucNextByteToRead += ulWantedBytes;\r
- ulNumberOfBytesRead = ulWantedBytes;\r
- }\r
- else\r
- {\r
- /* The write pointer has wrapped around from our read pointer. Is there\r
- enough space from our read pointer to the end of the buffer without the\r
- read pointer also wrapping around? */\r
- ulNumberOfBytesAvailable = ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) - ( unsigned long ) pxBuffer->pucNextByteToRead;\r
- \r
- if( ulNumberOfBytesAvailable >= ulWantedBytes )\r
- {\r
- /* There is enough space from our current read pointer up to the end\r
- of the buffer to obtain the number of bytes requested. */\r
- memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes );\r
-\r
- /* Move up our read buffer. */\r
- pxBuffer->pucNextByteToRead += ulWantedBytes;\r
- ulNumberOfBytesRead = ulWantedBytes;\r
- }\r
- else\r
- {\r
- /* There is not enough space up to the end of the buffer to obtain\r
- the number of bytes requested. Copy up to the end of the buffer. */\r
- memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulNumberOfBytesAvailable );\r
- ulNumberOfBytesRead = ulNumberOfBytesAvailable;\r
- \r
- /* Then wrap back to the beginning of the buffer to attempt to\r
- read the remaining bytes. */\r
- pxBuffer->pucNextByteToRead = pxBuffer->pucDataBuffer;\r
- pucBuffer += ulNumberOfBytesAvailable;\r
- \r
- /* How many more bytes do we want to read? */\r
- ulWantedBytes -= ulNumberOfBytesAvailable;\r
- \r
- /* Clip the number of bytes we are going to read to the number\r
- available if this is less than the number we want. */\r
- ulNumberOfBytesAvailable = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucNextByteToRead;\r
- \r
- if( ulNumberOfBytesAvailable < ulWantedBytes )\r
- {\r
- ulWantedBytes = ulNumberOfBytesAvailable;\r
- }\r
-\r
- /* Copy these into the buffer. */\r
- memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes );\r
-\r
- /* Move up our read buffer. */\r
- pxBuffer->pucNextByteToRead += ulWantedBytes;\r
- ulNumberOfBytesRead += ulWantedBytes;\r
- }\r
- }\r
- \r
- /* Check we have not moved our read pointer off the end of the buffer. */\r
- if( ( unsigned long ) pxBuffer->pucNextByteToRead >= ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) )\r
- {\r
- pxBuffer->pucNextByteToRead = pxBuffer->pucDataBuffer; \r
- }\r
- \r
- /* Return the number of bytes read. */\r
- return ulNumberOfBytesRead;\r
-}\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.\r
-\r
- ***************************************************************************\r
- * *\r
- * If you are: *\r
- * *\r
- * + New to FreeRTOS, *\r
- * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
- * + Looking for basic training, *\r
- * + Wanting to improve your FreeRTOS skills and productivity *\r
- * *\r
- * then take a look at the FreeRTOS eBook *\r
- * *\r
- * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- * A pdf reference manual is also available. Both are usually delivered *\r
- * to your inbox within 20 minutes to two hours when purchased between 8am *\r
- * and 8pm GMT (although please allow up to 24 hours in case of *\r
- * exceptional circumstances). Thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- ***NOTE*** The exception to the GPL is included to allow you to distribute\r
- a combined work that includes FreeRTOS without being obliged to provide the\r
- source code for proprietary components outside of the FreeRTOS kernel.\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public \r
- License and the FreeRTOS license exception along with FreeRTOS; if not it \r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef CIRCULAR_BUFFER_H\r
-#define CIRCULAR_BUFFER_H\r
-\r
-/* Structure that holds the state of the circular buffer. */\r
-typedef struct\r
-{\r
- unsigned char *pucDataBuffer;\r
- unsigned long ulBufferSizeInBytes;\r
- unsigned char *pucNextByteToRead;\r
- unsigned char *pucNextByteToWrite;\r
- unsigned long ulDataSizeInBytes;\r
- void *pvTag;\r
-} xCircularBuffer;\r
-\r
-\r
-/*\r
- * Setup a circular buffer ready for use.\r
- *\r
- * pxBuffer : The xCicularBuffer structure being initialised.\r
- *\r
- * pucDataBuffer : The buffer to be used by the xCicularBuffer object.\r
- *\r
- * ulBufferSizeInBytes : The dimention of pucDataBuffer in bytes.\r
- *\r
- * ulDataSizeInBytes : The size of the data that is to be stored in the\r
- * circular buffer. For example, 4 if the buffer is used to hold\r
- * unsigned longs, 1 if the buffer is used to hold chars.\r
- *\r
- * pvTag : Can be used for anything, although normally used in conjunction with\r
- * a DMA register.\r
- */\r
-void vInitialiseCircularBuffer( xCircularBuffer *pxBuffer,\r
- unsigned char *pucDataBuffer,\r
- unsigned long ulBufferSizeInBytes,\r
- unsigned long ulDataSizeInBytes,\r
- void *pvTag\r
- );\r
-/*\r
- * Returns the number of bytes that are currently available within the\r
- * buffer.\r
- */\r
-unsigned long ulBytesInCircularBuffer( const xCircularBuffer * const pxBuffer );\r
-\r
-/*\r
- * Obtain bytes from the circular buffer. Data may have been placed in\r
- * the circular buffer by a DMA transfer or simply written to the buffer by\r
- * the application code.\r
- *\r
- * pxBuffer : The circular buffer from which data is to be read.\r
- *\r
- * pucBuffer : The buffer into which the received bytes should be copied.\r
- *\r
- * ulWantedBytes : The number of bytes we are going to attempt to receive\r
- * from the circular buffer.\r
- *\r
- * return : The actual number of bytes received from the circular buffer.\r
- * This might be less than the number of bytes we attempted to receive.\r
- */\r
-unsigned long ulCopyReceivedBytes( xCircularBuffer *pxBuffer, unsigned char * pucBuffer, unsigned long ulWantedBytes );\r
-\r
-#endif\r
-\r
*******************************************************************************/\r
\r
/* Includes ------------------------------------------------------------------*/\r
-#include "spi_flash.h"\r
+#include "SPI_Flash_ST_Eval.h"\r
\r
/* Private typedef -----------------------------------------------------------*/\r
#define SPI_FLASH_PageSize 0x100\r
--- /dev/null
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************\r
+* File Name : spi_flash.h\r
+* Author : MCD Application Team\r
+* Version : V2.0.0\r
+* Date : 04/27/2009\r
+* Description : Header for spi_flash.c file.\r
+********************************************************************************\r
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.\r
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,\r
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE\r
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING\r
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+*******************************************************************************/\r
+\r
+/* Define to prevent recursive inclusion -------------------------------------*/\r
+#ifndef __SPI_FLASH_H\r
+#define __SPI_FLASH_H\r
+\r
+/* Includes ------------------------------------------------------------------*/\r
+#include "stm32f10x.h"\r
+#include "stm32f10x_spi.h"\r
+#include "stm32f10x_gpio.h"\r
+#include "stm32f10x_rcc.h"\r
+\r
+#define uint32_t unsigned long\r
+#define uint8_t unsigned char\r
+#define uint16_t unsigned short\r
+\r
+/* Exported types ------------------------------------------------------------*/\r
+/* Exported constants --------------------------------------------------------*/\r
+/* Uncomment the line corresponding to the STMicroelectronics evaluation board\r
+ used to run the example */\r
+#if !defined (USE_STM3210B_EVAL) && !defined (USE_STM3210E_EVAL)\r
+ //#define USE_STM3210B_EVAL\r
+ #define USE_STM3210E_EVAL\r
+#endif\r
+\r
+#ifdef USE_STM3210B_EVAL\r
+ #define GPIO_CS GPIOA\r
+ #define RCC_APB2Periph_GPIO_CS RCC_APB2Periph_GPIOA\r
+ #define GPIO_Pin_CS GPIO_Pin_4 \r
+#else /* USE_STM3210E_EVAL */\r
+ #define GPIO_CS GPIOB\r
+ #define RCC_APB2Periph_GPIO_CS RCC_APB2Periph_GPIOB\r
+ #define GPIO_Pin_CS GPIO_Pin_2 \r
+#endif\r
+\r
+/* Exported macro ------------------------------------------------------------*/\r
+/* Select SPI FLASH: Chip Select pin low */\r
+#define SPI_FLASH_CS_LOW() __asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );GPIO_ResetBits(GPIO_CS, GPIO_Pin_CS);__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" )\r
+/* Deselect SPI FLASH: Chip Select pin high */\r
+#define SPI_FLASH_CS_HIGH() __asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );GPIO_SetBits(GPIO_CS, GPIO_Pin_CS);__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" )\r
+\r
+/* Exported functions ------------------------------------------------------- */\r
+/*----- High layer function -----*/\r
+void SPI_FLASH_Init(void);\r
+void SPI_FLASH_SectorErase(uint32_t SectorAddr);\r
+void SPI_FLASH_BulkErase(void);\r
+void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);\r
+void SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);\r
+void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);\r
+uint32_t SPI_FLASH_ReadID(void);\r
+void SPI_FLASH_StartReadSequence(uint32_t ReadAddr);\r
+\r
+/*----- Low layer function -----*/\r
+uint8_t SPI_FLASH_ReadByte(void);\r
+uint8_t SPI_FLASH_SendByte(uint8_t byte);\r
+uint16_t SPI_FLASH_SendHalfWord(uint16_t HalfWord);\r
+void SPI_FLASH_WriteEnable(void);\r
+void SPI_FLASH_WaitForWriteEnd(void);\r
+\r
+#endif /* __SPI_FLASH_H */\r
+\r
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/\r
\r
/* Scheduler includes. */\r
#include "FreeRTOS.h"\r
+#include "task.h"\r
#include "queue.h"\r
#include "semphr.h"\r
\r
-/* Driver includes. */\r
-#include "CircularBuffer.h"\r
-\r
/* Library includes. */\r
#include "stm32f10x_lib.h"\r
-#include "stm32f10x_rcc.h"\r
\r
/* Driver includes. */\r
#include "STM32_USART.h"\r
/* The number of COM ports that can be controlled at the same time. */\r
#define serNUM_COM_PORTS ( 2 )\r
\r
-/* Indexes into the xCOMBufferDefinitions array for the Rx and Tx buffers. */\r
-#define serRX_BUFFER_INDEX ( 0 )\r
-#define serTX_BUFFER_INDEX ( 1 )\r
+/* Queues are used to hold characters that are waiting to be transmitted. This\r
+constant sets the maximum number of characters that can be contained in such a\r
+queue at any one time. */\r
+#define serTX_QUEUE_LEN ( 100 )\r
+\r
+/* Queues are used to hold characters that have been received but not yet \r
+processed. This constant sets the maximum number of characters that can be \r
+contained in such a queue. */\r
+#define serRX_QUEUE_LEN ( 100 )\r
\r
-/* A counting semaphore is used to allows tasks to block to wait for characters\r
-to be received. This constant defines the max count. Making this value higher\r
-does not change the amount of RAM used by the semaphore, so its worth making it\r
-quite high. */\r
-#define serSEMAPHORE_MAX_COUNT ( 100 )\r
+/* The maximum amount of time that calls to lSerialPutString() should wait for\r
+there to be space to post each character to the queue of characters waiting\r
+transmission. NOTE! This is the time to wait per character - not the time to\r
+wait for the entire string. */\r
+#define serPUT_STRING_CHAR_DELAY ( 5 / portTICK_RATE_MS )\r
\r
/*-----------------------------------------------------------*/\r
\r
-/* An Rx and a Tx buffer structure for each COM port. */\r
-static xCircularBuffer xCOMBufferDefinitions[ serNUM_COM_PORTS ][ 2 ];\r
+/* References to the USART peripheral addresses themselves. */\r
+static USART_TypeDef * const xUARTS[ serNUM_COM_PORTS ] = { ( ( USART_TypeDef * ) USART1_BASE ), ( ( USART_TypeDef * ) USART2_BASE ) };\r
\r
-/* The buffers themselves. */\r
-static unsigned char ucCOM0_Rx_Buffer[ configCOM0_RX_BUFFER_LENGTH ];\r
-static unsigned char ucCOM0_Tx_Buffer[ configCOM0_TX_BUFFER_LENGTH ];\r
-static unsigned char ucCOM1_Rx_Buffer[ configCOM1_RX_BUFFER_LENGTH ];\r
-static unsigned char ucCOM1_Tx_Buffer[ configCOM1_TX_BUFFER_LENGTH ];\r
+/* Queues used to hold characters waiting to be transmitted - one queue per port. */\r
+static xQueueHandle xCharsForTx[ serNUM_COM_PORTS ] = { 0 };\r
\r
-/* Semaphores used to block tasks that are waiting for characters to be\r
-received. */\r
-static xSemaphoreHandle xCOM0RxSemaphore, xCOM1RxSemaphore;\r
+/* Queues holding received characters - one queue per port. */\r
+static xQueueHandle xRxedChars[ serNUM_COM_PORTS ] = { 0 };\r
\r
/*-----------------------------------------------------------*/\r
\r
-/* UART interrupt handler. */\r
-void vUARTInterruptHandler( void );\r
+/* UART interrupt handlers, as named in the vector table. */\r
+void USART1_IRQHandler( void );\r
+void USART2_IRQHandler( void );\r
\r
/*-----------------------------------------------------------*/\r
\r
/*\r
- * See serial.h in this project for parameter descriptions.\r
+ * See header file for parameter descriptions.\r
*/\r
long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud )\r
{\r
does not check to see if the COM port has already been initialised. */\r
if( ulPort == 0 )\r
{\r
- /* Create the semaphore used to enable tasks to block to wait for\r
- characters to be received. */\r
- xCOM0RxSemaphore = xSemaphoreCreateCounting( serSEMAPHORE_MAX_COUNT, 0 );\r
-\r
- vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serRX_BUFFER_INDEX ] ),\r
- ucCOM0_Rx_Buffer,\r
- configCOM0_RX_BUFFER_LENGTH,\r
- sizeof( unsigned char ),\r
- NULL\r
- );\r
-\r
- vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serTX_BUFFER_INDEX ] ),\r
- ucCOM0_Tx_Buffer,\r
- configCOM0_TX_BUFFER_LENGTH,\r
- sizeof( unsigned char ),\r
- NULL\r
- );\r
-\r
- /* Enable COM1 clock - the ST libraries start numbering from UART1, \r
- making this UART 2. */\r
+ /* Create the queue of chars that are waiting to be sent to COM0. */\r
+ xCharsForTx[ 0 ] = xQueueCreate( serTX_QUEUE_LEN, sizeof( char ) );\r
+\r
+ /* Create the queue used to hold characters received from COM0. */\r
+ xRxedChars[ 0 ] = xQueueCreate( serRX_QUEUE_LEN, sizeof( char ) );\r
+\r
+ /* Enable COM0 clock - the ST libraries start numbering from UART1. */\r
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE ); \r
\r
/* Configure USART1 Rx (PA10) as input floating */\r
\r
USART_DMACmd( USART1, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE );\r
USART_Cmd( USART1, ENABLE ); \r
+\r
+ /* Everything is ok. */\r
+ lReturn = pdPASS;\r
}\r
- else\r
+ else if( ulPort == 1 )\r
{\r
- /* Create the semaphore used to enable tasks to block to wait for\r
- characters to be received. */\r
- xCOM1RxSemaphore = xSemaphoreCreateCounting( serSEMAPHORE_MAX_COUNT, 0 );\r
-\r
- vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serRX_BUFFER_INDEX ] ),\r
- ucCOM1_Rx_Buffer,\r
- configCOM1_RX_BUFFER_LENGTH,\r
- sizeof( unsigned char ),\r
- NULL\r
- );\r
-\r
- vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serTX_BUFFER_INDEX ] ),\r
- ucCOM1_Tx_Buffer,\r
- configCOM1_TX_BUFFER_LENGTH,\r
- sizeof( unsigned char ),\r
- NULL\r
- );\r
+ /* Create the queue of chars that are waiting to be sent to COM1. */\r
+ xCharsForTx[ 1 ] = xQueueCreate( serTX_QUEUE_LEN, sizeof( char ) );\r
+\r
+ /* Create the queue used to hold characters received from COM0. */\r
+ xRxedChars[ 1 ] = xQueueCreate( serRX_QUEUE_LEN, sizeof( char ) );\r
\r
/* Enable COM0 clock - the ST libraries start numbering from 1. */\r
RCC_APB2PeriphClockCmd( RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOA, ENABLE ); \r
\r
USART_DMACmd( USART2, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE );\r
USART_Cmd( USART2, ENABLE ); \r
+\r
+ /* Everything is ok. */\r
+ lReturn = pdPASS;\r
} \r
- \r
- /* Everything is ok. */\r
- lReturn = pdPASS;\r
+ else\r
+ {\r
+ /* Nothing to do unless more than two ports are supported. */\r
+ }\r
}\r
\r
return lReturn;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-signed long xUSARTGetChar( long lPort, signed char *pcRxedChar, portTickType xBlockTime )\r
+signed long xSerialGetChar( long lPort, signed char *pcRxedChar, portTickType xBlockTime )\r
{\r
- return pdFALSE;\r
+long lReturn = pdFAIL;\r
+\r
+ if( lPort < serNUM_COM_PORTS ) \r
+ {\r
+ if( xQueueReceive( xRxedChars[ lPort ], pcRxedChar, xBlockTime ) == pdPASS )\r
+ {\r
+ lReturn = pdPASS;\r
+ }\r
+ }\r
+\r
+ return lReturn;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vSerialPutString( long lPort, const signed char * const pcString, unsigned portSHORT usStringLength )\r
+long lSerialPutString( long lPort, const char * const pcString, unsigned long ulStringLength )\r
{\r
+long lReturn;\r
+unsigned long ul;\r
+\r
+ if( lPort < serNUM_COM_PORTS )\r
+ {\r
+ lReturn = pdPASS;\r
+\r
+ for( ul = 0; ul < ulStringLength; ul++ )\r
+ {\r
+ if( xQueueSend( xCharsForTx[ lPort ], &( pcString[ ul ] ), serPUT_STRING_CHAR_DELAY ) != pdPASS )\r
+ {\r
+ /* Cannot fit any more in the queue. Try turning the Tx on to \r
+ clear some space. */\r
+ USART_ITConfig( xUARTS[ lPort ], USART_IT_TXE, ENABLE );\r
+ vTaskDelay( serPUT_STRING_CHAR_DELAY );\r
+\r
+ /* Go back and try again. */\r
+ continue;\r
+ }\r
+ }\r
+\r
+ USART_ITConfig( xUARTS[ lPort ], USART_IT_TXE, ENABLE );\r
+ }\r
+ else\r
+ {\r
+ lReturn = pdFAIL;\r
+ }\r
+\r
+ return lReturn;\r
}\r
/*-----------------------------------------------------------*/\r
\r
signed long xSerialPutChar( long lPort, signed char cOutChar, portTickType xBlockTime )\r
{\r
- return pdFALSE;\r
+long lReturn;\r
+\r
+ if( xQueueSend( xCharsForTx[ lPort ], &cOutChar, xBlockTime ) == pdPASS )\r
+ {\r
+ lReturn = pdPASS;\r
+ USART_ITConfig( xUARTS[ lPort ], USART_IT_TXE, ENABLE );\r
+ }\r
+ else\r
+ {\r
+ lReturn = pdFAIL;\r
+ }\r
+\r
+ return lReturn;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vUARTInterruptHandler( void )\r
+void USART1_IRQHandler( void )\r
{\r
long xHigherPriorityTaskWoken = pdFALSE;\r
char cChar;\r
{\r
/* The interrupt was caused by the THR becoming empty. Are there any\r
more characters to transmit? */\r
-if( 0 )// if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )\r
+ if( xQueueReceiveFromISR( xCharsForTx[ 0 ], &cChar, &xHigherPriorityTaskWoken ) )\r
{\r
- /* A character was retrieved from the queue so can be sent to the\r
+ /* A character was retrieved from the buffer so can be sent to the\r
THR now. */\r
USART_SendData( USART1, cChar );\r
}\r
if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET )\r
{\r
cChar = USART_ReceiveData( USART1 );\r
-// xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );\r
+ xQueueSendFromISR( xRxedChars[ 0 ], &cChar, &xHigherPriorityTaskWoken );\r
} \r
\r
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );\r
}\r
+/*-----------------------------------------------------------*/\r
\r
+void USART2_IRQHandler( void )\r
+{\r
+}\r
\r
\r
\r
#define STM_32_SERIAL_COMMS_H\r
\r
long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud );\r
+signed long xSerialPutChar( long lPort, signed char cOutChar, portTickType xBlockTime );\r
+signed long xSerialGetChar( long lPort, signed char *pcRxedChar, portTickType xBlockTime );\r
+long lSerialPutString( long lPort, const char * const pcString, unsigned long ulStringLength );\r
\r
#endif\r
\r
<!DOCTYPE CrossStudio_Project_File>
<solution Name="RTOSDemo" version="2">
<project Name="RTOSDemo">
- <configuration Name="Common" Target="STM32F103RB" arm_architecture="v7M" arm_core_type="Cortex-M3" arm_linker_fiq_stack_size="0" arm_linker_heap_size="128" arm_linker_irq_stack_size="0" arm_linker_jtag_pad_pre_dr="1" arm_linker_jtag_pad_pre_ir="5" arm_linker_stack_size="128" arm_simulator_memory_simulation_filename="$(PackagesDir)/targets/ST_STM32F10x/STM32F10xSimulatorMemory.dll" arm_simulator_memory_simulation_parameter="0x20000;0x4000" arm_target_debug_interface_type="ADIv5" arm_target_loader_parameter="8000000" c_only_additional_options="-Wall;-Wextra" c_system_include_directories="$(StudioDir)/include;$(PackagesDir)/include;$(PackagesDir)/targets/stm32/include" c_user_include_directories=".;../../Source/include/;../../Source/portable/GCC/ARM_CM3/;../Common/Include/;ST Library/inc/;./Drivers/" link_include_startup_code="No" linker_memory_map_file="$(TargetsDir)/ST_STM32F10x/ST_STM32F103RB_MemoryMap.xml" linker_printf_width_precision_supported="No" oscillator_frequency="8MHz" project_directory="" project_type="Executable" property_groups_file_path="$(PackagesDir)/targets/ST_STM32F10x/propertyGroups.xml"/>
+ <configuration Name="Common" Target="STM32F103RB" arm_architecture="v7M" arm_core_type="Cortex-M3" arm_linker_fiq_stack_size="0" arm_linker_heap_size="8" arm_linker_irq_stack_size="0" arm_linker_jtag_pad_pre_dr="1" arm_linker_jtag_pad_pre_ir="5" arm_linker_stack_size="256" arm_simulator_memory_simulation_filename="$(PackagesDir)/targets/ST_STM32F10x/STM32F10xSimulatorMemory.dll" arm_simulator_memory_simulation_parameter="0x20000;0x4000" arm_target_debug_interface_type="ADIv5" arm_target_loader_parameter="8000000" c_only_additional_options="-Wall;-Wextra" c_preprocessor_definitions="USE_STM3210B_EVAL" c_system_include_directories="$(StudioDir)/include;$(PackagesDir)/include;$(PackagesDir)/targets/stm32/include" c_user_include_directories=".;../../Source/include/;../../Source/portable/GCC/ARM_CM3/;../Common/Include/;ST Library/inc/;./Drivers/" link_include_startup_code="No" linker_memory_map_file="$(TargetsDir)/ST_STM32F10x/ST_STM32F103RB_MemoryMap.xml" linker_printf_width_precision_supported="No" oscillator_frequency="8MHz" project_directory="" project_type="Executable" property_groups_file_path="$(PackagesDir)/targets/ST_STM32F10x/propertyGroups.xml"/>
<configuration Name="RAM" Placement="RAM" linker_section_placement_file="$(StudioDir)/targets/sram_placement.xml" target_reset_script="SRAMReset()"/>
<configuration Name="Flash" Placement="Flash" arm_target_flash_loader_file_path="$(PackagesDir)/targets/ST_STM32F10x/Release/Loader_rpc.elf" arm_target_flash_loader_type="LIBMEM RPC Loader" linker_section_placement_file="$(StudioDir)/targets/flash_placement.xml" target_reset_script="FLASHReset()"/>
<folder Name="Source Files">
<file file_name="ST Library/src/stm32f10x_i2c.c"/>
</folder>
<folder Name="Drivers">
- <file file_name="Drivers/CircularBuffer.c"/>
<file file_name="Drivers/STM32_USART.c"/>
+ <file file_name="Drivers/SPI_Flash_ST_Eval.c"/>
</folder>
<folder Name="ParTest">
<file file_name="ParTest/ParTest_MCBSTM32.c">
+ <configuration Name="THUMB Flash Debug" build_exclude_from_build="No"/>
+ </file>
+ <file file_name="ParTest/ParTest_ST_Eval.c">
<configuration Name="THUMB Flash Debug" build_exclude_from_build="Yes"/>
</file>
- <file file_name="ParTest/ParTest_ST_Eval.c"/>
</folder>
</folder>
<folder Name="System Files">
<Project>
<ProjectSessionItem path="RTOSDemo" name="unnamed" />
<ProjectSessionItem path="RTOSDemo;RTOSDemo" name="unnamed" />
- <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files" name="unnamed" />
- <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;Drivers" name="unnamed" />
- <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;FreeRTOS Source" name="unnamed" />
- <ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;ST Library" name="unnamed" />
<ProjectSessionItem path="RTOSDemo;RTOSDemo;System Files" name="unnamed" />
</Project>
<Register1>
<Watches active="0" update="Never" />
</Watch4>
<Files>
- <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ParTest\ParTest.c" y="0" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ParTest\ParTest.c" left="0" selected="0" name="unnamed" top="39" />
- <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ParTest\ParTest_ST_Eval.c" y="80" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ParTest\ParTest_ST_Eval.c" left="0" selected="0" name="unnamed" top="60" />
- <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\stm32f10x_conf.h" y="83" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\stm32f10x_conf.h" left="0" selected="0" name="unnamed" top="63" />
- <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="15" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" y="266" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" left="0" selected="0" name="unnamed" top="235" />
- <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" y="0" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" left="0" selected="1" name="unnamed" top="0" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="56" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\Drivers\STM32_USART.c" y="93" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\Drivers\STM32_USART.c" left="0" selected="0" name="unnamed" top="74" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="5" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\src\stm32f10x_usart.c" y="353" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\src\stm32f10x_usart.c" left="0" selected="0" name="unnamed" top="336" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="33" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\inc\stm32f10x_usart.h" y="238" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\inc\stm32f10x_usart.h" left="0" selected="0" name="unnamed" top="218" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" y="138" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" left="0" selected="0" name="unnamed" top="119" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="41" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\Drivers\STM32_USART.h" y="59" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\Drivers\STM32_USART.h" left="0" selected="0" name="unnamed" top="36" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" y="110" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" left="0" selected="0" name="unnamed" top="91" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\Common\Minimal\semtest.c" y="221" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\Common\Minimal\semtest.c" left="0" selected="0" name="unnamed" top="205" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Source\queue.c" y="820" path="C:\E\Dev\FreeRTOS\WorkingCopy\Source\queue.c" left="0" selected="1" name="unnamed" top="801" />
</Files>
- <ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="USB CrossConnect for ARM" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\src" fileDialogDefaultFilter="*.c" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
+ <ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="USB CrossConnect for ARM" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley" fileDialogDefaultFilter="*.c" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
</session>
* In addition to the standard demo tasks, the following tasks and tests are\r
* defined and/or created within this file:\r
*\r
- * "Check" task - This only executes every five seconds but has the highest\r
+ * "Check" task - This only executes every five seconds but has the highest\r
* priority so is guaranteed to get processor time. Its main function is to \r
* check that all the standard demo tasks are still operational. The check task\r
- * will toggle LED 7 (PB15) every five seconds so long as no errors have been\r
+ * will toggle LED 3 (PB11) every five seconds so long as no errors have been\r
* detected. The toggle rate will increase to half a second if an error has \r
* been found in any task.\r
*\r
+ * "Echo" task - This is a very basic task that simply echoes any characters \r
+ * received on COM0 (USART1). This can be tested by transmitting a text file\r
+ * from a dumb terminal to the STM32 USART.\r
*/\r
\r
/* Standard includes. */\r
-#include <stdio.h>\r
+#include <string.h>\r
\r
/* Scheduler includes. */\r
#include "FreeRTOS.h"\r
#include "task.h"\r
#include "queue.h"\r
-#include "semphr.h"\r
\r
/* Library includes. */\r
#include "stm32f10x_it.h"\r
-#include "stm32f10x_tim.h"\r
\r
/* Demo app includes. */\r
#include "BlockQ.h"\r
#include "QPeek.h"\r
#include "recmutex.h"\r
\r
+/* Driver includes. */\r
+#include "STM32_USART.h"\r
+\r
\r
/* The time between cycles of the 'check' task - which depends on whether the\r
check task has detected an error or not. */\r
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )\r
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainECHO_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
\r
+/* COM port and baud rate used by the echo task. */\r
+#define mainCOM0 ( 0 )\r
+#define mainBAUD_RATE ( 115200 )\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
/* The 'check' task as described at the top of this file. */\r
static void prvCheckTask( void *pvParameters );\r
\r
+/* A simple task that echoes all the characters that are received on COM0 \r
+(USART1). */\r
+static void prvUSARTEchoTask( void *pvParameters );\r
+\r
/*-----------------------------------------------------------*/\r
\r
int main( void )\r
vStartQueuePeekTasks();\r
vStartRecursiveMutexTasks();\r
\r
- /* Create the 'check' task, which is defined within this file. */\r
+ /* Create the 'echo' task, which is also defined within this file. */\r
+ xTaskCreate( prvUSARTEchoTask, ( signed char * ) "Echo", configMINIMAL_STACK_SIZE, NULL, mainECHO_TASK_PRIORITY, NULL );\r
+\r
+ /* Create the 'check' task, which is also defined within this file. */\r
xTaskCreate( prvCheckTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
\r
/* Start the scheduler. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
+/* Described at the top of this file. */\r
static void prvCheckTask( void *pvParameters )\r
{\r
portTickType xLastExecutionTime;\r
}\r
/*-----------------------------------------------------------*/\r
\r
+/* Described at the top of this file. */\r
+static void prvUSARTEchoTask( void *pvParameters )\r
+{\r
+signed char cChar;\r
+\r
+/* String declared static to ensure it does not end up on the stack, no matter\r
+what the optimisation level. */\r
+static const char *pcLongishString = \r
+"ABBA was a Swedish pop music group formed in Stockholm in 1972, consisting of Anni-Frid Frida Lyngstad, "\r
+"Björn Ulvaeus, Benny Andersson and Agnetha Fältskog. Throughout the band's existence, Fältskog and Ulvaeus "\r
+"were a married couple, as were Lyngstad and Andersson - although both couples later divorced. They became one "\r
+"of the most commercially successful acts in the history of popular music, and they topped the charts worldwide "\r
+"from 1972 to 1983. ABBA gained international popularity employing catchy song hooks, simple lyrics, sound "\r
+"effects (reverb, phasing) and a Wall of Sound achieved by overdubbing the female singers' voices in multiple "\r
+"harmonies. As their popularity grew, they were sought after to tour Europe, Australia, and North America, drawing "\r
+"crowds of ardent fans, notably in Australia. Touring became a contentious issue, being particularly cumbersome for "\r
+"Fältskog, but they continued to release studio albums to widespread commercial success. At the height of their "\r
+"popularity, however, both relationships began suffering strain that led ultimately to the collapse of first the "\r
+"Ulvaeus-Fältskog marriage (in 1979) and then of the Andersson-Lyngstad marriage in 1981. In the late 1970s and early "\r
+"1980s these relationship changes began manifesting in the group's music, as they produced more thoughtful, "\r
+"introspective lyrics with different compositions.";\r
+\r
+ /* Just to avoid compiler warnings. */\r
+ ( void ) pvParameters;\r
+\r
+ /* Initialise COM0, which is USART1 according to the STM32 libraries. */\r
+ lCOMPortInit( mainCOM0, mainBAUD_RATE );\r
+\r
+ /* Try sending out a string all in one go, as a very basic test of the\r
+ lSerialPutString() function. */\r
+ lSerialPutString( mainCOM0, pcLongishString, strlen( pcLongishString ) );\r
+\r
+ for( ;; )\r
+ {\r
+ /* Block to wait for a character to be received on COM0. */\r
+ xSerialGetChar( mainCOM0, &cChar, portMAX_DELAY );\r
+\r
+ /* Write the received character back to COM0. */\r
+ xSerialPutChar( mainCOM0, cChar, 0 );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
static void prvSetupHardware( void )\r
{\r
/* RCC system reset(for debug purpose). */\r
\r
/* SPI2 Periph clock enable */\r
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );\r
-\r
- /* Initialize the SPI FLASH driver */\r
- SPI_FLASH_Init();\r
}\r
/*-----------------------------------------------------------*/\r
\r
/************************************* SPI ************************************/\r
#define _SPI\r
#define _SPI1\r
-//#define _SPI2\r
+#define _SPI2\r
//#define _SPI3\r
\r
/************************************* SysTick ********************************/\r