From 332a489f34615af6701de5dbee56436ebf6e4ad5 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Mon, 7 Jun 2010 15:24:50 +0000 Subject: [PATCH] Work in progress - checked in for backup only. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1022 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../Drivers/CircularBuffer.c | 214 ++++++++ .../Drivers/CircularBuffer.h | 115 +++++ .../Drivers/SPI_Flash_ST_Eval.c | 482 ++++++++++++++++++ .../Drivers/STM32_USART.c | 289 +++++++++++ .../Drivers/STM32_USART.h | 60 +++ .../FreeRTOSConfig.h | 29 +- .../ParTest/{ParTest.c => ParTest_ST_Eval.c} | 71 +-- .../ParTest/ReadMe.txt | 1 + Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzp | 14 +- Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzs | 16 +- Demo/CORTEX_STM32F103_GCC_Rowley/main.c | 34 +- .../serial/serial.c | 247 --------- .../stm32f10x_conf.h | 4 +- 13 files changed, 1240 insertions(+), 336 deletions(-) create mode 100644 Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/CircularBuffer.c create mode 100644 Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/CircularBuffer.h create mode 100644 Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/SPI_Flash_ST_Eval.c create mode 100644 Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/STM32_USART.c create mode 100644 Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/STM32_USART.h rename Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/{ParTest.c => ParTest_ST_Eval.c} (76%) create mode 100644 Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ReadMe.txt delete mode 100644 Demo/CORTEX_STM32F103_GCC_Rowley/serial/serial.c diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/CircularBuffer.c b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/CircularBuffer.c new file mode 100644 index 000000000..7f5d8f7e0 --- /dev/null +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/CircularBuffer.c @@ -0,0 +1,214 @@ +/* + FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include + +#include "FreeRTOS.h" +#include "CircularBuffer.h" + +/*-----------------------------------------------------------*/ + +/* See the header file for function information. */ +void vInitialiseCircularBuffer( xCircularBuffer *pxBuffer, + unsigned char *pucDataBuffer, + unsigned long ulBufferSizeInBytes, + unsigned long ulDataSizeInBytes, + void *pvTag + ) +{ + pxBuffer->pucDataBuffer = pucDataBuffer; + pxBuffer->ulBufferSizeInBytes = ulBufferSizeInBytes; + pxBuffer->pucNextByteToRead = pucDataBuffer; + pxBuffer->pucNextByteToWrite = pucDataBuffer; + pxBuffer->ulDataSizeInBytes = ulDataSizeInBytes; + pxBuffer->pvTag = pvTag; +} +/*-----------------------------------------------------------*/ + +/* See the header file for function information. */ +unsigned long ulBytesInCircularBuffer( const xCircularBuffer * const pxBuffer ) +{ +unsigned char *pucNextByteToWrite; +unsigned long ulReturn; + + if( pxBuffer->pvTag != NULL ) + { + /* Locate the position that the DMA will next write to. */ + pucNextByteToWrite = ( unsigned char * ) *( ( unsigned long * ) pxBuffer->pvTag ); + } + else + { + /* Locate the position the application will next write to. */ + pucNextByteToWrite = pxBuffer->pucNextByteToWrite; + } + + /* Has the write pointer wrapped back to the start of the buffer + compared to our read pointer? */ + if( ( unsigned long ) pucNextByteToWrite >= ( unsigned long ) pxBuffer->pucNextByteToRead ) + { + /* The write pointer is still ahead of us in the buffer. The amount of + data available is simple the gap between the two pointers. */ + ulReturn = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucNextByteToRead; + } + else + { + /* The write pointer has wrapped back to the start. The amount of data + available is equal to the data between the read pointer and the end of + the buffer...*/ + ulReturn = ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) - ( unsigned long ) pxBuffer->pucNextByteToRead; + + /*... plus the data between the start of the buffer and the write + pointer. */ + ulReturn += ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucDataBuffer; + } + + return ulReturn; +} +/*-----------------------------------------------------------*/ + +unsigned long ulCopyReceivedBytes( xCircularBuffer *pxBuffer, unsigned char * pucBuffer, unsigned long ulWantedBytes ) +{ +unsigned char *pucNextByteToWrite; +unsigned long ulNumberOfBytesRead = 0, ulNumberOfBytesAvailable; + + if( pxBuffer->pvTag != NULL ) + { + /* Locate the position that the DMA will next write to. */ + pucNextByteToWrite = ( unsigned char * ) *( ( unsigned long * ) pxBuffer->pvTag ); + } + else + { + /* Locate the position that the application will next write to. */ + pucNextByteToWrite = pxBuffer->pucNextByteToWrite; + } + + if( ( unsigned long ) pucNextByteToWrite >= ( unsigned long ) pxBuffer->pucNextByteToRead ) + { + /* The write pointer has not wrapped around from our read pointer. + + Clip the number of bytes to read to the number available if the number + available is less than that wanted. */ + ulNumberOfBytesAvailable = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) ( pxBuffer->pucNextByteToRead ); + + if( ulNumberOfBytesAvailable < ulWantedBytes ) + { + ulWantedBytes = ulNumberOfBytesAvailable; + } + + /* Copy the data from ulRxBuffer into the application buffer. */ + memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes ); + + /* Move up our read buffer. */ + pxBuffer->pucNextByteToRead += ulWantedBytes; + ulNumberOfBytesRead = ulWantedBytes; + } + else + { + /* The write pointer has wrapped around from our read pointer. Is there + enough space from our read pointer to the end of the buffer without the + read pointer also wrapping around? */ + ulNumberOfBytesAvailable = ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) - ( unsigned long ) pxBuffer->pucNextByteToRead; + + if( ulNumberOfBytesAvailable >= ulWantedBytes ) + { + /* There is enough space from our current read pointer up to the end + of the buffer to obtain the number of bytes requested. */ + memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes ); + + /* Move up our read buffer. */ + pxBuffer->pucNextByteToRead += ulWantedBytes; + ulNumberOfBytesRead = ulWantedBytes; + } + else + { + /* There is not enough space up to the end of the buffer to obtain + the number of bytes requested. Copy up to the end of the buffer. */ + memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulNumberOfBytesAvailable ); + ulNumberOfBytesRead = ulNumberOfBytesAvailable; + + /* Then wrap back to the beginning of the buffer to attempt to + read the remaining bytes. */ + pxBuffer->pucNextByteToRead = pxBuffer->pucDataBuffer; + pucBuffer += ulNumberOfBytesAvailable; + + /* How many more bytes do we want to read? */ + ulWantedBytes -= ulNumberOfBytesAvailable; + + /* Clip the number of bytes we are going to read to the number + available if this is less than the number we want. */ + ulNumberOfBytesAvailable = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucNextByteToRead; + + if( ulNumberOfBytesAvailable < ulWantedBytes ) + { + ulWantedBytes = ulNumberOfBytesAvailable; + } + + /* Copy these into the buffer. */ + memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes ); + + /* Move up our read buffer. */ + pxBuffer->pucNextByteToRead += ulWantedBytes; + ulNumberOfBytesRead += ulWantedBytes; + } + } + + /* Check we have not moved our read pointer off the end of the buffer. */ + if( ( unsigned long ) pxBuffer->pucNextByteToRead >= ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) ) + { + pxBuffer->pucNextByteToRead = pxBuffer->pucDataBuffer; + } + + /* Return the number of bytes read. */ + return ulNumberOfBytesRead; +} + diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/CircularBuffer.h b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/CircularBuffer.h new file mode 100644 index 000000000..488082824 --- /dev/null +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/CircularBuffer.h @@ -0,0 +1,115 @@ +/* + FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef CIRCULAR_BUFFER_H +#define CIRCULAR_BUFFER_H + +/* Structure that holds the state of the circular buffer. */ +typedef struct +{ + unsigned char *pucDataBuffer; + unsigned long ulBufferSizeInBytes; + unsigned char *pucNextByteToRead; + unsigned char *pucNextByteToWrite; + unsigned long ulDataSizeInBytes; + void *pvTag; +} xCircularBuffer; + + +/* + * Setup a circular buffer ready for use. + * + * pxBuffer : The xCicularBuffer structure being initialised. + * + * pucDataBuffer : The buffer to be used by the xCicularBuffer object. + * + * ulBufferSizeInBytes : The dimention of pucDataBuffer in bytes. + * + * ulDataSizeInBytes : The size of the data that is to be stored in the + * circular buffer. For example, 4 if the buffer is used to hold + * unsigned longs, 1 if the buffer is used to hold chars. + * + * pvTag : Can be used for anything, although normally used in conjunction with + * a DMA register. + */ +void vInitialiseCircularBuffer( xCircularBuffer *pxBuffer, + unsigned char *pucDataBuffer, + unsigned long ulBufferSizeInBytes, + unsigned long ulDataSizeInBytes, + void *pvTag + ); +/* + * Returns the number of bytes that are currently available within the + * buffer. + */ +unsigned long ulBytesInCircularBuffer( const xCircularBuffer * const pxBuffer ); + +/* + * Obtain bytes from the circular buffer. Data may have been placed in + * the circular buffer by a DMA transfer or simply written to the buffer by + * the application code. + * + * pxBuffer : The circular buffer from which data is to be read. + * + * pucBuffer : The buffer into which the received bytes should be copied. + * + * ulWantedBytes : The number of bytes we are going to attempt to receive + * from the circular buffer. + * + * return : The actual number of bytes received from the circular buffer. + * This might be less than the number of bytes we attempted to receive. + */ +unsigned long ulCopyReceivedBytes( xCircularBuffer *pxBuffer, unsigned char * pucBuffer, unsigned long ulWantedBytes ); + +#endif + diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/SPI_Flash_ST_Eval.c b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/SPI_Flash_ST_Eval.c new file mode 100644 index 000000000..6f4ba14fa --- /dev/null +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/SPI_Flash_ST_Eval.c @@ -0,0 +1,482 @@ +/******************** (C) COPYRIGHT 2009 STMicroelectronics ******************** +* File Name : spi_flash.c +* Author : MCD Application Team +* Version : V2.0.0 +* Date : 04/27/2009 +* Description : This file provides a set of functions needed to manage the +* communication between SPI peripheral and SPI M25P64 FLASH. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "spi_flash.h" + +/* Private typedef -----------------------------------------------------------*/ +#define SPI_FLASH_PageSize 0x100 + +/* Private define ------------------------------------------------------------*/ +#define WRITE 0x02 /* Write to Memory instruction */ +#define WRSR 0x01 /* Write Status Register instruction */ +#define WREN 0x06 /* Write enable instruction */ + +#define READ 0x03 /* Read from Memory instruction */ +#define RDSR 0x05 /* Read Status Register instruction */ +#define RDID 0x9F /* Read identification */ +#define SE 0xD8 /* Sector Erase instruction */ +#define BE 0xC7 /* Bulk Erase instruction */ + +#define WIP_Flag 0x01 /* Write In Progress (WIP) flag */ + +#define Dummy_Byte 0xA5 + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : SPI_FLASH_Init +* Description : Initializes the peripherals used by the SPI FLASH driver. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_Init(void) +{ + SPI_InitTypeDef SPI_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable SPI1 and GPIO clocks */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | + RCC_APB2Periph_GPIO_CS, ENABLE); + + /* Configure SPI1 pins: SCK, MISO and MOSI */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /* Configure I/O for Flash Chip select */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CS; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIO_CS, &GPIO_InitStructure); + + /* Deselect the FLASH: Chip Select high */ + SPI_FLASH_CS_HIGH(); + + /* SPI1 configuration */ + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + SPI_Init(SPI1, &SPI_InitStructure); + + /* Enable SPI1 */ + SPI_Cmd(SPI1, ENABLE); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_SectorErase +* Description : Erases the specified FLASH sector. +* Input : SectorAddr: address of the sector to erase. +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_SectorErase(uint32_t SectorAddr) +{ + /* Send write enable instruction */ + SPI_FLASH_WriteEnable(); + + /* Sector Erase */ + /* Select the FLASH: Chip Select low */ + SPI_FLASH_CS_LOW(); + /* Send Sector Erase instruction */ + SPI_FLASH_SendByte(SE); + /* Send SectorAddr high nibble address byte */ + SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16); + /* Send SectorAddr medium nibble address byte */ + SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8); + /* Send SectorAddr low nibble address byte */ + SPI_FLASH_SendByte(SectorAddr & 0xFF); + /* Deselect the FLASH: Chip Select high */ + SPI_FLASH_CS_HIGH(); + + /* Wait the end of Flash writing */ + SPI_FLASH_WaitForWriteEnd(); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_BulkErase +* Description : Erases the entire FLASH. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_BulkErase(void) +{ + /* Send write enable instruction */ + SPI_FLASH_WriteEnable(); + + /* Bulk Erase */ + /* Select the FLASH: Chip Select low */ + SPI_FLASH_CS_LOW(); + /* Send Bulk Erase instruction */ + SPI_FLASH_SendByte(BE); + /* Deselect the FLASH: Chip Select high */ + SPI_FLASH_CS_HIGH(); + + /* Wait the end of Flash writing */ + SPI_FLASH_WaitForWriteEnd(); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_PageWrite +* Description : Writes more than one byte to the FLASH with a single WRITE +* cycle(Page WRITE sequence). The number of byte can't exceed +* the FLASH page size. +* Input : - pBuffer : pointer to the buffer containing the data to be +* written to the FLASH. +* - WriteAddr : FLASH's internal address to write to. +* - NumByteToWrite : number of bytes to write to the FLASH, +* must be equal or less than "SPI_FLASH_PageSize" value. +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) +{ + /* Enable the write access to the FLASH */ + SPI_FLASH_WriteEnable(); + + /* Select the FLASH: Chip Select low */ + SPI_FLASH_CS_LOW(); + /* Send "Write to Memory " instruction */ + SPI_FLASH_SendByte(WRITE); + /* Send WriteAddr high nibble address byte to write to */ + SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16); + /* Send WriteAddr medium nibble address byte to write to */ + SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8); + /* Send WriteAddr low nibble address byte to write to */ + SPI_FLASH_SendByte(WriteAddr & 0xFF); + + /* while there is data to be written on the FLASH */ + while (NumByteToWrite--) + { + /* Send the current byte */ + SPI_FLASH_SendByte(*pBuffer); + /* Point on the next byte to be written */ + pBuffer++; + } + + /* Deselect the FLASH: Chip Select high */ + SPI_FLASH_CS_HIGH(); + + /* Wait the end of Flash writing */ + SPI_FLASH_WaitForWriteEnd(); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_BufferWrite +* Description : Writes block of data to the FLASH. In this function, the +* number of WRITE cycles are reduced, using Page WRITE sequence. +* Input : - pBuffer : pointer to the buffer containing the data to be +* written to the FLASH. +* - WriteAddr : FLASH's internal address to write to. +* - NumByteToWrite : number of bytes to write to the FLASH. +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) +{ + uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0; + + Addr = WriteAddr % SPI_FLASH_PageSize; + count = SPI_FLASH_PageSize - Addr; + NumOfPage = NumByteToWrite / SPI_FLASH_PageSize; + NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize; + + if (Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned */ + { + if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */ + { + SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite); + } + else /* NumByteToWrite > SPI_FLASH_PageSize */ + { + while (NumOfPage--) + { + SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize); + WriteAddr += SPI_FLASH_PageSize; + pBuffer += SPI_FLASH_PageSize; + } + + SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle); + } + } + else /* WriteAddr is not SPI_FLASH_PageSize aligned */ + { + if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */ + { + if (NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */ + { + temp = NumOfSingle - count; + + SPI_FLASH_PageWrite(pBuffer, WriteAddr, count); + WriteAddr += count; + pBuffer += count; + + SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp); + } + else + { + SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite); + } + } + else /* NumByteToWrite > SPI_FLASH_PageSize */ + { + NumByteToWrite -= count; + NumOfPage = NumByteToWrite / SPI_FLASH_PageSize; + NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize; + + SPI_FLASH_PageWrite(pBuffer, WriteAddr, count); + WriteAddr += count; + pBuffer += count; + + while (NumOfPage--) + { + SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize); + WriteAddr += SPI_FLASH_PageSize; + pBuffer += SPI_FLASH_PageSize; + } + + if (NumOfSingle != 0) + { + SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle); + } + } + } +} + +/******************************************************************************* +* Function Name : SPI_FLASH_BufferRead +* Description : Reads a block of data from the FLASH. +* Input : - pBuffer : pointer to the buffer that receives the data read +* from the FLASH. +* - ReadAddr : FLASH's internal address to read from. +* - NumByteToRead : number of bytes to read from the FLASH. +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) +{ + /* Select the FLASH: Chip Select low */ + SPI_FLASH_CS_LOW(); + + /* Send "Read from Memory " instruction */ + SPI_FLASH_SendByte(READ); + + /* Send ReadAddr high nibble address byte to read from */ + SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16); + /* Send ReadAddr medium nibble address byte to read from */ + SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8); + /* Send ReadAddr low nibble address byte to read from */ + SPI_FLASH_SendByte(ReadAddr & 0xFF); + + while (NumByteToRead--) /* while there is data to be read */ + { + /* Read a byte from the FLASH */ + *pBuffer = SPI_FLASH_SendByte(Dummy_Byte); + /* Point to the next location where the byte read will be saved */ + pBuffer++; + } + + /* Deselect the FLASH: Chip Select high */ + SPI_FLASH_CS_HIGH(); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_ReadID +* Description : Reads FLASH identification. +* Input : None +* Output : None +* Return : FLASH identification +*******************************************************************************/ +uint32_t SPI_FLASH_ReadID(void) +{ + uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0; + + /* Select the FLASH: Chip Select low */ + SPI_FLASH_CS_LOW(); + + /* Send "RDID " instruction */ + SPI_FLASH_SendByte(0x9F); + + /* Read a byte from the FLASH */ + Temp0 = SPI_FLASH_SendByte(Dummy_Byte); + + /* Read a byte from the FLASH */ + Temp1 = SPI_FLASH_SendByte(Dummy_Byte); + + /* Read a byte from the FLASH */ + Temp2 = SPI_FLASH_SendByte(Dummy_Byte); + + /* Deselect the FLASH: Chip Select high */ + SPI_FLASH_CS_HIGH(); + + Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2; + + return Temp; +} + +/******************************************************************************* +* Function Name : SPI_FLASH_StartReadSequence +* Description : Initiates a read data byte (READ) sequence from the Flash. +* This is done by driving the /CS line low to select the device, +* then the READ instruction is transmitted followed by 3 bytes +* address. This function exit and keep the /CS line low, so the +* Flash still being selected. With this technique the whole +* content of the Flash is read with a single READ instruction. +* Input : - ReadAddr : FLASH's internal address to read from. +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_StartReadSequence(uint32_t ReadAddr) +{ + /* Select the FLASH: Chip Select low */ + SPI_FLASH_CS_LOW(); + + /* Send "Read from Memory " instruction */ + SPI_FLASH_SendByte(READ); + + /* Send the 24-bit address of the address to read from -----------------------*/ + /* Send ReadAddr high nibble address byte */ + SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16); + /* Send ReadAddr medium nibble address byte */ + SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8); + /* Send ReadAddr low nibble address byte */ + SPI_FLASH_SendByte(ReadAddr & 0xFF); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_ReadByte +* Description : Reads a byte from the SPI Flash. +* This function must be used only if the Start_Read_Sequence +* function has been previously called. +* Input : None +* Output : None +* Return : Byte Read from the SPI Flash. +*******************************************************************************/ +uint8_t SPI_FLASH_ReadByte(void) +{ + return (SPI_FLASH_SendByte(Dummy_Byte)); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_SendByte +* Description : Sends a byte through the SPI interface and return the byte +* received from the SPI bus. +* Input : byte : byte to send. +* Output : None +* Return : The value of the received byte. +*******************************************************************************/ +uint8_t SPI_FLASH_SendByte(uint8_t byte) +{ + /* Loop while DR register in not emplty */ + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); + + /* Send byte through the SPI1 peripheral */ + SPI_I2S_SendData(SPI1, byte); + + /* Wait to receive a byte */ + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); + + /* Return the byte read from the SPI bus */ + return SPI_I2S_ReceiveData(SPI1); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_SendHalfWord +* Description : Sends a Half Word through the SPI interface and return the +* Half Word received from the SPI bus. +* Input : Half Word : Half Word to send. +* Output : None +* Return : The value of the received Half Word. +*******************************************************************************/ +uint16_t SPI_FLASH_SendHalfWord(uint16_t HalfWord) +{ + /* Loop while DR register in not emplty */ + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); + + /* Send Half Word through the SPI1 peripheral */ + SPI_I2S_SendData(SPI1, HalfWord); + + /* Wait to receive a Half Word */ + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); + + /* Return the Half Word read from the SPI bus */ + return SPI_I2S_ReceiveData(SPI1); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_WriteEnable +* Description : Enables the write access to the FLASH. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_WriteEnable(void) +{ + /* Select the FLASH: Chip Select low */ + SPI_FLASH_CS_LOW(); + + /* Send "Write Enable" instruction */ + SPI_FLASH_SendByte(WREN); + + /* Deselect the FLASH: Chip Select high */ + SPI_FLASH_CS_HIGH(); +} + +/******************************************************************************* +* Function Name : SPI_FLASH_WaitForWriteEnd +* Description : Polls the status of the Write In Progress (WIP) flag in the +* FLASH's status register and loop until write opertaion +* has completed. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SPI_FLASH_WaitForWriteEnd(void) +{ + uint8_t FLASH_Status = 0; + + /* Select the FLASH: Chip Select low */ + SPI_FLASH_CS_LOW(); + + /* Send "Read Status Register" instruction */ + SPI_FLASH_SendByte(RDSR); + + /* Loop as long as the memory is busy with a write cycle */ + do + { + /* Send a dummy byte to generate the clock needed by the FLASH + and put the value of the status register in FLASH_Status variable */ + FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte); + + } + while ((FLASH_Status & WIP_Flag) == SET); /* Write in progress */ + + /* Deselect the FLASH: Chip Select high */ + SPI_FLASH_CS_HIGH(); +} + +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/STM32_USART.c b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/STM32_USART.c new file mode 100644 index 000000000..20c0c5d46 --- /dev/null +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/STM32_USART.c @@ -0,0 +1,289 @@ +/* + FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + INTERRUPT DRIVEN SERIAL PORT DRIVER. +*/ + + +/****************************************************************************** +*** NOTE: COM0 == USART1, COM1 == USART2 +******************************************************************************/ + + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "queue.h" +#include "semphr.h" + +/* Driver includes. */ +#include "CircularBuffer.h" + +/* Library includes. */ +#include "stm32f10x_lib.h" +#include "stm32f10x_rcc.h" + +/* Driver includes. */ +#include "STM32_USART.h" +/*-----------------------------------------------------------*/ + +/* The number of COM ports that can be controlled at the same time. */ +#define serNUM_COM_PORTS ( 2 ) + +/* Indexes into the xCOMBufferDefinitions array for the Rx and Tx buffers. */ +#define serRX_BUFFER_INDEX ( 0 ) +#define serTX_BUFFER_INDEX ( 1 ) + +/* A counting semaphore is used to allows tasks to block to wait for characters +to be received. This constant defines the max count. Making this value higher +does not change the amount of RAM used by the semaphore, so its worth making it +quite high. */ +#define serSEMAPHORE_MAX_COUNT ( 100 ) + +/*-----------------------------------------------------------*/ + +/* An Rx and a Tx buffer structure for each COM port. */ +static xCircularBuffer xCOMBufferDefinitions[ serNUM_COM_PORTS ][ 2 ]; + +/* The buffers themselves. */ +static unsigned char ucCOM0_Rx_Buffer[ configCOM0_RX_BUFFER_LENGTH ]; +static unsigned char ucCOM0_Tx_Buffer[ configCOM0_TX_BUFFER_LENGTH ]; +static unsigned char ucCOM1_Rx_Buffer[ configCOM1_RX_BUFFER_LENGTH ]; +static unsigned char ucCOM1_Tx_Buffer[ configCOM1_TX_BUFFER_LENGTH ]; + +/* Semaphores used to block tasks that are waiting for characters to be +received. */ +static xSemaphoreHandle xCOM0RxSemaphore, xCOM1RxSemaphore; + +/*-----------------------------------------------------------*/ + +/* UART interrupt handler. */ +void vUARTInterruptHandler( void ); + +/*-----------------------------------------------------------*/ + +/* + * See serial.h in this project for parameter descriptions. + */ +long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud ) +{ +long lReturn = pdFAIL; +USART_InitTypeDef USART_InitStructure; +NVIC_InitTypeDef NVIC_InitStructure; +GPIO_InitTypeDef GPIO_InitStructure; + + if( ulPort < serNUM_COM_PORTS ) + { + /* The common (not port dependent) part of the initialisation. */ + USART_InitStructure.USART_BaudRate = ulWantedBaud; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + + + /* Init the buffer structures with the buffer for the COM port being + initialised, and perform any non-common initialisation necessary. This + does not check to see if the COM port has already been initialised. */ + if( ulPort == 0 ) + { + /* Create the semaphore used to enable tasks to block to wait for + characters to be received. */ + xCOM0RxSemaphore = xSemaphoreCreateCounting( serSEMAPHORE_MAX_COUNT, 0 ); + + vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serRX_BUFFER_INDEX ] ), + ucCOM0_Rx_Buffer, + configCOM0_RX_BUFFER_LENGTH, + sizeof( unsigned char ), + NULL + ); + + vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serTX_BUFFER_INDEX ] ), + ucCOM0_Tx_Buffer, + configCOM0_TX_BUFFER_LENGTH, + sizeof( unsigned char ), + NULL + ); + + /* Enable COM1 clock - the ST libraries start numbering from UART1, + making this UART 2. */ + RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE ); + + /* Configure USART1 Rx (PA10) as input floating */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init( GPIOA, &GPIO_InitStructure ); + + /* Configure USART1 Tx (PA9) as alternate function push-pull */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init( GPIOA, &GPIO_InitStructure ); + + USART_Init( USART1, &USART_InitStructure ); + USART_ITConfig( USART1, USART_IT_RXNE, ENABLE ); + + NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; + NVIC_Init( &NVIC_InitStructure ); + + USART_DMACmd( USART1, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE ); + USART_Cmd( USART1, ENABLE ); + } + else + { + /* Create the semaphore used to enable tasks to block to wait for + characters to be received. */ + xCOM1RxSemaphore = xSemaphoreCreateCounting( serSEMAPHORE_MAX_COUNT, 0 ); + + vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serRX_BUFFER_INDEX ] ), + ucCOM1_Rx_Buffer, + configCOM1_RX_BUFFER_LENGTH, + sizeof( unsigned char ), + NULL + ); + + vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serTX_BUFFER_INDEX ] ), + ucCOM1_Tx_Buffer, + configCOM1_TX_BUFFER_LENGTH, + sizeof( unsigned char ), + NULL + ); + + /* Enable COM0 clock - the ST libraries start numbering from 1. */ + RCC_APB2PeriphClockCmd( RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOA, ENABLE ); + + /* Configure USART2 Rx (PA3) as input floating */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init( GPIOA, &GPIO_InitStructure ); + + /* Configure USART2 Tx (PA2) as alternate function push-pull */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init( GPIOA, &GPIO_InitStructure ); + + USART_Init( USART2, &USART_InitStructure ); + USART_ITConfig( USART2, USART_IT_RXNE, ENABLE ); + + NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel; + NVIC_Init( &NVIC_InitStructure ); + + USART_DMACmd( USART2, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE ); + USART_Cmd( USART2, ENABLE ); + } + + /* Everything is ok. */ + lReturn = pdPASS; + } + + return lReturn; +} +/*-----------------------------------------------------------*/ + +signed long xUSARTGetChar( long lPort, signed char *pcRxedChar, portTickType xBlockTime ) +{ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +void vSerialPutString( long lPort, const signed char * const pcString, unsigned portSHORT usStringLength ) +{ +} +/*-----------------------------------------------------------*/ + +signed long xSerialPutChar( long lPort, signed char cOutChar, portTickType xBlockTime ) +{ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +void vUARTInterruptHandler( void ) +{ +long xHigherPriorityTaskWoken = pdFALSE; +char cChar; + + if( USART_GetITStatus( USART1, USART_IT_TXE ) == SET ) + { + /* The interrupt was caused by the THR becoming empty. Are there any + more characters to transmit? */ +if( 0 )// if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE ) + { + /* A character was retrieved from the queue so can be sent to the + THR now. */ + USART_SendData( USART1, cChar ); + } + else + { + USART_ITConfig( USART1, USART_IT_TXE, DISABLE ); + } + } + + if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET ) + { + cChar = USART_ReceiveData( USART1 ); +// xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken ); + } + + portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); +} + + + + + + diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/STM32_USART.h b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/STM32_USART.h new file mode 100644 index 000000000..9ef0cd66d --- /dev/null +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/Drivers/STM32_USART.h @@ -0,0 +1,60 @@ +/* + FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef STM_32_SERIAL_COMMS_H +#define STM_32_SERIAL_COMMS_H + +long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud ); + +#endif + diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/FreeRTOSConfig.h b/Demo/CORTEX_STM32F103_GCC_Rowley/FreeRTOSConfig.h index cb2fe39c4..c0ef754ca 100644 --- a/Demo/CORTEX_STM32F103_GCC_Rowley/FreeRTOSConfig.h +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/FreeRTOSConfig.h @@ -84,7 +84,7 @@ #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) #define configUSE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 0 +#define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_ALTERNATIVE_API 0 #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 @@ -115,29 +115,12 @@ NVIC value of 255. */ #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 /*----------------------------------------------------------- - * Ethernet configuration. + * UART configuration. *-----------------------------------------------------------*/ - -/* MAC address configuration. */ -#define configMAC_ADDR0 0x00 -#define configMAC_ADDR1 0x12 -#define configMAC_ADDR2 0x13 -#define configMAC_ADDR3 0x10 -#define configMAC_ADDR4 0x15 -#define configMAC_ADDR5 0x11 - -/* IP address configuration. */ -#define configIP_ADDR0 172 -#define configIP_ADDR1 25 -#define configIP_ADDR2 218 -#define configIP_ADDR3 202 - -/* Netmask configuration. */ -#define configNET_MASK0 255 -#define configNET_MASK1 255 -#define configNET_MASK2 255 -#define configNET_MASK3 0 - +#define configCOM0_RX_BUFFER_LENGTH 128 +#define configCOM0_TX_BUFFER_LENGTH 128 +#define configCOM1_RX_BUFFER_LENGTH 128 +#define configCOM1_TX_BUFFER_LENGTH 128 #endif /* FREERTOS_CONFIG_H */ diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ParTest.c b/Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ParTest_ST_Eval.c similarity index 76% rename from Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ParTest.c rename to Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ParTest_ST_Eval.c index b6288b6f3..67f0e1f27 100644 --- a/Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ParTest.c +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ParTest_ST_Eval.c @@ -60,16 +60,13 @@ #include "task.h" #include "partest.h" -/* Standard includes. */ -#include - /* Library includes. */ #include "stm32f10x_lib.h" -#define partstNUM_LEDs 8 +#define partstMAX_OUTPUT_LED ( 4 ) +#define partstFIRST_LED GPIO_Pin_6 -/* Holds the current output state for each of the LEDs. */ -static unsigned char ucBitStates[ partstNUM_LEDs ]; +static unsigned portSHORT usOutputValue = 0; /*-----------------------------------------------------------*/ @@ -77,60 +74,64 @@ void vParTestInitialise( void ) { GPIO_InitTypeDef GPIO_InitStructure; - /* Configure PE14, PD13, PD3 and PD4 output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; + /* Configure PC.06, PC.07, PC.08 and PC.09 as output push-pull */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init( GPIOB, &GPIO_InitStructure ); - - memset( ucBitStates, 0x00, sizeof( ucBitStates ) ); + GPIO_Init( GPIOC, &GPIO_InitStructure ); } /*-----------------------------------------------------------*/ void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ) { - if( uxLED < partstNUM_LEDs ) +unsigned portSHORT usBit; + + vTaskSuspendAll(); { - portENTER_CRITICAL(); + if( uxLED < partstMAX_OUTPUT_LED ) { - if( xValue != pdFALSE ) + usBit = partstFIRST_LED << uxLED; + + if( xValue == pdFALSE ) { - ucBitStates[ uxLED ] = pdTRUE; + usBit ^= ( unsigned portSHORT ) 0xffff; + usOutputValue &= usBit; } else { - ucBitStates[ uxLED ] = pdFALSE; + usOutputValue |= usBit; } - GPIO_WriteBit( GPIOB, ( GPIO_Pin_8 << uxLED ), ucBitStates[ uxLED ] ); - } - portEXIT_CRITICAL(); + GPIO_Write( GPIOC, usOutputValue ); + } } + xTaskResumeAll(); } /*-----------------------------------------------------------*/ void vParTestToggleLED( unsigned portBASE_TYPE uxLED ) { - if( uxLED < partstNUM_LEDs ) +unsigned portSHORT usBit; + + vTaskSuspendAll(); { - portENTER_CRITICAL(); + if( uxLED < partstMAX_OUTPUT_LED ) { - ucBitStates[ uxLED ] = !ucBitStates[ uxLED ]; - GPIO_WriteBit( GPIOB, ( GPIO_Pin_8 << uxLED ), ucBitStates[ uxLED ] ); + usBit = partstFIRST_LED << uxLED; + + if( usOutputValue & usBit ) + { + usOutputValue &= ~usBit; + } + else + { + usOutputValue |= usBit; + } + + GPIO_Write( GPIOC, usOutputValue ); } - portEXIT_CRITICAL(); } + xTaskResumeAll(); } /*-----------------------------------------------------------*/ -portBASE_TYPE xGetLEDState( unsigned portBASE_TYPE uxLED ) -{ - if( uxLED < partstNUM_LEDs ) - { - return ( portBASE_TYPE ) ucBitStates[ uxLED ]; - } - else - { - return 0; - } -} diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ReadMe.txt b/Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ReadMe.txt new file mode 100644 index 000000000..9836f4820 --- /dev/null +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/ParTest/ReadMe.txt @@ -0,0 +1 @@ +Only include one of the two ParTest source files in your build at any one time. \ No newline at end of file diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzp b/Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzp index 7af078806..446f0dc1c 100644 --- a/Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzp +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzp @@ -1,7 +1,7 @@ - + @@ -24,7 +24,6 @@ - @@ -36,7 +35,16 @@ - + + + + + + + + + + diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzs b/Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzs index e374461c4..53fa2ecde 100644 --- a/Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzs +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/RTOSDemo.hzs @@ -18,6 +18,10 @@ + + + + @@ -49,11 +53,11 @@ - - - - - + + + + + - + diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/main.c b/Demo/CORTEX_STM32F103_GCC_Rowley/main.c index 7aa1bc3ed..ba3761bc4 100644 --- a/Demo/CORTEX_STM32F103_GCC_Rowley/main.c +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/main.c @@ -100,28 +100,16 @@ check task has detected an error or not. */ #define mainCHECK_DELAY_ERROR ( ( portTickType ) 500 / portTICK_RATE_MS ) /* The LED controlled by the 'check' task. */ -#define mainCHECK_LED ( 7 ) +#define mainCHECK_LED ( 3 ) /* Task priorities. */ #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) -/* The WEB server has a larger stack as it utilises stack hungry string -handling library calls. */ -#define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 ) - -/* The length of the queue used to send messages to the LCD task. */ -#define mainQUEUE_SIZE ( 3 ) - -/* The period of the system clock in nano seconds. This is used to calculate -the jitter time in nano seconds. */ -#define mainNS_PER_CLOCK ( ( unsigned long ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) ) - /*-----------------------------------------------------------*/ /* @@ -222,31 +210,31 @@ static void prvSetupHardware( void ) RCC_DeInit (); /* Enable HSE. */ - RCC_HSEConfig (RCC_HSE_ON); + RCC_HSEConfig( RCC_HSE_ON ); /* Wait till HSE is ready. */ while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); /* HCLK = SYSCLK. */ - RCC_HCLKConfig (RCC_SYSCLK_Div1); + RCC_HCLKConfig( RCC_SYSCLK_Div1 ); /* PCLK2 = HCLK. */ - RCC_PCLK2Config (RCC_HCLK_Div1); + RCC_PCLK2Config( RCC_HCLK_Div1 ); /* PCLK1 = HCLK/2. */ - RCC_PCLK1Config (RCC_HCLK_Div2); + RCC_PCLK1Config( RCC_HCLK_Div2 ); /* ADCCLK = PCLK2/4. */ - RCC_ADCCLKConfig (RCC_PCLK2_Div4); + RCC_ADCCLKConfig( RCC_PCLK2_Div4 ); /* Flash 2 wait state. */ *( volatile unsigned long * )0x40022000 = 0x01; /* PLLCLK = 8MHz * 9 = 72 MHz */ - RCC_PLLConfig (RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); + RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 ); /* Enable PLL. */ - RCC_PLLCmd (ENABLE); + RCC_PLLCmd( ENABLE ); /* Wait till PLL is ready. */ while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); @@ -271,6 +259,12 @@ static void prvSetupHardware( void ) /* Initialise the IO used for the LED outputs. */ vParTestInitialise(); + + /* SPI2 Periph clock enable */ + RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE ); + + /* Initialize the SPI FLASH driver */ + SPI_FLASH_Init(); } /*-----------------------------------------------------------*/ diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/serial/serial.c b/Demo/CORTEX_STM32F103_GCC_Rowley/serial/serial.c deleted file mode 100644 index a12186090..000000000 --- a/Demo/CORTEX_STM32F103_GCC_Rowley/serial/serial.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd. - - *************************************************************************** - * * - * If you are: * - * * - * + New to FreeRTOS, * - * + Wanting to learn FreeRTOS or multitasking in general quickly * - * + Looking for basic training, * - * + Wanting to improve your FreeRTOS skills and productivity * - * * - * then take a look at the FreeRTOS eBook * - * * - * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * - * http://www.FreeRTOS.org/Documentation * - * * - * A pdf reference manual is also available. Both are usually delivered * - * to your inbox within 20 minutes to two hours when purchased between 8am * - * and 8pm GMT (although please allow up to 24 hours in case of * - * exceptional circumstances). Thank you for your support! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation AND MODIFIED BY the FreeRTOS exception. - ***NOTE*** The exception to the GPL is included to allow you to distribute - a combined work that includes FreeRTOS without being obliged to provide the - source code for proprietary components outside of the FreeRTOS kernel. - FreeRTOS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License and the FreeRTOS license exception along with FreeRTOS; if not it - can be viewed here: http://www.freertos.org/a00114.html and also obtained - by writing to Richard Barry, contact details for whom are available on the - FreeRTOS WEB site. - - 1 tab == 4 spaces! - - http://www.FreeRTOS.org - Documentation, latest information, license and - contact details. - - http://www.SafeRTOS.com - A version that is certified for use in safety - critical systems. - - http://www.OpenRTOS.com - Commercial support, development, porting, - licensing and training services. -*/ - -/* - BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART0. -*/ - -/* Scheduler includes. */ -#include "FreeRTOS.h" -#include "queue.h" -#include "semphr.h" - -/* Library includes. */ -#include "stm32f10x_lib.h" - -/* Demo application includes. */ -#include "serial.h" -/*-----------------------------------------------------------*/ - -/* Misc defines. */ -#define serINVALID_QUEUE ( ( xQueueHandle ) 0 ) -#define serNO_BLOCK ( ( portTickType ) 0 ) -#define serTX_BLOCK_TIME ( 40 / portTICK_RATE_MS ) - -/*-----------------------------------------------------------*/ - -/* The queue used to hold received characters. */ -static xQueueHandle xRxedChars; -static xQueueHandle xCharsForTx; - -/*-----------------------------------------------------------*/ - -/* UART interrupt handler. */ -void vUARTInterruptHandler( void ); - -/*-----------------------------------------------------------*/ - -/* - * See the serial2.h header file. - */ -xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) -{ -xComPortHandle xReturn; -USART_InitTypeDef USART_InitStructure; -NVIC_InitTypeDef NVIC_InitStructure; -GPIO_InitTypeDef GPIO_InitStructure; - - /* Create the queues used to hold Rx/Tx characters. */ - xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); - xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); - - /* If the queue/semaphore was created correctly then setup the serial port - hardware. */ - if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) - { - /* Enable USART1 clock */ - RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE ); - - /* Configure USART1 Rx (PA10) as input floating */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; - GPIO_Init( GPIOA, &GPIO_InitStructure ); - - /* Configure USART1 Tx (PA9) as alternate function push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init( GPIOA, &GPIO_InitStructure ); - - USART_InitStructure.USART_BaudRate = ulWantedBaud; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - - USART_Init( USART1, &USART_InitStructure ); - - USART_ITConfig( USART1, USART_IT_RXNE, ENABLE ); - - NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init( &NVIC_InitStructure ); - - USART_Cmd( USART1, ENABLE ); - } - else - { - xReturn = ( xComPortHandle ) 0; - } - - /* This demo file only supports a single port but we have to return - something to comply with the standard demo header file. */ - return xReturn; -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime ) -{ - /* The port handle is not required as this driver only supports one port. */ - ( void ) pxPort; - - /* Get the next character from the buffer. Return false if no characters - are available, or arrive before xBlockTime expires. */ - if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) ) - { - return pdTRUE; - } - else - { - return pdFALSE; - } -} -/*-----------------------------------------------------------*/ - -void vSerialPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength ) -{ -signed portCHAR *pxNext; - - /* A couple of parameters that this port does not use. */ - ( void ) usStringLength; - ( void ) pxPort; - - /* NOTE: This implementation does not handle the queue being full as no - block time is used! */ - - /* The port handle is not required as this driver only supports UART1. */ - ( void ) pxPort; - - /* Send each character in the string, one at a time. */ - pxNext = ( signed portCHAR * ) pcString; - while( *pxNext ) - { - xSerialPutChar( pxPort, *pxNext, serNO_BLOCK ); - pxNext++; - } -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime ) -{ -signed portBASE_TYPE xReturn; - - /* Just to remove the compiler warning. */ - ( void ) pxPort; - - if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS ) - { - xReturn = pdPASS; - USART_ITConfig( USART1, USART_IT_TXE, ENABLE ); - } - else - { - xReturn = pdFAIL; - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -void vUARTInterruptHandler( void ) -{ -portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; -portCHAR cChar; - - if( USART_GetITStatus( USART1, USART_IT_TXE ) == SET ) - { - /* The interrupt was caused by the THR becoming empty. Are there any - more characters to transmit? */ - if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE ) - { - /* A character was retrieved from the queue so can be sent to the - THR now. */ - USART_SendData( USART1, cChar ); - } - else - { - USART_ITConfig( USART1, USART_IT_TXE, DISABLE ); - } - } - - if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET ) - { - cChar = USART_ReceiveData( USART1 ); - xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken ); - } - - portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); -} - - - - - - diff --git a/Demo/CORTEX_STM32F103_GCC_Rowley/stm32f10x_conf.h b/Demo/CORTEX_STM32F103_GCC_Rowley/stm32f10x_conf.h index a558d035a..4baed96ec 100644 --- a/Demo/CORTEX_STM32F103_GCC_Rowley/stm32f10x_conf.h +++ b/Demo/CORTEX_STM32F103_GCC_Rowley/stm32f10x_conf.h @@ -81,7 +81,7 @@ #define _GPIO #define _GPIOA #define _GPIOB -//#define _GPIOC +#define _GPIOC #define _GPIOD #define _GPIOE //#define _GPIOF @@ -134,7 +134,7 @@ /************************************* USART **********************************/ #define _USART #define _USART1 -//#define _USART2 +#define _USART2 //#define _USART3 //#define _UART4 //#define _UART5 -- 2.39.2