BSP Drivers
Dependencies: CMSIS_STM32L4xx CMSIS_DSP_401 STM32L4xx_HAL_Driver
Revision 0:ad9dfc0179dc, committed 2015-11-02
- Comitter:
- EricLew
- Date:
- Mon Nov 02 19:38:36 2015 +0000
- Child:
- 1:996254f97479
- Child:
- 3:5ecd65e5d28b
- Commit message:
- commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_Shield/stm32_adafruit_lcd.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,1061 @@ +/** + ****************************************************************************** + * @file stm32_adafruit_lcd.c + * @author MCD Application Team + * @version V2.0.0 + * @date 10-September-2015 + * @brief This file includes the driver for Liquid Crystal Display (LCD) module + * mounted on the Adafruit 1.8" TFT LCD shield (reference ID 802), + * that is used with the STM32 Nucleo board through SPI interface. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* File Info : ----------------------------------------------------------------- + User NOTES +1. How To use this driver: +-------------------------- + - The LCD st7735 component driver MUST be included with this driver. + +2. Driver description: +--------------------- + + Initialization steps: + o Initialize the LCD using the BSP_LCD_Init() function. + + + Display on LCD + o Clear the whole LCD using the BSP_LCD_Clear() function or only one specified + string line using the BSP_LCD_ClearStringLine() function. + o Display a character on the specified line and column using the BSP_LCD_DisplayChar() + function or a complete string line using the BSP_LCD_DisplayStringAtLine() function. + o Display a string line on the specified position (x,y in pixel) and align mode + using the BSP_LCD_DisplayStringAtLine() function. + o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, ..) + on LCD using a set of functions. + +------------------------------------------------------------------------------*/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_adafruit_lcd.h" +#include "../../../Utilities/Fonts/fonts.h" +#include "../../../Utilities/Fonts/font24.c" +#include "../../../Utilities/Fonts/font20.c" +#include "../../../Utilities/Fonts/font16.c" +#include "../../../Utilities/Fonts/font12.c" +#include "../../../Utilities/Fonts/font8.c" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32_ADAFRUIT + * @{ + */ + +/** @addtogroup STM32_ADAFRUIT_LCD + * @{ + */ + +/** @defgroup STM32_ADAFRUIT_LCD_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_LCD_Private_Defines + * @{ + */ +#define POLY_X(Z) ((int32_t)((Points + (Z))->X)) +#define POLY_Y(Z) ((int32_t)((Points + (Z))->Y)) +#define NULL (void *)0 + +#define MAX_HEIGHT_FONT 17 +#define MAX_WIDTH_FONT 24 +#define OFFSET_BITMAP 54 +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_LCD_Private_Macros + * @{ + */ +#define ABS(X) ((X) > 0 ? (X) : -(X)) + +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_LCD_Private_Variables + * @{ + */ +LCD_DrawPropTypeDef DrawProp; + +static LCD_DrvTypeDef *lcd_drv; + +/* Max size of bitmap will based on a font24 (17x24) */ +static uint8_t bitmap[MAX_HEIGHT_FONT*MAX_WIDTH_FONT*2+OFFSET_BITMAP] = {0}; + +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_LCD_Private_FunctionPrototypes + * @{ + */ +static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c); +static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3); +static void SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height); +/** + * @} + */ + + +/** @defgroup STM32_ADAFRUIT_LCD_Private_Functions + * @{ + */ + +/** + * @brief Initializes the LCD. + * @param None + * @retval LCD state + */ +uint8_t BSP_LCD_Init(void) +{ + uint8_t ret = LCD_ERROR; + + /* Default value for draw propriety */ + DrawProp.BackColor = 0xFFFF; + DrawProp.pFont = &Font24; + DrawProp.TextColor = 0x0000; + + lcd_drv = &st7735_drv; + + /* LCD Init */ + lcd_drv->Init(); + + /* Clear the LCD screen */ + BSP_LCD_Clear(LCD_COLOR_WHITE); + + /* Initialize the font */ + BSP_LCD_SetFont(&LCD_DEFAULT_FONT); + + ret = LCD_OK; + + return ret; +} + +/** + * @brief Gets the LCD X size. + * @param None + * @retval Used LCD X size + */ +uint32_t BSP_LCD_GetXSize(void) +{ + return(lcd_drv->GetLcdPixelWidth()); +} + +/** + * @brief Gets the LCD Y size. + * @param None + * @retval Used LCD Y size + */ +uint32_t BSP_LCD_GetYSize(void) +{ + return(lcd_drv->GetLcdPixelHeight()); +} + +/** + * @brief Gets the LCD text color. + * @param None + * @retval Used text color. + */ +uint16_t BSP_LCD_GetTextColor(void) +{ + return DrawProp.TextColor; +} + +/** + * @brief Gets the LCD background color. + * @param None + * @retval Used background color + */ +uint16_t BSP_LCD_GetBackColor(void) +{ + return DrawProp.BackColor; +} + +/** + * @brief Sets the LCD text color. + * @param Color: Text color code RGB(5-6-5) + * @retval None + */ +void BSP_LCD_SetTextColor(uint16_t Color) +{ + DrawProp.TextColor = Color; +} + +/** + * @brief Sets the LCD background color. + * @param Color: Background color code RGB(5-6-5) + * @retval None + */ +void BSP_LCD_SetBackColor(uint16_t Color) +{ + DrawProp.BackColor = Color; +} + +/** + * @brief Sets the LCD text font. + * @param fonts: Font to be used + * @retval None + */ +void BSP_LCD_SetFont(sFONT *pFonts) +{ + DrawProp.pFont = pFonts; +} + +/** + * @brief Gets the LCD text font. + * @param None + * @retval Used font + */ +sFONT *BSP_LCD_GetFont(void) +{ + return DrawProp.pFont; +} + +/** + * @brief Clears the hole LCD. + * @param Color: Color of the background + * @retval None + */ +void BSP_LCD_Clear(uint16_t Color) +{ + uint32_t counter = 0; + uint32_t color_backup = DrawProp.TextColor; + DrawProp.TextColor = Color; + + for(counter = 0; counter < BSP_LCD_GetYSize(); counter++) + { + BSP_LCD_DrawHLine(0, counter, BSP_LCD_GetXSize()); + } + DrawProp.TextColor = color_backup; + BSP_LCD_SetTextColor(DrawProp.TextColor); +} + +/** + * @brief Clears the selected line. + * @param Line: Line to be cleared + * This parameter can be one of the following values: + * @arg 0..9: if the Current fonts is Font16x24 + * @arg 0..19: if the Current fonts is Font12x12 or Font8x12 + * @arg 0..29: if the Current fonts is Font8x8 + * @retval None + */ +void BSP_LCD_ClearStringLine(uint16_t Line) +{ + uint32_t color_backup = DrawProp.TextColor; + DrawProp.TextColor = DrawProp.BackColor;; + + /* Draw a rectangle with background color */ + BSP_LCD_FillRect(0, (Line * DrawProp.pFont->Height), BSP_LCD_GetXSize(), DrawProp.pFont->Height); + + DrawProp.TextColor = color_backup; + BSP_LCD_SetTextColor(DrawProp.TextColor); +} + +/** + * @brief Displays one character. + * @param Xpos: Start column address + * @param Ypos: Line where to display the character shape. + * @param Ascii: Character ascii code + * This parameter must be a number between Min_Data = 0x20 and Max_Data = 0x7E + * @retval None + */ +void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii) +{ + DrawChar(Xpos, Ypos, &DrawProp.pFont->table[(Ascii-' ') *\ + DrawProp.pFont->Height * ((DrawProp.pFont->Width + 7) / 8)]); +} + +/** + * @brief Displays characters on the LCD. + * @param Xpos: X position (in pixel) + * @param Ypos: Y position (in pixel) + * @param Text: Pointer to string to display on LCD + * @param Mode: Display mode + * This parameter can be one of the following values: + * @arg CENTER_MODE + * @arg RIGHT_MODE + * @arg LEFT_MODE + * @retval None + */ +void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Line_ModeTypdef Mode) +{ + uint16_t refcolumn = 1, i = 0; + uint32_t size = 0, xsize = 0; + uint8_t *ptr = Text; + + /* Get the text size */ + while (*ptr++) size ++ ; + + /* Characters number per line */ + xsize = (BSP_LCD_GetXSize()/DrawProp.pFont->Width); + + switch (Mode) + { + case CENTER_MODE: + { + refcolumn = Xpos + ((xsize - size)* DrawProp.pFont->Width) / 2; + break; + } + case LEFT_MODE: + { + refcolumn = Xpos; + break; + } + case RIGHT_MODE: + { + refcolumn = - Xpos + ((xsize - size)*DrawProp.pFont->Width); + break; + } + default: + { + refcolumn = Xpos; + break; + } + } + + /* Send the string character by character on lCD */ + while ((*Text != 0) & (((BSP_LCD_GetXSize() - (i*DrawProp.pFont->Width)) & 0xFFFF) >= DrawProp.pFont->Width)) + { + /* Display one character on LCD */ + BSP_LCD_DisplayChar(refcolumn, Ypos, *Text); + /* Decrement the column position by 16 */ + refcolumn += DrawProp.pFont->Width; + /* Point on the next character */ + Text++; + i++; + } +} + +/** + * @brief Displays a character on the LCD. + * @param Line: Line where to display the character shape + * This parameter can be one of the following values: + * @arg 0..19: if the Current fonts is Font8 + * @arg 0..12: if the Current fonts is Font12 + * @arg 0...9: if the Current fonts is Font16 + * @arg 0...7: if the Current fonts is Font20 + * @arg 0...5: if the Current fonts is Font24 + * @param ptr: Pointer to string to display on LCD + * @retval None + */ +void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr) +{ + BSP_LCD_DisplayStringAt(0, LINE(Line), ptr, LEFT_MODE); +} + +/** + * @brief Draws a pixel on LCD. + * @param Xpos: X position + * @param Ypos: Y position + * @param RGB_Code: Pixel color in RGB mode (5-6-5) + * @retval None + */ +void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGB_Code) +{ + if(lcd_drv->WritePixel != NULL) + { + lcd_drv->WritePixel(Xpos, Ypos, RGB_Code); + } +} + +/** + * @brief Draws an horizontal line. + * @param Xpos: X position + * @param Ypos: Y position + * @param Length: Line length + * @retval None + */ +void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length) +{ + uint32_t index = 0; + + if(lcd_drv->DrawHLine != NULL) + { + lcd_drv->DrawHLine(DrawProp.TextColor, Xpos, Ypos, Length); + } + else + { + for(index = 0; index < Length; index++) + { + BSP_LCD_DrawPixel((Xpos + index), Ypos, DrawProp.TextColor); + } + } +} + +/** + * @brief Draws a vertical line. + * @param Xpos: X position + * @param Ypos: Y position + * @param Length: Line length + * @retval None + */ +void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length) +{ + uint32_t index = 0; + + if(lcd_drv->DrawVLine != NULL) + { + lcd_drv->DrawVLine(DrawProp.TextColor, Xpos, Ypos, Length); + } + else + { + for(index = 0; index < Length; index++) + { + BSP_LCD_DrawPixel(Xpos, Ypos + index, DrawProp.TextColor); + } + } +} + +/** + * @brief Draws an uni-line (between two points). + * @param x1: Point 1 X position + * @param y1: Point 1 Y position + * @param x2: Point 2 X position + * @param y2: Point 2 Y position + * @retval None + */ +void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) +{ + int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, + yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, + curpixel = 0; + + deltax = ABS(x2 - x1); /* The difference between the x's */ + deltay = ABS(y2 - y1); /* The difference between the y's */ + x = x1; /* Start x off at the first pixel */ + y = y1; /* Start y off at the first pixel */ + + if (x2 >= x1) /* The x-values are increasing */ + { + xinc1 = 1; + xinc2 = 1; + } + else /* The x-values are decreasing */ + { + xinc1 = -1; + xinc2 = -1; + } + + if (y2 >= y1) /* The y-values are increasing */ + { + yinc1 = 1; + yinc2 = 1; + } + else /* The y-values are decreasing */ + { + yinc1 = -1; + yinc2 = -1; + } + + if (deltax >= deltay) /* There is at least one x-value for every y-value */ + { + xinc1 = 0; /* Don't change the x when numerator >= denominator */ + yinc2 = 0; /* Don't change the y for every iteration */ + den = deltax; + num = deltax / 2; + numadd = deltay; + numpixels = deltax; /* There are more x-values than y-values */ + } + else /* There is at least one y-value for every x-value */ + { + xinc2 = 0; /* Don't change the x for every iteration */ + yinc1 = 0; /* Don't change the y when numerator >= denominator */ + den = deltay; + num = deltay / 2; + numadd = deltax; + numpixels = deltay; /* There are more y-values than x-values */ + } + + for (curpixel = 0; curpixel <= numpixels; curpixel++) + { + BSP_LCD_DrawPixel(x, y, DrawProp.TextColor); /* Draw the current pixel */ + num += numadd; /* Increase the numerator by the top of the fraction */ + if (num >= den) /* Check if numerator >= denominator */ + { + num -= den; /* Calculate the new numerator value */ + x += xinc1; /* Change the x as appropriate */ + y += yinc1; /* Change the y as appropriate */ + } + x += xinc2; /* Change the x as appropriate */ + y += yinc2; /* Change the y as appropriate */ + } +} + +/** + * @brief Draws a rectangle. + * @param Xpos: X position + * @param Ypos: Y position + * @param Width: Rectangle width + * @param Height: Rectangle height + * @retval None + */ +void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) +{ + /* Draw horizontal lines */ + BSP_LCD_DrawHLine(Xpos, Ypos, Width); + BSP_LCD_DrawHLine(Xpos, (Ypos+ Height), Width); + + /* Draw vertical lines */ + BSP_LCD_DrawVLine(Xpos, Ypos, Height); + BSP_LCD_DrawVLine((Xpos + Width), Ypos, Height); +} + +/** + * @brief Draws a circle. + * @param Xpos: X position + * @param Ypos: Y position + * @param Radius: Circle radius + * @retval None + */ +void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius) +{ + int32_t D; /* Decision Variable */ + uint32_t CurX; /* Current X Value */ + uint32_t CurY; /* Current Y Value */ + + D = 3 - (Radius << 1); + CurX = 0; + CurY = Radius; + + while (CurX <= CurY) + { + BSP_LCD_DrawPixel((Xpos + CurX), (Ypos - CurY), DrawProp.TextColor); + + BSP_LCD_DrawPixel((Xpos - CurX), (Ypos - CurY), DrawProp.TextColor); + + BSP_LCD_DrawPixel((Xpos + CurY), (Ypos - CurX), DrawProp.TextColor); + + BSP_LCD_DrawPixel((Xpos - CurY), (Ypos - CurX), DrawProp.TextColor); + + BSP_LCD_DrawPixel((Xpos + CurX), (Ypos + CurY), DrawProp.TextColor); + + BSP_LCD_DrawPixel((Xpos - CurX), (Ypos + CurY), DrawProp.TextColor); + + BSP_LCD_DrawPixel((Xpos + CurY), (Ypos + CurX), DrawProp.TextColor); + + BSP_LCD_DrawPixel((Xpos - CurY), (Ypos + CurX), DrawProp.TextColor); + + /* Initialize the font */ + BSP_LCD_SetFont(&LCD_DEFAULT_FONT); + + if (D < 0) + { + D += (CurX << 2) + 6; + } + else + { + D += ((CurX - CurY) << 2) + 10; + CurY--; + } + CurX++; + } +} + +/** + * @brief Draws an poly-line (between many points). + * @param Points: Pointer to the points array + * @param PointCount: Number of points + * @retval None + */ +void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount) +{ + int16_t X = 0, Y = 0; + + if(PointCount < 2) + { + return; + } + + BSP_LCD_DrawLine(Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y); + + while(--PointCount) + { + X = Points->X; + Y = Points->Y; + Points++; + BSP_LCD_DrawLine(X, Y, Points->X, Points->Y); + } +} + +/** + * @brief Draws an ellipse on LCD. + * @param Xpos: X position + * @param Ypos: Y position + * @param XRadius: Ellipse X radius + * @param YRadius: Ellipse Y radius + * @retval None + */ +void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius) +{ + int x = 0, y = -YRadius, err = 2-2*XRadius, e2; + float K = 0, rad1 = 0, rad2 = 0; + + rad1 = XRadius; + rad2 = YRadius; + + K = (float)(rad2/rad1); + + do { + BSP_LCD_DrawPixel((Xpos-(uint16_t)(x/K)), (Ypos+y), DrawProp.TextColor); + BSP_LCD_DrawPixel((Xpos+(uint16_t)(x/K)), (Ypos+y), DrawProp.TextColor); + BSP_LCD_DrawPixel((Xpos+(uint16_t)(x/K)), (Ypos-y), DrawProp.TextColor); + BSP_LCD_DrawPixel((Xpos-(uint16_t)(x/K)), (Ypos-y), DrawProp.TextColor); + + e2 = err; + if (e2 <= x) { + err += ++x*2+1; + if (-y == x && e2 <= y) e2 = 0; + } + if (e2 > y) err += ++y*2+1; + } + while (y <= 0); +} + +/** + * @brief Draws a bitmap picture loaded in the STM32 MCU internal memory. + * @param Xpos: Bmp X position in the LCD + * @param Ypos: Bmp Y position in the LCD + * @param pBmp: Pointer to Bmp picture address + * @retval None + */ +void BSP_LCD_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pBmp) +{ + uint32_t height = 0, width = 0; + + /* Read bitmap width */ + width = *(uint16_t *) (pBmp + 18); + width |= (*(uint16_t *) (pBmp + 20)) << 16; + + /* Read bitmap height */ + height = *(uint16_t *) (pBmp + 22); + height |= (*(uint16_t *) (pBmp + 24)) << 16; + + /* Remap Ypos, st7735 works with inverted X in case of bitmap */ + /* X = 0, cursor is on Top corner */ + if(lcd_drv == &st7735_drv) + { + Ypos = BSP_LCD_GetYSize() - Ypos - height; + } + + SetDisplayWindow(Xpos, Ypos, width, height); + + if(lcd_drv->DrawBitmap != NULL) + { + lcd_drv->DrawBitmap(Xpos, Ypos, pBmp); + } + SetDisplayWindow(0, 0, BSP_LCD_GetXSize(), BSP_LCD_GetYSize()); +} + +/** + * @brief Draws a full rectangle. + * @param Xpos: X position + * @param Ypos: Y position + * @param Width: Rectangle width + * @param Height: Rectangle height + * @retval None + */ +void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) +{ + BSP_LCD_SetTextColor(DrawProp.TextColor); + do + { + BSP_LCD_DrawHLine(Xpos, Ypos++, Width); + } + while(Height--); +} + +/** + * @brief Draws a full circle. + * @param Xpos: X position + * @param Ypos: Y position + * @param Radius: Circle radius + * @retval None + */ +void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius) +{ + int32_t D; /* Decision Variable */ + uint32_t CurX; /* Current X Value */ + uint32_t CurY; /* Current Y Value */ + + D = 3 - (Radius << 1); + + CurX = 0; + CurY = Radius; + + BSP_LCD_SetTextColor(DrawProp.TextColor); + + while (CurX <= CurY) + { + if(CurY > 0) + { + BSP_LCD_DrawHLine(Xpos - CurY, Ypos + CurX, 2*CurY); + BSP_LCD_DrawHLine(Xpos - CurY, Ypos - CurX, 2*CurY); + } + + if(CurX > 0) + { + BSP_LCD_DrawHLine(Xpos - CurX, Ypos - CurY, 2*CurX); + BSP_LCD_DrawHLine(Xpos - CurX, Ypos + CurY, 2*CurX); + } + if (D < 0) + { + D += (CurX << 2) + 6; + } + else + { + D += ((CurX - CurY) << 2) + 10; + CurY--; + } + CurX++; + } + + BSP_LCD_SetTextColor(DrawProp.TextColor); + BSP_LCD_DrawCircle(Xpos, Ypos, Radius); +} + +/** + * @brief Draws a full poly-line (between many points). + * @param Points: Pointer to the points array + * @param PointCount: Number of points + * @retval None + */ +void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount) +{ + int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0; + uint16_t IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0; + + IMAGE_LEFT = IMAGE_RIGHT = Points->X; + IMAGE_TOP= IMAGE_BOTTOM = Points->Y; + + for(counter = 1; counter < PointCount; counter++) + { + pixelX = POLY_X(counter); + if(pixelX < IMAGE_LEFT) + { + IMAGE_LEFT = pixelX; + } + if(pixelX > IMAGE_RIGHT) + { + IMAGE_RIGHT = pixelX; + } + + pixelY = POLY_Y(counter); + if(pixelY < IMAGE_TOP) + { + IMAGE_TOP = pixelY; + } + if(pixelY > IMAGE_BOTTOM) + { + IMAGE_BOTTOM = pixelY; + } + } + + if(PointCount < 2) + { + return; + } + + X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2; + Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2; + + X_first = Points->X; + Y_first = Points->Y; + + while(--PointCount) + { + X = Points->X; + Y = Points->Y; + Points++; + X2 = Points->X; + Y2 = Points->Y; + + FillTriangle(X, X2, X_center, Y, Y2, Y_center); + FillTriangle(X, X_center, X2, Y, Y_center, Y2); + FillTriangle(X_center, X2, X, Y_center, Y2, Y); + } + + FillTriangle(X_first, X2, X_center, Y_first, Y2, Y_center); + FillTriangle(X_first, X_center, X2, Y_first, Y_center, Y2); + FillTriangle(X_center, X2, X_first, Y_center, Y2, Y_first); +} + +/** + * @brief Draws a full ellipse. + * @param Xpos: X position + * @param Ypos: Y position + * @param XRadius: Ellipse X radius + * @param YRadius: Ellipse Y radius + * @retval None + */ +void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius) +{ + int x = 0, y = -YRadius, err = 2-2*XRadius, e2; + float K = 0, rad1 = 0, rad2 = 0; + + rad1 = XRadius; + rad2 = YRadius; + + K = (float)(rad2/rad1); + + do + { + BSP_LCD_DrawHLine((Xpos-(uint16_t)(x/K)), (Ypos+y), (2*(uint16_t)(x/K) + 1)); + BSP_LCD_DrawHLine((Xpos-(uint16_t)(x/K)), (Ypos-y), (2*(uint16_t)(x/K) + 1)); + + e2 = err; + if (e2 <= x) + { + err += ++x*2+1; + if (-y == x && e2 <= y) e2 = 0; + } + if (e2 > y) err += ++y*2+1; + } + while (y <= 0); +} + +/** + * @brief Enables the display. + * @param None + * @retval None + */ +void BSP_LCD_DisplayOn(void) +{ + lcd_drv->DisplayOn(); +} + +/** + * @brief Disables the display. + * @param None + * @retval None + */ +void BSP_LCD_DisplayOff(void) +{ + lcd_drv->DisplayOff(); +} + +/******************************************************************************* + Static Functions +*******************************************************************************/ + +/** + * @brief Draws a character on LCD. + * @param Xpos: Line where to display the character shape + * @param Ypos: Start column address + * @param pChar: Pointer to the character data + * @retval None + */ +static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *pChar) +{ + uint32_t counterh = 0, counterw = 0, index = 0; + uint16_t height = 0, width = 0; + uint8_t offset = 0; + uint8_t *pchar = NULL; + uint32_t line = 0; + + height = DrawProp.pFont->Height; + width = DrawProp.pFont->Width; + + /* Fill bitmap header*/ + *(uint16_t *) (bitmap + 2) = (uint16_t)(height*width*2+OFFSET_BITMAP); + *(uint16_t *) (bitmap + 4) = (uint16_t)((height*width*2+OFFSET_BITMAP)>>16); + *(uint16_t *) (bitmap + 10) = OFFSET_BITMAP; + *(uint16_t *) (bitmap + 18) = (uint16_t)(width); + *(uint16_t *) (bitmap + 20) = (uint16_t)((width)>>16); + *(uint16_t *) (bitmap + 22) = (uint16_t)(height); + *(uint16_t *) (bitmap + 24) = (uint16_t)((height)>>16); + + offset = 8 *((width + 7)/8) - width ; + + for(counterh = 0; counterh < height; counterh++) + { + pchar = ((uint8_t *)pChar + (width + 7)/8 * counterh); + + if(((width + 7)/8) == 3) + { + line = (pchar[0]<< 16) | (pchar[1]<< 8) | pchar[2]; + } + + if(((width + 7)/8) == 2) + { + line = (pchar[0]<< 8) | pchar[1]; + } + + if(((width + 7)/8) == 1) + { + line = pchar[0]; + } + + for (counterw = 0; counterw < width; counterw++) + { + /* Image in the bitmap is written from the bottom to the top */ + /* Need to invert image in the bitmap */ + index = (((height-counterh-1)*width)+(counterw))*2+OFFSET_BITMAP; + if(line & (1 << (width- counterw + offset- 1))) + { + bitmap[index] = (uint8_t)DrawProp.TextColor; + bitmap[index+1] = (uint8_t)(DrawProp.TextColor >> 8); + } + else + { + bitmap[index] = (uint8_t)DrawProp.BackColor; + bitmap[index+1] = (uint8_t)(DrawProp.BackColor >> 8); + } + } + } + + BSP_LCD_DrawBitmap(Xpos, Ypos, bitmap); +} + +/** + * @brief Fills a triangle (between 3 points). + * @param Points: Pointer to the points array + * @param x1: Point 1 X position + * @param y1: Point 1 Y position + * @param x2: Point 2 X position + * @param y2: Point 2 Y position + * @param x3: Point 3 X position + * @param y3: Point 3 Y position + * @retval None + */ +static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3) +{ + int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, + yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, + curpixel = 0; + + deltax = ABS(x2 - x1); /* The difference between the x's */ + deltay = ABS(y2 - y1); /* The difference between the y's */ + x = x1; /* Start x off at the first pixel */ + y = y1; /* Start y off at the first pixel */ + + if (x2 >= x1) /* The x-values are increasing */ + { + xinc1 = 1; + xinc2 = 1; + } + else /* The x-values are decreasing */ + { + xinc1 = -1; + xinc2 = -1; + } + + if (y2 >= y1) /* The y-values are increasing */ + { + yinc1 = 1; + yinc2 = 1; + } + else /* The y-values are decreasing */ + { + yinc1 = -1; + yinc2 = -1; + } + + if (deltax >= deltay) /* There is at least one x-value for every y-value */ + { + xinc1 = 0; /* Don't change the x when numerator >= denominator */ + yinc2 = 0; /* Don't change the y for every iteration */ + den = deltax; + num = deltax / 2; + numadd = deltay; + numpixels = deltax; /* There are more x-values than y-values */ + } + else /* There is at least one y-value for every x-value */ + { + xinc2 = 0; /* Don't change the x for every iteration */ + yinc1 = 0; /* Don't change the y when numerator >= denominator */ + den = deltay; + num = deltay / 2; + numadd = deltax; + numpixels = deltay; /* There are more y-values than x-values */ + } + + for (curpixel = 0; curpixel <= numpixels; curpixel++) + { + BSP_LCD_DrawLine(x, y, x3, y3); + + num += numadd; /* Increase the numerator by the top of the fraction */ + if (num >= den) /* Check if numerator >= denominator */ + { + num -= den; /* Calculate the new numerator value */ + x += xinc1; /* Change the x as appropriate */ + y += yinc1; /* Change the y as appropriate */ + } + x += xinc2; /* Change the x as appropriate */ + y += yinc2; /* Change the y as appropriate */ + } +} + +/** + * @brief Sets display window. + * @param LayerIndex: layer index + * @param Xpos: LCD X position + * @param Ypos: LCD Y position + * @param Width: LCD window width + * @param Height: LCD window height + * @retval None + */ +static void SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) +{ + if(lcd_drv->SetDisplayWindow != NULL) + { + lcd_drv->SetDisplayWindow(Xpos, Ypos, Width, Height); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_Shield/stm32_adafruit_lcd.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,198 @@ +/** + ****************************************************************************** + * @file stm32_adafruit_lcd.h + * @author MCD Application Team + * @version V2.0.0 + * @date 10-September-2015 + * @brief This file contains the common defines and functions prototypes for + * the stm32_adafruit_lcd.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_ADAFRUIT_LCD_H +#define __STM32_ADAFRUIT_LCD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "../Components/st7735/st7735.h" +#include "../../../Utilities/Fonts/fonts.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32_ADAFRUIT + * @{ + */ + +/** @addtogroup STM32_ADAFRUIT_LCD + * @{ + */ + + +/** @defgroup STM32_ADAFRUIT_LCD_Exported_Types + * @{ + */ + +/** + * @brief Draw Properties structures definition + */ +typedef struct +{ + uint32_t TextColor; + uint32_t BackColor; + sFONT *pFont; + +}LCD_DrawPropTypeDef; + +/** + * @brief Point structures definition + */ +typedef struct +{ + int16_t X; + int16_t Y; + +}Point, * pPoint; + +/** + * @brief Line mode structures definition + */ +typedef enum +{ + CENTER_MODE = 0x01, /*!< Center mode */ + RIGHT_MODE = 0x02, /*!< Right mode */ + LEFT_MODE = 0x03 /*!< Left mode */ + +}Line_ModeTypdef; + +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_LCD_Exported_Constants + * @{ + */ + +#define __IO volatile + +/** + * @brief LCD status structure definition + */ +#define LCD_OK 0x00 +#define LCD_ERROR 0x01 +#define LCD_TIMEOUT 0x02 + +/** + * @brief LCD color + */ +#define LCD_COLOR_BLACK 0x0000 +#define LCD_COLOR_GREY 0xF7DE +#define LCD_COLOR_BLUE 0x001F +#define LCD_COLOR_RED 0xF800 +#define LCD_COLOR_GREEN 0x07E0 +#define LCD_COLOR_CYAN 0x07FF +#define LCD_COLOR_MAGENTA 0xF81F +#define LCD_COLOR_YELLOW 0xFFE0 +#define LCD_COLOR_WHITE 0xFFFF + +/** + * @brief LCD default font + */ +#define LCD_DEFAULT_FONT Font8 + +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_LCD_Exported_Functions + * @{ + */ +uint8_t BSP_LCD_Init(void); +uint32_t BSP_LCD_GetXSize(void); +uint32_t BSP_LCD_GetYSize(void); + +uint16_t BSP_LCD_GetTextColor(void); +uint16_t BSP_LCD_GetBackColor(void); +void BSP_LCD_SetTextColor(__IO uint16_t Color); +void BSP_LCD_SetBackColor(__IO uint16_t Color); +void BSP_LCD_SetFont(sFONT *fonts); +sFONT *BSP_LCD_GetFont(void); + +void BSP_LCD_Clear(uint16_t Color); +void BSP_LCD_ClearStringLine(uint16_t Line); +void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr); +void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Line_ModeTypdef Mode); +void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii); + +void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGB_Code); +void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length); +void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length); +void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); +void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height); +void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius); +void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount); +void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius); +void BSP_LCD_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pBmp); +void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height); +void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius); +void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount); +void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius); + +void BSP_LCD_DisplayOff(void); +void BSP_LCD_DisplayOn(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_ADAFRUIT_LCD_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_Shield/stm32_adafruit_sd.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,1025 @@ +/** + ****************************************************************************** + * @file stm32_adafruit_sd.c + * @author MCD Application Team + * @version V2.0.0 + * @date 10-September-2015 + * @brief This file provides a set of functions needed to manage the SD card + * mounted on the Adafruit 1.8" TFT LCD shield (reference ID 802), + * that is used with the STM32 Nucleo board through SPI interface. + * It implements a high level communication layer for read and write + * from/to this memory. The needed STM32XXxx hardware resources (SPI and + * GPIO) are defined in stm32XXxx_nucleo.h file, and the initialization is + * performed in SD_IO_Init() function declared in stm32XXxx_nucleo.c + * file. + * You can easily tailor this driver to any other development board, + * by just adapting the defines for hardware resources and + * SD_IO_Init() function. + * + * +-------------------------------------------------------+ + * | Pin assignment | + * +-------------------------+---------------+-------------+ + * | STM32XXxx SPI Pins | SD | Pin | + * +-------------------------+---------------+-------------+ + * | SD_SPI_CS_PIN | ChipSelect | 1 | + * | SD_SPI_MOSI_PIN / MOSI | DataIn | 2 | + * | | GND | 3 (0 V) | + * | | VDD | 4 (3.3 V)| + * | SD_SPI_SCK_PIN / SCLK | Clock | 5 | + * | | GND | 6 (0 V) | + * | SD_SPI_MISO_PIN / MISO | DataOut | 7 | + * +-------------------------+---------------+-------------+ + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* File Info : ----------------------------------------------------------------- + User NOTES +1. How to use this driver: +-------------------------- + - This driver does not need a specific component driver for the micro SD device + to be included with. + +2. Driver description: +--------------------- + + Initialization steps: + o Initialize the micro SD card using the BSP_SD_Init() function. + o Checking the SD card presence is not managed because SD detection pin is + not physically mapped on the Adafruit shield. + o The function BSP_SD_GetCardInfo() is used to get the micro SD card information + which is stored in the structure "SD_CardInfo". + + + Micro SD card operations + o The micro SD card can be accessed with read/write block(s) operations once + it is ready for access. The access can be performed in polling + mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks() + + o The SD erase block(s) is performed using the function BSP_SD_Erase() with + specifying the number of blocks to erase. + o The SD runtime status is returned when calling the function BSP_SD_GetStatus(). + +------------------------------------------------------------------------------*/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_adafruit_sd.h" +#include "stdlib.h" +#include "string.h" +#include "stdio.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32_ADAFRUIT + * @{ + */ + +/** @defgroup STM32_ADAFRUIT_SD + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Types_Definitions + * @{ + */ +typedef struct { + uint8_t r1; + uint8_t r2; + uint8_t r3; + uint8_t r4; + uint8_t r5; +} SD_CmdAnswer_typedef; + +/** + * @} + */ + +/* Private define ------------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Defines + * @{ + */ +#define SD_DUMMY_BYTE 0xFF + +#define SD_MAX_FRAME_LENGTH 17 /* Lenght = 16 + 1 */ +#define SD_CMD_LENGTH 6 + +#define SD_MAX_TRY 100 /* Number of try */ + +#define SD_CSD_STRUCT_V1 0x2 /* CSD struct version V1 */ +#define SD_CSD_STRUCT_V2 0x1 /* CSD struct version V2 */ + + +/** + * @brief SD ansewer format + */ +typedef enum { + SD_ANSWER_R1_EXPECTED, + SD_ANSWER_R1B_EXPECTED, + SD_ANSWER_R2_EXPECTED, + SD_ANSWER_R3_EXPECTED, + SD_ANSWER_R4R5_EXPECTED, + SD_ANSWER_R7_EXPECTED, +}SD_Answer_type; + +/** + * @brief Start Data tokens: + * Tokens (necessary because at nop/idle (and CS active) only 0xff is + * on the data/command line) + */ +#define SD_TOKEN_START_DATA_SINGLE_BLOCK_READ 0xFE /* Data token start byte, Start Single Block Read */ +#define SD_TOKEN_START_DATA_MULTIPLE_BLOCK_READ 0xFE /* Data token start byte, Start Multiple Block Read */ +#define SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE 0xFE /* Data token start byte, Start Single Block Write */ +#define SD_TOKEN_START_DATA_MULTIPLE_BLOCK_WRITE 0xFD /* Data token start byte, Start Multiple Block Write */ +#define SD_TOKEN_STOP_DATA_MULTIPLE_BLOCK_WRITE 0xFD /* Data toke stop byte, Stop Multiple Block Write */ + +/** + * @brief Commands: CMDxx = CMD-number | 0x40 + */ +#define SD_CMD_GO_IDLE_STATE 0 /* CMD0 = 0x40 */ +#define SD_CMD_SEND_OP_COND 1 /* CMD1 = 0x41 */ +#define SD_CMD_SEND_IF_COND 8 /* CMD8 = 0x48 */ +#define SD_CMD_SEND_CSD 9 /* CMD9 = 0x49 */ +#define SD_CMD_SEND_CID 10 /* CMD10 = 0x4A */ +#define SD_CMD_STOP_TRANSMISSION 12 /* CMD12 = 0x4C */ +#define SD_CMD_SEND_STATUS 13 /* CMD13 = 0x4D */ +#define SD_CMD_SET_BLOCKLEN 16 /* CMD16 = 0x50 */ +#define SD_CMD_READ_SINGLE_BLOCK 17 /* CMD17 = 0x51 */ +#define SD_CMD_READ_MULT_BLOCK 18 /* CMD18 = 0x52 */ +#define SD_CMD_SET_BLOCK_COUNT 23 /* CMD23 = 0x57 */ +#define SD_CMD_WRITE_SINGLE_BLOCK 24 /* CMD24 = 0x58 */ +#define SD_CMD_WRITE_MULT_BLOCK 25 /* CMD25 = 0x59 */ +#define SD_CMD_PROG_CSD 27 /* CMD27 = 0x5B */ +#define SD_CMD_SET_WRITE_PROT 28 /* CMD28 = 0x5C */ +#define SD_CMD_CLR_WRITE_PROT 29 /* CMD29 = 0x5D */ +#define SD_CMD_SEND_WRITE_PROT 30 /* CMD30 = 0x5E */ +#define SD_CMD_SD_ERASE_GRP_START 32 /* CMD32 = 0x60 */ +#define SD_CMD_SD_ERASE_GRP_END 33 /* CMD33 = 0x61 */ +#define SD_CMD_UNTAG_SECTOR 34 /* CMD34 = 0x62 */ +#define SD_CMD_ERASE_GRP_START 35 /* CMD35 = 0x63 */ +#define SD_CMD_ERASE_GRP_END 36 /* CMD36 = 0x64 */ +#define SD_CMD_UNTAG_ERASE_GROUP 37 /* CMD37 = 0x65 */ +#define SD_CMD_ERASE 38 /* CMD38 = 0x66 */ +#define SD_CMD_SD_APP_OP_COND 41 /* CMD41 = 0x69 */ +#define SD_CMD_APP_CMD 55 /* CMD55 = 0x77 */ +#define SD_CMD_READ_OCR 58 /* CMD55 = 0x79 */ + +/** + * @brief SD reponses and error flags + */ +typedef enum +{ +/* R1 answer value */ + SD_R1_NO_ERROR = (0x00), + SD_R1_IN_IDLE_STATE = (0x01), + SD_R1_ERASE_RESET = (0x02), + SD_R1_ILLEGAL_COMMAND = (0x04), + SD_R1_COM_CRC_ERROR = (0x08), + SD_R1_ERASE_SEQUENCE_ERROR= (0x10), + SD_R1_ADDRESS_ERROR = (0x20), + SD_R1_PARAMETER_ERROR = (0x40), + +/* R2 answer value */ + SD_R2_NO_ERROR = 0x00, + SD_R2_CARD_LOCKED = 0x01, + SD_R2_LOCKUNLOCK_ERROR = 0x02, + SD_R2_ERROR = 0x04, + SD_R2_CC_ERROR = 0x08, + SD_R2_CARD_ECC_FAILED = 0x10, + SD_R2_WP_VIOLATION = 0x20, + SD_R2_ERASE_PARAM = 0x40, + SD_R2_OUTOFRANGE = 0x80, + +/** + * @brief Data response error + */ + SD_DATA_OK = (0x05), + SD_DATA_CRC_ERROR = (0x0B), + SD_DATA_WRITE_ERROR = (0x0D), + SD_DATA_OTHER_ERROR = (0xFF) +} SD_Error; + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Macros + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Variables + * @{ + */ +__IO uint8_t SdStatus = SD_NOT_PRESENT; + +/* flag_SDHC : + 0 : Standard capacity + 1 : High capacity +*/ +uint16_t flag_SDHC = 0; + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +static uint8_t SD_GetCIDRegister(SD_CID* Cid); +static uint8_t SD_GetCSDRegister(SD_CSD* Csd); +static uint8_t SD_GetDataResponse(void); +static uint8_t SD_GoIdleState(void); +static SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Answer); +static uint8_t SD_WaitData(uint8_t data); +static uint8_t SD_ReadData(void); +/** @defgroup STM32_ADAFRUIT_SD_Private_Function_Prototypes + * @{ + */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Functions + * @{ + */ + +/** + * @brief Initializes the SD/SD communication. + * @param None + * @retval The SD Response: + * - MSD_ERROR: Sequence failed + * - MSD_OK: Sequence succeed + */ +uint8_t BSP_SD_Init(void) +{ + /* Configure IO functionalities for SD pin */ + SD_IO_Init(); + + /* SD detection pin is not physically mapped on the Adafruit shield */ + SdStatus = SD_PRESENT; + + /* SD initialized and set to SPI mode properly */ + return SD_GoIdleState(); +} + +/** + * @brief Returns information about specific card. + * @param pCardInfo: Pointer to a SD_CardInfo structure that contains all SD + * card information. + * @retval The SD Response: + * - MSD_ERROR: Sequence failed + * - MSD_OK: Sequence succeed + */ +uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo) +{ + uint8_t status; + + status = SD_GetCSDRegister(&(pCardInfo->Csd)); + status|= SD_GetCIDRegister(&(pCardInfo->Cid)); + if(flag_SDHC == 1 ) + { + pCardInfo->CardBlockSize = 512; + pCardInfo->CardCapacity = (pCardInfo->Csd.version.v2.DeviceSize + 1) * pCardInfo->CardBlockSize; + } + else + { + pCardInfo->CardCapacity = (pCardInfo->Csd.version.v1.DeviceSize + 1) ; + pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.version.v1.DeviceSizeMul + 2)); + pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen); + pCardInfo->CardCapacity *= pCardInfo->CardBlockSize; + } + + return status; +} + +/** + * @brief Reads block(s) from a specified address in the SD card, in polling mode. + * @param pData: Pointer to the buffer that will contain the data to transmit + * @param ReadAddr: Address from where data is to be read + * @param BlockSize: SD card data block size, that should be 512 + * @param NumOfBlocks: Number of SD blocks to read + * @retval SD status + */ +uint8_t BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) +{ + uint32_t offset = 0; + uint8_t retr = BSP_SD_ERROR; + uint8_t *ptr = NULL; + SD_CmdAnswer_typedef response; + + /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and + Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if ( response.r1 != SD_R1_NO_ERROR) + { + goto error; + } + + ptr = malloc(sizeof(uint8_t)*BlockSize); + if( ptr == NULL ) + { + goto error; + } + memset(ptr, SD_DUMMY_BYTE, sizeof(uint8_t)*BlockSize); + + /* Data transfer */ + while (NumberOfBlocks--) + { + /* Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */ + /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, (ReadAddr + offset)/(flag_SDHC == 1 ?BlockSize: 1), 0xFF, SD_ANSWER_R1_EXPECTED); + if ( response.r1 != SD_R1_NO_ERROR) + { + goto error; + } + + /* Now look for the data token to signify the start of the data */ + if (SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) + { + /* Read the SD block data : read NumByteToRead data */ + SD_IO_WriteReadData(ptr, (uint8_t*)pData + offset, BlockSize); + + /* Set next read address*/ + offset += BlockSize; + /* get CRC bytes (not really needed by us, but required by SD) */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + else + { + goto error; + } + + /* End the command data read cycle */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + + retr = BSP_SD_OK; + +error : + /* Send dummy byte: 8 Clock pulses of delay */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(ptr != NULL) free(ptr); + + /* Return the reponse */ + return retr; +} + +/** + * @brief Writes block(s) to a specified address in the SD card, in polling mode. + * @param pData: Pointer to the buffer that will contain the data to transmit + * @param WriteAddr: Address from where data is to be written + * @param BlockSize: SD card data block size, that should be 512 + * @param NumOfBlocks: Number of SD blocks to write + * @retval SD status + */ +uint8_t BSP_SD_WriteBlocks(uint32_t* pData, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) +{ + uint32_t offset = 0; + uint8_t retr = BSP_SD_ERROR; + uint8_t *ptr = NULL; + SD_CmdAnswer_typedef response; + + /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and + Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if ( response.r1 != SD_R1_NO_ERROR) + { + goto error; + } + + ptr = malloc(sizeof(uint8_t)*BlockSize); + if (ptr == NULL) + { + goto error; + } + + /* Data transfer */ + while (NumberOfBlocks--) + { + /* Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks and + Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, (WriteAddr + offset)/(flag_SDHC == 1 ? BlockSize: 1), 0xFF, SD_ANSWER_R1_EXPECTED); + if (response.r1 != SD_R1_NO_ERROR) + { + goto error; + } + + /* Send dummy byte for NWR timing : one byte between CMDWRITE and TOKEN */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Send the data token to signify the start of the data */ + SD_IO_WriteByte(SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE); + + /* Write the block data to SD */ + SD_IO_WriteReadData((uint8_t*)pData + offset, ptr, BlockSize); + + /* Set next write address */ + offset += BlockSize; + + /* Put CRC bytes (not really needed by us, but required by SD) */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Read data response */ + if (SD_GetDataResponse() != SD_DATA_OK) + { + /* Set response value to failure */ + goto error; + } + + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + retr = BSP_SD_OK; + +error : + if(ptr != NULL) free(ptr); + /* Send dummy byte: 8 Clock pulses of delay */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Return the reponse */ + return retr; +} + +/** + * @brief Erases the specified memory area of the given SD card. + * @param StartAddr: Start byte address + * @param EndAddr: End byte address + * @retval SD status + */ +uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr) +{ + uint8_t retr = BSP_SD_ERROR; + SD_CmdAnswer_typedef response; + + /* Send CMD32 (Erase group start) and check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SD_ERASE_GRP_START, StartAddr, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); if (response.r1 == SD_R1_NO_ERROR) + { + /* Send CMD33 (Erase group end) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SD_ERASE_GRP_END, EndAddr, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if (response.r1 == SD_R1_NO_ERROR) + { + /* Send CMD38 (Erase) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_ERASE, 0, 0xFF, SD_ANSWER_R1B_EXPECTED); + if (response.r1 == SD_R1_NO_ERROR) + { + retr = BSP_SD_OK; + } + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + } + + /* Return the reponse */ + return retr; +} + +/** + * @brief Returns the SD status. + * @param None + * @retval The SD status. + */ +uint8_t BSP_SD_GetStatus(void) +{ + SD_CmdAnswer_typedef retr; + + /* Send CMD13 (SD_SEND_STATUS) to get SD status */ + retr = SD_SendCmd(SD_CMD_SEND_STATUS, 0, 0xFF, SD_ANSWER_R2_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Find SD status according to card state */ + if(( retr.r1 == SD_R1_NO_ERROR) && ( retr.r2 == SD_R2_NO_ERROR)) + { + return BSP_SD_OK; + } + + return BSP_SD_ERROR; +} + +/** + * @brief Reads the SD card SCD register. + * Reading the contents of the CSD register in SPI mode is a simple + * read-block transaction. + * @param Csd: pointer on an SCD register structure + * @retval SD status + */ +uint8_t SD_GetCSDRegister(SD_CSD* Csd) +{ + uint16_t counter = 0; + uint8_t CSD_Tab[16]; + uint8_t retr = BSP_SD_ERROR; + SD_CmdAnswer_typedef response; + + /* Send CMD9 (CSD register) or CMD10(CSD register) and Wait for response in the R1 format (0x00 is no errors) */ + response = SD_SendCmd(SD_CMD_SEND_CSD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); + if(response.r1 == SD_R1_NO_ERROR) + { + if (SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) + { + for (counter = 0; counter < 16; counter++) + { + /* Store CSD register value on CSD_Tab */ + CSD_Tab[counter] = SD_IO_WriteByte(SD_DUMMY_BYTE); + } + + /* Get CRC bytes (not really needed by us, but required by SD) */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /************************************************************************* + CSD header decoding + *************************************************************************/ + + /* Byte 0 */ + Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6; + Csd->Reserved1 = CSD_Tab[0] & 0x3F; + + /* Byte 1 */ + Csd->TAAC = CSD_Tab[1]; + + /* Byte 2 */ + Csd->NSAC = CSD_Tab[2]; + + /* Byte 3 */ + Csd->MaxBusClkFrec = CSD_Tab[3]; + + /* Byte 4/5 */ + Csd->CardComdClasses = (CSD_Tab[4] << 4) | ((CSD_Tab[5] & 0xF0) >> 4); + Csd->RdBlockLen = CSD_Tab[5] & 0x0F; + + /* Byte 6 */ + Csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7; + Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6; + Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5; + Csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4; + + /************************************************************************* + CSD v1/v2 decoding + *************************************************************************/ + + if(flag_SDHC == 0) + { + Csd->version.v1.Reserved1 = ((CSD_Tab[6] & 0x0C) >> 2); + + Csd->version.v1.DeviceSize = ((CSD_Tab[6] & 0x03) << 10) + | (CSD_Tab[7] << 2) + | ((CSD_Tab[8] & 0xC0) >> 6); + Csd->version.v1.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3; + Csd->version.v1.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07); + Csd->version.v1.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5; + Csd->version.v1.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2; + Csd->version.v1.DeviceSizeMul = ((CSD_Tab[9] & 0x03) << 1) + |((CSD_Tab[10] & 0x80) >> 7); + } + else + { + Csd->version.v2.Reserved1 = ((CSD_Tab[6] & 0x0F) << 2) | ((CSD_Tab[7] & 0xC0) >> 6); + Csd->version.v2.DeviceSize= ((CSD_Tab[7] & 0x3F) << 16) | (CSD_Tab[8] << 8) | CSD_Tab[9]; + Csd->version.v2.Reserved2 = ((CSD_Tab[10] & 0x80) >> 8); + } + + Csd->EraseSingleBlockEnable = (CSD_Tab[10] & 0x40) >> 6; + Csd->EraseSectorSize = ((CSD_Tab[10] & 0x3F) << 1) + |((CSD_Tab[11] & 0x80) >> 7); + Csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F); + Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7; + Csd->Reserved2 = (CSD_Tab[12] & 0x60) >> 5; + Csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2; + Csd->MaxWrBlockLen = ((CSD_Tab[12] & 0x03) << 2) + |((CSD_Tab[13] & 0xC0) >> 6); + Csd->WriteBlockPartial = (CSD_Tab[13] & 0x20) >> 5; + Csd->Reserved3 = (CSD_Tab[13] & 0x1F); + Csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7; + Csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6; + Csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5; + Csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4; + Csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2; + Csd->Reserved4 = (CSD_Tab[14] & 0x03); + Csd->crc = (CSD_Tab[15] & 0xFE) >> 1; + Csd->Reserved5 = (CSD_Tab[15] & 0x01); + + retr = BSP_SD_OK; + } + } + + /* Send dummy byte: 8 Clock pulses of delay */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Return the reponse */ + return retr; +} + +/** + * @brief Reads the SD card CID register. + * Reading the contents of the CID register in SPI mode is a simple + * read-block transaction. + * @param Cid: pointer on an CID register structure + * @retval SD status + */ +uint8_t SD_GetCIDRegister(SD_CID* Cid) +{ + uint32_t counter = 0; + uint8_t retr = BSP_SD_ERROR; + uint8_t CID_Tab[16]; + SD_CmdAnswer_typedef response; + + /* Send CMD10 (CID register) and Wait for response in the R1 format (0x00 is no errors) */ + response = SD_SendCmd(SD_CMD_SEND_CID, 0, 0xFF, SD_ANSWER_R1_EXPECTED); + if(response.r1 == SD_R1_NO_ERROR) + { + if(SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) + { + /* Store CID register value on CID_Tab */ + for (counter = 0; counter < 16; counter++) + { + CID_Tab[counter] = SD_IO_WriteByte(SD_DUMMY_BYTE); + } + + /* Get CRC bytes (not really needed by us, but required by SD) */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Byte 0 */ + Cid->ManufacturerID = CID_Tab[0]; + + /* Byte 1 */ + Cid->OEM_AppliID = CID_Tab[1] << 8; + + /* Byte 2 */ + Cid->OEM_AppliID |= CID_Tab[2]; + + /* Byte 3 */ + Cid->ProdName1 = CID_Tab[3] << 24; + + /* Byte 4 */ + Cid->ProdName1 |= CID_Tab[4] << 16; + + /* Byte 5 */ + Cid->ProdName1 |= CID_Tab[5] << 8; + + /* Byte 6 */ + Cid->ProdName1 |= CID_Tab[6]; + + /* Byte 7 */ + Cid->ProdName2 = CID_Tab[7]; + + /* Byte 8 */ + Cid->ProdRev = CID_Tab[8]; + + /* Byte 9 */ + Cid->ProdSN = CID_Tab[9] << 24; + + /* Byte 10 */ + Cid->ProdSN |= CID_Tab[10] << 16; + + /* Byte 11 */ + Cid->ProdSN |= CID_Tab[11] << 8; + + /* Byte 12 */ + Cid->ProdSN |= CID_Tab[12]; + + /* Byte 13 */ + Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4; + Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8; + + /* Byte 14 */ + Cid->ManufactDate |= CID_Tab[14]; + + /* Byte 15 */ + Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1; + Cid->Reserved2 = 1; + + retr = BSP_SD_OK; + } + } + + /* Send dummy byte: 8 Clock pulses of delay */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Return the reponse */ + return retr; +} + +/** + * @brief Sends 5 bytes command to the SD card and get response + * @param Cmd: The user expected command to send to SD card. + * @param Arg: The command argument. + * @param Crc: The CRC. + * @param Answer: SD_ANSWER_NOT_EXPECTED or SD_ANSWER_EXPECTED + * @retval SD status + */ +SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Answer) +{ + uint8_t frame[SD_CMD_LENGTH], frameout[SD_CMD_LENGTH]; + SD_CmdAnswer_typedef retr = {0xFF, 0xFF , 0xFF, 0xFF, 0xFF}; + + /* R1 Lenght = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 1 Bytes answer + NEC(0) = 15bytes */ + /* R1b identical to R1 + Busy information */ + /* R2 Lenght = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 2 Bytes answer + NEC(0) = 16bytes */ + + /* Prepare Frame to send */ + frame[0] = (Cmd | 0x40); /* Construct byte 1 */ + frame[1] = (uint8_t)(Arg >> 24); /* Construct byte 2 */ + frame[2] = (uint8_t)(Arg >> 16); /* Construct byte 3 */ + frame[3] = (uint8_t)(Arg >> 8); /* Construct byte 4 */ + frame[4] = (uint8_t)(Arg); /* Construct byte 5 */ + frame[5] = (Crc | 0x01); /* Construct byte 6 */ + + /* Send the command */ + SD_IO_CSState(0); + SD_IO_WriteReadData(frame, frameout, SD_CMD_LENGTH); /* Send the Cmd bytes */ + + switch(Answer) + { + case SD_ANSWER_R1_EXPECTED : + retr.r1 = SD_ReadData(); + break; + case SD_ANSWER_R1B_EXPECTED : + retr.r1 = SD_ReadData(); + retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); + /* Set CS High */ + SD_IO_CSState(1); + HAL_Delay(1); + /* Set CS Low */ + SD_IO_CSState(0); + + /* Wait IO line return 0xFF */ + while (SD_IO_WriteByte(SD_DUMMY_BYTE) != 0xFF); + break; + case SD_ANSWER_R2_EXPECTED : + retr.r1 = SD_ReadData(); + retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); + break; + case SD_ANSWER_R3_EXPECTED : + case SD_ANSWER_R7_EXPECTED : + retr.r1 = SD_ReadData(); + retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); + retr.r3 = SD_IO_WriteByte(SD_DUMMY_BYTE); + retr.r4 = SD_IO_WriteByte(SD_DUMMY_BYTE); + retr.r5 = SD_IO_WriteByte(SD_DUMMY_BYTE); + break; + } + return retr; +} + +/** + * @brief Gets the SD card data response and check the busy flag. + * @param None + * @retval The SD status: Read data response xxx0<status>1 + * - status 010: Data accecpted + * - status 101: Data rejected due to a crc error + * - status 110: Data rejected due to a Write error. + * - status 111: Data rejected due to other error. + */ +uint8_t SD_GetDataResponse(void) +{ + uint8_t dataresponse; + uint8_t rvalue = SD_DATA_OTHER_ERROR; + + dataresponse = SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); /* read the busy response byte*/ + + /* Mask unused bits */ + switch (dataresponse & 0x1F) + { + case SD_DATA_OK: + rvalue = SD_DATA_OK; + + /* Set CS High */ + SD_IO_CSState(1); + /* Set CS Low */ + SD_IO_CSState(0); + + /* Wait IO line return 0xFF */ + while (SD_IO_WriteByte(SD_DUMMY_BYTE) != 0xFF); + break; + case SD_DATA_CRC_ERROR: + rvalue = SD_DATA_CRC_ERROR; + case SD_DATA_WRITE_ERROR: + rvalue = SD_DATA_WRITE_ERROR; + } + + /* Return response */ + return rvalue; +} + + +/** + * @brief Put the SD in Idle state. + * @param None + * @retval SD status + */ +uint8_t SD_GoIdleState(void) +{ + SD_CmdAnswer_typedef response; + __IO uint8_t counter = 0; + /* Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode and + wait for In Idle State Response (R1 Format) equal to 0x01 */ + do{ + counter++; + response = SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(counter >= SD_MAX_TRY) + { + return BSP_SD_ERROR; + } + } + while(response.r1 != SD_R1_IN_IDLE_STATE); + + + /* Send CMD8 (SD_CMD_SEND_IF_COND) to check the power supply status + and wait until response (R7 Format) equal to 0xAA and */ + response = SD_SendCmd(SD_CMD_SEND_IF_COND, 0x1AA, 0x87, SD_ANSWER_R7_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) + { + /* initialise card V1 */ + do + { + /* initialise card V1 */ + /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_APP_CMD, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + while(response.r1 == SD_R1_IN_IDLE_STATE); + flag_SDHC = 0; + } + else if(response.r1 == SD_R1_IN_IDLE_STATE) + { + /* initialise card V2 */ + do { + + /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x40000000, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + while(response.r1 == SD_R1_IN_IDLE_STATE); + + if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) + { + do { + /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(response.r1 != SD_R1_IN_IDLE_STATE) + { + return BSP_SD_ERROR; + } + /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + while(response.r1 == SD_R1_IN_IDLE_STATE); + } + + /* Send CMD58 (SD_CMD_READ_OCR) to initialize SDHC or SDXC cards: R3 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_READ_OCR, 0x00000000, 0xFF, SD_ANSWER_R3_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(response.r1 != SD_R1_NO_ERROR) + { + return BSP_SD_ERROR; + } + flag_SDHC = (response.r2 & 0x40) >> 6; + } + else + { + return BSP_SD_ERROR; + } + + return BSP_SD_OK; +} + +/** + * @brief Waits a data until a value different from SD_DUMMY_BITE + * @param None + * @retval the value read + */ +uint8_t SD_ReadData(void) +{ + uint8_t timeout = 0x08; + uint8_t readvalue; + + /* Check if response is got or a timeout is happen */ + do { + readvalue = SD_IO_WriteByte(SD_DUMMY_BYTE); + timeout--; + + }while ((readvalue == SD_DUMMY_BYTE) && timeout); + + /* Right response got */ + return readvalue; +} + +/** + * @brief Waits a data from the SD card + * @param data : Expected data from the SD card + * @retval BSP_SD_OK or BSP_SD_TIMEOUT + */ +uint8_t SD_WaitData(uint8_t data) +{ + uint16_t timeout = 0xFFFF; + uint8_t readvalue; + + /* Check if response is got or a timeout is happen */ + + do { + readvalue = SD_IO_WriteByte(SD_DUMMY_BYTE); + timeout--; + }while ((readvalue != data) && timeout); + + if (timeout == 0) + { + /* After time out */ + return BSP_SD_TIMEOUT; + } + + /* Right response got */ + return BSP_SD_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_Shield/stm32_adafruit_sd.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,241 @@ +/** + ****************************************************************************** + * @file stm32_adafruit_sd.h + * @author MCD Application Team + * @version V2.0.0 + * @date 10-September-2015 + * @brief This file contains the common defines and functions prototypes for + * the stm32_adafruit_sd.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_ADAFRUIT_SD_H +#define __STM32_ADAFRUIT_SD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ +#define __IO volatile + +/** @addtogroup STM32_ADAFRUIT + * @{ + */ + +/** @defgroup STM32_ADAFRUIT_SD + * @{ + */ + +/** @defgroup STM32_ADAFRUIT_SD_Exported_Types + * @{ + */ + +/** + * @brief SD status structure definition + */ +enum { + BSP_SD_OK = 0x00, + MSD_OK = 0x00, + BSP_SD_ERROR = 0x01, + BSP_SD_TIMEOUT +}; + +typedef struct +{ + uint8_t Reserved1:2; /* Reserved */ + uint16_t DeviceSize:12; /* Device Size */ + uint8_t MaxRdCurrentVDDMin:3; /* Max. read current @ VDD min */ + uint8_t MaxRdCurrentVDDMax:3; /* Max. read current @ VDD max */ + uint8_t MaxWrCurrentVDDMin:3; /* Max. write current @ VDD min */ + uint8_t MaxWrCurrentVDDMax:3; /* Max. write current @ VDD max */ + uint8_t DeviceSizeMul:3; /* Device size multiplier */ +} struct_v1; + + +typedef struct +{ + uint8_t Reserved1:6; /* Reserved */ + uint32_t DeviceSize:22; /* Device Size */ + uint8_t Reserved2:1; /* Reserved */ +} struct_v2; + +/** + * @brief Card Specific Data: CSD Register + */ +typedef struct +{ + /* Header part */ + uint8_t CSDStruct:2; /* CSD structure */ + uint8_t Reserved1:6; /* Reserved */ + uint8_t TAAC:8; /* Data read access-time 1 */ + uint8_t NSAC:8; /* Data read access-time 2 in CLK cycles */ + uint8_t MaxBusClkFrec:8; /* Max. bus clock frequency */ + uint16_t CardComdClasses:12; /* Card command classes */ + uint8_t RdBlockLen:4; /* Max. read data block length */ + uint8_t PartBlockRead:1; /* Partial blocks for read allowed */ + uint8_t WrBlockMisalign:1; /* Write block misalignment */ + uint8_t RdBlockMisalign:1; /* Read block misalignment */ + uint8_t DSRImpl:1; /* DSR implemented */ + + /* v1 or v2 struct */ + union csd_version { + struct_v1 v1; + struct_v2 v2; + } version; + + uint8_t EraseSingleBlockEnable:1; /* Erase single block enable */ + uint8_t EraseSectorSize:7; /* Erase group size multiplier */ + uint8_t WrProtectGrSize:7; /* Write protect group size */ + uint8_t WrProtectGrEnable:1; /* Write protect group enable */ + uint8_t Reserved2:2; /* Reserved */ + uint8_t WrSpeedFact:3; /* Write speed factor */ + uint8_t MaxWrBlockLen:4; /* Max. write data block length */ + uint8_t WriteBlockPartial:1; /* Partial blocks for write allowed */ + uint8_t Reserved3:5; /* Reserved */ + uint8_t FileFormatGrouop:1; /* File format group */ + uint8_t CopyFlag:1; /* Copy flag (OTP) */ + uint8_t PermWrProtect:1; /* Permanent write protection */ + uint8_t TempWrProtect:1; /* Temporary write protection */ + uint8_t FileFormat:2; /* File Format */ + uint8_t Reserved4:2; /* Reserved */ + uint8_t crc:7; /* Reserved */ + uint8_t Reserved5:1; /* always 1*/ + +} SD_CSD; + +/** + * @brief Card Identification Data: CID Register + */ +typedef struct +{ + __IO uint8_t ManufacturerID; /* ManufacturerID */ + __IO uint16_t OEM_AppliID; /* OEM/Application ID */ + __IO uint32_t ProdName1; /* Product Name part1 */ + __IO uint8_t ProdName2; /* Product Name part2*/ + __IO uint8_t ProdRev; /* Product Revision */ + __IO uint32_t ProdSN; /* Product Serial Number */ + __IO uint8_t Reserved1; /* Reserved1 */ + __IO uint16_t ManufactDate; /* Manufacturing Date */ + __IO uint8_t CID_CRC; /* CID CRC */ + __IO uint8_t Reserved2; /* always 1 */ +} SD_CID; + +/** + * @brief SD Card information + */ +typedef struct +{ + SD_CSD Csd; + SD_CID Cid; + uint32_t CardCapacity; /* Card Capacity */ + uint32_t CardBlockSize; /* Card Block Size */ +} SD_CardInfo; + +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_SPI_SD_Exported_Constants + * @{ + */ + +/** + * @brief Block Size + */ +#define SD_BLOCK_SIZE 0x200 + +/** + * @brief SD detection on its memory slot + */ +#define SD_PRESENT ((uint8_t)0x01) +#define SD_NOT_PRESENT ((uint8_t)0x00) + +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_SD_Exported_Macro + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32_ADAFRUIT_SD_Exported_Functions + * @{ + */ +uint8_t BSP_SD_Init(void); +uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks); +uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks); +uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr); +uint8_t BSP_SD_GetStatus(void); +uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo); + +/* Link functions for SD Card peripheral*/ +void SD_IO_Init(void); +void SD_IO_CSState(uint8_t state); +void SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength); +uint8_t SD_IO_WriteByte(uint8_t Data); + +/* Link function for HAL delay */ +void HAL_Delay(__IO uint32_t Delay); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_ADAFRUIT_SD_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/accelero.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,144 @@ +/** + ****************************************************************************** + * @file accelero.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This header file contains the functions prototypes for the Accelerometer driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ACCELERO_H +#define __ACCELERO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup ACCELERO + * @{ + */ + +/** @defgroup ACCELERO_Exported_Types + * @{ + */ + +/** @defgroup ACCELERO_Driver_structure Accelerometer Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(uint16_t); + void (*DeInit)(void); + uint8_t (*ReadID)(void); + void (*Reset)(void); + void (*LowPower)(void); + void (*ConfigIT)(void); + void (*EnableIT)(uint8_t); + void (*DisableIT)(uint8_t); + uint8_t (*ITStatus)(uint16_t); + void (*ClearIT)(void); + void (*FilterConfig)(uint8_t); + void (*FilterCmd)(uint8_t); + void (*GetXYZ)(int16_t *); +}ACCELERO_DrvTypeDef; +/** + * @} + */ + +/** @defgroup ACCELERO_Configuration_structure Accelerometer Configuration structure + * @{ + */ + +/* ACCELERO struct */ +typedef struct +{ + uint8_t Power_Mode; /* Power-down/Normal Mode */ + uint8_t AccOutput_DataRate; /* OUT data rate */ + uint8_t Axes_Enable; /* Axes enable */ + uint8_t High_Resolution; /* High Resolution enabling/disabling */ + uint8_t BlockData_Update; /* Block Data Update */ + uint8_t Endianness; /* Endian Data selection */ + uint8_t AccFull_Scale; /* Full Scale selection */ + uint8_t Communication_Mode; +}ACCELERO_InitTypeDef; + +/* ACCELERO High Pass Filter struct */ +typedef struct +{ + uint8_t HighPassFilter_Mode_Selection; /* Internal filter mode */ + uint8_t HighPassFilter_CutOff_Frequency; /* High pass filter cut-off frequency */ + uint8_t HighPassFilter_AOI1; /* HPF_enabling/disabling for AOI function on interrupt 1 */ + uint8_t HighPassFilter_AOI2; /* HPF_enabling/disabling for AOI function on interrupt 2 */ + uint8_t HighPassFilter_Data_Sel; + uint8_t HighPassFilter_Stat; +}ACCELERO_FilterConfigTypeDef; + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ACCELERO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/audio.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * @file audio.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This header file contains the common defines and functions prototypes + * for the Audio driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AUDIO_H +#define __AUDIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup AUDIO + * @{ + */ + +/** @defgroup AUDIO_Exported_Constants + * @{ + */ + +/* Codec audio Standards */ +#define CODEC_STANDARD 0x04 +#define I2S_STANDARD I2S_STANDARD_PHILIPS + +/** + * @} + */ + +/** @defgroup AUDIO_Exported_Types + * @{ + */ + +/** @defgroup AUDIO_Driver_structure Audio Driver structure + * @{ + */ +typedef struct +{ + uint32_t (*Init)(uint16_t, uint16_t, uint8_t, uint32_t); + void (*DeInit)(void); + uint32_t (*ReadID)(uint16_t); + uint32_t (*Play)(uint16_t, uint16_t*, uint16_t); + uint32_t (*Pause)(uint16_t); + uint32_t (*Resume)(uint16_t); + uint32_t (*Stop)(uint16_t, uint32_t); + uint32_t (*SetFrequency)(uint16_t, uint32_t); + uint32_t (*SetVolume)(uint16_t, uint8_t); + uint32_t (*SetMute)(uint16_t, uint32_t); + uint32_t (*SetOutputMode)(uint16_t, uint8_t); + uint32_t (*Reset)(uint16_t); +}AUDIO_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __AUDIO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/camera.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,142 @@ +/** + ****************************************************************************** + * @file camera.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This header file contains the common defines and functions prototypes + * for the camera driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CAMERA_H +#define __CAMERA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup CAMERA + * @{ + */ + + +/** @defgroup CAMERA_Exported_Types + * @{ + */ + +/** @defgroup CAMERA_Driver_structure Camera Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(uint16_t, uint32_t); + uint16_t (*ReadID)(uint16_t); + void (*Config)(uint16_t, uint32_t, uint32_t, uint32_t); +}CAMERA_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup CAMERA_Exported_Constants + * @{ + */ +#define CAMERA_R160x120 0x00 /* QQVGA Resolution */ +#define CAMERA_R320x240 0x01 /* QVGA Resolution */ +#define CAMERA_R480x272 0x02 /* 480x272 Resolution */ +#define CAMERA_R640x480 0x03 /* VGA Resolution */ + +#define CAMERA_CONTRAST_BRIGHTNESS 0x00 /* Camera contrast brightness features */ +#define CAMERA_BLACK_WHITE 0x01 /* Camera black white feature */ +#define CAMERA_COLOR_EFFECT 0x03 /* Camera color effect feature */ + +#define CAMERA_BRIGHTNESS_LEVEL0 0x00 /* Brightness level -2 */ +#define CAMERA_BRIGHTNESS_LEVEL1 0x01 /* Brightness level -1 */ +#define CAMERA_BRIGHTNESS_LEVEL2 0x02 /* Brightness level 0 */ +#define CAMERA_BRIGHTNESS_LEVEL3 0x03 /* Brightness level +1 */ +#define CAMERA_BRIGHTNESS_LEVEL4 0x04 /* Brightness level +2 */ + +#define CAMERA_CONTRAST_LEVEL0 0x05 /* Contrast level -2 */ +#define CAMERA_CONTRAST_LEVEL1 0x06 /* Contrast level -1 */ +#define CAMERA_CONTRAST_LEVEL2 0x07 /* Contrast level 0 */ +#define CAMERA_CONTRAST_LEVEL3 0x08 /* Contrast level +1 */ +#define CAMERA_CONTRAST_LEVEL4 0x09 /* Contrast level +2 */ + +#define CAMERA_BLACK_WHITE_BW 0x00 /* Black and white effect */ +#define CAMERA_BLACK_WHITE_NEGATIVE 0x01 /* Negative effect */ +#define CAMERA_BLACK_WHITE_BW_NEGATIVE 0x02 /* BW and Negative effect */ +#define CAMERA_BLACK_WHITE_NORMAL 0x03 /* Normal effect */ + +#define CAMERA_COLOR_EFFECT_NONE 0x00 /* No effects */ +#define CAMERA_COLOR_EFFECT_BLUE 0x01 /* Blue effect */ +#define CAMERA_COLOR_EFFECT_GREEN 0x02 /* Green effect */ +#define CAMERA_COLOR_EFFECT_RED 0x03 /* Red effect */ +#define CAMERA_COLOR_EFFECT_ANTIQUE 0x04 /* Antique effect */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CAMERA_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/epd.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,116 @@ +/** + ****************************************************************************** + * @file epd.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This file contains all the functions prototypes for the + * EPD (E Paper Display) driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __EPD_H +#define __EPD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup Common + * @{ + */ + +/** @addtogroup EPD + * @{ + */ + +/** @defgroup EPD_Exported_Types + * @{ + */ + +/** @defgroup EPD_Driver_structure E Paper Display Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(void); + void (*WritePixel)(uint8_t); + + /* Optimized operation */ + void (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t); + void (*RefreshDisplay)(void); + void (*CloseChargePump)(void); + + uint16_t (*GetEpdPixelWidth)(void); + uint16_t (*GetEpdPixelHeight)(void); + void (*DrawImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint8_t*); +} +EPD_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* EPD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/gyro.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,146 @@ +/** + ****************************************************************************** + * @file gyro.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This header file contains the functions prototypes for the gyroscope driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GYRO_H +#define __GYRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup GYRO + * @{ + */ + +/** @defgroup GYRO_Exported_Types + * @{ + */ + +/** @defgroup GYRO_Driver_structure Gyroscope Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(uint16_t); + void (*DeInit)(void); + uint8_t (*ReadID)(void); + void (*Reset)(void); + void (*LowPower)(uint16_t); + void (*ConfigIT)(uint16_t); + void (*EnableIT)(uint8_t); + void (*DisableIT)(uint8_t); + uint8_t (*ITStatus)(uint16_t, uint16_t); + void (*ClearIT)(uint16_t, uint16_t); + void (*FilterConfig)(uint8_t); + void (*FilterCmd)(uint8_t); + void (*GetXYZ)(float *); +}GYRO_DrvTypeDef; +/** + * @} + */ + +/** @defgroup GYRO_Config_structure Gyroscope Configuration structure + * @{ + */ + +typedef struct +{ + uint8_t Power_Mode; /* Power-down/Sleep/Normal Mode */ + uint8_t Output_DataRate; /* OUT data rate */ + uint8_t Axes_Enable; /* Axes enable */ + uint8_t Band_Width; /* Bandwidth selection */ + uint8_t BlockData_Update; /* Block Data Update */ + uint8_t Endianness; /* Endian Data selection */ + uint8_t Full_Scale; /* Full Scale selection */ +}GYRO_InitTypeDef; + +/* GYRO High Pass Filter struct */ +typedef struct +{ + uint8_t HighPassFilter_Mode_Selection; /* Internal filter mode */ + uint8_t HighPassFilter_CutOff_Frequency; /* High pass filter cut-off frequency */ +}GYRO_FilterConfigTypeDef; + +/*GYRO Interrupt struct */ +typedef struct +{ + uint8_t Latch_Request; /* Latch interrupt request into CLICK_SRC register */ + uint8_t Interrupt_Axes; /* X, Y, Z Axes Interrupts */ + uint8_t Interrupt_ActiveEdge; /* Interrupt Active edge */ +}GYRO_InterruptConfigTypeDef; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GYRO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/idd.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,169 @@ +/** + ****************************************************************************** + * @file idd.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This file contains all the functions prototypes for the IDD driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __IDD_H +#define __IDD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup IDD + * @{ + */ + +/** @defgroup IDD_Exported_Types IDD Exported Types + * @{ + */ + +/** @defgroup IDD_Config_structure IDD Configuration structure + * @{ + */ +typedef struct +{ + uint16_t AmpliGain; /*!< Specifies ampli gain value + */ + uint16_t VddMin; /*!< Specifies minimum MCU VDD can reach to protect MCU from reset + */ + uint16_t Shunt0Value; /*!< Specifies value of Shunt 0 if existing + */ + uint16_t Shunt1Value; /*!< Specifies value of Shunt 1 if existing + */ + uint16_t Shunt2Value; /*!< Specifies value of Shunt 2 if existing + */ + uint16_t Shunt3Value; /*!< Specifies value of Shunt 3 if existing + */ + uint16_t Shunt4Value; /*!< Specifies value of Shunt 4 if existing + */ + uint16_t Shunt0StabDelay; /*!< Specifies delay of Shunt 0 stabilization if existing + */ + uint16_t Shunt1StabDelay; /*!< Specifies delay of Shunt 1 stabilization if existing + */ + uint16_t Shunt2StabDelay; /*!< Specifies delay of Shunt 2 stabilization if existing + */ + uint16_t Shunt3StabDelay; /*!< Specifies delay of Shunt 3 stabilization if existing + */ + uint16_t Shunt4StabDelay; /*!< Specifies delay of Shunt 4 stabilization if existing + */ + uint8_t ShuntNbOnBoard; /*!< Specifies number of shunts that are present on board + This parameter can be a value of @ref IDD_shunt_number */ + uint8_t ShuntNbUsed; /*!< Specifies number of shunts used for measurement + This parameter can be a value of @ref IDD_shunt_number */ + uint8_t VrefMeasurement; /*!< Specifies if Vref is automatically measured before each Idd measurement + This parameter can be a value of @ref IDD_Vref_Measurement */ + uint8_t Calibration; /*!< Specifies if calibration is done before each Idd measurement + */ + uint8_t PreDelayUnit; /*!< Specifies Pre delay unit + This parameter can be a value of @ref IDD_PreDelay */ + uint8_t PreDelayValue; /*!< Specifies Pre delay value in selected unit + */ + uint8_t MeasureNb; /*!< Specifies number of Measure to be performed + This parameter can be a value between 1 and 256 */ + uint8_t DeltaDelayUnit; /*!< Specifies Delta delay unit + This parameter can be a value of @ref IDD_DeltaDelay */ + uint8_t DeltaDelayValue; /*!< Specifies Delta delay between 2 measures + value can be between 1 and 128 */ +}IDD_ConfigTypeDef; +/** + * @} + */ + +/** @defgroup IDD_Driver_structure IDD Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(uint16_t); + void (*DeInit)(uint16_t); + uint16_t (*ReadID)(uint16_t); + void (*Reset)(uint16_t); + void (*LowPower)(uint16_t); + void (*WakeUp)(uint16_t); + void (*Start)(uint16_t); + void (*Config)(uint16_t,IDD_ConfigTypeDef); + void (*GetValue)(uint16_t, uint32_t *); + void (*EnableIT)(uint16_t); + void (*ClearIT)(uint16_t); + uint8_t (*GetITStatus)(uint16_t); + void (*DisableIT)(uint16_t); + void (*ErrorEnableIT)(uint16_t); + void (*ErrorClearIT)(uint16_t); + uint8_t (*ErrorGetITStatus)(uint16_t); + void (*ErrorDisableIT)(uint16_t); + uint8_t (*ErrorGetSrc)(uint16_t); + uint8_t (*ErrorGetCode)(uint16_t); +}IDD_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __IDD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/io.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,151 @@ +/** + ****************************************************************************** + * @file io.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This file contains all the functions prototypes for the IO driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __IO_H +#define __IO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup IO + * @{ + */ + +/** @defgroup IO_Exported_Types + * @{ + */ + +/** + * @brief IO Bit SET and Bit RESET enumeration + */ +typedef enum +{ + IO_PIN_RESET = 0, + IO_PIN_SET +}IO_PinState; + +typedef enum +{ + IO_MODE_INPUT = 0, /* input floating */ + IO_MODE_OUTPUT, /* output Push Pull */ + IO_MODE_IT_RISING_EDGE, /* float input - irq detect on rising edge */ + IO_MODE_IT_FALLING_EDGE, /* float input - irq detect on falling edge */ + IO_MODE_IT_LOW_LEVEL, /* float input - irq detect on low level */ + IO_MODE_IT_HIGH_LEVEL, /* float input - irq detect on high level */ + /* following modes only available on MFX*/ + IO_MODE_ANALOG, /* analog mode */ + IO_MODE_OFF, /* when pin isn't used*/ + IO_MODE_INPUT_PU, /* input with internal pull up resistor */ + IO_MODE_INPUT_PD, /* input with internal pull down resistor */ + IO_MODE_OUTPUT_OD, /* Open Drain output without internal resistor */ + IO_MODE_OUTPUT_OD_PU, /* Open Drain output with internal pullup resistor */ + IO_MODE_OUTPUT_OD_PD, /* Open Drain output with internal pulldown resistor */ + IO_MODE_OUTPUT_PP, /* PushPull output without internal resistor */ + IO_MODE_OUTPUT_PP_PU, /* PushPull output with internal pullup resistor */ + IO_MODE_OUTPUT_PP_PD, /* PushPull output with internal pulldown resistor */ + IO_MODE_IT_RISING_EDGE_PU, /* push up resistor input - irq on rising edge */ + IO_MODE_IT_RISING_EDGE_PD, /* push dw resistor input - irq on rising edge */ + IO_MODE_IT_FALLING_EDGE_PU, /* push up resistor input - irq on falling edge */ + IO_MODE_IT_FALLING_EDGE_PD, /* push dw resistor input - irq on falling edge */ + IO_MODE_IT_LOW_LEVEL_PU, /* push up resistor input - irq detect on low level */ + IO_MODE_IT_LOW_LEVEL_PD, /* push dw resistor input - irq detect on low level */ + IO_MODE_IT_HIGH_LEVEL_PU, /* push up resistor input - irq detect on high level */ + IO_MODE_IT_HIGH_LEVEL_PD, /* push dw resistor input - irq detect on high level */ + +}IO_ModeTypedef; + +/** @defgroup IO_Driver_structure IO Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(uint16_t); + uint16_t (*ReadID)(uint16_t); + void (*Reset)(uint16_t); + + void (*Start)(uint16_t, uint32_t); + uint8_t (*Config)(uint16_t, uint32_t, IO_ModeTypedef); + void (*WritePin)(uint16_t, uint32_t, uint8_t); + uint32_t (*ReadPin)(uint16_t, uint32_t); + + void (*EnableIT)(uint16_t); + void (*DisableIT)(uint16_t); + uint32_t (*ITStatus)(uint16_t, uint32_t); + void (*ClearIT)(uint16_t, uint32_t); + +}IO_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __IO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/lcd.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,115 @@ +/** + ****************************************************************************** + * @file lcd.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This file contains all the functions prototypes for the LCD driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __LCD_H +#define __LCD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup LCD + * @{ + */ + +/** @defgroup LCD_Exported_Types + * @{ + */ + +/** @defgroup LCD_Driver_structure LCD Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(void); + uint16_t (*ReadID)(void); + void (*DisplayOn)(void); + void (*DisplayOff)(void); + void (*SetCursor)(uint16_t, uint16_t); + void (*WritePixel)(uint16_t, uint16_t, uint16_t); + uint16_t (*ReadPixel)(uint16_t, uint16_t); + + /* Optimized operation */ + void (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t); + void (*DrawHLine)(uint16_t, uint16_t, uint16_t, uint16_t); + void (*DrawVLine)(uint16_t, uint16_t, uint16_t, uint16_t); + + uint16_t (*GetLcdPixelWidth)(void); + uint16_t (*GetLcdPixelHeight)(void); + void (*DrawBitmap)(uint16_t, uint16_t, uint8_t*); + void (*DrawRGBImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint8_t*); +}LCD_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LCD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/magneto.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,126 @@ +/** + ****************************************************************************** + * @file magneto.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This header file contains the functions prototypes for the MAGNETO driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAGNETO_H +#define __MAGNETO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup MAGNETO + * @{ + */ + +/** @defgroup MAGNETO_Exported_Types + * @{ + */ + +/** @defgroup MAGNETO_Config_structure Magnetometer Configuration structure + * @{ + */ +typedef struct +{ + uint8_t Register1; + uint8_t Register2; + uint8_t Register3; + uint8_t Register4; + uint8_t Register5; +}MAGNETO_InitTypeDef; +/** + * @} + */ + +/** @defgroup MAGNETO_Driver_structure Magnetometer Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(MAGNETO_InitTypeDef); + void (*DeInit)(void); + uint8_t (*ReadID)(void); + void (*Reset)(void); + void (*LowPower)(void); + void (*ConfigIT)(void); + void (*EnableIT)(uint8_t); + void (*DisableIT)(uint8_t); + uint8_t (*ITStatus)(uint16_t); + void (*ClearIT)(void); + void (*FilterConfig)(uint8_t); + void (*FilterCmd)(uint8_t); + void (*GetXYZ)(int16_t *); +}MAGNETO_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAGNETO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/ts.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,108 @@ +/** + ****************************************************************************** + * @file ts.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This file contains all the functions prototypes for the Touch Screen driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TS_H +#define __TS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup TS + * @{ + */ + +/** @defgroup TS_Exported_Types + * @{ + */ + +/** @defgroup TS_Driver_structure Touch Sensor Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(uint16_t); + uint16_t (*ReadID)(uint16_t); + void (*Reset)(uint16_t); + void (*Start)(uint16_t); + uint8_t (*DetectTouch)(uint16_t); + void (*GetXY)(uint16_t, uint16_t*, uint16_t*); + void (*EnableIT)(uint16_t); + void (*ClearIT)(uint16_t); + uint8_t (*GetITStatus)(uint16_t); + void (*DisableIT)(uint16_t); +}TS_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/Common/tsensor.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,119 @@ +/** + ****************************************************************************** + * @file tsensor.h + * @author MCD Application Team + * @version V4.0.1 + * @date 21-July-2015 + * @brief This header file contains the functions prototypes for the + * Temperature Sensor driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TSENSOR_H +#define __TSENSOR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup TSENSOR + * @{ + */ + +/** @defgroup TSENSOR_Exported_Types + * @{ + */ + +/** @defgroup TSENSOR_Config_structure Temperature Sensor Configuration structure + * @{ + */ +typedef struct +{ + uint8_t AlertMode; /* Alert Mode Temperature out of range*/ + uint8_t ConversionMode; /* Continuous/One Shot Mode */ + uint8_t ConversionResolution; /* Temperature Resolution */ + uint8_t ConversionRate; /* Number of measure per second */ + uint8_t TemperatureLimitHigh; /* High Temperature Limit Range */ + uint8_t TemperatureLimitLow; /* Low Temperature Limit Range */ +}TSENSOR_InitTypeDef; +/** + * @} + */ + +/** @defgroup TSENSOR_Driver_structure Temperature Sensor Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(uint16_t, TSENSOR_InitTypeDef *); + uint8_t (*IsReady)(uint16_t, uint32_t); + uint8_t (*ReadStatus)(uint16_t); + uint16_t (*ReadTemp)(uint16_t); +}TSENSOR_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TSENSOR_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/cs43l22/cs43l22.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,494 @@ +/** + ****************************************************************************** + * @file cs43l22.c + * @author MCD Application Team + * @version V2.0.1 + * @date 16-September-2015 + * @brief This file provides the CS43L22 Audio Codec driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "cs43l22.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup cs43l22 + * @brief This file provides a set of functions needed to drive the + * CS43l22 audio codec. + * @{ + */ + +/** @defgroup CS43L22_Private_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup CS43L22_Private_Defines + * @{ + */ +/* Uncomment this line to enable verifying data sent to codec after each write + operation (for debug purpose) */ +#if !defined (VERIFY_WRITTENDATA) +/* #define VERIFY_WRITTENDATA */ +#endif /* VERIFY_WRITTENDATA */ +/** + * @} + */ + +/** @defgroup CS43L22_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup CS43L22_Private_Variables + * @{ + */ + +/* Audio codec driver structure initialization */ +AUDIO_DrvTypeDef cs43l22_drv = +{ + cs43l22_Init, + cs43l22_DeInit, + cs43l22_ReadID, + + cs43l22_Play, + cs43l22_Pause, + cs43l22_Resume, + cs43l22_Stop, + + cs43l22_SetFrequency, + cs43l22_SetVolume, + cs43l22_SetMute, + cs43l22_SetOutputMode, + cs43l22_Reset, +}; + +static uint8_t Is_cs43l22_Stop = 1; + +volatile uint8_t OutputDev = 0; + +/** + * @} + */ + +/** @defgroup CS43L22_Function_Prototypes + * @{ + */ +static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value); +/** + * @} + */ + +/** @defgroup CS43L22_Private_Functions + * @{ + */ + +/** + * @brief Initializes the audio codec and the control interface. + * @param DeviceAddr: Device address on communication Bus. + * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, + * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . + * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) +{ + uint32_t counter = 0; + + /* Initialize the Control interface of the Audio Codec */ + AUDIO_IO_Init(); + + /* Keep Codec powered OFF */ + counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01); + + /*Save Output device for mute ON/OFF procedure*/ + switch (OutputDevice) + { + case OUTPUT_DEVICE_SPEAKER: + OutputDev = 0xFA; + break; + + case OUTPUT_DEVICE_HEADPHONE: + OutputDev = 0xAF; + break; + + case OUTPUT_DEVICE_BOTH: + OutputDev = 0xAA; + break; + + case OUTPUT_DEVICE_AUTO: + OutputDev = 0x05; + break; + + default: + OutputDev = 0x05; + break; + } + + counter += CODEC_IO_Write(DeviceAddr, 0x04, OutputDev); + + /* Clock configuration: Auto detection */ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x81); + + /* Set the Slave Mode and the audio Standard */ + counter += CODEC_IO_Write(DeviceAddr, 0x06, CODEC_STANDARD); + + /* Set the Master volume */ + counter += cs43l22_SetVolume(DeviceAddr, Volume); + + /* If the Speaker is enabled, set the Mono mode and volume attenuation level */ + if(OutputDevice != OUTPUT_DEVICE_HEADPHONE) + { + /* Set the Speaker Mono mode */ + counter += CODEC_IO_Write(DeviceAddr, 0x0F , 0x06); + + /* Set the Speaker attenuation level */ + counter += CODEC_IO_Write(DeviceAddr, 0x24, 0x00); + counter += CODEC_IO_Write(DeviceAddr, 0x25, 0x00); + } + + /* Additional configuration for the CODEC. These configurations are done to reduce + the time needed for the Codec to power off. If these configurations are removed, + then a long delay should be added between powering off the Codec and switching + off the I2S peripheral MCLK clock (which is the operating clock for Codec). + If this delay is not inserted, then the codec will not shut down properly and + it results in high noise after shut down. */ + + /* Disable the analog soft ramp */ + counter += CODEC_IO_Write(DeviceAddr, 0x0A, 0x00); + /* Disable the digital soft ramp */ + counter += CODEC_IO_Write(DeviceAddr, 0x0E, 0x04); + /* Disable the limiter attack level */ + counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x00); + /* Adjust Bass and Treble levels */ + counter += CODEC_IO_Write(DeviceAddr, 0x1F, 0x0F); + /* Adjust PCM volume level */ + counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x0A); + counter += CODEC_IO_Write(DeviceAddr, 0x1B, 0x0A); + + /* Return communication control value */ + return counter; +} + +/** + * @brief Deinitializes the audio codec. + * @param None + * @retval None + */ +void cs43l22_DeInit(void) +{ + /* Deinitialize Audio Codec interface */ + AUDIO_IO_DeInit(); +} + +/** + * @brief Get the CS43L22 ID. + * @param DeviceAddr: Device address on communication Bus. + * @retval The CS43L22 ID + */ +uint32_t cs43l22_ReadID(uint16_t DeviceAddr) +{ + uint8_t Value; + /* Initialize the Control interface of the Audio Codec */ + AUDIO_IO_Init(); + + Value = AUDIO_IO_Read(DeviceAddr, CS43L22_CHIPID_ADDR); + Value = (Value & CS43L22_ID_MASK); + + return((uint32_t) Value); +} + +/** + * @brief Start the audio Codec play feature. + * @note For this codec no Play options are required. + * @param DeviceAddr: Device address on communication Bus. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size) +{ + uint32_t counter = 0; + + if(Is_cs43l22_Stop == 1) + { + /* Enable the digital soft ramp */ + counter += CODEC_IO_Write(DeviceAddr, 0x0E, 0x06); + + /* Enable Output device */ + counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_OFF); + + /* Power on the Codec */ + counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x9E); + Is_cs43l22_Stop = 0; + } + + /* Return communication control value */ + return counter; +} + +/** + * @brief Pauses playing on the audio codec. + * @param DeviceAddr: Device address on communication Bus. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_Pause(uint16_t DeviceAddr) +{ + uint32_t counter = 0; + + /* Pause the audio file playing */ + /* Mute the output first */ + counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_ON); + + /* Put the Codec in Power save mode */ + counter += CODEC_IO_Write(DeviceAddr,0x02, 0x01); + + return counter; +} + +/** + * @brief Resumes playing on the audio codec. + * @param DeviceAddr: Device address on communication Bus. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_Resume(uint16_t DeviceAddr) +{ + uint32_t counter = 0; + volatile uint32_t index = 0x00; + /* Resumes the audio file playing */ + /* Unmute the output first */ + counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_OFF); + + for(index = 0x00; index < 0xFF; index++); + + counter += CODEC_IO_Write(DeviceAddr,0x04, OutputDev); + + /* Exit the Power save mode */ + counter += CODEC_IO_Write(DeviceAddr,0x02, 0x9E); + + return counter; +} + +/** + * @brief Stops audio Codec playing. It powers down the codec. + * @param DeviceAddr: Device address on communication Bus. + * @param CodecPdwnMode: selects the power down mode. + * - CODEC_PDWN_HW: Physically power down the codec. When resuming from this + * mode, the codec is set to default configuration + * (user should re-Initialize the codec in order to + * play again the audio stream). + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode) +{ + uint32_t counter = 0; + + /* Mute the output first */ + counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_ON); + + /* Disable the digital soft ramp */ + counter += CODEC_IO_Write(DeviceAddr, 0x0E, 0x04); + + /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x9F); + + Is_cs43l22_Stop = 1; + return counter; +} + +/** + * @brief Sets higher or lower the codec volume level. + * @param DeviceAddr: Device address on communication Bus. + * @param Volume: a byte value from 0 to 255 (refer to codec registers + * description for more details). + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_SetVolume(uint16_t DeviceAddr, uint8_t Volume) +{ + uint32_t counter = 0; + uint8_t convertedvol = VOLUME_CONVERT(Volume); + + if(Volume > 0xE6) + { + /* Set the Master volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x20, convertedvol - 0xE7); + counter += CODEC_IO_Write(DeviceAddr, 0x21, convertedvol - 0xE7); + } + else + { + /* Set the Master volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x20, convertedvol + 0x19); + counter += CODEC_IO_Write(DeviceAddr, 0x21, convertedvol + 0x19); + } + + return counter; +} + +/** + * @brief Sets new frequency. + * @param DeviceAddr: Device address on communication Bus. + * @param AudioFreq: Audio frequency used to play the audio stream. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq) +{ + return 0; +} + +/** + * @brief Enables or disables the mute feature on the audio codec. + * @param DeviceAddr: Device address on communication Bus. + * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the + * mute mode. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_SetMute(uint16_t DeviceAddr, uint32_t Cmd) +{ + uint32_t counter = 0; + + /* Set the Mute mode */ + if(Cmd == AUDIO_MUTE_ON) + { + counter += CODEC_IO_Write(DeviceAddr, 0x04, 0xFF); + counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x01); + counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x01); + } + else /* AUDIO_MUTE_OFF Disable the Mute */ + { + counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x00); + counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x00); + counter += CODEC_IO_Write(DeviceAddr, 0x04, OutputDev); + } + return counter; +} + +/** + * @brief Switch dynamically (while audio file is played) the output target + * (speaker or headphone). + * @note This function modifies a global variable of the audio codec driver: OutputDev. + * @param DeviceAddr: Device address on communication Bus. + * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER, + * OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_SetOutputMode(uint16_t DeviceAddr, uint8_t Output) +{ + uint32_t counter = 0; + + switch (Output) + { + case OUTPUT_DEVICE_SPEAKER: + counter += CODEC_IO_Write(DeviceAddr, 0x04, 0xFA); /* SPK always ON & HP always OFF */ + OutputDev = 0xFA; + break; + + case OUTPUT_DEVICE_HEADPHONE: + counter += CODEC_IO_Write(DeviceAddr, 0x04, 0xAF); /* SPK always OFF & HP always ON */ + OutputDev = 0xAF; + break; + + case OUTPUT_DEVICE_BOTH: + counter += CODEC_IO_Write(DeviceAddr, 0x04, 0xAA); /* SPK always ON & HP always ON */ + OutputDev = 0xAA; + break; + + case OUTPUT_DEVICE_AUTO: + counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x05); /* Detect the HP or the SPK automatically */ + OutputDev = 0x05; + break; + + default: + counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x05); /* Detect the HP or the SPK automatically */ + OutputDev = 0x05; + break; + } + return counter; +} + +/** + * @brief Resets cs43l22 registers. + * @param DeviceAddr: Device address on communication Bus. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t cs43l22_Reset(uint16_t DeviceAddr) +{ + return 0; +} + +/** + * @brief Writes/Read a single data. + * @param Addr: I2C address + * @param Reg: Reg address + * @param Value: Data to be written + * @retval None + */ +static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value) +{ + uint32_t result = 0; + + AUDIO_IO_Write(Addr, Reg, Value); + +#ifdef VERIFY_WRITTENDATA + /* Verify that the data has been correctly written */ + result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1; +#endif /* VERIFY_WRITTENDATA */ + + return result; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/cs43l22/cs43l22.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,189 @@ +/** + ****************************************************************************** + * @file cs43l22.h + * @author MCD Application Team + * @version V2.0.1 + * @date 16-September-2015 + * @brief This file contains all the functions prototypes for the cs43l22.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CS43l22_H +#define __CS43l22_H + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/audio.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @addtogroup CS43l22 + * @{ + */ + +/** @defgroup CS43l22_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup CS43l22_Exported_Constants + * @{ + */ + +/******************************************************************************/ +/*************************** Codec User defines ******************************/ +/******************************************************************************/ +/* Codec output DEVICE */ +#define OUTPUT_DEVICE_SPEAKER 1 +#define OUTPUT_DEVICE_HEADPHONE 2 +#define OUTPUT_DEVICE_BOTH 3 +#define OUTPUT_DEVICE_AUTO 4 + +/* Volume Levels values */ +#define DEFAULT_VOLMIN 0x00 +#define DEFAULT_VOLMAX 0xFF +#define DEFAULT_VOLSTEP 0x04 + +#define AUDIO_PAUSE 0 +#define AUDIO_RESUME 1 + +/* Codec POWER DOWN modes */ +#define CODEC_PDWN_HW 1 +#define CODEC_PDWN_SW 2 + +/* MUTE commands */ +#define AUDIO_MUTE_ON 1 +#define AUDIO_MUTE_OFF 0 + +/* AUDIO FREQUENCY */ +#define AUDIO_FREQUENCY_192K ((uint32_t)192000) +#define AUDIO_FREQUENCY_96K ((uint32_t)96000) +#define AUDIO_FREQUENCY_48K ((uint32_t)48000) +#define AUDIO_FREQUENCY_44K ((uint32_t)44100) +#define AUDIO_FREQUENCY_32K ((uint32_t)32000) +#define AUDIO_FREQUENCY_22K ((uint32_t)22050) +#define AUDIO_FREQUENCY_16K ((uint32_t)16000) +#define AUDIO_FREQUENCY_11K ((uint32_t)11025) +#define AUDIO_FREQUENCY_8K ((uint32_t)8000) + +/******************************************************************************/ +/****************************** REGISTER MAPPING ******************************/ +/******************************************************************************/ +/** + * @brief CS43L22 ID + */ +#define CS43L22_ID 0xE0 +#define CS43L22_ID_MASK 0xF8 +/** + * @brief Chip ID Register: Chip I.D. and Revision Register + * Read only register + * Default value: 0x01 + * [7:3] CHIPID[4:0]: I.D. code for the CS43L22. + * Default value: 11100b + * [2:0] REVID[2:0]: CS43L22 revision level. + * Default value: + * 000 - Rev A0 + * 001 - Rev A1 + * 010 - Rev B0 + * 011 - Rev B1 + */ +#define CS43L22_CHIPID_ADDR 0x01 + +/** + * @} + */ + +/** @defgroup CS43l22_Exported_Macros + * @{ + */ +#define VOLUME_CONVERT(Volume) (((Volume) > 100)? 100:((uint8_t)(((Volume) * 255) / 100))) +/** + * @} + */ + +/** @defgroup CS43l22_Exported_Functions + * @{ + */ + +/*------------------------------------------------------------------------------ + Audio Codec functions +------------------------------------------------------------------------------*/ +/* High Layer codec functions */ +uint32_t cs43l22_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq); +void cs43l22_DeInit(void); +uint32_t cs43l22_ReadID(uint16_t DeviceAddr); +uint32_t cs43l22_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size); +uint32_t cs43l22_Pause(uint16_t DeviceAddr); +uint32_t cs43l22_Resume(uint16_t DeviceAddr); +uint32_t cs43l22_Stop(uint16_t DeviceAddr, uint32_t Cmd); +uint32_t cs43l22_SetVolume(uint16_t DeviceAddr, uint8_t Volume); +uint32_t cs43l22_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq); +uint32_t cs43l22_SetMute(uint16_t DeviceAddr, uint32_t Cmd); +uint32_t cs43l22_SetOutputMode(uint16_t DeviceAddr, uint8_t Output); +uint32_t cs43l22_Reset(uint16_t DeviceAddr); + +/* AUDIO IO functions */ +void AUDIO_IO_Init(void); +void AUDIO_IO_DeInit(void); +void AUDIO_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value); +uint8_t AUDIO_IO_Read(uint8_t Addr, uint8_t Reg); + +/* Audio driver structure */ +extern AUDIO_DrvTypeDef cs43l22_drv; + +#endif /* __CS43l22_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/hx8347g/hx8347g.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,482 @@ +/** + ****************************************************************************** + * @file hx8347g.c + * @author MCD Application Team + * @version V1.1.0 + * @date 10-February-2015 + * @brief This file includes the LCD driver for HX8347G LCD. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "hx8347g.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup HX8347G + * @brief This file provides a set of functions needed to drive the + * HX8347G LCD. + * @{ + */ + +/** @defgroup HX8347G_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup HX8347G_Private_Defines + * @{ + */ + +/** + * @} + */ + +/** @defgroup HX8347G_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup HX8347G_Private_Variables + * @{ + */ +LCD_DrvTypeDef hx8347g_drv = +{ + hx8347g_Init, + hx8347g_ReadID, + hx8347g_DisplayOn, + hx8347g_DisplayOff, + hx8347g_SetCursor, + hx8347g_WritePixel, + hx8347g_ReadPixel, + hx8347g_SetDisplayWindow, + hx8347g_DrawHLine, + hx8347g_DrawVLine, + hx8347g_GetLcdPixelWidth, + hx8347g_GetLcdPixelHeight, + hx8347g_DrawBitmap, +}; + +static uint8_t Is_hx8347g_Initialized = 0; +static uint16_t ArrayRGB[320] = {0}; + +/** + * @} + */ + +/** @defgroup HX8347G_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup HX8347G_Private_Functions + * @{ + */ + +/** + * @brief Initialise the HX8347G LCD Component. + * @param None + * @retval None + */ +void hx8347g_Init(void) +{ + if(Is_hx8347g_Initialized == 0) + { + Is_hx8347g_Initialized = 1; + /* Initialise HX8347G low level bus layer --------------------------------*/ + LCD_IO_Init(); + + /* Driving ability setting */ + hx8347g_WriteReg(LCD_REG_234, 0x00); + hx8347g_WriteReg(LCD_REG_235, 0x20); + hx8347g_WriteReg(LCD_REG_236, 0x0C); + hx8347g_WriteReg(LCD_REG_237, 0xC4); + hx8347g_WriteReg(LCD_REG_232, 0x40); + hx8347g_WriteReg(LCD_REG_233, 0x38); + hx8347g_WriteReg(LCD_REG_241, 0x01); + hx8347g_WriteReg(LCD_REG_242, 0x10); + hx8347g_WriteReg(LCD_REG_39, 0xA3); + + /* Adjust the Gamma Curve */ + hx8347g_WriteReg(LCD_REG_64, 0x01); + hx8347g_WriteReg(LCD_REG_65, 0x00); + hx8347g_WriteReg(LCD_REG_66, 0x00); + hx8347g_WriteReg(LCD_REG_67, 0x10); + hx8347g_WriteReg(LCD_REG_68, 0x0E); + hx8347g_WriteReg(LCD_REG_69, 0x24); + hx8347g_WriteReg(LCD_REG_70, 0x04); + hx8347g_WriteReg(LCD_REG_71, 0x50); + hx8347g_WriteReg(LCD_REG_72, 0x02); + hx8347g_WriteReg(LCD_REG_73, 0x13); + hx8347g_WriteReg(LCD_REG_74, 0x19); + hx8347g_WriteReg(LCD_REG_75, 0x19); + hx8347g_WriteReg(LCD_REG_76, 0x16); + hx8347g_WriteReg(LCD_REG_80, 0x1B); + hx8347g_WriteReg(LCD_REG_81, 0x31); + hx8347g_WriteReg(LCD_REG_82, 0x2F); + hx8347g_WriteReg(LCD_REG_83, 0x3F); + hx8347g_WriteReg(LCD_REG_84, 0x3F); + hx8347g_WriteReg(LCD_REG_85, 0x3E); + hx8347g_WriteReg(LCD_REG_86, 0x2F); + hx8347g_WriteReg(LCD_REG_87, 0x7B); + hx8347g_WriteReg(LCD_REG_88, 0x09); + hx8347g_WriteReg(LCD_REG_89, 0x06); + hx8347g_WriteReg(LCD_REG_90, 0x06); + hx8347g_WriteReg(LCD_REG_91, 0x0C); + hx8347g_WriteReg(LCD_REG_92, 0x1D); + hx8347g_WriteReg(LCD_REG_93, 0xCC); + + /* Power voltage setting */ + hx8347g_WriteReg(LCD_REG_27, 0x1B); + hx8347g_WriteReg(LCD_REG_26, 0x01); + hx8347g_WriteReg(LCD_REG_36, 0x2F); + hx8347g_WriteReg(LCD_REG_37, 0x57); + /*****VCOM offset ****/ + hx8347g_WriteReg(LCD_REG_35, 0x86); + + hx8347g_DisplayOn(); + + /* Set GRAM Area - Partial Display Control */ + hx8347g_WriteReg(LCD_REG_1, 0x00); /* DP_STB = 0, DP_STB_S = 0, SCROLL = 0, */ + hx8347g_SetDisplayWindow(0, 0, hx8347g_GetLcdPixelWidth(), hx8347g_GetLcdPixelHeight()); + hx8347g_WriteReg(LCD_REG_22, 0xA0); /* Memory access control: MY = 1, MX = 0, MV = 1, ML = 0 */ + } + + /* Set the Cursor */ + hx8347g_SetCursor(0, 0); + + /* Prepare to write GRAM */ + LCD_IO_WriteReg(LCD_REG_34); +} + +/** + * @brief Enables the Display. + * @param None + * @retval None + */ +void hx8347g_DisplayOn(void) +{ + /* Power On sequence ---------------------------------------------------------*/ + hx8347g_WriteReg(LCD_REG_24, 0x36); /* Display frame rate = 70Hz RADJ = '0110' */ + hx8347g_WriteReg(LCD_REG_25, 0x01); /* OSC_EN = 1 */ + hx8347g_WriteReg(LCD_REG_28, 0x06); /* AP[2:0] = 111 */ + hx8347g_WriteReg(LCD_REG_31, 0x90); /* GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0*/ + LCD_Delay(10); + /* 262k/65k color selection */ + hx8347g_WriteReg(LCD_REG_23, 0x05); /* default 0x06 262k color, 0x05 65k color */ + /* SET PANEL */ + hx8347g_WriteReg(LCD_REG_54, 0x09); /* SS_PANEL = 1, GS_PANEL = 0,REV_PANEL = 0, BGR_PANEL = 1 */ + + /* Display On */ + hx8347g_WriteReg(LCD_REG_40, 0x38); + LCD_Delay(60); + hx8347g_WriteReg(LCD_REG_40, 0x3C); +} + +/** + * @brief Disables the Display. + * @param None + * @retval None + */ +void hx8347g_DisplayOff(void) +{ + /* Display Off */ + hx8347g_WriteReg(LCD_REG_40, 0x38); + LCD_Delay(60); + hx8347g_WriteReg(LCD_REG_40, 0x04); + + /* Power Off sequence ---------------------------------------------------------*/ + hx8347g_WriteReg(LCD_REG_23, 0x0000); /* default 0x06 262k color, 0x05 65k color */ + hx8347g_WriteReg(LCD_REG_24, 0x0000); /* Display frame rate = 70Hz RADJ = '0110' */ + hx8347g_WriteReg(LCD_REG_25, 0x0000); /* OSC_EN = 1 */ + hx8347g_WriteReg(LCD_REG_28, 0x0000); /* AP[2:0] = 111 */ + hx8347g_WriteReg(LCD_REG_31, 0x0000); /* GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0*/ + hx8347g_WriteReg(LCD_REG_54, 0x0000); /* SS_PANEL = 1, GS_PANEL = 0,REV_PANEL = 0, BGR_PANEL = 1 */ +} + +/** + * @brief Get the LCD pixel Width. + * @param None + * @retval The Lcd Pixel Width + */ +uint16_t hx8347g_GetLcdPixelWidth(void) +{ + return (uint16_t)HX8347G_LCD_PIXEL_WIDTH; +} + +/** + * @brief Get the LCD pixel Height. + * @param None + * @retval The Lcd Pixel Height + */ +uint16_t hx8347g_GetLcdPixelHeight(void) +{ + return (uint16_t)HX8347G_LCD_PIXEL_HEIGHT; +} + +/** + * @brief Get the HX8347G ID. + * @param None + * @retval The HX8347G ID + */ +uint16_t hx8347g_ReadID(void) +{ + if(Is_hx8347g_Initialized == 0) + { + LCD_IO_Init(); + } + return (hx8347g_ReadReg(0x00)); +} + +/** + * @brief Set Cursor position. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @retval None + */ +void hx8347g_SetCursor(uint16_t Xpos, uint16_t Ypos) +{ + hx8347g_WriteReg(LCD_REG_6, 0x00); + hx8347g_WriteReg(LCD_REG_7, Xpos); + hx8347g_WriteReg(LCD_REG_2, Ypos >> 8); + hx8347g_WriteReg(LCD_REG_3, Ypos & 0xFF); +} + +/** + * @brief Write pixel. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. +* @param RGBCode: the RGB pixel color + * @retval None + */ +void hx8347g_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode) +{ + /* Set Cursor */ + hx8347g_SetCursor(Xpos, Ypos); + + /* Prepare to write GRAM */ + LCD_IO_WriteReg(LCD_REG_34); + + /* Write 16-bit GRAM Reg */ + LCD_IO_WriteMultipleData((uint8_t*)&RGBCode, 2); +} + +/** + * @brief Read pixel. + * @param None + * @retval the RGB pixel color + */ +uint16_t hx8347g_ReadPixel(uint16_t Xpos, uint16_t Ypos) +{ + /* Set Cursor */ + hx8347g_SetCursor(Xpos, Ypos); + + /* Dummy read */ + LCD_IO_ReadData(LCD_REG_34); + + /* Read 16-bit Reg */ + return (LCD_IO_ReadData(LCD_REG_34)); +} + +/** + * @brief Writes to the selected LCD register. +* @param LCDReg: address of the selected register. +* @param LCDRegValue: value to write to the selected register. + * @retval None + */ +void hx8347g_WriteReg(uint8_t LCDReg, uint16_t LCDRegValue) +{ + LCD_IO_WriteReg(LCDReg); + + /* Write 16-bit GRAM Reg */ + LCD_IO_WriteMultipleData((uint8_t*)&LCDRegValue, 2); +} + +/** + * @brief Reads the selected LCD Register. +* @param LCDReg: address of the selected register. + * @retval LCD Register Value. + */ +uint16_t hx8347g_ReadReg(uint8_t LCDReg) +{ + /* Read 16-bit Reg */ + return (LCD_IO_ReadData(LCDReg)); +} + +/** + * @brief Sets a display window + * @param Xpos: specifies the X bottom left position. + * @param Ypos: specifies the Y bottom left position. + * @param Height: display window height. + * @param Width: display window width. + * @retval None + */ +void hx8347g_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) +{ + /* Horizontal GRAM Start Address */ + hx8347g_WriteReg(LCD_REG_6, (Xpos) >> 8); /* SP */ + hx8347g_WriteReg(LCD_REG_7, (Xpos) & 0xFF); /* SP */ + + /* Horizontal GRAM End Address */ + hx8347g_WriteReg(LCD_REG_8, (Xpos + Height - 1) >> 8); /* EP */ + hx8347g_WriteReg(LCD_REG_9, (Xpos + Height - 1) & 0xFF); /* EP */ + + /* Vertical GRAM Start Address */ + hx8347g_WriteReg(LCD_REG_2, (Ypos) >> 8); /* SC */ + hx8347g_WriteReg(LCD_REG_3, (Ypos) & 0xFF); /* SC */ + + /* Vertical GRAM End Address */ + hx8347g_WriteReg(LCD_REG_4, (Ypos + Width - 1) >> 8); /* EC */ + hx8347g_WriteReg(LCD_REG_5, (Ypos + Width - 1) & 0xFF); /* EC */ +} + +/** + * @brief Draw vertical line. +* @param RGBCode: Specifies the RGB color + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Length: specifies the Line length. + * @retval None + */ +void hx8347g_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length) +{ + uint32_t i = 0; + + /* Set Cursor */ + hx8347g_SetCursor(Xpos, Ypos); + + /* Prepare to write GRAM */ + LCD_IO_WriteReg(LCD_REG_34); + + /* Sent a complete line */ + for(i = 0; i < Length; i++) + { + ArrayRGB[i] = RGBCode; + } + + LCD_IO_WriteMultipleData((uint8_t*)&ArrayRGB[0], Length * 2); +} + +/** + * @brief Draw vertical line. +* @param RGBCode: Specifies the RGB color + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Length: specifies the Line length. + * @retval None + */ +void hx8347g_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length) +{ + uint16_t counter = 0; + + /* Set Cursor */ + hx8347g_SetCursor(Xpos, Ypos); + + /* Prepare to write GRAM */ + LCD_IO_WriteReg(LCD_REG_34); + + /* Fill a complete vertical line */ + for(counter = 0; counter < Length; counter++) + { + ArrayRGB[counter] = RGBCode; + } + + /* Write 16-bit GRAM Reg */ + LCD_IO_WriteMultipleData((uint8_t*)&ArrayRGB[0], Length * 2); +} + +/** + * @brief Displays a bitmap picture loaded in the internal Flash. + * @param BmpAddress: Bmp picture address in the internal Flash. + * @retval None + */ +void hx8347g_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp) +{ + uint32_t index = 0, size = 0; + + /* Read bitmap size */ + size = *(volatile uint16_t *) (pbmp + 2); + size |= (*(volatile uint16_t *) (pbmp + 4)) << 16; + /* Get bitmap data address offset */ + index = *(volatile uint16_t *) (pbmp + 10); + index |= (*(volatile uint16_t *) (pbmp + 12)) << 16; + size = (size - index)/2; + pbmp += index; + + /* Set GRAM write direction and BGR = 0 */ + /* Memory access control: MY = 1, MX = 0, MV = 1, ML = 0 */ + hx8347g_WriteReg(LCD_REG_22, 0xE0); + + /* Set Cursor */ + hx8347g_SetCursor(Xpos, Ypos); + + /* Prepare to write GRAM */ + LCD_IO_WriteReg(LCD_REG_34); + + LCD_IO_WriteMultipleData((uint8_t*)pbmp, size*2); + + /* Set GRAM write direction and BGR = 0 */ + /* Memory access control: MY = 1, MX = 1, MV = 1, ML = 0 */ + hx8347g_WriteReg(LCD_REG_22, 0xA0); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/hx8347g/hx8347g.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,275 @@ +/** + ****************************************************************************** + * @file hx8347g.h + * @author MCD Application Team + * @version V1.1.0 + * @date 10-February-2015 + * @brief This file contains all the functions prototypes for the hx8347g.c + * driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __HX8347G_H +#define __HX8347G_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/lcd.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup hx8347g + * @{ + */ + +/** @defgroup HX8347G_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup HX8347G_Exported_Constants + * @{ + */ +/** + * @brief HX8347G ID + */ +#define HX8347G_ID 0x0075 + +/** + * @brief HX8347G Size + */ +#define HX8347G_LCD_PIXEL_WIDTH ((uint16_t)320) +#define HX8347G_LCD_PIXEL_HEIGHT ((uint16_t)240) + +/** + * @brief HX8347G Registers + */ +#define LCD_REG_0 0x00 +#define LCD_REG_1 0x01 +#define LCD_REG_2 0x02 +#define LCD_REG_3 0x03 +#define LCD_REG_4 0x04 +#define LCD_REG_5 0x05 +#define LCD_REG_6 0x06 +#define LCD_REG_7 0x07 +#define LCD_REG_8 0x08 +#define LCD_REG_9 0x09 +#define LCD_REG_10 0x0A +#define LCD_REG_11 0x0B +#define LCD_REG_12 0x0C +#define LCD_REG_13 0x0D +#define LCD_REG_14 0x0E +#define LCD_REG_15 0x0F +#define LCD_REG_16 0x10 +#define LCD_REG_17 0x11 +#define LCD_REG_18 0x12 +#define LCD_REG_19 0x13 +#define LCD_REG_20 0x14 +#define LCD_REG_21 0x15 +#define LCD_REG_22 0x16 +#define LCD_REG_23 0x17 +#define LCD_REG_24 0x18 +#define LCD_REG_25 0x19 +#define LCD_REG_26 0x1A +#define LCD_REG_27 0x1B +#define LCD_REG_28 0x1C +#define LCD_REG_29 0x1D +#define LCD_REG_30 0x1E +#define LCD_REG_31 0x1F +#define LCD_REG_32 0x20 +#define LCD_REG_33 0x21 +#define LCD_REG_34 0x22 +#define LCD_REG_35 0x23 +#define LCD_REG_36 0x24 +#define LCD_REG_37 0x25 +#define LCD_REG_38 0x26 +#define LCD_REG_39 0x27 +#define LCD_REG_40 0x28 +#define LCD_REG_41 0x29 +#define LCD_REG_42 0x2A +#define LCD_REG_43 0x2B +#define LCD_REG_44 0x2C +#define LCD_REG_45 0x2D +#define LCD_REG_46 0x2E +#define LCD_REG_47 0x2F +#define LCD_REG_48 0x30 +#define LCD_REG_49 0x31 +#define LCD_REG_50 0x32 +#define LCD_REG_51 0x33 +#define LCD_REG_52 0x34 +#define LCD_REG_53 0x35 +#define LCD_REG_54 0x36 +#define LCD_REG_55 0x37 +#define LCD_REG_56 0x38 +#define LCD_REG_57 0x39 +#define LCD_REG_58 0x3A +#define LCD_REG_59 0x3B +#define LCD_REG_60 0x3C +#define LCD_REG_61 0x3D +#define LCD_REG_62 0x3E +#define LCD_REG_63 0x3F +#define LCD_REG_64 0x40 +#define LCD_REG_65 0x41 +#define LCD_REG_66 0x42 +#define LCD_REG_67 0x43 +#define LCD_REG_68 0x44 +#define LCD_REG_69 0x45 +#define LCD_REG_70 0x46 +#define LCD_REG_71 0x47 +#define LCD_REG_72 0x48 +#define LCD_REG_73 0x49 +#define LCD_REG_74 0x4A +#define LCD_REG_75 0x4B +#define LCD_REG_76 0x4C +#define LCD_REG_77 0x4D +#define LCD_REG_78 0x4E +#define LCD_REG_79 0x4F +#define LCD_REG_80 0x50 +#define LCD_REG_81 0x51 +#define LCD_REG_82 0x52 +#define LCD_REG_83 0x53 +#define LCD_REG_84 0x54 +#define LCD_REG_85 0x55 +#define LCD_REG_86 0x56 +#define LCD_REG_87 0x57 +#define LCD_REG_88 0x58 +#define LCD_REG_89 0x59 +#define LCD_REG_90 0x5A +#define LCD_REG_91 0x5B +#define LCD_REG_92 0x5C +#define LCD_REG_93 0x5D +#define LCD_REG_94 0x5E +#define LCD_REG_95 0x5F +#define LCD_REG_96 0x60 +#define LCD_REG_97 0x61 +#define LCD_REG_98 0x62 +#define LCD_REG_99 0x63 +#define LCD_REG_104 0x68 +#define LCD_REG_105 0x69 +#define LCD_REG_112 0x70 +#define LCD_REG_113 0x71 +#define LCD_REG_132 0x84 +#define LCD_REG_133 0x85 +#define LCD_REG_195 0xC3 +#define LCD_REG_197 0xC5 +#define LCD_REG_199 0xC7 +#define LCD_REG_203 0xCB +#define LCD_REG_204 0xCC +#define LCD_REG_205 0xCD +#define LCD_REG_206 0xCE +#define LCD_REG_207 0xCF +#define LCD_REG_208 0xD0 +#define LCD_REG_209 0xD1 +#define LCD_REG_210 0xD2 +#define LCD_REG_211 0xD3 +#define LCD_REG_232 0xE8 +#define LCD_REG_233 0xE9 +#define LCD_REG_234 0xEA +#define LCD_REG_235 0xEB +#define LCD_REG_236 0xEC +#define LCD_REG_237 0xED +#define LCD_REG_241 0xF1 +#define LCD_REG_242 0xF2 +#define LCD_REG_255 0xFF + +/** + * @} + */ + +/** @defgroup HX8347G_Exported_Functions + * @{ + */ +void hx8347g_Init(void); +uint16_t hx8347g_ReadID(void); +void hx8347g_WriteReg(uint8_t LCDReg, uint16_t LCDRegValue); +uint16_t hx8347g_ReadReg(uint8_t LCDReg); + +void hx8347g_DisplayOn(void); +void hx8347g_DisplayOff(void); +void hx8347g_SetCursor(uint16_t Xpos, uint16_t Ypos); +void hx8347g_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode); +uint16_t hx8347g_ReadPixel(uint16_t Xpos, uint16_t Ypos); + +void hx8347g_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length); +void hx8347g_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length); +void hx8347g_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp); + +void hx8347g_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height); + + +uint16_t hx8347g_GetLcdPixelWidth(void); +uint16_t hx8347g_GetLcdPixelHeight(void); + +/* LCD driver structure */ +extern LCD_DrvTypeDef hx8347g_drv; + +/* LCD IO functions */ +void LCD_IO_Init(void); +void LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size); +void LCD_IO_WriteReg(uint8_t Reg); +uint16_t LCD_IO_ReadData(uint16_t Reg); +void LCD_Delay (uint32_t delay); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __HX8347G_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/l3gd20/l3gd20.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,417 @@ +/** + ****************************************************************************** + * @file l3gd20.c + * @author MCD Application Team + * @version V2.0.0 + * @date 26-June-2015 + * @brief This file provides a set of functions needed to manage the L3GD20, + * ST MEMS motion sensor, 3-axis digital output gyroscope. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "l3gd20.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup L3GD20 + * @{ + */ + +/** @defgroup L3GD20_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup L3GD20_Private_Defines + * @{ + */ + +/** + * @} + */ + +/** @defgroup L3GD20_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup L3GD20_Private_Variables + * @{ + */ +GYRO_DrvTypeDef L3gd20Drv = +{ + L3GD20_Init, + L3GD20_DeInit, + L3GD20_ReadID, + L3GD20_RebootCmd, + L3GD20_LowPower, + L3GD20_INT1InterruptConfig, + L3GD20_EnableIT, + L3GD20_DisableIT, + 0, + 0, + L3GD20_FilterConfig, + L3GD20_FilterCmd, + L3GD20_ReadXYZAngRate +}; + +/** + * @} + */ + +/** @defgroup L3GD20_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup L3GD20_Private_Functions + * @{ + */ + +/** + * @brief Set L3GD20 Initialization. + * @param L3GD20_InitStruct: pointer to a L3GD20_InitTypeDef structure + * that contains the configuration setting for the L3GD20. + * @retval None + */ +void L3GD20_Init(uint16_t InitStruct) +{ + uint8_t ctrl = 0x00; + + /* Configure the low level interface */ + GYRO_IO_Init(); + + /* Write value to MEMS CTRL_REG1 register */ + ctrl = (uint8_t) InitStruct; + GYRO_IO_Write(&ctrl, L3GD20_CTRL_REG1_ADDR, 1); + + /* Write value to MEMS CTRL_REG4 register */ + ctrl = (uint8_t) (InitStruct >> 8); + GYRO_IO_Write(&ctrl, L3GD20_CTRL_REG4_ADDR, 1); +} + + + +/** + * @brief L3GD20 De-initialization + * @param None + * @retval None + */ +void L3GD20_DeInit(void) +{ +} + +/** + * @brief Read ID address of L3GD20 + * @param None + * @retval ID name + */ +uint8_t L3GD20_ReadID(void) +{ + uint8_t tmp; + + /* Configure the low level interface */ + GYRO_IO_Init(); + + /* Read WHO I AM register */ + GYRO_IO_Read(&tmp, L3GD20_WHO_AM_I_ADDR, 1); + + /* Return the ID */ + return (uint8_t)tmp; +} + +/** + * @brief Reboot memory content of L3GD20 + * @param None + * @retval None + */ +void L3GD20_RebootCmd(void) +{ + uint8_t tmpreg; + + /* Read CTRL_REG5 register */ + GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG5_ADDR, 1); + + /* Enable or Disable the reboot memory */ + tmpreg |= L3GD20_BOOT_REBOOTMEMORY; + + /* Write value to MEMS CTRL_REG5 register */ + GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG5_ADDR, 1); +} + +/** + * @brief Set L3GD20 in low-power mode + * @param + * @retval None + */ +void L3GD20_LowPower(uint16_t InitStruct) +{ + uint8_t ctrl = 0x00; + + /* Write value to MEMS CTRL_REG1 register */ + ctrl = (uint8_t) InitStruct; + GYRO_IO_Write(&ctrl, L3GD20_CTRL_REG1_ADDR, 1); +} + +/** + * @brief Set L3GD20 Interrupt INT1 configuration + * @param Int1Config: the configuration setting for the L3GD20 Interrupt. + * @retval None + */ +void L3GD20_INT1InterruptConfig(uint16_t Int1Config) +{ + uint8_t ctrl_cfr = 0x00, ctrl3 = 0x00; + + /* Read INT1_CFG register */ + GYRO_IO_Read(&ctrl_cfr, L3GD20_INT1_CFG_ADDR, 1); + + /* Read CTRL_REG3 register */ + GYRO_IO_Read(&ctrl3, L3GD20_CTRL_REG3_ADDR, 1); + + ctrl_cfr &= 0x80; + ctrl_cfr |= ((uint8_t) Int1Config >> 8); + + ctrl3 &= 0xDF; + ctrl3 |= ((uint8_t) Int1Config); + + /* Write value to MEMS INT1_CFG register */ + GYRO_IO_Write(&ctrl_cfr, L3GD20_INT1_CFG_ADDR, 1); + + /* Write value to MEMS CTRL_REG3 register */ + GYRO_IO_Write(&ctrl3, L3GD20_CTRL_REG3_ADDR, 1); +} + +/** + * @brief Enable INT1 or INT2 interrupt + * @param IntSel: choice of INT1 or INT2 + * This parameter can be: + * @arg L3GD20_INT1 + * @arg L3GD20_INT2 + * @retval None + */ +void L3GD20_EnableIT(uint8_t IntSel) +{ + uint8_t tmpreg; + + /* Read CTRL_REG3 register */ + GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG3_ADDR, 1); + + if(IntSel == L3GD20_INT1) + { + tmpreg &= 0x7F; + tmpreg |= L3GD20_INT1INTERRUPT_ENABLE; + } + else if(IntSel == L3GD20_INT2) + { + tmpreg &= 0xF7; + tmpreg |= L3GD20_INT2INTERRUPT_ENABLE; + } + + /* Write value to MEMS CTRL_REG3 register */ + GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG3_ADDR, 1); +} + +/** + * @brief Disable INT1 or INT2 interrupt + * @param IntSel: choice of INT1 or INT2 + * This parameter can be: + * @arg L3GD20_INT1 + * @arg L3GD20_INT2 + * @retval None + */ +void L3GD20_DisableIT(uint8_t IntSel) +{ + uint8_t tmpreg; + + /* Read CTRL_REG3 register */ + GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG3_ADDR, 1); + + if(IntSel == L3GD20_INT1) + { + tmpreg &= 0x7F; + tmpreg |= L3GD20_INT1INTERRUPT_DISABLE; + } + else if(IntSel == L3GD20_INT2) + { + tmpreg &= 0xF7; + tmpreg |= L3GD20_INT2INTERRUPT_DISABLE; + } + + /* Write value to MEMS CTRL_REG3 register */ + GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG3_ADDR, 1); +} + +/** + * @brief Set High Pass Filter Modality + * @param FilterStruct: contains the configuration setting for the L3GD20. + * @retval None + */ +void L3GD20_FilterConfig(uint8_t FilterStruct) +{ + uint8_t tmpreg; + + /* Read CTRL_REG2 register */ + GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG2_ADDR, 1); + + tmpreg &= 0xC0; + + /* Configure MEMS: mode and cutoff frequency */ + tmpreg |= FilterStruct; + + /* Write value to MEMS CTRL_REG2 register */ + GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG2_ADDR, 1); +} + +/** + * @brief Enable or Disable High Pass Filter + * @param HighPassFilterState: new state of the High Pass Filter feature. + * This parameter can be: + * @arg: L3GD20_HIGHPASSFILTER_DISABLE + * @arg: L3GD20_HIGHPASSFILTER_ENABLE + * @retval None + */ +void L3GD20_FilterCmd(uint8_t HighPassFilterState) +{ + uint8_t tmpreg; + + /* Read CTRL_REG5 register */ + GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG5_ADDR, 1); + + tmpreg &= 0xEF; + + tmpreg |= HighPassFilterState; + + /* Write value to MEMS CTRL_REG5 register */ + GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG5_ADDR, 1); +} + +/** + * @brief Get status for L3GD20 data + * @param None + * @retval Data status in a L3GD20 Data + */ +uint8_t L3GD20_GetDataStatus(void) +{ + uint8_t tmpreg; + + /* Read STATUS_REG register */ + GYRO_IO_Read(&tmpreg, L3GD20_STATUS_REG_ADDR, 1); + + return tmpreg; +} + +/** +* @brief Calculate the L3GD20 angular data. +* @param pfData: Data out pointer +* @retval None +*/ +void L3GD20_ReadXYZAngRate(float *pfData) +{ + uint8_t tmpbuffer[6] ={0}; + int16_t RawData[3] = {0}; + uint8_t tmpreg = 0; + float sensitivity = 0; + int i =0; + + GYRO_IO_Read(&tmpreg,L3GD20_CTRL_REG4_ADDR,1); + + GYRO_IO_Read(tmpbuffer,L3GD20_OUT_X_L_ADDR,6); + + /* check in the control register 4 the data alignment (Big Endian or Little Endian)*/ + if(!(tmpreg & L3GD20_BLE_MSB)) + { + for(i=0; i<3; i++) + { + RawData[i]=(int16_t)(((uint16_t)tmpbuffer[2*i+1] << 8) + tmpbuffer[2*i]); + } + } + else + { + for(i=0; i<3; i++) + { + RawData[i]=(int16_t)(((uint16_t)tmpbuffer[2*i] << 8) + tmpbuffer[2*i+1]); + } + } + + /* Switch the sensitivity value set in the CRTL4 */ + switch(tmpreg & L3GD20_FULLSCALE_SELECTION) + { + case L3GD20_FULLSCALE_250: + sensitivity=L3GD20_SENSITIVITY_250DPS; + break; + + case L3GD20_FULLSCALE_500: + sensitivity=L3GD20_SENSITIVITY_500DPS; + break; + + case L3GD20_FULLSCALE_2000: + sensitivity=L3GD20_SENSITIVITY_2000DPS; + break; + } + /* Divide by sensitivity */ + for(i=0; i<3; i++) + { + pfData[i]=(float)(RawData[i] * sensitivity); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/l3gd20/l3gd20.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,325 @@ +/** + ****************************************************************************** + * @file l3gd20.h + * @author MCD Application Team + * @version V2.0.0 + * @date 26-June-2015 + * @brief This file contains all the functions prototypes for the l3gd20.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __L3GD20_H +#define __L3GD20_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/gyro.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup L3GD20 + * @{ + */ + +/** @defgroup L3GD20_Exported_Constants + * @{ + */ + +/******************************************************************************/ +/*************************** START REGISTER MAPPING **************************/ +/******************************************************************************/ +#define L3GD20_WHO_AM_I_ADDR 0x0F /* device identification register */ +#define L3GD20_CTRL_REG1_ADDR 0x20 /* Control register 1 */ +#define L3GD20_CTRL_REG2_ADDR 0x21 /* Control register 2 */ +#define L3GD20_CTRL_REG3_ADDR 0x22 /* Control register 3 */ +#define L3GD20_CTRL_REG4_ADDR 0x23 /* Control register 4 */ +#define L3GD20_CTRL_REG5_ADDR 0x24 /* Control register 5 */ +#define L3GD20_REFERENCE_REG_ADDR 0x25 /* Reference register */ +#define L3GD20_OUT_TEMP_ADDR 0x26 /* Out temp register */ +#define L3GD20_STATUS_REG_ADDR 0x27 /* Status register */ +#define L3GD20_OUT_X_L_ADDR 0x28 /* Output Register X */ +#define L3GD20_OUT_X_H_ADDR 0x29 /* Output Register X */ +#define L3GD20_OUT_Y_L_ADDR 0x2A /* Output Register Y */ +#define L3GD20_OUT_Y_H_ADDR 0x2B /* Output Register Y */ +#define L3GD20_OUT_Z_L_ADDR 0x2C /* Output Register Z */ +#define L3GD20_OUT_Z_H_ADDR 0x2D /* Output Register Z */ +#define L3GD20_FIFO_CTRL_REG_ADDR 0x2E /* Fifo control Register */ +#define L3GD20_FIFO_SRC_REG_ADDR 0x2F /* Fifo src Register */ + +#define L3GD20_INT1_CFG_ADDR 0x30 /* Interrupt 1 configuration Register */ +#define L3GD20_INT1_SRC_ADDR 0x31 /* Interrupt 1 source Register */ +#define L3GD20_INT1_TSH_XH_ADDR 0x32 /* Interrupt 1 Threshold X register */ +#define L3GD20_INT1_TSH_XL_ADDR 0x33 /* Interrupt 1 Threshold X register */ +#define L3GD20_INT1_TSH_YH_ADDR 0x34 /* Interrupt 1 Threshold Y register */ +#define L3GD20_INT1_TSH_YL_ADDR 0x35 /* Interrupt 1 Threshold Y register */ +#define L3GD20_INT1_TSH_ZH_ADDR 0x36 /* Interrupt 1 Threshold Z register */ +#define L3GD20_INT1_TSH_ZL_ADDR 0x37 /* Interrupt 1 Threshold Z register */ +#define L3GD20_INT1_DURATION_ADDR 0x38 /* Interrupt 1 DURATION register */ + +/******************************************************************************/ +/**************************** END REGISTER MAPPING ***************************/ +/******************************************************************************/ + +#define I_AM_L3GD20 ((uint8_t)0xD4) +#define I_AM_L3GD20_TR ((uint8_t)0xD5) + +/** @defgroup Power_Mode_selection + * @{ + */ +#define L3GD20_MODE_POWERDOWN ((uint8_t)0x00) +#define L3GD20_MODE_ACTIVE ((uint8_t)0x08) +/** + * @} + */ + +/** @defgroup OutPut_DataRate_Selection + * @{ + */ +#define L3GD20_OUTPUT_DATARATE_1 ((uint8_t)0x00) +#define L3GD20_OUTPUT_DATARATE_2 ((uint8_t)0x40) +#define L3GD20_OUTPUT_DATARATE_3 ((uint8_t)0x80) +#define L3GD20_OUTPUT_DATARATE_4 ((uint8_t)0xC0) +/** + * @} + */ + +/** @defgroup Axes_Selection + * @{ + */ +#define L3GD20_X_ENABLE ((uint8_t)0x02) +#define L3GD20_Y_ENABLE ((uint8_t)0x01) +#define L3GD20_Z_ENABLE ((uint8_t)0x04) +#define L3GD20_AXES_ENABLE ((uint8_t)0x07) +#define L3GD20_AXES_DISABLE ((uint8_t)0x00) +/** + * @} + */ + +/** @defgroup Bandwidth_Selection + * @{ + */ +#define L3GD20_BANDWIDTH_1 ((uint8_t)0x00) +#define L3GD20_BANDWIDTH_2 ((uint8_t)0x10) +#define L3GD20_BANDWIDTH_3 ((uint8_t)0x20) +#define L3GD20_BANDWIDTH_4 ((uint8_t)0x30) +/** + * @} + */ + +/** @defgroup Full_Scale_Selection + * @{ + */ +#define L3GD20_FULLSCALE_250 ((uint8_t)0x00) +#define L3GD20_FULLSCALE_500 ((uint8_t)0x10) +#define L3GD20_FULLSCALE_2000 ((uint8_t)0x20) +#define L3GD20_FULLSCALE_SELECTION ((uint8_t)0x30) +/** + * @} + */ + +/** @defgroup Full_Scale_Sensitivity + * @{ + */ +#define L3GD20_SENSITIVITY_250DPS ((float)8.75f) /*!< gyroscope sensitivity with 250 dps full scale [DPS/LSB] */ +#define L3GD20_SENSITIVITY_500DPS ((float)17.50f) /*!< gyroscope sensitivity with 500 dps full scale [DPS/LSB] */ +#define L3GD20_SENSITIVITY_2000DPS ((float)70.00f) /*!< gyroscope sensitivity with 2000 dps full scale [DPS/LSB] */ +/** + * @} + */ + + +/** @defgroup Block_Data_Update + * @{ + */ +#define L3GD20_BlockDataUpdate_Continous ((uint8_t)0x00) +#define L3GD20_BlockDataUpdate_Single ((uint8_t)0x80) +/** + * @} + */ + +/** @defgroup Endian_Data_selection + * @{ + */ +#define L3GD20_BLE_LSB ((uint8_t)0x00) +#define L3GD20_BLE_MSB ((uint8_t)0x40) +/** + * @} + */ + +/** @defgroup High_Pass_Filter_status + * @{ + */ +#define L3GD20_HIGHPASSFILTER_DISABLE ((uint8_t)0x00) +#define L3GD20_HIGHPASSFILTER_ENABLE ((uint8_t)0x10) +/** + * @} + */ + +/** @defgroup INT1_INT2_selection + * @{ + */ +#define L3GD20_INT1 ((uint8_t)0x00) +#define L3GD20_INT2 ((uint8_t)0x01) +/** + * @} + */ + +/** @defgroup INT1_Interrupt_status + * @{ + */ +#define L3GD20_INT1INTERRUPT_DISABLE ((uint8_t)0x00) +#define L3GD20_INT1INTERRUPT_ENABLE ((uint8_t)0x80) +/** + * @} + */ + +/** @defgroup INT2_Interrupt_status + * @{ + */ +#define L3GD20_INT2INTERRUPT_DISABLE ((uint8_t)0x00) +#define L3GD20_INT2INTERRUPT_ENABLE ((uint8_t)0x08) +/** + * @} + */ + +/** @defgroup INT1_Interrupt_ActiveEdge + * @{ + */ +#define L3GD20_INT1INTERRUPT_LOW_EDGE ((uint8_t)0x20) +#define L3GD20_INT1INTERRUPT_HIGH_EDGE ((uint8_t)0x00) +/** + * @} + */ + +/** @defgroup Boot_Mode_selection + * @{ + */ +#define L3GD20_BOOT_NORMALMODE ((uint8_t)0x00) +#define L3GD20_BOOT_REBOOTMEMORY ((uint8_t)0x80) +/** + * @} + */ + +/** @defgroup High_Pass_Filter_Mode + * @{ + */ +#define L3GD20_HPM_NORMAL_MODE_RES ((uint8_t)0x00) +#define L3GD20_HPM_REF_SIGNAL ((uint8_t)0x10) +#define L3GD20_HPM_NORMAL_MODE ((uint8_t)0x20) +#define L3GD20_HPM_AUTORESET_INT ((uint8_t)0x30) +/** + * @} + */ + +/** @defgroup High_Pass_CUT OFF_Frequency + * @{ + */ +#define L3GD20_HPFCF_0 0x00 +#define L3GD20_HPFCF_1 0x01 +#define L3GD20_HPFCF_2 0x02 +#define L3GD20_HPFCF_3 0x03 +#define L3GD20_HPFCF_4 0x04 +#define L3GD20_HPFCF_5 0x05 +#define L3GD20_HPFCF_6 0x06 +#define L3GD20_HPFCF_7 0x07 +#define L3GD20_HPFCF_8 0x08 +#define L3GD20_HPFCF_9 0x09 +/** + * @} + */ + +/** + * @} + */ +/** @defgroup L3GD20_Exported_Functions + * @{ + */ +/* Sensor Configuration Functions */ +void L3GD20_Init(uint16_t InitStruct); +void L3GD20_DeInit(void); +void L3GD20_LowPower(uint16_t InitStruct); +uint8_t L3GD20_ReadID(void); +void L3GD20_RebootCmd(void); + +/* Interrupt Configuration Functions */ +void L3GD20_INT1InterruptConfig(uint16_t Int1Config); +void L3GD20_EnableIT(uint8_t IntSel); +void L3GD20_DisableIT(uint8_t IntSel); + +/* High Pass Filter Configuration Functions */ +void L3GD20_FilterConfig(uint8_t FilterStruct); +void L3GD20_FilterCmd(uint8_t HighPassFilterState); +void L3GD20_ReadXYZAngRate(float *pfData); +uint8_t L3GD20_GetDataStatus(void); + +/* Gyroscope IO functions */ +void GYRO_IO_Init(void); +void GYRO_IO_DeInit(void); +void GYRO_IO_Write(uint8_t *pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite); +void GYRO_IO_Read(uint8_t *pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead); + +/* Gyroscope driver structure */ +extern GYRO_DrvTypeDef L3gd20Drv; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus + } +#endif + +#endif /* __L3GD20_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/lsm303c/lsm303c.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,445 @@ +/** + ****************************************************************************** + * @file lsm303c.c + * @author MCD Application Team + * @version V1.0.0 + * @date 24-June-2015 + * @brief This file provides a set of functions needed to manage the LSM303C + * MEMS accelerometer. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "lsm303c.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup LSM303C + * @{ + */ + +/** @defgroup LSM303C_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup LSM303C_Private_Defines + * @{ + */ + +/** + * @} + */ + +/** @defgroup LSM303C_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup LSM303C_Private_Functions + * @{ + */ + +/* ACCELEROMETER functions */ +void LSM303C_AccInit(uint16_t InitStruct); +void LSM303C_AccDeInit(void); +uint8_t LSM303C_AccReadID(void); +void LSM303C_AccLowPower(void); +void LSM303C_AccFilterConfig(uint8_t FilterStruct); +void LSM303C_AccFilterCmd(uint8_t HighPassFilterState); +void LSM303C_AccReadXYZ(int16_t* pData); +void LSM303C_AccFilterClickCmd(uint8_t HighPassFilterClickState); +void LSM303C_AccIT1Enable(uint8_t LSM303C_IT); +void LSM303C_AccIT1Disable(uint8_t LSM303C_IT); +void LSM303C_AccIT2Enable(uint8_t LSM303C_IT); +void LSM303C_AccIT2Disable(uint8_t LSM303C_IT); +void LSM303C_AccClickITEnable(uint8_t ITClick); +void LSM303C_AccClickITDisable(uint8_t ITClick); +void LSM303C_AccZClickITConfig(void); + +/* MAGNETOMETER functions */ +void LSM303C_MagInit(MAGNETO_InitTypeDef LSM303C_InitStruct); +void LSM303C_MagDeInit(void); +uint8_t LSM303C_MagReadID(void); +void LSM303C_MagLowPower(void); +void LSM303C_MagReadXYZ(int16_t* pData); +uint8_t LSM303C_MagGetDataStatus(void); + + +/* COMPASS / ACCELERO IO functions */ +extern void ACCELERO_IO_Init(void); +extern void ACCELERO_IO_ITConfig(void); +extern void ACCELERO_IO_Write(uint8_t RegisterAddr, uint8_t Value); +extern uint8_t ACCELERO_IO_Read(uint8_t RegisterAddr); + +/* COMPASS IO function */ +extern void MAGNETO_IO_Init(void); +extern void MAGNETO_IO_ITConfig(void); +extern void MAGNETO_IO_Write(uint8_t RegisterAddr, uint8_t Value); +extern uint8_t MAGNETO_IO_Read(uint8_t RegisterAddr); + +/** + * @} + */ + + +/** @defgroup LSM303C_Private_Variables + * @{ + */ +ACCELERO_DrvTypeDef Lsm303cDrv_accelero = +{ + LSM303C_AccInit, + LSM303C_AccDeInit, + LSM303C_AccReadID, + 0, + LSM303C_AccLowPower, + 0, + 0, + 0, + 0, + 0, + LSM303C_AccFilterConfig, + 0, + LSM303C_AccReadXYZ +}; + +MAGNETO_DrvTypeDef Lsm303cDrv_magneto = +{ + LSM303C_MagInit, + LSM303C_MagDeInit, + LSM303C_MagReadID, + 0, + LSM303C_MagLowPower, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + LSM303C_MagReadXYZ + +}; + +/** + * @} + */ + + +/** + * @brief Set LSM303C Accelerometer Initialization. + * @param InitStruct: Init parameters + * @retval None + */ +void LSM303C_AccInit(uint16_t InitStruct) +{ + uint8_t ctrl = 0x00; + + /* Low level init */ + ACCELERO_IO_Init(); + + /* Write value to ACC MEMS CTRL_REG1 register */ + ctrl = (uint8_t) InitStruct; + ACCELERO_IO_Write(LSM303C_CTRL_REG1_A, ctrl); + + /* Write value to ACC MEMS CTRL_REG4 register */ + ctrl = ((uint8_t) (InitStruct >> 8)); + ACCELERO_IO_Write(LSM303C_CTRL_REG4_A, ctrl); +} + +/** + * @brief LSM303C Accelerometer De-initialization. + * @param None + * @retval None + */ +void LSM303C_AccDeInit(void) +{ +} + +/** + * @brief Read LSM303C ID. + * @param None + * @retval ID + */ +uint8_t LSM303C_AccReadID(void) +{ + uint8_t ctrl = 0x00; + + /* Low level init */ + ACCELERO_IO_Init(); + + /* Enabled SPI/I2C read communication */ + ACCELERO_IO_Write(LSM303C_CTRL_REG4_A, 0x5); + + /* Read value at Who am I register address */ + ctrl = ACCELERO_IO_Read(LSM303C_WHO_AM_I_ADDR); + + return ctrl; +} + +/** + * @brief Put Accelerometer in power down mode. + * @param None + * @retval None + */ +void LSM303C_AccLowPower(void) +{ + uint8_t ctrl = 0x00; + + /* Read control register 1 value */ + ctrl = ACCELERO_IO_Read(LSM303C_CTRL_REG1_A); + + /* Clear ODR bits */ + ctrl &= ~(LSM303C_ACC_ODR_BITPOSITION); + + /* Set Power down */ + ctrl |= LSM303C_ACC_ODR_OFF; + + /* write back control register */ + ACCELERO_IO_Write(LSM303C_CTRL_REG1_A, ctrl); +} + +/** + * @brief Set High Pass Filter Modality + * @param FilterStruct: contains data for filter config + * @retval None + */ +void LSM303C_AccFilterConfig(uint8_t FilterStruct) +{ + uint8_t tmpreg; + +// /* Read CTRL_REG2 register */ +// tmpreg = ACCELERO_IO_Read(LSM303C_CTRL_REG2_A); +// +// tmpreg &= 0x0C; + tmpreg = FilterStruct; + + /* Write value to ACC MEMS CTRL_REG2 register */ + ACCELERO_IO_Write(LSM303C_CTRL_REG2_A, tmpreg); +} + +/** + * @brief Read X, Y & Z Acceleration values + * @param pData: Data out pointer + * @retval None + */ +void LSM303C_AccReadXYZ(int16_t* pData) +{ + int16_t pnRawData[3]; + uint8_t ctrlx[2]={0,0}; + uint8_t buffer[6]; + uint8_t i = 0; + uint8_t sensitivity = LSM303C_ACC_SENSITIVITY_2G; + + /* Read the acceleration control register content */ + ctrlx[0] = ACCELERO_IO_Read(LSM303C_CTRL_REG4_A); + ctrlx[1] = ACCELERO_IO_Read(LSM303C_CTRL_REG5_A); + + /* Read output register X, Y & Z acceleration */ + buffer[0] = ACCELERO_IO_Read(LSM303C_OUT_X_L_A); + buffer[1] = ACCELERO_IO_Read(LSM303C_OUT_X_H_A); + buffer[2] = ACCELERO_IO_Read(LSM303C_OUT_Y_L_A); + buffer[3] = ACCELERO_IO_Read(LSM303C_OUT_Y_H_A); + buffer[4] = ACCELERO_IO_Read(LSM303C_OUT_Z_L_A); + buffer[5] = ACCELERO_IO_Read(LSM303C_OUT_Z_H_A); + + for(i=0; i<3; i++) + { + pnRawData[i]=((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i]); + } + + /* Normal mode */ + /* Switch the sensitivity value set in the CRTL4 */ + switch(ctrlx[0] & LSM303C_ACC_FULLSCALE_8G) + { + case LSM303C_ACC_FULLSCALE_2G: + sensitivity = LSM303C_ACC_SENSITIVITY_2G; + break; + case LSM303C_ACC_FULLSCALE_4G: + sensitivity = LSM303C_ACC_SENSITIVITY_4G; + break; + case LSM303C_ACC_FULLSCALE_8G: + sensitivity = LSM303C_ACC_SENSITIVITY_8G; + break; + } + + /* Obtain the mg value for the three axis */ + for(i=0; i<3; i++) + { + pData[i]=(pnRawData[i] * sensitivity); + } +} + +/*********************************************************************************************** + Magnetometer driver +***********************************************************************************************/ + +/** + * @brief Set LSM303C Magnetometer Initialization. + * @param LSM303C_InitStruct: pointer to a LSM303C_MagInitTypeDef structure + * that contains the configuration setting for the LSM303C. + * @retval None + */ +void LSM303C_MagInit(MAGNETO_InitTypeDef LSM303C_InitStruct) +{ + MAGNETO_IO_Write(LSM303C_CTRL_REG1_M, LSM303C_InitStruct.Register1); + MAGNETO_IO_Write(LSM303C_CTRL_REG2_M, LSM303C_InitStruct.Register2); + MAGNETO_IO_Write(LSM303C_CTRL_REG3_M, LSM303C_InitStruct.Register3); + MAGNETO_IO_Write(LSM303C_CTRL_REG4_M, LSM303C_InitStruct.Register4); + MAGNETO_IO_Write(LSM303C_CTRL_REG5_M, LSM303C_InitStruct.Register5); +} + +/** + * @brief LSM303C Magnetometer De-initialization. + * @param None + * @retval None + */ +void LSM303C_MagDeInit(void) +{ +} + +/** + * @brief Read LSM303C ID. + * @param None + * @retval ID + */ +uint8_t LSM303C_MagReadID(void) +{ + /* Low level init */ + MAGNETO_IO_Init(); + + /* Enabled the SPI/I2C read operation */ + MAGNETO_IO_Write(LSM303C_CTRL_REG3_M, 0x84); + + /* Read value at Who am I register address */ + return MAGNETO_IO_Read(LSM303C_WHO_AM_I_ADDR); +} + +/** + * @brief Put Magnetometer in power down mode. + * @param None + * @retval None + */ +void LSM303C_MagLowPower(void) +{ + uint8_t ctrl = 0x00; + + /* Read control register 1 value */ + ctrl = MAGNETO_IO_Read(LSM303C_CTRL_REG3_M); + + /* Clear ODR bits */ + ctrl &= ~(LSM303C_MAG_SELECTION_MODE); + + /* Set Power down */ + ctrl |= LSM303C_MAG_POWERDOWN2_MODE; + + /* write back control register */ + MAGNETO_IO_Write(LSM303C_CTRL_REG3_M, ctrl); +} + +/** + * @brief Get status for Mag LSM303C data + * @param None + * @retval Data status in a LSM303C Data register + */ +uint8_t LSM303C_MagGetDataStatus(void) +{ + /* Read Mag STATUS register */ + return MAGNETO_IO_Read(LSM303C_STATUS_REG_M); +} + +/** + * @brief Read X, Y & Z Magnetometer values + * @param pData: Data out pointer + * @retval None + */ +void LSM303C_MagReadXYZ(int16_t* pData) +{ + uint8_t ctrlx; + uint8_t buffer[6]; + uint8_t i=0; + + /* Read the magnetometer control register content */ + ctrlx = MAGNETO_IO_Read(LSM303C_CTRL_REG4_M); + + /* Read output register X, Y & Z magnetometer */ + buffer[0] = MAGNETO_IO_Read(LSM303C_OUT_X_L_M); + buffer[1] = MAGNETO_IO_Read(LSM303C_OUT_X_H_M); + buffer[2] = MAGNETO_IO_Read(LSM303C_OUT_Y_L_M); + buffer[3] = MAGNETO_IO_Read(LSM303C_OUT_Y_H_M); + buffer[4] = MAGNETO_IO_Read(LSM303C_OUT_Z_L_M); + buffer[5] = MAGNETO_IO_Read(LSM303C_OUT_Z_H_M); + + /* Check in the control register4 the data alignment*/ + if((ctrlx & LSM303C_MAG_BLE_MSB)) + { + for(i=0; i<3; i++) + { + pData[i]=((int16_t)((uint16_t)buffer[2*i] << 8) + buffer[2*i+1]); + } + } + else + { + for(i=0; i<3; i++) + { + pData[i]=((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i]); + } + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/lsm303c/lsm303c.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,567 @@ +/** + ****************************************************************************** + * @file lsm303c.h + * @author MCD Application Team + * @version V1.0.0 + * @date 24-June-2015 + * @brief This file contains all the functions prototypes for the LSM303C.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __LSM303C_H +#define __LSM303C_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/accelero.h" +#include "../Common/magneto.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup LSM303C + * @{ + */ + +/** @defgroup LSM303C_Exported_Types + * @{ + */ + +/** + * @} + */ + +/******************************************************************************/ +/*************************** START REGISTER MAPPING **************************/ +/******************************************************************************/ +/* Acceleration Registers */ +#define LSM303C_WHO_AM_I_ADDR 0x0F /* device identification register */ +#define LSM303C_ACT_THS_A 0x1E +#define LSM303C_ACT_DUR_A 0x1F +#define LSM303C_CTRL_REG1_A 0x20 /* Control register 1 acceleration */ +#define LSM303C_CTRL_REG2_A 0x21 /* Control register 2 acceleration */ +#define LSM303C_CTRL_REG3_A 0x22 /* Control register 3 acceleration */ +#define LSM303C_CTRL_REG4_A 0x23 /* Control register 4 acceleration */ +#define LSM303C_CTRL_REG5_A 0x24 /* Control register 5 acceleration */ +#define LSM303C_CTRL_REG6_A 0x25 /* Control register 6 acceleration */ +#define LSM303C_CTRL_REG7_A 0x26 /* Control register 6 acceleration */ +#define LSM303C_STATUS_REG_A 0x27 /* Status register acceleration */ +#define LSM303C_OUT_X_L_A 0x28 /* Output Register X acceleration */ +#define LSM303C_OUT_X_H_A 0x29 /* Output Register X acceleration */ +#define LSM303C_OUT_Y_L_A 0x2A /* Output Register Y acceleration */ +#define LSM303C_OUT_Y_H_A 0x2B /* Output Register Y acceleration */ +#define LSM303C_OUT_Z_L_A 0x2C /* Output Register Z acceleration */ +#define LSM303C_OUT_Z_H_A 0x2D /* Output Register Z acceleration */ +#define LSM303C_FIFO_CTRL 0x2E /* Fifo control Register acceleration */ +#define LSM303C_FIFO_SRC 0x2F /* Fifo src Register acceleration */ + +#define LSM303C_IG_CFG1_A 0x30 /* Interrupt 1 configuration Register acceleration */ +#define LSM303C_IG_SRC1_A 0x31 /* Interrupt 1 source Register acceleration */ +#define LSM303C_IG_THS_X1_A 0x32 +#define LSM303C_IG_THS_Y1_A 0x33 +#define LSM303C_IG_THS_Z1_A 0x34 + +#define LSM303C_IG_DUR1_A 0x32 +#define LSM303C_INT1_DURATION_A 0x33 /* Interrupt 1 DURATION register acceleration */ + +#define LSM303C_INT2_CFG_A 0x34 /* Interrupt 2 configuration Register acceleration */ +#define LSM303C_INT2_SOURCE_A 0x35 /* Interrupt 2 source Register acceleration */ +#define LSM303C_INT2_THS_A 0x36 /* Interrupt 2 Threshold register acceleration */ +#define LSM303C_INT2_DURATION_A 0x37 /* Interrupt 2 DURATION register acceleration */ + +#define LSM303C_CLICK_CFG_A 0x38 /* Click configuration Register acceleration */ +#define LSM303C_CLICK_SOURCE_A 0x39 /* Click 2 source Register acceleration */ +#define LSM303C_CLICK_THS_A 0x3A /* Click 2 Threshold register acceleration */ + +#define LSM303C_TIME_LIMIT_A 0x3B /* Time Limit Register acceleration */ +#define LSM303C_TIME_LATENCY_A 0x3C /* Time Latency Register acceleration */ +#define LSM303C_TIME_WINDOW_A 0x3D /* Time window register acceleration */ + +/* Magnetic field Registers */ +#define LSM303C_CTRL_REG1_M 0x20 /* Magnetic control register 1 */ +#define LSM303C_CTRL_REG2_M 0x21 /* Magnetic control register 2 */ +#define LSM303C_CTRL_REG3_M 0x22 /* Magnetic control register 3 */ +#define LSM303C_CTRL_REG4_M 0x23 /* Magnetic control register 4 */ +#define LSM303C_CTRL_REG5_M 0x24 /* Magnetic control register 5 */ + +#define LSM303C_STATUS_REG_M 0x27 /* Magnetic status register M */ + +#define LSM303C_OUT_X_L_M 0x28 /* Output Register X magnetic field */ +#define LSM303C_OUT_X_H_M 0x29 /* Output Register X magnetic field */ +#define LSM303C_OUT_Y_L_M 0x2A /* Output Register Y magnetic field */ +#define LSM303C_OUT_Y_H_M 0x2B /* Output Register Y magnetic field */ +#define LSM303C_OUT_Z_L_M 0x2C /* Output Register Z magnetic field */ +#define LSM303C_OUT_Z_H_M 0x2D /* Output Register Z magnetic field */ + +#define LSM303C_TEMP_OUT_L_M 0x2E /* Temperature Register magnetic field */ +#define LSM303C_TEMP_OUT_H_M 0x2F /* Temperature Register magnetic field */ + +#define LSM303C_INT_CFG_M 0x30 /* Axis interrupt configuration */ +#define LSM303C_INT_SRC_M 0x31 /* Axis interrupt source */ +#define LSM303C_INT_THS_L_M 0x32 /* Interrupt threshold L */ +#define LSM303C_INT_THS_H_M 0x33 /* Interrupt threshold M */ + + +/******************************************************************************/ +/**************************** END REGISTER MAPPING ***************************/ +/******************************************************************************/ + +/** @defgroup Power_Mode_selection + * @{ + */ +#define LMS303C_ACC_ID ((uint8_t)0x41) +#define LMS303C_MAG_ID ((uint8_t)0x3D) +/** + * @} + */ + +/** @defgroup Acc_OutPut_DataRate_Selection + * @{ + */ +#define LSM303C_ACC_ODR_BITPOSITION ((uint8_t)0x70) /*!< Output Data Rate bit position */ +#define LSM303C_ACC_ODR_OFF ((uint8_t)0x00) /*!< Output Data Rate powerdown */ +#define LSM303C_ACC_ODR_10_HZ ((uint8_t)0x10) /*!< Output Data Rate = 10 Hz */ +#define LSM303C_ACC_ODR_50_HZ ((uint8_t)0x20) /*!< Output Data Rate = 50 Hz */ +#define LSM303C_ACC_ODR_100_HZ ((uint8_t)0x30) /*!< Output Data Rate = 100 Hz */ +#define LSM303C_ACC_ODR_200_HZ ((uint8_t)0x40) /*!< Output Data Rate = 200 Hz */ +#define LSM303C_ACC_ODR_400_HZ ((uint8_t)0x50) /*!< Output Data Rate = 400 Hz */ +#define LSM303C_ACC_ODR_800_HZ ((uint8_t)0x60) /*!< Output Data Rate = 800 Hz */ + +/** + * @} + */ + +/** @defgroup Acc_Axes_Selection + * @{ + */ +#define LSM303C_ACC_X_ENABLE ((uint8_t)0x01) +#define LSM303C_ACC_Y_ENABLE ((uint8_t)0x02) +#define LSM303C_ACC_Z_ENABLE ((uint8_t)0x04) +#define LSM303C_ACC_AXES_ENABLE ((uint8_t)0x07) +#define LSM303C_ACC_AXES_DISABLE ((uint8_t)0x00) +/** + * @} + */ + +/** @defgroup Acc_High_Resolution + * @{ + */ +#define LSM303C_ACC_HR_ENABLE ((uint8_t)0x80) +#define LSM303C_ACC_HR_DISABLE ((uint8_t)0x00) +/** + * @} + */ + +/** @defgroup Communication_Mode + * @{ + */ +#define LSM303C_ACC_I2C_MODE ((uint8_t) 0x02) +#define LSM303C_ACC_SPI_MODE ((uint8_t) 0x01) +/** + * @} + */ + +/** @defgroup Acc_Full_Scale_Selection + * @{ + */ +#define LSM303C_ACC_FULLSCALE_2G ((uint8_t)0x00) /*!< ±2 g */ +#define LSM303C_ACC_FULLSCALE_4G ((uint8_t)0x20) /*!< ±4 g */ +#define LSM303C_ACC_FULLSCALE_8G ((uint8_t)0x30) /*!< ±8 g */ +/** + * @} + */ + +/** @defgroup Acc_Full_Scale_Selection + * @{ + */ +#define LSM303C_ACC_SENSITIVITY_2G ((uint8_t)1) /*!< accelerometer sensitivity with 2 g full scale [mg/LSB] */ +#define LSM303C_ACC_SENSITIVITY_4G ((uint8_t)2) /*!< accelerometer sensitivity with 4 g full scale [mg/LSB] */ +#define LSM303C_ACC_SENSITIVITY_8G ((uint8_t)4) /*!< accelerometer sensitivity with 8 g full scale [mg/LSB] */ +#define LSM303C_ACC_SENSITIVITY_16G ((uint8_t)12) /*!< accelerometer sensitivity with 12 g full scale [mg/LSB] */ +/** + * @} + */ + +/** @defgroup Acc_Block_Data_Update + * @{ + */ +#define LSM303C_ACC_BDU_CONTINUOUS ((uint8_t)0x00) /*!< Continuos Update */ +#define LSM303C_ACC_BDU_MSBLSB ((uint8_t)0x08) /*!< Single Update: output registers not updated until MSB and LSB reading */ +/** + * @} + */ + +/** @defgroup Acc_Endian_Data_selection + * @{ + */ +#define LSM303C_ACC_BLE_LSB ((uint8_t)0x00) /*!< Little Endian: data LSB @ lower address */ +#define LSM303C_ACC_BLE_MSB ((uint8_t)0x40) /*!< Big Endian: data MSB @ lower address */ +/** + * @} + */ + +/** @defgroup Acc_High_Pass_Filter_Mode + * @{ + */ +#define LSM303C_ACC_HPM_REF_SIGNAL ((uint8_t)0x08) +#define LSM303C_ACC_HPM_NORMAL_MODE ((uint8_t)0x00) +/** + * @} + */ + +/** @defgroup Acc_High_Pass_CUT OFF_Frequency + * @{ + */ +#define LSM303C_ACC_DFC1_ODRDIV50 ((uint8_t)0x00) +#define LSM303C_ACC_DFC1_ODRDIV100 ((uint8_t)0x20) +#define LSM303C_ACC_DFC1_ODRDIV9 ((uint8_t)0x40) +#define LSM303C_ACC_DFC1_ODRDIV400 ((uint8_t)0x60) +/** + * @} + */ + +/** @defgroup Acc_High_Pass_Filter_status + * @{ + */ +#define LSM303C_ACC_HPF_DISABLE ((uint8_t)0x00) +#define LSM303C_ACC_HPF_ENABLE ((uint8_t)0x08) +/** + * @} + */ + +/** @defgroup Acc_High_Pass_Filter_Click_status + * @{ + */ +#define LSM303C_ACC_HPF_CLICK_DISABLE ((uint8_t)0x00) +#define LSM303C_ACC_HPF_CLICK_ENABLE ((uint8_t)0x04) +/** + * @} + */ + +/** @defgroup Acc_High_Pass_Filter_HPI2S_status + * @{ + */ +#define LSM303C_ACC_HPI2S_INT1_DISABLE ((uint8_t)0x00) +#define LSM303C_ACC_HPI2S_INT1_ENABLE ((uint8_t)0x01) +#define LSM303C_ACC_HPI2S_INT2_DISABLE ((uint8_t)0x00) +#define LSM303C_ACC_HPI2S_INT2_ENABLE ((uint8_t)0x02) +/** + * @} + */ + +/** @defgroup Acc_Interrupt1_Configuration_definition + * @{ + */ +#define LSM303C_IT1_CLICK ((uint8_t)0x80) +#define LSM303C_IT1_AOI1 ((uint8_t)0x40) +#define LSM303C_IT1_AOI2 ((uint8_t)0x20) +#define LSM303C_IT1_DRY1 ((uint8_t)0x10) +#define LSM303C_IT1_DRY2 ((uint8_t)0x08) +#define LSM303C_IT1_WTM ((uint8_t)0x04) +#define LSM303C_IT1_OVERRUN ((uint8_t)0x02) +/** + * @} + */ + +/** @defgroup Acc_Interrupt2_Configuration_definition + * @{ + */ +#define LSM303C_IT2_CLICK ((uint8_t)0x80) +#define LSM303C_IT2_INT1 ((uint8_t)0x40) +#define LSM303C_IT2_INT2 ((uint8_t)0x20) +#define LSM303C_IT2_BOOT ((uint8_t)0x10) +#define LSM303C_IT2_ACT ((uint8_t)0x08) +#define LSM303C_IT2_HLACTIVE ((uint8_t)0x02) +/** + * @} + */ + +/** @defgroup Acc_INT_Combination_Status + * @{ + */ +#define LSM303C_OR_COMBINATION ((uint8_t)0x00) /*!< OR combination of enabled IRQs */ +#define LSM303C_AND_COMBINATION ((uint8_t)0x80) /*!< AND combination of enabled IRQs */ +#define LSM303C_MOV_RECOGNITION ((uint8_t)0x40) /*!< 6D movement recognition */ +#define LSM303C_POS_RECOGNITION ((uint8_t)0xC0) /*!< 6D position recognition */ +/** + * @} + */ + +/** @defgroup Acc_INT_Axes + * @{ + */ +#define LSM303C_Z_HIGH ((uint8_t)0x20) /*!< Z High enabled IRQs */ +#define LSM303C_Z_LOW ((uint8_t)0x10) /*!< Z low enabled IRQs */ +#define LSM303C_Y_HIGH ((uint8_t)0x08) /*!< Y High enabled IRQs */ +#define LSM303C_Y_LOW ((uint8_t)0x04) /*!< Y low enabled IRQs */ +#define LSM303C_X_HIGH ((uint8_t)0x02) /*!< X High enabled IRQs */ +#define LSM303C_X_LOW ((uint8_t)0x01) /*!< X low enabled IRQs */ +/** + * @} + */ + +/** @defgroup Acc_INT_Click +* @{ +*/ +#define LSM303C_Z_DOUBLE_CLICK ((uint8_t)0x20) /*!< Z double click IRQs */ +#define LSM303C_Z_SINGLE_CLICK ((uint8_t)0x10) /*!< Z single click IRQs */ +#define LSM303C_Y_DOUBLE_CLICK ((uint8_t)0x08) /*!< Y double click IRQs */ +#define LSM303C_Y_SINGLE_CLICK ((uint8_t)0x04) /*!< Y single click IRQs */ +#define LSM303C_X_DOUBLE_CLICK ((uint8_t)0x02) /*!< X double click IRQs */ +#define LSM303C_X_SINGLE_CLICK ((uint8_t)0x01) /*!< X single click IRQs */ +/** +* @} +*/ + +/** @defgroup Acc_INT1_Interrupt_status + * @{ + */ +#define LSM303C_INT1INTERRUPT_DISABLE ((uint8_t)0x00) +#define LSM303C_INT1INTERRUPT_ENABLE ((uint8_t)0x80) +/** + * @} + */ + +/** @defgroup Acc_INT1_Interrupt_ActiveEdge + * @{ + */ +#define LSM303C_INT1INTERRUPT_LOW_EDGE ((uint8_t)0x20) +#define LSM303C_INT1INTERRUPT_HIGH_EDGE ((uint8_t)0x00) +/** + * @} + */ + + +/** @defgroup Mag_Temperature_Sensor + * @{ + */ +#define LSM303C_MAG_TEMPSENSOR_ENABLE ((uint8_t) 0x80) /*!< Temp sensor Enable */ +#define LSM303C_MAG_TEMPSENSOR_DISABLE ((uint8_t) 0x00) /*!< Temp sensor Disable */ +/** + * @} + */ + +/** @defgroup Mag_XY-axis_Operating_Mode + * @{ + */ +#define LSM303C_MAG_OM_XY_LOWPOWER ((uint8_t) 0x00 << 5) +#define LSM303C_MAG_OM_XY_MEDIUM ((uint8_t) 0x01 << 5) +#define LSM303C_MAG_OM_XY_HIGH ((uint8_t) 0x02 << 5) +#define LSM303C_MAG_OM_XY_ULTRAHIGH ((uint8_t) 0x03 << 5) + + /** + * @} + */ + + +/** @defgroup Mag_Data_Rate + * @{ + */ +#define LSM303C_MAG_ODR_0_625_HZ ((uint8_t) 0x00 << 2) /*!< Output Data Rate = 0.625 Hz */ +#define LSM303C_MAG_ODR_1_25_HZ ((uint8_t) 0x01 << 2) /*!< Output Data Rate = 1.25 Hz */ +#define LSM303C_MAG_ODR_2_5_HZ ((uint8_t) 0x02 << 2) /*!< Output Data Rate = 2.5 Hz */ +#define LSM303C_MAG_ODR_5_0_HZ ((uint8_t) 0x03 << 2) /*!< Output Data Rate = 5.0 Hz */ +#define LSM303C_MAG_ODR_10_HZ ((uint8_t) 0x04 << 2) /*!< Output Data Rate = 10 Hz */ +#define LSM303C_MAG_ODR_20_HZ ((uint8_t) 0x05 << 2) /*!< Output Data Rate = 20 Hz */ +#define LSM303C_MAG_ODR_40_HZ ((uint8_t) 0x06 << 2) /*!< Output Data Rate = 40 Hz */ +#define LSM303C_MAG_ODR_80_HZ ((uint8_t) 0x07 << 2) /*!< Output Data Rate = 80 Hz */ +/** + * @} + */ + +/** @defgroup Mag_Data_Rate + * @{ + */ +#define LMS303C_MAG_SELFTEST_DISABLE ((uint8_t 0x00) +#define LMS303C_MAG_SELFTEST_ENABLE ((uint8_t 0x01) + +/** @defgroup Mag_Full_Scale + * @{ + */ +#define LSM303C_MAG_FS_DEFAULT ((uint8_t) 0x00 << 5) +#define LSM303C_MAG_FS_16_GA ((uint8_t) 0x03 << 5) /*!< Full scale = ±16 Gauss */ +/** + * @} + */ + +/** @defgroup Mag_Reboot + * @{ + */ +#define LSM303C_MAG_REBOOT_DEFAULT ((uint8_t) 0x00 << 3) +#define LSM303C_MAG_REBOOT_ENABLE ((uint8_t) 0x01 << 3) +/** + * @} + */ + +/** @defgroup Mag_Soft_reset + * @{ + */ +#define LSM303C_MAG_SOFT_RESET_DEFAULT ((uint8_t) 0x00 << 2) +#define LSM303C_MAG_SOFT_RESET_ENABLE ((uint8_t) 0x01 << 2) +/** + * @} + */ + +/** @defgroup Mag_Communication_Mode + * @{ + */ +#define LSM303C_MAG_I2C_MODE ((uint8_t) 0x80) +#define LSM303C_MAG_SPI_MODE ((uint8_t) 0x04) +/** + * @} + */ + +/** @defgroup Mag_Lowpower_mode_config + * @{ + */ +#define LSM303C_MAG_CONFIG_NORMAL_MODE ((uint8_t) 0x00) +#define LSM303C_MAG_CONFIG_LOWPOWER_MODE ((uint8_t) 0x20) +/** + * @} + */ + +/** @defgroup Mag_Operation_Mode + * @{ + */ +#define LSM303C_MAG_SELECTION_MODE ((uint8_t) 0x03) +#define LSM303C_MAG_CONTINUOUS_MODE ((uint8_t) 0x00) +#define LSM303C_MAG_SINGLE_MODE ((uint8_t) 0x01) +#define LSM303C_MAG_POWERDOWN1_MODE ((uint8_t) 0x02) +#define LSM303C_MAG_POWERDOWN2_MODE ((uint8_t) 0x03) + +/** + * @} + */ + +/** @defgroup Mag_Z-axis_Operation_Mode + * @{ + */ +#define LSM303C_MAG_OM_Z_LOWPOWER ((uint8_t) 0x00 << 2) +#define LSM303C_MAG_OM_Z_MEDIUM ((uint8_t) 0x01 << 2) +#define LSM303C_MAG_OM_Z_HIGH ((uint8_t) 0x02 << 2) +#define LSM303C_MAG_OM_Z_ULTRAHIGH ((uint8_t) 0x03 << 2) + +/** + * @} + */ + +/** @defgroup Mag_Big_little-endian_selection + * @{ + */ +#define LSM303C_MAG_BLE_LSB ((uint8_t) 0x00) +#define LSM303C_MAG_BLE_MSB ((uint8_t) 0x02) +/** + * @} + */ + +/** @defgroup Mag_Bloc_update_magnetic_data + * @{ + */ +#define LSM303C_MAG_BDU_CONTINUOUS ((uint8_t) 0x00) +#define LSM303C_MAG_BDU_MSBLSB ((uint8_t) 0x40) +/** + * @} + */ + +/** + * @defgroup Magnetometer_Sensitivity + * @{ + */ +#define LSM303C_M_SENSITIVITY_XY_1_3Ga 1100 /*!< magnetometer X Y axes sensitivity for 1.3 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_XY_1_9Ga 855 /*!< magnetometer X Y axes sensitivity for 1.9 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_XY_2_5Ga 670 /*!< magnetometer X Y axes sensitivity for 2.5 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_XY_4Ga 450 /*!< magnetometer X Y axes sensitivity for 4 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_XY_4_7Ga 400 /*!< magnetometer X Y axes sensitivity for 4.7 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_XY_5_6Ga 330 /*!< magnetometer X Y axes sensitivity for 5.6 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_XY_8_1Ga 230 /*!< magnetometer X Y axes sensitivity for 8.1 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_Z_1_3Ga 980 /*!< magnetometer Z axis sensitivity for 1.3 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_Z_1_9Ga 760 /*!< magnetometer Z axis sensitivity for 1.9 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_Z_2_5Ga 600 /*!< magnetometer Z axis sensitivity for 2.5 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_Z_4Ga 400 /*!< magnetometer Z axis sensitivity for 4 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_Z_4_7Ga 355 /*!< magnetometer Z axis sensitivity for 4.7 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_Z_5_6Ga 295 /*!< magnetometer Z axis sensitivity for 5.6 Ga full scale [LSB/Ga] */ +#define LSM303C_M_SENSITIVITY_Z_8_1Ga 205 /*!< magnetometer Z axis sensitivity for 8.1 Ga full scale [LSB/Ga] */ +/** + * @} + */ + +/** @defgroup Mag_Working_Mode + * @{ + */ +#define LSM303C_CONTINUOUS_CONVERSION ((uint8_t) 0x00) /*!< Continuous-Conversion Mode */ +#define LSM303C_SINGLE_CONVERSION ((uint8_t) 0x01) /*!< Single-Conversion Mode */ +#define LSM303C_SLEEP ((uint8_t) 0x02) /*!< Sleep Mode */ +/** + * @} + */ + + +/** @defgroup LSM303C_Exported_Functions + * @{ + */ + + +/* ACC driver structure */ +extern ACCELERO_DrvTypeDef Lsm303cDrv_accelero; +extern MAGNETO_DrvTypeDef Lsm303cDrv_magneto; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LSM303C_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/mfxstm32l152/mfxstm32l152.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,1585 @@ +/** + ****************************************************************************** + * @file mfxstm32l152.c + * @author MCD Application Team + * @version V2.0.0 + * @date 24-June-2015 + * @brief This file provides a set of functions needed to manage the MFXSTM32L152 + * IO Expander devices. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "mfxstm32l152.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @defgroup MFXSTM32L152 + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Private_Types_Definitions + * @{ + */ + +/* Private define ------------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Private_Defines + * @{ + */ +#define MFXSTM32L152_MAX_INSTANCE 3 + +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Private_Macros + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Private_Variables + * @{ + */ + +/* Touch screen driver structure initialization */ +TS_DrvTypeDef mfxstm32l152_ts_drv = +{ + mfxstm32l152_Init, + mfxstm32l152_ReadID, + mfxstm32l152_Reset, + + mfxstm32l152_TS_Start, + mfxstm32l152_TS_DetectTouch, + mfxstm32l152_TS_GetXY, + + mfxstm32l152_TS_EnableIT, + mfxstm32l152_TS_ClearIT, + mfxstm32l152_TS_ITStatus, + mfxstm32l152_TS_DisableIT, +}; + +/* IO driver structure initialization */ +IO_DrvTypeDef mfxstm32l152_io_drv = +{ + mfxstm32l152_Init, + mfxstm32l152_ReadID, + mfxstm32l152_Reset, + + mfxstm32l152_IO_Start, + mfxstm32l152_IO_Config, + mfxstm32l152_IO_WritePin, + mfxstm32l152_IO_ReadPin, + + mfxstm32l152_IO_EnableIT, + mfxstm32l152_IO_DisableIT, + mfxstm32l152_IO_ITStatus, + mfxstm32l152_IO_ClearIT, +}; + +/* IDD driver structure initialization */ +IDD_DrvTypeDef mfxstm32l152_idd_drv = +{ + mfxstm32l152_Init, + mfxstm32l152_DeInit, + mfxstm32l152_ReadID, + mfxstm32l152_Reset, + mfxstm32l152_LowPower, + mfxstm32l152_WakeUp, + + mfxstm32l152_IDD_Start, + mfxstm32l152_IDD_Config, + mfxstm32l152_IDD_GetValue, + + mfxstm32l152_IDD_EnableIT, + mfxstm32l152_IDD_ClearIT, + mfxstm32l152_IDD_GetITStatus, + mfxstm32l152_IDD_DisableIT, + + mfxstm32l152_Error_EnableIT, + mfxstm32l152_Error_ClearIT, + mfxstm32l152_Error_GetITStatus, + mfxstm32l152_Error_DisableIT, + mfxstm32l152_Error_ReadSrc, + mfxstm32l152_Error_ReadMsg +}; + + +/* mfxstm32l152 instances by address */ +uint8_t mfxstm32l152[MFXSTM32L152_MAX_INSTANCE] = {0}; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Private_Function_Prototypes + * @{ + */ +static uint8_t mfxstm32l152_GetInstance(uint16_t DeviceAddr); +static uint8_t mfxstm32l152_ReleaseInstance(uint16_t DeviceAddr); +static void mfxstm32l152_reg24_setPinValue(uint16_t DeviceAddr, uint8_t RegisterAddr, uint32_t PinPosition, uint8_t PinValue ); + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Private_Functions + * @{ + */ + +/** + * @brief Initialize the mfxstm32l152 and configure the needed hardware resources + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_Init(uint16_t DeviceAddr) +{ + uint8_t instance; + uint8_t empty; + + /* Check if device instance already exists */ + instance = mfxstm32l152_GetInstance(DeviceAddr); + + /* To prevent double initialization */ + if(instance == 0xFF) + { + /* Look for empty instance */ + empty = mfxstm32l152_GetInstance(0); + + if(empty < MFXSTM32L152_MAX_INSTANCE) + { + /* Register the current device instance */ + mfxstm32l152[empty] = DeviceAddr; + + /* Initialize IO BUS layer */ + MFX_IO_Init(); + } + } + + mfxstm32l152_SetIrqOutPinPolarity(DeviceAddr, MFXSTM32L152_OUT_PIN_POLARITY_HIGH); + mfxstm32l152_SetIrqOutPinType(DeviceAddr, MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL); +} + +/** + * @brief DeInitialize the mfxstm32l152 and unconfigure the needed hardware resources + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_DeInit(uint16_t DeviceAddr) +{ + uint8_t instance; + + /* release existing instance */ + instance = mfxstm32l152_ReleaseInstance(DeviceAddr); + + /* De-Init only if instance was previously registered */ + if(instance != 0xFF) + { + /* De-Initialize IO BUS layer */ + MFX_IO_DeInit(); + } +} + +/** + * @brief Reset the mfxstm32l152 by Software. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_Reset(uint16_t DeviceAddr) +{ + /* Soft Reset */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, MFXSTM32L152_SWRST); + + /* Wait for a delay to ensure registers erasing */ + MFX_IO_Delay(10); +} + +/** + * @brief Put mfxstm32l152 Device in Low Power standby mode + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_LowPower(uint16_t DeviceAddr) +{ + /* Enter standby mode */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, MFXSTM32L152_STANDBY); + + /* enable wakeup pin */ + MFX_IO_EnableWakeupPin(); +} + +/** + * @brief WakeUp mfxstm32l152 from standby mode + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_WakeUp(uint16_t DeviceAddr) +{ + uint8_t instance; + + /* Check if device instance already exists */ + instance = mfxstm32l152_GetInstance(DeviceAddr); + + /* if instance does not exist, first initialize pins*/ + if(instance == 0xFF) + { + /* enable wakeup pin */ + MFX_IO_EnableWakeupPin(); + } + + /* toggle wakeup pin */ + MFX_IO_Wakeup(); +} + +/** + * @brief Read the MFXSTM32L152 IO Expander device ID. + * @param DeviceAddr: Device address on communication Bus. + * @retval The Device ID (two bytes). + */ +uint16_t mfxstm32l152_ReadID(uint16_t DeviceAddr) +{ + uint8_t id; + + /* Wait for a delay to ensure the state of registers */ + MFX_IO_Delay(1); + + /* Initialize IO BUS layer */ + MFX_IO_Init(); + + id = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_ID); + + /* Return the device ID value */ + return (id); +} + +/** + * @brief Read the MFXSTM32L152 device firmware version. + * @param DeviceAddr: Device address on communication Bus. + * @retval The Device FW version (two bytes). + */ +uint16_t mfxstm32l152_ReadFwVersion(uint16_t DeviceAddr) +{ + uint8_t data[2]; + + MFX_IO_ReadMultiple((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_FW_VERSION_MSB, data, sizeof(data)) ; + + /* Recompose MFX firmware value */ + return ((data[0] << 8) | data[1]); +} + +/** + * @brief Enable the interrupt mode for the selected IT source + * @param DeviceAddr: Device address on communication Bus. + * @param Source: The interrupt source to be configured, could be: + * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt + * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt + * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt + * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt + * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty + * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered + * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full + * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow + * @retval None + */ +void mfxstm32l152_EnableITSource(uint16_t DeviceAddr, uint8_t Source) +{ + uint8_t tmp = 0; + + /* Get the current value of the INT_EN register */ + tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN); + + /* Set the interrupts to be Enabled */ + tmp |= Source; + + /* Set the register */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN, tmp); +} + +/** + * @brief Disable the interrupt mode for the selected IT source + * @param DeviceAddr: Device address on communication Bus. + * @param Source: The interrupt source to be configured, could be: + * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt + * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt + * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt + * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt + * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty + * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered + * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full + * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow + * @retval None + */ +void mfxstm32l152_DisableITSource(uint16_t DeviceAddr, uint8_t Source) +{ + uint8_t tmp = 0; + + /* Get the current value of the INT_EN register */ + tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN); + + /* Set the interrupts to be Enabled */ + tmp &= ~Source; + + /* Set the register */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN, tmp); +} + + +/** + * @brief Returns the selected Global interrupt source pending bit value + * @param DeviceAddr: Device address on communication Bus. + * @param Source: the Global interrupt source to be checked, could be: + * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt + * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt + * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt + * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt + * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty + * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered + * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full + * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow + * @retval The value of the checked Global interrupt source status. + */ +uint8_t mfxstm32l152_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source) +{ + /* Return the global IT source status (pending or not)*/ + return((MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_PENDING) & Source)); +} + +/** + * @brief Clear the selected Global interrupt pending bit(s) + * @param DeviceAddr: Device address on communication Bus. + * @param Source: the Global interrupt source to be cleared, could be any combination + * of the below values. The acknowledge signal for MFXSTM32L152_GPIOs configured in input + * with interrupt is not on this register but in IRQ_GPI_ACK1, IRQ_GPI_ACK2 registers. + * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt + * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt + * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt + * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty + * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered + * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full + * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow + * /\/\ IMPORTANT NOTE /\/\ must not use MFXSTM32L152_IRQ_GPIO as argument, see IRQ_GPI_ACK1 and IRQ_GPI_ACK2 registers + * @retval None + */ +void mfxstm32l152_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source) +{ + /* Write 1 to the bits that have to be cleared */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_ACK, Source); +} + +/** + * @brief Set the global interrupt Polarity of IRQ_OUT_PIN. + * @param DeviceAddr: Device address on communication Bus. + * @param Polarity: the IT mode polarity, could be one of the following values: + * @arg MFXSTM32L152_OUT_PIN_POLARITY_LOW: Interrupt output line is active Low edge + * @arg MFXSTM32L152_OUT_PIN_POLARITY_HIGH: Interrupt line output is active High edge + * @retval None + */ +void mfxstm32l152_SetIrqOutPinPolarity(uint16_t DeviceAddr, uint8_t Polarity) +{ + uint8_t tmp = 0; + + /* Get the current register value */ + tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT); + + /* Mask the polarity bits */ + tmp &= ~(uint8_t)0x02; + + /* Modify the Interrupt Output line configuration */ + tmp |= Polarity; + + /* Set the new register value */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT, tmp); + + /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */ + MFX_IO_Delay(1); + +} + +/** + * @brief Set the global interrupt Type of IRQ_OUT_PIN. + * @param DeviceAddr: Device address on communication Bus. + * @param Type: Interrupt line activity type, could be one of the following values: + * @arg MFXSTM32L152_OUT_PIN_TYPE_OPENDRAIN: Open Drain output Interrupt line + * @arg MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL: Push Pull output Interrupt line + * @retval None + */ +void mfxstm32l152_SetIrqOutPinType(uint16_t DeviceAddr, uint8_t Type) +{ + uint8_t tmp = 0; + + /* Get the current register value */ + tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT); + + /* Mask the type bits */ + tmp &= ~(uint8_t)0x01; + + /* Modify the Interrupt Output line configuration */ + tmp |= Type; + + /* Set the new register value */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT, tmp); + + /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */ + MFX_IO_Delay(1); + +} + + +/* ------------------------------------------------------------------ */ +/* ----------------------- GPIO ------------------------------------- */ +/* ------------------------------------------------------------------ */ + + +/** + * @brief Start the IO functionality used and enable the AF for selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param AF_en: 0 to disable, else enabled. + * @retval None + */ +void mfxstm32l152_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t mode; + + /* Get the current register value */ + mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL); + + /* Set the IO Functionalities to be Enabled */ + mode |= MFXSTM32L152_GPIO_EN; + + /* Enable ALTERNATE functions */ + /* AGPIO[0..3] can be either IDD or GPIO */ + /* AGPIO[4..7] can be either TS or GPIO */ + /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */ + /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */ + /* so if IDD and TS are both active it is better to let ALTERNATE off (0) */ + /* if however IDD or TS are not connected then set it on gives more GPIOs availability */ + /* remind that AGPIO are less efficient then normal GPIO (They use pooling rather then EXTI */ + if (IO_Pin > 0xFFFF) + { + mode |= MFXSTM32L152_ALTERNATE_GPIO_EN; + } + else + { + mode &= ~MFXSTM32L152_ALTERNATE_GPIO_EN; + } + + /* Write the new register value */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode); + + /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */ + MFX_IO_Delay(1); +} + +/** + * @brief Configures the IO pin(s) according to IO mode structure value. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The output pin to be set or reset. This parameter can be one + * of the following values: + * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23. + * @param IO_Mode: The IO pin mode to configure, could be one of the following values: + * @arg IO_MODE_INPUT + * @arg IO_MODE_OUTPUT + * @arg IO_MODE_IT_RISING_EDGE + * @arg IO_MODE_IT_FALLING_EDGE + * @arg IO_MODE_IT_LOW_LEVEL + * @arg IO_MODE_IT_HIGH_LEVEL + * @arg IO_MODE_INPUT_PU, + * @arg IO_MODE_INPUT_PD, + * @arg IO_MODE_OUTPUT_OD_PU, + * @arg IO_MODE_OUTPUT_OD_PD, + * @arg IO_MODE_OUTPUT_PP_PU, + * @arg IO_MODE_OUTPUT_PP_PD, + * @arg IO_MODE_IT_RISING_EDGE_PU + * @arg IO_MODE_IT_FALLING_EDGE_PU + * @arg IO_MODE_IT_LOW_LEVEL_PU + * @arg IO_MODE_IT_HIGH_LEVEL_PU + * @arg IO_MODE_IT_RISING_EDGE_PD + * @arg IO_MODE_IT_FALLING_EDGE_PD + * @arg IO_MODE_IT_LOW_LEVEL_PD + * @arg IO_MODE_IT_HIGH_LEVEL_PD + * @retval None + */ +uint8_t mfxstm32l152_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode) +{ + uint8_t error_code = 0; + + /* Configure IO pin according to selected IO mode */ + switch(IO_Mode) + { + case IO_MODE_OFF: /* Off or analog mode */ + case IO_MODE_ANALOG: /* Off or analog mode */ + mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */ + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN); + break; + + case IO_MODE_INPUT: /* Input mode */ + mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */ + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + break; + + case IO_MODE_INPUT_PU: /* Input mode */ + mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */ + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + break; + + case IO_MODE_INPUT_PD: /* Input mode */ + mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */ + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN); + break; + + case IO_MODE_OUTPUT: /* Output mode */ + case IO_MODE_OUTPUT_PP_PD: /* Output mode */ + mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */ + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_PUSH_PULL); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN); + break; + + case IO_MODE_OUTPUT_PP_PU: /* Output mode */ + mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */ + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_PUSH_PULL); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + break; + + case IO_MODE_OUTPUT_OD_PD: /* Output mode */ + mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */ + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_OPEN_DRAIN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN); + break; + + case IO_MODE_OUTPUT_OD_PU: /* Output mode */ + mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */ + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_OPEN_DRAIN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + break; + + case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_RISING_EDGE_PU: /* Interrupt rising edge mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_RISING_EDGE_PD: /* Interrupt rising edge mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_FALLING_EDGE_PU: /* Interrupt falling edge mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_FALLING_EDGE_PD: /* Interrupt falling edge mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_LOW_LEVEL: /* Low level interrupt mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_LOW_LEVEL_PU: /* Low level interrupt mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_LOW_LEVEL_PD: /* Low level interrupt mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_HIGH_LEVEL: /* High level interrupt mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_HIGH_LEVEL_PU: /* High level interrupt mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + case IO_MODE_IT_HIGH_LEVEL_PD: /* High level interrupt mode */ + mfxstm32l152_IO_EnableIT(DeviceAddr); + mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR); + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN); + mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL); + mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE); + mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */ + break; + + default: + error_code = (uint8_t) IO_Mode; + break; + } + + return error_code; +} + +/** + * @brief Initialize the selected IO pin direction. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO pin to be configured. This parameter could be any + * combination of the following values: + * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23. + * @param Direction: could be MFXSTM32L152_GPIO_DIR_IN or MFXSTM32L152_GPIO_DIR_OUT. + * @retval None + */ +void mfxstm32l152_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction) +{ + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_DIR1, IO_Pin, Direction); +} + +/** + * @brief Set the global interrupt Type. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO pin to be configured. This parameter could be any + * combination of the following values: + * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23. + * @param Evt: Interrupt line activity type, could be one of the following values: + * @arg MFXSTM32L152_IRQ_GPI_EVT_LEVEL: Interrupt line is active in level model + * @arg MFXSTM32L152_IRQ_GPI_EVT_EDGE: Interrupt line is active in edge model + * @retval None + */ +void mfxstm32l152_IO_SetIrqEvtMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Evt) +{ + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_EVT1, IO_Pin, Evt); + MFX_IO_Delay(1); +} + +/** + * @brief Configure the Edge for which a transition is detectable for the + * selected pin. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO pin to be configured. This parameter could be any + * combination of the following values: + * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23. + * @param Evt: Interrupt line activity type, could be one of the following values: + * @arg MFXSTM32L152_IRQ_GPI_TYPE_LLFE: Interrupt line is active in Low Level or Falling Edge + * @arg MFXSTM32L152_IRQ_GPI_TYPE_HLRE: Interrupt line is active in High Level or Rising Edge + * @retval None + */ +void mfxstm32l152_IO_SetIrqTypeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Type) +{ + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE1, IO_Pin, Type); + MFX_IO_Delay(1); +} + +/** + * @brief When GPIO is in output mode, puts the corresponding GPO in High (1) or Low (0) level. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The output pin to be set or reset. This parameter can be one + * of the following values: + * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23. + * @param PinState: The new IO pin state. + * @retval None + */ +void mfxstm32l152_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState) +{ + /* Apply the bit value to the selected pin */ + if (PinState != 0) + { + /* Set the SET register */ + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPO_SET1, IO_Pin, 1); + } + else + { + /* Set the CLEAR register */ + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPO_CLR1, IO_Pin, 1); + } +} + +/** + * @brief Return the state of the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The output pin to be set or reset. This parameter can be one + * of the following values: + * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23. + * @retval IO pin(s) state. + */ +uint32_t mfxstm32l152_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmp1; + uint16_t tmp2; + uint32_t tmp3; + + tmp1 = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE1); + tmp2 = (uint16_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE2); + tmp3 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE3); + tmp3 = tmp1 + (tmp2 << 8) + (tmp3 << 16); + + return(tmp3 & IO_Pin); +} + +/** + * @brief Enable the global IO interrupt source. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_IO_EnableIT(uint16_t DeviceAddr) +{ + MFX_IO_ITConfig(); + + /* Enable global IO IT source */ + mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_GPIO); +} + +/** + * @brief Disable the global IO interrupt source. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_IO_DisableIT(uint16_t DeviceAddr) +{ + /* Disable global IO IT source */ + mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_GPIO); +} + +/** + * @brief Enable interrupt mode for the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO interrupt to be enabled. This parameter could be any + * combination of the following values: + * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23. + * @retval None + */ +void mfxstm32l152_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1, IO_Pin, 1); +} + +/** + * @brief Disable interrupt mode for the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO interrupt to be disabled. This parameter could be any + * combination of the following values: + * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23. + * @retval None + */ +void mfxstm32l152_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1, IO_Pin, 0); +} + + +/** + * @brief Check the status of the selected IO interrupt pending bit + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO interrupt to be checked could be: + * @arg MFXSTM32L152_GPIO_PIN_x Where x can be from 0 to 23. + * @retval Status of the checked IO pin(s). + */ +uint32_t mfxstm32l152_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + /* Get the Interrupt status */ + uint8_t tmp1; + uint16_t tmp2; + uint32_t tmp3; + + tmp1 = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING1); + tmp2 = (uint16_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING2); + tmp3 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING3); + tmp3 = tmp1 + (tmp2 << 8) + (tmp3 << 16); + + return(tmp3 & IO_Pin); +} + +/** + * @brief Clear the selected IO interrupt pending bit(s). It clear automatically also the general MFXSTM32L152_REG_ADR_IRQ_PENDING + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: the IO interrupt to be cleared, could be: + * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23. + * @retval None + */ +void mfxstm32l152_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + /* Clear the IO IT pending bit(s) by acknowledging */ + /* it cleans automatically also the Global IRQ_GPIO */ + /* normally this function is called under interrupt */ + uint8_t pin_0_7, pin_8_15, pin_16_23; + + pin_0_7 = IO_Pin & 0x0000ff; + pin_8_15 = IO_Pin >> 8; + pin_8_15 = pin_8_15 & 0x00ff; + pin_16_23 = IO_Pin >> 16; + + if (pin_0_7) + { + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK1, pin_0_7); + } + if (pin_8_15) + { + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK2, pin_8_15); + } + if (pin_16_23) + { + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK3, pin_16_23); + } +} + + +/** + * @brief Enable the AF for aGPIO. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_IO_EnableAF(uint16_t DeviceAddr) +{ + uint8_t mode; + + /* Get the current register value */ + mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL); + + /* Enable ALTERNATE functions */ + /* AGPIO[0..3] can be either IDD or GPIO */ + /* AGPIO[4..7] can be either TS or GPIO */ + /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */ + /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */ + /* so if IDD and TS are both active it is better to let ALTERNATE disabled (0) */ + /* if however IDD or TS are not connected then set it on gives more GPIOs availability */ + /* remind that AGPIO are less efficient then normal GPIO (they use pooling rather then EXTI) */ + mode |= MFXSTM32L152_ALTERNATE_GPIO_EN; + + /* Write the new register value */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode); +} + +/** + * @brief Disable the AF for aGPIO. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ + void mfxstm32l152_IO_DisableAF(uint16_t DeviceAddr) +{ + uint8_t mode; + + /* Get the current register value */ + mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL); + + /* Enable ALTERNATE functions */ + /* AGPIO[0..3] can be either IDD or GPIO */ + /* AGPIO[4..7] can be either TS or GPIO */ + /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */ + /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */ + /* so if IDD and TS are both active it is better to let ALTERNATE disabled (0) */ + /* if however IDD or TS are not connected then set it on gives more GPIOs availability */ + /* remind that AGPIO are less efficient then normal GPIO (they use pooling rather then EXTI) */ + mode &= ~MFXSTM32L152_ALTERNATE_GPIO_EN; + + /* Write the new register value */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode); + +} + + +/* ------------------------------------------------------------------ */ +/* --------------------- TOUCH SCREEN ------------------------------- */ +/* ------------------------------------------------------------------ */ + +/** + * @brief Configures the touch Screen Controller (Single point detection) + * @param DeviceAddr: Device address on communication Bus. + * @retval None. + */ +void mfxstm32l152_TS_Start(uint16_t DeviceAddr) +{ + uint8_t mode; + + /* Get the current register value */ + mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL); + + /* Set the Functionalities to be Enabled */ + mode |= MFXSTM32L152_TS_EN; + + /* Set the new register value */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode); + + /* Wait for 2 ms */ + MFX_IO_Delay(2); + + /* Select 2 nF filter capacitor */ + /* Configuration: + - Touch average control : 4 samples + - Touch delay time : 500 uS + - Panel driver setting time: 500 uS + */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_SETTLING, 0x32); + MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_TOUCH_DET_DELAY, 0x5); + MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_AVE, 0x04); + + /* Configure the Touch FIFO threshold: single point reading */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, 0x01); + + /* Clear the FIFO memory content. */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, MFXSTM32L152_TS_CLEAR_FIFO); + + /* Touch screen control configuration : + - No window tracking index + */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_TRACK, 0x00); + + + /* Clear all the IT status pending bits if any */ + mfxstm32l152_IO_ClearIT(DeviceAddr, 0xFFFFFF); + + /* Wait for 1 ms delay */ + MFX_IO_Delay(1); +} + +/** + * @brief Return if there is touch detected or not. + * @param DeviceAddr: Device address on communication Bus. + * @retval Touch detected state. + */ +uint8_t mfxstm32l152_TS_DetectTouch(uint16_t DeviceAddr) +{ + uint8_t state; + uint8_t ret = 0; + + state = MFX_IO_Read(DeviceAddr, MFXSTM32L152_TS_FIFO_STA); + state = ((state & (uint8_t)MFXSTM32L152_TS_CTRL_STATUS) == (uint8_t)MFXSTM32L152_TS_CTRL_STATUS); + + if(state > 0) + { + if(MFX_IO_Read(DeviceAddr, MFXSTM32L152_TS_FIFO_LEVEL) > 0) + { + ret = 1; + } + } + + return ret; +} + +/** + * @brief Get the touch screen X and Y positions values + * @param DeviceAddr: Device address on communication Bus. + * @param X: Pointer to X position value + * @param Y: Pointer to Y position value + * @retval None. + */ +void mfxstm32l152_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y) +{ + uint8_t data_xy[3]; + + MFX_IO_ReadMultiple(DeviceAddr, MFXSTM32L152_TS_XY_DATA, data_xy, sizeof(data_xy)) ; + + /* Calculate positions values */ + *X = (data_xy[1]<<4) + (data_xy[0]>>4); + *Y = (data_xy[2]<<4) + (data_xy[0]&4); + + /* Reset the FIFO memory content. */ + MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, MFXSTM32L152_TS_CLEAR_FIFO); +} + +/** + * @brief Configure the selected source to generate a global interrupt or not + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_TS_EnableIT(uint16_t DeviceAddr) +{ + MFX_IO_ITConfig(); + + /* Enable global TS IT source */ + mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_TS_DET); +} + +/** + * @brief Configure the selected source to generate a global interrupt or not + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_TS_DisableIT(uint16_t DeviceAddr) +{ + /* Disable global TS IT source */ + mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_TS_DET); +} + +/** + * @brief Configure the selected source to generate a global interrupt or not + * @param DeviceAddr: Device address on communication Bus. + * @retval TS interrupts status + */ +uint8_t mfxstm32l152_TS_ITStatus(uint16_t DeviceAddr) +{ + /* Return TS interrupts status */ + return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_TS)); +} + +/** + * @brief Configure the selected source to generate a global interrupt or not + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_TS_ClearIT(uint16_t DeviceAddr) +{ + /* Clear the global TS IT source */ + mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_TS); +} + +/* ------------------------------------------------------------------ */ +/* --------------------- IDD MEASUREMENT ---------------------------- */ +/* ------------------------------------------------------------------ */ + +/** + * @brief Launch IDD current measurement + * @param DeviceAddr: Device address on communication Bus + * @retval None. + */ +void mfxstm32l152_IDD_Start(uint16_t DeviceAddr) +{ + uint8_t mode = 0; + + /* Get the current register value */ + mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL); + + /* Set the Functionalities to be enabled */ + mode |= MFXSTM32L152_IDD_CTRL_REQ; + + /* Start measurement campaign */ + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode); +} + +/** + * @brief Configures the IDD current measurement + * @param DeviceAddr: Device address on communication Bus. + * @param MfxIddConfig: Parameters depending on hardware config. + * @retval None + */ +void mfxstm32l152_IDD_Config(uint16_t DeviceAddr, IDD_ConfigTypeDef MfxIddConfig) +{ + uint8_t value = 0; + uint8_t mode = 0; + + /* Get the current register value */ + mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL); + + if((mode & MFXSTM32L152_IDD_EN) != MFXSTM32L152_IDD_EN) + { + /* Set the Functionalities to be enabled */ + mode |= MFXSTM32L152_IDD_EN; + + /* Set the new register value */ + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode); + } + + /* Control register setting: number of shunts */ + value = ((MfxIddConfig.ShuntNbUsed << 1) & MFXSTM32L152_IDD_CTRL_SHUNT_NB); + value |= (MfxIddConfig.VrefMeasurement & MFXSTM32L152_IDD_CTRL_VREF_DIS); + value |= (MfxIddConfig.Calibration & MFXSTM32L152_IDD_CTRL_CAL_DIS); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, value); + + /* Idd pre delay configuration: unit and value*/ + value = (MfxIddConfig.PreDelayUnit & MFXSTM32L152_IDD_PREDELAY_UNIT) | + (MfxIddConfig.PreDelayValue & MFXSTM32L152_IDD_PREDELAY_VALUE); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_PRE_DELAY, value); + + /* Shunt 0 register value: MSB then LSB */ + value = (uint8_t) (MfxIddConfig.Shunt0Value >> 8); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT0_MSB, value); + value = (uint8_t) (MfxIddConfig.Shunt0Value); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT0_LSB, value); + + /* Shunt 1 register value: MSB then LSB */ + value = (uint8_t) (MfxIddConfig.Shunt1Value >> 8); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT1_MSB, value); + value = (uint8_t) (MfxIddConfig.Shunt1Value); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT1_LSB, value); + + /* Shunt 2 register value: MSB then LSB */ + value = (uint8_t) (MfxIddConfig.Shunt2Value >> 8); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT2_MSB, value); + value = (uint8_t) (MfxIddConfig.Shunt2Value); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT2_LSB, value); + + /* Shunt 3 register value: MSB then LSB */ + value = (uint8_t) (MfxIddConfig.Shunt3Value >> 8); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT3_MSB, value); + value = (uint8_t) (MfxIddConfig.Shunt3Value); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT3_LSB, value); + + /* Shunt 4 register value: MSB then LSB */ + value = (uint8_t) (MfxIddConfig.Shunt4Value >> 8); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT4_MSB, value); + value = (uint8_t) (MfxIddConfig.Shunt4Value); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT4_LSB, value); + + /* Shunt 0 stabilization delay */ + value = MfxIddConfig.Shunt0StabDelay; + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH0_STABILIZATION, value); + + /* Shunt 1 stabilization delay */ + value = MfxIddConfig.Shunt1StabDelay; + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH1_STABILIZATION, value); + + /* Shunt 2 stabilization delay */ + value = MfxIddConfig.Shunt2StabDelay; + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH2_STABILIZATION, value); + + /* Shunt 3 stabilization delay */ + value = MfxIddConfig.Shunt3StabDelay; + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH3_STABILIZATION, value); + + /* Shunt 4 stabilization delay */ + value = MfxIddConfig.Shunt4StabDelay; + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH4_STABILIZATION, value); + + /* Idd ampli gain value: MSB then LSB */ + value = (uint8_t) (MfxIddConfig.AmpliGain >> 8); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_GAIN_MSB, value); + value = (uint8_t) (MfxIddConfig.AmpliGain); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_GAIN_LSB, value); + + /* Idd VDD min value: MSB then LSB */ + value = (uint8_t) (MfxIddConfig.VddMin >> 8); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VDD_MIN_MSB, value); + value = (uint8_t) (MfxIddConfig.VddMin); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VDD_MIN_LSB, value); + + /* Idd number of measurements */ + value = MfxIddConfig.MeasureNb; + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_NBR_OF_MEAS, value); + + /* Idd delta delay configuration: unit and value */ + value = (MfxIddConfig.DeltaDelayUnit & MFXSTM32L152_IDD_DELTADELAY_UNIT) | + (MfxIddConfig.DeltaDelayValue & MFXSTM32L152_IDD_DELTADELAY_VALUE); + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_MEAS_DELTA_DELAY, value); + + /* Idd number of shut on board */ + value = MfxIddConfig.ShuntNbOnBoard; + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNTS_ON_BOARD, value); +} + +/** + * @brief This function allows to modify number of shunt used for a measurement + * @param DeviceAddr: Device address on communication Bus + * @retval None. + */ +void mfxstm32l152_IDD_ConfigShuntNbLimit(uint16_t DeviceAddr, uint8_t ShuntNbLimit) +{ + uint8_t mode = 0; + + /* Get the current register value */ + mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL); + + /* Clear number of shunt limit */ + mode &= ~(MFXSTM32L152_IDD_CTRL_SHUNT_NB); + + /* Clear number of shunt limit */ + mode |= ((ShuntNbLimit << 1) & MFXSTM32L152_IDD_CTRL_SHUNT_NB); + + /* Write noewx desired limit */ + MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode); +} + +/** + * @brief Get Idd current value + * @param DeviceAddr: Device address on communication Bus + * @param ReadValue: Pointer on value to be read + * @retval Idd value in 10 nA. + */ +void mfxstm32l152_IDD_GetValue(uint16_t DeviceAddr, uint32_t *ReadValue) +{ + uint8_t data[3]; + + MFX_IO_ReadMultiple((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VALUE_MSB, data, sizeof(data)) ; + + /* Recompose Idd current value */ + *ReadValue = (data[0] << 16) | (data[1] << 8) | data[2]; + +} + +/** + * @brief Get Last shunt used for measurement + * @param DeviceAddr: Device address on communication Bus + * @retval Last shunt used + */ +uint8_t mfxstm32l152_IDD_GetShuntUsed(uint16_t DeviceAddr) +{ + return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT_USED)); +} + +/** + * @brief Configure mfx to enable Idd interrupt + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_IDD_EnableIT(uint16_t DeviceAddr) +{ + MFX_IO_ITConfig(); + + /* Enable global IDD interrupt source */ + mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_IDD); +} + +/** + * @brief Clear Idd global interrupt + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_IDD_ClearIT(uint16_t DeviceAddr) +{ + /* Clear the global IDD interrupt source */ + mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_IDD); +} + +/** + * @brief get Idd interrupt status + * @param DeviceAddr: Device address on communication Bus. + * @retval IDD interrupts status + */ +uint8_t mfxstm32l152_IDD_GetITStatus(uint16_t DeviceAddr) +{ + /* Return IDD interrupt status */ + return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_IDD)); +} + +/** + * @brief disable Idd interrupt + * @param DeviceAddr: Device address on communication Bus. + * @retval None. + */ +void mfxstm32l152_IDD_DisableIT(uint16_t DeviceAddr) +{ + /* Disable global IDD interrupt source */ + mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_IDD); +} + + +/* ------------------------------------------------------------------ */ +/* --------------------- ERROR MANAGEMENT --------------------------- */ +/* ------------------------------------------------------------------ */ + +/** + * @brief Read Error Source. + * @param DeviceAddr: Device address on communication Bus. + * @retval Error message code with error source + */ +uint8_t mfxstm32l152_Error_ReadSrc(uint16_t DeviceAddr) +{ + /* Get the current source register value */ + return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_ERROR_SRC)); +} + +/** + * @brief Read Error Message + * @param DeviceAddr: Device address on communication Bus. + * @retval Error message code with error source + */ +uint8_t mfxstm32l152_Error_ReadMsg(uint16_t DeviceAddr) +{ + /* Get the current message register value */ + return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_ERROR_MSG)); +} + +/** + * @brief Enable Error global interrupt + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ + +void mfxstm32l152_Error_EnableIT(uint16_t DeviceAddr) +{ + MFX_IO_ITConfig(); + + /* Enable global Error interrupt source */ + mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_ERROR); +} + +/** + * @brief Clear Error global interrupt + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void mfxstm32l152_Error_ClearIT(uint16_t DeviceAddr) +{ + /* Clear the global Error interrupt source */ + mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_ERROR); +} + +/** + * @brief get Error interrupt status + * @param DeviceAddr: Device address on communication Bus. + * @retval Error interrupts status + */ +uint8_t mfxstm32l152_Error_GetITStatus(uint16_t DeviceAddr) +{ + /* Return Error interrupt status */ + return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_ERROR)); +} + +/** + * @brief disable Error interrupt + * @param DeviceAddr: Device address on communication Bus. + * @retval None. + */ +void mfxstm32l152_Error_DisableIT(uint16_t DeviceAddr) +{ + /* Disable global Error interrupt source */ + mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_ERROR); +} + +/** + * @brief FOR DEBUG ONLY + */ +uint8_t mfxstm32l152_ReadReg(uint16_t DeviceAddr, uint8_t RegAddr) +{ + /* Get the current register value */ + return(MFX_IO_Read((uint8_t) DeviceAddr, RegAddr)); +} + +void mfxstm32l152_WriteReg(uint16_t DeviceAddr, uint8_t RegAddr, uint8_t Value) +{ + /* set the current register value */ + MFX_IO_Write((uint8_t) DeviceAddr, RegAddr, Value); +} + +/* ------------------------------------------------------------------ */ +/* ----------------------- Private functions ------------------------ */ +/* ------------------------------------------------------------------ */ +/** + * @brief Check if the device instance of the selected address is already registered + * and return its index + * @param DeviceAddr: Device address on communication Bus. + * @retval Index of the device instance if registered, 0xFF if not. + */ +static uint8_t mfxstm32l152_GetInstance(uint16_t DeviceAddr) +{ + uint8_t idx = 0; + + /* Check all the registered instances */ + for(idx = 0; idx < MFXSTM32L152_MAX_INSTANCE ; idx ++) + { + if(mfxstm32l152[idx] == DeviceAddr) + { + return idx; + } + } + + return 0xFF; +} + +/** + * @brief Release registered device instance + * @param DeviceAddr: Device address on communication Bus. + * @retval Index of released device instance, 0xFF if not. + */ +static uint8_t mfxstm32l152_ReleaseInstance(uint16_t DeviceAddr) +{ + uint8_t idx = 0; + + /* Check for all the registered instances */ + for(idx = 0; idx < MFXSTM32L152_MAX_INSTANCE ; idx ++) + { + if(mfxstm32l152[idx] == DeviceAddr) + { + mfxstm32l152[idx] = 0; + return idx; + } + } + return 0xFF; +} + +/** + * @brief Internal routine + * @param DeviceAddr: Device address on communication Bus. + * @param RegisterAddr: Register Address + * @param PinPosition: Pin [0:23] + * @param PinValue: 0/1 + * @retval None + */ +void mfxstm32l152_reg24_setPinValue(uint16_t DeviceAddr, uint8_t RegisterAddr, uint32_t PinPosition, uint8_t PinValue ) +{ + uint8_t tmp = 0; + uint8_t pin_0_7, pin_8_15, pin_16_23; + + pin_0_7 = PinPosition & 0x0000ff; + pin_8_15 = PinPosition >> 8; + pin_8_15 = pin_8_15 & 0x00ff; + pin_16_23 = PinPosition >> 16; + + if (pin_0_7) + { + /* Get the current register value */ + tmp = MFX_IO_Read(DeviceAddr, RegisterAddr); + + /* Set the selected pin direction */ + if (PinValue != 0) + { + tmp |= (uint8_t)pin_0_7; + } + else + { + tmp &= ~(uint8_t)pin_0_7; + } + + /* Set the new register value */ + MFX_IO_Write(DeviceAddr, RegisterAddr, tmp); + } + + if (pin_8_15) + { + /* Get the current register value */ + tmp = MFX_IO_Read(DeviceAddr, RegisterAddr+1); + + /* Set the selected pin direction */ + if (PinValue != 0) + { + tmp |= (uint8_t)pin_8_15; + } + else + { + tmp &= ~(uint8_t)pin_8_15; + } + + /* Set the new register value */ + MFX_IO_Write(DeviceAddr, RegisterAddr+1, tmp); + } + + if (pin_16_23) + { + /* Get the current register value */ + tmp = MFX_IO_Read(DeviceAddr, RegisterAddr+2); + + /* Set the selected pin direction */ + if (PinValue != 0) + { + tmp |= (uint8_t)pin_16_23; + } + else + { + tmp &= ~(uint8_t)pin_16_23; + } + + /* Set the new register value */ + MFX_IO_Write(DeviceAddr, RegisterAddr+2, tmp); + } +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/mfxstm32l152/mfxstm32l152.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,669 @@ +/** + ****************************************************************************** + * @file mfxstm32l152.h + * @author MCD Application Team + * @version V2.0.0 + * @date 24-June-2015 + * @brief This file contains all the functions prototypes for the + * mfxstm32l152.c IO expander driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MFXSTM32L152_H +#define __MFXSTM32L152_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/ts.h" +#include "../Common/io.h" +#include "../Common/idd.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @defgroup MFXSTM32L152 + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Exported_Types + * @{ + */ +typedef struct +{ + uint8_t SYS_CTRL; + uint8_t ERROR_SRC; + uint8_t ERROR_MSG; + uint8_t IRQ_OUT; + uint8_t IRQ_SRC_EN; + uint8_t IRQ_PENDING; + uint8_t IDD_CTRL; + uint8_t IDD_PRE_DELAY; + uint8_t IDD_SHUNT0_MSB; + uint8_t IDD_SHUNT0_LSB; + uint8_t IDD_SHUNT1_MSB; + uint8_t IDD_SHUNT1_LSB; + uint8_t IDD_SHUNT2_MSB; + uint8_t IDD_SHUNT2_LSB; + uint8_t IDD_SHUNT3_MSB; + uint8_t IDD_SHUNT3_LSB; + uint8_t IDD_SHUNT4_MSB; + uint8_t IDD_SHUNT4_LSB; + uint8_t IDD_GAIN_MSB; + uint8_t IDD_GAIN_LSB; + uint8_t IDD_VDD_MIN_MSB; + uint8_t IDD_VDD_MIN_LSB; + uint8_t IDD_VALUE_MSB; + uint8_t IDD_VALUE_MID; + uint8_t IDD_VALUE_LSB; + uint8_t IDD_CAL_OFFSET_MSB; + uint8_t IDD_CAL_OFFSET_LSB; + uint8_t IDD_SHUNT_USED; +}IDD_dbgTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Exported_Constants + * @{ + */ + + /** + * @brief MFX COMMON defines + */ + + /** + * @brief Register address: chip IDs (R) + */ +#define MFXSTM32L152_REG_ADR_ID ((uint8_t)0x00) + /** + * @brief Register address: chip FW_VERSION (R) + */ +#define MFXSTM32L152_REG_ADR_FW_VERSION_MSB ((uint8_t)0x01) +#define MFXSTM32L152_REG_ADR_FW_VERSION_LSB ((uint8_t)0x00) + /** + * @brief Register address: System Control Register (R/W) + */ +#define MFXSTM32L152_REG_ADR_SYS_CTRL ((uint8_t)0x40) + /** + * @brief Register address: Vdd monitoring (R) + */ +#define MFXSTM32L152_REG_ADR_VDD_REF_MSB ((uint8_t)0x06) +#define MFXSTM32L152_REG_ADR_VDD_REF_LSB ((uint8_t)0x07) + /** + * @brief Register address: Error source + */ +#define MFXSTM32L152_REG_ADR_ERROR_SRC ((uint8_t)0x03) + /** + * @brief Register address: Error Message + */ +#define MFXSTM32L152_REG_ADR_ERROR_MSG ((uint8_t)0x04) + + /** + * @brief Reg Addr IRQs: to config the pin that informs Main MCU that MFX events appear + */ +#define MFXSTM32L152_REG_ADR_MFX_IRQ_OUT ((uint8_t)0x41) + /** + * @brief Reg Addr IRQs: to select the events which activate the MFXSTM32L152_IRQ_OUT signal + */ +#define MFXSTM32L152_REG_ADR_IRQ_SRC_EN ((uint8_t)0x42) + /** + * @brief Reg Addr IRQs: the Main MCU must read the IRQ_PENDING register to know the interrupt reason + */ +#define MFXSTM32L152_REG_ADR_IRQ_PENDING ((uint8_t)0x08) + /** + * @brief Reg Addr IRQs: the Main MCU must acknowledge it thanks to a writing access to the IRQ_ACK register + */ +#define MFXSTM32L152_REG_ADR_IRQ_ACK ((uint8_t)0x44) + + /** + * @brief MFXSTM32L152_REG_ADR_ID choices + */ +#define MFXSTM32L152_ID_1 ((uint8_t)0x7B) +#define MFXSTM32L152_ID_2 ((uint8_t)0x79) + + /** + * @brief MFXSTM32L152_REG_ADR_SYS_CTRL choices + */ +#define MFXSTM32L152_SWRST ((uint8_t)0x80) +#define MFXSTM32L152_STANDBY ((uint8_t)0x40) +#define MFXSTM32L152_ALTERNATE_GPIO_EN ((uint8_t)0x08) /* by the way if IDD and TS are enabled they take automatically the AF pins*/ +#define MFXSTM32L152_IDD_EN ((uint8_t)0x04) +#define MFXSTM32L152_TS_EN ((uint8_t)0x02) +#define MFXSTM32L152_GPIO_EN ((uint8_t)0x01) + + /** + * @brief MFXSTM32L152_REG_ADR_ERROR_SRC choices + */ +#define MFXSTM32L152_IDD_ERROR_SRC ((uint8_t)0x04) /* Error raised by Idd */ +#define MFXSTM32L152_TS_ERROR_SRC ((uint8_t)0x02) /* Error raised by Touch Screen */ +#define MFXSTM32L152_GPIO_ERROR_SRC ((uint8_t)0x01) /* Error raised by Gpio */ + + /** + * @brief MFXSTM32L152_REG_ADR_MFX_IRQ_OUT choices + */ +#define MFXSTM32L152_OUT_PIN_TYPE_OPENDRAIN ((uint8_t)0x00) +#define MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL ((uint8_t)0x01) +#define MFXSTM32L152_OUT_PIN_POLARITY_LOW ((uint8_t)0x00) +#define MFXSTM32L152_OUT_PIN_POLARITY_HIGH ((uint8_t)0x02) + + /** + * @brief REG_ADR_IRQ_SRC_EN, REG_ADR_IRQ_PENDING & REG_ADR_IRQ_ACK choices + */ +#define MFXSTM32L152_IRQ_TS_OVF ((uint8_t)0x80) /* TouchScreen FIFO Overflow irq*/ +#define MFXSTM32L152_IRQ_TS_FULL ((uint8_t)0x40) /* TouchScreen FIFO Full irq*/ +#define MFXSTM32L152_IRQ_TS_TH ((uint8_t)0x20) /* TouchScreen FIFO threshold triggered irq*/ +#define MFXSTM32L152_IRQ_TS_NE ((uint8_t)0x10) /* TouchScreen FIFO Not Empty irq*/ +#define MFXSTM32L152_IRQ_TS_DET ((uint8_t)0x08) /* TouchScreen Detect irq*/ +#define MFXSTM32L152_IRQ_ERROR ((uint8_t)0x04) /* Error message from MFXSTM32L152 firmware irq */ +#define MFXSTM32L152_IRQ_IDD ((uint8_t)0x02) /* IDD function irq */ +#define MFXSTM32L152_IRQ_GPIO ((uint8_t)0x01) /* General GPIO irq (only for SRC_EN and PENDING) */ +#define MFXSTM32L152_IRQ_ALL ((uint8_t)0xFF) /* All global interrupts */ +#define MFXSTM32L152_IRQ_TS (MFXSTM32L152_IRQ_TS_DET | MFXSTM32L152_IRQ_TS_NE | MFXSTM32L152_IRQ_TS_TH | MFXSTM32L152_IRQ_TS_FULL | MFXSTM32L152_IRQ_TS_OVF ) + + + /** + * @brief GPIO: 24 programmable input/output called MFXSTM32L152_GPIO[23:0] are provided + */ + + /** + * @brief Reg addr: GPIO DIRECTION (R/W): GPIO pins direction: (0) input, (1) output. + */ +#define MFXSTM32L152_REG_ADR_GPIO_DIR1 ((uint8_t)0x60) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_GPIO_DIR2 ((uint8_t)0x61) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_GPIO_DIR3 ((uint8_t)0x62) /* agpio [0:7] */ + /** + * @brief Reg addr: GPIO TYPE (R/W): If GPIO in output: (0) output push pull, (1) output open drain. + * If GPIO in input: (0) input without pull resistor, (1) input with pull resistor. + */ +#define MFXSTM32L152_REG_ADR_GPIO_TYPE1 ((uint8_t)0x64) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_GPIO_TYPE2 ((uint8_t)0x65) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_GPIO_TYPE3 ((uint8_t)0x66) /* agpio [0:7] */ + /** + * @brief Reg addr: GPIO PULL_UP_PULL_DOWN (R/W): discussion open with Jean Claude + */ +#define MFXSTM32L152_REG_ADR_GPIO_PUPD1 ((uint8_t)0x68) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_GPIO_PUPD2 ((uint8_t)0x69) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_GPIO_PUPD3 ((uint8_t)0x6A) /* agpio [0:7] */ + /** + * @brief Reg addr: GPIO SET (W): When GPIO is in output mode, write (1) puts the corresponding GPO in High level. + */ +#define MFXSTM32L152_REG_ADR_GPO_SET1 ((uint8_t)0x6C) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_GPO_SET2 ((uint8_t)0x6D) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_GPO_SET3 ((uint8_t)0x6E) /* agpio [0:7] */ + /** + * @brief Reg addr: GPIO CLEAR (W): When GPIO is in output mode, write (1) puts the corresponding GPO in Low level. + */ +#define MFXSTM32L152_REG_ADR_GPO_CLR1 ((uint8_t)0x70) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_GPO_CLR2 ((uint8_t)0x71) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_GPO_CLR3 ((uint8_t)0x72) /* agpio [0:7] */ + /** + * @brief Reg addr: GPIO STATE (R): Give state of the GPIO pin. + */ +#define MFXSTM32L152_REG_ADR_GPIO_STATE1 ((uint8_t)0x10) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_GPIO_STATE2 ((uint8_t)0x11) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_GPIO_STATE3 ((uint8_t)0x12) /* agpio [0:7] */ + + /** + * @brief GPIO IRQ_GPIs + */ +/* GPIOs can INDIVIDUALLY generate interruption to the Main MCU thanks to the MFXSTM32L152_IRQ_OUT signal */ +/* the general MFXSTM32L152_IRQ_GPIO_SRC_EN shall be enabled too */ + /** + * @brief GPIO IRQ_GPI_SRC1/2/3 (R/W): registers enable or not the feature to generate irq + */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1 ((uint8_t)0x48) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC2 ((uint8_t)0x49) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC3 ((uint8_t)0x4A) /* agpio [0:7] */ + /** + * @brief GPIO IRQ_GPI_EVT1/2/3 (R/W): Irq generated on level (0) or edge (1). + */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT1 ((uint8_t)0x4C) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT2 ((uint8_t)0x4D) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT3 ((uint8_t)0x4E) /* agpio [0:7] */ + /** + * @brief GPIO IRQ_GPI_TYPE1/2/3 (R/W): Irq generated on (0) : Low level or Falling edge. (1) : High level or Rising edge. + */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE1 ((uint8_t)0x50) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE2 ((uint8_t)0x51) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE3 ((uint8_t)0x52) /* agpio [0:7] */ + /** + * @brief GPIO IRQ_GPI_PENDING1/2/3 (R): irq occurs + */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING1 ((uint8_t)0x0C) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING2 ((uint8_t)0x0D) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING3 ((uint8_t)0x0E) /* agpio [0:7] */ + /** + * @brief GPIO IRQ_GPI_ACK1/2/3 (W): Write (1) to acknowledge IRQ event + */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK1 ((uint8_t)0x54) /* gpio [0:7] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK2 ((uint8_t)0x55) /* gpio [8:15] */ +#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK3 ((uint8_t)0x56) /* agpio [0:7] */ + + + /** + * @brief GPIO: IO Pins definition + */ +#define MFXSTM32L152_GPIO_PIN_0 ((uint32_t)0x0001) +#define MFXSTM32L152_GPIO_PIN_1 ((uint32_t)0x0002) +#define MFXSTM32L152_GPIO_PIN_2 ((uint32_t)0x0004) +#define MFXSTM32L152_GPIO_PIN_3 ((uint32_t)0x0008) +#define MFXSTM32L152_GPIO_PIN_4 ((uint32_t)0x0010) +#define MFXSTM32L152_GPIO_PIN_5 ((uint32_t)0x0020) +#define MFXSTM32L152_GPIO_PIN_6 ((uint32_t)0x0040) +#define MFXSTM32L152_GPIO_PIN_7 ((uint32_t)0x0080) + +#define MFXSTM32L152_GPIO_PIN_8 ((uint32_t)0x0100) +#define MFXSTM32L152_GPIO_PIN_9 ((uint32_t)0x0200) +#define MFXSTM32L152_GPIO_PIN_10 ((uint32_t)0x0400) +#define MFXSTM32L152_GPIO_PIN_11 ((uint32_t)0x0800) +#define MFXSTM32L152_GPIO_PIN_12 ((uint32_t)0x1000) +#define MFXSTM32L152_GPIO_PIN_13 ((uint32_t)0x2000) +#define MFXSTM32L152_GPIO_PIN_14 ((uint32_t)0x4000) +#define MFXSTM32L152_GPIO_PIN_15 ((uint32_t)0x8000) + +#define MFXSTM32L152_GPIO_PIN_16 ((uint32_t)0x010000) +#define MFXSTM32L152_GPIO_PIN_17 ((uint32_t)0x020000) +#define MFXSTM32L152_GPIO_PIN_18 ((uint32_t)0x040000) +#define MFXSTM32L152_GPIO_PIN_19 ((uint32_t)0x080000) +#define MFXSTM32L152_GPIO_PIN_20 ((uint32_t)0x100000) +#define MFXSTM32L152_GPIO_PIN_21 ((uint32_t)0x200000) +#define MFXSTM32L152_GPIO_PIN_22 ((uint32_t)0x400000) +#define MFXSTM32L152_GPIO_PIN_23 ((uint32_t)0x800000) + +#define MFXSTM32L152_AGPIO_PIN_0 MFXSTM32L152_GPIO_PIN_16 +#define MFXSTM32L152_AGPIO_PIN_1 MFXSTM32L152_GPIO_PIN_17 +#define MFXSTM32L152_AGPIO_PIN_2 MFXSTM32L152_GPIO_PIN_18 +#define MFXSTM32L152_AGPIO_PIN_3 MFXSTM32L152_GPIO_PIN_19 +#define MFXSTM32L152_AGPIO_PIN_4 MFXSTM32L152_GPIO_PIN_20 +#define MFXSTM32L152_AGPIO_PIN_5 MFXSTM32L152_GPIO_PIN_21 +#define MFXSTM32L152_AGPIO_PIN_6 MFXSTM32L152_GPIO_PIN_22 +#define MFXSTM32L152_AGPIO_PIN_7 MFXSTM32L152_GPIO_PIN_23 + +#define MFXSTM32L152_GPIO_PINS_ALL ((uint32_t)0xFFFFFF) + + /** + * @brief GPIO: constant + */ +#define MFXSTM32L152_GPIO_DIR_IN ((uint8_t)0x0) +#define MFXSTM32L152_GPIO_DIR_OUT ((uint8_t)0x1) +#define MFXSTM32L152_IRQ_GPI_EVT_LEVEL ((uint8_t)0x0) +#define MFXSTM32L152_IRQ_GPI_EVT_EDGE ((uint8_t)0x1) +#define MFXSTM32L152_IRQ_GPI_TYPE_LLFE ((uint8_t)0x0) /* Low Level Falling Edge */ +#define MFXSTM32L152_IRQ_GPI_TYPE_HLRE ((uint8_t)0x1) /*High Level Raising Edge */ +#define MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR ((uint8_t)0x0) +#define MFXSTM32L152_GPI_WITH_PULL_RESISTOR ((uint8_t)0x1) +#define MFXSTM32L152_GPO_PUSH_PULL ((uint8_t)0x0) +#define MFXSTM32L152_GPO_OPEN_DRAIN ((uint8_t)0x1) +#define MFXSTM32L152_GPIO_PULL_DOWN ((uint8_t)0x0) +#define MFXSTM32L152_GPIO_PULL_UP ((uint8_t)0x1) + + + /** + * @brief TOUCH SCREEN Registers + */ + + /** + * @brief Touch Screen Registers + */ +#define MFXSTM32L152_TS_SETTLING ((uint8_t)0xA0) +#define MFXSTM32L152_TS_TOUCH_DET_DELAY ((uint8_t)0xA1) +#define MFXSTM32L152_TS_AVE ((uint8_t)0xA2) +#define MFXSTM32L152_TS_TRACK ((uint8_t)0xA3) +#define MFXSTM32L152_TS_FIFO_TH ((uint8_t)0xA4) +#define MFXSTM32L152_TS_FIFO_STA ((uint8_t)0x20) +#define MFXSTM32L152_TS_FIFO_LEVEL ((uint8_t)0x21) +#define MFXSTM32L152_TS_XY_DATA ((uint8_t)0x24) + + /** + * @brief TS registers masks + */ +#define MFXSTM32L152_TS_CTRL_STATUS ((uint8_t)0x08) +#define MFXSTM32L152_TS_CLEAR_FIFO ((uint8_t)0x80) + + +/** + * @brief Register address: Idd control register (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_CTRL ((uint8_t)0x80) + +/** + * @brief Register address: Idd pre delay register (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_PRE_DELAY ((uint8_t)0x81) + +/** + * @brief Register address: Idd Shunt registers (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_SHUNT0_MSB ((uint8_t)0x82) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT0_LSB ((uint8_t)0x83) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT1_MSB ((uint8_t)0x84) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT1_LSB ((uint8_t)0x85) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT2_MSB ((uint8_t)0x86) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT2_LSB ((uint8_t)0x87) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT3_MSB ((uint8_t)0x88) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT3_LSB ((uint8_t)0x89) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT4_MSB ((uint8_t)0x8A) +#define MFXSTM32L152_REG_ADR_IDD_SHUNT4_LSB ((uint8_t)0x8B) + +/** + * @brief Register address: Idd ampli gain register (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_GAIN_MSB ((uint8_t)0x8C) +#define MFXSTM32L152_REG_ADR_IDD_GAIN_LSB ((uint8_t)0x8D) + +/** + * @brief Register address: Idd VDD min register (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_VDD_MIN_MSB ((uint8_t)0x8E) +#define MFXSTM32L152_REG_ADR_IDD_VDD_MIN_LSB ((uint8_t)0x8F) + +/** + * @brief Register address: Idd value register (R) + */ +#define MFXSTM32L152_REG_ADR_IDD_VALUE_MSB ((uint8_t)0x14) +#define MFXSTM32L152_REG_ADR_IDD_VALUE_MID ((uint8_t)0x15) +#define MFXSTM32L152_REG_ADR_IDD_VALUE_LSB ((uint8_t)0x16) + +/** + * @brief Register address: Idd calibration offset register (R) + */ +#define MFXSTM32L152_REG_ADR_IDD_CAL_OFFSET_MSB ((uint8_t)0x18) +#define MFXSTM32L152_REG_ADR_IDD_CAL_OFFSET_LSB ((uint8_t)0x19) + +/** + * @brief Register address: Idd shunt used offset register (R) + */ +#define MFXSTM32L152_REG_ADR_IDD_SHUNT_USED ((uint8_t)0x1A) + +/** + * @brief Register address: shunt stabilisation delay registers (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_SH0_STABILIZATION ((uint8_t)0x90) +#define MFXSTM32L152_REG_ADR_IDD_SH1_STABILIZATION ((uint8_t)0x91) +#define MFXSTM32L152_REG_ADR_IDD_SH2_STABILIZATION ((uint8_t)0x92) +#define MFXSTM32L152_REG_ADR_IDD_SH3_STABILIZATION ((uint8_t)0x93) +#define MFXSTM32L152_REG_ADR_IDD_SH4_STABILIZATION ((uint8_t)0x94) + +/** + * @brief Register address: Idd number of measurements register (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_NBR_OF_MEAS ((uint8_t)0x96) + +/** + * @brief Register address: Idd delta delay between 2 measurements register (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_MEAS_DELTA_DELAY ((uint8_t)0x97) + +/** + * @brief Register address: Idd number of shunt on board register (R/W) + */ +#define MFXSTM32L152_REG_ADR_IDD_SHUNTS_ON_BOARD ((uint8_t)0x98) + + + +/** @defgroup IDD_Control_Register_Defines IDD Control Register Defines + * @{ + */ +/** + * @brief IDD control register masks + */ +#define MFXSTM32L152_IDD_CTRL_REQ ((uint8_t)0x01) +#define MFXSTM32L152_IDD_CTRL_SHUNT_NB ((uint8_t)0x0E) +#define MFXSTM32L152_IDD_CTRL_VREF_DIS ((uint8_t)0x40) +#define MFXSTM32L152_IDD_CTRL_CAL_DIS ((uint8_t)0x80) + +/** + * @brief IDD Shunt Number + */ +#define MFXSTM32L152_IDD_SHUNT_NB_1 ((uint8_t) 0x01) +#define MFXSTM32L152_IDD_SHUNT_NB_2 ((uint8_t) 0x02) +#define MFXSTM32L152_IDD_SHUNT_NB_3 ((uint8_t) 0x03) +#define MFXSTM32L152_IDD_SHUNT_NB_4 ((uint8_t) 0x04) +#define MFXSTM32L152_IDD_SHUNT_NB_5 ((uint8_t) 0x05) + +/** + * @brief Vref Measurement + */ +#define MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_ENABLE ((uint8_t) 0x00) +#define MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_DISABLE ((uint8_t) 0x70) + +/** + * @brief IDD Calibration + */ +#define MFXSTM32L152_IDD_AUTO_CALIBRATION_ENABLE ((uint8_t) 0x00) +#define MFXSTM32L152_IDD_AUTO_CALIBRATION_DISABLE ((uint8_t) 0x80) +/** + * @} + */ + +/** @defgroup IDD_PreDelay_Defines IDD PreDelay Defines + * @{ + */ +/** + * @brief IDD PreDelay masks + */ +#define MFXSTM32L152_IDD_PREDELAY_UNIT ((uint8_t) 0x80) +#define MFXSTM32L152_IDD_PREDELAY_VALUE ((uint8_t) 0x7F) + + +/** + * @brief IDD PreDelay unit + */ +#define MFXSTM32L152_IDD_PREDELAY_0_5_MS ((uint8_t) 0x00) +#define MFXSTM32L152_IDD_PREDELAY_20_MS ((uint8_t) 0x80) +/** + * @} + */ + +/** @defgroup IDD_DeltaDelay_Defines IDD Delta DElay Defines + * @{ + */ +/** + * @brief IDD Delta Delay masks + */ +#define MFXSTM32L152_IDD_DELTADELAY_UNIT ((uint8_t) 0x80) +#define MFXSTM32L152_IDD_DELTADELAY_VALUE ((uint8_t) 0x7F) + + +/** + * @brief IDD Delta Delay unit + */ +#define MFXSTM32L152_IDD_DELTADELAY_0_5_MS ((uint8_t) 0x00) +#define MFXSTM32L152_IDD_DELTADELAY_20_MS ((uint8_t) 0x80) + + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup MFXSTM32L152_Exported_Functions + * @{ + */ + +/** + * @brief MFXSTM32L152 Control functions + */ +void mfxstm32l152_Init(uint16_t DeviceAddr); +void mfxstm32l152_DeInit(uint16_t DeviceAddr); +void mfxstm32l152_Reset(uint16_t DeviceAddr); +uint16_t mfxstm32l152_ReadID(uint16_t DeviceAddr); +uint16_t mfxstm32l152_ReadFwVersion(uint16_t DeviceAddr); +void mfxstm32l152_LowPower(uint16_t DeviceAddr); +void mfxstm32l152_WakeUp(uint16_t DeviceAddr); + +void mfxstm32l152_EnableITSource(uint16_t DeviceAddr, uint8_t Source); +void mfxstm32l152_DisableITSource(uint16_t DeviceAddr, uint8_t Source); +uint8_t mfxstm32l152_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source); +void mfxstm32l152_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source); + +void mfxstm32l152_SetIrqOutPinPolarity(uint16_t DeviceAddr, uint8_t Polarity); +void mfxstm32l152_SetIrqOutPinType(uint16_t DeviceAddr, uint8_t Type); + + +/** + * @brief MFXSTM32L152 IO functionalities functions + */ +void mfxstm32l152_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin); +uint8_t mfxstm32l152_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode); +void mfxstm32l152_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState); +uint32_t mfxstm32l152_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin); +void mfxstm32l152_IO_EnableIT(uint16_t DeviceAddr); +void mfxstm32l152_IO_DisableIT(uint16_t DeviceAddr); +uint32_t mfxstm32l152_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin); +void mfxstm32l152_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin); + +void mfxstm32l152_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction); +void mfxstm32l152_IO_EnableAF(uint16_t DeviceAddr); +void mfxstm32l152_IO_DisableAF(uint16_t DeviceAddr); +void mfxstm32l152_IO_SetIrqTypeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Type); +void mfxstm32l152_IO_SetIrqEvtMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Evt); +void mfxstm32l152_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin); +void mfxstm32l152_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin); + +/** + * @brief MFXSTM32L152 Touch screen functionalities functions + */ +void mfxstm32l152_TS_Start(uint16_t DeviceAddr); +uint8_t mfxstm32l152_TS_DetectTouch(uint16_t DeviceAddr); +void mfxstm32l152_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y); +void mfxstm32l152_TS_EnableIT(uint16_t DeviceAddr); +void mfxstm32l152_TS_DisableIT(uint16_t DeviceAddr); +uint8_t mfxstm32l152_TS_ITStatus (uint16_t DeviceAddr); +void mfxstm32l152_TS_ClearIT (uint16_t DeviceAddr); + +/** + * @brief MFXSTM32L152 IDD current measurement functionalities functions + */ +void mfxstm32l152_IDD_Start(uint16_t DeviceAddr); +void mfxstm32l152_IDD_Config(uint16_t DeviceAddr, IDD_ConfigTypeDef MfxIddConfig); +void mfxstm32l152_IDD_ConfigShuntNbLimit(uint16_t DeviceAddr, uint8_t ShuntNbLimit); +void mfxstm32l152_IDD_GetValue(uint16_t DeviceAddr, uint32_t *ReadValue); +uint8_t mfxstm32l152_IDD_GetShuntUsed(uint16_t DeviceAddr); +void mfxstm32l152_IDD_EnableIT(uint16_t DeviceAddr); +void mfxstm32l152_IDD_ClearIT(uint16_t DeviceAddr); +uint8_t mfxstm32l152_IDD_GetITStatus(uint16_t DeviceAddr); +void mfxstm32l152_IDD_DisableIT(uint16_t DeviceAddr); + +/** + * @brief MFXSTM32L152 Error management functions + */ +uint8_t mfxstm32l152_Error_ReadSrc(uint16_t DeviceAddr); +uint8_t mfxstm32l152_Error_ReadMsg(uint16_t DeviceAddr); +void mfxstm32l152_Error_EnableIT(uint16_t DeviceAddr); +void mfxstm32l152_Error_ClearIT(uint16_t DeviceAddr); +uint8_t mfxstm32l152_Error_GetITStatus(uint16_t DeviceAddr); +void mfxstm32l152_Error_DisableIT(uint16_t DeviceAddr); + +uint8_t mfxstm32l152_ReadReg(uint16_t DeviceAddr, uint8_t RegAddr); +void mfxstm32l152_WriteReg(uint16_t DeviceAddr, uint8_t RegAddr, uint8_t Value); + + + +/** + * @brief iobus prototypes (they should be defined in common/stm32_iobus.h) + */ +void MFX_IO_Init(void); +void MFX_IO_DeInit(void); +void MFX_IO_ITConfig (void); +void MFX_IO_EnableWakeupPin(void); +void MFX_IO_Wakeup(void); +void MFX_IO_Delay(uint32_t delay); +void MFX_IO_Write(uint16_t addr, uint8_t reg, uint8_t value); +uint8_t MFX_IO_Read(uint16_t addr, uint8_t reg); +uint16_t MFX_IO_ReadMultiple(uint16_t addr, uint8_t reg, uint8_t *buffer, uint16_t length); + +/** + * @} + */ + +/* Touch screen driver structure */ +extern TS_DrvTypeDef mfxstm32l152_ts_drv; + +/* IO driver structure */ +extern IO_DrvTypeDef mfxstm32l152_io_drv; + +/* IDD driver structure */ +extern IDD_DrvTypeDef mfxstm32l152_idd_drv; + + +#ifdef __cplusplus +} +#endif +#endif /* __MFXSTM32L152_H */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/n25q128a/n25q128a.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,220 @@ +/** + ****************************************************************************** + * @file n25q128a.h + * @author MCD Application Team + * @version V1.0.0 + * @date 29-May-2015 + * @brief This file contains all the description of the N25Q128A QSPI memory. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __N25Q128A_H +#define __N25Q128A_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup n25q128a + * @{ + */ + +/** @defgroup N25Q128A_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup N25Q128A_Exported_Constants + * @{ + */ + +/** + * @brief N25Q128A Configuration + */ +#define N25Q128A_FLASH_SIZE 0x1000000 /* 128 MBits => 16MBytes */ +#define N25Q128A_SECTOR_SIZE 0x10000 /* 256 sectors of 64KBytes */ +#define N25Q128A_SUBSECTOR_SIZE 0x1000 /* 4096 subsectors of 4kBytes */ +#define N25Q128A_PAGE_SIZE 0x100 /* 65536 pages of 256 bytes */ + +#define N25Q128A_DUMMY_CYCLES_READ 8 +#define N25Q128A_DUMMY_CYCLES_READ_QUAD 10 + +#define N25Q128A_BULK_ERASE_MAX_TIME 250000 +#define N25Q128A_SECTOR_ERASE_MAX_TIME 3000 +#define N25Q128A_SUBSECTOR_ERASE_MAX_TIME 800 + +/** + * @brief N25Q128A Commands + */ +/* Reset Operations */ +#define RESET_ENABLE_CMD 0x66 +#define RESET_MEMORY_CMD 0x99 + +/* Identification Operations */ +#define READ_ID_CMD 0x9E +#define READ_ID_CMD2 0x9F +#define MULTIPLE_IO_READ_ID_CMD 0xAF +#define READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5A + +/* Read Operations */ +#define READ_CMD 0x03 +#define FAST_READ_CMD 0x0B +#define DUAL_OUT_FAST_READ_CMD 0x3B +#define DUAL_INOUT_FAST_READ_CMD 0xBB +#define QUAD_OUT_FAST_READ_CMD 0x6B +#define QUAD_INOUT_FAST_READ_CMD 0xEB + +/* Write Operations */ +#define WRITE_ENABLE_CMD 0x06 +#define WRITE_DISABLE_CMD 0x04 + +/* Register Operations */ +#define READ_STATUS_REG_CMD 0x05 +#define WRITE_STATUS_REG_CMD 0x01 + +#define READ_LOCK_REG_CMD 0xE8 +#define WRITE_LOCK_REG_CMD 0xE5 + +#define READ_FLAG_STATUS_REG_CMD 0x70 +#define CLEAR_FLAG_STATUS_REG_CMD 0x50 + +#define READ_NONVOL_CFG_REG_CMD 0xB5 +#define WRITE_NONVOL_CFG_REG_CMD 0xB1 + +#define READ_VOL_CFG_REG_CMD 0x85 +#define WRITE_VOL_CFG_REG_CMD 0x81 + +#define READ_ENHANCED_VOL_CFG_REG_CMD 0x65 +#define WRITE_ENHANCED_VOL_CFG_REG_CMD 0x61 + +/* Program Operations */ +#define PAGE_PROG_CMD 0x02 +#define DUAL_IN_FAST_PROG_CMD 0xA2 +#define EXT_DUAL_IN_FAST_PROG_CMD 0xD2 +#define QUAD_IN_FAST_PROG_CMD 0x32 +#define EXT_QUAD_IN_FAST_PROG_CMD 0x12 + +/* Erase Operations */ +#define SUBSECTOR_ERASE_CMD 0x20 +#define SECTOR_ERASE_CMD 0xD8 +#define BULK_ERASE_CMD 0xC7 + +#define PROG_ERASE_RESUME_CMD 0x7A +#define PROG_ERASE_SUSPEND_CMD 0x75 + +/* One-Time Programmable Operations */ +#define READ_OTP_ARRAY_CMD 0x4B +#define PROG_OTP_ARRAY_CMD 0x42 + +/** + * @brief N25Q128A Registers + */ +/* Status Register */ +#define N25Q128A_SR_WIP ((uint8_t)0x01) /*!< Write in progress */ +#define N25Q128A_SR_WREN ((uint8_t)0x02) /*!< Write enable latch */ +#define N25Q128A_SR_BLOCKPR ((uint8_t)0x5C) /*!< Block protected against program and erase operations */ +#define N25Q128A_SR_PRBOTTOM ((uint8_t)0x20) /*!< Protected memory area defined by BLOCKPR starts from top or bottom */ +#define N25Q128A_SR_SRWREN ((uint8_t)0x80) /*!< Status register write enable/disable */ + +/* Nonvolatile Configuration Register */ +#define N25Q128A_NVCR_LOCK ((uint16_t)0x0001) /*!< Lock nonvolatile configuration register */ +#define N25Q128A_NVCR_DUAL ((uint16_t)0x0004) /*!< Dual I/O protocol */ +#define N25Q128A_NVCR_QUAB ((uint16_t)0x0008) /*!< Quad I/O protocol */ +#define N25Q128A_NVCR_RH ((uint16_t)0x0010) /*!< Reset/hold */ +#define N25Q128A_NVCR_ODS ((uint16_t)0x01C0) /*!< Output driver strength */ +#define N25Q128A_NVCR_XIP ((uint16_t)0x0E00) /*!< XIP mode at power-on reset */ +#define N25Q128A_NVCR_NB_DUMMY ((uint16_t)0xF000) /*!< Number of dummy clock cycles */ + +/* Volatile Configuration Register */ +#define N25Q128A_VCR_WRAP ((uint8_t)0x03) /*!< Wrap */ +#define N25Q128A_VCR_XIP ((uint8_t)0x08) /*!< XIP */ +#define N25Q128A_VCR_NB_DUMMY ((uint8_t)0xF0) /*!< Number of dummy clock cycles */ + +/* Enhanced Volatile Configuration Register */ +#define N25Q128A_EVCR_ODS ((uint8_t)0x07) /*!< Output driver strength */ +#define N25Q128A_EVCR_VPPA ((uint8_t)0x08) /*!< Vpp accelerator */ +#define N25Q128A_EVCR_RH ((uint8_t)0x10) /*!< Reset/hold */ +#define N25Q128A_EVCR_DUAL ((uint8_t)0x40) /*!< Dual I/O protocol */ +#define N25Q128A_EVCR_QUAD ((uint8_t)0x80) /*!< Quad I/O protocol */ + +/* Flag Status Register */ +#define N25Q128A_FSR_PRERR ((uint8_t)0x02) /*!< Protection error */ +#define N25Q128A_FSR_PGSUS ((uint8_t)0x04) /*!< Program operation suspended */ +#define N25Q128A_FSR_VPPERR ((uint8_t)0x08) /*!< Invalid voltage during program or erase */ +#define N25Q128A_FSR_PGERR ((uint8_t)0x10) /*!< Program error */ +#define N25Q128A_FSR_ERERR ((uint8_t)0x20) /*!< Erase error */ +#define N25Q128A_FSR_ERSUS ((uint8_t)0x40) /*!< Erase operation suspended */ +#define N25Q128A_FSR_READY ((uint8_t)0x80) /*!< Ready or command in progress */ + +/** + * @} + */ + +/** @defgroup N25Q128A_Exported_Functions + * @{ + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __N25Q128A_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/n25q256a/n25q256a.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,262 @@ +/** + ****************************************************************************** + * @file n25q256a.h + * @author MCD Application Team + * @version V1.0.0 + * @date 02-March-2015 + * @brief This file contains all the description of the N25Q256A QSPI memory. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __N25Q256A_H +#define __N25Q256A_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup n25q256a + * @{ + */ + +/** @defgroup N25Q256A_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup N25Q256A_Exported_Constants + * @{ + */ + +/** + * @brief N25Q256A Configuration + */ +#define N25Q256A_FLASH_SIZE 0x2000000 /* 256 MBits => 32MBytes */ +#define N25Q256A_SECTOR_SIZE 0x10000 /* 512 sectors of 64KBytes */ +#define N25Q256A_SUBSECTOR_SIZE 0x1000 /* 8192 subsectors of 4kBytes */ +#define N25Q256A_PAGE_SIZE 0x100 /* 131072 pages of 256 bytes */ + +#define N25Q256A_DUMMY_CYCLES_READ 8 +#define N25Q256A_DUMMY_CYCLES_READ_QUAD 10 +#define N25Q256A_DUMMY_CYCLES_READ_DTR 6 +#define N25Q256A_DUMMY_CYCLES_READ_QUAD_DTR 8 + +#define N25Q256A_BULK_ERASE_MAX_TIME 480000 +#define N25Q256A_SECTOR_ERASE_MAX_TIME 3000 +#define N25Q256A_SUBSECTOR_ERASE_MAX_TIME 800 + +/** + * @brief N25Q256A Commands + */ +/* Reset Operations */ +#define RESET_ENABLE_CMD 0x66 +#define RESET_MEMORY_CMD 0x99 + +/* Identification Operations */ +#define READ_ID_CMD 0x9E +#define READ_ID_CMD2 0x9F +#define MULTIPLE_IO_READ_ID_CMD 0xAF +#define READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5A + +/* Read Operations */ +#define READ_CMD 0x03 +#define READ_4_BYTE_ADDR_CMD 0x13 + +#define FAST_READ_CMD 0x0B +#define FAST_READ_DTR_CMD 0x0D +#define FAST_READ_4_BYTE_ADDR_CMD 0x0C + +#define DUAL_OUT_FAST_READ_CMD 0x3B +#define DUAL_OUT_FAST_READ_DTR_CMD 0x3D +#define DUAL_OUT_FAST_READ_4_BYTE_ADDR_CMD 0x3C + +#define DUAL_INOUT_FAST_READ_CMD 0xBB +#define DUAL_INOUT_FAST_READ_DTR_CMD 0xBD +#define DUAL_INOUT_FAST_READ_4_BYTE_ADDR_CMD 0xBC + +#define QUAD_OUT_FAST_READ_CMD 0x6B +#define QUAD_OUT_FAST_READ_DTR_CMD 0x6D +#define QUAD_OUT_FAST_READ_4_BYTE_ADDR_CMD 0x6C + +#define QUAD_INOUT_FAST_READ_CMD 0xEB +#define QUAD_INOUT_FAST_READ_DTR_CMD 0xED +#define QUAD_INOUT_FAST_READ_4_BYTE_ADDR_CMD 0xEC + +/* Write Operations */ +#define WRITE_ENABLE_CMD 0x06 +#define WRITE_DISABLE_CMD 0x04 + +/* Register Operations */ +#define READ_STATUS_REG_CMD 0x05 +#define WRITE_STATUS_REG_CMD 0x01 + +#define READ_LOCK_REG_CMD 0xE8 +#define WRITE_LOCK_REG_CMD 0xE5 + +#define READ_FLAG_STATUS_REG_CMD 0x70 +#define CLEAR_FLAG_STATUS_REG_CMD 0x50 + +#define READ_NONVOL_CFG_REG_CMD 0xB5 +#define WRITE_NONVOL_CFG_REG_CMD 0xB1 + +#define READ_VOL_CFG_REG_CMD 0x85 +#define WRITE_VOL_CFG_REG_CMD 0x81 + +#define READ_ENHANCED_VOL_CFG_REG_CMD 0x65 +#define WRITE_ENHANCED_VOL_CFG_REG_CMD 0x61 + +#define READ_EXT_ADDR_REG_CMD 0xC8 +#define WRITE_EXT_ADDR_REG_CMD 0xC5 + +/* Program Operations */ +#define PAGE_PROG_CMD 0x02 +#define PAGE_PROG_4_BYTE_ADDR_CMD 0x12 + +#define DUAL_IN_FAST_PROG_CMD 0xA2 +#define EXT_DUAL_IN_FAST_PROG_CMD 0xD2 + +#define QUAD_IN_FAST_PROG_CMD 0x32 +#define EXT_QUAD_IN_FAST_PROG_CMD 0x12 /*0x38*/ +#define QUAD_IN_FAST_PROG_4_BYTE_ADDR_CMD 0x34 + +/* Erase Operations */ +#define SUBSECTOR_ERASE_CMD 0x20 +#define SUBSECTOR_ERASE_4_BYTE_ADDR_CMD 0x21 + +#define SECTOR_ERASE_CMD 0xD8 +#define SECTOR_ERASE_4_BYTE_ADDR_CMD 0xDC + +#define BULK_ERASE_CMD 0xC7 + +#define PROG_ERASE_RESUME_CMD 0x7A +#define PROG_ERASE_SUSPEND_CMD 0x75 + +/* One-Time Programmable Operations */ +#define READ_OTP_ARRAY_CMD 0x4B +#define PROG_OTP_ARRAY_CMD 0x42 + +/* 4-byte Address Mode Operations */ +#define ENTER_4_BYTE_ADDR_MODE_CMD 0xB7 +#define EXIT_4_BYTE_ADDR_MODE_CMD 0xE9 + +/* Quad Operations */ +#define ENTER_QUAD_CMD 0x35 +#define EXIT_QUAD_CMD 0xF5 + +/** + * @brief N25Q256A Registers + */ +/* Status Register */ +#define N25Q256A_SR_WIP ((uint8_t)0x01) /*!< Write in progress */ +#define N25Q256A_SR_WREN ((uint8_t)0x02) /*!< Write enable latch */ +#define N25Q256A_SR_BLOCKPR ((uint8_t)0x5C) /*!< Block protected against program and erase operations */ +#define N25Q256A_SR_PRBOTTOM ((uint8_t)0x20) /*!< Protected memory area defined by BLOCKPR starts from top or bottom */ +#define N25Q256A_SR_SRWREN ((uint8_t)0x80) /*!< Status register write enable/disable */ + +/* Nonvolatile Configuration Register */ +#define N25Q256A_NVCR_NBADDR ((uint16_t)0x0001) /*!< 3-bytes or 4-bytes addressing */ +#define N25Q256A_NVCR_SEGMENT ((uint16_t)0x0002) /*!< Upper or lower 128Mb segment selected by default */ +#define N25Q256A_NVCR_DUAL ((uint16_t)0x0004) /*!< Dual I/O protocol */ +#define N25Q256A_NVCR_QUAB ((uint16_t)0x0008) /*!< Quad I/O protocol */ +#define N25Q256A_NVCR_RH ((uint16_t)0x0010) /*!< Reset/hold */ +#define N25Q256A_NVCR_ODS ((uint16_t)0x01C0) /*!< Output driver strength */ +#define N25Q256A_NVCR_XIP ((uint16_t)0x0E00) /*!< XIP mode at power-on reset */ +#define N25Q256A_NVCR_NB_DUMMY ((uint16_t)0xF000) /*!< Number of dummy clock cycles */ + +/* Volatile Configuration Register */ +#define N25Q256A_VCR_WRAP ((uint8_t)0x03) /*!< Wrap */ +#define N25Q256A_VCR_XIP ((uint8_t)0x08) /*!< XIP */ +#define N25Q256A_VCR_NB_DUMMY ((uint8_t)0xF0) /*!< Number of dummy clock cycles */ + +/* Extended Address Register */ +#define N25Q256A_EAR_A24 ((uint8_t)0x01) /*!< Select the lower or upper 128Mb segment */ + +/* Enhanced Volatile Configuration Register */ +#define N25Q256A_EVCR_ODS ((uint8_t)0x07) /*!< Output driver strength */ +#define N25Q256A_EVCR_VPPA ((uint8_t)0x08) /*!< Vpp accelerator */ +#define N25Q256A_EVCR_RH ((uint8_t)0x10) /*!< Reset/hold */ +#define N25Q256A_EVCR_DUAL ((uint8_t)0x40) /*!< Dual I/O protocol */ +#define N25Q256A_EVCR_QUAD ((uint8_t)0x80) /*!< Quad I/O protocol */ + +/* Flag Status Register */ +#define N25Q256A_FSR_NBADDR ((uint8_t)0x01) /*!< 3-bytes or 4-bytes addressing */ +#define N25Q256A_FSR_PRERR ((uint8_t)0x02) /*!< Protection error */ +#define N25Q256A_FSR_PGSUS ((uint8_t)0x04) /*!< Program operation suspended */ +#define N25Q256A_FSR_VPPERR ((uint8_t)0x08) /*!< Invalid voltage during program or erase */ +#define N25Q256A_FSR_PGERR ((uint8_t)0x10) /*!< Program error */ +#define N25Q256A_FSR_ERERR ((uint8_t)0x20) /*!< Erase error */ +#define N25Q256A_FSR_ERSUS ((uint8_t)0x40) /*!< Erase operation suspended */ +#define N25Q256A_FSR_READY ((uint8_t)0x80) /*!< Ready or command in progress */ + +/** + * @} + */ + +/** @defgroup N25Q256A_Exported_Functions + * @{ + */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __N25Q256A_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/st7735/st7735.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file st7735.c + * @author MCD Application Team + * @version V1.1.1 + * @date 24-November-2014 + * @brief This file includes the driver for ST7735 LCD mounted on the Adafruit + * 1.8" TFT LCD shield (reference ID 802). + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "st7735.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup ST7735 + * @brief This file provides a set of functions needed to drive the + * ST7735 LCD. + * @{ + */ + +/** @defgroup ST7735_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup ST7735_Private_Defines + * @{ + */ + +/** + * @} + */ + +/** @defgroup ST7735_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup ST7735_Private_Variables + * @{ + */ + + +LCD_DrvTypeDef st7735_drv = +{ + st7735_Init, + 0, + st7735_DisplayOn, + st7735_DisplayOff, + st7735_SetCursor, + st7735_WritePixel, + 0, + st7735_SetDisplayWindow, + st7735_DrawHLine, + st7735_DrawVLine, + st7735_GetLcdPixelWidth, + st7735_GetLcdPixelHeight, + st7735_DrawBitmap, +}; + +static uint16_t ArrayRGB[320] = {0}; + +/** +* @} +*/ + +/** @defgroup ST7735_Private_FunctionPrototypes + * @{ + */ + +/** +* @} +*/ + +/** @defgroup ST7735_Private_Functions + * @{ + */ + +/** + * @brief Initialize the ST7735 LCD Component. + * @param None + * @retval None + */ +void st7735_Init(void) +{ + uint8_t data = 0; + + /* Initialize ST7735 low level bus layer -----------------------------------*/ + LCD_IO_Init(); + /* Out of sleep mode, 0 args, no delay */ + st7735_WriteReg(LCD_REG_17, 0x00); + /* Frame rate ctrl - normal mode, 3 args:Rate = fosc/(1x2+40) * (LINE+2C+2D)*/ + LCD_IO_WriteReg(LCD_REG_177); + data = 0x01; + LCD_IO_WriteMultipleData(&data, 1); + data = 0x2C; + LCD_IO_WriteMultipleData(&data, 1); + data = 0x2D; + LCD_IO_WriteMultipleData(&data, 1); + /* Frame rate control - idle mode, 3 args:Rate = fosc/(1x2+40) * (LINE+2C+2D) */ + st7735_WriteReg(LCD_REG_178, 0x01); + st7735_WriteReg(LCD_REG_178, 0x2C); + st7735_WriteReg(LCD_REG_178, 0x2D); + /* Frame rate ctrl - partial mode, 6 args: Dot inversion mode, Line inversion mode */ + st7735_WriteReg(LCD_REG_179, 0x01); + st7735_WriteReg(LCD_REG_179, 0x2C); + st7735_WriteReg(LCD_REG_179, 0x2D); + st7735_WriteReg(LCD_REG_179, 0x01); + st7735_WriteReg(LCD_REG_179, 0x2C); + st7735_WriteReg(LCD_REG_179, 0x2D); + /* Display inversion ctrl, 1 arg, no delay: No inversion */ + st7735_WriteReg(LCD_REG_180, 0x07); + /* Power control, 3 args, no delay: -4.6V , AUTO mode */ + st7735_WriteReg(LCD_REG_192, 0xA2); + st7735_WriteReg(LCD_REG_192, 0x02); + st7735_WriteReg(LCD_REG_192, 0x84); + /* Power control, 1 arg, no delay: VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */ + st7735_WriteReg(LCD_REG_193, 0xC5); + /* Power control, 2 args, no delay: Opamp current small, Boost frequency */ + st7735_WriteReg(LCD_REG_194, 0x0A); + st7735_WriteReg(LCD_REG_194, 0x00); + /* Power control, 2 args, no delay: BCLK/2, Opamp current small & Medium low */ + st7735_WriteReg(LCD_REG_195, 0x8A); + st7735_WriteReg(LCD_REG_195, 0x2A); + /* Power control, 2 args, no delay */ + st7735_WriteReg(LCD_REG_196, 0x8A); + st7735_WriteReg(LCD_REG_196, 0xEE); + /* Power control, 1 arg, no delay */ + st7735_WriteReg(LCD_REG_197, 0x0E); + /* Don't invert display, no args, no delay */ + LCD_IO_WriteReg(LCD_REG_32); + /* Set color mode, 1 arg, no delay: 16-bit color */ + st7735_WriteReg(LCD_REG_58, 0x05); + /* Column addr set, 4 args, no delay: XSTART = 0, XEND = 127 */ + LCD_IO_WriteReg(LCD_REG_42); + data = 0x00; + LCD_IO_WriteMultipleData(&data, 1); + LCD_IO_WriteMultipleData(&data, 1); + LCD_IO_WriteMultipleData(&data, 1); + data = 0x7F; + LCD_IO_WriteMultipleData(&data, 1); + /* Row addr set, 4 args, no delay: YSTART = 0, YEND = 159 */ + LCD_IO_WriteReg(LCD_REG_43); + data = 0x00; + LCD_IO_WriteMultipleData(&data, 1); + LCD_IO_WriteMultipleData(&data, 1); + LCD_IO_WriteMultipleData(&data, 1); + data = 0x9F; + LCD_IO_WriteMultipleData(&data, 1); + /* Magical unicorn dust, 16 args, no delay */ + st7735_WriteReg(LCD_REG_224, 0x02); + st7735_WriteReg(LCD_REG_224, 0x1c); + st7735_WriteReg(LCD_REG_224, 0x07); + st7735_WriteReg(LCD_REG_224, 0x12); + st7735_WriteReg(LCD_REG_224, 0x37); + st7735_WriteReg(LCD_REG_224, 0x32); + st7735_WriteReg(LCD_REG_224, 0x29); + st7735_WriteReg(LCD_REG_224, 0x2d); + st7735_WriteReg(LCD_REG_224, 0x29); + st7735_WriteReg(LCD_REG_224, 0x25); + st7735_WriteReg(LCD_REG_224, 0x2B); + st7735_WriteReg(LCD_REG_224, 0x39); + st7735_WriteReg(LCD_REG_224, 0x00); + st7735_WriteReg(LCD_REG_224, 0x01); + st7735_WriteReg(LCD_REG_224, 0x03); + st7735_WriteReg(LCD_REG_224, 0x10); + /* Sparkles and rainbows, 16 args, no delay */ + st7735_WriteReg(LCD_REG_225, 0x03); + st7735_WriteReg(LCD_REG_225, 0x1d); + st7735_WriteReg(LCD_REG_225, 0x07); + st7735_WriteReg(LCD_REG_225, 0x06); + st7735_WriteReg(LCD_REG_225, 0x2E); + st7735_WriteReg(LCD_REG_225, 0x2C); + st7735_WriteReg(LCD_REG_225, 0x29); + st7735_WriteReg(LCD_REG_225, 0x2D); + st7735_WriteReg(LCD_REG_225, 0x2E); + st7735_WriteReg(LCD_REG_225, 0x2E); + st7735_WriteReg(LCD_REG_225, 0x37); + st7735_WriteReg(LCD_REG_225, 0x3F); + st7735_WriteReg(LCD_REG_225, 0x00); + st7735_WriteReg(LCD_REG_225, 0x00); + st7735_WriteReg(LCD_REG_225, 0x02); + st7735_WriteReg(LCD_REG_225, 0x10); + /* Normal display on, no args, no delay */ + st7735_WriteReg(LCD_REG_19, 0x00); + /* Main screen turn on, no delay */ + st7735_WriteReg(LCD_REG_41, 0x00); + /* Memory access control: MY = 1, MX = 1, MV = 0, ML = 0 */ + st7735_WriteReg(LCD_REG_54, 0xC0); +} + +/** + * @brief Enables the Display. + * @param None + * @retval None + */ +void st7735_DisplayOn(void) +{ + uint8_t data = 0; + LCD_IO_WriteReg(LCD_REG_19); + LCD_Delay(10); + LCD_IO_WriteReg(LCD_REG_41); + LCD_Delay(10); + LCD_IO_WriteReg(LCD_REG_54); + data = 0xC0; + LCD_IO_WriteMultipleData(&data, 1); +} + +/** + * @brief Disables the Display. + * @param None + * @retval None + */ +void st7735_DisplayOff(void) +{ + uint8_t data = 0; + LCD_IO_WriteReg(LCD_REG_19); + LCD_Delay(10); + LCD_IO_WriteReg(LCD_REG_40); + LCD_Delay(10); + LCD_IO_WriteReg(LCD_REG_54); + data = 0xC0; + LCD_IO_WriteMultipleData(&data, 1); +} + +/** + * @brief Sets Cursor position. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @retval None + */ +void st7735_SetCursor(uint16_t Xpos, uint16_t Ypos) +{ + uint8_t data = 0; + LCD_IO_WriteReg(LCD_REG_42); + data = (Xpos) >> 8; + LCD_IO_WriteMultipleData(&data, 1); + data = (Xpos) & 0xFF; + LCD_IO_WriteMultipleData(&data, 1); + LCD_IO_WriteReg(LCD_REG_43); + data = (Ypos) >> 8; + LCD_IO_WriteMultipleData(&data, 1); + data = (Ypos) & 0xFF; + LCD_IO_WriteMultipleData(&data, 1); + LCD_IO_WriteReg(LCD_REG_44); +} + +/** + * @brief Writes pixel. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param RGBCode: the RGB pixel color + * @retval None + */ +void st7735_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode) +{ + uint8_t data = 0; + if((Xpos >= ST7735_LCD_PIXEL_WIDTH) || (Ypos >= ST7735_LCD_PIXEL_HEIGHT)) + { + return; + } + + /* Set Cursor */ + st7735_SetCursor(Xpos, Ypos); + + data = RGBCode >> 8; + LCD_IO_WriteMultipleData(&data, 1); + data = RGBCode; + LCD_IO_WriteMultipleData(&data, 1); +} + + +/** + * @brief Writes to the selected LCD register. + * @param LCDReg: Address of the selected register. + * @param LCDRegValue: value to write to the selected register. + * @retval None + */ +void st7735_WriteReg(uint8_t LCDReg, uint8_t LCDRegValue) +{ + LCD_IO_WriteReg(LCDReg); + LCD_IO_WriteMultipleData(&LCDRegValue, 1); +} + +/** + * @brief Sets a display window + * @param Xpos: specifies the X bottom left position. + * @param Ypos: specifies the Y bottom left position. + * @param Height: display window height. + * @param Width: display window width. + * @retval None + */ +void st7735_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) +{ + uint8_t data = 0; + /* Column addr set, 4 args, no delay: XSTART = Xpos, XEND = (Xpos + Width - 1) */ + LCD_IO_WriteReg(LCD_REG_42); + data = (Xpos) >> 8; + LCD_IO_WriteMultipleData(&data, 1); + data = (Xpos) & 0xFF; + LCD_IO_WriteMultipleData(&data, 1); + data = (Xpos + Width - 1) >> 8; + LCD_IO_WriteMultipleData(&data, 1); + data = (Xpos + Width - 1) & 0xFF; + LCD_IO_WriteMultipleData(&data, 1); + /* Row addr set, 4 args, no delay: YSTART = Ypos, YEND = (Ypos + Height - 1) */ + LCD_IO_WriteReg(LCD_REG_43); + data = (Ypos) >> 8; + LCD_IO_WriteMultipleData(&data, 1); + data = (Ypos) & 0xFF; + LCD_IO_WriteMultipleData(&data, 1); + data = (Ypos + Height - 1) >> 8; + LCD_IO_WriteMultipleData(&data, 1); + data = (Ypos + Height - 1) & 0xFF; + LCD_IO_WriteMultipleData(&data, 1); +} + +/** + * @brief Draws horizontal line. + * @param RGBCode: Specifies the RGB color + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Length: specifies the line length. + * @retval None + */ +void st7735_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length) +{ + uint8_t counter = 0; + + if(Xpos + Length > ST7735_LCD_PIXEL_WIDTH) return; + + /* Set Cursor */ + st7735_SetCursor(Xpos, Ypos); + + for(counter = 0; counter < Length; counter++) + { + ArrayRGB[counter] = RGBCode; + } + LCD_IO_WriteMultipleData((uint8_t*)&ArrayRGB[0], Length * 2); +} + +/** + * @brief Draws vertical line. + * @param RGBCode: Specifies the RGB color + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Length: specifies the line length. + * @retval None + */ +void st7735_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length) +{ + uint8_t counter = 0; + + if(Ypos + Length > ST7735_LCD_PIXEL_HEIGHT) return; + for(counter = 0; counter < Length; counter++) + { + st7735_WritePixel(Xpos, Ypos + counter, RGBCode); + } +} + +/** + * @brief Gets the LCD pixel Width. + * @param None + * @retval The Lcd Pixel Width + */ +uint16_t st7735_GetLcdPixelWidth(void) +{ + return ST7735_LCD_PIXEL_WIDTH; +} + +/** + * @brief Gets the LCD pixel Height. + * @param None + * @retval The Lcd Pixel Height + */ +uint16_t st7735_GetLcdPixelHeight(void) +{ + return ST7735_LCD_PIXEL_HEIGHT; +} + +/** + * @brief Displays a bitmap picture loaded in the internal Flash. + * @param BmpAddress: Bmp picture address in the internal Flash. + * @retval None + */ +void st7735_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp) +{ + uint32_t index = 0, size = 0; + + /* Read bitmap size */ + size = *(volatile uint16_t *) (pbmp + 2); + size |= (*(volatile uint16_t *) (pbmp + 4)) << 16; + /* Get bitmap data address offset */ + index = *(volatile uint16_t *) (pbmp + 10); + index |= (*(volatile uint16_t *) (pbmp + 12)) << 16; + size = (size - index)/2; + pbmp += index; + + /* Set GRAM write direction and BGR = 0 */ + /* Memory access control: MY = 0, MX = 1, MV = 0, ML = 0 */ + st7735_WriteReg(LCD_REG_54, 0x40); + + /* Set Cursor */ + st7735_SetCursor(Xpos, Ypos); + + LCD_IO_WriteMultipleData((uint8_t*)pbmp, size*2); + + /* Set GRAM write direction and BGR = 0 */ + /* Memory access control: MY = 1, MX = 1, MV = 0, ML = 0 */ + st7735_WriteReg(LCD_REG_54, 0xC0); +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/st7735/st7735.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,215 @@ +/** + ****************************************************************************** + * @file st7735.h + * @author MCD Application Team + * @version V1.1.1 + * @date 24-November-2014 + * @brief This file contains all the functions prototypes for the st7735.c + * driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ST7735_H +#define __ST7735_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/lcd.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup ST7735 + * @{ + */ + +/** @defgroup ST7735_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup ST7735_Exported_Constants + * @{ + */ + +/** + * @brief ST7735 Size + */ +#define ST7735_LCD_PIXEL_WIDTH ((uint16_t)128) +#define ST7735_LCD_PIXEL_HEIGHT ((uint16_t)160) + +/** + * @brief ST7735 Registers + */ +#define LCD_REG_0 0x00 /* No Operation: NOP */ +#define LCD_REG_1 0x01 /* Software reset: SWRESET */ +#define LCD_REG_4 0x04 /* Read Display ID: RDDID */ +#define LCD_REG_9 0x09 /* Read Display Statu: RDDST */ +#define LCD_REG_10 0x0A /* Read Display Power: RDDPM */ +#define LCD_REG_11 0x0B /* Read Display: RDDMADCTL */ +#define LCD_REG_12 0x0C /* Read Display Pixel: RDDCOLMOD */ +#define LCD_REG_13 0x0D /* Read Display Image: RDDIM */ +#define LCD_REG_14 0x0E /* Read Display Signal: RDDSM */ +#define LCD_REG_16 0x10 /* Sleep in & booster off: SLPIN */ +#define LCD_REG_17 0x11 /* Sleep out & booster on: SLPOUT */ +#define LCD_REG_18 0x12 /* Partial mode on: PTLON */ +#define LCD_REG_19 0x13 /* Partial off (Normal): NORON */ +#define LCD_REG_32 0x20 /* Display inversion off: INVOFF */ +#define LCD_REG_33 0x21 /* Display inversion on: INVON */ +#define LCD_REG_38 0x26 /* Gamma curve select: GAMSET */ +#define LCD_REG_40 0x28 /* Display off: DISPOFF */ +#define LCD_REG_41 0x29 /* Display on: DISPON */ +#define LCD_REG_42 0x2A /* Column address set: CASET */ +#define LCD_REG_43 0x2B /* Row address set: RASET */ +#define LCD_REG_44 0x2C /* Memory write: RAMWR */ +#define LCD_REG_45 0x2D /* LUT for 4k,65k,262k color: RGBSET */ +#define LCD_REG_46 0x2E /* Memory read: RAMRD*/ +#define LCD_REG_48 0x30 /* Partial start/end address set: PTLAR */ +#define LCD_REG_52 0x34 /* Tearing effect line off: TEOFF */ +#define LCD_REG_53 0x35 /* Tearing effect mode set & on: TEON */ +#define LCD_REG_54 0x36 /* Memory data access control: MADCTL */ +#define LCD_REG_56 0x38 /* Idle mode off: IDMOFF */ +#define LCD_REG_57 0x39 /* Idle mode on: IDMON */ +#define LCD_REG_58 0x3A /* Interface pixel format: COLMOD */ +#define LCD_REG_177 0xB1 /* In normal mode (Full colors): FRMCTR1 */ +#define LCD_REG_178 0xB2 /* In Idle mode (8-colors): FRMCTR2 */ +#define LCD_REG_179 0xB3 /* In partial mode + Full colors: FRMCTR3 */ +#define LCD_REG_180 0xB4 /* Display inversion control: INVCTR */ +#define LCD_REG_192 0xC0 /* Power control setting: PWCTR1 */ +#define LCD_REG_193 0xC1 /* Power control setting: PWCTR2 */ +#define LCD_REG_194 0xC2 /* In normal mode (Full colors): PWCTR3 */ +#define LCD_REG_195 0xC3 /* In Idle mode (8-colors): PWCTR4 */ +#define LCD_REG_196 0xC4 /* In partial mode + Full colors: PWCTR5 */ +#define LCD_REG_197 0xC5 /* VCOM control 1: VMCTR1 */ +#define LCD_REG_199 0xC7 /* Set VCOM offset control: VMOFCTR */ +#define LCD_REG_209 0xD1 /* Set LCM version code: WRID2 */ +#define LCD_REG_210 0xD2 /* Customer Project code: WRID3 */ +#define LCD_REG_217 0xD9 /* NVM control status: NVCTR1 */ +#define LCD_REG_218 0xDA /* Read ID1: RDID1 */ +#define LCD_REG_219 0xDB /* Read ID2: RDID2 */ +#define LCD_REG_220 0xDC /* Read ID3: RDID3 */ +#define LCD_REG_222 0xDE /* NVM Read Command: NVCTR2 */ +#define LCD_REG_223 0xDF /* NVM Write Command: NVCTR3 */ +#define LCD_REG_224 0xE0 /* Set Gamma adjustment (+ polarity): GAMCTRP1 */ +#define LCD_REG_225 0xE1 /* Set Gamma adjustment (- polarity): GAMCTRN1 */ + +/** + * @brief LCD Lines depending on the chosen fonts. + */ +#define LCD_LINE_0 LINE(0) +#define LCD_LINE_1 LINE(1) +#define LCD_LINE_2 LINE(2) +#define LCD_LINE_3 LINE(3) +#define LCD_LINE_4 LINE(4) +#define LCD_LINE_5 LINE(5) +#define LCD_LINE_6 LINE(6) +#define LCD_LINE_7 LINE(7) +#define LCD_LINE_8 LINE(8) +#define LCD_LINE_9 LINE(9) +#define LCD_LINE_10 LINE(10) +#define LCD_LINE_11 LINE(11) +#define LCD_LINE_12 LINE(12) +#define LCD_LINE_13 LINE(13) +#define LCD_LINE_14 LINE(14) +#define LCD_LINE_15 LINE(15) +#define LCD_LINE_16 LINE(16) +#define LCD_LINE_17 LINE(17) +#define LCD_LINE_18 LINE(18) +#define LCD_LINE_19 LINE(19) + +/** + * @} + */ + +/** @defgroup ADAFRUIT_SPI_LCD_Exported_Functions + * @{ + */ +void st7735_Init(void); +uint16_t st7735_ReadID(void); + +void st7735_DisplayOn(void); +void st7735_DisplayOff(void); +void st7735_SetCursor(uint16_t Xpos, uint16_t Ypos); +void st7735_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode); +void st7735_WriteReg(uint8_t LCDReg, uint8_t LCDRegValue); +uint8_t st7735_ReadReg(uint8_t LCDReg); + +void st7735_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height); +void st7735_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length); +void st7735_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length); + +uint16_t st7735_GetLcdPixelWidth(void); +uint16_t st7735_GetLcdPixelHeight(void); +void st7735_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp); + +/* LCD driver structure */ +extern LCD_DrvTypeDef st7735_drv; + +/* LCD IO functions */ +void LCD_IO_Init(void); +void LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size); +void LCD_IO_WriteReg(uint8_t Reg); +void LCD_Delay(uint32_t delay); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ST7735_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/stmpe1600/stmpe1600.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,605 @@ +/** + ****************************************************************************** + * @file stmpe1600.c + * @author MCD Application Team + * @version V1.1.0 + * @date 10-February-2015 + * @brief This file provides a set of functions needed to manage the STMPE1600 + * IO Expander devices. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stmpe1600.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @defgroup STMPE1600 + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ + +/** @defgroup STMPE1600_Private_Types_Definitions + * @{ + */ + +/* Private define ------------------------------------------------------------*/ + +/** @defgroup STMPE1600_Private_Defines + * @{ + */ +#define STMPE1600_MAX_INSTANCE 2 + +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup STMPE1600_Private_Macros + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ +static uint16_t tmp = 0; + +/** @defgroup STMPE1600_Private_Variables + * @{ + */ +/* IO driver structure initialization */ +IO_DrvTypeDef stmpe1600_io_drv = +{ + stmpe1600_Init, + stmpe1600_ReadID, + stmpe1600_Reset, + stmpe1600_Start, + stmpe1600_IO_Config, + stmpe1600_IO_WritePin, + stmpe1600_IO_ReadPin, + 0, + 0, + stmpe1600_IO_ITStatus, + stmpe1600_IO_ClearIT, +}; + +uint8_t stmpe1600[STMPE1600_MAX_INSTANCE] = {0}; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/** @defgroup STMPE1600_Private_Function_Prototypes + * @{ + */ +static uint8_t stmpe1600_GetInstance(uint16_t DeviceAddr); + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup STMPE1600_Private_Functions + * @{ + */ + +/** + * @brief Initialize the stmpe1600 and configure the needed hardware resources + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe1600_Init(uint16_t DeviceAddr) +{ + uint8_t instance; + uint8_t empty; + + /* Check if device instance already exists */ + instance = stmpe1600_GetInstance(DeviceAddr); + + if(instance == 0xFF) + { + /* Look for empty instance */ + empty = stmpe1600_GetInstance(0); + + if(empty < STMPE1600_MAX_INSTANCE) + { + /* Register the current device instance */ + stmpe1600[empty] = DeviceAddr; + + /* Initialize IO BUS layer */ + IOE_Init(); + + /* Generate stmpe1600 Software reset */ + stmpe1600_Reset(DeviceAddr); + } + } +} + +/** + * @brief Configures the touch Screen Controller (Single point detection) + * @param DeviceAddr: Device address on communication Bus. + * @retval None. + */ +void stmpe1600_Start(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + /*Configuration already done during the initialization */ +} + +/** + * @brief Reset the stmpe1600 by Software. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe1600_Reset(uint16_t DeviceAddr) +{ + /* Power Down the stmpe1600 */ + IOE_Write(DeviceAddr, STMPE1600_REG_SYS_CTRL, (uint16_t)0x80); + + /* Wait for a delay to ensure registers erasing */ + IOE_Delay(2); + + /* Power On the Codec after the power off: all registers are reinitialized */ + IOE_Write(DeviceAddr, STMPE1600_REG_SYS_CTRL, (uint16_t)0x00); + + /* Wait for a delay to ensure registers erasing */ + IOE_Delay(2); +} + +/** + * @brief Read the stmpe1600 device ID. + * @param DeviceAddr: Device address on communication Bus. + * @retval The Device ID (two bytes). + */ +uint16_t stmpe1600_ReadID(uint16_t DeviceAddr) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Initialize IO BUS layer */ + IOE_Init(); + + /* Read the stmpe1600 device ID */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_CHP_ID, tmpData, 2); + + /* Return the device ID value */ + return((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); +} + +/** + * @brief Set the global interrupt Polarity. + * @param DeviceAddr: Device address on communication Bus. + * @param Polarity: could be one of these values; + * @arg STMPE1600_POLARITY_LOW: Interrupt line is active Low/Falling edge + * @arg STMPE1600_POLARITY_HIGH: Interrupt line is active High/Rising edge + * @retval None + */ +void stmpe1600_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity) +{ + uint8_t tmp = 0; + + /* Get the current register value */ + tmp = IOE_Read(DeviceAddr, STMPE1600_REG_SYS_CTRL); + + /* Mask the polarity bit */ + tmp &= ~(uint16_t)0x01; + + /* Set the Interrupt Output line polarity */ + tmp |= (uint8_t)Polarity; + + /* Set the new register value */ + IOE_Write(DeviceAddr, STMPE1600_REG_SYS_CTRL, tmp); +} + +/** + * @brief Enable the Global interrupt. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe1600_EnableGlobalIT(uint16_t DeviceAddr) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Configure NVIC IT for IOE */ + IOE_ITConfig(); + + /* Get the current register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_SYS_CTRL, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Set the global interrupts to be Enabled */ + tmp |= (uint16_t)STMPE1600_IT_ENABLE; + + /* Write Back the Interrupt Control register */ + IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_SYS_CTRL, (uint8_t *)&tmp, 2); +} + +/** + * @brief Disable the Global interrupt. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe1600_DisableGlobalIT(uint16_t DeviceAddr) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the current register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_SYS_CTRL, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Set the global interrupts to be Enabled */ + tmp &= ~(uint16_t)STMPE1600_IT_ENABLE; + + /* Write Back the Interrupt Control register */ + IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_SYS_CTRL, (uint8_t *)&tmp, 2); +} + +/** + * @brief Initialize the selected pin(s) direction. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be configured. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @param Direction: could be STMPE1600_DIRECTION_IN or STMPE1600_DIRECTION_OUT. + * @retval None + */ +void stmpe1600_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the current register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPDR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Set the Pin direction */ + if (Direction != STMPE1600_DIRECTION_IN) + { + tmp |= (uint16_t)IO_Pin; + } + else + { + tmp &= ~(uint16_t)IO_Pin; + } + + /* Set the new register value */ + IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_GPDR, (uint8_t *)&tmp, 2); +} + +/** + * @brief Configure the IO pin(s) according to IO mode structure value. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The output pin to be set or reset. This parameter can be one + * of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 7. + * @param IO_Mode: The IO pin mode to configure, could be one of the following values: + * @arg IO_MODE_INPUT + * @arg IO_MODE_OUTPUT + * @arg IO_MODE_IT_RISING_EDGE + * @arg IO_MODE_IT_FALLING_EDGE + * @retval 0 if no error, IO_Mode if error + */ +uint8_t stmpe1600_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode) +{ + uint8_t error_code = 0; + uint8_t buffer[2] = {0,0}; + + /* Configure IO pin according to selected IO mode */ + switch(IO_Mode) + { + case IO_MODE_INPUT: /* Input mode */ + stmpe1600_IO_DisablePinIT(DeviceAddr, IO_Pin); + stmpe1600_IO_InitPin(DeviceAddr, IO_Pin, STMPE1600_DIRECTION_IN); + break; + + case IO_MODE_OUTPUT: /* Output mode */ + stmpe1600_IO_DisablePinIT(DeviceAddr, IO_Pin); + stmpe1600_IO_InitPin(DeviceAddr, IO_Pin, STMPE1600_DIRECTION_OUT); + break; + + case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */ + stmpe1600_SetITPolarity(DeviceAddr, STMPE1600_POLARITY_HIGH); + stmpe1600_IO_EnablePinIT(DeviceAddr, IO_Pin); + stmpe1600_IO_InitPin(DeviceAddr, IO_Pin, STMPE1600_DIRECTION_IN); + /* Clear all IO IT pending bits if any */ + stmpe1600_IO_ClearIT(DeviceAddr, IO_Pin); + + /* Read GMPR to enable interrupt */ + IOE_ReadMultiple(DeviceAddr , STMPE1600_REG_GPMR, buffer, 2); + break; + + case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */ + stmpe1600_SetITPolarity(DeviceAddr, STMPE1600_POLARITY_LOW); + stmpe1600_IO_EnablePinIT(DeviceAddr, IO_Pin); + stmpe1600_IO_InitPin(DeviceAddr, IO_Pin, STMPE1600_DIRECTION_IN); + + /* Clear all IO IT pending bits if any */ + stmpe1600_IO_ClearIT(DeviceAddr, IO_Pin); + + /* Read GMPR to enable interrupt */ + IOE_ReadMultiple(DeviceAddr , STMPE1600_REG_GPMR, buffer, 2); + break; + + default: + error_code = (uint8_t) IO_Mode; + break; + } + return error_code; +} + +/** + * @brief Enable polarity inversion of the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be configured. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @retval None + */ +void stmpe1600_IO_PolarityInv_Enable(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the current register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPPIR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Enable pin polarity inversion */ + tmp |= (uint16_t)IO_Pin; + + /* Set the new register value */ + IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_GPPIR, (uint8_t *)&tmp, 2); +} + +/** + * @brief Disable polarity inversion of the selected IO pins. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be configured. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @retval None + */ +void stmpe1600_IO_PolarityInv_Disable(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the current register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPPIR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Disable pin polarity inversion */ + tmp &= ~ (uint16_t)IO_Pin; + + /* Set the new register value */ + IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_GPPIR, (uint8_t *)&tmp, 2); +} + +/** + * @brief Set the value of the selected IO pins. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be set. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @param PinState: The value to be set. + * @retval None + */ +void stmpe1600_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the current register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPMR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Set the pin state */ + if(PinState != 0) + { + tmp |= (uint16_t)IO_Pin; + } + else + { + tmp &= ~(uint16_t)IO_Pin; + } + + /* Set the new register value */ + IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_GPSR, (uint8_t *)&tmp, 2); +} + +/** + * @brief Read the state of the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be read. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @retval State of the selected IO pin(s). + */ +uint32_t stmpe1600_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPMR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Return the pin(s) state */ + return(tmp & IO_Pin); +} + +/** + * @brief Enable the interrupt mode for the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be configured. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @retval None + */ +void stmpe1600_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Enable global interrupt */ + stmpe1600_EnableGlobalIT(DeviceAddr); + + /* Get the current register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_IEGPIOR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Put pin in IT mode */ + tmp |= (uint16_t)IO_Pin; + + /* Write the new register value */ + IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_IEGPIOR, (uint8_t *)&tmp, 2); +} + +/** + * @brief Disable the interrupt mode for the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be configured. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @retval None + */ +void stmpe1600_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the current register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_IEGPIOR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Disable the IT pin mode */ + tmp &= ~(uint16_t)IO_Pin; + + /* Set the new register value */ + IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_IEGPIOR, (uint8_t *)&tmp, 2); +} + +/** + * @brief Read the IT status of the selected IO pin(s) + * (clears all the pending bits if any). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be checked. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @retval IT Status of the selected IO pin(s). + */ +uint32_t stmpe1600_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_ISGPIOR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Return the pin IT status */ + return((tmp & IO_Pin) == IO_Pin); +} + +/** + * @brief Detect an IT pending bit from the selected IO pin(s). + * (clears all the pending bits if any). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: IO pin(s) to be checked. + * This parameter could be any combination of the following values: + * @arg STMPE1600_PIN_x: where x can be from 0 to 15. + * @retval IT pending bit detection status. + */ +uint8_t stmpe1600_IO_ReadIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the register value */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_ISGPIOR, tmpData, 2); + + tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8)); + + /* Return if there is an IT pending bit or not */ + return(tmp & IO_Pin); +} + +/** + * @brief Clear all the IT pending bits if any. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe1600_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmpData[2] = {0 , 0}; + + /* Get the register value to clear all pending bits */ + IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_ISGPIOR, tmpData, 2); +} + +/** + * @brief Check if the device instance of the selected address is already registered + * and return its index + * @param DeviceAddr: Device address on communication Bus. + * @retval Index of the device instance if registered, 0xFF if not. + */ +static uint8_t stmpe1600_GetInstance(uint16_t DeviceAddr) +{ + uint8_t idx = 0; + + /* Check all the registered instances */ + for(idx = 0; idx < STMPE1600_MAX_INSTANCE ; idx ++) + { + /* Return index if there is address match */ + if(stmpe1600[idx] == DeviceAddr) + { + return idx; + } + } + + return 0xFF; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/stmpe1600/stmpe1600.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,214 @@ +/** + ****************************************************************************** + * @file stmpe1600.h + * @author MCD Application Team + * @version V1.1.0 + * @date 10-February-2015 + * @brief This file contains all the functions prototypes for the + * stmpe1600.c IO expander driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STMPE1600_H +#define __STMPE1600_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/io.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @defgroup STMPE1600 + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup STMPE1600_Exported_Types + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup STMPE1600_Exported_Constants + * @{ + */ + +/** + * @brief STMPE1600 chip IDs + */ +#define STMPE1600_ID 0x1600 + +/** + * @brief Interrupt enable + */ +#define STMPE1600_IT_ENABLE 0x04 + +/** + * @brief Identification registers & System Control + */ +#define STMPE1600_REG_CHP_ID 0x00 +#define STMPE1600_REG_ID_VERSION 0x02 +#define STMPE1600_REG_SYS_CTRL 0x03 + +/** + * @brief IO Registers + */ + +#define STMPE1600_REG_GPMR 0x10 +#define STMPE1600_REG_GPSR 0x12 +#define STMPE1600_REG_GPDR 0x14 +#define STMPE1600_REG_GPPIR 0x16 + +/** + * @brief Interrupt Control registers + */ +#define STMPE1600_REG_IEGPIOR 0x08 +#define STMPE1600_REG_ISGPIOR 0x0A + +/** + * @brief IO Pins direction + */ +#define STMPE1600_DIRECTION_IN 0x00 +#define STMPE1600_DIRECTION_OUT 0x01 + +/** + * @brief IO IT polarity + */ +#define STMPE1600_POLARITY_LOW 0x00 +#define STMPE1600_POLARITY_HIGH 0x01 + +/** + * @brief IO Pins + */ +#define STMPE1600_PIN_0 0x0001 +#define STMPE1600_PIN_1 0x0002 +#define STMPE1600_PIN_2 0x0004 +#define STMPE1600_PIN_3 0x0008 +#define STMPE1600_PIN_4 0x0010 +#define STMPE1600_PIN_5 0x0020 +#define STMPE1600_PIN_6 0x0040 +#define STMPE1600_PIN_7 0x0080 +#define STMPE1600_PIN_8 0x0100 +#define STMPE1600_PIN_9 0x0200 +#define STMPE1600_PIN_10 0x0400 +#define STMPE1600_PIN_11 0x0800 +#define STMPE1600_PIN_12 0x1000 +#define STMPE1600_PIN_13 0x2000 +#define STMPE1600_PIN_14 0x4000 +#define STMPE1600_PIN_15 0x8000 +#define STMPE1600_PIN_ALL 0xFFFF + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup STMPE1600_Exported_Macros + * @{ + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup STMPE1600_Exported_Functions + * @{ + */ + +/** + * @brief STMPE1600 Control functions + */ +void stmpe1600_Init(uint16_t DeviceAddr); +void stmpe1600_Reset(uint16_t DeviceAddr); +uint16_t stmpe1600_ReadID(uint16_t DeviceAddr); +void stmpe1600_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity); +void stmpe1600_EnableGlobalIT(uint16_t DeviceAddr); +void stmpe1600_DisableGlobalIT(uint16_t DeviceAddr); + +/** + * @brief STMPE1600 IO functionalities functions + */ +void stmpe1600_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction); +uint8_t stmpe1600_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode); +void stmpe1600_IO_PolarityInv_Enable(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe1600_IO_PolarityInv_Disable(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe1600_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState); +uint32_t stmpe1600_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe1600_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe1600_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin); +uint32_t stmpe1600_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin); +uint8_t stmpe1600_IO_ReadIT(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe1600_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe1600_Start(uint16_t DeviceAddr, uint32_t IO_Pin); + +void IOE_Init(void); +void IOE_ITConfig (void); +void IOE_Delay(uint32_t delay); +void IOE_Write(uint8_t addr, uint8_t reg, uint8_t value); +uint8_t IOE_Read(uint8_t addr, uint8_t reg); +uint16_t IOE_ReadMultiple(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t length); +void IOE_WriteMultiple(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t length); + +/* STMPE1600 driver structure */ +extern IO_DrvTypeDef stmpe1600_io_drv; + + +#ifdef __cplusplus +} +#endif +#endif /* __STMPE1600_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/stmpe811/stmpe811.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,978 @@ +/** + ****************************************************************************** + * @file stmpe811.c + * @author MCD Application Team + * @version V2.0.0 + * @date 15-December-2014 + * @brief This file provides a set of functions needed to manage the STMPE811 + * IO Expander devices. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stmpe811.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @defgroup STMPE811 + * @{ + */ + +/** @defgroup STMPE811_Private_Types_Definitions + * @{ + */ + +/** @defgroup STMPE811_Private_Defines + * @{ + */ +#define STMPE811_MAX_INSTANCE 2 +/** + * @} + */ + +/** @defgroup STMPE811_Private_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup STMPE811_Private_Variables + * @{ + */ + +/* Touch screen driver structure initialization */ +TS_DrvTypeDef stmpe811_ts_drv = +{ + stmpe811_Init, + stmpe811_ReadID, + stmpe811_Reset, + stmpe811_TS_Start, + stmpe811_TS_DetectTouch, + stmpe811_TS_GetXY, + stmpe811_TS_EnableIT, + stmpe811_TS_ClearIT, + stmpe811_TS_ITStatus, + stmpe811_TS_DisableIT, +}; + +/* IO driver structure initialization */ +IO_DrvTypeDef stmpe811_io_drv = +{ + stmpe811_Init, + stmpe811_ReadID, + stmpe811_Reset, + stmpe811_IO_Start, + stmpe811_IO_Config, + stmpe811_IO_WritePin, + stmpe811_IO_ReadPin, + stmpe811_IO_EnableIT, + stmpe811_IO_DisableIT, + stmpe811_IO_ITStatus, + stmpe811_IO_ClearIT, +}; + +/* stmpe811 instances by address */ +uint8_t stmpe811[STMPE811_MAX_INSTANCE] = {0}; +/** + * @} + */ + +/** @defgroup STMPE811_Private_Function_Prototypes + * @{ + */ +static uint8_t stmpe811_GetInstance(uint16_t DeviceAddr); +/** + * @} + */ + +/** @defgroup STMPE811_Private_Functions + * @{ + */ + +/** + * @brief Initialize the stmpe811 and configure the needed hardware resources + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_Init(uint16_t DeviceAddr) +{ + uint8_t instance; + uint8_t empty; + + /* Check if device instance already exists */ + instance = stmpe811_GetInstance(DeviceAddr); + + /* To prevent double initialization */ + if(instance == 0xFF) + { + /* Look for empty instance */ + empty = stmpe811_GetInstance(0); + + if(empty < STMPE811_MAX_INSTANCE) + { + /* Register the current device instance */ + stmpe811[empty] = DeviceAddr; + + /* Initialize IO BUS layer */ + IOE_Init(); + + /* Generate stmpe811 Software reset */ + stmpe811_Reset(DeviceAddr); + } + } +} + +/** + * @brief Reset the stmpe811 by Software. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_Reset(uint16_t DeviceAddr) +{ + /* Power Down the stmpe811 */ + IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL1, 2); + + /* Wait for a delay to ensure registers erasing */ + IOE_Delay(10); + + /* Power On the Codec after the power off => all registers are reinitialized */ + IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL1, 0); + + /* Wait for a delay to ensure registers erasing */ + IOE_Delay(2); +} + +/** + * @brief Read the stmpe811 IO Expander device ID. + * @param DeviceAddr: Device address on communication Bus. + * @retval The Device ID (two bytes). + */ +uint16_t stmpe811_ReadID(uint16_t DeviceAddr) +{ + /* Initialize IO BUS layer */ + IOE_Init(); + + /* Return the device ID value */ + return ((IOE_Read(DeviceAddr, STMPE811_REG_CHP_ID_LSB) << 8) |\ + (IOE_Read(DeviceAddr, STMPE811_REG_CHP_ID_MSB))); +} + +/** + * @brief Enable the Global interrupt. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_EnableGlobalIT(uint16_t DeviceAddr) +{ + uint8_t tmp = 0; + + /* Read the Interrupt Control register */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL); + + /* Set the global interrupts to be Enabled */ + tmp |= (uint8_t)STMPE811_GIT_EN; + + /* Write Back the Interrupt Control register */ + IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp); +} + +/** + * @brief Disable the Global interrupt. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_DisableGlobalIT(uint16_t DeviceAddr) +{ + uint8_t tmp = 0; + + /* Read the Interrupt Control register */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL); + + /* Set the global interrupts to be Disabled */ + tmp &= ~(uint8_t)STMPE811_GIT_EN; + + /* Write Back the Interrupt Control register */ + IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp); + +} + +/** + * @brief Enable the interrupt mode for the selected IT source + * @param DeviceAddr: Device address on communication Bus. + * @param Source: The interrupt source to be configured, could be: + * @arg STMPE811_GIT_IO: IO interrupt + * @arg STMPE811_GIT_ADC : ADC interrupt + * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt + * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt + * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt + * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt + * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt + * @retval None + */ +void stmpe811_EnableITSource(uint16_t DeviceAddr, uint8_t Source) +{ + uint8_t tmp = 0; + + /* Get the current value of the INT_EN register */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_EN); + + /* Set the interrupts to be Enabled */ + tmp |= Source; + + /* Set the register */ + IOE_Write(DeviceAddr, STMPE811_REG_INT_EN, tmp); +} + +/** + * @brief Disable the interrupt mode for the selected IT source + * @param DeviceAddr: Device address on communication Bus. + * @param Source: The interrupt source to be configured, could be: + * @arg STMPE811_GIT_IO: IO interrupt + * @arg STMPE811_GIT_ADC : ADC interrupt + * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt + * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt + * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt + * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt + * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt + * @retval None + */ +void stmpe811_DisableITSource(uint16_t DeviceAddr, uint8_t Source) +{ + uint8_t tmp = 0; + + /* Get the current value of the INT_EN register */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_EN); + + /* Set the interrupts to be Enabled */ + tmp &= ~Source; + + /* Set the register */ + IOE_Write(DeviceAddr, STMPE811_REG_INT_EN, tmp); +} + +/** + * @brief Set the global interrupt Polarity. + * @param DeviceAddr: Device address on communication Bus. + * @param Polarity: the IT mode polarity, could be one of the following values: + * @arg STMPE811_POLARITY_LOW: Interrupt line is active Low/Falling edge + * @arg STMPE811_POLARITY_HIGH: Interrupt line is active High/Rising edge + * @retval None + */ +void stmpe811_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity) +{ + uint8_t tmp = 0; + + /* Get the current register value */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL); + + /* Mask the polarity bits */ + tmp &= ~(uint8_t)0x04; + + /* Modify the Interrupt Output line configuration */ + tmp |= Polarity; + + /* Set the new register value */ + IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp); + +} + +/** + * @brief Set the global interrupt Type. + * @param DeviceAddr: Device address on communication Bus. + * @param Type: Interrupt line activity type, could be one of the following values: + * @arg STMPE811_TYPE_LEVEL: Interrupt line is active in level model + * @arg STMPE811_TYPE_EDGE: Interrupt line is active in edge model + * @retval None + */ +void stmpe811_SetITType(uint16_t DeviceAddr, uint8_t Type) +{ + uint8_t tmp = 0; + + /* Get the current register value */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL); + + /* Mask the type bits */ + tmp &= ~(uint8_t)0x02; + + /* Modify the Interrupt Output line configuration */ + tmp |= Type; + + /* Set the new register value */ + IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp); + +} + +/** + * @brief Check the selected Global interrupt source pending bit + * @param DeviceAddr: Device address on communication Bus. + * @param Source: the Global interrupt source to be checked, could be: + * @arg STMPE811_GIT_IO: IO interrupt + * @arg STMPE811_GIT_ADC : ADC interrupt + * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt + * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt + * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt + * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt + * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt + * @retval The checked Global interrupt source status. + */ +uint8_t stmpe811_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source) +{ + /* Return the global IT source status */ + return((IOE_Read(DeviceAddr, STMPE811_REG_INT_STA) & Source) == Source); +} + +/** + * @brief Return the Global interrupts status + * @param DeviceAddr: Device address on communication Bus. + * @param Source: the Global interrupt source to be checked, could be: + * @arg STMPE811_GIT_IO: IO interrupt + * @arg STMPE811_GIT_ADC : ADC interrupt + * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt + * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt + * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt + * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt + * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt + * @retval The checked Global interrupt source status. + */ +uint8_t stmpe811_ReadGITStatus(uint16_t DeviceAddr, uint8_t Source) +{ + /* Return the global IT source status */ + return((IOE_Read(DeviceAddr, STMPE811_REG_INT_STA) & Source)); +} + +/** + * @brief Clear the selected Global interrupt pending bit(s) + * @param DeviceAddr: Device address on communication Bus. + * @param Source: the Global interrupt source to be cleared, could be any combination + * of the following values: + * @arg STMPE811_GIT_IO: IO interrupt + * @arg STMPE811_GIT_ADC : ADC interrupt + * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt + * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt + * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt + * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt + * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt + * @retval None + */ +void stmpe811_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source) +{ + /* Write 1 to the bits that have to be cleared */ + IOE_Write(DeviceAddr, STMPE811_REG_INT_STA, Source); +} + +/** + * @brief Start the IO functionality use and disable the AF for selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO pin(s) to put in AF. This parameter can be one + * of the following values: + * @arg STMPE811_PIN_x: where x can be from 0 to 7. + * @retval None + */ +void stmpe811_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t mode; + + /* Get the current register value */ + mode = IOE_Read(DeviceAddr, STMPE811_REG_SYS_CTRL2); + + /* Set the Functionalities to be Disabled */ + mode &= ~(STMPE811_IO_FCT | STMPE811_ADC_FCT); + + /* Write the new register value */ + IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode); + + /* Disable AF for the selected IO pin(s) */ + stmpe811_IO_DisableAF(DeviceAddr, (uint8_t)IO_Pin); +} + +/** + * @brief Configures the IO pin(s) according to IO mode structure value. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The output pin to be set or reset. This parameter can be one + * of the following values: + * @arg STMPE811_PIN_x: where x can be from 0 to 7. + * @param IO_Mode: The IO pin mode to configure, could be one of the following values: + * @arg IO_MODE_INPUT + * @arg IO_MODE_OUTPUT + * @arg IO_MODE_IT_RISING_EDGE + * @arg IO_MODE_IT_FALLING_EDGE + * @arg IO_MODE_IT_LOW_LEVEL + * @arg IO_MODE_IT_HIGH_LEVEL + * @retval 0 if no error, IO_Mode if error + */ +uint8_t stmpe811_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode) +{ + uint8_t error_code = 0; + + /* Configure IO pin according to selected IO mode */ + switch(IO_Mode) + { + case IO_MODE_INPUT: /* Input mode */ + stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); + break; + + case IO_MODE_OUTPUT: /* Output mode */ + stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_OUT); + break; + + case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */ + stmpe811_IO_EnableIT(DeviceAddr); + stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin); + stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); + stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_EDGE); + stmpe811_IO_SetEdgeMode(DeviceAddr, IO_Pin, STMPE811_EDGE_RISING); + break; + + case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */ + stmpe811_IO_EnableIT(DeviceAddr); + stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin); + stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); + stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_EDGE); + stmpe811_IO_SetEdgeMode(DeviceAddr, IO_Pin, STMPE811_EDGE_FALLING); + break; + + case IO_MODE_IT_LOW_LEVEL: /* Low level interrupt mode */ + stmpe811_IO_EnableIT(DeviceAddr); + stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin); + stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); + stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_LEVEL); + stmpe811_SetITPolarity(DeviceAddr, STMPE811_POLARITY_LOW); + break; + + case IO_MODE_IT_HIGH_LEVEL: /* High level interrupt mode */ + stmpe811_IO_EnableIT(DeviceAddr); + stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin); + stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); + stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_LEVEL); + stmpe811_SetITPolarity(DeviceAddr, STMPE811_POLARITY_HIGH); + break; + + default: + error_code = (uint8_t) IO_Mode; + break; + } + return error_code; +} + +/** + * @brief Initialize the selected IO pin direction. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO pin to be configured. This parameter could be any + * combination of the following values: + * @arg STMPE811_PIN_x: Where x can be from 0 to 7. + * @param Direction: could be STMPE811_DIRECTION_IN or STMPE811_DIRECTION_OUT. + * @retval None + */ +void stmpe811_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction) +{ + uint8_t tmp = 0; + + /* Get all the Pins direction */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_DIR); + + /* Set the selected pin direction */ + if (Direction != STMPE811_DIRECTION_IN) + { + tmp |= (uint8_t)IO_Pin; + } + else + { + tmp &= ~(uint8_t)IO_Pin; + } + + /* Write the register new value */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_DIR, tmp); +} + +/** + * @brief Disable the AF for the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO pin to be configured. This parameter could be any + * combination of the following values: + * @arg STMPE811_PIN_x: Where x can be from 0 to 7. + * @retval None + */ +void stmpe811_IO_DisableAF(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmp = 0; + + /* Get the current state of the IO_AF register */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_AF); + + /* Enable the selected pins alternate function */ + tmp |= (uint8_t)IO_Pin; + + /* Write back the new value in IO AF register */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_AF, tmp); + +} + +/** + * @brief Enable the AF for the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO pin to be configured. This parameter could be any + * combination of the following values: + * @arg STMPE811_PIN_x: Where x can be from 0 to 7. + * @retval None + */ +void stmpe811_IO_EnableAF(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmp = 0; + + /* Get the current register value */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_AF); + + /* Enable the selected pins alternate function */ + tmp &= ~(uint8_t)IO_Pin; + + /* Write back the new register value */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_AF, tmp); +} + +/** + * @brief Configure the Edge for which a transition is detectable for the + * selected pin. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO pin to be configured. This parameter could be any + * combination of the following values: + * @arg STMPE811_PIN_x: Where x can be from 0 to 7. + * @param Edge: The edge which will be detected. This parameter can be one or + * a combination of following values: STMPE811_EDGE_FALLING and STMPE811_EDGE_RISING . + * @retval None + */ +void stmpe811_IO_SetEdgeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Edge) +{ + uint8_t tmp1 = 0, tmp2 = 0; + + /* Get the current registers values */ + tmp1 = IOE_Read(DeviceAddr, STMPE811_REG_IO_FE); + tmp2 = IOE_Read(DeviceAddr, STMPE811_REG_IO_RE); + + /* Disable the Falling Edge */ + tmp1 &= ~(uint8_t)IO_Pin; + + /* Disable the Falling Edge */ + tmp2 &= ~(uint8_t)IO_Pin; + + /* Enable the Falling edge if selected */ + if (Edge & STMPE811_EDGE_FALLING) + { + tmp1 |= (uint8_t)IO_Pin; + } + + /* Enable the Rising edge if selected */ + if (Edge & STMPE811_EDGE_RISING) + { + tmp2 |= (uint8_t)IO_Pin; + } + + /* Write back the new registers values */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_FE, tmp1); + IOE_Write(DeviceAddr, STMPE811_REG_IO_RE, tmp2); +} + +/** + * @brief Write a new IO pin state. + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The output pin to be set or reset. This parameter can be one + * of the following values: + * @arg STMPE811_PIN_x: where x can be from 0 to 7. + * @param PinState: The new IO pin state. + * @retval None + */ +void stmpe811_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState) +{ + /* Apply the bit value to the selected pin */ + if (PinState != 0) + { + /* Set the register */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_SET_PIN, (uint8_t)IO_Pin); + } + else + { + /* Set the register */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_CLR_PIN, (uint8_t)IO_Pin); + } +} + +/** + * @brief Return the state of the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The output pin to be set or reset. This parameter can be one + * of the following values: + * @arg STMPE811_PIN_x: where x can be from 0 to 7. + * @retval IO pin(s) state. + */ +uint32_t stmpe811_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + return((uint32_t)(IOE_Read(DeviceAddr, STMPE811_REG_IO_MP_STA) & (uint8_t)IO_Pin)); +} + +/** + * @brief Enable the global IO interrupt source. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_IO_EnableIT(uint16_t DeviceAddr) +{ + IOE_ITConfig(); + + /* Enable global IO IT source */ + stmpe811_EnableITSource(DeviceAddr, STMPE811_GIT_IO); + + /* Enable global interrupt */ + stmpe811_EnableGlobalIT(DeviceAddr); +} + +/** + * @brief Disable the global IO interrupt source. + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_IO_DisableIT(uint16_t DeviceAddr) +{ + /* Disable the global interrupt */ + stmpe811_DisableGlobalIT(DeviceAddr); + + /* Disable global IO IT source */ + stmpe811_DisableITSource(DeviceAddr, STMPE811_GIT_IO); +} + +/** + * @brief Enable interrupt mode for the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO interrupt to be enabled. This parameter could be any + * combination of the following values: + * @arg STMPE811_PIN_x: where x can be from 0 to 7. + * @retval None + */ +void stmpe811_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmp = 0; + + /* Get the IO interrupt state */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_EN); + + /* Set the interrupts to be enabled */ + tmp |= (uint8_t)IO_Pin; + + /* Write the register new value */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_EN, tmp); +} + +/** + * @brief Disable interrupt mode for the selected IO pin(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO interrupt to be disabled. This parameter could be any + * combination of the following values: + * @arg STMPE811_PIN_x: where x can be from 0 to 7. + * @retval None + */ +void stmpe811_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + uint8_t tmp = 0; + + /* Get the IO interrupt state */ + tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_EN); + + /* Set the interrupts to be Disabled */ + tmp &= ~(uint8_t)IO_Pin; + + /* Write the register new value */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_EN, tmp); +} + +/** + * @brief Check the status of the selected IO interrupt pending bit + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: The IO interrupt to be checked could be: + * @arg STMPE811_PIN_x Where x can be from 0 to 7. + * @retval Status of the checked IO pin(s). + */ +uint32_t stmpe811_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + /* Get the Interrupt status */ + return(IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_STA) & (uint8_t)IO_Pin); +} + +/** + * @brief Clear the selected IO interrupt pending bit(s). + * @param DeviceAddr: Device address on communication Bus. + * @param IO_Pin: the IO interrupt to be cleared, could be: + * @arg STMPE811_PIN_x: Where x can be from 0 to 7. + * @retval None + */ +void stmpe811_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin) +{ + /* Clear the global IO IT pending bit */ + stmpe811_ClearGlobalIT(DeviceAddr, STMPE811_GIT_IO); + + /* Clear the IO IT pending bit(s) */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_STA, (uint8_t)IO_Pin); + + /* Clear the Edge detection pending bit*/ + IOE_Write(DeviceAddr, STMPE811_REG_IO_ED, (uint8_t)IO_Pin); + + /* Clear the Rising edge pending bit */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_RE, (uint8_t)IO_Pin); + + /* Clear the Falling edge pending bit */ + IOE_Write(DeviceAddr, STMPE811_REG_IO_FE, (uint8_t)IO_Pin); +} + +/** + * @brief Configures the touch Screen Controller (Single point detection) + * @param DeviceAddr: Device address on communication Bus. + * @retval None. + */ +void stmpe811_TS_Start(uint16_t DeviceAddr) +{ + uint8_t mode; + + /* Get the current register value */ + mode = IOE_Read(DeviceAddr, STMPE811_REG_SYS_CTRL2); + + /* Set the Functionalities to be Enabled */ + mode &= ~(STMPE811_IO_FCT); + + /* Write the new register value */ + IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode); + + /* Select TSC pins in TSC alternate mode */ + stmpe811_IO_EnableAF(DeviceAddr, STMPE811_TOUCH_IO_ALL); + + /* Set the Functionalities to be Enabled */ + mode &= ~(STMPE811_TS_FCT | STMPE811_ADC_FCT); + + /* Set the new register value */ + IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode); + + /* Select Sample Time, bit number and ADC Reference */ + IOE_Write(DeviceAddr, STMPE811_REG_ADC_CTRL1, 0x49); + + /* Wait for 2 ms */ + IOE_Delay(2); + + /* Select the ADC clock speed: 3.25 MHz */ + IOE_Write(DeviceAddr, STMPE811_REG_ADC_CTRL2, 0x01); + + /* Select 2 nF filter capacitor */ + /* Configuration: + - Touch average control : 4 samples + - Touch delay time : 500 uS + - Panel driver setting time: 500 uS + */ + IOE_Write(DeviceAddr, STMPE811_REG_TSC_CFG, 0x9A); + + /* Configure the Touch FIFO threshold: single point reading */ + IOE_Write(DeviceAddr, STMPE811_REG_FIFO_TH, 0x01); + + /* Clear the FIFO memory content. */ + IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01); + + /* Put the FIFO back into operation mode */ + IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00); + + /* Set the range and accuracy pf the pressure measurement (Z) : + - Fractional part :7 + - Whole part :1 + */ + IOE_Write(DeviceAddr, STMPE811_REG_TSC_FRACT_XYZ, 0x01); + + /* Set the driving capability (limit) of the device for TSC pins: 50mA */ + IOE_Write(DeviceAddr, STMPE811_REG_TSC_I_DRIVE, 0x01); + + /* Touch screen control configuration (enable TSC): + - No window tracking index + - XYZ acquisition mode + */ + IOE_Write(DeviceAddr, STMPE811_REG_TSC_CTRL, 0x01); + + /* Clear all the status pending bits if any */ + IOE_Write(DeviceAddr, STMPE811_REG_INT_STA, 0xFF); + + /* Wait for 2 ms delay */ + IOE_Delay(2); +} + +/** + * @brief Return if there is touch detected or not. + * @param DeviceAddr: Device address on communication Bus. + * @retval Touch detected state. + */ +uint8_t stmpe811_TS_DetectTouch(uint16_t DeviceAddr) +{ + uint8_t state; + uint8_t ret = 0; + + state = ((IOE_Read(DeviceAddr, STMPE811_REG_TSC_CTRL) & (uint8_t)STMPE811_TS_CTRL_STATUS) == (uint8_t)0x80); + + if(state > 0) + { + if(IOE_Read(DeviceAddr, STMPE811_REG_FIFO_SIZE) > 0) + { + ret = 1; + } + } + else + { + /* Reset FIFO */ + IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01); + /* Enable the FIFO again */ + IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00); + } + + return ret; +} + +/** + * @brief Get the touch screen X and Y positions values + * @param DeviceAddr: Device address on communication Bus. + * @param X: Pointer to X position value + * @param Y: Pointer to Y position value + * @retval None. + */ +void stmpe811_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y) +{ + uint8_t dataXYZ[4]; + uint32_t uldataXYZ; + + IOE_ReadMultiple(DeviceAddr, STMPE811_REG_TSC_DATA_NON_INC, dataXYZ, sizeof(dataXYZ)) ; + + /* Calculate positions values */ + uldataXYZ = (dataXYZ[0] << 24)|(dataXYZ[1] << 16)|(dataXYZ[2] << 8)|(dataXYZ[3] << 0); + *X = (uldataXYZ >> 20) & 0x00000FFF; + *Y = (uldataXYZ >> 8) & 0x00000FFF; + + /* Reset FIFO */ + IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01); + /* Enable the FIFO again */ + IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00); +} + +/** + * @brief Configure the selected source to generate a global interrupt or not + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_TS_EnableIT(uint16_t DeviceAddr) +{ + IOE_ITConfig(); + + /* Enable global TS IT source */ + stmpe811_EnableITSource(DeviceAddr, STMPE811_TS_IT); + + /* Enable global interrupt */ + stmpe811_EnableGlobalIT(DeviceAddr); +} + +/** + * @brief Configure the selected source to generate a global interrupt or not + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_TS_DisableIT(uint16_t DeviceAddr) +{ + /* Disable global interrupt */ + stmpe811_DisableGlobalIT(DeviceAddr); + + /* Disable global TS IT source */ + stmpe811_DisableITSource(DeviceAddr, STMPE811_TS_IT); +} + +/** + * @brief Configure the selected source to generate a global interrupt or not + * @param DeviceAddr: Device address on communication Bus. + * @retval TS interrupts status + */ +uint8_t stmpe811_TS_ITStatus(uint16_t DeviceAddr) +{ + /* Return TS interrupts status */ + return(stmpe811_ReadGITStatus(DeviceAddr, STMPE811_TS_IT)); +} + +/** + * @brief Configure the selected source to generate a global interrupt or not + * @param DeviceAddr: Device address on communication Bus. + * @retval None + */ +void stmpe811_TS_ClearIT(uint16_t DeviceAddr) +{ + /* Clear the global TS IT source */ + stmpe811_ClearGlobalIT(DeviceAddr, STMPE811_TS_IT); +} + +/** + * @brief Check if the device instance of the selected address is already registered + * and return its index + * @param DeviceAddr: Device address on communication Bus. + * @retval Index of the device instance if registered, 0xFF if not. + */ +static uint8_t stmpe811_GetInstance(uint16_t DeviceAddr) +{ + uint8_t idx = 0; + + /* Check all the registered instances */ + for(idx = 0; idx < STMPE811_MAX_INSTANCE ; idx ++) + { + if(stmpe811[idx] == DeviceAddr) + { + return idx; + } + } + + return 0xFF; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/stmpe811/stmpe811.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,292 @@ +/** + ****************************************************************************** + * @file stmpe811.h + * @author MCD Application Team + * @version V2.0.0 + * @date 15-December-2014 + * @brief This file contains all the functions prototypes for the + * stmpe811.c IO expander driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STMPE811_H +#define __STMPE811_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/ts.h" +#include "../Common/io.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @defgroup STMPE811 + * @{ + */ + +/** @defgroup STMPE811_Exported_Types + * @{ + */ +/** + * @} + */ + +/** @defgroup STMPE811_Exported_Constants + * @{ + */ + +/* Chip IDs */ +#define STMPE811_ID 0x0811 + +/* Identification registers & System Control */ +#define STMPE811_REG_CHP_ID_LSB 0x00 +#define STMPE811_REG_CHP_ID_MSB 0x01 +#define STMPE811_REG_ID_VER 0x02 + +/* Global interrupt Enable bit */ +#define STMPE811_GIT_EN 0x01 + +/* IO expander functionalities */ +#define STMPE811_ADC_FCT 0x01 +#define STMPE811_TS_FCT 0x02 +#define STMPE811_IO_FCT 0x04 +#define STMPE811_TEMPSENS_FCT 0x08 + +/* Global Interrupts definitions */ +#define STMPE811_GIT_IO 0x80 /* IO interrupt */ +#define STMPE811_GIT_ADC 0x40 /* ADC interrupt */ +#define STMPE811_GIT_TEMP 0x20 /* Not implemented */ +#define STMPE811_GIT_FE 0x10 /* FIFO empty interrupt */ +#define STMPE811_GIT_FF 0x08 /* FIFO full interrupt */ +#define STMPE811_GIT_FOV 0x04 /* FIFO overflowed interrupt */ +#define STMPE811_GIT_FTH 0x02 /* FIFO above threshold interrupt */ +#define STMPE811_GIT_TOUCH 0x01 /* Touch is detected interrupt */ +#define STMPE811_ALL_GIT 0x1F /* All global interrupts */ +#define STMPE811_TS_IT (STMPE811_GIT_TOUCH | STMPE811_GIT_FTH | STMPE811_GIT_FOV | STMPE811_GIT_FF | STMPE811_GIT_FE) /* Touch screen interrupts */ + +/* General Control Registers */ +#define STMPE811_REG_SYS_CTRL1 0x03 +#define STMPE811_REG_SYS_CTRL2 0x04 +#define STMPE811_REG_SPI_CFG 0x08 + +/* Interrupt system Registers */ +#define STMPE811_REG_INT_CTRL 0x09 +#define STMPE811_REG_INT_EN 0x0A +#define STMPE811_REG_INT_STA 0x0B +#define STMPE811_REG_IO_INT_EN 0x0C +#define STMPE811_REG_IO_INT_STA 0x0D + +/* IO Registers */ +#define STMPE811_REG_IO_SET_PIN 0x10 +#define STMPE811_REG_IO_CLR_PIN 0x11 +#define STMPE811_REG_IO_MP_STA 0x12 +#define STMPE811_REG_IO_DIR 0x13 +#define STMPE811_REG_IO_ED 0x14 +#define STMPE811_REG_IO_RE 0x15 +#define STMPE811_REG_IO_FE 0x16 +#define STMPE811_REG_IO_AF 0x17 + +/* ADC Registers */ +#define STMPE811_REG_ADC_INT_EN 0x0E +#define STMPE811_REG_ADC_INT_STA 0x0F +#define STMPE811_REG_ADC_CTRL1 0x20 +#define STMPE811_REG_ADC_CTRL2 0x21 +#define STMPE811_REG_ADC_CAPT 0x22 +#define STMPE811_REG_ADC_DATA_CH0 0x30 +#define STMPE811_REG_ADC_DATA_CH1 0x32 +#define STMPE811_REG_ADC_DATA_CH2 0x34 +#define STMPE811_REG_ADC_DATA_CH3 0x36 +#define STMPE811_REG_ADC_DATA_CH4 0x38 +#define STMPE811_REG_ADC_DATA_CH5 0x3A +#define STMPE811_REG_ADC_DATA_CH6 0x3B +#define STMPE811_REG_ADC_DATA_CH7 0x3C + +/* Touch Screen Registers */ +#define STMPE811_REG_TSC_CTRL 0x40 +#define STMPE811_REG_TSC_CFG 0x41 +#define STMPE811_REG_WDM_TR_X 0x42 +#define STMPE811_REG_WDM_TR_Y 0x44 +#define STMPE811_REG_WDM_BL_X 0x46 +#define STMPE811_REG_WDM_BL_Y 0x48 +#define STMPE811_REG_FIFO_TH 0x4A +#define STMPE811_REG_FIFO_STA 0x4B +#define STMPE811_REG_FIFO_SIZE 0x4C +#define STMPE811_REG_TSC_DATA_X 0x4D +#define STMPE811_REG_TSC_DATA_Y 0x4F +#define STMPE811_REG_TSC_DATA_Z 0x51 +#define STMPE811_REG_TSC_DATA_XYZ 0x52 +#define STMPE811_REG_TSC_FRACT_XYZ 0x56 +#define STMPE811_REG_TSC_DATA_INC 0x57 +#define STMPE811_REG_TSC_DATA_NON_INC 0xD7 +#define STMPE811_REG_TSC_I_DRIVE 0x58 +#define STMPE811_REG_TSC_SHIELD 0x59 + +/* Touch Screen Pins definition */ +#define STMPE811_TOUCH_YD STMPE811_PIN_7 +#define STMPE811_TOUCH_XD STMPE811_PIN_6 +#define STMPE811_TOUCH_YU STMPE811_PIN_5 +#define STMPE811_TOUCH_XU STMPE811_PIN_4 +#define STMPE811_TOUCH_IO_ALL (uint32_t)(STMPE811_TOUCH_YD | STMPE811_TOUCH_XD | STMPE811_TOUCH_YU | STMPE811_TOUCH_XU) + +/* IO Pins definition */ +#define STMPE811_PIN_0 0x01 +#define STMPE811_PIN_1 0x02 +#define STMPE811_PIN_2 0x04 +#define STMPE811_PIN_3 0x08 +#define STMPE811_PIN_4 0x10 +#define STMPE811_PIN_5 0x20 +#define STMPE811_PIN_6 0x40 +#define STMPE811_PIN_7 0x80 +#define STMPE811_PIN_ALL 0xFF + +/* IO Pins directions */ +#define STMPE811_DIRECTION_IN 0x00 +#define STMPE811_DIRECTION_OUT 0x01 + +/* IO IT types */ +#define STMPE811_TYPE_LEVEL 0x00 +#define STMPE811_TYPE_EDGE 0x02 + +/* IO IT polarity */ +#define STMPE811_POLARITY_LOW 0x00 +#define STMPE811_POLARITY_HIGH 0x04 + +/* IO Pin IT edge modes */ +#define STMPE811_EDGE_FALLING 0x01 +#define STMPE811_EDGE_RISING 0x02 + +/* TS registers masks */ +#define STMPE811_TS_CTRL_ENABLE 0x01 +#define STMPE811_TS_CTRL_STATUS 0x80 +/** + * @} + */ + +/** @defgroup STMPE811_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup STMPE811_Exported_Functions + * @{ + */ + +/** + * @brief STMPE811 Control functions + */ +void stmpe811_Init(uint16_t DeviceAddr); +void stmpe811_Reset(uint16_t DeviceAddr); +uint16_t stmpe811_ReadID(uint16_t DeviceAddr); +void stmpe811_EnableGlobalIT(uint16_t DeviceAddr); +void stmpe811_DisableGlobalIT(uint16_t DeviceAddr); +void stmpe811_EnableITSource(uint16_t DeviceAddr, uint8_t Source); +void stmpe811_DisableITSource(uint16_t DeviceAddr, uint8_t Source); +void stmpe811_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity); +void stmpe811_SetITType(uint16_t DeviceAddr, uint8_t Type); +uint8_t stmpe811_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source); +uint8_t stmpe811_ReadGITStatus(uint16_t DeviceAddr, uint8_t Source); +void stmpe811_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source); + +/** + * @brief STMPE811 IO functionalities functions + */ +void stmpe811_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin); +uint8_t stmpe811_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode); +void stmpe811_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction); +void stmpe811_IO_EnableAF(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe811_IO_DisableAF(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe811_IO_SetEdgeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Edge); +void stmpe811_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState); +uint32_t stmpe811_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe811_IO_EnableIT(uint16_t DeviceAddr); +void stmpe811_IO_DisableIT(uint16_t DeviceAddr); +void stmpe811_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe811_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin); +uint32_t stmpe811_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin); +void stmpe811_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin); + +/** + * @brief STMPE811 Touch screen functionalities functions + */ +void stmpe811_TS_Start(uint16_t DeviceAddr); +uint8_t stmpe811_TS_DetectTouch(uint16_t DeviceAddr); +void stmpe811_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y); +void stmpe811_TS_EnableIT(uint16_t DeviceAddr); +void stmpe811_TS_DisableIT(uint16_t DeviceAddr); +uint8_t stmpe811_TS_ITStatus (uint16_t DeviceAddr); +void stmpe811_TS_ClearIT (uint16_t DeviceAddr); + +void IOE_Init(void); +void IOE_ITConfig (void); +void IOE_Delay(uint32_t delay); +void IOE_Write(uint8_t addr, uint8_t reg, uint8_t value); +uint8_t IOE_Read(uint8_t addr, uint8_t reg); +uint16_t IOE_ReadMultiple(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t length); + +/* Touch screen driver structure */ +extern TS_DrvTypeDef stmpe811_ts_drv; + +/* IO driver structure */ +extern IO_DrvTypeDef stmpe811_io_drv; + +#ifdef __cplusplus +} +#endif +#endif /* __STMPE811_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/wm8994/wm8994.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,925 @@ +/** + ****************************************************************************** + * @file wm8994.c + * @author MCD Application Team + * @version V2.0.0 + * @date 24-June-2015 + * @brief This file provides the WM8994 Audio Codec driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "wm8994.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup wm8994 + * @brief This file provides a set of functions needed to drive the + * WM8994 audio codec. + * @{ + */ + +/** @defgroup WM8994_Private_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup WM8994_Private_Defines + * @{ + */ +/* Uncomment this line to enable verifying data sent to codec after each write + operation (for debug purpose) */ +#if !defined (VERIFY_WRITTENDATA) +/* #define VERIFY_WRITTENDATA */ +#endif /* VERIFY_WRITTENDATA */ +/** + * @} + */ + +/** @defgroup WM8994_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup WM8994_Private_Variables + * @{ + */ + +/* Audio codec driver structure initialization */ +AUDIO_DrvTypeDef wm8994_drv = +{ + wm8994_Init, + wm8994_DeInit, + wm8994_ReadID, + + wm8994_Play, + wm8994_Pause, + wm8994_Resume, + wm8994_Stop, + + wm8994_SetFrequency, + wm8994_SetVolume, + wm8994_SetMute, + wm8994_SetOutputMode, + + wm8994_Reset +}; + +static uint32_t outputEnabled = 0; +static uint32_t inputEnabled = 0; +/** + * @} + */ + +/** @defgroup WM8994_Function_Prototypes + * @{ + */ +static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value); +/** + * @} + */ + +/** @defgroup WM8994_Private_Functions + * @{ + */ + +/** + * @brief Initializes the audio codec and the control interface. + * @param DeviceAddr: Device address on communication Bus. + * @param OutputInputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, + * OUTPUT_DEVICE_BOTH, OUTPUT_DEVICE_AUTO, INPUT_DEVICE_DIGITAL_MICROPHONE_1, + * INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_INPUT_LINE_1 or INPUT_DEVICE_INPUT_LINE_2. + * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) + * @param AudioFreq: Audio Frequency + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq) +{ + uint32_t counter = 0; + uint16_t output_device = OutputInputDevice & 0xFF; + uint16_t input_device = OutputInputDevice & 0xFF00; + uint16_t power_mgnt_reg_1 = 0; + + /* Initialize the Control interface of the Audio Codec */ + AUDIO_IO_Init(); + /* wm8994 Errata Work-Arounds */ + counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0003); + counter += CODEC_IO_Write(DeviceAddr, 0x817, 0x0000); + counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0000); + + /* Enable VMID soft start (fast), Start-up Bias Current Enabled */ + counter += CODEC_IO_Write(DeviceAddr, 0x39, 0x006C); + + /* Enable bias generator, Enable VMID */ + counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0003); + + /* Add Delay */ + AUDIO_IO_Delay(50); + + /* Path Configurations for output */ + if (output_device > 0) + { + outputEnabled = 1; + switch (output_device) + { + case OUTPUT_DEVICE_SPEAKER: + /* Enable DAC1 (Left), Enable DAC1 (Right), + Disable DAC2 (Left), Disable DAC2 (Right)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C); + + /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000); + + /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000); + + /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002); + + /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002); + break; + + case OUTPUT_DEVICE_HEADPHONE: + /* Disable DAC1 (Left), Disable DAC1 (Right), + Enable DAC2 (Left), Enable DAC2 (Right)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303); + + /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001); + + /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001); + + /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000); + + /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000); + break; + + case OUTPUT_DEVICE_BOTH: + /* Enable DAC1 (Left), Enable DAC1 (Right), + also Enable DAC2 (Left), Enable DAC2 (Right)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C); + + /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001); + + /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001); + + /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002); + + /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002); + break; + + case OUTPUT_DEVICE_AUTO : + default: + /* Disable DAC1 (Left), Disable DAC1 (Right), + Enable DAC2 (Left), Enable DAC2 (Right)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303); + + /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001); + + /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001); + + /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000); + + /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000); + break; + } + } + else + { + outputEnabled = 0; + } + + /* Path Configurations for input */ + if (input_device > 0) + { + inputEnabled = 1; + switch (input_device) + { + case INPUT_DEVICE_DIGITAL_MICROPHONE_2 : + /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right) + * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right) + * Enable Left ADC, Enable Right ADC */ + counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0C30); + + /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */ + counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB); + + /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */ + counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6000); + + /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002); + + /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002); + + /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */ + counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000E); + break; + + case INPUT_DEVICE_INPUT_LINE_1 : + /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right) + * Enable Left ADC, Enable Right ADC */ + counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0303); + + /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */ + counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB); + + /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */ + counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350); + + /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002); + + /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002); + + /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */ + counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D); + break; + + case INPUT_DEVICE_DIGITAL_MICROPHONE_1 : + case INPUT_DEVICE_INPUT_LINE_2 : + default: + /* Actually, no other input devices supported */ + counter++; + break; + } + } + else + { + inputEnabled = 0; + } + + /* Clock Configurations */ + switch (AudioFreq) + { + case AUDIO_FREQUENCY_8K: + /* AIF1 Sample Rate = 8 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003); + break; + + case AUDIO_FREQUENCY_16K: + /* AIF1 Sample Rate = 16 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033); + break; + + case AUDIO_FREQUENCY_48K: + /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083); + break; + + case AUDIO_FREQUENCY_96K: + /* AIF1 Sample Rate = 96 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3); + break; + + case AUDIO_FREQUENCY_11K: + /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013); + break; + + case AUDIO_FREQUENCY_22K: + /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043); + break; + + case AUDIO_FREQUENCY_44K: + /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073); + break; + + default: + /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083); + break; + } + /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */ + counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4010); + + /* slave mode */ + counter += CODEC_IO_Write(DeviceAddr, 0x302, 0x0000); + + /* Enable the DSP processing clock for AIF1, Enable the core clock */ + counter += CODEC_IO_Write(DeviceAddr, 0x208, 0x000A); + + /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */ + counter += CODEC_IO_Write(DeviceAddr, 0x200, 0x0001); + + if (output_device > 0) /* Audio output selected */ + { + /* Analog Output Configuration */ + + /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */ + counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0300); + + /* Left Speaker Mixer Volume = 0dB */ + counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000); + + /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0000); + + /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path, + Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */ + counter += CODEC_IO_Write(DeviceAddr, 0x36, 0x0300); + + /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */ + counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x3003); + + /* Headphone/Speaker Enable */ + + /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */ + counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0005); + + /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */ + /* idem for Speaker */ + power_mgnt_reg_1 |= 0x0303 | 0x3003; + counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1); + + /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */ + counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x0022); + + /* Enable Charge Pump */ + counter += CODEC_IO_Write(DeviceAddr, 0x4C, 0x9F25); + + /* Add Delay */ + AUDIO_IO_Delay(15); + + /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */ + counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0001); + + /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */ + counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0001); + + /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */ + /* idem for SPKOUTL and SPKOUTR */ + counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0030 | 0x0300); + + /* Enable DC Servo and trigger start-up mode on left and right channels */ + counter += CODEC_IO_Write(DeviceAddr, 0x54, 0x0033); + + /* Add Delay */ + AUDIO_IO_Delay(250); + + /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */ + counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x00EE); + + /* Unmutes */ + + /* Unmute DAC 1 (Left) */ + counter += CODEC_IO_Write(DeviceAddr, 0x610, 0x00C0); + + /* Unmute DAC 1 (Right) */ + counter += CODEC_IO_Write(DeviceAddr, 0x611, 0x00C0); + + /* Unmute the AIF1 Timeslot 0 DAC path */ + counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000); + + /* Unmute DAC 2 (Left) */ + counter += CODEC_IO_Write(DeviceAddr, 0x612, 0x00C0); + + /* Unmute DAC 2 (Right) */ + counter += CODEC_IO_Write(DeviceAddr, 0x613, 0x00C0); + + /* Unmute the AIF1 Timeslot 1 DAC2 path */ + counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000); + + /* Volume Control */ + wm8994_SetVolume(DeviceAddr, Volume); + } + + if (input_device > 0) /* Audio input selected */ + { + if ((input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_2)) + { + /* Enable Microphone bias 1 generator, Enable VMID */ + power_mgnt_reg_1 |= 0x0013; + counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1); + + /* ADC oversample enable */ + counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002); + + /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */ + counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x3800); + } + else if ((input_device == INPUT_DEVICE_INPUT_LINE_1) || (input_device == INPUT_DEVICE_INPUT_LINE_2)) + { + /* Enable normal bias generator, Enable VMID */ + power_mgnt_reg_1 |= 0x0003; + counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1); + + /* Disable mute on IN1L, IN1L Volume = +0dB */ + counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x000B); + + /* Disable mute on IN1R, IN1R Volume = +0dB */ + counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x000B); + + /* Disable mute on IN1L_TO_MIXINL, Gain = +0dB */ + counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0025); + + /* Disable mute on IN1R_TO_MIXINL, Gain = +0dB */ + counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0025); + + /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */ + counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011); + + /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */ + counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800); + } + /* Volume Control */ + wm8994_SetVolume(DeviceAddr, Volume); + } + /* Return communication control value */ + return counter; +} + +/** + * @brief Deinitializes the audio codec. + * @param None + * @retval None + */ +void wm8994_DeInit(void) +{ + /* Deinitialize Audio Codec interface */ + AUDIO_IO_DeInit(); +} + +/** + * @brief Get the WM8994 ID. + * @param DeviceAddr: Device address on communication Bus. + * @retval The WM8994 ID + */ +uint32_t wm8994_ReadID(uint16_t DeviceAddr) +{ + /* Initialize the Control interface of the Audio Codec */ + AUDIO_IO_Init(); + + return ((uint32_t)AUDIO_IO_Read(DeviceAddr, WM8994_CHIPID_ADDR)); +} + +/** + * @brief Start the audio Codec play feature. + * @note For this codec no Play options are required. + * @param DeviceAddr: Device address on communication Bus. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size) +{ + uint32_t counter = 0; + + /* Resumes the audio file playing */ + /* Unmute the output first */ + counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF); + + return counter; +} + +/** + * @brief Pauses playing on the audio codec. + * @param DeviceAddr: Device address on communication Bus. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_Pause(uint16_t DeviceAddr) +{ + uint32_t counter = 0; + + /* Pause the audio file playing */ + /* Mute the output first */ + counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON); + + /* Put the Codec in Power save mode */ + counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01); + + return counter; +} + +/** + * @brief Resumes playing on the audio codec. + * @param DeviceAddr: Device address on communication Bus. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_Resume(uint16_t DeviceAddr) +{ + uint32_t counter = 0; + + /* Resumes the audio file playing */ + /* Unmute the output first */ + counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF); + + return counter; +} + +/** + * @brief Stops audio Codec playing. It powers down the codec. + * @param DeviceAddr: Device address on communication Bus. + * @param CodecPdwnMode: selects the power down mode. + * - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this + * mode the codec keeps the previous initialization + * (no need to re-Initialize the codec registers). + * - CODEC_PDWN_HW: Physically power down the codec. When resuming from this + * mode, the codec is set to default configuration + * (user should re-Initialize the codec in order to + * play again the audio stream). + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode) +{ + uint32_t counter = 0; + + if (outputEnabled != 0) + { + /* Mute the output first */ + counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON); + + if (CodecPdwnMode == CODEC_PDWN_SW) + { + /* Only output mute required*/ + } + else /* CODEC_PDWN_HW */ + { + /* Mute the AIF1 Timeslot 0 DAC1 path */ + counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200); + + /* Mute the AIF1 Timeslot 1 DAC2 path */ + counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200); + + /* Disable DAC1L_TO_HPOUT1L */ + counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0000); + + /* Disable DAC1R_TO_HPOUT1R */ + counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0000); + + /* Disable DAC1 and DAC2 */ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0000); + + /* Reset Codec by writing in 0x0000 address register */ + counter += CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000); + + outputEnabled = 0; + } + } + return counter; +} + +/** + * @brief Sets higher or lower the codec volume level. + * @param DeviceAddr: Device address on communication Bus. + * @param Volume: a byte value from 0 to 255 (refer to codec registers + * description for more details). + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume) +{ + uint32_t counter = 0; + uint8_t convertedvol = VOLUME_CONVERT(Volume); + + /* Output volume */ + if (outputEnabled != 0) + { + if(convertedvol > 0x3E) + { + /* Unmute audio codec */ + counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF); + + /* Left Headphone Volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x1C, 0x3F | 0x140); + + /* Right Headphone Volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x1D, 0x3F | 0x140); + + /* Left Speaker Volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x26, 0x3F | 0x140); + + /* Right Speaker Volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x3F | 0x140); + } + else if (Volume == 0) + { + /* Mute audio codec */ + counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON); + } + else + { + /* Unmute audio codec */ + counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF); + + /* Left Headphone Volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x1C, convertedvol | 0x140); + + /* Right Headphone Volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x1D, convertedvol | 0x140); + + /* Left Speaker Volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x26, convertedvol | 0x140); + + /* Right Speaker Volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x27, convertedvol | 0x140); + } + } + + /* Input volume */ + if (inputEnabled != 0) + { + convertedvol = VOLUME_IN_CONVERT(Volume); + + /* Left AIF1 ADC1 volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x400, convertedvol | 0x100); + + /* Right AIF1 ADC1 volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x401, convertedvol | 0x100); + + /* Left AIF1 ADC2 volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x404, convertedvol | 0x100); + + /* Right AIF1 ADC2 volume */ + counter += CODEC_IO_Write(DeviceAddr, 0x405, convertedvol | 0x100); + } + return counter; +} + +/** + * @brief Enables or disables the mute feature on the audio codec. + * @param DeviceAddr: Device address on communication Bus. + * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the + * mute mode. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd) +{ + uint32_t counter = 0; + + if (outputEnabled != 0) + { + /* Set the Mute mode */ + if(Cmd == AUDIO_MUTE_ON) + { + /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */ + counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200); + + /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */ + counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200); + } + else /* AUDIO_MUTE_OFF Disable the Mute */ + { + /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */ + counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000); + + /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */ + counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000); + } + } + return counter; +} + +/** + * @brief Switch dynamically (while audio file is played) the output target + * (speaker or headphone). + * @param DeviceAddr: Device address on communication Bus. + * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER, + * OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output) +{ + uint32_t counter = 0; + + switch (Output) + { + case OUTPUT_DEVICE_SPEAKER: + /* Enable DAC1 (Left), Enable DAC1 (Right), + Disable DAC2 (Left), Disable DAC2 (Right)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C); + + /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000); + + /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000); + + /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002); + + /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002); + break; + + case OUTPUT_DEVICE_HEADPHONE: + /* Disable DAC1 (Left), Disable DAC1 (Right), + Enable DAC2 (Left), Enable DAC2 (Right)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303); + + /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001); + + /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001); + + /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000); + + /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000); + break; + + case OUTPUT_DEVICE_BOTH: + /* Enable DAC1 (Left), Enable DAC1 (Right), + also Enable DAC2 (Left), Enable DAC2 (Right)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C); + + /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001); + + /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001); + + /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002); + + /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002); + break; + + default: + /* Disable DAC1 (Left), Disable DAC1 (Right), + Enable DAC2 (Left), Enable DAC2 (Right)*/ + counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303); + + /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001); + + /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001); + + /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000); + + /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */ + counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000); + break; + } + return counter; +} + +/** + * @brief Sets new frequency. + * @param DeviceAddr: Device address on communication Bus. + * @param AudioFreq: Audio frequency used to play the audio stream. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq) +{ + uint32_t counter = 0; + + /* Clock Configurations */ + switch (AudioFreq) + { + case AUDIO_FREQUENCY_8K: + /* AIF1 Sample Rate = 8 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003); + break; + + case AUDIO_FREQUENCY_16K: + /* AIF1 Sample Rate = 16 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033); + break; + + case AUDIO_FREQUENCY_48K: + /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083); + break; + + case AUDIO_FREQUENCY_96K: + /* AIF1 Sample Rate = 96 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3); + break; + + case AUDIO_FREQUENCY_11K: + /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013); + break; + + case AUDIO_FREQUENCY_22K: + /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043); + break; + + case AUDIO_FREQUENCY_44K: + /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073); + break; + + default: + /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ + counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083); + break; + } + return counter; +} + +/** + * @brief Resets wm8994 registers. + * @param DeviceAddr: Device address on communication Bus. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t wm8994_Reset(uint16_t DeviceAddr) +{ + uint32_t counter = 0; + + /* Reset Codec by writing in 0x0000 address register */ + counter = CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000); + outputEnabled = 0; + inputEnabled=0; + + return counter; +} + +/** + * @brief Writes/Read a single data. + * @param Addr: I2C address + * @param Reg: Reg address + * @param Value: Data to be written + * @retval None + */ +static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value) +{ + uint32_t result = 0; + + AUDIO_IO_Write(Addr, Reg, Value); + +#ifdef VERIFY_WRITTENDATA + /* Verify that the data has been correctly written */ + result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1; +#endif /* VERIFY_WRITTENDATA */ + + return result; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Components/wm8994/wm8994.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,188 @@ +/** + ****************************************************************************** + * @file wm8994.h + * @author MCD Application Team + * @version V2.0.0 + * @date 24-June-2015 + * @brief This file contains all the functions prototypes for the + * wm8994.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __WM8994_H +#define __WM8994_H + +/* Includes ------------------------------------------------------------------*/ +#include "../Common/audio.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @addtogroup WM8994 + * @{ + */ + +/** @defgroup WM8994_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup WM8994_Exported_Constants + * @{ + */ + +/******************************************************************************/ +/*************************** Codec User defines ******************************/ +/******************************************************************************/ +/* Codec output DEVICE */ +#define OUTPUT_DEVICE_SPEAKER ((uint16_t)0x0001) +#define OUTPUT_DEVICE_HEADPHONE ((uint16_t)0x0002) +#define OUTPUT_DEVICE_BOTH ((uint16_t)0x0003) +#define OUTPUT_DEVICE_AUTO ((uint16_t)0x0004) +#define INPUT_DEVICE_DIGITAL_MICROPHONE_1 ((uint16_t)0x0100) +#define INPUT_DEVICE_DIGITAL_MICROPHONE_2 ((uint16_t)0x0200) +#define INPUT_DEVICE_INPUT_LINE_1 ((uint16_t)0x0300) +#define INPUT_DEVICE_INPUT_LINE_2 ((uint16_t)0x0400) + +/* Volume Levels values */ +#define DEFAULT_VOLMIN 0x00 +#define DEFAULT_VOLMAX 0xFF +#define DEFAULT_VOLSTEP 0x04 + +#define AUDIO_PAUSE 0 +#define AUDIO_RESUME 1 + +/* Codec POWER DOWN modes */ +#define CODEC_PDWN_HW 1 +#define CODEC_PDWN_SW 2 + +/* MUTE commands */ +#define AUDIO_MUTE_ON 1 +#define AUDIO_MUTE_OFF 0 + +/* AUDIO FREQUENCY */ +#define AUDIO_FREQUENCY_192K ((uint32_t)192000) +#define AUDIO_FREQUENCY_96K ((uint32_t)96000) +#define AUDIO_FREQUENCY_48K ((uint32_t)48000) +#define AUDIO_FREQUENCY_44K ((uint32_t)44100) +#define AUDIO_FREQUENCY_32K ((uint32_t)32000) +#define AUDIO_FREQUENCY_22K ((uint32_t)22050) +#define AUDIO_FREQUENCY_16K ((uint32_t)16000) +#define AUDIO_FREQUENCY_11K ((uint32_t)11025) +#define AUDIO_FREQUENCY_8K ((uint32_t)8000) + +#define VOLUME_CONVERT(Volume) (((Volume) > 100)? 100:((uint8_t)(((Volume) * 63) / 100))) +#define VOLUME_IN_CONVERT(Volume) (((Volume) >= 100)? 239:((uint8_t)(((Volume) * 240) / 100))) + +/******************************************************************************/ +/****************************** REGISTER MAPPING ******************************/ +/******************************************************************************/ +/** + * @brief WM8994 ID + */ +#define WM8994_ID 0x8994 + +/** + * @brief Device ID Register: Reading from this register will indicate device + * family ID 8994h + */ +#define WM8994_CHIPID_ADDR 0x00 + +/** + * @} + */ + +/** @defgroup WM8994_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup WM8994_Exported_Functions + * @{ + */ + +/*------------------------------------------------------------------------------ + Audio Codec functions +------------------------------------------------------------------------------*/ +/* High Layer codec functions */ +uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq); +void wm8994_DeInit(void); +uint32_t wm8994_ReadID(uint16_t DeviceAddr); +uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size); +uint32_t wm8994_Pause(uint16_t DeviceAddr); +uint32_t wm8994_Resume(uint16_t DeviceAddr); +uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t Cmd); +uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume); +uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd); +uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output); +uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq); +uint32_t wm8994_Reset(uint16_t DeviceAddr); + +/* AUDIO IO functions */ +void AUDIO_IO_Init(void); +void AUDIO_IO_DeInit(void); +void AUDIO_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value); +uint8_t AUDIO_IO_Read(uint8_t Addr, uint16_t Reg); +void AUDIO_IO_Delay(uint32_t Delay); + +/* Audio driver structure */ +extern AUDIO_DrvTypeDef wm8994_drv; + +#endif /* __WM8994_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,1771 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery.c + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file provides a set of firmware functions to manage Leds, + * push-button and joystick of STM32L476G-Discovery board (MB1184) + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery.h" + +/** @addtogroup BSP + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY STM32L476G-DISCOVERY + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_Common STM32L476G-DISCOVERY Common + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_Private_TypesDefinitions Private Types Definitions + * @brief This file provides firmware functions to manage Leds, push-buttons, + * COM ports, SD card on SPI and temperature sensor (TS751) available on + * STM32L476G-DISCOVERY discoveryuation board from STMicroelectronics. + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_Private_Defines Private Defines + * @{ + */ + +/** + * @brief STM32L476G DISCOVERY BSP Driver version number V1.0.1 + */ +#define __STM32L476G_DISCOVERY_BSP_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32L476G_DISCOVERY_BSP_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __STM32L476G_DISCOVERY_BSP_VERSION_SUB2 (0x01) /*!< [15:8] sub2 version */ +#define __STM32L476G_DISCOVERY_BSP_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32L476G_DISCOVERY_BSP_VERSION ((__STM32L476G_DISCOVERY_BSP_VERSION_MAIN << 24)\ + |(__STM32L476G_DISCOVERY_BSP_VERSION_SUB1 << 16)\ + |(__STM32L476G_DISCOVERY_BSP_VERSION_SUB2 << 8 )\ + |(__STM32L476G_DISCOVERY_BSP_VERSION_RC)) +/** + * @} + */ + + +/** @defgroup STM32L476G_DISCOVERY_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup STM32L476G_DISCOVERY_Exported_Variables Exported Variables + * @{ + */ + +/** + * @brief LED variables + */ +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +GPIO_TypeDef* LED_PORT[LEDn] = {LED4_GPIO_PORT, + LED5_GPIO_PORT}; + +const uint16_t LED_PIN[LEDn] = {LED4_PIN, + LED5_PIN}; +#elif defined (USE_STM32L476G_DISCO_REVA) +GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT, + LED4_GPIO_PORT}; + +const uint16_t LED_PIN[LEDn] = {LED3_PIN, + LED4_PIN}; +#endif + + +/** + * @brief JOYSTICK variables + */ + GPIO_TypeDef* JOY_PORT[JOYn] = {SEL_JOY_GPIO_PORT, + DOWN_JOY_GPIO_PORT, + LEFT_JOY_GPIO_PORT, + RIGHT_JOY_GPIO_PORT, + UP_JOY_GPIO_PORT}; + +const uint16_t JOY_PIN[JOYn] = {SEL_JOY_PIN, + LEFT_JOY_PIN, + RIGHT_JOY_PIN, + DOWN_JOY_PIN, + UP_JOY_PIN}; + +const uint8_t JOY_IRQn[JOYn] = {SEL_JOY_EXTI_IRQn, + LEFT_JOY_EXTI_IRQn, + RIGHT_JOY_EXTI_IRQn, + DOWN_JOY_EXTI_IRQn, + UP_JOY_EXTI_IRQn}; + +/** + * @brief BUS variables + */ +#if defined(HAL_I2C_MODULE_ENABLED) +uint32_t I2c1Timeout = DISCOVERY_I2C2_TIMEOUT_MAX; /*<! Value of Timeout when I2C1 communication fails */ +uint32_t I2c2Timeout = DISCOVERY_I2C2_TIMEOUT_MAX; /*<! Value of Timeout when I2C2 communication fails */ +static I2C_HandleTypeDef I2c1Handle; +static I2C_HandleTypeDef I2c2Handle; +#endif /* HAL_I2C_MODULE_ENABLED */ + +#if defined(HAL_SPI_MODULE_ENABLED) + +/* LL definition */ +#define __SPI_DIRECTION_2LINES(__HANDLE__) do{\ + CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\ + }while(0); + +#define __SPI_DIRECTION_2LINES_RXONLY(__HANDLE__) do{\ + CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\ + SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY);\ + }while(0); + +#define __SPI_DIRECTION_1LINE_TX(__HANDLE__) do{\ + CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\ + SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\ + }while(0); + +#define __SPI_DIRECTION_1LINE_RX(__HANDLE__) do {\ + CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\ + SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_BIDIMODE);\ + } while(0); + + +uint32_t SpixTimeout = SPIx_TIMEOUT_MAX; /*<! Value of Timeout when SPI communication fails */ +static SPI_HandleTypeDef SpiHandle; +#endif /* HAL_SPI_MODULE_ENABLED */ + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_Private_FunctionPrototypes Private Functions + * @{ + */ +/**************************** Bus functions ************************************/ +/* I2C2 bus function */ +#if defined(HAL_I2C_MODULE_ENABLED) +static void I2C2_Init(void); +static void I2C2_MspInit(I2C_HandleTypeDef *hi2c); +static void I2C2_DeInit(void); +static void I2C2_MspDeInit(I2C_HandleTypeDef *hi2c); +static void I2C2_WriteData(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t Value); +static HAL_StatusTypeDef I2C2_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length); +static uint8_t I2C2_ReadData(uint16_t Addr, uint16_t Reg, uint16_t RegSize); +static HAL_StatusTypeDef I2C2_ReadBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length); +static void I2C2_Error (void); + +static void I2C1_Init(void); +static void I2C1_MspInit(I2C_HandleTypeDef *hi2c); +static void I2C1_DeInit(void); +static void I2C1_MspDeInit(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C1_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length); +static HAL_StatusTypeDef I2C1_ReadBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length); +static void I2C1_Error (void); +#endif/* HAL_I2C_MODULE_ENABLED */ + +/* SPIx bus function */ +#if defined(HAL_SPI_MODULE_ENABLED) +static void SPIx_Init(void); +static void SPIx_MspInit(SPI_HandleTypeDef *hspi); +static void SPIx_DeInit(void); +static void SPIx_MspDeInit(void); +static uint8_t SPIx_WriteRead(uint8_t Byte); +static void SPIx_Write(uint8_t byte); +static uint8_t SPIx_Read(void); +#endif + +/**************************** Link functions ***********************************/ +#if defined(HAL_I2C_MODULE_ENABLED) +/* Link functions for EEPROM peripheral over I2C */ +void EEPROM_I2C_IO_Init(void); +HAL_StatusTypeDef EEPROM_I2C_IO_WriteData(uint16_t DevAddress, uint16_t MemAddress, uint8_t* pBuffer, uint32_t BufferSize); +HAL_StatusTypeDef EEPROM_I2C_IO_ReadData(uint16_t DevAddress, uint16_t MemAddress, uint8_t* pBuffer, uint32_t BufferSize); +HAL_StatusTypeDef EEPROM_I2C_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials); + +/* Link functions for Audio Codec peripheral */ +void AUDIO_IO_Init(void); +void AUDIO_IO_DeInit(void); +void AUDIO_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value); +uint8_t AUDIO_IO_Read(uint8_t Addr, uint8_t Reg); +void AUDIO_IO_Delay(uint32_t delay); +#endif/* HAL_I2C_MODULE_ENABLED */ + +#if defined(HAL_SPI_MODULE_ENABLED) +/* Link function for COMPASS / ACCELERO peripheral */ +void ACCELERO_IO_Init(void); +void ACCELERO_IO_DeInit(void); +void ACCELERO_IO_ITConfig(void); +void ACCELERO_IO_Write(uint8_t RegisterAddr, uint8_t Value); +uint8_t ACCELERO_IO_Read(uint8_t RegisterAddr); + +void MAGNETO_IO_Init(void); +void MAGNETO_IO_DeInit(void); +void MAGNETO_IO_ITConfig(void); +void MAGNETO_IO_Write(uint8_t RegisterAddr, uint8_t Value); +uint8_t MAGNETO_IO_Read(uint8_t RegisterAddr); + + +/* Link functions for GYRO peripheral */ +void GYRO_IO_Init(void); +void GYRO_IO_DeInit(void); +void GYRO_IO_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite); +void GYRO_IO_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead); + +#endif + +#if defined(HAL_I2C_MODULE_ENABLED) +/* Link functions IOExpander */ +void IOE_Init(void); +void IOE_ITConfig(void); +void IOE_Delay(uint32_t Delay); +void IOE_Write(uint8_t Addr, uint8_t Reg, uint8_t Value); +uint8_t IOE_Read(uint8_t Addr, uint8_t Reg); +uint16_t IOE_ReadMultiple(uint8_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length); + +/* Link functions for IDD measurment */ +void MFX_IO_Init(void); +void MFX_IO_DeInit(void); +void MFX_IO_ITConfig (void); +void MFX_IO_EnableWakeupPin(void); +void MFX_IO_Wakeup(void); +void MFX_IO_Delay(uint32_t delay); +void MFX_IO_Write(uint16_t addr, uint8_t reg, uint8_t value); +uint8_t MFX_IO_Read(uint16_t addr, uint8_t reg); +void MFX_IO_WriteMultiple(uint16_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length); +uint16_t MFX_IO_ReadMultiple(uint16_t addr, uint8_t reg, uint8_t *buffer, uint16_t length); +#endif/* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief This method returns the STM32L476 DISCOVERY BSP Driver revision + * @retval version : 0xXYZR (8bits for each decimal, R for RC) + */ +uint32_t BSP_GetVersion(void) +{ + return __STM32L476G_DISCOVERY_BSP_VERSION; +} + +/** + * @brief This method returns the STM32L476 DISCOVERY supply mode + * @retval Code of current supply mode + * This code can be one of following: + * @arg SUPPLY_MODE_EXTERNAL + * @arg SUPPLY_MODE_BATTERY + */ +SupplyMode_TypeDef BSP_SupplyModeDetection(void) +{ + SupplyMode_TypeDef supplymode = SUPPLY_MODE_ERROR; + GPIO_InitTypeDef GPIO_InitStruct; + + BATTERY_DETECTION_GPIO_CLK_ENABLE(); + + /* COMP GPIO pin configuration */ + GPIO_InitStruct.Pin = BATTERY_DETECTION_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(BATTERY_DETECTION_GPIO_PORT, &GPIO_InitStruct); + + HAL_Delay(400); + if(HAL_GPIO_ReadPin(BATTERY_DETECTION_GPIO_PORT, GPIO_InitStruct.Pin) != GPIO_PIN_RESET) + { + supplymode = SUPPLY_MODE_EXTERNAL; + } + else + { + supplymode = SUPPLY_MODE_BATTERY; + } + + HAL_GPIO_DeInit(BATTERY_DETECTION_GPIO_PORT, GPIO_InitStruct.Pin); + + return supplymode; +} + +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +/** + * @brief Configures LED GPIOs. + * @param Led: Specifies the Led to be configured. + * This parameter can be one of following parameters: + * @arg LED4 + * @arg LED5 + * @retval None + */ +#elif defined (USE_STM32L476G_DISCO_REVA) +/** + * @brief Configures LED GPIOs. + * @param Led: Specifies the Led to be configured. + * This parameter can be one of following parameters: + * @arg LED3 + * @arg LED4 + * @retval None + */ +#endif +void BSP_LED_Init(Led_TypeDef Led) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable the GPIO_LED clock */ + LEDx_GPIO_CLK_ENABLE(Led); + + /* Configure the GPIO_LED pin */ + GPIO_InitStructure.Pin = LED_PIN[Led]; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + HAL_GPIO_Init(LED_PORT[Led], &GPIO_InitStructure); + + HAL_GPIO_WritePin(LED_PORT[Led], GPIO_InitStructure.Pin, GPIO_PIN_RESET); +} + +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +/** + * @brief Unconfigures LED GPIOs. + * @param Led: Specifies the Led to be unconfigured. + * This parameter can be one of following parameters: + * @arg LED4 + * @arg LED5 + * @retval None + */ +#elif defined (USE_STM32L476G_DISCO_REVA) +/** + * @brief Unconfigures LED GPIOs. + * @param Led: Specifies the Led to be unconfigured. + * This parameter can be one of following parameters: + * @arg LED3 + * @arg LED4 + * @retval None + */ +#endif +void BSP_LED_DeInit(Led_TypeDef Led) +{ + /* Enable the GPIO_LED clock */ + LEDx_GPIO_CLK_ENABLE(Led); + + HAL_GPIO_DeInit(LED_PORT[Led], LED_PIN[Led]); +} + +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +/** + * @brief Turns selected LED On. + * @param Led: Specifies the Led to be set on. + * This parameter can be one of following parameters: + * @arg LED4 + * @arg LED5 + * @retval None + */ +#elif defined (USE_STM32L476G_DISCO_REVA) +/** + * @brief Turns selected LED On. + * @param Led: Specifies the Led to be set on. + * This parameter can be one of following parameters: + * @arg LED3 + * @arg LED4 + * @retval None + */ +#endif +void BSP_LED_On(Led_TypeDef Led) +{ + HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET); +} + +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +/** + * @brief Turns selected LED Off. + * @param Led: Specifies the Led to be set off. + * This parameter can be one of following parameters: + * @arg LED4 + * @arg LED5 + * @retval None + */ +#elif defined (USE_STM32L476G_DISCO_REVA) +/** + * @brief Turns selected LED Off. + * @param Led: Specifies the Led to be set off. + * This parameter can be one of following parameters: + * @arg LED3 + * @arg LED4 + * @retval None + */ +#endif +void BSP_LED_Off(Led_TypeDef Led) +{ + HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET); +} + +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +/** + * @brief Toggles the selected LED. + * @param Led: Specifies the Led to be toggled. + * This parameter can be one of following parameters: + * @arg LED4 + * @arg LED5 + * @retval None + */ +#elif defined (USE_STM32L476G_DISCO_REVA) +/** + * @brief Toggles the selected LED. + * @param Led: Specifies the Led to be toggled. + * This parameter can be one of following parameters: + * @arg LED3 + * @arg LED4 + * @retval None + */ +#endif +void BSP_LED_Toggle(Led_TypeDef Led) +{ + HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]); +} + +/** + * @brief Configures all buttons of the joystick in GPIO or EXTI modes. + * @param Joy_Mode: Joystick mode. + * This parameter can be one of the following values: + * @arg JOY_MODE_GPIO: Joystick pins will be used as simple IOs + * @arg JOY_MODE_EXTI: Joystick pins will be connected to EXTI line + * with interrupt generation capability + * @retval HAL_OK: if all initializations are OK. Other value if error. + */ +uint8_t BSP_JOY_Init(JOYMode_TypeDef Joy_Mode) +{ + JOYState_TypeDef joykey; + GPIO_InitTypeDef GPIO_InitStruct; + + /* Initialized the Joystick. */ + for(joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++) + { + /* Enable the JOY clock */ + JOYx_GPIO_CLK_ENABLE(joykey); + + GPIO_InitStruct.Pin = JOY_PIN[joykey]; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + if (Joy_Mode == JOY_MODE_GPIO) + { + /* Configure Joy pin as input */ + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + HAL_GPIO_Init(JOY_PORT[joykey], &GPIO_InitStruct); + } + else if (Joy_Mode == JOY_MODE_EXTI) + { + /* Configure Joy pin as input with External interrupt */ + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + HAL_GPIO_Init(JOY_PORT[joykey], &GPIO_InitStruct); + + /* Enable and set Joy EXTI Interrupt to the lowest priority */ + HAL_NVIC_SetPriority((IRQn_Type)(JOY_IRQn[joykey]), 0x0F, 0x00); + HAL_NVIC_EnableIRQ((IRQn_Type)(JOY_IRQn[joykey])); + } + } + + return HAL_OK; +} + +/** + * @brief Unonfigures all GPIOs used as buttons of the joystick. + * @retval None. + */ +void BSP_JOY_DeInit(void) +{ + JOYState_TypeDef joykey; + + /* Initialized the Joystick. */ + for(joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++) + { + /* Enable the JOY clock */ + JOYx_GPIO_CLK_ENABLE(joykey); + + HAL_GPIO_DeInit(JOY_PORT[joykey], JOY_PIN[joykey]); + } +} + +/** +* @brief Returns the current joystick status. +* @retval Code of the joystick key pressed +* This code can be one of the following values: +* @arg JOY_NONE +* @arg JOY_SEL +* @arg JOY_DOWN +* @arg JOY_LEFT +* @arg JOY_RIGHT +* @arg JOY_UP +*/ +JOYState_TypeDef BSP_JOY_GetState(void) +{ + JOYState_TypeDef joykey; + + for (joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++) + { + if (HAL_GPIO_ReadPin(JOY_PORT[joykey], JOY_PIN[joykey]) == GPIO_PIN_SET) + { + /* Return Code Joystick key pressed */ + return joykey; + } + } + + /* No Joystick key pressed */ + return JOY_NONE; +} + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_BusOperations_Functions Bus Operations Functions + * @{ + */ + +/******************************************************************************* + BUS OPERATIONS +*******************************************************************************/ +#if defined(HAL_SPI_MODULE_ENABLED) +/******************************* SPI Routines**********************************/ +/** + * @brief SPIx Bus initialization + * @retval None + */ +static void SPIx_Init(void) +{ + if(HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET) + { + /* SPI Config */ + SpiHandle.Instance = DISCOVERY_SPIx; + /* SPI baudrate is set to 10 MHz (PCLK1/SPI_BaudRatePrescaler = 80/8 = 10 MHz) + to verify these constraints: + lsm303c SPI interface max baudrate is 10MHz for write/read + PCLK1 max frequency is set to 80 MHz + */ + SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; + SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; + SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; + SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; + SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + SpiHandle.Init.CRCPolynomial = 7; + SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; + SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; + SpiHandle.Init.NSS = SPI_NSS_SOFT; + SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE; + SpiHandle.Init.Mode = SPI_MODE_MASTER; + + SPIx_MspInit(&SpiHandle); + HAL_SPI_Init(&SpiHandle); + } +} + +/** + * @brief SPI MSP Init + * @param hspi: SPI handle + * @retval None + */ +static void SPIx_MspInit(SPI_HandleTypeDef *hspi) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable SPIx clock */ + DISCOVERY_SPIx_CLOCK_ENABLE(); + + /* enable SPIx gpio clock */ + DISCOVERY_SPIx_GPIO_CLK_ENABLE(); + + /* configure SPIx SCK, MOSI and MISO */ + GPIO_InitStructure.Pin = (DISCOVERY_SPIx_SCK_PIN | DISCOVERY_SPIx_MOSI_PIN | DISCOVERY_SPIx_MISO_PIN); + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; // GPIO_PULLDOWN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStructure.Alternate = DISCOVERY_SPIx_AF; + HAL_GPIO_Init(DISCOVERY_SPIx_GPIO_PORT, &GPIO_InitStructure); +} + +/** + * @brief SPIx Bus Deinitialization + * @retval None + */ +void SPIx_DeInit(void) +{ + if(HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_RESET) + { + /* SPI Deinit */ + HAL_SPI_DeInit(&SpiHandle); + SPIx_MspDeInit(); + } +} + +/** + * @brief SPI MSP DeInit + * @retval None + */ +static void SPIx_MspDeInit(void) +{ + /* enable SPIx gpio clock */ + DISCOVERY_SPIx_GPIO_CLK_ENABLE(); + + /* Unconfigure SPIx SCK, MOSI and MISO */ + HAL_GPIO_DeInit(DISCOVERY_SPIx_GPIO_PORT, (DISCOVERY_SPIx_SCK_PIN | DISCOVERY_SPIx_MOSI_PIN | DISCOVERY_SPIx_MISO_PIN)); + + DISCOVERY_SPIx_GPIO_FORCE_RESET(); + DISCOVERY_SPIx_GPIO_RELEASE_RESET(); + + /* Disable SPIx clock */ + DISCOVERY_SPIx_CLOCK_DISABLE(); +} + +/** + * @brief Sends a Byte through the SPI interface and return the Byte received + * from the SPI bus. + * @param Byte : Byte send. + * @retval none. + */ +static uint8_t SPIx_WriteRead(uint8_t Byte) +{ + uint8_t receivedbyte; + + /* Enable the SPI */ + __HAL_SPI_ENABLE(&SpiHandle); + /* check TXE flag */ + while((SpiHandle.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE); + + /* Write the data */ + *((__IO uint8_t*)&SpiHandle.Instance->DR) = Byte; + + while((SpiHandle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE); + receivedbyte = *((__IO uint8_t*)&SpiHandle.Instance->DR); + + /* Wait BSY flag */ + while((SpiHandle.Instance->SR & SPI_FLAG_FTLVL) != SPI_FTLVL_EMPTY); + while((SpiHandle.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY); + + /* disable the SPI */ + __HAL_SPI_DISABLE(&SpiHandle); + + return receivedbyte; +} + +/** + * @brief Sends a Byte through the SPI interface. + * @param Byte : Byte to send. + * @retval none. + */ +static void SPIx_Write(uint8_t Byte) +{ + /* Enable the SPI */ + __HAL_SPI_ENABLE(&SpiHandle); + /* check TXE flag */ + while((SpiHandle.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE); + + /* Write the data */ + *((__IO uint8_t*)&SpiHandle.Instance->DR) = Byte; + + /* Wait BSY flag */ + while((SpiHandle.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY); + + /* disable the SPI */ + __HAL_SPI_DISABLE(&SpiHandle); +} + +#if defined(__ICCARM__) +#pragma optimize=none +#endif +/** + * @brief Receives a Byte from the SPI bus. + * @retval The received byte value + */ +static uint8_t SPIx_Read(void) +{ + uint8_t receivedbyte; + + __HAL_SPI_ENABLE(&SpiHandle); + __DSB(); + __DSB(); + __DSB(); + __DSB(); + __DSB(); + __DSB(); + __DSB(); + __DSB(); + __HAL_SPI_DISABLE(&SpiHandle); + + while((SpiHandle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE); + /* read the received data */ + receivedbyte = *(__IO uint8_t *)&SpiHandle.Instance->DR; + + /* Wait for the BSY flag reset */ + while((SpiHandle.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY); + + + return receivedbyte; +} +#endif /* HAL_SPI_MODULE_ENABLED */ + + +#if defined(HAL_I2C_MODULE_ENABLED) +/******************************* I2C Routines**********************************/ +/** + * @brief Discovery I2C1 Bus initialization + * @retval None + */ +static void I2C1_Init(void) +{ + if(HAL_I2C_GetState(&I2c1Handle) == HAL_I2C_STATE_RESET) + { + I2c1Handle.Instance = DISCOVERY_I2C1; + I2c1Handle.Init.Timing = DISCOVERY_I2C1_TIMING; + I2c1Handle.Init.OwnAddress1 = 0; + I2c1Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + I2c1Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + I2c1Handle.Init.OwnAddress2 = 0; + I2c1Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + I2c1Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + + /* Init the I2C */ + I2C1_MspInit(&I2c1Handle); + HAL_I2C_Init(&I2c1Handle); + } +} + +/** + * @brief Discovery I2C1 MSP Initialization + * @param hi2c: I2C handle + * @retval None + */ +static void I2C1_MspInit(I2C_HandleTypeDef *hi2c) +{ + GPIO_InitTypeDef GPIO_InitStructure; + RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct; + + /* IOSV bit MUST be set to access GPIO port G[2:15] */ + __HAL_RCC_PWR_CLK_ENABLE(); + HAL_PWREx_EnableVddIO2(); + + if (hi2c->Instance == DISCOVERY_I2C1) + { + /*##-1- Configure the Discovery I2C clock source. The clock is derived from the SYSCLK #*/ + RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1; + RCC_PeriphCLKInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); + + /*##-2- Configure the GPIOs ################################################*/ + /* Enable GPIO clock */ + DISCOVERY_I2C1_SDA_GPIO_CLK_ENABLE(); + DISCOVERY_I2C1_SCL_GPIO_CLK_ENABLE(); + + /* Configure I2C Rx/Tx as alternate function */ + GPIO_InitStructure.Pin = DISCOVERY_I2C1_SCL_PIN | DISCOVERY_I2C1_SDA_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Alternate = DISCOVERY_I2C1_SCL_SDA_AF; + HAL_GPIO_Init(DISCOVERY_I2C1_SCL_GPIO_PORT, &GPIO_InitStructure); + + /*##-3- Configure the Discovery I2C1 peripheral #######################################*/ + /* Enable Discovery I2C1 clock */ + DISCOVERY_I2C1_CLK_ENABLE(); + + /* Force and release the I2C Peripheral Clock Reset */ + DISCOVERY_I2C1_FORCE_RESET(); + DISCOVERY_I2C1_RELEASE_RESET(); + + /* Enable and set Discovery I2C1 Interrupt to the highest priority */ + HAL_NVIC_SetPriority(DISCOVERY_I2C1_EV_IRQn, 0x00, 0); + HAL_NVIC_EnableIRQ(DISCOVERY_I2C1_EV_IRQn); + + /* Enable and set Discovery I2C1 Interrupt to the highest priority */ + HAL_NVIC_SetPriority(DISCOVERY_I2C1_ER_IRQn, 0x00, 0); + HAL_NVIC_EnableIRQ(DISCOVERY_I2C1_ER_IRQn); + } +} + +/** + * @brief Discovery I2C1 Bus Deitialization + * @retval None + */ +static void I2C1_DeInit(void) +{ + if(HAL_I2C_GetState(&I2c1Handle) != HAL_I2C_STATE_RESET) + { + /* Deinit the I2C */ + HAL_I2C_DeInit(&I2c1Handle); + I2C1_MspDeInit(&I2c1Handle); + } +} + +/** + * @brief Discovery I2C1 MSP Deinitialization + * @param hi2c: I2C handle + * @retval None + */ +static void I2C1_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->Instance == DISCOVERY_I2C1) + { + /*##-1- Unconfigure the GPIOs ################################################*/ + /* Enable GPIO clock */ + DISCOVERY_I2C1_SDA_GPIO_CLK_ENABLE(); + DISCOVERY_I2C1_SCL_GPIO_CLK_ENABLE(); + + /* Deinit Rx/Tx pins */ + HAL_GPIO_DeInit(DISCOVERY_I2C1_SCL_GPIO_PORT, (DISCOVERY_I2C1_SCL_PIN | DISCOVERY_I2C1_SDA_PIN)); + + /*##-2- Unconfigure the Discovery I2C1 peripheral ############################*/ + /* Force & Release the I2C Peripheral Clock Reset */ + DISCOVERY_I2C1_FORCE_RESET(); + DISCOVERY_I2C1_RELEASE_RESET(); + + /* Disable Discovery I2C1 clock */ + DISCOVERY_I2C1_CLK_DISABLE(); + + /* Disable Discovery I2C1 interrupts */ + HAL_NVIC_DisableIRQ(DISCOVERY_I2C1_EV_IRQn); + HAL_NVIC_DisableIRQ(DISCOVERY_I2C1_ER_IRQn); + + __HAL_RCC_PWR_CLK_ENABLE(); + HAL_PWREx_DisableVddIO2(); + } +} + +/** + * @brief Write a value in a register of the device through BUS. + * @param Addr: Device address on BUS Bus. + * @param Reg: The target register address to write + * @param RegSize: The target register size (can be 8BIT or 16BIT) + * @param pBuffer: The target register value to be written + * @param Length: buffer size to be written + * @retval None + */ +static HAL_StatusTypeDef I2C1_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + + status = HAL_I2C_Mem_Write(&I2c1Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c1Timeout); + +/* Check the communication status */ + if(status != HAL_OK) + { + /* Re-Initiaize the BUS */ + I2C1_Error(); + } + return status; +} + +/** + * @brief Reads multiple data on the BUS. + * @param Addr: I2C Address + * @param Reg: Reg Address + * @param RegSize : The target register size (can be 8BIT or 16BIT) + * @param pBuffer: pointer to read data buffer + * @param Length: length of the data + * @retval 0 if no problems to read multiple data + */ +static HAL_StatusTypeDef I2C1_ReadBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + + status = HAL_I2C_Mem_Read(&I2c1Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c1Timeout); + +/* Check the communication status */ + if(status != HAL_OK) + { + /* Re-Initiaize the BUS */ + I2C1_Error(); + } + return status; +} + +/** + * @brief Discovery I2C1 error treatment function + * @retval None + */ +static void I2C1_Error (void) +{ + /* De-initialize the I2C communication BUS */ + HAL_I2C_DeInit(&I2c1Handle); + + /* Re- Initiaize the I2C communication BUS */ + I2C1_Init(); +} + +/** + * @brief Discovery I2C2 Bus initialization + * @retval None + */ +static void I2C2_Init(void) +{ + if(HAL_I2C_GetState(&I2c2Handle) == HAL_I2C_STATE_RESET) + { + I2c2Handle.Instance = DISCOVERY_I2C2; + I2c2Handle.Init.Timing = DISCOVERY_I2C2_TIMING; + I2c2Handle.Init.OwnAddress1 = 0; + I2c2Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + I2c2Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + I2c2Handle.Init.OwnAddress2 = 0; + I2c2Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + I2c2Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + + /* Init the I2C */ + I2C2_MspInit(&I2c2Handle); + HAL_I2C_Init(&I2c2Handle); + } +} + +/** + * @brief Discovery I2C2 MSP Initialization + * @param hi2c: I2C2 handle + * @retval None + */ +static void I2C2_MspInit(I2C_HandleTypeDef *hi2c) +{ + GPIO_InitTypeDef GPIO_InitStructure; + RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct; + + if (hi2c->Instance == DISCOVERY_I2C2) + { + /*##-1- Configure the Discovery I2C2 clock source. The clock is derived from the SYSCLK #*/ + RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C2; + RCC_PeriphCLKInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_SYSCLK; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); + + /*##-2- Configure the GPIOs ################################################*/ + /* Enable GPIO clock */ + DISCOVERY_I2C2_SDA_GPIO_CLK_ENABLE(); + DISCOVERY_I2C2_SCL_GPIO_CLK_ENABLE(); + + /* Configure I2C Rx/Tx as alternate function */ + GPIO_InitStructure.Pin = DISCOVERY_I2C2_SCL_PIN | DISCOVERY_I2C2_SDA_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Alternate = DISCOVERY_I2C2_SCL_SDA_AF; + HAL_GPIO_Init(DISCOVERY_I2C2_SCL_GPIO_PORT, &GPIO_InitStructure); + + /*##-3- Configure the Discovery I2C2 peripheral #############################*/ + /* Enable Discovery_I2C2 clock */ + DISCOVERY_I2C2_CLK_ENABLE(); + + /* Force and release the I2C Peripheral Clock Reset */ + DISCOVERY_I2C2_FORCE_RESET(); + DISCOVERY_I2C2_RELEASE_RESET(); + + /* Enable and set Discovery I2C2 Interrupt to the highest priority */ + HAL_NVIC_SetPriority(DISCOVERY_I2C2_EV_IRQn, 0x00, 0); + HAL_NVIC_EnableIRQ(DISCOVERY_I2C2_EV_IRQn); + + /* Enable and set Discovery I2C2 Interrupt to the highest priority */ + HAL_NVIC_SetPriority(DISCOVERY_I2C2_ER_IRQn, 0x00, 0); + HAL_NVIC_EnableIRQ(DISCOVERY_I2C2_ER_IRQn); + } +} + +/** + * @brief Discovery I2C2 Bus Deinitialization + * @retval None + */ +static void I2C2_DeInit(void) +{ + if(HAL_I2C_GetState(&I2c2Handle) != HAL_I2C_STATE_RESET) + { + /* DeInit the I2C */ + HAL_I2C_DeInit(&I2c2Handle); + I2C2_MspDeInit(&I2c2Handle); + } +} + +/** + * @brief Discovery I2C2 MSP DeInitialization + * @param hi2c: I2C2 handle + * @retval None + */ +static void I2C2_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->Instance == DISCOVERY_I2C2) + { + /*##-1- Unconfigure the GPIOs ################################################*/ + /* Enable GPIO clock */ + DISCOVERY_I2C2_SDA_GPIO_CLK_ENABLE(); + DISCOVERY_I2C2_SCL_GPIO_CLK_ENABLE(); + + /* Configure I2C Rx/Tx as alternate function */ + HAL_GPIO_DeInit(DISCOVERY_I2C2_SCL_GPIO_PORT, (DISCOVERY_I2C2_SCL_PIN | DISCOVERY_I2C2_SDA_PIN)); + + /*##-2- Unconfigure the Discovery I2C2 peripheral ############################*/ + /* Force and release I2C Peripheral */ + DISCOVERY_I2C2_FORCE_RESET(); + DISCOVERY_I2C2_RELEASE_RESET(); + + /* Disable Discovery I2C2 clock */ + DISCOVERY_I2C2_CLK_DISABLE(); + + /* Disable Discovery I2C2 interrupts */ + HAL_NVIC_DisableIRQ(DISCOVERY_I2C2_EV_IRQn); + HAL_NVIC_DisableIRQ(DISCOVERY_I2C2_ER_IRQn); + } +} + +/** + * @brief Write a value in a register of the device through BUS. + * @param Addr: Device address on BUS Bus. + * @param Reg: The target register address to write + * @param RegSize: The target register size (can be 8BIT or 16BIT) + * @param Value: The target register value to be written + * @retval None + */ +static void I2C2_WriteData(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t Value) + { + HAL_StatusTypeDef status = HAL_OK; + + status = HAL_I2C_Mem_Write(&I2c2Handle, Addr, (uint16_t)Reg, RegSize, &Value, 1, I2c2Timeout); + + /* Check the communication status */ + if(status != HAL_OK) + { + /* Re-Initiaize the BUS */ + I2C2_Error(); + } +} + +/** + * @brief Write a value in a register of the device through BUS. + * @param Addr: Device address on BUS Bus. + * @param Reg: The target register address to write + * @param RegSize: The target register size (can be 8BIT or 16BIT) + * @param pBuffer: The target register value to be written + * @param Length: buffer size to be written + * @retval None + */ +static HAL_StatusTypeDef I2C2_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + + status = HAL_I2C_Mem_Write(&I2c2Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c2Timeout); + + /* Check the communication status */ + if(status != HAL_OK) + { + /* Re-Initiaize the BUS */ + I2C2_Error(); + } + + return status; +} + +/** + * @brief Read a register of the device through BUS + * @param Addr: Device address on BUS + * @param Reg: The target register address to read + * @param RegSize: The target register size (can be 8BIT or 16BIT) + * @retval read register value + */ +static uint8_t I2C2_ReadData(uint16_t Addr, uint16_t Reg, uint16_t RegSize) +{ + HAL_StatusTypeDef status = HAL_OK; + uint8_t value = 0x0; + + status = HAL_I2C_Mem_Read(&I2c2Handle, Addr, Reg, RegSize, &value, 1, I2c2Timeout); + + /* Check the communication status */ + if(status != HAL_OK) + { + /* Re-Initiaize the BUS */ + I2C2_Error(); + } + + return value; +} + +/** + * @brief Reads multiple data on the BUS. + * @param Addr: I2C Address + * @param Reg: Reg Address + * @param RegSize : The target register size (can be 8BIT or 16BIT) + * @param pBuffer: pointer to read data buffer + * @param Length: length of the data + * @retval 0 if no problems to read multiple data + */ +static HAL_StatusTypeDef I2C2_ReadBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + + status = HAL_I2C_Mem_Read(&I2c2Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c2Timeout); + + /* Check the communication status */ + if(status != HAL_OK) + { + /* Re-Initiaize the BUS */ + I2C2_Error(); + } + + return status; +} + +/** + * @brief Discovery I2C2 error treatment function + * @retval None + */ +static void I2C2_Error (void) +{ + /* De-initialize the I2C communication BUS */ + HAL_I2C_DeInit(&I2c2Handle); + + /* Re- Initiaize the I2C communication BUS */ + I2C2_Init(); +} +#endif /*HAL_I2C_MODULE_ENABLED*/ + + +/******************************************************************************* + LINK OPERATIONS +*******************************************************************************/ +#if defined(HAL_SPI_MODULE_ENABLED) +/*********************** LINK ACCELEROMETER ***********************************/ +/** + * @brief Configures COMPASS/ACCELEROMETER io interface. + * @retval None + */ +void ACCELERO_IO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable CS GPIO clock and Configure GPIO PIN for Gyroscope Chip select */ + ACCELERO_CS_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = ACCELERO_CS_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(ACCELERO_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Deselect : Chip Select high */ + ACCELERO_CS_HIGH(); + + SPIx_Init(); +} + +/** + * @brief De-Configures COMPASS/ACCELEROMETER io interface. + * @retval None + */ +void ACCELERO_IO_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable CS GPIO clock and Configure GPIO PIN for Gyroscope Chip select */ + ACCELERO_CS_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = ACCELERO_CS_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(ACCELERO_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Deselect : Chip Select high */ + ACCELERO_CS_HIGH(); + + /* Uninitialize SPI bus */ + SPIx_DeInit(); +} + +/** + * @brief Configures COMPASS / ACCELERO click IT + * @retval None + */ +void ACCELERO_IO_ITConfig(void) +{ +} + +/** + * @brief Writes one byte to the COMPASS / ACCELEROMETER. + * @param RegisterAddr specifies the COMPASS / ACCELEROMETER register to be written. + * @param Value : Data to be written + * @retval None + */ +void ACCELERO_IO_Write(uint8_t RegisterAddr, uint8_t Value) +{ + ACCELERO_CS_LOW(); + __SPI_DIRECTION_1LINE_TX(&SpiHandle); + /* call SPI Read data bus function */ + SPIx_Write(RegisterAddr); + SPIx_Write(Value); + ACCELERO_CS_HIGH(); +} + +/** + * @brief Reads a block of data from the COMPASS / ACCELEROMETER. + * @param RegisterAddr : specifies the COMPASS / ACCELEROMETER internal address register to read from + * @retval ACCELEROMETER register value + */ +uint8_t ACCELERO_IO_Read(uint8_t RegisterAddr) +{ + RegisterAddr = RegisterAddr | ((uint8_t)0x80); + ACCELERO_CS_LOW(); + __SPI_DIRECTION_1LINE_TX(&SpiHandle); + SPIx_Write(RegisterAddr); + __SPI_DIRECTION_1LINE_RX(&SpiHandle); + uint8_t val = SPIx_Read(); + ACCELERO_CS_HIGH(); + return val; +} + +/********************************* LINK MAGNETO *******************************/ +/** + * @brief Configures COMPASS/MAGNETO SPI interface. + * @retval None + */ +void MAGNETO_IO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable CS GPIO clock and Configure GPIO PIN for Gyroscope Chip select */ + MAGNETO_CS_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = MAGNETO_CS_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(MAGNETO_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Deselect : Chip Select high */ + MAGNETO_CS_HIGH(); + + SPIx_Init(); +} + +/** + * @brief de-Configures COMPASS/MAGNETO SPI interface. + * @retval None + */ +void MAGNETO_IO_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable CS GPIO clock and Configure GPIO PIN for Gyroscope Chip select */ + MAGNETO_CS_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = MAGNETO_CS_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(MAGNETO_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Deselect : Chip Select high */ + MAGNETO_CS_HIGH(); + + HAL_GPIO_DeInit(MAGNETO_CS_GPIO_PORT, MAGNETO_INT1_PIN|MAGNETO_DRDY_PIN); + + + /* Uninitialize SPI bus */ + SPIx_DeInit(); +} + +/** + * @brief Writes one byte to the COMPASS/MAGNETO. + * @param RegisterAddr specifies the COMPASS/MAGNETO register to be written. + * @param Value : Data to be written + * @retval None + */ +void MAGNETO_IO_Write(uint8_t RegisterAddr, uint8_t Value) +{ + MAGNETO_CS_LOW(); + __SPI_DIRECTION_1LINE_TX(&SpiHandle); + /* call SPI Read data bus function */ + SPIx_Write(RegisterAddr); + SPIx_Write(Value); + MAGNETO_CS_HIGH(); +} + +/** + * @brief Reads a block of data from the COMPASS/MAGNETO. + * @param RegisterAddr : specifies the COMPASS/MAGNETO internal address register to read from + * @retval ACCELEROMETER register value + */ +uint8_t MAGNETO_IO_Read(uint8_t RegisterAddr) +{ + MAGNETO_CS_LOW(); + __SPI_DIRECTION_1LINE_TX(&SpiHandle); + SPIx_Write(RegisterAddr | 0x80); + __SPI_DIRECTION_1LINE_RX(&SpiHandle); + uint8_t val = SPIx_Read(); + MAGNETO_CS_HIGH(); + return val; +} + +/********************************* LINK GYRO *****************************/ +/** + * @brief Configures the GYRO SPI interface. + * @retval None + */ +void GYRO_IO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + + /* Case GYRO not used in the demonstration software except being set in + low power mode. + To avoid access conflicts with accelerometer and magnetometer, + initialize XL_CS and MAG_CS pins then deselect these I/O */ + ACCELERO_CS_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = ACCELERO_CS_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(ACCELERO_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Deselect : Chip Select high */ + ACCELERO_CS_HIGH(); + + /* Enable CS GPIO clock and Configure GPIO PIN for Gyroscope Chip select */ + MAGNETO_CS_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = MAGNETO_CS_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(MAGNETO_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Deselect : Chip Select high */ + MAGNETO_CS_HIGH(); + + + /* Configure the Gyroscope Control pins ---------------------------------*/ + /* Enable CS GPIO clock and Configure GPIO PIN for Gyroscope Chip select */ + GYRO_CS_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = GYRO_CS_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GYRO_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Deselect : Chip Select high */ + GYRO_CS_HIGH(); + + /* Enable INT1, INT2 GPIO clock and Configure GPIO PINs to detect Interrupts */ + GYRO_INT1_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = GYRO_INT1_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Pull= GPIO_NOPULL; + HAL_GPIO_Init(GYRO_INT1_GPIO_PORT, &GPIO_InitStructure); + + GYRO_INT2_GPIO_CLK_ENABLE(); + GPIO_InitStructure.Pin = GYRO_INT2_PIN; + HAL_GPIO_Init(GYRO_INT2_GPIO_PORT, &GPIO_InitStructure); + + SPIx_Init(); + +} + + +/** + * @brief de-Configures GYRO SPI interface. + * @retval None + */ +void GYRO_IO_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + /* Enable CS GPIO clock */ + GYRO_CS_GPIO_CLK_ENABLE(); + + GPIO_InitStructure.Pin = GYRO_CS_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GYRO_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Deselect : Chip Select high */ + GYRO_CS_HIGH(); + + GYRO_INT1_GPIO_CLK_ENABLE(); + GYRO_INT2_GPIO_CLK_ENABLE(); + + /* Uninitialize the INT1/INT2 Pins */ + HAL_GPIO_DeInit(GYRO_INT1_GPIO_PORT, GYRO_INT1_PIN); + HAL_GPIO_DeInit(GYRO_INT2_GPIO_PORT, GYRO_INT2_PIN); + + /* Uninitialize SPI bus */ + SPIx_DeInit(); +} + +/** + * @brief Writes one byte to the GYRO. + * @param pBuffer : pointer to the buffer containing the data to be written to the GYRO. + * @param WriteAddr : GYRO's internal address to write to. + * @param NumByteToWrite: Number of bytes to write. + * @retval None + */ +void GYRO_IO_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite) +{ + /* Configure the MS bit: + - When 0, the address will remain unchanged in multiple read/write commands. + - When 1, the address will be auto incremented in multiple read/write commands. + */ + if(NumByteToWrite > 0x01) + { + WriteAddr |= (uint8_t)MULTIPLEBYTE_CMD; + } + /* Set chip select Low at the start of the transmission */ + GYRO_CS_LOW(); + __SPI_DIRECTION_2LINES(&SpiHandle); + + /* Send the Address of the indexed register */ + SPIx_WriteRead(WriteAddr); + + /* Send the data that will be written into the device (MSB First) */ + while(NumByteToWrite >= 0x01) + { + SPIx_WriteRead(*pBuffer); + NumByteToWrite--; + pBuffer++; + } + + /* Set chip select High at the end of the transmission */ + GYRO_CS_HIGH(); +} + +/** + * @brief Reads a block of data from the GYROSCOPE. + * @param pBuffer : pointer to the buffer that receives the data read from the GYROSCOPE. + * @param ReadAddr : GYROSCOPE's internal address to read from. + * @param NumByteToRead : number of bytes to read from the GYROSCOPE. + * @retval None + */ +void GYRO_IO_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead) +{ + if(NumByteToRead > 0x01) + { + ReadAddr |= (uint8_t)(READWRITE_CMD | MULTIPLEBYTE_CMD); + } + else + { + ReadAddr |= (uint8_t)READWRITE_CMD; + } + /* Set chip select Low at the start of the transmission */ + GYRO_CS_LOW(); + __SPI_DIRECTION_2LINES(&SpiHandle); + /* Send the Address of the indexed register */ + SPIx_WriteRead(ReadAddr); + + /* Receive the data that will be read from the device (MSB First) */ + while(NumByteToRead > 0x00) + { + /* Send dummy byte (0x00) to generate the SPI clock to GYROSCOPE (Slave device) */ + *pBuffer = SPIx_WriteRead(0x00); + NumByteToRead--; + pBuffer++; + } + + /* Set chip select High at the end of the transmission */ + GYRO_CS_HIGH(); +} +#endif /* HAL_SPI_MODULE_ENABLED */ + +#if defined(HAL_I2C_MODULE_ENABLED) +/********************************* LINK MFX ***********************************/ +/** + * @brief Initializes MFX low level. + * @retval None + */ +void MFX_IO_Init(void) +{ + /* I2C2 init */ + I2C2_Init(); +} +/** + * @brief Deinitializes MFX low level. + * @retval None + */ +void MFX_IO_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable wakeup gpio clock */ + IDD_WAKEUP_GPIO_CLK_ENABLE(); + + /* MFX wakeup pin configuration */ + GPIO_InitStruct.Pin = IDD_WAKEUP_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(IDD_WAKEUP_GPIO_PORT, &GPIO_InitStruct); + + /* DeInit interrupt pin : disable IRQ before to avoid spurious interrupt */ + HAL_NVIC_DisableIRQ((IRQn_Type)(IDD_INT_EXTI_IRQn)); + IDD_INT_GPIO_CLK_ENABLE(); + HAL_GPIO_DeInit(IDD_INT_GPIO_PORT, IDD_INT_PIN); + + /* I2C2 Deinit */ + I2C2_DeInit(); +} + +/** + * @brief Configures MFX low level interrupt. + * @retval None + */ +void MFX_IO_ITConfig(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable the GPIO clock */ + IDD_INT_GPIO_CLK_ENABLE(); + + /* MFX_OUT_IRQ (normally used for EXTI_WKUP) */ + GPIO_InitStruct.Pin = IDD_INT_PIN; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; + HAL_GPIO_Init(IDD_INT_GPIO_PORT, &GPIO_InitStruct); + + /* Enable and set GPIO EXTI Interrupt to the lowest priority */ + HAL_NVIC_SetPriority((IRQn_Type)(IDD_INT_EXTI_IRQn), 0x0F, 0x0F); + HAL_NVIC_EnableIRQ((IRQn_Type)(IDD_INT_EXTI_IRQn)); +} + +/** + * @brief Configures MFX wke up pin. + * @retval None + */ +void MFX_IO_EnableWakeupPin(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable wakeup gpio clock */ + IDD_WAKEUP_GPIO_CLK_ENABLE(); + + /* MFX wakeup pin configuration */ + GPIO_InitStruct.Pin = IDD_WAKEUP_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(IDD_WAKEUP_GPIO_PORT, &GPIO_InitStruct); +} + +/** + * @brief Wakeup MFX. + * @retval None + */ +void MFX_IO_Wakeup(void) +{ + /* Set Wakeup pin to high to wakeup Idd measurement component from standby mode */ + HAL_GPIO_WritePin(IDD_WAKEUP_GPIO_PORT, IDD_WAKEUP_PIN, GPIO_PIN_SET); + + /* Wait */ + HAL_Delay(1); + + /* Set gpio pin basck to low */ + HAL_GPIO_WritePin(IDD_WAKEUP_GPIO_PORT, IDD_WAKEUP_PIN, GPIO_PIN_RESET); +} + +/** + * @brief MFX writes single data. + * @param Addr: I2C address + * @param Reg: Register address + * @param Value: Data to be written + * @retval None + */ +void MFX_IO_Write(uint16_t Addr, uint8_t Reg, uint8_t Value) +{ + I2C2_WriteData(Addr, Reg, I2C_MEMADD_SIZE_8BIT, Value); +} + +/** + * @brief MFX reads single data. + * @param Addr: I2C address + * @param Reg: Register address + * @retval Read data + */ +uint8_t MFX_IO_Read(uint16_t Addr, uint8_t Reg) +{ + return I2C2_ReadData(Addr, Reg, I2C_MEMADD_SIZE_8BIT); +} + +/** + * @brief MFX reads multiple data. + * @param Addr: I2C address + * @param Reg: Register address + * @param Buffer: Pointer to data buffer + * @param Length: Length of the data + * @retval Number of read data + */ +uint16_t MFX_IO_ReadMultiple(uint16_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length) +{ + return I2C2_ReadBuffer(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, Buffer, Length); +} + +/** + * @brief MFX writes multiple data. + * @param Addr: I2C address + * @param Reg: Register address + * @param Buffer: Pointer to data buffer + * @param Length: Length of the data + * @retval None + */ +void MFX_IO_WriteMultiple(uint16_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length) +{ + I2C2_WriteBuffer(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, Buffer, Length); +} + +/** + * @brief MFX delay + * @param Delay: Delay in ms + * @retval None + */ +void MFX_IO_Delay(uint32_t Delay) +{ + HAL_Delay(Delay); +} + + +/********************************* LINK AUDIO *********************************/ +/** + * @brief Initializes Audio low level. + * @retval None + */ +void AUDIO_IO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable Reset GPIO Clock */ + AUDIO_RESET_GPIO_CLK_ENABLE(); + + /* Audio reset pin configuration */ + GPIO_InitStruct.Pin = AUDIO_RESET_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(AUDIO_RESET_GPIO, &GPIO_InitStruct); + + /* I2C bus init */ + I2C1_Init(); + + /* Power Down the codec */ + CODEC_AUDIO_POWER_OFF(); + + /* wait for a delay to insure registers erasing */ + HAL_Delay(5); + + /* Power on the codec */ + CODEC_AUDIO_POWER_ON(); + + /* wait for a delay to insure registers erasing */ + HAL_Delay(5); +} + +/** + * @brief Deinitializes Audio low level. + * @retval None + */ +void AUDIO_IO_DeInit(void) /* TO DO */ +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /***********************************************************************/ + /* In case of battery-supplied powered, there is no audio codec-based + features available. Set audio codec I/O default setting */ + /***********************************************************************/ + __HAL_RCC_GPIOE_CLK_ENABLE(); + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP ; + GPIO_InitStruct.Pin = (GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6); + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_RESET); + + /* I2C bus Deinit */ + I2C1_DeInit(); +} + +/** + * @brief Writes a single data. + * @param Addr: I2C address + * @param Reg: Reg address + * @param Value: Data to be written + * @retval None + */ +void AUDIO_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value) +{ + I2C1_WriteBuffer(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1); +} + +/** + * @brief Reads a single data. + * @param Addr: I2C address + * @param Reg: Reg address + * @retval Data to be read + */ +uint8_t AUDIO_IO_Read(uint8_t Addr, uint8_t Reg) +{ + uint8_t Read_Value = 0; + + I2C1_ReadBuffer((uint16_t) Addr, (uint16_t) Reg, I2C_MEMADD_SIZE_8BIT, &Read_Value, 1); + + return Read_Value; +} + +/** + * @brief AUDIO Codec delay + * @param Delay: Delay in ms + * @retval None + */ +void AUDIO_IO_Delay(uint32_t Delay) +{ + HAL_Delay(Delay); +} +#endif /* HAL_I2C_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,566 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery.h + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file contains definitions for STM32L476G_DISCOVERY's LEDs, + * push-buttons hardware resources (MB1184). + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L476G_DISCOVERY_H +#define __STM32L476G_DISCOVERY_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @brief Define for STM32L476G_DISCOVERY board + */ +#if !defined (USE_STM32L476G_DISCO_REVC) && !defined (USE_STM32L476G_DISCO_REVB) && !defined (USE_STM32L476G_DISCO_REVA) +#define USE_STM32L476G_DISCO_REVC +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY_Common + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_Exported_Types Exported Types + * @{ + */ + +/** + * @brief LED Types Definition + */ +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +typedef enum +{ + LED4 = 0, + LED5 = 1, + LED_RED = LED4, + LED_GREEN = LED5 +}Led_TypeDef; +#elif defined (USE_STM32L476G_DISCO_REVA) +typedef enum +{ + LED3 = 0, + LED4 = 1, + LED_RED = LED3, + LED_GREEN = LED4 +}Led_TypeDef; +#endif + +/** + * @brief JOYSTICK Types Definition + */ +typedef enum +{ + JOY_SEL = 0, + JOY_LEFT = 1, + JOY_RIGHT = 2, + JOY_DOWN = 3, + JOY_UP = 4, + JOY_NONE = 5 +}JOYState_TypeDef; + +typedef enum +{ + JOY_MODE_GPIO = 0, + JOY_MODE_EXTI = 1 +}JOYMode_TypeDef; + +typedef enum +{ + SUPPLY_MODE_ERROR = 0, + SUPPLY_MODE_EXTERNAL = 1, + SUPPLY_MODE_BATTERY = 2 +}SupplyMode_TypeDef; + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_BATTERY BATTERY Detection Constants + * @{ + */ +#define BATTERY_DETECTION_PIN GPIO_PIN_3 +#define BATTERY_DETECTION_GPIO_PORT GPIOB +#define BATTERY_DETECTION_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define BATTERY_DETECTION_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_LED LED Constants + * @{ + */ +#define LEDn 2 + +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +#define LED4_PIN GPIO_PIN_2 +#define LED4_GPIO_PORT GPIOB +#define LED4_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define LED4_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() + +#define LED5_PIN GPIO_PIN_8 +#define LED5_GPIO_PORT GPIOE +#define LED5_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define LED5_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() + +#define LEDx_GPIO_CLK_ENABLE(__LED__) do { if((__LED__) == LED4) { LED4_GPIO_CLK_ENABLE(); } else \ + if((__LED__) == LED5) { LED5_GPIO_CLK_ENABLE(); } } while(0) + +#define LEDx_GPIO_CLK_DISABLE(__LED__) do { if((__LED__) == LED4) { LED4_GPIO_CLK_DISABLE(); } else \ + if((__LED__) == LED5) { LED5_GPIO_CLK_DISABLE(); } } while(0) + +#elif defined (USE_STM32L476G_DISCO_REVA) +#define LED3_PIN GPIO_PIN_2 +#define LED3_GPIO_PORT GPIOB +#define LED3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define LED3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() + +#define LED4_PIN GPIO_PIN_8 +#define LED4_GPIO_PORT GPIOE +#define LED4_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define LED4_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() + +#define LEDx_GPIO_CLK_ENABLE(__LED__) do { if((__LED__) == LED3) { LED3_GPIO_CLK_ENABLE(); } else \ + if((__LED__) == LED4) { LED4_GPIO_CLK_ENABLE(); } } while(0) + +#define LEDx_GPIO_CLK_DISABLE(__LED__) do { if((__LED__) == LED3) { LED3_GPIO_CLK_DISABLE(); } else \ + if((__LED__) == LED4) { LED4_GPIO_CLK_DISABLE(); } } while(0) + +#endif +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_BUTTON BUTTON Constants + * @{ + */ +#define JOYn 5 + +/** +* @brief Joystick Right push-button +*/ +#define RIGHT_JOY_PIN GPIO_PIN_2 /* PA.02 */ +#define RIGHT_JOY_GPIO_PORT GPIOA +#define RIGHT_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define RIGHT_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() +#define RIGHT_JOY_EXTI_IRQn EXTI2_IRQn + +/** +* @brief Joystick Left push-button +*/ +#define LEFT_JOY_PIN GPIO_PIN_1 /* PA.01 */ +#define LEFT_JOY_GPIO_PORT GPIOA +#define LEFT_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define LEFT_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() +#define LEFT_JOY_EXTI_IRQn EXTI1_IRQn + +/** +* @brief Joystick Up push-button +*/ +#define UP_JOY_PIN GPIO_PIN_3 /* PA.03 */ +#define UP_JOY_GPIO_PORT GPIOA +#define UP_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define UP_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() +#define UP_JOY_EXTI_IRQn EXTI3_IRQn + +/** + * @brief Joystick Down push-button + */ +#define DOWN_JOY_PIN GPIO_PIN_5 /* PA.05 */ +#define DOWN_JOY_GPIO_PORT GPIOA +#define DOWN_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define DOWN_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() +#define DOWN_JOY_EXTI_IRQn EXTI9_5_IRQn + +/** + * @brief Joystick Sel push-button + */ +#define SEL_JOY_PIN GPIO_PIN_0 /* PA.00 */ +#define SEL_JOY_GPIO_PORT GPIOA +#define SEL_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SEL_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() +#define SEL_JOY_EXTI_IRQn EXTI0_IRQn + +#define JOYx_GPIO_CLK_ENABLE(__JOY__) do { if((__JOY__) == JOY_SEL) { SEL_JOY_GPIO_CLK_ENABLE(); } else \ + if((__JOY__) == JOY_DOWN) { DOWN_JOY_GPIO_CLK_ENABLE(); } else \ + if((__JOY__) == JOY_LEFT) { LEFT_JOY_GPIO_CLK_ENABLE(); } else \ + if((__JOY__) == JOY_RIGHT) { RIGHT_JOY_GPIO_CLK_ENABLE(); } else \ + if((__JOY__) == JOY_UP) { UP_JOY_GPIO_CLK_ENABLE(); } } while(0) + +#define JOYx_GPIO_CLK_DISABLE(__JOY__) do { if((__JOY__) == JOY_SEL) { SEL_JOY_GPIO_CLK_DISABLE(); } else \ + if((__JOY__) == JOY_DOWN) { DOWN_JOY_GPIO_CLK_DISABLE(); } else \ + if((__JOY__) == JOY_LEFT) { LEFT_JOY_GPIO_CLK_DISABLE(); } else \ + if((__JOY__) == JOY_RIGHT) { RIGHT_JOY_GPIO_CLK_DISABLE(); } else \ + if((__JOY__) == JOY_UP) { UP_JOY_GPIO_CLK_DISABLE(); } } while(0) + +#define JOY_ALL_PINS (RIGHT_JOY_PIN | LEFT_JOY_PIN | UP_JOY_PIN | DOWN_JOY_PIN | SEL_JOY_PIN) + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_BUS BUS Constants + * @{ + */ +#if defined(HAL_SPI_MODULE_ENABLED) +/*##################### SPI2 ###################################*/ +#define DISCOVERY_SPIx SPI2 +#define DISCOVERY_SPIx_CLOCK_ENABLE() __HAL_RCC_SPI2_CLK_ENABLE() +#define DISCOVERY_SPIx_CLOCK_DISABLE() __HAL_RCC_SPI2_CLK_DISABLE() +#define DISCOVERY_SPIx_GPIO_PORT GPIOD /* GPIOD */ +#define DISCOVERY_SPIx_AF GPIO_AF5_SPI2 +#define DISCOVERY_SPIx_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define DISCOVERY_SPIx_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE() +#define DISCOVERY_SPIx_GPIO_FORCE_RESET() __HAL_RCC_SPI2_FORCE_RESET() +#define DISCOVERY_SPIx_GPIO_RELEASE_RESET() __HAL_RCC_SPI2_RELEASE_RESET() +#define DISCOVERY_SPIx_SCK_PIN GPIO_PIN_1 /* PD.01*/ +#define DISCOVERY_SPIx_MISO_PIN GPIO_PIN_3 /* PD.03 */ +#define DISCOVERY_SPIx_MOSI_PIN GPIO_PIN_4 /* PD.04 */ + +/* Maximum Timeout values for flags waiting loops. These timeouts are not based + on accurate values, they just guarantee that the application will not remain + stuck if the SPI communication is corrupted. + You may modify these timeout values depending on CPU frequency and application + conditions (interrupts routines ...). */ +#define SPIx_TIMEOUT_MAX ((uint32_t)0x1000) +/* Read/Write command */ +#define READWRITE_CMD ((uint8_t)0x80) +/* Multiple byte read/write command */ +#define MULTIPLEBYTE_CMD ((uint8_t)0x40) +/* Dummy Byte Send by the SPI Master device in order to generate the Clock to the Slave device */ +#define DUMMY_BYTE ((uint8_t)0x00) + +#endif /* HAL_SPI_MODULE_ENABLED */ + +#if defined(HAL_I2C_MODULE_ENABLED) +/*##################### I2C1 ###################################*/ +/* User can use this section to tailor I2C1 instance used and associated + resources */ +/* Definition for I2C1 Pins */ +#define DISCOVERY_I2C1_SCL_GPIO_PORT GPIOB +#define DISCOVERY_I2C1_SDA_GPIO_PORT GPIOB +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +#define DISCOVERY_I2C1_SCL_PIN GPIO_PIN_6 +#define DISCOVERY_I2C1_SDA_PIN GPIO_PIN_7 +#elif defined (USE_STM32L476G_DISCO_REVA) +#define DISCOVERY_I2C1_SCL_PIN GPIO_PIN_8 +#define DISCOVERY_I2C1_SDA_PIN GPIO_PIN_9 +#endif +#define DISCOVERY_I2C1_SCL_SDA_AF GPIO_AF4_I2C1 + +/* Definition for I2C1 clock resources */ +#define DISCOVERY_I2C1 I2C1 +#define DISCOVERY_I2C1_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE() +#define DISCOVERY_I2C1_CLK_DISABLE() __HAL_RCC_I2C1_CLK_DISABLE() +#define DISCOVERY_I2C1_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define DISCOVERY_I2C1_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define DISCOVERY_I2C1_SDA_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define DISCOVERY_I2C1_SCL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define DISCOVERY_I2C1_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET() +#define DISCOVERY_I2C1_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET() + +/* Definition for I2C1's NVIC */ +#define DISCOVERY_I2C1_EV_IRQn I2C1_EV_IRQn +#define DISCOVERY_I2C1_EV_IRQHandler I2C1_EV_IRQHandler +#define DISCOVERY_I2C1_ER_IRQn I2C1_ER_IRQn +#define DISCOVERY_I2C1_ER_IRQHandler I2C1_ER_IRQHandler + +/* I2C TIMING Register define when I2C clock source is SYSCLK */ +/* I2C TIMING is calculated in case of the I2C Clock source is the SYSCLK = 80 MHz */ +/* Set 0x90112626 value to reach 100 KHz speed (Rise time = 640ns, Fall time = 20ns) */ +#ifndef DISCOVERY_I2C1_TIMING + #define DISCOVERY_I2C1_TIMING 0x90112626 +#endif /* DISCOVERY_I2C1_TIMING */ + +/* I2C clock speed configuration (in Hz) + WARNING: + Make sure that this define is not already declared in other files (ie. + stm324xg_discovery.h file). It can be used in parallel by other modules. */ +#ifndef BSP_I2C_SPEED + #define BSP_I2C_SPEED 100000 +#endif /* BSP_I2C_SPEED */ + + +/* Audio codec I2C address */ +#define AUDIO_I2C_ADDRESS ((uint16_t) 0x94) + +/* Maximum Timeout values for flags waiting loops. These timeouts are not based + on accurate values, they just guarantee that the application will not remain + stuck if the I2C communication is corrupted. + You may modify these timeout values depending on CPU frequency and application + conditions (interrupts routines ...). */ +#define DISCOVERY_I2C1_TIMEOUT_MAX 3000 + + +/*##################### I2C2 ###################################*/ +/* User can use this section to tailor I2C2 instance used and associated + resources */ +/* Definition for I2C2 Pins */ +#define DISCOVERY_I2C2_SCL_PIN GPIO_PIN_10 +#define DISCOVERY_I2C2_SCL_GPIO_PORT GPIOB +#define DISCOVERY_I2C2_SDA_PIN GPIO_PIN_11 +#define DISCOVERY_I2C2_SDA_GPIO_PORT GPIOB +#define DISCOVERY_I2C2_SCL_SDA_AF GPIO_AF4_I2C2 +/* Definition for I2C2 clock resources */ +#define DISCOVERY_I2C2 I2C2 +#define DISCOVERY_I2C2_CLK_ENABLE() __HAL_RCC_I2C2_CLK_ENABLE() +#define DISCOVERY_I2C2_CLK_DISABLE() __HAL_RCC_I2C2_CLK_DISABLE() +#define DISCOVERY_I2C2_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define DISCOVERY_I2C2_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define DISCOVERY_I2C2_SDA_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define DISCOVERY_I2C2_SCL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define DISCOVERY_I2C2_FORCE_RESET() __HAL_RCC_I2C2_FORCE_RESET() +#define DISCOVERY_I2C2_RELEASE_RESET() __HAL_RCC_I2C2_RELEASE_RESET() + +/* Definition for I2C2's NVIC */ +#define DISCOVERY_I2C2_EV_IRQn I2C2_EV_IRQn +#define DISCOVERY_I2C2_ER_IRQn I2C2_ER_IRQn + +/* I2C TIMING Register define when I2C clock source is SYSCLK */ +/* I2C TIMING is calculated in case of the I2C Clock source is the SYSCLK = 80 MHz */ +/* Set 0x90112626 value to reach 100 KHz speed (Rise time = 640ns, Fall time = 20ns) */ +#ifndef DISCOVERY_I2C2_TIMING + #define DISCOVERY_I2C2_TIMING 0x90112626 +#endif /* DISCOVERY_I2C2_TIMING */ + +/* I2C clock speed configuration (in Hz) + WARNING: + Make sure that this define is not already declared in other files (ie. + stm324xg_discovery.h file). It can be used in parallel by other modules. */ +#ifndef BSP_I2C_SPEED + #define BSP_I2C_SPEED 100000 +#endif /* BSP_I2C_SPEED */ + +#define IDD_I2C_ADDRESS ((uint16_t) 0x84) + +/* Maximum Timeout values for flags waiting loops. These timeouts are not based + on accurate values, they just guarantee that the application will not remain + stuck if the I2C communication is corrupted. + You may modify these timeout values depending on CPU frequency and application + conditions (interrupts routines ...). */ +#define DISCOVERY_I2C2_TIMEOUT_MAX 3000 +#endif /* HAL_I2C_MODULE_ENABLED */ + +/*##################### Accelerometer ##########################*/ +/** + * @brief Accelerometer Chip Select macro definition + */ +#define ACCELERO_CS_LOW() HAL_GPIO_WritePin(ACCELERO_CS_GPIO_PORT, ACCELERO_CS_PIN, GPIO_PIN_RESET) +#define ACCELERO_CS_HIGH() HAL_GPIO_WritePin(ACCELERO_CS_GPIO_PORT, ACCELERO_CS_PIN, GPIO_PIN_SET) + +/** + * @brief Accelerometer SPI Interface pins + */ +#define ACCELERO_CS_GPIO_PORT GPIOE /* GPIOE */ +#define ACCELERO_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define ACCELERO_CS_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() +#define ACCELERO_CS_PIN GPIO_PIN_0 /* PE.00 */ + +/** + * @brief Accelerometer Interrupt pins + */ +#define ACCELERO_XLINT_GPIO_PORT GPIOE /* GPIOE */ +#define ACCELERO_XLINT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define ACCELERO_XLINT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() +#define ACCELERO_XLINT_PIN GPIO_PIN_1 /* PE.01 */ +#define ACCELERO_XLINT_EXTI_IRQn EXTI1_IRQn + +/*##################### Magnetometer ##########################*/ +/** + * @brief Magnetometer Chip Select macro definition + */ +#define MAGNETO_CS_LOW() HAL_GPIO_WritePin(MAGNETO_CS_GPIO_PORT, MAGNETO_CS_PIN, GPIO_PIN_RESET) +#define MAGNETO_CS_HIGH() HAL_GPIO_WritePin(MAGNETO_CS_GPIO_PORT, MAGNETO_CS_PIN, GPIO_PIN_SET) + +/** + * @brief Magnetometer SPI Interface pins + */ +#define MAGNETO_CS_GPIO_PORT GPIOC /* GPIOC */ +#define MAGNETO_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define MAGNETO_CS_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE() +#define MAGNETO_CS_PIN GPIO_PIN_0 /* PC.00 */ + + +/** + * @brief Magnetometer Interrupt pins + */ +#define MAGNETO_INT_GPIO_PORT GPIOC /* GPIOC */ +#define MAGNETO_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define MAGNETO_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE() +#define MAGNETO_INT1_PIN GPIO_PIN_1 /* PC.01 */ +#define MAGNETO_INT1_EXTI_IRQn EXTI1_IRQn + +#define MAGNETO_DRDY_GPIO_PORT GPIOC /* GPIOC */ +#define MAGNETO_DRDY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define MAGNETO_DRDY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE() +#define MAGNETO_DRDY_PIN GPIO_PIN_2 /* PC.01 */ + + +/*##################### Audio Codec ##########################*/ +/** + * @brief Audio codec chip reset definition + */ +/* Audio codec power on/off macro definition */ +#define CODEC_AUDIO_POWER_OFF() HAL_GPIO_WritePin(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, GPIO_PIN_RESET) +#define CODEC_AUDIO_POWER_ON() HAL_GPIO_WritePin(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, GPIO_PIN_SET) + +/* Audio Reset Pin definition */ +#define AUDIO_RESET_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define AUDIO_RESET_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() +#define AUDIO_RESET_PIN GPIO_PIN_3 +#define AUDIO_RESET_GPIO GPIOE + +/*##################### Gyroscope ##########################*/ +/** + * @brief Gyroscope Chip Select macro definition + */ +#define GYRO_CS_LOW() HAL_GPIO_WritePin(GYRO_CS_GPIO_PORT, GYRO_CS_PIN, GPIO_PIN_RESET) +#define GYRO_CS_HIGH() HAL_GPIO_WritePin(GYRO_CS_GPIO_PORT, GYRO_CS_PIN, GPIO_PIN_SET) + +/** + * @brief Gyroscope SPI Interface pins + */ +#define GYRO_CS_GPIO_PORT GPIOD /* GPIOD */ +#define GYRO_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define GYRO_CS_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE() +#define GYRO_CS_PIN GPIO_PIN_7 /* PD.07 */ + +/** + * @brief Gyroscope Interrupt pins + */ +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +#define GYRO_INT1_GPIO_PORT GPIOD /* GPIOD */ +#define GYRO_INT1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define GYRO_INT1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE() +#define GYRO_INT1_PIN GPIO_PIN_2 /* PD.02 */ +#define GYRO_INT1_EXTI_IRQn EXTI2_IRQn +#define GYRO_INT2_GPIO_PORT GPIOB /* GPIOB */ +#define GYRO_INT2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define GYRO_INT2_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define GYRO_INT2_PIN GPIO_PIN_8 /* PB.08 */ +#define GYRO_INT2_EXTI_IRQn EXTI9_5_IRQn +#elif defined (USE_STM32L476G_DISCO_REVA) +#define GYRO_INT1_GPIO_PORT GPIOB /* GPIOB */ +#define GYRO_INT1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define GYRO_INT1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define GYRO_INT1_PIN GPIO_PIN_6 /* PB.06 */ +#define GYRO_INT1_EXTI_IRQn EXTI9_5_IRQn +#define GYRO_INT2_GPIO_PORT GPIOB /* GPIOB */ +#define GYRO_INT2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define GYRO_INT2_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define GYRO_INT2_PIN GPIO_PIN_7 /* PB.07 */ +#define GYRO_INT2_EXTI_IRQn EXTI9_5_IRQn +#endif + +/*##################### Idd ##########################*/ +/** + * @brief Idd current measurement interface pins + */ +#define IDD_INT_GPIO_PORT GPIOC /* GPIOC */ +#define IDD_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define IDD_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE() +#define IDD_INT_PIN GPIO_PIN_13 /* PC.13 */ +#define IDD_INT_EXTI_IRQn EXTI15_10_IRQn + +#define IDD_WAKEUP_GPIO_PORT GPIOA /* GPIOA */ +#define IDD_WAKEUP_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define IDD_WAKEUP_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() +#define IDD_WAKEUP_PIN GPIO_PIN_4 /* PA.04 */ + +/** + * @} + */ + +/** + * @} + */ + + +/** @defgroup STM32L476G_DISCOVERY_Exported_Functions Exported Functions + * @{ + */ +uint32_t BSP_GetVersion(void); +SupplyMode_TypeDef BSP_SupplyModeDetection(void); +void BSP_LED_Init(Led_TypeDef Led); +void BSP_LED_DeInit(Led_TypeDef Led); +void BSP_LED_On(Led_TypeDef Led); +void BSP_LED_Off(Led_TypeDef Led); +void BSP_LED_Toggle(Led_TypeDef Led); +uint8_t BSP_JOY_Init(JOYMode_TypeDef Joy_Mode); +void BSP_JOY_DeInit(void); +JOYState_TypeDef BSP_JOY_GetState(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L476G_DISCOVERY_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_audio.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,1422 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_audio.c + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file provides a set of functions needed to manage the + * Audio driver for the STM32L476G-Discovery board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/*============================================================================== + User NOTES + +1. How To use this driver: +-------------------------- + + This driver supports STM32L4xx devices on STM32L476G-Discovery (MB1184) Discovery boards. + a) to play an audio file (all functions names start by BSP_AUDIO_OUT_xxx) + b) to record an audio file through MP34DT01TR, ST MEMS (all functions names start by BSP_AUDIO_IN_xxx) + +a) PLAY A FILE: +============== + + Call the function BSP_AUDIO_OUT_Init( + OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, + OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH) + Volume : Initial volume to be set (0 is min (mute), 100 is max (100%) + AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...) + this parameter is relative to the audio file/stream type. + ) + This function configures all the hardware required for the audio application (codec, I2C, SAI, + GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK. + If the returned value is different from AUDIO_OK or the function is stuck then the communication with + the audio codec has failed. + - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream. + - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream. + - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream + at the same time. + + + Call the function BSP_AUDIO_OUT_RegisterCallbacks to register user callbacks + required to manage audio data streaming towards the audio codec (ErrorCallback(), + HalfTransfer_CallBack() and TransferComplete_CallBack()). + + + Call the function BSP_AUDIO_OUT_Play() to start audio playback (for the first time). + + Call the function BSP_AUDIO_OUT_Pause() to pause audio playabck + + Call the function BSP_AUDIO_OUT_Resume() to resume audio playback. + Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called + for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case). + Note. This function should be called only when the audio file is played or paused (not stopped). + + Call the function BSP_AUDIO_OUT_Stop() to stop audio playback. + + To modify the volume level, the sampling frequency, the device output mode, + the mute status or the audio configuration or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(), + AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetOutputMode(), BSP_AUDIO_OUT_SetMute()and + BSP_AUDIO_OUT_ChangeAudioConfig(). + +Driver architecture: +-------------------- + + This driver provides the audio layer high level API: it consists in functions + exported in the stm32l476g_discovery_audio.h file (e.g. BSP_AUDIO_OUT_Init(), + BSP_AUDIO_OUT_Play(), ...). + + This driver also includes the Media Access Layer (MAL): it consists in + functions allowing to access setup the audio devices. These functions + are included as local functions into the stm32l476g_discovery_audio.c file + (e.g. AUDIO_SAIx_Init()). + +Known Limitations: +------------------ + 1- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some + user interrupt routines (in this case, interrupts could be disabled just before the start of + communication then re-enabled when it is over). Note that this communication is only done at + the configuration phase (BSP_AUDIO_OUT_Init() or BSP_AUDIO_OUT_Stop()) and when Volume control modification is + performed (BSP_AUDIO_OUT_SetVolume() or BSP_AUDIO_OUT_SetMute()or BSP_AUDIO_OUT_SetOutputMode()). + When the audio data is played, no communication is required with the audio codec. + 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, + File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file. + 3- Supports only 16-bits audio data size. + +b) RECORD A FILE: +================ + + Call the function BSP_AUDIO_IN_Init( + AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...) + ) + This function configures all the hardware required for the audio application (DFSDM, + GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if the + configuration completes successfully. + + + Call the function BSP_AUDIO_IN_RegisterCallbacks to register user callbacks + used to stream audio data toward the record buffer (ErrorCallback(), + HalfTransfer_CallBack() and TransferComplete_CallBack()). + + + Call the function BSP_AUDIO_IN_Record( + pbuf Main buffer pointer for the recorded data storing + size Current size of the recorded buffer + ) + to start recording from the microphone. + + + Call the function AUDIO_IN_STOP() to stop recording +==============================================================================*/ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include "stm32l476g_discovery_audio.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_AUDIO STM32L476G-DISCOVERY AUDIO + * @brief This file includes the low layer driver for cs43l22 Audio Codec + * available on STM32L476G-Discovery board(MB1184). + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Types Private Types + * @{ + */ +typedef struct +{ + AUDIO_DrvTypeDef * AudioDrv; /* Audio codec driver */ + Audio_CallbackTypeDef CbError; /* pointer to the callback function invoked when ... */ + Audio_CallbackTypeDef CbHalfTransfer; /* pointer to the callback function invoked when ... */ + Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when ... */ +} AUDIO_OUT_TypeDef; + +typedef struct +{ + DFSDM_Channel_HandleTypeDef hDfsdmLeftChannel; /* DFSDM channel handle used for left channel */ + DMA_HandleTypeDef hDmaDfsdmLeft; /* DMA handle used for DFSDM regular conversions on left channel */ + int32_t * LeftRecBuff; /* Buffers for left samples */ + uint32_t Frequency; /* Record Frequency */ + uint32_t BitResolution; /* Record bit resolution */ + uint32_t ChannelNbr; /* Record Channel Number */ + uint16_t * pRecBuf; /* Pointer to record user buffer */ + uint32_t RecSize; /* Size to record in mono, double size to record in stereo */ + Audio_CallbackTypeDef CbError; /* pointer to the callback function invoked when a DMA transfer fails */ + Audio_CallbackTypeDef CbHalfTransfer; /* pointer to the callback function invoked when half of the DMA transfer is completed */ + Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when the DMA transfer is completed */ +} AUDIO_IN_TypeDef; + +/** + * @} + */ + +/* Private defines ------------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Constants Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Macros Private Macros + * @{ + */ +/*### PLAY ###*/ +/* SCK(kHz) = SAI_CK_x/(SAIClockDivider*2*256) */ +#define SAIClockDivider(__FREQUENCY__) \ + (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 12 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 2 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 1 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 2 : 1 \ + +/*### RECORD ###*/ +#define DFSDMOverSampling(__FREQUENCY__) \ + (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 256 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 256 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 128 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 128 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 64 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 64 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 16 \ + +#define DFSDMClockDivider(__FREQUENCY__) \ + (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 24 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 4 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 24 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 24 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 4 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 32 \ + +#define DFSDMFilterOrder(__FREQUENCY__) \ + (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? DFSDM_FILTER_SINC3_ORDER \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? DFSDM_FILTER_SINC3_ORDER \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? DFSDM_FILTER_SINC3_ORDER \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? DFSDM_FILTER_SINC3_ORDER \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? DFSDM_FILTER_SINC4_ORDER \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? DFSDM_FILTER_SINC4_ORDER \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? DFSDM_FILTER_SINC4_ORDER : DFSDM_FILTER_SINC5_ORDER \ + +#define DFSDMRightBitShift(__FREQUENCY__) \ + (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 2 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 3 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 3 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 0 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 3 \ + : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 7 : 0 \ + +/* Saturate the record PCM sample */ +#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N))) + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Variables Private Variables + * @{ + */ +/* Audio output context information */ +static AUDIO_OUT_TypeDef hAudioOut; + +/* Audio input context information */ +static AUDIO_IN_TypeDef hAudioIn; + +/* SAI DMA handle */ +static DMA_HandleTypeDef hDmaSai; +/** + * @} + */ + +/* Exported variables ---------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Variables Exported Variables + * @{ + */ +/* SAIx handle */ +SAI_HandleTypeDef BSP_AUDIO_hSai; + +/* DFSDM filter handle */ +DFSDM_Filter_HandleTypeDef BSP_AUDIO_hDfsdmLeftFilter; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Functions Private Functions + * @{ + */ +static void AUDIO_CODEC_Reset(void); +static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq); +static uint8_t AUDIO_SAIx_DeInit(void); +static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq); +static uint8_t AUDIO_DFSDMx_DeInit(void); +static uint8_t AUDIO_SAIPLLConfig(uint32_t AudioFreq); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup STM32L476G_DISCOVERY_AUDIO_Exported_Functions + * @{ + */ + +/** + * @brief Configures the audio codec related peripherals. + * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, + * or OUTPUT_DEVICE_BOTH. + * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) + * @param AudioFreq: Audio frequency used to play the audio stream.ion. + * @retval BSP AUDIO status + * @note The SAI PLL input clock must be configure in the user application. + * The SAI PLL configuration done within this function assumes that + * the SAI PLL input clock runs at 8 MHz. + */ +uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, + uint8_t Volume, + uint32_t AudioFreq) +{ + /* Initialize the audio output context */ + hAudioOut.AudioDrv = &cs43l22_drv; + hAudioOut.CbError = (Audio_CallbackTypeDef)NULL; + hAudioOut.CbHalfTransfer = (Audio_CallbackTypeDef)NULL; + hAudioOut.CbTransferComplete = (Audio_CallbackTypeDef)NULL; + + /* Configure the SAI PLL according to the requested audio frequency */ + if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* SAI data transfer preparation: prepare the Media to be used for the audio + transfer from memory to SAI peripheral. */ + if (AUDIO_SAIx_Init(AudioFreq) != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* Retieve audio codec identifier */ + if (cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS) != CS43L22_ID) + { + return AUDIO_ERROR; + } + + /* Reset the audio codec Registers */ + AUDIO_CODEC_Reset(); + + /* Initialize the audio codec internal registers */ + if (hAudioOut.AudioDrv->Init(AUDIO_I2C_ADDRESS, + OutputDevice, + Volume, + AudioFreq) != 0) + { + return AUDIO_ERROR; + } + + /* Set the requested volume */ + BSP_AUDIO_OUT_SetVolume(Volume); + + return AUDIO_OK; +} + +/** + * @brief De-Initializes audio codec related peripherals + * @retval BSP AUDIO status + + */ +uint8_t BSP_AUDIO_OUT_DeInit(void) +{ + /* De-initializes the Audio Codec audio interface */ + if (AUDIO_SAIx_DeInit() != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* DeInit Audio component interface */ + hAudioOut.AudioDrv->DeInit(); + + return AUDIO_OK; +} + +/** + * @brief Starts playing audio stream from a data buffer for a determined size. + * @param pData: pointer on PCM samples buffer + * @param Size: Number of audio data BYTES. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_Play(uint16_t* pData, uint32_t Size) +{ + /* Initiate a DMA transfer of PCM samples towards the serial audio interface */ + if (HAL_SAI_Transmit_DMA(&BSP_AUDIO_hSai, (uint8_t *)pData, DMA_MAX(Size))!= HAL_OK) + { + return AUDIO_ERROR; + } + + /* Call the audio Codec Play function */ + if (hAudioOut.AudioDrv->Play(AUDIO_I2C_ADDRESS, pData, Size) != 0) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; + } + +/** + * @brief Sends n-Bytes on the SAI interface. + * @param pData: pointer on PCM samples buffer + * @param Size: number of data to be written + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size) +{ + /* Initiate a DMA transfer of PCM samples towards the serial audio interface */ + if (HAL_SAI_Transmit_DMA(&BSP_AUDIO_hSai, (uint8_t *)pData, Size)!= HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief This function Pauses the audio file stream. In case + * of using DMA, the DMA Pause feature is used. + * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only + * BSP_AUDIO_OUT_Resume() function should be called for resume + * (use of BSP_AUDIO_OUT_Play() function for resume could lead + * to unexpected behavior). + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_Pause(void) +{ + /* Call the Audio Codec Pause function */ + if (hAudioOut.AudioDrv->Pause(AUDIO_I2C_ADDRESS) != 0) + { + return AUDIO_ERROR; + } + + /* Pause DMA transfer of PCM samples towards the serial audio interface */ + if (HAL_SAI_DMAPause(&BSP_AUDIO_hSai)!= HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief This function Resumes the audio file stream. + * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only + * BSP_AUDIO_OUT_Resume() function should be called for resume + * (use of BSP_AUDIO_OUT_Play() function for resume could lead to + * unexpected behavior). + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_Resume(void) +{ + /* Call the Audio Codec Resume function */ + if (hAudioOut.AudioDrv->Resume(AUDIO_I2C_ADDRESS) != 0) + { + return AUDIO_ERROR; + } + + /* Resume DMA transfer of PCM samples towards the serial audio interface */ + if (HAL_SAI_DMAResume(&BSP_AUDIO_hSai)!= HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief Stops audio playing and Power down the Audio Codec. + * @param Option: could be one of the following parameters + * - CODEC_PDWN_SW: for software power off (by writing registers). + * Then no need to reconfigure the Codec after power on. + * - CODEC_PDWN_HW: completely shut down the codec (physically). + * Then need to reconfigure the Codec after power on. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option) +{ + /* Call Audio Codec Stop function */ + if (hAudioOut.AudioDrv->Stop(AUDIO_I2C_ADDRESS, Option) != 0) + { + return AUDIO_ERROR; + } + + if(Option == CODEC_PDWN_HW) + { + /* Wait at least 100us */ + HAL_Delay(1); + } + + /* Stop DMA transfer of PCM samples towards the serial audio interface */ + if (HAL_SAI_DMAStop(&BSP_AUDIO_hSai)!= HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief Controls the current audio volume level. + * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for + * Mute and 100 for Max volume level). + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume) +{ + /* Call the codec volume control function with converted volume value */ + if (hAudioOut.AudioDrv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief Enables or disables the MUTE mode by software + * @param Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to + * unmute the codec and restore previous volume level. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd) +{ + /* Call the Codec Mute function */ + if (hAudioOut.AudioDrv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief Switch dynamically (while audio file is being played) the output + * target (speaker or headphone). + * @param Output: The audio output target: OUTPUT_DEVICE_SPEAKER, + * OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output) +{ + /* Call the Codec output device function */ + if (hAudioOut.AudioDrv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief Updates the audio frequency. + * @param AudioFreq: Audio frequency used to play the audio stream. + * @note The SAI PLL input clock must be configure in the user application. + * The SAI PLL configuration done within this function assumes that + * the SAI PLL input clock runs at 8 MHz. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq) +{ + /* Configure the SAI PLL according to the requested audio frequency */ + if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* Disable SAI peripheral to allow access to SAI internal registers */ + __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); + + /* Update the SAI audio frequency configuration */ + BSP_AUDIO_hSai.Init.Mckdiv = SAIClockDivider(AudioFreq); + HAL_SAI_Init(&BSP_AUDIO_hSai); + + /* Enable SAI peripheral to generate MCLK */ + __HAL_SAI_ENABLE(&BSP_AUDIO_hSai); + + return AUDIO_OK; +} + +/** + * @brief Changes the Audio Out Configuration. + * @param AudioOutOption: specifies the audio out new configuration + * This parameter can be any value of @ref BSP_Audio_Out_Option + * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the + * audio out configuration. + * @retval None + */ +void BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption) +{ + /********** Playback Buffer circular/normal mode **********/ + if(AudioOutOption & BSP_AUDIO_OUT_CIRCULARMODE) + { + /* Deinitialize the Stream to update DMA mode */ + HAL_DMA_DeInit(BSP_AUDIO_hSai.hdmatx); + + /* Update the SAI audio Transfer DMA mode */ + BSP_AUDIO_hSai.hdmatx->Init.Mode = DMA_CIRCULAR; + + /* Configure the DMA Stream with new Transfer DMA mode */ + HAL_DMA_Init(BSP_AUDIO_hSai.hdmatx); + } + else /* BSP_AUDIO_OUT_NORMALMODE */ + { + /* Deinitialize the Stream to update DMA mode */ + HAL_DMA_DeInit(BSP_AUDIO_hSai.hdmatx); + + /* Update the SAI audio Transfer DMA mode */ + BSP_AUDIO_hSai.hdmatx->Init.Mode = DMA_NORMAL; + + /* Configure the DMA Stream with new Transfer DMA mode */ + HAL_DMA_Init(BSP_AUDIO_hSai.hdmatx); + } + + /********** Playback Buffer stereo/mono mode **********/ + if(AudioOutOption & BSP_AUDIO_OUT_STEREOMODE) + { + /* Disable SAI peripheral to allow access to SAI internal registers */ + __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); + + /* Update the SAI audio frame slot configuration */ + BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE; + HAL_SAI_Init(&BSP_AUDIO_hSai); + + /* Enable SAI peripheral to generate MCLK */ + __HAL_SAI_ENABLE(&BSP_AUDIO_hSai); + } + else /* BSP_AUDIO_OUT_MONOMODE */ + { + /* Disable SAI peripheral to allow access to SAI internal registers */ + __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); + + /* Update the SAI audio frame slot configuration */ + BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_MONOMODE; + HAL_SAI_Init(&BSP_AUDIO_hSai); + + /* Enable SAI peripheral to generate MCLK */ + __HAL_SAI_ENABLE(&BSP_AUDIO_hSai); + } +} + +/** + * @brief register user callback functions + * @param ErrorCallback: pointer to the error callback function + * @param HalfTransferCallback: pointer to the half transfer callback function + * @param TransferCompleteCallback: pointer to the transfer complete callback function + * @retval None + */ +void BSP_AUDIO_OUT_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback, + Audio_CallbackTypeDef HalfTransferCallback, + Audio_CallbackTypeDef TransferCompleteCallback) +{ + hAudioOut.CbError = ErrorCallback; + hAudioOut.CbHalfTransfer = HalfTransferCallback; + hAudioOut.CbTransferComplete = TransferCompleteCallback; +} + +/** + * @brief Tx Transfer completed callbacks. + * @param hsai: SAI handle + * @retval None + */ +void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* Invoke the registered 'TransferComplete' function (if any) */ + if (hAudioOut.CbTransferComplete != (Audio_CallbackTypeDef)NULL) + { + hAudioOut.CbTransferComplete(); + } +} + +/** + * @brief Tx Half Transfer completed callbacks. + * @param hsai: SAI handle + * @retval None + */ +void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* Invoke the registered 'HalfTransfer' callback function (if any) */ + if (hAudioOut.CbHalfTransfer != (Audio_CallbackTypeDef)NULL) + { + hAudioOut.CbHalfTransfer(); + } +} + +/** + * @brief SAI error callbacks. + * @param hsai: SAI handle + * @retval None + */ +void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai) +{ + /* Invoke the registered 'ErrorCallback' callback function (if any) */ + if (hAudioOut.CbError != (Audio_CallbackTypeDef)NULL) + { + hAudioOut.CbError(); + } +} + +/** + * @} + */ + +/** @addtogroup STM32L476G_EVAL_AUDIO_Exported_Functions + * @{ + */ + +/** + * @brief Initializes micropone related peripherals. + * @note This function assumes that the SAI input clock (through PLL_M) + * is already configured and ready to be used. + * @param AudioFreq: Audio frequency to be configured for the SAI peripheral. + * @param BitRes: Audio frequency to be configured for the SAI peripheral. + * @param ChnlNbr: Audio frequency to be configured for the SAI peripheral. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr) +{ + /* Update the audio input context */ + hAudioIn.Frequency = AudioFreq; + hAudioIn.BitResolution = BitRes; + hAudioIn.ChannelNbr = ChnlNbr; + hAudioIn.CbError = (Audio_CallbackTypeDef)NULL; + hAudioIn.CbHalfTransfer = (Audio_CallbackTypeDef)NULL; + hAudioIn.CbTransferComplete = (Audio_CallbackTypeDef)NULL; + + /* Configure the SAI PLL according to the requested audio frequency */ + if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* Initializes the Digital Filter for Sigma-Delta Modulators interface */ + if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; + } + +/** + * @brief De-Initializes microphone related peripherals. + * @retval BSP AUDIO status + + */ +uint8_t BSP_AUDIO_IN_DeInit(void) +{ + /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */ + if (AUDIO_DFSDMx_DeInit() != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* Reset the audio input context */ + memset(&hAudioIn, 0, sizeof(hAudioIn)); + + return AUDIO_OK; +} + +/** + * @brief Starts audio recording. + * @param pbuf: Main buffer pointer for the recorded data storing + * @param size: Current size of the recorded buffer + * @note The Right channel is start at first with synchro on start of Left channel + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size) +{ + hAudioIn.pRecBuf = pbuf; + hAudioIn.RecSize = size; + + /* Allocate hAudioIn.LeftRecBuff buffer */ +#if defined(BSP_AUDIO_USE_RTOS) + hAudioIn.LeftRecBuff = (int32_t *)k_malloc(size * sizeof(int32_t)); +#else + hAudioIn.LeftRecBuff = (int32_t *)malloc(size * sizeof(int32_t)); +#endif + if(hAudioIn.LeftRecBuff == NULL) + { + return AUDIO_ERROR; + } + + /* Call the Media layer start function for left channel */ + if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter, + (int32_t*)hAudioIn.LeftRecBuff, + (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief Updates the audio frequency. + * @param AudioFreq: Audio frequency used to record the audio stream. + * @note This API should be called after the BSP_AUDIO_IN_Init() to adjust the + * audio frequency. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq) +{ + /* Configure the SAI PLL according to the requested audio frequency */ + if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */ + if(AUDIO_DFSDMx_DeInit() != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* Initializes the Digital Filter for Sigma-Delta Modulators interface */ + if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief Regular conversion complete callback. + * @note In interrupt mode, user has to read conversion value in this function + using HAL_DFSDM_FilterGetRegularValue. + * @param hdfsdm_filter : DFSDM filter handle. + * @retval None + */ +void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter) +{ + uint32_t index; + uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR); + + for(index = (recbufsize/2); index < recbufsize; index++) + { + hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760)); + } + + /* Invoke the registered 'TransferComplete' function (if any) */ + if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL) + { + hAudioIn.CbTransferComplete(); + } +} + +/** + * @brief Half regular conversion complete callback. + * @param hdfsdm_filter : DFSDM filter handle. + * @retval None + */ +void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter) +{ + uint32_t index; + uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR); + + + for(index = 0; index < (recbufsize/2); index++) + { + hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760)); + } + + /* Invoke the registered 'HalfTransfer' callback function (if any) */ + if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL) + { + hAudioIn.CbHalfTransfer(); + } +} + +/** + * @brief Error callback. + * @param hdfsdm_filter : DFSDM filter handle. + * @retval None + */ +void HAL_DFSDM_FilterErrorCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter) +{ + /* Invoke the registered 'ErrorCallback' callback function (if any) */ + if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL) + { + hAudioIn.CbError(); + } +} + +/** + * @brief Stops audio recording. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_IN_Stop(void) +{ + /* Call the Media layer stop function for left channel */ + if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK ) + { + return AUDIO_ERROR; + } + + /* Free hAudioIn.LeftRecBuff buffer */ +#if defined(BSP_AUDIO_USE_RTOS) + k_free((void *)hAudioIn.LeftRecBuff); +#else + free((void *)hAudioIn.LeftRecBuff); +#endif + + return AUDIO_OK; +} + +/** + * @brief Pauses the audio file stream. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_IN_Pause(void) +{ + /* Call the Media layer stop function */ + if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief Resumes the audio file stream. + * @retval BSP AUDIO status + */ +uint8_t BSP_AUDIO_IN_Resume(void) +{ + /* Call the Media layer start function for left channel */ + if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter, + (int32_t*)hAudioIn.LeftRecBuff, + (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief register user callback functions + * @param ErrorCallback: pointer to the error callback function + * @param HalfTransferCallback: pointer to the half transfer callback function + * @param TransferCompleteCallback: pointer to the transfer complete callback function + * @retval None + */ +void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback, + Audio_CallbackTypeDef HalfTransferCallback, + Audio_CallbackTypeDef TransferCompleteCallback) +{ + hAudioIn.CbError = ErrorCallback; + hAudioIn.CbHalfTransfer = HalfTransferCallback; + hAudioIn.CbTransferComplete = TransferCompleteCallback; +} +/** + * @} + */ + +/* private functions --------------------------------------------------------*/ +/** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions + * @{ + */ +/** + * @brief Initializes the Audio Codec audio interface (SAI). + * @param AudioFreq: Audio frequency to be configured for the SAI peripheral. + * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 + * and user can update this configuration using + * @retval BSP AUDIO status + */ +static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq) +{ + /* Disable SAI peripheral to allow access to SAI internal registers */ + __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); + + /* Initialize the BSP_AUDIO_hSai Instance parameter */ + BSP_AUDIO_hSai.Instance = AUDIO_SAIx; + + /* Configure SAI_Block_x + LSBFirst: Disabled + DataSize: 16 */ + BSP_AUDIO_hSai.Init.AudioMode = SAI_MODEMASTER_TX; + BSP_AUDIO_hSai.Init.Synchro = SAI_ASYNCHRONOUS; + BSP_AUDIO_hSai.Init.SynchroExt = SAI_SYNCEXT_DISABLE; + BSP_AUDIO_hSai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE; + BSP_AUDIO_hSai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; + BSP_AUDIO_hSai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF; + BSP_AUDIO_hSai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV; + BSP_AUDIO_hSai.Init.Mckdiv = SAIClockDivider(AudioFreq); + BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE; + BSP_AUDIO_hSai.Init.CompandingMode = SAI_NOCOMPANDING; + BSP_AUDIO_hSai.Init.TriState = SAI_OUTPUT_NOTRELEASED; + BSP_AUDIO_hSai.Init.Protocol = SAI_FREE_PROTOCOL; + BSP_AUDIO_hSai.Init.DataSize = SAI_DATASIZE_16; + BSP_AUDIO_hSai.Init.FirstBit = SAI_FIRSTBIT_MSB; + BSP_AUDIO_hSai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; + + /* Configure SAI_Block_x Frame + Frame Length: 32 + Frame active Length: 16 + FS Definition: Start frame + Channel Side identification + FS Polarity: FS active Low + FS Offset: FS asserted one bit before the first bit of slot 0 */ + BSP_AUDIO_hSai.FrameInit.FrameLength = 32; + BSP_AUDIO_hSai.FrameInit.ActiveFrameLength = 16; + BSP_AUDIO_hSai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; + BSP_AUDIO_hSai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; + BSP_AUDIO_hSai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; + + /* Configure SAI Block_x Slot + Slot First Bit Offset: 0 + Slot Size : 16 + Slot Number: 2 + Slot Active: Slots 0 and 1 actives */ + BSP_AUDIO_hSai.SlotInit.FirstBitOffset = 0; + BSP_AUDIO_hSai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; + BSP_AUDIO_hSai.SlotInit.SlotNumber = 2; + BSP_AUDIO_hSai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1; + + /* Initializes the SAI peripheral*/ + if (HAL_SAI_Init(&BSP_AUDIO_hSai) != HAL_OK) + { + return AUDIO_ERROR; + } + + /* Enable SAI peripheral to generate MCLK */ + __HAL_SAI_ENABLE(&BSP_AUDIO_hSai); + + return AUDIO_OK; + +} + +/** + * @brief De-initializes the Audio Codec audio interface (SAI). + * @retval BSP AUDIO status + */ +static uint8_t AUDIO_SAIx_DeInit(void) +{ + /* Disable the SAI audio block */ + __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); + + /* De-initializes the SAI peripheral */ + if (HAL_SAI_DeInit(&BSP_AUDIO_hSai) != HAL_OK) + { + return AUDIO_ERROR; + } + + /* Disable SAIx PLL */ + if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief SAI MSP Init + * @param hsai : pointer to a SAI_HandleTypeDef structure + * @retval None + */ +void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable SAI clock */ + AUDIO_SAIx_CLK_ENABLE(); + + /* Enable GPIO clock */ + AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE(); + + /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/ + GPIO_InitStruct.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = AUDIO_SAIx_MCK_SCK_SD_FS_AF; + HAL_GPIO_Init(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, &GPIO_InitStruct); + + /* Enable the DMA clock */ + AUDIO_SAIx_DMAx_CLK_ENABLE(); + + if(hsai->Instance == AUDIO_SAIx) + { + /* Configure the hDmaSai handle parameters */ + hDmaSai.Init.Request = DMA_REQUEST_1; + hDmaSai.Init.Direction = DMA_MEMORY_TO_PERIPH; + hDmaSai.Init.PeriphInc = DMA_PINC_DISABLE; + hDmaSai.Init.MemInc = DMA_MINC_ENABLE; + hDmaSai.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE; + hDmaSai.Init.MemDataAlignment = AUDIO_SAIx_DMAx_MEM_DATA_SIZE; + hDmaSai.Init.Mode = DMA_NORMAL; + hDmaSai.Init.Priority = DMA_PRIORITY_HIGH; + + hDmaSai.Instance = AUDIO_SAIx_DMAx_CHANNEL; + + /* Associate the DMA handle */ + __HAL_LINKDMA(hsai, hdmatx, hDmaSai); + + /* Deinitialize the Stream for new transfer */ + HAL_DMA_DeInit(&hDmaSai); + + /* Configure the DMA Stream */ + HAL_DMA_Init(&hDmaSai); + } + + /* SAI DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0); + HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ); +} + +/** + * @brief SAI MSP De-init + * @param hsai : pointer to a SAI_HandleTypeDef structure + * @retval None + */ +void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai) +{ + /* Disable SAI DMA Channel IRQ */ + HAL_NVIC_DisableIRQ(AUDIO_SAIx_DMAx_IRQ); + + /* Reset the DMA Stream configuration*/ + HAL_DMA_DeInit(&hDmaSai); + + /* Disable the DMA clock */ + AUDIO_SAIx_DMAx_CLK_DISABLE(); + + /* De-initialize FS, SCK, MCK and SD pins*/ + HAL_GPIO_DeInit(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, + AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN); + + /* Disable GPIO clock */ + AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE(); + + /* Disable SAI clock */ + AUDIO_SAIx_CLK_DISABLE(); +} + +/** + * @brief Resets the audio codec. It restores the default configuration of the + * codec (this function shall be called before initializing the codec). + * @retval None + */ +static void AUDIO_CODEC_Reset(void) +{ + /* Initialize the audio driver structure */ + hAudioOut.AudioDrv = &cs43l22_drv; + + hAudioOut.AudioDrv->Reset(AUDIO_I2C_ADDRESS); +} + +/** + * @} + */ + +/** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions + * @{ + */ + +/** + * @brief Initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM). + * @param AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral. + * @retval BSP AUDIO status + */ +static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq) +{ + /*####CHANNEL 2####*/ + hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Activation = ENABLE; + hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO; + /* Set the DFSDM clock OUT audio frequency configuration */ + hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Divider = DFSDMClockDivider(AudioFreq); + hAudioIn.hDfsdmLeftChannel.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS; + hAudioIn.hDfsdmLeftChannel.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE; + hAudioIn.hDfsdmLeftChannel.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS; + /* Request to sample stable data for LEFT micro on Rising edge */ + hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING; + hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL; + hAudioIn.hDfsdmLeftChannel.Init.Awd.FilterOrder = DFSDM_CHANNEL_SINC1_ORDER; + hAudioIn.hDfsdmLeftChannel.Init.Awd.Oversampling = 10; + hAudioIn.hDfsdmLeftChannel.Init.Offset = 0; + hAudioIn.hDfsdmLeftChannel.Init.RightBitShift = DFSDMRightBitShift(AudioFreq); + + hAudioIn.hDfsdmLeftChannel.Instance = DFSDM_Channel2; + + /* Init the DFSDM Channel */ + if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK) + { + return AUDIO_ERROR; + } + + /*####FILTER 0####*/ + BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER; + BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.FastMode = ENABLE; + BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.DmaMode = ENABLE; + BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER; + BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ScanMode = DISABLE; + BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.DmaMode = DISABLE; + BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTrigger = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO; + BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES; + BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.SincOrder = DFSDMFilterOrder(AudioFreq); + /* Set the DFSDM Filters Oversampling to have correct sample rate */ + BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.Oversampling = DFSDMOverSampling(AudioFreq); + BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.IntOversampling = 1; + + BSP_AUDIO_hDfsdmLeftFilter.Instance = AUDIO_DFSDMx_LEFT_FILTER; + + /* Init the DFSDM Filter */ + if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK) + { + return AUDIO_ERROR; + } + + /* Configure regular channel */ + if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmLeftFilter, + DFSDM_CHANNEL_2, + DFSDM_CONTINUOUS_CONV_ON) != HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @brief De-initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM). + * @retval BSP AUDIO status + */ +static uint8_t AUDIO_DFSDMx_DeInit(void) +{ + /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */ + if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK) + { + return AUDIO_ERROR; + } + + /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */ + if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK) + { + return AUDIO_ERROR; + } + + /* Disable DFSDM clock */ + AUDIO_DFSDMx_CLK_DISABLE(); + + /* Disable SAIx PLL */ + if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK) + { + return AUDIO_ERROR; + } + + /* DFSDM reset */ + __HAL_RCC_DFSDM_FORCE_RESET(); + __HAL_RCC_DFSDM_RELEASE_RESET(); + + return AUDIO_OK; +} + +/** + * @brief Initializes the DFSDM channel MSP. + * @param hdfsdm_channel : DFSDM channel handle. + * @retval None + */ +void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable DFSDM clock */ + AUDIO_DFSDMx_CLK_ENABLE(); + + /* Enable GPIO clock */ + AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE(); + + /* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN pins ------------------*/ + GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN | AUDIO_DFSDMx_DMIC_DATIN_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF; + HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct); +} + +/** + * @brief De-initializes the DFSDM channel MSP. + * @param hdfsdm_channel : DFSDM channel handle. + * @retval None + */ +void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable GPIO clock */ + AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE(); + + /* DFSDM pins configuration: DFSDM_CKOUT */ + GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct); + HAL_GPIO_WritePin(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_CKOUT_PIN, GPIO_PIN_RESET); + + + /* De-initialize DMIC_DATIN pin */ + HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_DMIC_DATIN_PIN); +} + +/** + * @brief Initializes the DFSDM filter MSP. + * @param hdfsdm_filter : DFSDM filter handle. + * @retval None + */ +void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter) +{ + /* Enable DFSDM clock */ + AUDIO_DFSDMx_CLK_ENABLE(); + + /* Enable the DMA clock */ + AUDIO_DFSDMx_DMAx_CLK_ENABLE(); + + /* Configure the hAudioIn.hDmaDfsdmLeft handle parameters */ + hAudioIn.hDmaDfsdmLeft.Init.Request = DMA_REQUEST_0; + hAudioIn.hDmaDfsdmLeft.Init.Direction = DMA_PERIPH_TO_MEMORY; + hAudioIn.hDmaDfsdmLeft.Init.PeriphInc = DMA_PINC_DISABLE; + hAudioIn.hDmaDfsdmLeft.Init.MemInc = DMA_MINC_ENABLE; + hAudioIn.hDmaDfsdmLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE; + hAudioIn.hDmaDfsdmLeft.Init.MemDataAlignment = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE; + hAudioIn.hDmaDfsdmLeft.Init.Mode = DMA_CIRCULAR; + hAudioIn.hDmaDfsdmLeft.Init.Priority = DMA_PRIORITY_HIGH; + + hAudioIn.hDmaDfsdmLeft.Instance = AUDIO_DFSDMx_DMAx_LEFT_CHANNEL; + + /* Associate the DMA handle */ + __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmLeft); + + /* Reset DMA handle state */ + __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmLeft); + + /* Configure the DMA Channel */ + HAL_DMA_Init(&hAudioIn.hDmaDfsdmLeft); + + /* DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0); + HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ); + } + + /** + * @brief De-initializes the DFSDM filter MSP. + * @param hdfsdm_filter : DFSDM filter handle. + * @retval None + */ +void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter) +{ + /* Disable DMA Channel IRQ */ + HAL_NVIC_DisableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ); + + /* De-initialize the DMA Channel */ + HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmLeft); + + /* Disable the DMA clock */ + AUDIO_DFSDMx_DMAx_CLK_DISABLE(); +} + +/** + * @brief Configures the SAI PLL clock according to the required audio frequency. + * @param Frequency: Audio frequency. + * @retval BSP AUDIO status + * @note The SAI PLL input clock must be configured in the user application. + * The SAI PLL configuration done within this function assumes that + * the SAI PLL input clock runs at 8 MHz. + */ +static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency) +{ + RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct; + + /* Retreive actual RCC configuration */ + HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct); + + if ( (Frequency == AUDIO_FREQUENCY_11K) + || (Frequency == AUDIO_FREQUENCY_22K) + || (Frequency == AUDIO_FREQUENCY_44K) ) + { + /* Configure PLLSAI prescalers */ + /* SAI clock config + PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M + SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */ + RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1; + RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 24; + RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = 17; + RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK; + RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; + } + else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */ + { + /* SAI clock config + PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M + SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 344/7 = 49.142 Mhz */ + RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1; + RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 43; + RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = 7; + RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK; + RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; + } + + if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK) + { + return AUDIO_ERROR; + } + + return AUDIO_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_audio.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,268 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_audio.h + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file contains the common defines and functions prototypes for + * the stm32l476g_discovery_audio.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L476G_DISCOVERY_AUDIO_H +#define __STM32L476G_DISCOVERY_AUDIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if defined(BSP_AUDIO_USE_RTOS) +#include "k_mem.h" +#else +#include <stdlib.h> +#endif +/* Include audio component Driver */ +#include "../Components/cs43l22/cs43l22.h" +#include "stm32l476g_discovery.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY_AUDIO + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Types Exported Types + * @{ + */ +typedef void (*Audio_CallbackTypeDef)(void); + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Constants Exported Constants + * @{ + */ +/** @defgroup BSP_Audio_Out_Option BSP Audio Out Option + * @{ + */ +#define BSP_AUDIO_OUT_CIRCULARMODE ((uint32_t)0x00000001) /* BUFFER CIRCULAR MODE */ +#define BSP_AUDIO_OUT_NORMALMODE ((uint32_t)0x00000002) /* BUFFER NORMAL MODE */ +#define BSP_AUDIO_OUT_STEREOMODE ((uint32_t)0x00000004) /* STEREO MODE */ +#define BSP_AUDIO_OUT_MONOMODE ((uint32_t)0x00000008) /* MONO MODE */ +/** + * @} + */ + +/** @defgroup BSP_Audio_Sample_Rate BSP Audio Sample Rate + * @{ + */ +#define BSP_AUDIO_FREQUENCY_96K SAI_AUDIO_FREQUENCY_96K +#define BSP_AUDIO_FREQUENCY_48K SAI_AUDIO_FREQUENCY_48K +#define BSP_AUDIO_FREQUENCY_44K SAI_AUDIO_FREQUENCY_44K +#define BSP_AUDIO_FREQUENCY_32K SAI_AUDIO_FREQUENCY_32K +#define BSP_AUDIO_FREQUENCY_22K SAI_AUDIO_FREQUENCY_22K +#define BSP_AUDIO_FREQUENCY_16K SAI_AUDIO_FREQUENCY_16K +#define BSP_AUDIO_FREQUENCY_11K SAI_AUDIO_FREQUENCY_11K +#define BSP_AUDIO_FREQUENCY_8K SAI_AUDIO_FREQUENCY_8K +/** + * @} + */ +/*------------------------------------------------------------------------------ + USER SAI defines parameters + -----------------------------------------------------------------------------*/ +/* SAI peripheral configuration defines */ +#define AUDIO_SAIx SAI1_Block_A +#define AUDIO_SAIx_CLK_ENABLE() __HAL_RCC_SAI1_CLK_ENABLE() +#define AUDIO_SAIx_CLK_DISABLE() __HAL_RCC_SAI1_CLK_DISABLE() +#define AUDIO_SAIx_MCK_SCK_SD_FS_AF GPIO_AF13_SAI1 + +#define AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() +#define AUDIO_SAIx_FS_PIN GPIO_PIN_4 +#define AUDIO_SAIx_SCK_PIN GPIO_PIN_5 +#define AUDIO_SAIx_SD_PIN GPIO_PIN_6 +#define AUDIO_SAIx_MCK_PIN GPIO_PIN_2 +#define AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT GPIOE + +/* SAI DMA Channel definitions */ +#define AUDIO_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE() +#define AUDIO_SAIx_DMAx_CLK_DISABLE() __HAL_RCC_DMA2_CLK_DISABLE() +#define AUDIO_SAIx_DMAx_CHANNEL DMA2_Channel1 +#define AUDIO_SAIx_DMAx_IRQ DMA2_Channel1_IRQn +#define AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD +#define AUDIO_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD +#define DMA_MAX_SZE (uint32_t)0xFFFF + +#define AUDIO_SAIx_DMAx_IRQHandler DMA2_Channel1_IRQHandler + +/* Select the interrupt preemption priority for the DMA interrupt */ +#define AUDIO_OUT_IRQ_PREPRIO 5 /* Select the preemption priority level(0 is the highest) */ + +/* Disable SAIx PLL */ +#define AUDIO_SAIx_PLL_DISABLE() HAL_RCCEx_DisablePLLSAI1() + +/*------------------------------------------------------------------------------ + AUDIO IN CONFIGURATION +------------------------------------------------------------------------------*/ +/* DFSDM Configuration defines */ +#define AUDIO_DFSDMx_LEFT_CHANNEL DFSDM_Channel2 +#define AUDIO_DFSDMx_LEFT_FILTER DFSDM_Filter0 +#define AUDIO_DFSDMx_CLK_ENABLE() __HAL_RCC_DFSDM_CLK_ENABLE() +#define AUDIO_DFSDMx_CLK_DISABLE() __HAL_RCC_DFSDM_CLK_DISABLE() +#define AUDIO_DFSDMx_CKOUT_PIN GPIO_PIN_9 +#define AUDIO_DFSDMx_DMIC_DATIN_PIN GPIO_PIN_7 +#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT GPIOE +#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() +#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF GPIO_AF6_DFSDM + +/* DFSDM DMA Right and Left channels definitions */ +#define AUDIO_DFSDMx_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE() +#define AUDIO_DFSDMx_DMAx_CLK_DISABLE() __HAL_RCC_DMA1_CLK_DISABLE() +#define AUDIO_DFSDMx_DMAx_LEFT_CHANNEL DMA1_Channel4 +#define AUDIO_DFSDMx_DMAx_LEFT_IRQ DMA1_Channel4_IRQn +#define AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_WORD +#define AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_WORD + +#define AUDIO_DFSDM_DMAx_LEFT_IRQHandler DMA1_Channel4_IRQHandler + +/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */ +#define AUDIO_IN_IRQ_PREPRIO 6 /* Select the preemption priority level(0 is the highest) */ + +/*------------------------------------------------------------------------------ + CONFIGURATION: Audio Driver Configuration parameters +------------------------------------------------------------------------------*/ + +#define AUDIODATA_SIZE 2 /* 16-bits audio data size */ + +/* Audio status definition */ +#define AUDIO_OK 0 +#define AUDIO_ERROR 1 +#define AUDIO_TIMEOUT 2 + +/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */ +#define DEFAULT_AUDIO_IN_FREQ BSP_AUDIO_FREQUENCY_16K +#define DEFAULT_AUDIO_IN_BIT_RESOLUTION 16 +#define DEFAULT_AUDIO_IN_CHANNEL_NBR 1 /* Mono = 1, Stereo = 2 */ +#define DEFAULT_AUDIO_IN_VOLUME 64 + +/*------------------------------------------------------------------------------ + OPTIONAL Configuration defines parameters +------------------------------------------------------------------------------*/ + +/* Delay for the Codec to be correctly reset */ +#define CODEC_RESET_DELAY 5 + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Variables Exported Variables + * @{ + */ +extern SAI_HandleTypeDef BSP_AUDIO_hSai; +extern DFSDM_Filter_HandleTypeDef BSP_AUDIO_hDfsdmLeftFilter; + + /** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Macros Exported Macros + * @{ + */ +#define DMA_MAX(_X_) (((_X_) <= DMA_MAX_SZE)? (_X_):DMA_MAX_SZE) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Functions Exported Functions + * @{ + */ +uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq); +uint8_t BSP_AUDIO_OUT_DeInit(void); +uint8_t BSP_AUDIO_OUT_Play(uint16_t* pData, uint32_t Size); +uint8_t BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size); +uint8_t BSP_AUDIO_OUT_Pause(void); +uint8_t BSP_AUDIO_OUT_Resume(void); +uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option); +uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume); +uint8_t BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq); +void BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption); +uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd); +uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output); +void BSP_AUDIO_OUT_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback, + Audio_CallbackTypeDef HalfTransferCallback, + Audio_CallbackTypeDef TransferCompleteCallback); + +uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr); +uint8_t BSP_AUDIO_IN_DeInit(void); +uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size); +uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq); +uint8_t BSP_AUDIO_IN_Stop(void); +uint8_t BSP_AUDIO_IN_Pause(void); +uint8_t BSP_AUDIO_IN_Resume(void); +void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback, + Audio_CallbackTypeDef HalfTransferCallback, + Audio_CallbackTypeDef TransferCompleteCallback); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L476G_DISCOVERY_AUDIO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_compass.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,270 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_compass.c + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file provides a set of functions needed to manage the E-Compass + * (ACCELEROMETER + MAGNETOMETER) MEMS LSM303C available on STM32L476G-Discovery + * board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery.h" +#include "stm32l476g_discovery_compass.h" +#include "../Components/lsm303c/lsm303c.h" +#include <math.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_COMPASS STM32L476G-DISCOVERY COMPASS + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_COMPASS_Private_Types Private Types + * @{ + */ +/** + * @} + */ + +/* Private defines ------------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_COMPASS_Private_Constants Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_COMPASS_Private_Macros Private Macros + * @{ + */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_COMPASS_Private_Variables Private Variables + * @{ + */ +static ACCELERO_DrvTypeDef *AccelerometerDrv; +static MAGNETO_DrvTypeDef *MagnetoDrv; + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup STM32L476G_DISCOVERY_COMPASS_Private_FunctionPrototypes Private Functions + * @{ + */ +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @addtogroup STM32L476G_DISCOVERY_COMPASS_Exported_Functions + * @{ + */ +extern void ACCELERO_IO_DeInit(void); +extern void MAGNETO_IO_DeInit(void); + +/** + * @brief Initialize the COMPASS. + * @retval COMPASS_OK or COMPASS_ERROR + */ +COMPASS_StatusTypeDef BSP_COMPASS_Init(void) +{ + COMPASS_StatusTypeDef ret = COMPASS_OK; + uint16_t ctrl = 0x0000; + ACCELERO_InitTypeDef LSM303C_InitStructure; + ACCELERO_FilterConfigTypeDef LSM303C_FilterStructure; + MAGNETO_InitTypeDef LSM303C_InitStructureMag; + + if(Lsm303cDrv_accelero.ReadID() != LMS303C_ACC_ID) + { + ret = COMPASS_ERROR; + } + else + { + /* Initialize the COMPASS accelerometer driver structure */ + AccelerometerDrv = &Lsm303cDrv_accelero; + + /* MEMS configuration ------------------------------------------------------*/ + /* Fill the COMPASS accelerometer structure */ + LSM303C_InitStructure.AccOutput_DataRate = LSM303C_ACC_ODR_50_HZ; + LSM303C_InitStructure.Axes_Enable= LSM303C_ACC_AXES_ENABLE; + LSM303C_InitStructure.AccFull_Scale = LSM303C_ACC_FULLSCALE_2G; + LSM303C_InitStructure.BlockData_Update = LSM303C_ACC_BDU_CONTINUOUS; + LSM303C_InitStructure.High_Resolution = LSM303C_ACC_HR_DISABLE; + LSM303C_InitStructure.Communication_Mode = LSM303C_ACC_SPI_MODE; + + /* Configure MEMS: data rate, power mode, full scale and axes */ + ctrl = (LSM303C_InitStructure.High_Resolution | LSM303C_InitStructure.AccOutput_DataRate | \ + LSM303C_InitStructure.Axes_Enable | LSM303C_InitStructure.BlockData_Update); + + ctrl |= (LSM303C_InitStructure.AccFull_Scale | LSM303C_InitStructure.Communication_Mode) << 8; + + /* Configure the COMPASS accelerometer main parameters */ + AccelerometerDrv->Init(ctrl); + + /* Fill the COMPASS accelerometer HPF structure */ + LSM303C_FilterStructure.HighPassFilter_Mode_Selection = LSM303C_ACC_HPM_NORMAL_MODE; + LSM303C_FilterStructure.HighPassFilter_CutOff_Frequency = LSM303C_ACC_DFC1_ODRDIV50; + LSM303C_FilterStructure.HighPassFilter_Stat = LSM303C_ACC_HPI2S_INT1_DISABLE | LSM303C_ACC_HPI2S_INT2_DISABLE; + + /* Configure MEMS: mode, cutoff frequency, Filter status, Click, AOI1 and AOI2 */ + ctrl = (uint8_t) (LSM303C_FilterStructure.HighPassFilter_Mode_Selection |\ + LSM303C_FilterStructure.HighPassFilter_CutOff_Frequency|\ + LSM303C_FilterStructure.HighPassFilter_Stat); + + /* Configure the COMPASS accelerometer LPF main parameters */ + AccelerometerDrv->FilterConfig(ctrl); + } + + if(Lsm303cDrv_magneto.ReadID() != LMS303C_MAG_ID) + { + ret = COMPASS_ERROR; + } + else + { + /* Initialize the COMPASS magnetometer driver structure */ + MagnetoDrv = &Lsm303cDrv_magneto; + + /* MEMS configuration ------------------------------------------------------*/ + /* Fill the COMPASS magnetometer structure */ + LSM303C_InitStructureMag.Register1 = LSM303C_MAG_TEMPSENSOR_DISABLE | LSM303C_MAG_OM_XY_ULTRAHIGH | LSM303C_MAG_ODR_40_HZ; + LSM303C_InitStructureMag.Register2 = LSM303C_MAG_FS_16_GA | LSM303C_MAG_REBOOT_DEFAULT | LSM303C_MAG_SOFT_RESET_DEFAULT; + LSM303C_InitStructureMag.Register3 = LSM303C_MAG_SPI_MODE | LSM303C_MAG_CONFIG_NORMAL_MODE | LSM303C_MAG_CONTINUOUS_MODE; + LSM303C_InitStructureMag.Register4 = LSM303C_MAG_OM_Z_ULTRAHIGH | LSM303C_MAG_BLE_LSB; + LSM303C_InitStructureMag.Register5 = LSM303C_MAG_BDU_CONTINUOUS; + /* Configure the COMPASS magnetometer main parameters */ + MagnetoDrv->Init(LSM303C_InitStructureMag); + } + + return ret; +} + +/** + * @brief DeInitialize the COMPASS. + * @retval None. + */ +void BSP_COMPASS_DeInit(void) +{ + /* DeInitialize the COMPASS accelerometer & magnetometer IO interfaces */ + ACCELERO_IO_DeInit(); + MAGNETO_IO_DeInit(); +} + +/** + * @brief Put the COMPASS in low power mode. + * @retval None + */ +void BSP_COMPASS_LowPower(void) +{ + /* Put the COMPASS accelerometer in low power mode */ + if(AccelerometerDrv != NULL) + { + if(AccelerometerDrv->LowPower != NULL) + { + AccelerometerDrv->LowPower(); + } + } + /* Put the COMPASS magnetometer in low power mode */ + if(MagnetoDrv != NULL) + { + if(MagnetoDrv->LowPower != NULL) + { + MagnetoDrv->LowPower(); + } + } +} + +/** + * @brief Get XYZ acceleration values. + * @param pDataXYZ Pointer on 3 angular accelerations table with + * pDataXYZ[0] = X axis, pDataXYZ[1] = Y axis, pDataXYZ[2] = Z axis + * @retval None + */ +void BSP_COMPASS_AccGetXYZ(int16_t *pDataXYZ) +{ + if(AccelerometerDrv != NULL) + { + if(AccelerometerDrv->GetXYZ != NULL) + { + AccelerometerDrv->GetXYZ(pDataXYZ); + } + } +} + +/** + * @brief Get XYZ magnetometer values. + * @param pDataXYZ Pointer on 3 magnetometer values table with + * pDataXYZ[0] = X axis, pDataXYZ[1] = Y axis, pDataXYZ[2] = Z axis + * @retval None + */ +void BSP_COMPASS_MagGetXYZ(int16_t *pDataXYZ) +{ + if(MagnetoDrv != NULL) + { + if(MagnetoDrv->GetXYZ != NULL) + { + MagnetoDrv->GetXYZ(pDataXYZ); + } + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_compass.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,127 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_compass.h + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file contains definitions for stm32l476g_discovery_compass.c + * firmware driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L476G_DISCOVERY_COMPASS_H +#define __STM32L476G_DISCOVERY_COMPASS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY_COMPASS + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_COMPASS_Exported_Types Exported Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_COMPASS_Exported_Constants Exported Constants + * @{ + */ +typedef enum +{ + COMPASS_OK = 0, + COMPASS_ERROR = 1, + COMPASS_TIMEOUT = 2 +} +COMPASS_StatusTypeDef; + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_COMPASS_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_COMPASS_Exported_Functions Exported Functions + * @{ + */ +/* COMPASS functions */ +COMPASS_StatusTypeDef BSP_COMPASS_Init(void); +void BSP_COMPASS_DeInit(void); +void BSP_COMPASS_LowPower(void); +void BSP_COMPASS_MagGetXYZ(int16_t *pDataXYZ); +void BSP_COMPASS_AccGetXYZ(int16_t *pDataXYZ); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L476G_DISCOVERY_COMPASS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_glass_lcd.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,989 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_glass_lcd.c + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file provides a set of functions needed to manage the + * LCD Glass driver for the STM32L476G-Discovery board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery_glass_lcd.h" + + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD STM32L476G-DISCOVERY GLASS LCD + * @brief This file includes the LCD Glass driver for LCD Module of + * STM32L476G-DISCOVERY board. + * @{ + */ + +/* Private constants ---------------------------------------------------------*/ + +/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Private_Constants Private Constants + * @{ + */ +#define ASCII_CHAR_0 0x30 /* 0 */ +#define ASCII_CHAR_AT_SYMBOL 0x40 /* @ */ +#define ASCII_CHAR_LEFT_OPEN_BRACKET 0x5B /* [ */ +#define ASCII_CHAR_APOSTROPHE 0x60 /* ` */ +#define ASCII_CHAR_LEFT_OPEN_BRACE 0x7B /* ( */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Private_Variables Private Variables + * @{ + */ + +/* this variable can be used for accelerate the scrolling exit when push user button */ +__IO uint8_t bLCDGlass_KeyPressed = 0; + +/** + @verbatim +================================================================================ + GLASS LCD MAPPING +================================================================================ +LCD allows to display informations on six 14-segment digits and 4 bars: + + 1 2 3 4 5 6 +----- ----- ----- ----- ----- ----- +|\|/| o |\|/| o |\|/| o |\|/| o |\|/| |\|/| BAR3 +-- -- -- -- -- -- -- -- -- -- -- -- BAR2 +|/|\| o |/|\| o |/|\| o |/|\| o |/|\| |/|\| BAR1 +----- * ----- * ----- * ----- * ----- ----- BAR0 + +LCD segment mapping: +-------------------- + -----A----- _ + |\ | /| COL |_| + F H J K B + | \ | / | _ + --G-- --M-- COL |_| + | / | \ | + E Q P N C + |/ | \| _ + -----D----- DP |_| + + An LCD character coding is based on the following matrix: +COM 0 1 2 3 +SEG(n) { E , D , P , N } +SEG(n+1) { M , C , COL , DP } +SEG(23-n-1) { B , A , K , J } +SEG(23-n) { G , F , Q , H } +with n positive odd number. + + The character 'A' for example is: + ------------------------------- +LSB { 1 , 0 , 0 , 0 } + { 1 , 1 , 0 , 0 } + { 1 , 1 , 0 , 0 } +MSB { 1 , 1 , 0 , 0 } + ------------------- + 'A' = F E 0 0 hexa + + @endverbatim +*/ + +LCD_HandleTypeDef LCDHandle; + +/* Constant table for cap characters 'A' --> 'Z' */ +const uint16_t CapLetterMap[26]= + { + /* A B C D E F G H I */ + 0xFE00, 0x6714, 0x1D00, 0x4714, 0x9D00, 0x9C00, 0x3F00, 0xFA00, 0x0014, + /* J K L M N O P Q R */ + 0x5300, 0x9841, 0x1900, 0x5A48, 0x5A09, 0x5F00, 0xFC00, 0x5F01, 0xFC01, + /* S T U V W X Y Z */ + 0xAF00, 0x0414, 0x5b00, 0x18C0, 0x5A81, 0x00C9, 0x0058, 0x05C0 + }; + +/* Constant table for number '0' --> '9' */ +const uint16_t NumberMap[10]= + { + /* 0 1 2 3 4 5 6 7 8 9 */ + 0x5F00,0x4200,0xF500,0x6700,0xEa00,0xAF00,0xBF00,0x04600,0xFF00,0xEF00 + }; + +uint32_t Digit[4]; /* Digit frame buffer */ + +/* LCD BAR status: To save the bar setting after writing in LCD RAM memory */ +uint8_t LCDBar = BATTERYLEVEL_FULL; + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_LCD_Private_Functions Private Functions + * @{ + */ +static void Convert(uint8_t* Char, Point_Typedef Point, DoublePoint_Typedef Colon); +static void WriteChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position); +static void LCD_MspInit(LCD_HandleTypeDef *hlcd); +static void LCD_MspDeInit(LCD_HandleTypeDef *hlcd); + +/** + * @} + */ + +/** @addtogroup STM32L476G_DISCOVERY_LCD_Exported_Functions + * @{ + */ + +/** + * @brief Initialize the LCD GLASS relative GPIO port IOs and LCD peripheral. + * @retval None + */ +void BSP_LCD_GLASS_Init(void) +{ + LCDHandle.Instance = LCD; + LCDHandle.Init.Prescaler = LCD_PRESCALER_1; + LCDHandle.Init.Divider = LCD_DIVIDER_31; +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) + LCDHandle.Init.Duty = LCD_DUTY_1_4; +#elif defined (USE_STM32L476G_DISCO_REVA) + LCDHandle.Init.Duty = LCD_DUTY_1_8; +#endif + LCDHandle.Init.Bias = LCD_BIAS_1_3; + LCDHandle.Init.VoltageSource = LCD_VOLTAGESOURCE_INTERNAL; + LCDHandle.Init.Contrast = LCD_CONTRASTLEVEL_5; + LCDHandle.Init.DeadTime = LCD_DEADTIME_0; + LCDHandle.Init.PulseOnDuration = LCD_PULSEONDURATION_4; + LCDHandle.Init.HighDrive = LCD_HIGHDRIVE_DISABLE; + LCDHandle.Init.BlinkMode = LCD_BLINKMODE_OFF; + LCDHandle.Init.BlinkFrequency = LCD_BLINKFREQUENCY_DIV32; + LCDHandle.Init.MuxSegment = LCD_MUXSEGMENT_DISABLE; + + /* Initialize the LCD */ + LCD_MspInit(&LCDHandle); + HAL_LCD_Init(&LCDHandle); + + BSP_LCD_GLASS_Clear(); +} + +/** + * @brief DeInitialize the LCD GLASS relative GPIO port IOs and LCD peripheral. + * @retval None + */ +void BSP_LCD_GLASS_DeInit(void) +{ + /* De-Initialize the LCD */ + LCD_MspDeInit(&LCDHandle); + HAL_LCD_DeInit(&LCDHandle); +} + + +/** + * @brief Configure the LCD Blink mode and Blink frequency. + * @param BlinkMode: specifies the LCD blink mode. + * This parameter can be one of the following values: + * @arg LCD_BLINKMODE_OFF: Blink disabled + * @arg LCD_BLINKMODE_SEG0_COM0: Blink enabled on SEG[0], COM[0] (1 pixel) + * @arg LCD_BLINKMODE_SEG0_ALLCOM: Blink enabled on SEG[0], all COM (up to 8 + * pixels according to the programmed duty) + * @arg LCD_BLINKMODE_ALLSEG_ALLCOM: Blink enabled on all SEG and all COM + * (all pixels) + * @param BlinkFrequency: specifies the LCD blink frequency. + * @arg LCD_BLINKFREQUENCY_DIV8: The Blink frequency = fLcd/8 + * @arg LCD_BLINKFREQUENCY_DIV16: The Blink frequency = fLcd/16 + * @arg LCD_BLINKFREQUENCY_DIV32: The Blink frequency = fLcd/32 + * @arg LCD_BLINKFREQUENCY_DIV64: The Blink frequency = fLcd/64 + * @arg LCD_BLINKFREQUENCY_DIV128: The Blink frequency = fLcd/128 + * @arg LCD_BLINKFREQUENCY_DIV256: The Blink frequency = fLcd/256 + * @arg LCD_BLINKFREQUENCY_DIV512: The Blink frequency = fLcd/512 + * @arg LCD_BLINKFREQUENCY_DIV1024: The Blink frequency = fLcd/1024 + * @retval None + */ +void BSP_LCD_GLASS_BlinkConfig(uint32_t BlinkMode, uint32_t BlinkFrequency) +{ + __HAL_LCD_BLINK_CONFIG(&LCDHandle, BlinkMode, BlinkFrequency); +} + +/** + * @brief Configure the LCD contrast. + * @param Contrast: specifies the LCD contrast value. + * This parameter can be one of the following values: + * @arg LCD_CONTRASTLEVEL_0: Maximum Voltage = 2.60V + * @arg LCD_CONTRASTLEVEL_1: Maximum Voltage = 2.73V + * @arg LCD_CONTRASTLEVEL_2: Maximum Voltage = 2.86V + * @arg LCD_CONTRASTLEVEL_3: Maximum Voltage = 2.99V + * @arg LCD_CONTRASTLEVEL_4: Maximum Voltage = 3.12V + * @arg LCD_CONTRASTLEVEL_5: Maximum Voltage = 3.25V + * @arg LCD_CONTRASTLEVEL_6: Maximum Voltage = 3.38V + * @arg LCD_CONTRASTLEVEL_7: Maximum Voltage = 3.51V + * @retval None + */ +void BSP_LCD_GLASS_Contrast(uint32_t Contrast) +{ + __HAL_LCD_CONTRAST_CONFIG(&LCDHandle, Contrast); +} + +/** + * @brief Display one or several bar in LCD frame buffer. + * @param BarId: specifies the LCD GLASS Bar to display + * This parameter can be one of the following values: + * @arg BAR0: LCD GLASS Bar 0 + * @arg BAR0: LCD GLASS Bar 1 + * @arg BAR0: LCD GLASS Bar 2 + * @arg BAR0: LCD GLASS Bar 3 + * @retval None + */ +void BSP_LCD_GLASS_DisplayBar(uint32_t BarId) +{ + uint32_t position = 0; + + /* Check which bar is selected */ + while ((BarId) >> position) + { + /* Check if current bar is selected */ + switch(BarId & (1 << position)) + { + /* Bar 0 */ + case LCD_BAR_0: + /* Set BAR0 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG), LCD_BAR0_SEG); + break; + + /* Bar 1 */ + case LCD_BAR_1: + /* Set BAR1 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG), LCD_BAR1_SEG); + break; + + /* Bar 2 */ + case LCD_BAR_2: + /* Set BAR2 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR2_SEG), LCD_BAR2_SEG); + break; + + /* Bar 3 */ + case LCD_BAR_3: + /* Set BAR3 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR3_SEG), LCD_BAR3_SEG); + break; + + default: + break; + } + position++; + } + + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Clear one or several bar in LCD frame buffer. + * @param BarId: specifies the LCD GLASS Bar to display + * This parameter can be combination of one of the following values: + * @arg LCD_BAR_0: LCD GLASS Bar 0 + * @arg LCD_BAR_1: LCD GLASS Bar 1 + * @arg LCD_BAR_2: LCD GLASS Bar 2 + * @arg LCD_BAR_3: LCD GLASS Bar 3 + * @retval None + */ +void BSP_LCD_GLASS_ClearBar(uint32_t BarId) +{ + uint32_t position = 0; + + /* Check which bar is selected */ + while ((BarId) >> position) + { + /* Check if current bar is selected */ + switch(BarId & (1 << position)) + { + /* Bar 0 */ + case LCD_BAR_0: + /* Set BAR0 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG) , 0); + break; + + /* Bar 1 */ + case LCD_BAR_1: + /* Set BAR1 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG), 0); + break; + + /* Bar 2 */ + case LCD_BAR_2: + /* Set BAR2 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR2_SEG), 0); + break; + + /* Bar 3 */ + case LCD_BAR_3: + /* Set BAR3 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR3_SEG), 0); + break; + + default: + break; + } + position++; + } + + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Configure the bar level on LCD by writing bar value in LCD frame buffer. + * @param BarLevel: specifies the LCD GLASS Battery Level. + * This parameter can be one of the following values: + * @arg BATTERYLEVEL_OFF: LCD GLASS Battery Empty + * @arg BATTERYLEVEL_1_4: LCD GLASS Battery 1/4 Full + * @arg BATTERYLEVEL_1_2: LCD GLASS Battery 1/2 Full + * @arg BATTERYLEVEL_3_4: LCD GLASS Battery 3/4 Full + * @arg BATTERYLEVEL_FULL: LCD GLASS Battery Full + * @retval None + */ +void BSP_LCD_GLASS_BarLevelConfig(uint8_t BarLevel) +{ + switch (BarLevel) + { + /* BATTERYLEVEL_OFF */ + case BATTERYLEVEL_OFF: + /* Set BAR0 & BAR2 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), 0); + /* Set BAR1 & BAR3 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), 0); + LCDBar = BATTERYLEVEL_OFF; + break; + + /* BARLEVEL 1/4 */ + case BATTERYLEVEL_1_4: + /* Set BAR0 on & BAR2 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), LCD_BAR0_SEG); + /* Set BAR1 & BAR3 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), 0); + LCDBar = BATTERYLEVEL_1_4; + break; + + /* BARLEVEL 1/2 */ + case BATTERYLEVEL_1_2: + /* Set BAR0 on & BAR2 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), LCD_BAR0_SEG); + /* Set BAR1 on & BAR3 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), LCD_BAR1_SEG); + LCDBar = BATTERYLEVEL_1_2; + break; + + /* Battery Level 3/4 */ + case BATTERYLEVEL_3_4: + /* Set BAR0 & BAR2 on */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), (LCD_BAR0_SEG | LCD_BAR2_SEG)); + /* Set BAR1 on & BAR3 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), LCD_BAR1_SEG); + LCDBar = BATTERYLEVEL_3_4; + break; + + /* BATTERYLEVEL_FULL */ + case BATTERYLEVEL_FULL: + /* Set BAR0 & BAR2 on */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), (LCD_BAR0_SEG | LCD_BAR2_SEG)); + /* Set BAR1 on & BAR3 on */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), (LCD_BAR1_SEG | LCD_BAR3_SEG)); + LCDBar = BATTERYLEVEL_FULL; + break; + + default: + break; + } + + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Write a character in the LCD RAM buffer. + * @param ch: The character to display. + * @param Point: A point to add in front of char. + * This parameter can be one of the following values: + * @arg POINT_OFF: No point to add in front of char. + * @arg POINT_ON: Add a point in front of char. + * @param Colon: Flag indicating if a colon character has to be added in front + * of displayed character. + * This parameter can be one of the following values: + * @arg DOUBLEPOINT_OFF: No colon to add in back of char. + * @arg DOUBLEPOINT_ON: Add an colon in back of char. + * @param Position: Position in the LCD of the character to write. + * This parameter can be any value in range [1:6]. + * @retval None + * @note Required preconditions: The LCD should be cleared before to start the + * write operation. + */ +void BSP_LCD_GLASS_DisplayChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position) +{ + WriteChar(ch, Point, Colon, Position); + + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Write a character string in the LCD RAM buffer. + * @param ptr: Pointer to string to display on the LCD Glass. + * @retval None + */ +void BSP_LCD_GLASS_DisplayString(uint8_t* ptr) +{ + DigitPosition_Typedef position = LCD_DIGIT_POSITION_1; + + /* Send the string character by character on lCD */ + while ((*ptr != 0) & (position <= LCD_DIGIT_POSITION_6)) + { + /* Write one character on LCD */ + WriteChar(ptr, POINT_OFF, DOUBLEPOINT_OFF, position); + + /* Point on the next character */ + ptr++; + + /* Increment the character counter */ + position++; + } + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Write a character string with decimal point in the LCD RAM buffer. + * @param ptr: Pointer to string to display on the LCD Glass. + * @retval None + * @note Required preconditions: Char is ASCCI value "ORed" with decimal point or Colon flag + */ +void BSP_LCD_GLASS_DisplayStrDeci(uint16_t* ptr) +{ + DigitPosition_Typedef index = LCD_DIGIT_POSITION_1; + uint8_t tmpchar = 0; + + /* Send the string character by character on lCD */ + while((*ptr != 0) & (index <= LCD_DIGIT_POSITION_6)) + { + tmpchar = (*ptr) & 0x00FF; + + switch((*ptr) & 0xF000) + { + case DOT: + /* Write one character on LCD with decimal point */ + WriteChar(&tmpchar, POINT_ON, DOUBLEPOINT_OFF, index); + break; + case DOUBLE_DOT: + /* Write one character on LCD with decimal point */ + WriteChar(&tmpchar, POINT_OFF, DOUBLEPOINT_ON, index); + break; + default: + WriteChar(&tmpchar, POINT_OFF, DOUBLEPOINT_OFF, index); + break; + }/* Point on the next character */ + ptr++; + + /* Increment the character counter */ + index++; + } + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Clear the whole LCD RAM buffer. + * @retval None + */ +void BSP_LCD_GLASS_Clear(void) +{ + HAL_LCD_Clear(&LCDHandle); +} + +/** + * @brief Display a string in scrolling mode + * @param ptr: Pointer to string to display on the LCD Glass. + * @param nScroll: Specifies how many time the message will be scrolled + * @param ScrollSpeed : Specifies the speed of the scroll, low value gives + * higher speed + * @retval None + * @note Required preconditions: The LCD should be cleared before to start the + * write operation. + */ +void BSP_LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed) +{ + uint8_t repetition = 0, nbrchar = 0, sizestr = 0; + uint8_t* ptr1; + uint8_t str[6] = ""; + + /* Reset interrupt variable in case key was press before entering function */ + bLCDGlass_KeyPressed = 0; + + if(ptr == 0) + { + return; + } + + /* To calculate end of string */ + for(ptr1 = ptr, sizestr = 0; *ptr1 != 0; sizestr++, ptr1++); + + ptr1 = ptr; + + BSP_LCD_GLASS_DisplayString(str); + HAL_Delay(ScrollSpeed); + + /* To shift the string for scrolling display*/ + for (repetition = 0; repetition < nScroll; repetition++) + { + for(nbrchar = 0; nbrchar < sizestr; nbrchar++) + { + *(str) =* (ptr1+((nbrchar+1)%sizestr)); + *(str+1) =* (ptr1+((nbrchar+2)%sizestr)); + *(str+2) =* (ptr1+((nbrchar+3)%sizestr)); + *(str+3) =* (ptr1+((nbrchar+4)%sizestr)); + *(str+4) =* (ptr1+((nbrchar+5)%sizestr)); + *(str+5) =* (ptr1+((nbrchar+6)%sizestr)); + BSP_LCD_GLASS_Clear(); + BSP_LCD_GLASS_DisplayString(str); + + /* user button pressed stop the scrolling sentence */ + if(bLCDGlass_KeyPressed) + { + bLCDGlass_KeyPressed = 0; + return; + } + HAL_Delay(ScrollSpeed); + } + } +} + +/** + * @} + */ + +/** @addtogroup STM32L476G_DISCOVERY_LCD_Private_Functions + * @{ + */ + +/** + * @brief Initialize the LCD MSP. + * @param hlcd: LCD handle + * @retval None + */ +static void LCD_MspInit(LCD_HandleTypeDef *hlcd) +{ + GPIO_InitTypeDef gpioinitstruct = {0}; + RCC_OscInitTypeDef oscinitstruct = {0}; + RCC_PeriphCLKInitTypeDef periphclkstruct = {0}; + + /*##-1- Enable PWR peripheral Clock #######################################*/ + __HAL_RCC_PWR_CLK_ENABLE(); + + /*##-2- Configure LSE as RTC clock soucre ###################################*/ + oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; + oscinitstruct.PLL.PLLState = RCC_PLL_NONE; + oscinitstruct.LSEState = RCC_LSE_ON; + if(HAL_RCC_OscConfig(&oscinitstruct) != HAL_OK) + { + while(1); + } + + /*##-3- Select LSE as RTC clock source.##########################*/ + /* Backup domain management is done in RCC function */ + periphclkstruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + periphclkstruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + HAL_RCCEx_PeriphCLKConfig(&periphclkstruct); + + /*##-4- Enable LCD GPIO Clocks #############################################*/ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + + /*##-5- Configure peripheral GPIO ##########################################*/ + /* Configure Output for LCD */ + /* Port A */ + gpioinitstruct.Pin = LCD_GPIO_BANKA_PINS; + gpioinitstruct.Mode = GPIO_MODE_AF_PP; + gpioinitstruct.Pull = GPIO_NOPULL; + gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpioinitstruct.Alternate = GPIO_AF11_LCD; + HAL_GPIO_Init(GPIOA, &gpioinitstruct); + + /* Port B */ + gpioinitstruct.Pin = LCD_GPIO_BANKB_PINS; + HAL_GPIO_Init(GPIOB, &gpioinitstruct); + + /* Port C*/ + gpioinitstruct.Pin = LCD_GPIO_BANKC_PINS; + HAL_GPIO_Init(GPIOC, &gpioinitstruct); + + /* Port D */ + gpioinitstruct.Pin = LCD_GPIO_BANKD_PINS; + HAL_GPIO_Init(GPIOD, &gpioinitstruct); + + /* Wait for the external capacitor Cext which is connected to the VLCD pin is charged + (approximately 2ms for Cext=1uF) */ + HAL_Delay(2); + + /*##-6- Enable LCD peripheral Clock ########################################*/ + __HAL_RCC_LCD_CLK_ENABLE(); +} + +/** + * @brief DeInitialize the LCD MSP. + * @param hlcd: LCD handle + * @retval None + */ +static void LCD_MspDeInit(LCD_HandleTypeDef *hlcd) +{ + uint32_t gpiopin = 0; + + /*##-1- Enable LCD GPIO Clocks #############################################*/ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + /*##-1- Configure peripheral GPIO ##########################################*/ + /* Configure Output for LCD */ + /* Port A */ + gpiopin = LCD_GPIO_BANKA_PINS; + HAL_GPIO_DeInit(GPIOA, gpiopin); + + /* Port B */ + gpiopin = LCD_GPIO_BANKB_PINS; + HAL_GPIO_DeInit(GPIOB, gpiopin); + + /* Port C*/ + gpiopin = LCD_GPIO_BANKC_PINS; + HAL_GPIO_DeInit(GPIOC, gpiopin); + + /* Port D */ + gpiopin = LCD_GPIO_BANKD_PINS; + HAL_GPIO_DeInit(GPIOD, gpiopin); + + /*##-5- Enable LCD peripheral Clock ########################################*/ + __HAL_RCC_LCD_CLK_DISABLE(); +} + +/** + * @brief Convert an ascii char to the a LCD digit. + * @param Char: a char to display. + * @param Point: a point to add in front of char + * This parameter can be: POINT_OFF or POINT_ON + * @param Colon : flag indicating if a colon character has to be added in front + * of displayed character. + * This parameter can be: DOUBLEPOINT_OFF or DOUBLEPOINT_ON. + * @retval None + */ +static void Convert(uint8_t* Char, Point_Typedef Point, DoublePoint_Typedef Colon) +{ + uint16_t ch = 0 ; + uint8_t loop = 0, index = 0; + + switch (*Char) + { + case ' ' : + ch = 0x00; + break; + + case '*': + ch = C_STAR; + break; + + case '(' : + ch = C_OPENPARMAP; + break; + + case ')' : + ch = C_CLOSEPARMAP; + break; + + case 'd' : + ch = C_DMAP; + break; + + case 'm' : + ch = C_MMAP; + break; + + case 'n' : + ch = C_NMAP; + break; + + case 'u' : + ch = C_UMAP; + break; + + case '-' : + ch = C_MINUS; + break; + + case '+' : + ch = C_PLUS; + break; + + case '/' : + ch = C_SLATCH; + break; + + case '�' : + ch = C_PERCENT_1; + break; + case '%' : + ch = C_PERCENT_2; + break; + case 255 : + ch = C_FULL; + break ; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ch = NumberMap[*Char - ASCII_CHAR_0]; + break; + + default: + /* The character Char is one letter in upper case*/ + if ( (*Char < ASCII_CHAR_LEFT_OPEN_BRACKET) && (*Char > ASCII_CHAR_AT_SYMBOL) ) + { + ch = CapLetterMap[*Char - 'A']; + } + /* The character Char is one letter in lower case*/ + if ( (*Char < ASCII_CHAR_LEFT_OPEN_BRACE) && ( *Char > ASCII_CHAR_APOSTROPHE) ) + { + ch = CapLetterMap[*Char - 'a']; + } + break; + } + + /* Set the digital point can be displayed if the point is on */ + if (Point == POINT_ON) + { + ch |= 0x0002; + } + + /* Set the "COL" segment in the character that can be displayed if the colon is on */ + if (Colon == DOUBLEPOINT_ON) + { + ch |= 0x0020; + } + + for (loop = 12,index=0 ;index < 4; loop -= 4,index++) + { + Digit[index] = (ch >> loop) & 0x0f; /*To isolate the less significant digit */ + } +} + +/** + * @brief Write a character in the LCD frame buffer. + * @param ch: the character to display. + * @param Point: a point to add in front of char + * This parameter can be: POINT_OFF or POINT_ON + * @param Colon: flag indicating if a colon character has to be added in front + * of displayed character. + * This parameter can be: DOUBLEPOINT_OFF or DOUBLEPOINT_ON. + * @param Position: position in the LCD of the character to write [1:6] + * @retval None + */ +static void WriteChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position) +{ + uint32_t data =0x00; + /* To convert displayed character in segment in array digit */ + Convert(ch, (Point_Typedef)Point, (DoublePoint_Typedef)Colon); + + switch (Position) + { + /* Position 1 on LCD (Digit1)*/ + case LCD_DIGIT_POSITION_1: + data = ((Digit[0] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG1_SHIFT) + | (((Digit[0] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG23_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM0, LCD_DIGIT1_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG1_SHIFT) + | (((Digit[1] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG23_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM1, LCD_DIGIT1_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG1_SHIFT) + | (((Digit[2] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG23_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM2, LCD_DIGIT1_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG1_SHIFT) + | (((Digit[3] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG23_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM3, LCD_DIGIT1_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 2 on LCD (Digit2)*/ + case LCD_DIGIT_POSITION_2: + data = ((Digit[0] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG3_SHIFT) + | (((Digit[0] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG21_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM0, LCD_DIGIT2_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG3_SHIFT) + | (((Digit[1] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG21_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM1, LCD_DIGIT2_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG3_SHIFT) + | (((Digit[2] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG21_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM2, LCD_DIGIT2_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG3_SHIFT) + | (((Digit[3] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG21_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM3, LCD_DIGIT2_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 3 on LCD (Digit3)*/ + case LCD_DIGIT_POSITION_3: + data = ((Digit[0] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG5_SHIFT) + | (((Digit[0] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG19_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM0, LCD_DIGIT3_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG5_SHIFT) + | (((Digit[1] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG19_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM1, LCD_DIGIT3_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG5_SHIFT) + | (((Digit[2] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG19_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM2, LCD_DIGIT3_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG5_SHIFT) + | (((Digit[3] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG19_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM3, LCD_DIGIT3_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 4 on LCD (Digit4)*/ + case LCD_DIGIT_POSITION_4: + data = ((Digit[0] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG17_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM0, LCD_DIGIT4_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = (((Digit[0] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[0] & 0x4) >> 2) << LCD_SEG16_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM0_1, LCD_DIGIT4_COM0_1_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG17_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM1, LCD_DIGIT4_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = (((Digit[1] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[1] & 0x4) >> 2) << LCD_SEG16_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM1_1, LCD_DIGIT4_COM1_1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG17_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM2, LCD_DIGIT4_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = (((Digit[2] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[2] & 0x4) >> 2) << LCD_SEG16_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM2_1, LCD_DIGIT4_COM2_1_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG17_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM3, LCD_DIGIT4_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + + data = (((Digit[3] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[3] & 0x4) >> 2) << LCD_SEG16_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM3_1, LCD_DIGIT4_COM3_1_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 5 on LCD (Digit5)*/ + case LCD_DIGIT_POSITION_5: + data = (((Digit[0] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[0] & 0x4) >> 2) << LCD_SEG14_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM0, LCD_DIGIT5_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[0] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG15_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM0_1, LCD_DIGIT5_COM0_1_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = (((Digit[1] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[1] & 0x4) >> 2) << LCD_SEG14_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM1, LCD_DIGIT5_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[1] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG15_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM1_1, LCD_DIGIT5_COM1_1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = (((Digit[2] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[2] & 0x4) >> 2) << LCD_SEG14_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM2, LCD_DIGIT5_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[2] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG15_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM2_1, LCD_DIGIT5_COM2_1_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = (((Digit[3] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[3] & 0x4) >> 2) << LCD_SEG14_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM3, LCD_DIGIT5_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + + data = ((Digit[3] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG15_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM3_1, LCD_DIGIT5_COM3_1_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 6 on LCD (Digit6)*/ + case LCD_DIGIT_POSITION_6: + data = ((Digit[0] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG11_SHIFT) + | (((Digit[0] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG13_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM0, LCD_DIGIT6_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG11_SHIFT) + | (((Digit[1] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG13_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM1, LCD_DIGIT6_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG11_SHIFT) + | (((Digit[2] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG13_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM2, LCD_DIGIT6_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG11_SHIFT) + | (((Digit[3] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG13_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM3, LCD_DIGIT6_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + default: + break; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_glass_lcd.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,547 @@ + /** + ****************************************************************************** + * @file stm32l476g_discovery_glass_lcd.h + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief Header file for stm32l476g_discovery_glass_lcd.c module. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L476G_DISCOVERY_GLASS_LCD_H +#define __STM32L476G_DISCOVERY_GLASS_LCD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY_GLASS_LCD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Exported_Types Exported Types + * @{ + */ +/** + * @brief LCD Glass digit position + */ +typedef enum +{ + LCD_DIGIT_POSITION_1 = 0, + LCD_DIGIT_POSITION_2 = 1, + LCD_DIGIT_POSITION_3 = 2, + LCD_DIGIT_POSITION_4 = 3, + LCD_DIGIT_POSITION_5 = 4, + LCD_DIGIT_POSITION_6 = 5, + LCD_DIGIT_MAX_NUMBER = 6, +}DigitPosition_Typedef; +/** + * @brief LCD Glass point + * Warning: element values correspond to LCD Glass point. + */ + +typedef enum +{ + POINT_OFF = 0, + POINT_ON = 1 +}Point_Typedef; + +/** + * @brief LCD Glass Double point + * Warning: element values correspond to LCD Glass Double point. + */ +typedef enum +{ + DOUBLEPOINT_OFF = 0, + DOUBLEPOINT_ON = 1 +}DoublePoint_Typedef; + +/** + * @brief LCD Glass Battery Level + * element values correspond to different LCD Glass battery levels + */ +typedef enum +{ + BATTERYLEVEL_OFF = 0, + BATTERYLEVEL_1_4 = 1, + BATTERYLEVEL_1_2 = 2, + BATTERYLEVEL_3_4 = 3, + BATTERYLEVEL_FULL = 4 +}BatteryLevel_Typedef; + +/** + * @brief LCD Glass Bar Id + */ +typedef enum +{ + LCD_BAR_NONE = 0, + LCD_BAR_0 = (1 << 0), + LCD_BAR_1 = (1 << 1), + LCD_BAR_2 = (1 << 2), + LCD_BAR_3 = (1 << 3) +}BarId_Typedef; +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Exported_Constants Exported Constants + * @{ +*/ +/** + * @brief LCD digit defintion + */ +#define COM_PER_DIGIT_NB 4/*!< Specifies number of COM to address a digit */ +#define SEG_PER_DIGIT_NB 4/*!< Specifies number of SEG to address a digit */ + +#define LCD_MAP_CHAR_COM0_SEG_1ST_POS (1 << LCD_MAP_CHAR_COM0_SEG_1ST_SHIFT) +#define LCD_MAP_CHAR_COM0_SEG_2ND_POS (1 << LCD_MAP_CHAR_COM0_SEG_2ND_SHIFT) +#define LCD_MAP_CHAR_COM0_SEG_3RD_POS (1 << LCD_MAP_CHAR_COM0_SEG_3RD_SHIFT) +#define LCD_MAP_CHAR_COM0_SEG_4TH_POS (1 << LCD_MAP_CHAR_COM0_SEG_4TH_SHIFT) +#define LCD_MAP_CHAR_COM1_SEG_1ST_POS (1 << LCD_MAP_CHAR_COM1_SEG_1ST_SHIFT) +#define LCD_MAP_CHAR_COM1_SEG_2ND_POS (1 << LCD_MAP_CHAR_COM1_SEG_2ND_SHIFT) +#define LCD_MAP_CHAR_COM1_SEG_3RD_POS (1 << LCD_MAP_CHAR_COM1_SEG_3RD_SHIFT) +#define LCD_MAP_CHAR_COM1_SEG_4TH_POS (1 << LCD_MAP_CHAR_COM1_SEG_4TH_SHIFT) +#define LCD_MAP_CHAR_COM2_SEG_1ST_POS (1 << LCD_MAP_CHAR_COM2_SEG_1ST_SHIFT) +#define LCD_MAP_CHAR_COM2_SEG_2ND_POS (1 << LCD_MAP_CHAR_COM2_SEG_2ND_SHIFT) +#define LCD_MAP_CHAR_COM2_SEG_3RD_POS (1 << LCD_MAP_CHAR_COM2_SEG_3RD_SHIFT) +#define LCD_MAP_CHAR_COM2_SEG_4TH_POS (1 << LCD_MAP_CHAR_COM2_SEG_4TH_SHIFT) +#define LCD_MAP_CHAR_COM3_SEG_1ST_POS (1 << LCD_MAP_CHAR_COM3_SEG_1ST_SHIFT) +#define LCD_MAP_CHAR_COM3_SEG_2ND_POS (1 << LCD_MAP_CHAR_COM3_SEG_2ND_SHIFT) +#define LCD_MAP_CHAR_COM3_SEG_3RD_POS (1 << LCD_MAP_CHAR_COM3_SEG_3RD_SHIFT) +#define LCD_MAP_CHAR_COM3_SEG_4TH_POS (1 << LCD_MAP_CHAR_COM3_SEG_4TH_SHIFT) +#define LCD_MAP_CHAR_COM0_SEG_1ST_SHIFT 0x00000000 +#define LCD_MAP_CHAR_COM0_SEG_2ND_SHIFT 0x00000001 +#define LCD_MAP_CHAR_COM0_SEG_3RD_SHIFT 0x00000002 +#define LCD_MAP_CHAR_COM0_SEG_4TH_SHIFT 0x00000003 +#define LCD_MAP_CHAR_COM1_SEG_1ST_SHIFT 0x00000004 +#define LCD_MAP_CHAR_COM1_SEG_2ND_SHIFT 0x00000005 +#define LCD_MAP_CHAR_COM1_SEG_3RD_SHIFT 0x00000006 +#define LCD_MAP_CHAR_COM1_SEG_4TH_SHIFT 0x00000007 +#define LCD_MAP_CHAR_COM2_SEG_1ST_SHIFT 0x00000008 +#define LCD_MAP_CHAR_COM2_SEG_2ND_SHIFT 0x00000009 +#define LCD_MAP_CHAR_COM2_SEG_3RD_SHIFT 0x00000010 +#define LCD_MAP_CHAR_COM2_SEG_4TH_SHIFT 0x00000011 +#define LCD_MAP_CHAR_COM3_SEG_1ST_SHIFT 0x00000012 +#define LCD_MAP_CHAR_COM3_SEG_2ND_SHIFT 0x00000013 +#define LCD_MAP_CHAR_COM3_SEG_3RD_SHIFT 0x00000014 +#define LCD_MAP_CHAR_COM3_SEG_4TH_SHIFT 0x00000015 + +/** + * @brief LCD Digit defines + */ +#define LCD_DIGIT1_COM0 LCD_COM0 +#define LCD_DIGIT1_COM0_SEG_MASK ~(LCD_SEG0 | LCD_SEG1 | LCD_SEG22 | LCD_SEG23) +#define LCD_DIGIT1_COM1 LCD_COM1 +#define LCD_DIGIT1_COM1_SEG_MASK ~(LCD_SEG0 | LCD_SEG1 | LCD_SEG22 | LCD_SEG23) +#define LCD_DIGIT1_COM2 LCD_COM2 +#define LCD_DIGIT1_COM2_SEG_MASK ~(LCD_SEG0 | LCD_SEG1 | LCD_SEG22 | LCD_SEG23) +#define LCD_DIGIT1_COM3 LCD_COM3 +#define LCD_DIGIT1_COM3_SEG_MASK ~(LCD_SEG0 | LCD_SEG1 | LCD_SEG22 | LCD_SEG23) + +#define LCD_DIGIT2_COM0 LCD_COM0 +#define LCD_DIGIT2_COM0_SEG_MASK ~(LCD_SEG2 | LCD_SEG3 | LCD_SEG20 | LCD_SEG21) +#define LCD_DIGIT2_COM1 LCD_COM1 +#define LCD_DIGIT2_COM1_SEG_MASK ~(LCD_SEG2 | LCD_SEG3 | LCD_SEG20 | LCD_SEG21) +#define LCD_DIGIT2_COM2 LCD_COM2 +#define LCD_DIGIT2_COM2_SEG_MASK ~(LCD_SEG2 | LCD_SEG3 | LCD_SEG20 | LCD_SEG21) +#define LCD_DIGIT2_COM3 LCD_COM3 +#define LCD_DIGIT2_COM3_SEG_MASK ~(LCD_SEG2 | LCD_SEG3 | LCD_SEG20 | LCD_SEG21) + +#define LCD_DIGIT3_COM0 LCD_COM0 +#define LCD_DIGIT3_COM0_SEG_MASK ~(LCD_SEG4 | LCD_SEG5 | LCD_SEG18 | LCD_SEG19) +#define LCD_DIGIT3_COM1 LCD_COM1 +#define LCD_DIGIT3_COM1_SEG_MASK ~(LCD_SEG4 | LCD_SEG5 | LCD_SEG18 | LCD_SEG19) +#define LCD_DIGIT3_COM2 LCD_COM2 +#define LCD_DIGIT3_COM2_SEG_MASK ~(LCD_SEG4 | LCD_SEG5 | LCD_SEG18 | LCD_SEG19) +#define LCD_DIGIT3_COM3 LCD_COM3 +#define LCD_DIGIT3_COM3_SEG_MASK ~(LCD_SEG4 | LCD_SEG5 | LCD_SEG18 | LCD_SEG19) + +#define LCD_DIGIT4_COM0 LCD_COM0 +#define LCD_DIGIT4_COM0_SEG_MASK ~(LCD_SEG6 | LCD_SEG17) +#define LCD_DIGIT4_COM0_1 LCD_COM0_1 +#define LCD_DIGIT4_COM0_1_SEG_MASK ~(LCD_SEG7 | LCD_SEG16) +#define LCD_DIGIT4_COM1 LCD_COM1 +#define LCD_DIGIT4_COM1_SEG_MASK ~(LCD_SEG6 | LCD_SEG17) +#define LCD_DIGIT4_COM1_1 LCD_COM1_1 +#define LCD_DIGIT4_COM1_1_SEG_MASK ~(LCD_SEG7 | LCD_SEG16) +#define LCD_DIGIT4_COM2 LCD_COM2 +#define LCD_DIGIT4_COM2_SEG_MASK ~(LCD_SEG6 | LCD_SEG17) +#define LCD_DIGIT4_COM2_1 LCD_COM2_1 +#define LCD_DIGIT4_COM2_1_SEG_MASK ~(LCD_SEG7 | LCD_SEG16) +#define LCD_DIGIT4_COM3 LCD_COM3 +#define LCD_DIGIT4_COM3_SEG_MASK ~(LCD_SEG6 | LCD_SEG17) +#define LCD_DIGIT4_COM3_1 LCD_COM3_1 +#define LCD_DIGIT4_COM3_1_SEG_MASK ~(LCD_SEG7 | LCD_SEG16) + +#define LCD_DIGIT5_COM0 LCD_COM0 +#define LCD_DIGIT5_COM0_SEG_MASK ~(LCD_SEG9 | LCD_SEG14) +#define LCD_DIGIT5_COM0_1 LCD_COM0_1 +#define LCD_DIGIT5_COM0_1_SEG_MASK ~(LCD_SEG8 | LCD_SEG15) +#define LCD_DIGIT5_COM1 LCD_COM1 +#define LCD_DIGIT5_COM1_SEG_MASK ~(LCD_SEG9 | LCD_SEG14) +#define LCD_DIGIT5_COM1_1 LCD_COM1_1 +#define LCD_DIGIT5_COM1_1_SEG_MASK ~(LCD_SEG8 | LCD_SEG15) +#define LCD_DIGIT5_COM2 LCD_COM2 +#define LCD_DIGIT5_COM2_SEG_MASK ~(LCD_SEG9 | LCD_SEG14) +#define LCD_DIGIT5_COM2_1 LCD_COM2_1 +#define LCD_DIGIT5_COM2_1_SEG_MASK ~(LCD_SEG8 | LCD_SEG15) +#define LCD_DIGIT5_COM3 LCD_COM3 +#define LCD_DIGIT5_COM3_SEG_MASK ~(LCD_SEG9 | LCD_SEG14) +#define LCD_DIGIT5_COM3_1 LCD_COM3_1 +#define LCD_DIGIT5_COM3_1_SEG_MASK ~(LCD_SEG8 | LCD_SEG15) + +#define LCD_DIGIT6_COM0 LCD_COM0 +#define LCD_DIGIT6_COM0_SEG_MASK ~(LCD_SEG10 | LCD_SEG11 | LCD_SEG12 | LCD_SEG13) +#define LCD_DIGIT6_COM1 LCD_COM1 +#define LCD_DIGIT6_COM1_SEG_MASK ~(LCD_SEG10 | LCD_SEG11 | LCD_SEG12 | LCD_SEG13) +#define LCD_DIGIT6_COM2 LCD_COM2 +#define LCD_DIGIT6_COM2_SEG_MASK ~(LCD_SEG10 | LCD_SEG11 | LCD_SEG12 | LCD_SEG13) +#define LCD_DIGIT6_COM3 LCD_COM3 +#define LCD_DIGIT6_COM3_SEG_MASK ~(LCD_SEG10 | LCD_SEG11 | LCD_SEG12 | LCD_SEG13) + +/** + * @brief LCD Bar location + */ +#define LCD_BAR0_2_COM LCD_COM3 +#define LCD_BAR1_3_COM LCD_COM2 +#define LCD_BAR0_SEG LCD_SEG11 +#define LCD_BAR1_SEG LCD_SEG11 +#define LCD_BAR2_SEG LCD_SEG9 +#define LCD_BAR3_SEG LCD_SEG9 +#define LCD_BAR0_2_SEG_MASK ~(LCD_BAR0_SEG | LCD_BAR2_SEG) +#define LCD_BAR1_3_SEG_MASK ~(LCD_BAR1_SEG | LCD_BAR3_SEG) + +/** + * @brief LCD segments & coms redefinition. + * LCD component segments & coms are not necessarily link to MCU segmnents & coms output. + */ +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +#define LCD_COM0 MCU_LCD_COM0 +#define LCD_COM0_1 MCU_LCD_COM0_1 +#define LCD_COM1 MCU_LCD_COM1 +#define LCD_COM1_1 MCU_LCD_COM1_1 +#define LCD_COM2 MCU_LCD_COM2 +#define LCD_COM2_1 MCU_LCD_COM2_1 +#define LCD_COM3 MCU_LCD_COM3 +#define LCD_COM3_1 MCU_LCD_COM3_1 +#elif defined (USE_STM32L476G_DISCO_REVA) +#define LCD_COM0 MCU_LCD_COM5 +#define LCD_COM0_1 MCU_LCD_COM5_1 +#define LCD_COM1 MCU_LCD_COM7 +#define LCD_COM1_1 MCU_LCD_COM7_1 +#define LCD_COM2 MCU_LCD_COM6 +#define LCD_COM2_1 MCU_LCD_COM6_1 +#define LCD_COM3 MCU_LCD_COM4 +#define LCD_COM3_1 MCU_LCD_COM4_1 +#endif +#define LCD_SEG0 MCU_LCD_SEG4 +#define LCD_SEG1 MCU_LCD_SEG23 +#define LCD_SEG2 MCU_LCD_SEG6 +#define LCD_SEG3 MCU_LCD_SEG13 +#define LCD_SEG4 MCU_LCD_SEG15 +#define LCD_SEG5 MCU_LCD_SEG29 +#define LCD_SEG6 MCU_LCD_SEG31 +#define LCD_SEG7 MCU_LCD_SEG33 +#define LCD_SEG8 MCU_LCD_SEG35 +#define LCD_SEG9 MCU_LCD_SEG25 +#define LCD_SEG10 MCU_LCD_SEG17 +#define LCD_SEG11 MCU_LCD_SEG8 +#define LCD_SEG12 MCU_LCD_SEG9 +#define LCD_SEG13 MCU_LCD_SEG26 +#define LCD_SEG14 MCU_LCD_SEG24 +#define LCD_SEG15 MCU_LCD_SEG34 +#define LCD_SEG16 MCU_LCD_SEG32 +#define LCD_SEG17 MCU_LCD_SEG30 +#define LCD_SEG18 MCU_LCD_SEG28 +#define LCD_SEG19 MCU_LCD_SEG14 +#define LCD_SEG20 MCU_LCD_SEG12 +#define LCD_SEG21 MCU_LCD_SEG5 +#define LCD_SEG22 MCU_LCD_SEG22 +#define LCD_SEG23 MCU_LCD_SEG3 +#define LCD_SEG0_SHIFT MCU_LCD_SEG4_SHIFT +#define LCD_SEG1_SHIFT MCU_LCD_SEG23_SHIFT +#define LCD_SEG2_SHIFT MCU_LCD_SEG6_SHIFT +#define LCD_SEG3_SHIFT MCU_LCD_SEG13_SHIFT +#define LCD_SEG4_SHIFT MCU_LCD_SEG15_SHIFT +#define LCD_SEG5_SHIFT MCU_LCD_SEG29_SHIFT +#define LCD_SEG6_SHIFT MCU_LCD_SEG31_SHIFT +#define LCD_SEG7_SHIFT MCU_LCD_SEG33_SHIFT +#define LCD_SEG8_SHIFT MCU_LCD_SEG35_SHIFT +#define LCD_SEG9_SHIFT MCU_LCD_SEG25_SHIFT +#define LCD_SEG10_SHIFT MCU_LCD_SEG17_SHIFT +#define LCD_SEG11_SHIFT MCU_LCD_SEG8_SHIFT +#define LCD_SEG12_SHIFT MCU_LCD_SEG9_SHIFT +#define LCD_SEG13_SHIFT MCU_LCD_SEG26_SHIFT +#define LCD_SEG14_SHIFT MCU_LCD_SEG24_SHIFT +#define LCD_SEG15_SHIFT MCU_LCD_SEG34_SHIFT +#define LCD_SEG16_SHIFT MCU_LCD_SEG32_SHIFT +#define LCD_SEG17_SHIFT MCU_LCD_SEG30_SHIFT +#define LCD_SEG18_SHIFT MCU_LCD_SEG28_SHIFT +#define LCD_SEG19_SHIFT MCU_LCD_SEG14_SHIFT +#define LCD_SEG20_SHIFT MCU_LCD_SEG12_SHIFT +#define LCD_SEG21_SHIFT MCU_LCD_SEG5_SHIFT +#define LCD_SEG22_SHIFT MCU_LCD_SEG22_SHIFT +#define LCD_SEG23_SHIFT MCU_LCD_SEG3_SHIFT + +/** + * @brief STM32 LCD segments & coms definitions. + */ +#define MCU_LCD_COM0 LCD_RAM_REGISTER0 +#define MCU_LCD_COM0_1 LCD_RAM_REGISTER1 +#define MCU_LCD_COM1 LCD_RAM_REGISTER2 +#define MCU_LCD_COM1_1 LCD_RAM_REGISTER3 +#define MCU_LCD_COM2 LCD_RAM_REGISTER4 +#define MCU_LCD_COM2_1 LCD_RAM_REGISTER5 +#define MCU_LCD_COM3 LCD_RAM_REGISTER6 +#define MCU_LCD_COM3_1 LCD_RAM_REGISTER7 +#define MCU_LCD_COM4 LCD_RAM_REGISTER8 +#define MCU_LCD_COM4_1 LCD_RAM_REGISTER9 +#define MCU_LCD_COM5 LCD_RAM_REGISTER10 +#define MCU_LCD_COM5_1 LCD_RAM_REGISTER11 +#define MCU_LCD_COM6 LCD_RAM_REGISTER12 +#define MCU_LCD_COM6_1 LCD_RAM_REGISTER13 +#define MCU_LCD_COM7 LCD_RAM_REGISTER14 +#define MCU_LCD_COM7_1 LCD_RAM_REGISTER15 +#define MCU_LCD_SEG0 (1U << MCU_LCD_SEG0_SHIFT) +#define MCU_LCD_SEG1 (1U << MCU_LCD_SEG1_SHIFT) +#define MCU_LCD_SEG2 (1U << MCU_LCD_SEG2_SHIFT) +#define MCU_LCD_SEG3 (1U << MCU_LCD_SEG3_SHIFT) +#define MCU_LCD_SEG4 (1U << MCU_LCD_SEG4_SHIFT) +#define MCU_LCD_SEG5 (1U << MCU_LCD_SEG5_SHIFT) +#define MCU_LCD_SEG6 (1U << MCU_LCD_SEG6_SHIFT) +#define MCU_LCD_SEG7 (1U << MCU_LCD_SEG7_SHIFT) +#define MCU_LCD_SEG8 (1U << MCU_LCD_SEG8_SHIFT) +#define MCU_LCD_SEG9 (1U << MCU_LCD_SEG9_SHIFT) +#define MCU_LCD_SEG10 (1U << MCU_LCD_SEG10_SHIFT) +#define MCU_LCD_SEG11 (1U << MCU_LCD_SEG11_SHIFT) +#define MCU_LCD_SEG12 (1U << MCU_LCD_SEG12_SHIFT) +#define MCU_LCD_SEG13 (1U << MCU_LCD_SEG13_SHIFT) +#define MCU_LCD_SEG14 (1U << MCU_LCD_SEG14_SHIFT) +#define MCU_LCD_SEG15 (1U << MCU_LCD_SEG15_SHIFT) +#define MCU_LCD_SEG16 (1U << MCU_LCD_SEG16_SHIFT) +#define MCU_LCD_SEG17 (1U << MCU_LCD_SEG17_SHIFT) +#define MCU_LCD_SEG18 (1U << MCU_LCD_SEG18_SHIFT) +#define MCU_LCD_SEG19 (1U << MCU_LCD_SEG19_SHIFT) +#define MCU_LCD_SEG20 (1U << MCU_LCD_SEG20_SHIFT) +#define MCU_LCD_SEG21 (1U << MCU_LCD_SEG21_SHIFT) +#define MCU_LCD_SEG22 (1U << MCU_LCD_SEG22_SHIFT) +#define MCU_LCD_SEG23 (1U << MCU_LCD_SEG23_SHIFT) +#define MCU_LCD_SEG24 (1U << MCU_LCD_SEG24_SHIFT) +#define MCU_LCD_SEG25 (1U << MCU_LCD_SEG25_SHIFT) +#define MCU_LCD_SEG26 (1U << MCU_LCD_SEG26_SHIFT) +#define MCU_LCD_SEG27 (1U << MCU_LCD_SEG27_SHIFT) +#define MCU_LCD_SEG28 (1U << MCU_LCD_SEG28_SHIFT) +#define MCU_LCD_SEG29 (1U << MCU_LCD_SEG29_SHIFT) +#define MCU_LCD_SEG30 (1U << MCU_LCD_SEG30_SHIFT) +#define MCU_LCD_SEG31 (1U << MCU_LCD_SEG31_SHIFT) +#define MCU_LCD_SEG32 (1U << MCU_LCD_SEG32_SHIFT) +#define MCU_LCD_SEG33 (1U << MCU_LCD_SEG33_SHIFT) +#define MCU_LCD_SEG34 (1U << MCU_LCD_SEG34_SHIFT) +#define MCU_LCD_SEG35 (1U << MCU_LCD_SEG35_SHIFT) +#define MCU_LCD_SEG36 (1U << MCU_LCD_SEG36_SHIFT) +#define MCU_LCD_SEG37 (1U << MCU_LCD_SEG37_SHIFT) +#define MCU_LCD_SEG38 (1U << MCU_LCD_SEG38_SHIFT) +#define MCU_LCD_SEG0_SHIFT 0 +#define MCU_LCD_SEG1_SHIFT 1 +#define MCU_LCD_SEG2_SHIFT 2 +#define MCU_LCD_SEG3_SHIFT 3 +#define MCU_LCD_SEG4_SHIFT 4 +#define MCU_LCD_SEG5_SHIFT 5 +#define MCU_LCD_SEG6_SHIFT 6 +#define MCU_LCD_SEG7_SHIFT 7 +#define MCU_LCD_SEG8_SHIFT 8 +#define MCU_LCD_SEG9_SHIFT 9 +#define MCU_LCD_SEG10_SHIFT 10 +#define MCU_LCD_SEG11_SHIFT 11 +#define MCU_LCD_SEG12_SHIFT 12 +#define MCU_LCD_SEG13_SHIFT 13 +#define MCU_LCD_SEG14_SHIFT 14 +#define MCU_LCD_SEG15_SHIFT 15 +#define MCU_LCD_SEG16_SHIFT 16 +#define MCU_LCD_SEG17_SHIFT 17 +#define MCU_LCD_SEG18_SHIFT 18 +#define MCU_LCD_SEG19_SHIFT 19 +#define MCU_LCD_SEG20_SHIFT 20 +#define MCU_LCD_SEG21_SHIFT 21 +#define MCU_LCD_SEG22_SHIFT 22 +#define MCU_LCD_SEG23_SHIFT 23 +#define MCU_LCD_SEG24_SHIFT 24 +#define MCU_LCD_SEG25_SHIFT 25 +#define MCU_LCD_SEG26_SHIFT 26 +#define MCU_LCD_SEG27_SHIFT 27 +#define MCU_LCD_SEG28_SHIFT 28 +#define MCU_LCD_SEG29_SHIFT 29 +#define MCU_LCD_SEG30_SHIFT 30 +#define MCU_LCD_SEG31_SHIFT 31 +#define MCU_LCD_SEG32_SHIFT 0 +#define MCU_LCD_SEG33_SHIFT 1 +#define MCU_LCD_SEG34_SHIFT 2 +#define MCU_LCD_SEG35_SHIFT 3 +#define MCU_LCD_SEG36_SHIFT 4 +#define MCU_LCD_SEG37_SHIFT 5 +#define MCU_LCD_SEG38_SHIFT 6 +#define MCU_LCD_SEG39_SHIFT 7 +#define MCU_LCD_SEG40_SHIFT 8 +#define MCU_LCD_SEG41_SHIFT 9 +#define MCU_LCD_SEG42_SHIFT 10 +#define MCU_LCD_SEG43_SHIFT 11 + +/** + * @brief LCD Pins definition. + */ +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) +#define LCD_GPIO_BANKA_PINS (GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | \ + GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_15) +#define LCD_GPIO_BANKB_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | \ + GPIO_PIN_5 | GPIO_PIN_9 | GPIO_PIN_12 | \ + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15) +#define LCD_GPIO_BANKC_PINS (GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \ + GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8) +#define LCD_GPIO_BANKD_PINS (GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \ + GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | \ + GPIO_PIN_14 | GPIO_PIN_15) +#elif defined (USE_STM32L476G_DISCO_REVA) +#define LCD_GPIO_BANKA_PINS (GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_15) +#define LCD_GPIO_BANKB_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | \ + GPIO_PIN_5 | GPIO_PIN_12 | GPIO_PIN_13 | \ + GPIO_PIN_14 | GPIO_PIN_15) +#define LCD_GPIO_BANKC_PINS (GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \ + GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | \ + GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12) +#define LCD_GPIO_BANKD_PINS (GPIO_PIN_2 | GPIO_PIN_8 | GPIO_PIN_9 | \ + GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | \ + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15) +#endif + +/* Define for scrolling sentences*/ +#define SCROLL_SPEED_HIGH 150 +#define SCROLL_SPEED_MEDIUM 300 +#define SCROLL_SPEED_LOW 450 + +#define DOT ((uint16_t) 0x8000 ) /* for add decimal point in string */ +#define DOUBLE_DOT ((uint16_t) 0x4000) /* for add decimal point in string */ + +/* code for '(' character */ +#define C_OPENPARMAP ((uint16_t) 0x0028) + +/* code for ')' character */ +#define C_CLOSEPARMAP ((uint16_t) 0x0011) + +/* code for 'd' character */ +#define C_DMAP ((uint16_t) 0xf300) + +/* code for 'm' character */ +#define C_MMAP ((uint16_t) 0xb210) + +/* code for 'n' character */ +#define C_NMAP ((uint16_t) 0x2210) + +/* code for 'µ' character */ +#define C_UMAP ((uint16_t) 0x6084) + +/* constant code for '*' character */ +#define C_STAR ((uint16_t) 0xA0DD) + +/* constant code for '-' character */ +#define C_MINUS ((uint16_t) 0xA000) + +/* constant code for '+' character */ +#define C_PLUS ((uint16_t) 0xA014) + +/* constant code for '/' */ +#define C_SLATCH ((uint16_t) 0x00c0) + +/* constant code for ° */ +#define C_PERCENT_1 ((uint16_t) 0xec00) + +/* constant code for small o */ +#define C_PERCENT_2 ((uint16_t) 0xb300) + +#define C_FULL ((uint16_t) 0xffdd) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup STM32L476G_DISCOVERY_LCD_Exported_Functions Exported Functions + * @{ + */ +void BSP_LCD_GLASS_Init(void); +void BSP_LCD_GLASS_DeInit(void); +void BSP_LCD_GLASS_BlinkConfig(uint32_t BlinkMode, uint32_t BlinkFrequency); +void BSP_LCD_GLASS_Contrast(uint32_t Contrast); +void BSP_LCD_GLASS_DisplayChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Column, DigitPosition_Typedef Position); +void BSP_LCD_GLASS_DisplayString(uint8_t* ptr); +void BSP_LCD_GLASS_DisplayStrDeci(uint16_t* ptr); +void BSP_LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed); +void BSP_LCD_GLASS_DisplayBar(uint32_t BarId); +void BSP_LCD_GLASS_ClearBar(uint32_t BarId); +void BSP_LCD_GLASS_BarLevelConfig(uint8_t BarLevel); +void BSP_LCD_GLASS_Clear(void); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L476G_DISCOVERY_GLASS_LCD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_gyroscope.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,300 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_gyroscope.c + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file provides a set of functions needed to manage the L3GD20 + * MEMS accelerometer available on STM32L476G-Discovery board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery_gyroscope.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE STM32L476G-DISCOVERY GYROSCOPE + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_Types Private Types + * @{ + */ +/** + * @} + */ + +/* Private defines ------------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_Constants Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_Macros Private Macros + * @{ + */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_Variables Private Variables + * @{ + */ +static GYRO_DrvTypeDef *GyroscopeDrv; + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_FunctionPrototypes Private Functions + * @{ + */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Functions + * @{ + */ + +/** + * @brief Initialize Gyroscope. + * @retval GYRO_OK or GYRO_ERROR + */ +uint8_t BSP_GYRO_Init(void) +{ + uint8_t ret = GYRO_ERROR; + uint16_t ctrl = 0x0000; + GYRO_InitTypeDef L3GD20_InitStructure; + GYRO_FilterConfigTypeDef L3GD20_FilterStructure={0,0}; + + if((L3gd20Drv.ReadID() == I_AM_L3GD20) || (L3gd20Drv.ReadID() == I_AM_L3GD20_TR)) + { + /* Initialize the gyroscope driver structure */ + GyroscopeDrv = &L3gd20Drv; + + /* Configure Mems : data rate, power mode, full scale and axes */ + L3GD20_InitStructure.Power_Mode = L3GD20_MODE_ACTIVE; + L3GD20_InitStructure.Output_DataRate = L3GD20_OUTPUT_DATARATE_1; + L3GD20_InitStructure.Axes_Enable = L3GD20_AXES_ENABLE; + L3GD20_InitStructure.Band_Width = L3GD20_BANDWIDTH_4; + L3GD20_InitStructure.BlockData_Update = L3GD20_BlockDataUpdate_Continous; + L3GD20_InitStructure.Endianness = L3GD20_BLE_LSB; + L3GD20_InitStructure.Full_Scale = L3GD20_FULLSCALE_500; + + /* Configure MEMS: data rate, power mode, full scale and axes */ + ctrl = (uint16_t) (L3GD20_InitStructure.Power_Mode | L3GD20_InitStructure.Output_DataRate | \ + L3GD20_InitStructure.Axes_Enable | L3GD20_InitStructure.Band_Width); + + ctrl |= (uint16_t) ((L3GD20_InitStructure.BlockData_Update | L3GD20_InitStructure.Endianness | \ + L3GD20_InitStructure.Full_Scale) << 8); + + /* Initialize component */ + GyroscopeDrv->Init(ctrl); + + L3GD20_FilterStructure.HighPassFilter_Mode_Selection =L3GD20_HPM_NORMAL_MODE_RES; + L3GD20_FilterStructure.HighPassFilter_CutOff_Frequency = L3GD20_HPFCF_0; + + ctrl = (uint8_t) ((L3GD20_FilterStructure.HighPassFilter_Mode_Selection |\ + L3GD20_FilterStructure.HighPassFilter_CutOff_Frequency)); + + /* Configure component filter */ + GyroscopeDrv->FilterConfig(ctrl) ; + + /* Enable component filter */ + GyroscopeDrv->FilterCmd(L3GD20_HIGHPASSFILTER_ENABLE); + + ret = GYRO_OK; + } + else + { + ret = GYRO_ERROR; + } + + return ret; +} + + +/** + * @brief DeInitialize Gyroscope. + * @retval None + */ +void BSP_GYRO_DeInit(void) +{ + GYRO_IO_DeInit(); +} + + +/** + * @brief Put Gyroscope in low power mode. + * @retval None + */ +void BSP_GYRO_LowPower(void) +{ + uint16_t ctrl = 0x0000; + GYRO_InitTypeDef L3GD20_InitStructure; + + /* configure only Power_Mode field */ + L3GD20_InitStructure.Power_Mode = L3GD20_MODE_POWERDOWN; + + ctrl = (uint16_t) (L3GD20_InitStructure.Power_Mode); + + /* Set component in low-power mode */ + GyroscopeDrv->LowPower(ctrl); + + +} + +/** + * @brief Read ID of Gyroscope component. + * @retval ID + */ +uint8_t BSP_GYRO_ReadID(void) +{ + uint8_t id = 0x00; + + if(GyroscopeDrv->ReadID != NULL) + { + id = GyroscopeDrv->ReadID(); + } + return id; +} + +/** + * @brief Reboot memory content of Gyroscope. + * @retval None + */ +void BSP_GYRO_Reset(void) +{ + if(GyroscopeDrv->Reset != NULL) + { + GyroscopeDrv->Reset(); + } +} + +/** + * @brief Configure Gyroscope interrupts (INT1 or INT2). + * @param pIntConfig: pointer to a GYRO_InterruptConfigTypeDef + * structure that contains the configuration setting for the L3GD20 Interrupt. + * @retval None + */ +void BSP_GYRO_ITConfig(GYRO_InterruptConfigTypeDef *pIntConfig) +{ + uint16_t interruptconfig = 0x0000; + + if(GyroscopeDrv->ConfigIT != NULL) + { + /* Configure latch Interrupt request and axe interrupts */ + interruptconfig |= ((uint8_t)(pIntConfig->Latch_Request| \ + pIntConfig->Interrupt_Axes) << 8); + + interruptconfig |= (uint8_t)(pIntConfig->Interrupt_ActiveEdge); + + GyroscopeDrv->ConfigIT(interruptconfig); + } +} + +/** + * @brief Enable Gyroscope interrupts (INT1 or INT2). + * @param IntPin: Interrupt pin + * This parameter can be: + * @arg L3GD20_INT1 + * @arg L3GD20_INT2 + * @retval None + */ +void BSP_GYRO_EnableIT(uint8_t IntPin) +{ + if(GyroscopeDrv->EnableIT != NULL) + { + GyroscopeDrv->EnableIT(IntPin); + } +} + +/** + * @brief Disable Gyroscope interrupts (INT1 or INT2). + * @param IntPin: Interrupt pin + * This parameter can be: + * @arg L3GD20_INT1 + * @arg L3GD20_INT2 + * @retval None + */ +void BSP_GYRO_DisableIT(uint8_t IntPin) +{ + if(GyroscopeDrv->DisableIT != NULL) + { + GyroscopeDrv->DisableIT(IntPin); + } +} + +/** + * @brief Get XYZ angular acceleration from the Gyroscope. + * @param pfData: pointer on floating array + * @retval None + */ +void BSP_GYRO_GetXYZ(float* pfData) +{ + if(GyroscopeDrv->GetXYZ!= NULL) + { + GyroscopeDrv->GetXYZ(pfData); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_gyroscope.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,132 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_gyroscope.h + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file contains definitions for stm32l476g_discovery_gyroscope.c + * firmware driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L476G_DISCOVERY_GYROSCOPE_H +#define __STM32L476G_DISCOVERY_GYROSCOPE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery.h" +/* Include Gyroscope component driver */ +#include "../Components/l3gd20/l3gd20.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY_GYROSCOPE + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Types Exported Types + * @{ + */ +typedef enum +{ + GYRO_OK = 0, + GYRO_ERROR = 1, + GYRO_TIMEOUT = 2 +} +GYRO_StatusTypeDef; + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Constants Exported Constants + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Functions Exported Functions + * @{ + */ +/* Sensor Configuration Functions */ +uint8_t BSP_GYRO_Init(void); +void BSP_GYRO_DeInit(void); +void BSP_GYRO_LowPower(void); +void BSP_GYRO_Reset(void); +uint8_t BSP_GYRO_ReadID(void); +void BSP_GYRO_ITConfig(GYRO_InterruptConfigTypeDef *pIntConfigStruct); +void BSP_GYRO_EnableIT(uint8_t IntPin); +void BSP_GYRO_DisableIT(uint8_t IntPin); +void BSP_GYRO_GetXYZ(float* pfData); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L476G_DISCOVERY_GYROSCOPE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_idd.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,388 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_idd.c + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file provides a set of firmware functions to manage the + * Idd measurement driver for STM32L476G-Discovery board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery_idd.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_IDD STM32L476G-DISCOVERY IDD + * @brief This file includes the Idd driver for STM32L476G-DISCOVERY board. + * It allows user to measure MCU Idd current on board, especially in + * different low power modes. + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_IDD_Private_Defines Private Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup STM32L476G_DISCOVERY_IDD_Private_Variables Private Variables + * @{ + */ +static IDD_DrvTypeDef *IddDrv; + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_IDD_Private_Functions Private Functions + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_IDD_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Configures IDD measurement component. + * @retval IDD_OK if no problem during initialization + */ +uint8_t BSP_IDD_Init(void) +{ + IDD_ConfigTypeDef iddconfig = {0}; + uint8_t mfxstm32l152_id = 0; + uint8_t ret = 0; + + /* wake up mfx component in case it went to standby mode */ + mfxstm32l152_idd_drv.WakeUp(IDD_I2C_ADDRESS); + HAL_Delay(5); + + /* Read ID and verify if the MFX is ready */ + mfxstm32l152_id = mfxstm32l152_idd_drv.ReadID(IDD_I2C_ADDRESS); + + if((mfxstm32l152_id == MFXSTM32L152_ID_1) || (mfxstm32l152_id == MFXSTM32L152_ID_2)) + { + /* Initialize the Idd driver structure */ + IddDrv = &mfxstm32l152_idd_drv; + + /* Initialize the Idd driver */ + if(IddDrv->Init != NULL) + { + IddDrv->Init(IDD_I2C_ADDRESS); + } + + /* Configure Idd component with default values */ + iddconfig.AmpliGain = DISCOVERY_IDD_AMPLI_GAIN; + iddconfig.VddMin = DISCOVERY_IDD_VDD_MIN; + iddconfig.Shunt0Value = DISCOVERY_IDD_SHUNT0_VALUE; + iddconfig.Shunt1Value = DISCOVERY_IDD_SHUNT1_VALUE; + iddconfig.Shunt2Value = DISCOVERY_IDD_SHUNT2_VALUE; + iddconfig.Shunt3Value = 0; + iddconfig.Shunt4Value = DISCOVERY_IDD_SHUNT4_VALUE; + iddconfig.Shunt0StabDelay = DISCOVERY_IDD_SHUNT0_STABDELAY; + iddconfig.Shunt1StabDelay = DISCOVERY_IDD_SHUNT1_STABDELAY; + iddconfig.Shunt2StabDelay = DISCOVERY_IDD_SHUNT2_STABDELAY; + iddconfig.Shunt3StabDelay = 0; + iddconfig.Shunt4StabDelay = DISCOVERY_IDD_SHUNT4_STABDELAY; + iddconfig.ShuntNbOnBoard = MFXSTM32L152_IDD_SHUNT_NB_4; + iddconfig.ShuntNbUsed = MFXSTM32L152_IDD_SHUNT_NB_4; + iddconfig.VrefMeasurement = MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_ENABLE; + iddconfig.Calibration = MFXSTM32L152_IDD_AUTO_CALIBRATION_ENABLE; + iddconfig.PreDelayUnit = MFXSTM32L152_IDD_PREDELAY_20_MS; + iddconfig.PreDelayValue = 0x7F; + iddconfig.MeasureNb = 100; + iddconfig.DeltaDelayUnit= MFXSTM32L152_IDD_DELTADELAY_0_5_MS; + iddconfig.DeltaDelayValue = 10; + BSP_IDD_Config(iddconfig); + + ret = IDD_OK; + } + else + { + ret = IDD_ERROR; + } + + return ret; +} + +/** + * @brief Unconfigures IDD measurement component. + * @retval IDD_OK if no problem during deinitialization + */ +void BSP_IDD_DeInit(void) +{ + if(IddDrv->DeInit!= NULL) + { + IddDrv->DeInit(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Reset Idd measurement component. + * @retval None + */ +void BSP_IDD_Reset(void) +{ + if(IddDrv->Reset != NULL) + { + IddDrv->Reset(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Turn Idd measurement component in low power (standby/sleep) mode + * @retval None + */ +void BSP_IDD_LowPower(void) +{ + if(IddDrv->LowPower != NULL) + { + IddDrv->LowPower(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Start Measurement campaign + * @retval None + */ +void BSP_IDD_StartMeasure(void) +{ + if(IddDrv->Start != NULL) + { + IddDrv->Start(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Configure Idd component + * @param IddConfig: structure of idd parameters + * @retval None + */ +void BSP_IDD_Config(IDD_ConfigTypeDef IddConfig) +{ + if(IddDrv->Config != NULL) + { + IddDrv->Config(IDD_I2C_ADDRESS, IddConfig); + } +} + +/** + * @brief Get Idd current value. + * @param IddValue: Pointer on u32 to store Idd. Value unit is 10 nA. + * @retval None + */ +void BSP_IDD_GetValue(uint32_t *IddValue) +{ + if(IddDrv->GetValue != NULL) + { + IddDrv->GetValue(IDD_I2C_ADDRESS, IddValue); + } +} + +/** + * @brief Enable Idd interrupt that warn end of measurement + * @retval None + */ +void BSP_IDD_EnableIT(void) +{ + if(IddDrv->EnableIT != NULL) + { + IddDrv->EnableIT(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Clear Idd interrupt that warn end of measurement + * @retval None + */ +void BSP_IDD_ClearIT(void) +{ + if(IddDrv->ClearIT != NULL) + { + IddDrv->ClearIT(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Get Idd interrupt status + * @retval status + */ +uint8_t BSP_IDD_GetITStatus(void) +{ + if(IddDrv->GetITStatus != NULL) + { + return (IddDrv->GetITStatus(IDD_I2C_ADDRESS)); + } + else + { + return IDD_ERROR; + } +} + +/** + * @brief Disable Idd interrupt that warn end of measurement + * @retval None + */ +void BSP_IDD_DisableIT(void) +{ + if(IddDrv->DisableIT != NULL) + { + IddDrv->DisableIT(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Get Error Code . + * @retval Error code or error status + */ +uint8_t BSP_IDD_ErrorGetCode(void) +{ + if(IddDrv->ErrorGetSrc != NULL) + { + if((IddDrv->ErrorGetSrc(IDD_I2C_ADDRESS) & MFXSTM32L152_IDD_ERROR_SRC) != RESET) + { + if(IddDrv->ErrorGetCode != NULL) + { + return IddDrv->ErrorGetCode(IDD_I2C_ADDRESS); + } + else + { + return IDD_ERROR; + } + } + else + { + return IDD_ERROR; + } + } + else + { + return IDD_ERROR; + } +} + + +/** + * @brief Enable error interrupt that warn end of measurement + * @retval None + */ +void BSP_IDD_ErrorEnableIT(void) +{ + if(IddDrv->ErrorEnableIT != NULL) + { + IddDrv->ErrorEnableIT(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Clear Error interrupt that warn end of measurement + * @retval None + */ +void BSP_IDD_ErrorClearIT(void) +{ + if(IddDrv->ErrorClearIT != NULL) + { + IddDrv->ErrorClearIT(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Get Error interrupt status + * @retval Status + */ +uint8_t BSP_IDD_ErrorGetITStatus(void) +{ + if(IddDrv->ErrorGetITStatus != NULL) + { + return (IddDrv->ErrorGetITStatus(IDD_I2C_ADDRESS)); + } + else + { + return 0; + } +} + +/** + * @brief Disable Error interrupt + * @retval None + */ +void BSP_IDD_ErrorDisableIT(void) +{ + if(IddDrv->ErrorDisableIT != NULL) + { + IddDrv->ErrorDisableIT(IDD_I2C_ADDRESS); + } +} + +/** + * @brief Wake up Idd measurement component. + * @retval None + */ +void BSP_IDD_WakeUp(void) +{ + if(IddDrv->WakeUp != NULL) + { + IddDrv->WakeUp(IDD_I2C_ADDRESS); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_idd.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,168 @@ + /** + ****************************************************************************** + * @file stm32l476g_discovery_idd.h + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief Header file for stm32l476g_discovery_idd.c module. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L476G_DISCOVERY_IDD_H +#define __STM32L476G_DISCOVERY_IDD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery.h" +/* Include Idd measurement component driver */ +#include "../Components/mfxstm32l152/mfxstm32l152.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY_IDD + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_IDD_Exported_Types Exported Types + * @{ + */ + +/** @defgroup IDD_Config IDD Config + * @{ + */ +typedef enum +{ + IDD_OK = 0, + IDD_TIMEOUT = 1, + IDD_ZERO_VALUE = 2, + IDD_ERROR = 0xFF +} +IDD_StatusTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_IDD_Exported_Defines Exported Defines + * @{ + */ +/** + * @brief Shunt values on discovery in milli ohms + */ +#define DISCOVERY_IDD_SHUNT0_VALUE ((uint16_t) 1000) /*!< value in milliohm */ +#define DISCOVERY_IDD_SHUNT1_VALUE ((uint16_t) 24) /*!< value in ohm */ +#define DISCOVERY_IDD_SHUNT2_VALUE ((uint16_t) 620) /*!< value in ohm */ +#define DISCOVERY_IDD_SHUNT4_VALUE ((uint16_t) 10000) /*!< value in ohm */ + +/** + * @brief Shunt stabilization delay on discovery in milli ohms + */ +#define DISCOVERY_IDD_SHUNT0_STABDELAY ((uint8_t) 149) /*!< value in millisec */ +#define DISCOVERY_IDD_SHUNT1_STABDELAY ((uint8_t) 149) /*!< value in millisec */ +#define DISCOVERY_IDD_SHUNT2_STABDELAY ((uint8_t) 149) /*!< value in millisec */ +#define DISCOVERY_IDD_SHUNT4_STABDELAY ((uint8_t) 255) /*!< value in millisec */ + +/** + * @brief IDD Ampli Gain on discovery + */ +#if defined(USE_STM32L476G_DISCO_REVC) +#define DISCOVERY_IDD_AMPLI_GAIN ((uint16_t) 4967) /*!< value is gain * 100 */ +#else +#define DISCOVERY_IDD_AMPLI_GAIN ((uint16_t) 4990) /*!< value is gain * 100 */ +#endif + +/** + * @brief IDD Vdd Min on discovery + */ +#define DISCOVERY_IDD_VDD_MIN ((uint16_t) 2000) /*!< value in millivolt */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_IDD_Exported_Functions Exported Functions + * @{ + */ +uint8_t BSP_IDD_Init(void); +void BSP_IDD_DeInit(void); +void BSP_IDD_Reset(void); +void BSP_IDD_LowPower(void); +void BSP_IDD_WakeUp(void); +void BSP_IDD_StartMeasure(void); +void BSP_IDD_Config(IDD_ConfigTypeDef IddConfig); +void BSP_IDD_GetValue(uint32_t *IddValue); +void BSP_IDD_EnableIT(void); +void BSP_IDD_ClearIT(void); +uint8_t BSP_IDD_GetITStatus(void); +void BSP_IDD_DisableIT(void); +uint8_t BSP_IDD_ErrorGetCode(void); +void BSP_IDD_ErrorEnableIT(void); +void BSP_IDD_ErrorClearIT(void); +uint8_t BSP_IDD_ErrorGetITStatus(void); +void BSP_IDD_ErrorDisableIT(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L476G_DISCOVERY_IDD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_qspi.c Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,908 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_qspi.c + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file includes a standard driver for the N25Q128A QSPI + * memory mounted on STM32L476G-Discovery board. + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) This driver is used to drive the N25Q128A QSPI external + memory mounted on STM32L476G-DISCO evaluation board. + + (#) This driver need a specific component driver (N25Q128A) to be included with. + + (#) Initialization steps: + (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This + function includes the MSP layer hardware resources initialization and the + QSPI interface with the external memory. + + (#) QSPI memory operations + (++) QSPI memory can be accessed with read/write operations once it is + initialized. + Read/write operation can be performed with AHB access using the functions + BSP_QSPI_Read()/BSP_QSPI_Write(). + (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. + (see the QSPI memory data sheet) + (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by + specifying the block address. You can perform an erase operation of the whole + chip by calling the function BSP_QSPI_Erase_Chip(). + (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. + (see the QSPI memory data sheet) + @endverbatim + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery_qspi.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_QSPI STM32L476G-DISCOVERY QSPI + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup STM32L476G_DISCOVERY_QSPI_Private_Variables Private Variables + * @{ + */ +QSPI_HandleTypeDef QSPIHandle; + +/** + * @} + */ + + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup STM32L476G_DISCOVERY_QSPI_Private_Functions Private Functions + * @{ + */ +static void QSPI_MspInit (void); +static void QSPI_MspDeInit (void); +static uint8_t QSPI_ResetMemory (QSPI_HandleTypeDef *hqspi); +static uint8_t QSPI_DummyCyclesCfg (QSPI_HandleTypeDef *hqspi); +static uint8_t QSPI_WriteEnable (QSPI_HandleTypeDef *hqspi); +static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout); + +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @addtogroup STM32L476G_DISCOVERY_QSPI_Exported_Functions + * @{ + */ + +/** + * @brief Initializes the QSPI interface. + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_Init(void) +{ + QSPIHandle.Instance = QUADSPI; + + /* Call the DeInit function to reset the driver */ + if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) + { + return QSPI_ERROR; + } + + /* System level initialization */ + QSPI_MspInit(); + + /* QSPI initialization */ + QSPIHandle.Init.ClockPrescaler = 1; /* QSPI clock = 80MHz / (ClockPrescaler+1) = 40MHz */ + QSPIHandle.Init.FifoThreshold = 4; + QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; + QSPIHandle.Init.FlashSize = POSITION_VAL(N25Q128A_FLASH_SIZE) - 1; + QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; + QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0; + + if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) + { + return QSPI_ERROR; + } + + /* QSPI memory reset */ + if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK) + { + return QSPI_NOT_SUPPORTED; + } + + /* Configuration of the dummy cucles on QSPI memory side */ + if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK) + { + return QSPI_NOT_SUPPORTED; + } + + return QSPI_OK; +} + +/** + * @brief De-Initializes the QSPI interface. + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_DeInit(void) +{ + QSPIHandle.Instance = QUADSPI; + + /* Call the DeInit function to reset the driver */ + if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) + { + return QSPI_ERROR; + } + + /* System level De-initialization */ + QSPI_MspDeInit(); + + return QSPI_OK; +} + +/** + * @brief Reads an amount of data from the QSPI memory. + * @param pData: Pointer to data to be read + * @param ReadAddr: Read start address + * @param Size: Size of data to read + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) +{ + QSPI_CommandTypeDef sCommand; + + /* Initialize the read command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD; + sCommand.AddressMode = QSPI_ADDRESS_4_LINES; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.Address = ReadAddr; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_4_LINES; + sCommand.DummyCycles = N25Q128A_DUMMY_CYCLES_READ_QUAD; + sCommand.NbData = Size; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief Writes an amount of data to the QSPI memory. + * @param pData: Pointer to data to be written + * @param WriteAddr: Write start address + * @param Size: Size of data to write + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) +{ + QSPI_CommandTypeDef sCommand; + uint32_t end_addr, current_size, current_addr; + + /* Calculation of the size between the write address and the end of the page */ + current_addr = 0; + + while (current_addr <= WriteAddr) + { + current_addr += N25Q128A_PAGE_SIZE; + } + current_size = current_addr - WriteAddr; + + /* Check if the size of the data is less than the remaining place in the page */ + if (current_size > Size) + { + current_size = Size; + } + + /* Initialize the adress variables */ + current_addr = WriteAddr; + end_addr = WriteAddr + Size; + + /* Initialize the program command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = EXT_QUAD_IN_FAST_PROG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_4_LINES; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_4_LINES; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Perform the write page by page */ + do + { + sCommand.Address = current_addr; + sCommand.NbData = current_size; + + /* Enable write operations */ + if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Configure the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Transmission of the data */ + if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of program */ + if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Update the address and size variables for next page programming */ + current_addr += current_size; + pData += current_size; + current_size = ((current_addr + N25Q128A_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : N25Q128A_PAGE_SIZE; + } while (current_addr < end_addr); + + return QSPI_OK; +} + +/** + * @brief Erases the specified block of the QSPI memory. + * @param BlockAddress: Block address to erase + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) +{ + QSPI_CommandTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = SUBSECTOR_ERASE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_1_LINE; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.Address = BlockAddress; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Enable write operations */ + if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of erase */ + if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief Erases the specified sector of the QSPI memory. + * @param Sector: Sector address to erase (0 to 255) + * @retval QSPI memory status + * @note This function is non blocking meaning that sector erase + * operation is started but not completed when the function + * returns. Application has to call BSP_QSPI_GetStatus() + * to know when the device is available again (i.e. erase operation + * completed). + */ +uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) +{ + QSPI_CommandTypeDef sCommand; + + if (Sector >= (uint32_t)(N25Q128A_FLASH_SIZE/N25Q128A_SECTOR_SIZE)) + { + return QSPI_ERROR; + } + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = SECTOR_ERASE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_1_LINE; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.Address = (Sector * N25Q128A_SECTOR_SIZE); + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Enable write operations */ + if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief Erases the entire QSPI memory. + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_Erase_Chip(void) +{ + QSPI_CommandTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = BULK_ERASE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Enable write operations */ + if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of erase */ + if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_BULK_ERASE_MAX_TIME) != QSPI_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief Reads current status of the QSPI memory. + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_GetStatus(void) +{ + QSPI_CommandTypeDef sCommand; + uint8_t reg; + + /* Initialize the read flag status register command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = READ_FLAG_STATUS_REG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_1_LINE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Check the value of the register */ + if ((reg & (N25Q128A_FSR_PRERR | N25Q128A_FSR_VPPERR | N25Q128A_FSR_PGERR | N25Q128A_FSR_ERERR)) != 0) + { + return QSPI_ERROR; + } + else if ((reg & (N25Q128A_FSR_PGSUS | N25Q128A_FSR_ERSUS)) != 0) + { + return QSPI_SUSPENDED; + } + else if ((reg & N25Q128A_FSR_READY) != 0) + { + return QSPI_OK; + } + else + { + return QSPI_BUSY; + } +} + +/** + * @brief Return the configuration of the QSPI memory. + * @param pInfo: pointer on the configuration structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo) +{ + /* Configure the structure with the memory configuration */ + pInfo->FlashSize = N25Q128A_FLASH_SIZE; + pInfo->EraseSectorSize = N25Q128A_SUBSECTOR_SIZE; + pInfo->EraseSectorsNumber = (N25Q128A_FLASH_SIZE/N25Q128A_SUBSECTOR_SIZE); + pInfo->ProgPageSize = N25Q128A_PAGE_SIZE; + pInfo->ProgPagesNumber = (N25Q128A_FLASH_SIZE/N25Q128A_PAGE_SIZE); + + return QSPI_OK; +} + +/** + * @brief Configure the QSPI in memory-mapped mode + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_EnableMemoryMappedMode(void) +{ + QSPI_CommandTypeDef sCommand; + QSPI_MemoryMappedTypeDef sMemMappedCfg; + + /* Configure the command for the read instruction */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD; + sCommand.AddressMode = QSPI_ADDRESS_4_LINES; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_4_LINES; + sCommand.DummyCycles = N25Q128A_DUMMY_CYCLES_READ_QUAD; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the memory mapped mode */ + sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_ENABLE; + sMemMappedCfg.TimeOutPeriod = 4; /* 50 ns (4 periods of a 80 MHz clock) */ + + if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function suspends an ongoing erase command. + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_SuspendErase(void) +{ + QSPI_CommandTypeDef sCommand; + + /* Check whether the device is busy (erase operation is + in progress). + */ + if (BSP_QSPI_GetStatus() == QSPI_BUSY) + { + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Enable write operations */ + if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) + { + return QSPI_OK; + } + + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function resumes a paused erase command. + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_ResumeErase(void) +{ + QSPI_CommandTypeDef sCommand; + + /* Check whether the device is in suspended state */ + if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) + { + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = PROG_ERASE_RESUME_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Enable write operations */ + if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* + When this command is executed, the status register write in progress bit is set to 1, and + the flag status register program erase controller bit is set to 0. This command is ignored + if the device is not in a suspended state. + */ + + if (BSP_QSPI_GetStatus() == QSPI_BUSY) + { + return QSPI_OK; + } + + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @} + */ + +/** @addtogroup STM32L476G_DISCOVERY_QSPI_Private_Functions + * @{ + */ + +/** + * @brief Initializes the QSPI MSP. + * @retval None + */ +static void QSPI_MspInit(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable the QuadSPI memory interface clock */ + __HAL_RCC_QSPI_CLK_ENABLE(); + + /* Reset the QuadSPI memory interface */ + __HAL_RCC_QSPI_FORCE_RESET(); + __HAL_RCC_QSPI_RELEASE_RESET(); + + /* Enable GPIO clocks */ + __HAL_RCC_GPIOE_CLK_ENABLE(); + + /* QSPI CS GPIO pin configuration */ + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + /* QSPI CLK, D0, D1, D2 and D3 GPIO pins configuration */ + GPIO_InitStruct.Pin = (GPIO_PIN_10 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); +} + +/** + * @brief De-Initializes the QSPI MSP. + * @retval None + */ +static void QSPI_MspDeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* QSPI CLK, CS, PE10 - PE15 GPIO pins de-configuration */ + + __HAL_RCC_GPIOE_CLK_ENABLE(); + HAL_GPIO_DeInit(GPIOE, (GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)); + /* Set GPIOE pin 11 in pull up mode (optimum default setting) */ + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + /* Set GPIOE pin 10 in no pull, low state (optimum default setting) */ + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP ; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Pin = (GPIO_PIN_10); + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_10, GPIO_PIN_RESET); + + /* Reset the QuadSPI memory interface */ + __HAL_RCC_QSPI_FORCE_RESET(); + __HAL_RCC_QSPI_RELEASE_RESET(); + + /* Disable the QuadSPI memory interface clock */ + __HAL_RCC_QSPI_CLK_DISABLE(); +} + +/** + * @brief This function reset the QSPI memory. + * @param hqspi: QSPI handle + * @retval None + */ +static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi) +{ + QSPI_CommandTypeDef sCommand; + + /* Initialize the reset enable command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = RESET_ENABLE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Send the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Send the reset memory command */ + sCommand.Instruction = RESET_MEMORY_CMD; + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait the memory is ready */ + if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function configure the dummy cycles on memory side. + * @param hqspi: QSPI handle + * @retval None + */ +static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi) +{ + QSPI_CommandTypeDef sCommand; + uint8_t reg; + + /* Initialize the read volatile configuration register command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = READ_VOL_CFG_REG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_1_LINE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Enable write operations */ + if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Update volatile configuration register (with new dummy cycles) */ + sCommand.Instruction = WRITE_VOL_CFG_REG_CMD; + MODIFY_REG(reg, N25Q128A_VCR_NB_DUMMY, (N25Q128A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q128A_VCR_NB_DUMMY))); + + /* Configure the write volatile configuration register command */ + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Transmission of the data */ + if (HAL_QSPI_Transmit(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function send a Write Enable and wait it is effective. + * @param hqspi: QSPI handle + * @retval None + */ +static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi) +{ + QSPI_CommandTypeDef sCommand; + QSPI_AutoPollingTypeDef sConfig; + + /* Enable write operations */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = WRITE_ENABLE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for write enabling */ + sConfig.Match = N25Q128A_SR_WREN; + sConfig.Mask = N25Q128A_SR_WREN; + sConfig.MatchMode = QSPI_MATCH_MODE_AND; + sConfig.StatusBytesSize = 1; + sConfig.Interval = 0x10; + sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; + + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.DataMode = QSPI_DATA_1_LINE; + + if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function read the SR of the memory and wait the EOP. + * @param hqspi: QSPI handle + * @param Timeout: Timeout for auto-polling + * @retval None + */ +static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout) +{ + QSPI_CommandTypeDef sCommand; + QSPI_AutoPollingTypeDef sConfig; + + /* Configure automatic polling mode to wait for memory ready */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_1_LINE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + sConfig.Match = 0; + sConfig.Mask = N25Q128A_SR_WIP; + sConfig.MatchMode = QSPI_MATCH_MODE_AND; + sConfig.StatusBytesSize = 1; + sConfig.Interval = 0x10; + sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; + + if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, Timeout) != HAL_OK) + { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Disco/stm32l476g_discovery_qspi.h Mon Nov 02 19:38:36 2015 +0000 @@ -0,0 +1,135 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_qspi.h + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file contains the common defines and functions prototypes for + * the stm32l476g_discovery_qspi.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L476G_DISCOVERY_QSPI_H +#define __STM32L476G_DISCOVERY_QSPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" +#include "../Components/n25q128a/n25q128a.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY_QSPI + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_QSPI_Exported_Constants Exported Constants + * @{ + */ +/* QSPI Error codes */ +#define QSPI_OK ((uint8_t)0x00) +#define QSPI_ERROR ((uint8_t)0x01) +#define QSPI_BUSY ((uint8_t)0x02) +#define QSPI_NOT_SUPPORTED ((uint8_t)0x04) +#define QSPI_SUSPENDED ((uint8_t)0x08) + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_QSPI_Exported_Types Exported Types + * @{ + */ +/* QSPI Info */ +typedef struct { + uint32_t FlashSize; /*!< Size of the flash */ + uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */ + uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */ + uint32_t ProgPageSize; /*!< Size of pages for the program operation */ + uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */ +} QSPI_Info; + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup STM32L476G_DISCOVERY_QSPI_Exported_Functions Exported Functions + * @{ + */ +uint8_t BSP_QSPI_Init (void); +uint8_t BSP_QSPI_DeInit (void); +uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size); +uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size); +uint8_t BSP_QSPI_Erase_Block (uint32_t BlockAddress); +uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector); +uint8_t BSP_QSPI_Erase_Chip (void); +uint8_t BSP_QSPI_GetStatus (void); +uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo); +uint8_t BSP_QSPI_EnableMemoryMappedMode(void); +uint8_t BSP_QSPI_SuspendErase(void); +uint8_t BSP_QSPI_ResumeErase (void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L476G_DISCOVERY_QSPI_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +