Merge pull request #93 from zyp/master
[fw/stlink] / example / stm32f4 / STM32_USB_Device_Library / Class / dfu / src / usbd_dfu_mal.c
1 /**
2   ******************************************************************************
3   * @file    usbd_dfu_mal.c
4   * @author  MCD Application Team
5   * @version V1.0.0
6   * @date    22-July-2011
7   * @brief   Generic media access Layer.
8   ******************************************************************************
9   * @attention
10   *
11   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17   *
18   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
19   ******************************************************************************
20   */ 
21
22 /* Includes ------------------------------------------------------------------*/
23 #include "usbd_dfu_mal.h"
24
25 #include "usbd_flash_if.h"
26
27 #ifdef DFU_MAL_SUPPORT_OTP
28  #include "usbd_otp_if.h"
29 #endif
30
31 #ifdef DFU_MAL_SUPPORT_MEM
32  #include "usbd_mem_if_template.h"
33 #endif
34
35 /* Private typedef -----------------------------------------------------------*/
36 /* Private define ------------------------------------------------------------*/
37 /* Private macro -------------------------------------------------------------*/
38 /* Private variables ---------------------------------------------------------*/
39
40 /* Global Memories callback and string descriptors reference tables.
41    To add a new memory, modify the value of MAX_USED_MEDIA in usbd_dfu_mal.h
42    and add the pointer to the callback structure in this table.
43    Then add the pointer to the memory string descriptor in usbd_dfu_StringDesc table.
44    No other operation is required. */
45 DFU_MAL_Prop_TypeDef* tMALTab[MAX_USED_MEDIA] = {
46     &DFU_Flash_cb
47 #ifdef DFU_MAL_SUPPORT_OTP
48   , &DFU_Otp_cb
49 #endif
50 #ifdef DFU_MAL_SUPPORT_MEM
51   , &DFU_Mem_cb
52 #endif
53 };
54
55 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
56   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
57     #pragma data_alignment=4   
58   #endif
59 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
60
61 __ALIGN_BEGIN const uint8_t* usbd_dfu_StringDesc[MAX_USED_MEDIA] __ALIGN_END  = {
62     FLASH_IF_STRING
63 #ifdef DFU_MAL_SUPPORT_OTP
64   , OTP_IF_STRING
65 #endif
66 #ifdef DFU_MAL_SUPPORT_MEM
67   , MEM_IF_STRING
68 #endif
69 };
70
71 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
72   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
73     #pragma data_alignment=4   
74   #endif
75 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
76 /* RAM Buffer for Downloaded Data */
77 __ALIGN_BEGIN uint8_t  MAL_Buffer[XFERSIZE] __ALIGN_END ; 
78
79 /* Private function prototypes -----------------------------------------------*/
80 static uint8_t  MAL_CheckAdd  (uint32_t Add);
81 /* Private functions ---------------------------------------------------------*/
82
83 /**
84   * @brief  MAL_Init
85   *         Initializes the Media on the STM32
86   * @param  None
87   * @retval Result of the opeartion (MAL_OK in all cases)
88   */
89 uint16_t MAL_Init(void)
90 {
91   uint32_t memIdx = 0;
92   
93   /* Init all supported memories */
94   for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
95   {
96     /* If the check addres is positive, exit with the memory index */
97     if (tMALTab[memIdx]->pMAL_Init != NULL)
98     {
99       tMALTab[memIdx]->pMAL_Init();
100     }
101   }
102
103   return MAL_OK;
104 }
105
106 /**
107   * @brief  MAL_DeInit
108   *         DeInitializes the Media on the STM32
109   * @param  None
110   * @retval Result of the opeartion (MAL_OK in all cases)
111   */
112 uint16_t MAL_DeInit(void)
113 {
114   uint32_t memIdx = 0;
115   
116   /* Init all supported memories */
117   for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
118   {
119     /* Check if the command is supported */
120     if (tMALTab[memIdx]->pMAL_DeInit != NULL)
121     {
122       tMALTab[memIdx]->pMAL_DeInit();
123     }
124   }
125
126   return MAL_OK;
127 }
128
129 /**
130   * @brief  MAL_Erase
131   *         Erase a sector of memory.
132   * @param  Add: Sector address/code
133   * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL
134   */
135 uint16_t MAL_Erase(uint32_t Add)
136 {
137   uint32_t memIdx = MAL_CheckAdd(Add);
138  
139   /* Check if the area is protected */
140   if (DFU_MAL_IS_PROTECTED_AREA(Add))
141   {
142     return MAL_FAIL;
143   }    
144   
145   if (memIdx < MAX_USED_MEDIA)
146   {
147     /* Check if the command is supported */
148     if (tMALTab[memIdx]->pMAL_Erase != NULL)
149     {
150       return tMALTab[memIdx]->pMAL_Erase(Add);
151     }
152     else
153     {
154       return MAL_FAIL;
155     }
156   }
157   else
158   {
159     return MAL_FAIL;
160   }
161 }
162
163 /**
164   * @brief  MAL_Write
165   *         Write sectors of memory.
166   * @param  Add: Sector address/code
167   * @param  Len: Number of data to be written (in bytes)
168   * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL
169   */
170 uint16_t MAL_Write (uint32_t Add, uint32_t Len)
171 {
172   uint32_t memIdx = MAL_CheckAdd(Add);
173  
174   /* Check if the area is protected */
175   if (DFU_MAL_IS_PROTECTED_AREA(Add))
176   {
177     return MAL_FAIL;
178   }   
179   
180   if (memIdx < MAX_USED_MEDIA)
181   {
182     /* Check if the command is supported */
183     if (tMALTab[memIdx]->pMAL_Write != NULL)
184     {
185       return tMALTab[memIdx]->pMAL_Write(Add, Len);
186     }
187     else
188     {
189       return MAL_FAIL;
190     }    
191   }
192   else
193   {
194     return MAL_FAIL;
195   }
196 }
197
198 /**
199   * @brief  MAL_Read
200   *         Read sectors of memory.
201   * @param  Add: Sector address/code
202   * @param  Len: Number of data to be written (in bytes)
203   * @retval Buffer pointer
204   */
205 uint8_t *MAL_Read (uint32_t Add, uint32_t Len)
206 {
207   uint32_t memIdx = MAL_CheckAdd(Add);
208   
209   if (memIdx < MAX_USED_MEDIA)
210   {
211     /* Check if the command is supported */
212     if (tMALTab[memIdx]->pMAL_Read != NULL)
213     {
214       return tMALTab[memIdx]->pMAL_Read(Add, Len);
215     }
216     else
217     {
218       return MAL_Buffer;
219     }     
220   }
221   else
222   {
223     return MAL_Buffer;
224   }
225 }
226
227 /**
228   * @brief  MAL_GetStatus
229   *         Get the status of a given memory.
230   * @param  Add: Sector address/code (allow to determine which memory will be addressed)
231   * @param  Cmd: 0 for erase and 1 for write
232   * @param  buffer: pointer to the buffer where the status data will be stored.
233   * @retval Buffer pointer
234   */
235 uint16_t MAL_GetStatus(uint32_t Add , uint8_t Cmd, uint8_t *buffer)
236 {
237   uint32_t memIdx = MAL_CheckAdd(Add);
238   
239   if (memIdx < MAX_USED_MEDIA)
240   {
241     if (Cmd & 0x01)
242     {
243       SET_POLLING_TIMING(tMALTab[memIdx]->EraseTiming);
244     }
245     else
246     {
247       SET_POLLING_TIMING(tMALTab[memIdx]->WriteTiming);
248     }
249     
250     return MAL_OK;
251   }
252   else
253   {
254     return MAL_FAIL;
255   }
256 }
257
258 /**
259   * @brief  MAL_CheckAdd
260   *         Determine which memory should be managed.
261   * @param  Add: Sector address/code (allow to determine which memory will be addressed)
262   * @retval Index of the addressed memory.
263   */
264 static uint8_t  MAL_CheckAdd(uint32_t Add)
265 {
266   uint32_t memIdx = 0;
267   
268   /* Check with all supported memories */
269   for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
270   {
271     /* If the check addres is positive, exit with the memory index */
272     if (tMALTab[memIdx]->pMAL_CheckAdd(Add) == MAL_OK)
273     {
274       return memIdx;
275     }
276   }
277   /* If no memory found, return MAX_USED_MEDIA */
278   return (MAX_USED_MEDIA);
279 }
280
281 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/