add u8g2 and ui libs (#91)
* add u8g2 and ui libs * add display driver and usage example * not init display in test mode * change todo text * fix removed code * Target f2 (#107) * add ioc for flipperzero f2 * add generated f1 files to f2 * regenerate cubemx * invert initial state of led * blink backligh * shutdown backlight on idle
This commit is contained in:
		
							parent
							
								
									884fccc591
								
							
						
					
					
						commit
						5c81bb8abc
					
				
							
								
								
									
										184
									
								
								applications/display-u8g2/display-u8g2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								applications/display-u8g2/display-u8g2.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,184 @@ | |||||||
|  | #include "u8g2/u8g2.h" | ||||||
|  | #include "flipper.h" | ||||||
|  | 
 | ||||||
|  | extern SPI_HandleTypeDef hspi1; | ||||||
|  | 
 | ||||||
|  | // #define DEBUG 1
 | ||||||
|  | 
 | ||||||
|  | // TODO rewrite u8g2 to pass thread-local context in this handlers
 | ||||||
|  | 
 | ||||||
|  | static uint8_t u8g2_gpio_and_delay_stm32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { | ||||||
|  |     switch(msg) { | ||||||
|  |         //Initialize SPI peripheral
 | ||||||
|  |         case U8X8_MSG_GPIO_AND_DELAY_INIT: | ||||||
|  |             /* HAL initialization contains all what we need so we can skip this part. */ | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         //Function which implements a delay, arg_int contains the amount of ms
 | ||||||
|  |         case U8X8_MSG_DELAY_MILLI: | ||||||
|  |             osDelay(arg_int); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         //Function which delays 10us
 | ||||||
|  |         case U8X8_MSG_DELAY_10MICRO: | ||||||
|  |             delay_us(10); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         //Function which delays 100ns
 | ||||||
|  |         case U8X8_MSG_DELAY_100NANO: | ||||||
|  |             asm("nop"); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         // Function to define the logic level of the RESET line
 | ||||||
|  |         case U8X8_MSG_GPIO_RESET: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 fuprintf(log, "[u8g2] rst %d\n", arg_int); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             // TODO change it to FuriRecord pin
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_RST_GPIO_Port, DISPLAY_RST_Pin, arg_int ? GPIO_PIN_SET : GPIO_PIN_RESET); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         default: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 fufuprintf(log, "[u8g2] unknown io %d\n", msg); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             return 0; //A message was received which is not implemented, return 0 to indicate an error
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 1; // command processed successfully.
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static uint8_t u8x8_hw_spi_stm32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr){ | ||||||
|  |     switch (msg) { | ||||||
|  |         case U8X8_MSG_BYTE_SEND: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 fuprintf(log, "[u8g2] send %d bytes %02X\n", arg_int, ((uint8_t*)arg_ptr)[0]); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             // TODO change it to FuriRecord SPI
 | ||||||
|  |             HAL_SPI_Transmit(&hspi1, (uint8_t *)arg_ptr, arg_int, 10000); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 fuprintf(log, "[u8g2] dc %d\n", arg_int); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             // TODO change it to FuriRecord pin
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_DI_GPIO_Port, DISPLAY_DI_Pin, arg_int ? GPIO_PIN_SET : GPIO_PIN_RESET); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case U8X8_MSG_BYTE_INIT: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 fuprintf(log, "[u8g2] init\n"); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             // TODO change it to FuriRecord pin
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_RESET); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 fuprintf(log, "[u8g2] start\n"); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             // TODO change it to FuriRecord pin
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_RESET); | ||||||
|  |             asm("nop"); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 fuprintf(log, "[u8g2] end\n"); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             asm("nop"); | ||||||
|  |             // TODO change it to FuriRecord pin
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_SET); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         default: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 fuprintf(log, "[u8g2] unknown xfer %d\n", msg); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     SemaphoreHandle_t update; // queue to pass events from callback to app thread
 | ||||||
|  |     FuriRecordSubscriber* log; // app logger
 | ||||||
|  | } DisplayCtx; | ||||||
|  | 
 | ||||||
|  | static void handle_fb_change(const void* fb, size_t fb_size, void* raw_ctx) { | ||||||
|  |     DisplayCtx* ctx = (DisplayCtx*)raw_ctx; // make right type
 | ||||||
|  | 
 | ||||||
|  |     fuprintf(ctx->log, "[display_u8g2] change fb\n"); | ||||||
|  | 
 | ||||||
|  |     // send update to app thread
 | ||||||
|  |     xSemaphoreGive(ctx->update); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void display_u8g2(void* p) { | ||||||
|  |     FuriRecordSubscriber* log = get_default_log(); | ||||||
|  | 
 | ||||||
|  |     // TODO we need different app to contol backlight
 | ||||||
|  |     HAL_GPIO_WritePin(DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin, GPIO_PIN_SET); | ||||||
|  | 
 | ||||||
|  |     u8g2_t _u8g2; | ||||||
|  |     u8g2_Setup_st7565_erc12864_alt_f(&_u8g2, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); | ||||||
|  |     u8g2_InitDisplay(&_u8g2); // send init sequence to the display, display is in sleep mode after this
 | ||||||
|  |     u8g2_SetContrast(&_u8g2, 36); | ||||||
|  | 
 | ||||||
|  |     if(!furi_create("u8g2_fb", (void*)&_u8g2, sizeof(_u8g2))) { | ||||||
|  |         fuprintf(log, "[display_u8g2] cannot create fb record\n"); | ||||||
|  |         furiac_exit(NULL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     StaticSemaphore_t event_descriptor; | ||||||
|  |     // create stack-based counting semaphore
 | ||||||
|  |     SemaphoreHandle_t update = xSemaphoreCreateCountingStatic(255, 0, &event_descriptor); | ||||||
|  | 
 | ||||||
|  |     if(update == NULL) { | ||||||
|  |         fuprintf(log, "[display_u8g2] cannot create update semaphore\n"); | ||||||
|  |         furiac_exit(NULL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // save log and event queue in context structure
 | ||||||
|  |     DisplayCtx ctx = {.update = update, .log = log}; | ||||||
|  | 
 | ||||||
|  |     // subscribe to record. ctx will be passed to handle_fb_change
 | ||||||
|  |     FuriRecordSubscriber* fb_record = furi_open( | ||||||
|  |         "u8g2_fb", false, false, handle_fb_change, NULL, &ctx | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     if(fb_record == NULL) { | ||||||
|  |         fuprintf(log, "[display] cannot open fb record\n"); | ||||||
|  |         furiac_exit(NULL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     u8g2_t* u8g2 = (u8g2_t*)furi_take(fb_record); | ||||||
|  |     u8g2_SetPowerSave(u8g2, 0); // wake up display
 | ||||||
|  |     u8g2_SendBuffer(u8g2); | ||||||
|  |     furi_give(fb_record); | ||||||
|  | 
 | ||||||
|  |     while(1) { | ||||||
|  |         // wait for event
 | ||||||
|  |         if(xSemaphoreTake(update, 1000) == pdTRUE) { | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin, GPIO_PIN_SET); | ||||||
|  | 
 | ||||||
|  |             u8g2_t* u8g2 = (u8g2_t*)furi_take(fb_record); | ||||||
|  |             u8g2_SetPowerSave(u8g2, 0); // wake up display
 | ||||||
|  |             u8g2_SendBuffer(u8g2); | ||||||
|  |             furi_give(fb_record); | ||||||
|  |         } else { | ||||||
|  |             // TODO we need different app to contol backlight
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin, GPIO_PIN_RESET); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								applications/examples/u8g2_example.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								applications/examples/u8g2_example.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | #include "u8g2/u8g2.h" | ||||||
|  | #include "flipper.h" | ||||||
|  | 
 | ||||||
|  | void u8g2_example(void* p) { | ||||||
|  |     FuriRecordSubscriber* log = get_default_log(); | ||||||
|  | 
 | ||||||
|  |     // TODO try open record and retry on timeout (needs FURI behaviour change)
 | ||||||
|  |     delay(1000); | ||||||
|  |      | ||||||
|  |     // open record
 | ||||||
|  |     FuriRecordSubscriber* fb_record = furi_open( | ||||||
|  |         "u8g2_fb", false, false, NULL, NULL, NULL | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     if(fb_record == NULL) { | ||||||
|  |         fuprintf(log, "[widget] cannot create fb record\n"); | ||||||
|  |         furiac_exit(NULL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     while(1) { | ||||||
|  |         u8g2_t* fb = furi_take(fb_record); | ||||||
|  |         if(fb != NULL) { | ||||||
|  |             u8g2_SetFont(fb, u8g2_font_6x10_mf); | ||||||
|  |             u8g2_SetDrawColor(fb, 1); | ||||||
|  |             u8g2_SetFontMode(fb, 1); | ||||||
|  |             u8g2_DrawStr(fb, 2, 12, "hello world!"); | ||||||
|  |         } | ||||||
|  |         furi_commit(fb_record); | ||||||
|  | 
 | ||||||
|  |         if(fb != NULL) { | ||||||
|  |             furiac_exit(NULL); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         delay(1); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -16,7 +16,16 @@ void application_uart_write(void* p); | |||||||
| void application_ipc_display(void* p); | void application_ipc_display(void* p); | ||||||
| void application_ipc_widget(void* p); | void application_ipc_widget(void* p); | ||||||
| 
 | 
 | ||||||
|  | void display_u8g2(void* p); | ||||||
|  | 
 | ||||||
|  | void u8g2_example(void* p); | ||||||
|  | 
 | ||||||
| const FlipperStartupApp FLIPPER_STARTUP[] = { | const FlipperStartupApp FLIPPER_STARTUP[] = { | ||||||
|  |     #ifndef TEST | ||||||
|  |     {.app = display_u8g2, .name = "display_u8g2"}, | ||||||
|  |     {.app = u8g2_example, .name = "u8g2_example"}, | ||||||
|  |     #endif | ||||||
|  |      | ||||||
|     #ifdef TEST |     #ifdef TEST | ||||||
|     {.app = flipper_test_app, .name = "test app"}, |     {.app = flipper_test_app, .name = "test app"}, | ||||||
|     #endif |     #endif | ||||||
|  | |||||||
							
								
								
									
										3292
									
								
								lib/u8g2/u8g2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3292
									
								
								lib/u8g2/u8g2.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										218
									
								
								lib/u8g2/u8g2_bitmap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								lib/u8g2/u8g2_bitmap.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,218 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8g2_bitmap.c | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8g2.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_SetBitmapMode(u8g2_t *u8g2, uint8_t is_transparent) { | ||||||
|  |   u8g2->bitmap_transparency = is_transparent; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   x,y 	Position on the display | ||||||
|  |   len		Length of bitmap line in pixel. Note: This differs from u8glib which had a bytecount here. | ||||||
|  |   b		Pointer to the bitmap line. | ||||||
|  |   Only draw pixels which are set. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawHorizontalBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) | ||||||
|  | { | ||||||
|  |   uint8_t mask; | ||||||
|  |   uint8_t color = u8g2->draw_color; | ||||||
|  |   uint8_t ncolor = (color == 0 ? 1 : 0); | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   mask = 128; | ||||||
|  |   while(len > 0) | ||||||
|  |   { | ||||||
|  |     if ( *b & mask ) { | ||||||
|  |       u8g2->draw_color = color; | ||||||
|  |       u8g2_DrawHVLine(u8g2, x, y, 1, 0); | ||||||
|  |     } else if ( u8g2->bitmap_transparency == 0 ) { | ||||||
|  |       u8g2->draw_color = ncolor; | ||||||
|  |       u8g2_DrawHVLine(u8g2, x, y, 1, 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     x++; | ||||||
|  |     mask >>= 1; | ||||||
|  |     if ( mask == 0 ) | ||||||
|  |     { | ||||||
|  |       mask = 128; | ||||||
|  |       b++; | ||||||
|  |     } | ||||||
|  |     len--; | ||||||
|  |   } | ||||||
|  |   u8g2->draw_color = color; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* u8glib compatible bitmap draw function */ | ||||||
|  | void u8g2_DrawBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t cnt, u8g2_uint_t h, const uint8_t *bitmap) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t w; | ||||||
|  |   w = cnt; | ||||||
|  |   w *= 8; | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   while( h > 0 ) | ||||||
|  |   { | ||||||
|  |     u8g2_DrawHorizontalBitmap(u8g2, x, y, w, bitmap); | ||||||
|  |     bitmap += cnt; | ||||||
|  |     y++; | ||||||
|  |     h--; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawHXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) | ||||||
|  | { | ||||||
|  |   uint8_t mask; | ||||||
|  |   uint8_t color = u8g2->draw_color; | ||||||
|  |   uint8_t ncolor = (color == 0 ? 1 : 0); | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   mask = 1; | ||||||
|  |   while(len > 0) { | ||||||
|  |     if ( *b & mask ) { | ||||||
|  |       u8g2->draw_color = color; | ||||||
|  |       u8g2_DrawHVLine(u8g2, x, y, 1, 0); | ||||||
|  |     } else if ( u8g2->bitmap_transparency == 0 ) { | ||||||
|  |       u8g2->draw_color = ncolor; | ||||||
|  |       u8g2_DrawHVLine(u8g2, x, y, 1, 0); | ||||||
|  |     } | ||||||
|  |     x++; | ||||||
|  |     mask <<= 1; | ||||||
|  |     if ( mask == 0 ) | ||||||
|  |     { | ||||||
|  |       mask = 1; | ||||||
|  |       b++; | ||||||
|  |     } | ||||||
|  |     len--; | ||||||
|  |   } | ||||||
|  |   u8g2->draw_color = color; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t blen; | ||||||
|  |   blen = w; | ||||||
|  |   blen += 7; | ||||||
|  |   blen >>= 3; | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   while( h > 0 ) | ||||||
|  |   { | ||||||
|  |     u8g2_DrawHXBM(u8g2, x, y, w, bitmap); | ||||||
|  |     bitmap += blen; | ||||||
|  |     y++; | ||||||
|  |     h--; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawHXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) | ||||||
|  | { | ||||||
|  |   uint8_t mask; | ||||||
|  |   uint8_t color = u8g2->draw_color; | ||||||
|  |   uint8_t ncolor = (color == 0 ? 1 : 0); | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   mask = 1; | ||||||
|  |   while(len > 0) | ||||||
|  |   { | ||||||
|  |     if( u8x8_pgm_read(b) & mask ) { | ||||||
|  |       u8g2->draw_color = color; | ||||||
|  |       u8g2_DrawHVLine(u8g2, x, y, 1, 0); | ||||||
|  |     } else if( u8g2->bitmap_transparency == 0 ) { | ||||||
|  |       u8g2->draw_color = ncolor; | ||||||
|  |       u8g2_DrawHVLine(u8g2, x, y, 1, 0); | ||||||
|  |     } | ||||||
|  |     | ||||||
|  |     x++; | ||||||
|  |     mask <<= 1; | ||||||
|  |     if ( mask == 0 ) | ||||||
|  |     { | ||||||
|  |       mask = 1; | ||||||
|  |       b++; | ||||||
|  |     } | ||||||
|  |     len--; | ||||||
|  |   } | ||||||
|  |   u8g2->draw_color = color; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t blen; | ||||||
|  |   blen = w; | ||||||
|  |   blen += 7; | ||||||
|  |   blen >>= 3; | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   while( h > 0 ) | ||||||
|  |   { | ||||||
|  |     u8g2_DrawHXBMP(u8g2, x, y, w, bitmap); | ||||||
|  |     bitmap += blen; | ||||||
|  |     y++; | ||||||
|  |     h--; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										207
									
								
								lib/u8g2/u8g2_box.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								lib/u8g2/u8g2_box.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,207 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8g2_box.c | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8g2.h" | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   draw a filled box | ||||||
|  |   restriction: does not work for w = 0 or h = 0 | ||||||
|  | */ | ||||||
|  | void u8g2_DrawBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) | ||||||
|  | { | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |   while( h != 0 ) | ||||||
|  |   {  | ||||||
|  |     u8g2_DrawHVLine(u8g2, x, y, w, 0); | ||||||
|  |     y++;     | ||||||
|  |     h--; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   draw a frame (empty box) | ||||||
|  |   restriction: does not work for w = 0 or h = 0 | ||||||
|  |   ToDo: | ||||||
|  |     pixel in the corners are drawn twice. This could be optimized. | ||||||
|  | */ | ||||||
|  | void u8g2_DrawFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t xtmp = x; | ||||||
|  |    | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   u8g2_DrawHVLine(u8g2, x, y, w, 0); | ||||||
|  |   u8g2_DrawHVLine(u8g2, x, y, h, 1); | ||||||
|  |   x+=w; | ||||||
|  |   x--; | ||||||
|  |   u8g2_DrawHVLine(u8g2, x, y, h, 1); | ||||||
|  |   y+=h; | ||||||
|  |   y--; | ||||||
|  |   u8g2_DrawHVLine(u8g2, xtmp, y, w, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawRBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t xl, yu; | ||||||
|  |   u8g2_uint_t yl, xr; | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  | 
 | ||||||
|  |   xl = x; | ||||||
|  |   xl += r; | ||||||
|  |   yu = y; | ||||||
|  |   yu += r; | ||||||
|  |   | ||||||
|  |   xr = x; | ||||||
|  |   xr += w; | ||||||
|  |   xr -= r; | ||||||
|  |   xr -= 1; | ||||||
|  |    | ||||||
|  |   yl = y; | ||||||
|  |   yl += h; | ||||||
|  |   yl -= r;  | ||||||
|  |   yl -= 1; | ||||||
|  | 
 | ||||||
|  |   u8g2_DrawDisc(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT); | ||||||
|  |   u8g2_DrawDisc(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT); | ||||||
|  |   u8g2_DrawDisc(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT); | ||||||
|  |   u8g2_DrawDisc(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT); | ||||||
|  | 
 | ||||||
|  |   { | ||||||
|  |     u8g2_uint_t ww, hh; | ||||||
|  | 
 | ||||||
|  |     ww = w; | ||||||
|  |     ww -= r; | ||||||
|  |     ww -= r; | ||||||
|  |     xl++; | ||||||
|  |     yu++; | ||||||
|  |      | ||||||
|  |     if ( ww >= 3 ) | ||||||
|  |     { | ||||||
|  |       ww -= 2; | ||||||
|  |       u8g2_DrawBox(u8g2, xl, y, ww, r+1); | ||||||
|  |       u8g2_DrawBox(u8g2, xl, yl, ww, r+1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     hh = h; | ||||||
|  |     hh -= r; | ||||||
|  |     hh -= r; | ||||||
|  |     //h--;
 | ||||||
|  |     if ( hh >= 3 ) | ||||||
|  |     { | ||||||
|  |       hh -= 2; | ||||||
|  |       u8g2_DrawBox(u8g2, x, yu, w, hh); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawRFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t xl, yu; | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )  | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  | 
 | ||||||
|  |   xl = x; | ||||||
|  |   xl += r; | ||||||
|  |   yu = y; | ||||||
|  |   yu += r; | ||||||
|  |   | ||||||
|  |   { | ||||||
|  |     u8g2_uint_t yl, xr; | ||||||
|  |        | ||||||
|  |     xr = x; | ||||||
|  |     xr += w; | ||||||
|  |     xr -= r; | ||||||
|  |     xr -= 1; | ||||||
|  |      | ||||||
|  |     yl = y; | ||||||
|  |     yl += h; | ||||||
|  |     yl -= r;  | ||||||
|  |     yl -= 1; | ||||||
|  | 
 | ||||||
|  |     u8g2_DrawCircle(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT); | ||||||
|  |     u8g2_DrawCircle(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT); | ||||||
|  |     u8g2_DrawCircle(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT); | ||||||
|  |     u8g2_DrawCircle(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   { | ||||||
|  |     u8g2_uint_t ww, hh; | ||||||
|  | 
 | ||||||
|  |     ww = w; | ||||||
|  |     ww -= r; | ||||||
|  |     ww -= r; | ||||||
|  |     hh = h; | ||||||
|  |     hh -= r; | ||||||
|  |     hh -= r; | ||||||
|  |      | ||||||
|  |     xl++; | ||||||
|  |     yu++; | ||||||
|  |      | ||||||
|  |     if ( ww >= 3 ) | ||||||
|  |     { | ||||||
|  |       ww -= 2; | ||||||
|  |       h--; | ||||||
|  |       u8g2_DrawHLine(u8g2, xl, y, ww); | ||||||
|  |       u8g2_DrawHLine(u8g2, xl, y+h, ww); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if ( hh >= 3 ) | ||||||
|  |     { | ||||||
|  |       hh -= 2; | ||||||
|  |       w--; | ||||||
|  |       u8g2_DrawVLine(u8g2, x, yu, hh); | ||||||
|  |       u8g2_DrawVLine(u8g2, x+w, yu, hh); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										213
									
								
								lib/u8g2/u8g2_buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								lib/u8g2/u8g2_buffer.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,213 @@ | |||||||
|  | /* 
 | ||||||
|  | 
 | ||||||
|  |   u8g2_buffer.c  | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8g2.h" | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | void u8g2_ClearBuffer(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   size_t cnt; | ||||||
|  |   cnt = u8g2_GetU8x8(u8g2)->display_info->tile_width; | ||||||
|  |   cnt *= u8g2->tile_buf_height; | ||||||
|  |   cnt *= 8; | ||||||
|  |   memset(u8g2->tile_buf_ptr, 0, cnt); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | 
 | ||||||
|  | static void u8g2_send_tile_row(u8g2_t *u8g2, uint8_t src_tile_row, uint8_t dest_tile_row) | ||||||
|  | { | ||||||
|  |   uint8_t *ptr; | ||||||
|  |   uint16_t offset; | ||||||
|  |   uint8_t w; | ||||||
|  |    | ||||||
|  |   w = u8g2_GetU8x8(u8g2)->display_info->tile_width; | ||||||
|  |   offset = src_tile_row; | ||||||
|  |   ptr = u8g2->tile_buf_ptr; | ||||||
|  |   offset *= w; | ||||||
|  |   offset *= 8; | ||||||
|  |   ptr += offset; | ||||||
|  |   u8x8_DrawTile(u8g2_GetU8x8(u8g2), 0, dest_tile_row, w, ptr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 
 | ||||||
|  |   write the buffer to the display RAM.  | ||||||
|  |   For most displays, this will make the content visible to the user. | ||||||
|  |   Some displays (like the SSD1606) require a u8x8_RefreshDisplay() | ||||||
|  | */ | ||||||
|  | static void u8g2_send_buffer(u8g2_t *u8g2) U8X8_NOINLINE; | ||||||
|  | static void u8g2_send_buffer(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   uint8_t src_row; | ||||||
|  |   uint8_t src_max; | ||||||
|  |   uint8_t dest_row; | ||||||
|  |   uint8_t dest_max; | ||||||
|  | 
 | ||||||
|  |   src_row = 0; | ||||||
|  |   src_max = u8g2->tile_buf_height; | ||||||
|  |   dest_row = u8g2->tile_curr_row; | ||||||
|  |   dest_max = u8g2_GetU8x8(u8g2)->display_info->tile_height; | ||||||
|  |    | ||||||
|  |   do | ||||||
|  |   { | ||||||
|  |     u8g2_send_tile_row(u8g2, src_row, dest_row); | ||||||
|  |     src_row++; | ||||||
|  |     dest_row++; | ||||||
|  |   } while( src_row < src_max && dest_row < dest_max ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* same as u8g2_send_buffer but also send the DISPLAY_REFRESH message (used by SSD1606) */ | ||||||
|  | void u8g2_SendBuffer(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2_send_buffer(u8g2); | ||||||
|  |   u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) );   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | void u8g2_SetBufferCurrTileRow(u8g2_t *u8g2, uint8_t row) | ||||||
|  | { | ||||||
|  |   u8g2->tile_curr_row = row; | ||||||
|  |   u8g2->cb->update_dimension(u8g2); | ||||||
|  |   u8g2->cb->update_page_win(u8g2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_FirstPage(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   if ( u8g2->is_auto_page_clear ) | ||||||
|  |   { | ||||||
|  |     u8g2_ClearBuffer(u8g2); | ||||||
|  |   } | ||||||
|  |   u8g2_SetBufferCurrTileRow(u8g2, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8g2_NextPage(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   uint8_t row; | ||||||
|  |   u8g2_send_buffer(u8g2); | ||||||
|  |   row = u8g2->tile_curr_row; | ||||||
|  |   row += u8g2->tile_buf_height; | ||||||
|  |   if ( row >= u8g2_GetU8x8(u8g2)->display_info->tile_height ) | ||||||
|  |   { | ||||||
|  |     u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) ); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   if ( u8g2->is_auto_page_clear ) | ||||||
|  |   { | ||||||
|  |     u8g2_ClearBuffer(u8g2); | ||||||
|  |   } | ||||||
|  |   u8g2_SetBufferCurrTileRow(u8g2, row); | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | /*
 | ||||||
|  |   Description: | ||||||
|  |     Update a sub area of the display, given by tile position, width and height. | ||||||
|  |     The arguments are "tile" coordinates. Any u8g2 rotation is ignored. | ||||||
|  |     This procedure only checks whether full buffer mode is active. | ||||||
|  |     There is no error checking for the arguments: It is the responsibility of the | ||||||
|  |     user to ensure, that the provided arguments are correct. | ||||||
|  | 
 | ||||||
|  |   Limitations: | ||||||
|  |     - Only available in full buffer mode (will not do anything in page mode) | ||||||
|  |     - Tile positions and sizes (pixel position divided by 8) | ||||||
|  |     - Any display rotation/mirror is ignored | ||||||
|  |     - Only works with displays, which support U8x8 API | ||||||
|  |     - Will not send the e-paper refresh message (will probably not work with e-paper devices) | ||||||
|  | */ | ||||||
|  | void u8g2_UpdateDisplayArea(u8g2_t *u8g2, uint8_t  tx, uint8_t ty, uint8_t tw, uint8_t th) | ||||||
|  | { | ||||||
|  |   uint16_t page_size; | ||||||
|  |   uint8_t *ptr; | ||||||
|  |    | ||||||
|  |   /* check, whether we are in full buffer mode */ | ||||||
|  |   if ( u8g2->tile_buf_height != u8g2_GetU8x8(u8g2)->display_info->tile_height ) | ||||||
|  |     return; /* not in full buffer mode, do nothing */ | ||||||
|  | 
 | ||||||
|  |   page_size = u8g2->pixel_buf_width;  /* 8*u8g2->u8g2_GetU8x8(u8g2)->display_info->tile_width */ | ||||||
|  |      | ||||||
|  |   ptr = u8g2_GetBufferPtr(u8g2); | ||||||
|  |   ptr += tx*8; | ||||||
|  |   ptr += page_size*ty; | ||||||
|  |    | ||||||
|  |   while( th > 0 ) | ||||||
|  |   { | ||||||
|  |     u8x8_DrawTile( u8g2_GetU8x8(u8g2), tx, ty, tw, ptr ); | ||||||
|  |     ptr += page_size; | ||||||
|  |     ty++; | ||||||
|  |     th--; | ||||||
|  |   }   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* same as sendBuffer, but does not send the ePaper refresh message */ | ||||||
|  | void u8g2_UpdateDisplay(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2_send_buffer(u8g2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | 
 | ||||||
|  | /* vertical_top memory architecture */ | ||||||
|  | void u8g2_WriteBufferPBM(u8g2_t *u8g2, void (*out)(const char *s)) | ||||||
|  | { | ||||||
|  |   u8x8_capture_write_pbm_pre(u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), out); | ||||||
|  |   u8x8_capture_write_pbm_buffer(u8g2_GetBufferPtr(u8g2), u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), u8x8_capture_get_pixel_1, out); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_WriteBufferXBM(u8g2_t *u8g2, void (*out)(const char *s)) | ||||||
|  | { | ||||||
|  |   u8x8_capture_write_xbm_pre(u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), out); | ||||||
|  |   u8x8_capture_write_xbm_buffer(u8g2_GetBufferPtr(u8g2), u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), u8x8_capture_get_pixel_1, out); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* horizontal right memory architecture */ | ||||||
|  | /* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */  | ||||||
|  | void u8g2_WriteBufferPBM2(u8g2_t *u8g2, void (*out)(const char *s)) | ||||||
|  | { | ||||||
|  |   u8x8_capture_write_pbm_pre(u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), out); | ||||||
|  |   u8x8_capture_write_pbm_buffer(u8g2_GetBufferPtr(u8g2), u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), u8x8_capture_get_pixel_2, out); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_WriteBufferXBM2(u8g2_t *u8g2, void (*out)(const char *s)) | ||||||
|  | { | ||||||
|  |   u8x8_capture_write_xbm_pre(u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), out); | ||||||
|  |   u8x8_capture_write_xbm_buffer(u8g2_GetBufferPtr(u8g2), u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), u8x8_capture_get_pixel_2, out); | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										479
									
								
								lib/u8g2/u8g2_circle.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										479
									
								
								lib/u8g2/u8g2_circle.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,479 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8g2_circle.c | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8g2.h" | ||||||
|  | 
 | ||||||
|  | /*==============================================*/ | ||||||
|  | /* Circle */ | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_circle_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE; | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_circle_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) | ||||||
|  | { | ||||||
|  |     /* upper right */ | ||||||
|  |     if ( option & U8G2_DRAW_UPPER_RIGHT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 + x, y0 - y); | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 + y, y0 - x); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* upper left */ | ||||||
|  |     if ( option & U8G2_DRAW_UPPER_LEFT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 - x, y0 - y); | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 - y, y0 - x); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* lower right */ | ||||||
|  |     if ( option & U8G2_DRAW_LOWER_RIGHT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 + x, y0 + y); | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 + y, y0 + x); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* lower left */ | ||||||
|  |     if ( option & U8G2_DRAW_LOWER_LEFT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 - x, y0 + y); | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 - y, y0 + x); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_circle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option) | ||||||
|  | { | ||||||
|  |     u8g2_int_t f; | ||||||
|  |     u8g2_int_t ddF_x; | ||||||
|  |     u8g2_int_t ddF_y; | ||||||
|  |     u8g2_uint_t x; | ||||||
|  |     u8g2_uint_t y; | ||||||
|  | 
 | ||||||
|  |     f = 1; | ||||||
|  |     f -= rad; | ||||||
|  |     ddF_x = 1; | ||||||
|  |     ddF_y = 0; | ||||||
|  |     ddF_y -= rad; | ||||||
|  |     ddF_y *= 2; | ||||||
|  |     x = 0; | ||||||
|  |     y = rad; | ||||||
|  | 
 | ||||||
|  |     u8g2_draw_circle_section(u8g2, x, y, x0, y0, option); | ||||||
|  |      | ||||||
|  |     while ( x < y ) | ||||||
|  |     { | ||||||
|  |       if (f >= 0)  | ||||||
|  |       { | ||||||
|  |         y--; | ||||||
|  |         ddF_y += 2; | ||||||
|  |         f += ddF_y; | ||||||
|  |       } | ||||||
|  |       x++; | ||||||
|  |       ddF_x += 2; | ||||||
|  |       f += ddF_x; | ||||||
|  | 
 | ||||||
|  |       u8g2_draw_circle_section(u8g2, x, y, x0, y0, option);     | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawCircle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option) | ||||||
|  | { | ||||||
|  |   /* check for bounding box */ | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   { | ||||||
|  |     if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )  | ||||||
|  |       return; | ||||||
|  |   } | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   /* draw circle */ | ||||||
|  |   u8g2_draw_circle(u8g2, x0, y0, rad, option); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*==============================================*/ | ||||||
|  | /* Disk */ | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_disc_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE; | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_disc_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) | ||||||
|  | { | ||||||
|  |     /* upper right */ | ||||||
|  |     if ( option & U8G2_DRAW_UPPER_RIGHT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawVLine(u8g2, x0+x, y0-y, y+1); | ||||||
|  |       u8g2_DrawVLine(u8g2, x0+y, y0-x, x+1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* upper left */ | ||||||
|  |     if ( option & U8G2_DRAW_UPPER_LEFT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawVLine(u8g2, x0-x, y0-y, y+1); | ||||||
|  |       u8g2_DrawVLine(u8g2, x0-y, y0-x, x+1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* lower right */ | ||||||
|  |     if ( option & U8G2_DRAW_LOWER_RIGHT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawVLine(u8g2, x0+x, y0, y+1); | ||||||
|  |       u8g2_DrawVLine(u8g2, x0+y, y0, x+1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* lower left */ | ||||||
|  |     if ( option & U8G2_DRAW_LOWER_LEFT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawVLine(u8g2, x0-x, y0, y+1); | ||||||
|  |       u8g2_DrawVLine(u8g2, x0-y, y0, x+1); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_disc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option) | ||||||
|  | { | ||||||
|  |   u8g2_int_t f; | ||||||
|  |   u8g2_int_t ddF_x; | ||||||
|  |   u8g2_int_t ddF_y; | ||||||
|  |   u8g2_uint_t x; | ||||||
|  |   u8g2_uint_t y; | ||||||
|  | 
 | ||||||
|  |   f = 1; | ||||||
|  |   f -= rad; | ||||||
|  |   ddF_x = 1; | ||||||
|  |   ddF_y = 0; | ||||||
|  |   ddF_y -= rad; | ||||||
|  |   ddF_y *= 2; | ||||||
|  |   x = 0; | ||||||
|  |   y = rad; | ||||||
|  | 
 | ||||||
|  |   u8g2_draw_disc_section(u8g2, x, y, x0, y0, option); | ||||||
|  |    | ||||||
|  |   while ( x < y ) | ||||||
|  |   { | ||||||
|  |     if (f >= 0)  | ||||||
|  |     { | ||||||
|  |       y--; | ||||||
|  |       ddF_y += 2; | ||||||
|  |       f += ddF_y; | ||||||
|  |     } | ||||||
|  |     x++; | ||||||
|  |     ddF_x += 2; | ||||||
|  |     f += ddF_x; | ||||||
|  | 
 | ||||||
|  |     u8g2_draw_disc_section(u8g2, x, y, x0, y0, option);     | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawDisc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option) | ||||||
|  | { | ||||||
|  |   /* check for bounding box */ | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   { | ||||||
|  |     if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )  | ||||||
|  |       return; | ||||||
|  |   } | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   /* draw disc */ | ||||||
|  |   u8g2_draw_disc(u8g2, x0, y0, rad, option); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*==============================================*/ | ||||||
|  | /* Ellipse */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Source:  | ||||||
|  |     Foley, Computer Graphics, p 90 | ||||||
|  | */ | ||||||
|  | static void u8g2_draw_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE; | ||||||
|  | static void u8g2_draw_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) | ||||||
|  | { | ||||||
|  |     /* upper right */ | ||||||
|  |     if ( option & U8G2_DRAW_UPPER_RIGHT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 + x, y0 - y); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* upper left */ | ||||||
|  |     if ( option & U8G2_DRAW_UPPER_LEFT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 - x, y0 - y); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* lower right */ | ||||||
|  |     if ( option & U8G2_DRAW_LOWER_RIGHT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 + x, y0 + y); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* lower left */ | ||||||
|  |     if ( option & U8G2_DRAW_LOWER_LEFT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawPixel(u8g2, x0 - x, y0 + y); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_ellipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t x, y; | ||||||
|  |   u8g2_long_t xchg, ychg; | ||||||
|  |   u8g2_long_t err; | ||||||
|  |   u8g2_long_t rxrx2; | ||||||
|  |   u8g2_long_t ryry2; | ||||||
|  |   u8g2_long_t stopx, stopy; | ||||||
|  |    | ||||||
|  |   rxrx2 = rx; | ||||||
|  |   rxrx2 *= rx; | ||||||
|  |   rxrx2 *= 2; | ||||||
|  |    | ||||||
|  |   ryry2 = ry; | ||||||
|  |   ryry2 *= ry; | ||||||
|  |   ryry2 *= 2; | ||||||
|  |    | ||||||
|  |   x = rx; | ||||||
|  |   y = 0; | ||||||
|  |    | ||||||
|  |   xchg = 1; | ||||||
|  |   xchg -= rx; | ||||||
|  |   xchg -= rx; | ||||||
|  |   xchg *= ry; | ||||||
|  |   xchg *= ry; | ||||||
|  |    | ||||||
|  |   ychg = rx; | ||||||
|  |   ychg *= rx; | ||||||
|  |    | ||||||
|  |   err = 0; | ||||||
|  |    | ||||||
|  |   stopx = ryry2; | ||||||
|  |   stopx *= rx; | ||||||
|  |   stopy = 0; | ||||||
|  |    | ||||||
|  |   while( stopx >= stopy ) | ||||||
|  |   { | ||||||
|  |     u8g2_draw_ellipse_section(u8g2, x, y, x0, y0, option); | ||||||
|  |     y++; | ||||||
|  |     stopy += rxrx2; | ||||||
|  |     err += ychg; | ||||||
|  |     ychg += rxrx2; | ||||||
|  |     if ( 2*err+xchg > 0 ) | ||||||
|  |     { | ||||||
|  |       x--; | ||||||
|  |       stopx -= ryry2; | ||||||
|  |       err += xchg; | ||||||
|  |       xchg += ryry2;       | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   x = 0; | ||||||
|  |   y = ry; | ||||||
|  |    | ||||||
|  |   xchg = ry; | ||||||
|  |   xchg *= ry; | ||||||
|  |    | ||||||
|  |   ychg = 1; | ||||||
|  |   ychg -= ry; | ||||||
|  |   ychg -= ry; | ||||||
|  |   ychg *= rx; | ||||||
|  |   ychg *= rx; | ||||||
|  |    | ||||||
|  |   err = 0; | ||||||
|  |    | ||||||
|  |   stopx = 0; | ||||||
|  | 
 | ||||||
|  |   stopy = rxrx2; | ||||||
|  |   stopy *= ry; | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   while( stopx <= stopy ) | ||||||
|  |   { | ||||||
|  |     u8g2_draw_ellipse_section(u8g2, x, y, x0, y0, option); | ||||||
|  |     x++; | ||||||
|  |     stopx += ryry2; | ||||||
|  |     err += xchg; | ||||||
|  |     xchg += ryry2; | ||||||
|  |     if ( 2*err+ychg > 0 ) | ||||||
|  |     { | ||||||
|  |       y--; | ||||||
|  |       stopy -= rxrx2; | ||||||
|  |       err += ychg; | ||||||
|  |       ychg += rxrx2; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option) | ||||||
|  | { | ||||||
|  |   /* check for bounding box */ | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   { | ||||||
|  |     if ( u8g2_IsIntersection(u8g2, x0-rx, y0-ry, x0+rx+1, y0+ry+1) == 0 )  | ||||||
|  |       return; | ||||||
|  |   } | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   u8g2_draw_ellipse(u8g2, x0, y0, rx, ry, option); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*==============================================*/ | ||||||
|  | /* Filled Ellipse */ | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_filled_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE; | ||||||
|  | static void u8g2_draw_filled_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) | ||||||
|  | { | ||||||
|  |     /* upper right */ | ||||||
|  |     if ( option & U8G2_DRAW_UPPER_RIGHT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawVLine(u8g2, x0+x, y0-y, y+1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* upper left */ | ||||||
|  |     if ( option & U8G2_DRAW_UPPER_LEFT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawVLine(u8g2, x0-x, y0-y, y+1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* lower right */ | ||||||
|  |     if ( option & U8G2_DRAW_LOWER_RIGHT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawVLine(u8g2, x0+x, y0, y+1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* lower left */ | ||||||
|  |     if ( option & U8G2_DRAW_LOWER_LEFT ) | ||||||
|  |     { | ||||||
|  |       u8g2_DrawVLine(u8g2, x0-x, y0, y+1); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void u8g2_draw_filled_ellipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t x, y; | ||||||
|  |   u8g2_long_t xchg, ychg; | ||||||
|  |   u8g2_long_t err; | ||||||
|  |   u8g2_long_t rxrx2; | ||||||
|  |   u8g2_long_t ryry2; | ||||||
|  |   u8g2_long_t stopx, stopy; | ||||||
|  |    | ||||||
|  |   rxrx2 = rx; | ||||||
|  |   rxrx2 *= rx; | ||||||
|  |   rxrx2 *= 2; | ||||||
|  |    | ||||||
|  |   ryry2 = ry; | ||||||
|  |   ryry2 *= ry; | ||||||
|  |   ryry2 *= 2; | ||||||
|  |    | ||||||
|  |   x = rx; | ||||||
|  |   y = 0; | ||||||
|  |    | ||||||
|  |   xchg = 1; | ||||||
|  |   xchg -= rx; | ||||||
|  |   xchg -= rx; | ||||||
|  |   xchg *= ry; | ||||||
|  |   xchg *= ry; | ||||||
|  |    | ||||||
|  |   ychg = rx; | ||||||
|  |   ychg *= rx; | ||||||
|  |    | ||||||
|  |   err = 0; | ||||||
|  |    | ||||||
|  |   stopx = ryry2; | ||||||
|  |   stopx *= rx; | ||||||
|  |   stopy = 0; | ||||||
|  |    | ||||||
|  |   while( stopx >= stopy ) | ||||||
|  |   { | ||||||
|  |     u8g2_draw_filled_ellipse_section(u8g2, x, y, x0, y0, option); | ||||||
|  |     y++; | ||||||
|  |     stopy += rxrx2; | ||||||
|  |     err += ychg; | ||||||
|  |     ychg += rxrx2; | ||||||
|  |     if ( 2*err+xchg > 0 ) | ||||||
|  |     { | ||||||
|  |       x--; | ||||||
|  |       stopx -= ryry2; | ||||||
|  |       err += xchg; | ||||||
|  |       xchg += ryry2;       | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   x = 0; | ||||||
|  |   y = ry; | ||||||
|  |    | ||||||
|  |   xchg = ry; | ||||||
|  |   xchg *= ry; | ||||||
|  |    | ||||||
|  |   ychg = 1; | ||||||
|  |   ychg -= ry; | ||||||
|  |   ychg -= ry; | ||||||
|  |   ychg *= rx; | ||||||
|  |   ychg *= rx; | ||||||
|  |    | ||||||
|  |   err = 0; | ||||||
|  |    | ||||||
|  |   stopx = 0; | ||||||
|  | 
 | ||||||
|  |   stopy = rxrx2; | ||||||
|  |   stopy *= ry; | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   while( stopx <= stopy ) | ||||||
|  |   { | ||||||
|  |     u8g2_draw_filled_ellipse_section(u8g2, x, y, x0, y0, option); | ||||||
|  |     x++; | ||||||
|  |     stopx += ryry2; | ||||||
|  |     err += xchg; | ||||||
|  |     xchg += ryry2; | ||||||
|  |     if ( 2*err+ychg > 0 ) | ||||||
|  |     { | ||||||
|  |       y--; | ||||||
|  |       stopy -= rxrx2; | ||||||
|  |       err += ychg; | ||||||
|  |       ychg += rxrx2; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawFilledEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option) | ||||||
|  | { | ||||||
|  |   /* check for bounding box */ | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   { | ||||||
|  |     if ( u8g2_IsIntersection(u8g2, x0-rx, y0-ry, x0+rx+1, y0+ry+1) == 0 )  | ||||||
|  |       return; | ||||||
|  |   } | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |    | ||||||
|  |   u8g2_draw_filled_ellipse(u8g2, x0, y0, rx, ry, option); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										1458
									
								
								lib/u8g2/u8g2_d_memory.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1458
									
								
								lib/u8g2/u8g2_d_memory.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5366
									
								
								lib/u8g2/u8g2_d_setup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5366
									
								
								lib/u8g2/u8g2_d_setup.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1291
									
								
								lib/u8g2/u8g2_font.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1291
									
								
								lib/u8g2/u8g2_font.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										343578
									
								
								lib/u8g2/u8g2_fonts.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										343578
									
								
								lib/u8g2/u8g2_fonts.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										255
									
								
								lib/u8g2/u8g2_hvline.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								lib/u8g2/u8g2_hvline.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,255 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8g2_hvline.c | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   Calltree | ||||||
|  |    | ||||||
|  |     void u8g2_DrawHVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  |     u8g2->cb->draw_l90 | ||||||
|  |     u8g2_draw_hv_line_2dir | ||||||
|  |     u8g2->ll_hvline(u8g2, x, y, len, dir); | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8g2.h" | ||||||
|  | #include <assert.h> | ||||||
|  | 
 | ||||||
|  | /*==========================================================*/ | ||||||
|  | /* intersection procedure */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Description: | ||||||
|  |     clip range from pos a (included) with line len (a+len excluded) agains c (included) to d (excluded) | ||||||
|  |   Assumptions: | ||||||
|  |     len > 0 | ||||||
|  |     c <= d		(this is not checked) | ||||||
|  |   will return 0 if there is no intersection and if a > b | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | static uint8_t u8g2_clip_intersection2(u8g2_uint_t *ap, u8g2_uint_t *len, u8g2_uint_t c, u8g2_uint_t d) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t a = *ap; | ||||||
|  |   u8g2_uint_t b; | ||||||
|  |   b  = a; | ||||||
|  |   b += *len; | ||||||
|  | 
 | ||||||
|  |   /*
 | ||||||
|  |     Description: | ||||||
|  |       clip range from a (included) to b (excluded) agains c (included) to d (excluded) | ||||||
|  |     Assumptions: | ||||||
|  |       a <= b		(violation is checked and handled correctly) | ||||||
|  |       c <= d		(this is not checked) | ||||||
|  |     will return 0 if there is no intersection and if a > b | ||||||
|  | 
 | ||||||
|  |     optimized clipping: c is set to 0 --> 27 Oct 2018: again removed the c==0 assumption | ||||||
|  |      | ||||||
|  |     replaced by uint8_t u8g2_clip_intersection2 | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  |   /* handle the a>b case correctly. If code and time is critical, this could */ | ||||||
|  |   /* be removed completly (be aware about memory curruption for wrong */ | ||||||
|  |   /* arguments) or return 0 for a>b (will lead to skipped lines for wrong */ | ||||||
|  |   /* arguments) */   | ||||||
|  |    | ||||||
|  |   /* removing the following if clause completly may lead to memory corruption of a>b */ | ||||||
|  |   if ( a > b ) | ||||||
|  |   {     | ||||||
|  |     /* replacing this if with a simple "return 0;" will not handle the case with negative a */     | ||||||
|  |     if ( a < d ) | ||||||
|  |     { | ||||||
|  |       b = d; | ||||||
|  |       b--; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       a = c; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   /* from now on, the asumption a <= b is ok */ | ||||||
|  |    | ||||||
|  |   if ( a >= d ) | ||||||
|  |     return 0; | ||||||
|  |   if ( b <= c ) | ||||||
|  |     return 0; | ||||||
|  |   if ( a < c )		 | ||||||
|  |     a = c; | ||||||
|  |   if ( b > d ) | ||||||
|  |     b = d; | ||||||
|  |    | ||||||
|  |   *ap = a; | ||||||
|  |   b -= a; | ||||||
|  |   *len = b; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*==========================================================*/ | ||||||
|  | /* draw procedures */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   x,y		Upper left position of the line within the pixel buffer  | ||||||
|  |   len		length of the line in pixel, len must not be 0 | ||||||
|  |   dir		0: horizontal line (left to right) | ||||||
|  | 		1: vertical line (top to bottom) | ||||||
|  |   This function first adjusts the y position to the local buffer. Then it | ||||||
|  |   will clip the line and call u8g2_draw_low_level_hv_line() | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | void u8g2_draw_hv_line_2dir(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |   /* clipping happens before the display rotation */ | ||||||
|  | 
 | ||||||
|  |   /* transform to pixel buffer coordinates */ | ||||||
|  |   y -= u8g2->pixel_curr_row; | ||||||
|  |    | ||||||
|  |   u8g2->ll_hvline(u8g2, x, y, len, dir); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   This is the toplevel function for the hv line draw procedures. | ||||||
|  |   This function should be called by the user. | ||||||
|  |    | ||||||
|  |   "dir" may have 4 directions: 0 (left to right), 1, 2, 3 (down up) | ||||||
|  | */ | ||||||
|  | void u8g2_DrawHVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   /* Make a call to the callback function (e.g. u8g2_draw_l90_r0). */ | ||||||
|  |   /* The callback may rotate the hv line */ | ||||||
|  |   /* after rotation this will call u8g2_draw_hv_line_4dir() */ | ||||||
|  |    | ||||||
|  | #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT | ||||||
|  |   if ( u8g2->is_page_clip_window_intersection != 0 ) | ||||||
|  | #endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */ | ||||||
|  |     if ( len != 0 ) | ||||||
|  |     { | ||||||
|  |      | ||||||
|  |       /* convert to two directions */     | ||||||
|  |       if ( len > 1 ) | ||||||
|  |       { | ||||||
|  | 	if ( dir == 2 ) | ||||||
|  | 	{ | ||||||
|  | 	  x -= len; | ||||||
|  | 	  x++; | ||||||
|  | 	} | ||||||
|  | 	else if ( dir == 3 ) | ||||||
|  | 	{ | ||||||
|  | 	  y -= len; | ||||||
|  | 	  y++; | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |       dir &= 1;   | ||||||
|  |        | ||||||
|  |       /* clip against the user window */ | ||||||
|  |       if ( dir == 0 ) | ||||||
|  |       { | ||||||
|  | 	if ( y < u8g2->user_y0 ) | ||||||
|  | 	  return; | ||||||
|  | 	if ( y >= u8g2->user_y1 ) | ||||||
|  | 	  return; | ||||||
|  | 	if ( u8g2_clip_intersection2(&x, &len, u8g2->user_x0, u8g2->user_x1) == 0 ) | ||||||
|  | 	  return; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  | 	if ( x < u8g2->user_x0 ) | ||||||
|  | 	  return; | ||||||
|  | 	if ( x >= u8g2->user_x1 ) | ||||||
|  | 	  return; | ||||||
|  | 	if ( u8g2_clip_intersection2(&y, &len, u8g2->user_y0, u8g2->user_y1) == 0 ) | ||||||
|  | 	  return; | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |        | ||||||
|  |       u8g2->cb->draw_l90(u8g2, x, y, len, dir); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawHLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len) | ||||||
|  | { | ||||||
|  | // #ifdef U8G2_WITH_INTERSECTION
 | ||||||
|  | //   if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 ) 
 | ||||||
|  | //     return;
 | ||||||
|  | // #endif /* U8G2_WITH_INTERSECTION */
 | ||||||
|  |   u8g2_DrawHVLine(u8g2, x, y, len, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len) | ||||||
|  | { | ||||||
|  | // #ifdef U8G2_WITH_INTERSECTION
 | ||||||
|  | //   if ( u8g2_IsIntersection(u8g2, x, y, x+1, y+len) == 0 ) 
 | ||||||
|  | //     return;
 | ||||||
|  | // #endif /* U8G2_WITH_INTERSECTION */
 | ||||||
|  |   u8g2_DrawHVLine(u8g2, x, y, len, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_DrawPixel(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y) | ||||||
|  | { | ||||||
|  | #ifdef U8G2_WITH_INTERSECTION | ||||||
|  |   if ( y < u8g2->user_y0 ) | ||||||
|  |     return; | ||||||
|  |   if ( y >= u8g2->user_y1 ) | ||||||
|  |     return; | ||||||
|  |   if ( x < u8g2->user_x0 ) | ||||||
|  |     return; | ||||||
|  |   if ( x >= u8g2->user_x1 ) | ||||||
|  |     return; | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  |   u8g2_DrawHVLine(u8g2, x, y, 1, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Assign the draw color for all drawing functions. | ||||||
|  |   color may be 0 or 1. The actual color is defined by the display. | ||||||
|  |   With color = 1 the drawing function will set the display memory to 1. | ||||||
|  |   For OLEDs this ususally means, that the pixel is enabled and the LED  | ||||||
|  |   at the pixel is turned on. | ||||||
|  |   On an LCD it usually means that the LCD segment of the pixel is enabled,  | ||||||
|  |   which absorbs the light. | ||||||
|  |   For eInk/ePaper it means black ink. | ||||||
|  | 
 | ||||||
|  |   7 Jan 2017: Allow color value 2 for XOR operation. | ||||||
|  |    | ||||||
|  | */ | ||||||
|  | void u8g2_SetDrawColor(u8g2_t *u8g2, uint8_t color) | ||||||
|  | { | ||||||
|  |   u8g2->draw_color = color;	/* u8g2_SetDrawColor: just assign the argument */  | ||||||
|  |   if ( color >= 3 ) | ||||||
|  |     u8g2->draw_color = 1;	/* u8g2_SetDrawColor: make color as one if arg is invalid */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										176
									
								
								lib/u8g2/u8g2_intersection.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								lib/u8g2/u8g2_intersection.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,176 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8g2_intersection.c  | ||||||
|  |    | ||||||
|  |   Intersection calculation, code taken from u8g_clip.c | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8g2.h" | ||||||
|  | 
 | ||||||
|  | #ifdef __GNUC__ | ||||||
|  | #define U8G2_ALWAYS_INLINE __inline__ __attribute__((always_inline)) | ||||||
|  | #else | ||||||
|  | #define U8G2_ALWAYS_INLINE | ||||||
|  | #endif  | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #if defined(U8G2_WITH_INTERSECTION) || defined(U8G2_WITH_CLIP_WINDOW_SUPPORT) | ||||||
|  | 
 | ||||||
|  | #ifdef OLD_VERSION_WITH_SYMETRIC_BOUNDARIES | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   intersection assumptions: | ||||||
|  |     a1 <= a2 is always true     | ||||||
|  |      | ||||||
|  |     minimized version | ||||||
|  |     ---1----0 1             b1 <= a2 && b1 > b2 | ||||||
|  |     -----1--0 1             b2 >= a1 && b1 > b2 | ||||||
|  |     ---1-1--- 1             b1 <= a2 && b2 >= a1 | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   calculate the intersection between a0/a1 and v0/v1 | ||||||
|  |   The intersection check returns one if the range of a0/a1 has an intersection with v0/v1. | ||||||
|  |   The intersection check includes the boundary values v1 and a1. | ||||||
|  | 
 | ||||||
|  |   The following asserts will succeed: | ||||||
|  |     assert( u8g2_is_intersection_decision_tree(4, 6, 7, 9) == 0 ); | ||||||
|  |     assert( u8g2_is_intersection_decision_tree(4, 6, 6, 9) != 0 ); | ||||||
|  |     assert( u8g2_is_intersection_decision_tree(6, 9, 4, 6) != 0 ); | ||||||
|  |     assert( u8g2_is_intersection_decision_tree(7, 9, 4, 6) == 0 );   | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | //static uint8_t U8G2_ALWAYS_INLINE u8g2_is_intersection_decision_tree(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1) 
 | ||||||
|  | static uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1)  | ||||||
|  | { | ||||||
|  |   if ( v0 <= a1 ) | ||||||
|  |   { | ||||||
|  |     if ( v1 >= a0 ) | ||||||
|  |     { | ||||||
|  |       return 1; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       if ( v0 > v1 ) | ||||||
|  |       { | ||||||
|  | 	return 1; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  | 	return 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     if ( v1 >= a0 ) | ||||||
|  |     { | ||||||
|  |       if ( v0 > v1 ) | ||||||
|  |       { | ||||||
|  | 	return 1; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  | 	return 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif	/* OLD_VERSION_WITH_SYMETRIC_BOUNDARIES */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   version with asymetric boundaries. | ||||||
|  |   a1 and v1 are excluded | ||||||
|  |   v0 == v1 is not support end return 1 | ||||||
|  | */ | ||||||
|  | uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1) | ||||||
|  | { | ||||||
|  |   if ( v0 < a1 )		// v0 <= a1
 | ||||||
|  |   { | ||||||
|  |     if ( v1 > a0 )	// v1 >= a0
 | ||||||
|  |     { | ||||||
|  |       return 1; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       if ( v0 > v1 )	// v0 > v1
 | ||||||
|  |       { | ||||||
|  | 	return 1; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  | 	return 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     if ( v1 > a0 )	// v1 >= a0
 | ||||||
|  |     { | ||||||
|  |       if ( v0 > v1 )	// v0 > v1
 | ||||||
|  |       { | ||||||
|  | 	return 1; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  | 	return 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* upper limits are not included (asymetric boundaries) */ | ||||||
|  | uint8_t u8g2_IsIntersection(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1) | ||||||
|  | { | ||||||
|  |   if ( u8g2_is_intersection_decision_tree(u8g2->user_y0, u8g2->user_y1, y0, y1) == 0 ) | ||||||
|  |     return 0;  | ||||||
|  |    | ||||||
|  |   return u8g2_is_intersection_decision_tree(u8g2->user_x0, u8g2->user_x1, x0, x1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* U8G2_WITH_INTERSECTION */ | ||||||
|  | 
 | ||||||
							
								
								
									
										371
									
								
								lib/u8g2/u8g2_ll_hvline.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								lib/u8g2/u8g2_ll_hvline.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,371 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8g2_ll_hvline.c | ||||||
|  |    | ||||||
|  |   low level hvline | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   *ptr |= or_mask | ||||||
|  |   *ptr ^= xor_mask | ||||||
|  |    | ||||||
|  |   color = 0:   or_mask = 1, xor_mask = 1 | ||||||
|  |   color = 1:   or_mask = 1, xor_mask = 0 | ||||||
|  |   color = 2:   or_mask = 0, xor_mask = 1 | ||||||
|  | 
 | ||||||
|  |   if ( color <= 1 ) | ||||||
|  |     or_mask  = mask; | ||||||
|  |   if ( color != 1 ) | ||||||
|  |     xor_mask = mask; | ||||||
|  |      | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8g2.h" | ||||||
|  | #include <assert.h> | ||||||
|  | 
 | ||||||
|  | /*=================================================*/ | ||||||
|  | /*
 | ||||||
|  |   u8g2_ll_hvline_vertical_top_lsb | ||||||
|  |     SSD13xx | ||||||
|  |     UC1701     | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_HVLINE_SPEED_OPTIMIZATION | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   x,y		Upper left position of the line within the local buffer (not the display!) | ||||||
|  |   len		length of the line in pixel, len must not be 0 | ||||||
|  |   dir		0: horizontal line (left to right) | ||||||
|  | 		1: vertical line (top to bottom) | ||||||
|  |   asumption:  | ||||||
|  |     all clipping done | ||||||
|  | */ | ||||||
|  | void u8g2_ll_hvline_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   uint16_t offset; | ||||||
|  |   uint8_t *ptr; | ||||||
|  |   uint8_t bit_pos, mask; | ||||||
|  |   uint8_t or_mask, xor_mask; | ||||||
|  | #ifdef __unix | ||||||
|  |   uint8_t *max_ptr = u8g2->tile_buf_ptr + u8g2_GetU8x8(u8g2)->display_info->tile_width*u8g2->tile_buf_height*8; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |   //assert(x >= u8g2->buf_x0);
 | ||||||
|  |   //assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
 | ||||||
|  |   //assert(y >= u8g2->buf_y0);
 | ||||||
|  |   //assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
 | ||||||
|  |    | ||||||
|  |   /* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */ | ||||||
|  |   bit_pos = y;		/* overflow truncate is ok here... */ | ||||||
|  |   bit_pos &= 7; 	/* ... because only the lowest 3 bits are needed */ | ||||||
|  |   mask = 1; | ||||||
|  |   mask <<= bit_pos; | ||||||
|  | 
 | ||||||
|  |   or_mask = 0; | ||||||
|  |   xor_mask = 0; | ||||||
|  |   if ( u8g2->draw_color <= 1 ) | ||||||
|  |     or_mask  = mask; | ||||||
|  |   if ( u8g2->draw_color != 1 ) | ||||||
|  |     xor_mask = mask; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   offset = y;		/* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */ | ||||||
|  |   offset &= ~7; | ||||||
|  |   offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width; | ||||||
|  |   ptr = u8g2->tile_buf_ptr; | ||||||
|  |   ptr += offset; | ||||||
|  |   ptr += x; | ||||||
|  |    | ||||||
|  |   if ( dir == 0 ) | ||||||
|  |   { | ||||||
|  |       do | ||||||
|  |       { | ||||||
|  | #ifdef __unix | ||||||
|  | 	assert(ptr < max_ptr); | ||||||
|  | #endif | ||||||
|  | 	*ptr |= or_mask; | ||||||
|  | 	*ptr ^= xor_mask; | ||||||
|  | 	ptr++; | ||||||
|  | 	len--; | ||||||
|  |       } while( len != 0 ); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   {     | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  | #ifdef __unix | ||||||
|  |       assert(ptr < max_ptr); | ||||||
|  | #endif | ||||||
|  |       *ptr |= or_mask; | ||||||
|  |       *ptr ^= xor_mask; | ||||||
|  |        | ||||||
|  |       bit_pos++; | ||||||
|  |       bit_pos &= 7; | ||||||
|  | 
 | ||||||
|  |       len--; | ||||||
|  | 
 | ||||||
|  |       if ( bit_pos == 0 ) | ||||||
|  |       { | ||||||
|  | 	ptr+=u8g2->pixel_buf_width;	/* 6 Jan 17: Changed u8g2->width to u8g2->pixel_buf_width, issue #148 */ | ||||||
|  | 		 | ||||||
|  | 	if ( u8g2->draw_color <= 1 ) | ||||||
|  | 	  or_mask  = 1; | ||||||
|  | 	if ( u8g2->draw_color != 1 ) | ||||||
|  | 	  xor_mask = 1; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  | 	or_mask <<= 1; | ||||||
|  | 	xor_mask <<= 1; | ||||||
|  |       } | ||||||
|  |     } while( len != 0 ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #else /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   x,y position within the buffer | ||||||
|  | */ | ||||||
|  | static void u8g2_draw_pixel_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y) | ||||||
|  | { | ||||||
|  |   uint16_t offset; | ||||||
|  |   uint8_t *ptr; | ||||||
|  |   uint8_t bit_pos, mask; | ||||||
|  |    | ||||||
|  |   //assert(x >= u8g2->buf_x0);
 | ||||||
|  |   //assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
 | ||||||
|  |   //assert(y >= u8g2->buf_y0);
 | ||||||
|  |   //assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
 | ||||||
|  |    | ||||||
|  |   /* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */ | ||||||
|  |   bit_pos = y;		/* overflow truncate is ok here... */ | ||||||
|  |   bit_pos &= 7; 	/* ... because only the lowest 3 bits are needed */ | ||||||
|  |   mask = 1; | ||||||
|  |   mask <<= bit_pos; | ||||||
|  | 
 | ||||||
|  |   offset = y;		/* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */ | ||||||
|  |   offset &= ~7; | ||||||
|  |   offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width; | ||||||
|  |   ptr = u8g2->tile_buf_ptr; | ||||||
|  |   ptr += offset; | ||||||
|  |   ptr += x; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   if ( u8g2->draw_color <= 1 ) | ||||||
|  |     *ptr |= mask; | ||||||
|  |   if ( u8g2->draw_color != 1 ) | ||||||
|  |     *ptr ^= mask; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   x,y		Upper left position of the line within the local buffer (not the display!) | ||||||
|  |   len		length of the line in pixel, len must not be 0 | ||||||
|  |   dir		0: horizontal line (left to right) | ||||||
|  | 		1: vertical line (top to bottom) | ||||||
|  |   asumption:  | ||||||
|  |     all clipping done | ||||||
|  | */ | ||||||
|  | void u8g2_ll_hvline_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   if ( dir == 0 ) | ||||||
|  |   { | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |       u8g2_draw_pixel_vertical_top_lsb(u8g2, x, y); | ||||||
|  |       x++; | ||||||
|  |       len--; | ||||||
|  |     } while( len != 0 ); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |       u8g2_draw_pixel_vertical_top_lsb(u8g2, x, y); | ||||||
|  |       y++; | ||||||
|  |       len--; | ||||||
|  |     } while( len != 0 ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */ | ||||||
|  | 
 | ||||||
|  | /*=================================================*/ | ||||||
|  | /*
 | ||||||
|  |   u8g2_ll_hvline_horizontal_right_lsb | ||||||
|  |     ST7920 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_HVLINE_SPEED_OPTIMIZATION | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   x,y		Upper left position of the line within the local buffer (not the display!) | ||||||
|  |   len		length of the line in pixel, len must not be 0 | ||||||
|  |   dir		0: horizontal line (left to right) | ||||||
|  | 		1: vertical line (top to bottom) | ||||||
|  |   asumption:  | ||||||
|  |     all clipping done | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */  | ||||||
|  | void u8g2_ll_hvline_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   uint16_t offset; | ||||||
|  |   uint8_t *ptr; | ||||||
|  |   uint8_t bit_pos; | ||||||
|  |   uint8_t mask; | ||||||
|  |   uint8_t tile_width = u8g2_GetU8x8(u8g2)->display_info->tile_width; | ||||||
|  | 
 | ||||||
|  |   bit_pos = x;		/* overflow truncate is ok here... */ | ||||||
|  |   bit_pos &= 7; 	/* ... because only the lowest 3 bits are needed */ | ||||||
|  |   mask = 128; | ||||||
|  |   mask >>= bit_pos; | ||||||
|  | 
 | ||||||
|  |   offset = y;		/* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */ | ||||||
|  |   offset *= tile_width; | ||||||
|  |   offset += x>>3; | ||||||
|  |   ptr = u8g2->tile_buf_ptr; | ||||||
|  |   ptr += offset; | ||||||
|  |    | ||||||
|  |   if ( dir == 0 ) | ||||||
|  |   { | ||||||
|  |        | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |       if ( u8g2->draw_color <= 1 ) | ||||||
|  | 	*ptr |= mask; | ||||||
|  |       if ( u8g2->draw_color != 1 ) | ||||||
|  | 	*ptr ^= mask; | ||||||
|  |        | ||||||
|  |       mask >>= 1; | ||||||
|  |       if ( mask == 0 ) | ||||||
|  |       { | ||||||
|  | 	mask = 128; | ||||||
|  |         ptr++; | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       //x++;
 | ||||||
|  |       len--; | ||||||
|  |     } while( len != 0 ); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |       if ( u8g2->draw_color <= 1 ) | ||||||
|  | 	*ptr |= mask; | ||||||
|  |       if ( u8g2->draw_color != 1 ) | ||||||
|  | 	*ptr ^= mask; | ||||||
|  |        | ||||||
|  |       ptr += tile_width; | ||||||
|  |       //y++;
 | ||||||
|  |       len--; | ||||||
|  |     } while( len != 0 ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #else /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   x,y position within the buffer | ||||||
|  | */ | ||||||
|  | /* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */  | ||||||
|  | static void u8g2_draw_pixel_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y) | ||||||
|  | { | ||||||
|  |   uint16_t offset; | ||||||
|  |   uint8_t *ptr; | ||||||
|  |   uint8_t bit_pos, mask; | ||||||
|  | 
 | ||||||
|  |   //assert(x >= u8g2->buf_x0);
 | ||||||
|  |   //assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
 | ||||||
|  |   //assert(y >= u8g2->buf_y0);
 | ||||||
|  |   //assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
 | ||||||
|  |    | ||||||
|  |   /* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */ | ||||||
|  |   bit_pos = x;		/* overflow truncate is ok here... */ | ||||||
|  |   bit_pos &= 7; 	/* ... because only the lowest 3 bits are needed */ | ||||||
|  |   mask = 128; | ||||||
|  |   mask >>= bit_pos; | ||||||
|  |   x >>= 3; | ||||||
|  | 
 | ||||||
|  |   offset = y;		/* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */ | ||||||
|  |   offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width; | ||||||
|  |   offset += x; | ||||||
|  |   ptr = u8g2->tile_buf_ptr; | ||||||
|  |   ptr += offset; | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   if ( u8g2->draw_color <= 1 ) | ||||||
|  |     *ptr |= mask; | ||||||
|  |   if ( u8g2->draw_color != 1 ) | ||||||
|  |     *ptr ^= mask; | ||||||
|  |    | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   x,y		Upper left position of the line within the local buffer (not the display!) | ||||||
|  |   len		length of the line in pixel, len must not be 0 | ||||||
|  |   dir		0: horizontal line (left to right) | ||||||
|  | 		1: vertical line (top to bottom) | ||||||
|  |   asumption:  | ||||||
|  |     all clipping done | ||||||
|  | */ | ||||||
|  | /* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */  | ||||||
|  | void u8g2_ll_hvline_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   if ( dir == 0 ) | ||||||
|  |   { | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |       u8g2_draw_pixel_horizontal_right_lsb(u8g2, x, y); | ||||||
|  |       x++; | ||||||
|  |       len--; | ||||||
|  |     } while( len != 0 ); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |       u8g2_draw_pixel_horizontal_right_lsb(u8g2, x, y); | ||||||
|  |       y++; | ||||||
|  |       len--; | ||||||
|  |     } while( len != 0 ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */ | ||||||
							
								
								
									
										451
									
								
								lib/u8g2/u8g2_setup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										451
									
								
								lib/u8g2/u8g2_setup.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,451 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8g2_setup.c | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8g2.h" | ||||||
|  | #include <string.h> | ||||||
|  | #include <assert.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT | ||||||
|  | 
 | ||||||
|  | void u8g2_SetMaxClipWindow(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2->clip_x0 = 0; | ||||||
|  |   u8g2->clip_y0 = 0; | ||||||
|  |   u8g2->clip_x1 = (u8g2_uint_t)~(u8g2_uint_t)0; | ||||||
|  |   u8g2->clip_y1 = (u8g2_uint_t)~(u8g2_uint_t)0; | ||||||
|  |    | ||||||
|  |   u8g2->cb->update_page_win(u8g2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_SetClipWindow(u8g2_t *u8g2, u8g2_uint_t clip_x0, u8g2_uint_t clip_y0, u8g2_uint_t clip_x1, u8g2_uint_t clip_y1 ) | ||||||
|  | { | ||||||
|  |   u8g2->clip_x0 = clip_x0; | ||||||
|  |   u8g2->clip_y0 = clip_y0; | ||||||
|  |   u8g2->clip_x1 = clip_x1; | ||||||
|  |   u8g2->clip_y1 = clip_y1; | ||||||
|  |   u8g2->cb->update_page_win(u8g2); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | /*
 | ||||||
|  |   This procedure is called after setting up the display (u8x8 structure). | ||||||
|  |   --> This is the central init procedure for u8g2 object | ||||||
|  | */ | ||||||
|  | void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, u8g2_draw_ll_hvline_cb ll_hvline_cb, const u8g2_cb_t *u8g2_cb) | ||||||
|  | { | ||||||
|  |   u8g2->font = NULL; | ||||||
|  |   //u8g2->kerning = NULL;
 | ||||||
|  |   //u8g2->get_kerning_cb = u8g2_GetNullKerning;
 | ||||||
|  |    | ||||||
|  |   //u8g2->ll_hvline = u8g2_ll_hvline_vertical_top_lsb;
 | ||||||
|  |   u8g2->ll_hvline = ll_hvline_cb; | ||||||
|  |    | ||||||
|  |   u8g2->tile_buf_ptr = buf; | ||||||
|  |   u8g2->tile_buf_height = tile_buf_height; | ||||||
|  |    | ||||||
|  |   u8g2->tile_curr_row = 0; | ||||||
|  |    | ||||||
|  |   u8g2->font_decode.is_transparent = 0; /* issue 443 */ | ||||||
|  |   u8g2->bitmap_transparency = 0; | ||||||
|  |    | ||||||
|  |   u8g2->draw_color = 1; | ||||||
|  |   u8g2->is_auto_page_clear = 1; | ||||||
|  |    | ||||||
|  |   u8g2->cb = u8g2_cb; | ||||||
|  |   u8g2->cb->update_dimension(u8g2); | ||||||
|  | #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT | ||||||
|  |   u8g2_SetMaxClipWindow(u8g2);		/* assign a clip window and call the update() procedure */ | ||||||
|  | #else | ||||||
|  |   u8g2->cb->update_page_win(u8g2); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |   u8g2_SetFontPosBaseline(u8g2);  /* issue 195 */ | ||||||
|  |    | ||||||
|  | #ifdef U8G2_WITH_FONT_ROTATION   | ||||||
|  |   u8g2->font_decode.dir = 0; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Usually the display rotation is set initially, but it could be done later also | ||||||
|  |   u8g2_cb can be U8G2_R0..U8G2_R3 | ||||||
|  | */ | ||||||
|  | void u8g2_SetDisplayRotation(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb) | ||||||
|  | { | ||||||
|  |   u8g2->cb = u8g2_cb; | ||||||
|  |   u8g2->cb->update_dimension(u8g2); | ||||||
|  |   u8g2->cb->update_page_win(u8g2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | 
 | ||||||
|  | void u8g2_SendF(u8g2_t * u8g2, const char *fmt, ...) | ||||||
|  | { | ||||||
|  |   va_list va; | ||||||
|  |   va_start(va, fmt); | ||||||
|  |   u8x8_cad_vsendf(u8g2_GetU8x8(u8g2), fmt, va); | ||||||
|  |   va_end(va); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | /* 
 | ||||||
|  |   update dimension:  | ||||||
|  |   calculate the following variables: | ||||||
|  |     u8g2_uint_t buf_x0;	left corner of the buffer | ||||||
|  |     u8g2_uint_t buf_x1;	right corner of the buffer (excluded) | ||||||
|  |     u8g2_uint_t buf_y0; | ||||||
|  |     u8g2_uint_t buf_y1; 	 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | static void u8g2_update_dimension_common(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   const u8x8_display_info_t *display_info = u8g2_GetU8x8(u8g2)->display_info; | ||||||
|  |   u8g2_uint_t t; | ||||||
|  |    | ||||||
|  |   t = u8g2->tile_buf_height; | ||||||
|  |   t *= 8; | ||||||
|  |   u8g2->pixel_buf_height = t; | ||||||
|  |    | ||||||
|  |   t = display_info->tile_width; | ||||||
|  | #ifndef U8G2_16BIT | ||||||
|  |   if ( t >= 32 ) | ||||||
|  |     t = 31; | ||||||
|  | #endif | ||||||
|  |   t *= 8; | ||||||
|  |   u8g2->pixel_buf_width = t; | ||||||
|  |    | ||||||
|  |   t = u8g2->tile_curr_row; | ||||||
|  |   t *= 8; | ||||||
|  |   u8g2->pixel_curr_row = t; | ||||||
|  |    | ||||||
|  |   t = u8g2->tile_buf_height; | ||||||
|  |   /* handle the case, where the buffer is larger than the (remaining) part of the display */ | ||||||
|  |   if ( t + u8g2->tile_curr_row > display_info->tile_height ) | ||||||
|  |     t = display_info->tile_height - u8g2->tile_curr_row; | ||||||
|  |   t *= 8; | ||||||
|  |    | ||||||
|  |   u8g2->buf_y0 = u8g2->pixel_curr_row;    | ||||||
|  |   u8g2->buf_y1 = u8g2->buf_y0; | ||||||
|  |   u8g2->buf_y1 += t; | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | #ifdef U8G2_16BIT | ||||||
|  |   u8g2->width = display_info->pixel_width; | ||||||
|  |   u8g2->height = display_info->pixel_height; | ||||||
|  | #else | ||||||
|  |   u8g2->width = 240; | ||||||
|  |   if ( display_info->pixel_width <= 240 ) | ||||||
|  |     u8g2->width = display_info->pixel_width; | ||||||
|  |   u8g2->height = display_info->pixel_height; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*==========================================================*/ | ||||||
|  | /* apply clip window */ | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT | ||||||
|  | static void u8g2_apply_clip_window(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   /* check aganst the current user_??? window */ | ||||||
|  |   if ( u8g2_IsIntersection(u8g2, u8g2->clip_x0, u8g2->clip_y0, u8g2->clip_x1, u8g2->clip_y1) == 0 )  | ||||||
|  |   { | ||||||
|  |     u8g2->is_page_clip_window_intersection = 0; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     u8g2->is_page_clip_window_intersection = 1; | ||||||
|  | 
 | ||||||
|  |     if ( u8g2->user_x0 < u8g2->clip_x0 ) | ||||||
|  |       u8g2->user_x0 = u8g2->clip_x0; | ||||||
|  |     if ( u8g2->user_x1 > u8g2->clip_x1 ) | ||||||
|  |       u8g2->user_x1 = u8g2->clip_x1; | ||||||
|  |     if ( u8g2->user_y0 < u8g2->clip_y0 ) | ||||||
|  |       u8g2->user_y0 = u8g2->clip_y0; | ||||||
|  |     if ( u8g2->user_y1 > u8g2->clip_y1 ) | ||||||
|  |       u8g2->user_y1 = u8g2->clip_y1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | #endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */ | ||||||
|  | 
 | ||||||
|  | /*==========================================================*/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_update_dimension_r0(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2_update_dimension_common(u8g2);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_update_page_win_r0(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2->user_x0 = 0; | ||||||
|  |   u8g2->user_x1 = u8g2->width;			/* pixel_buf_width replaced with width */ | ||||||
|  |    | ||||||
|  |   u8g2->user_y0 = u8g2->buf_y0; | ||||||
|  |   u8g2->user_y1 = u8g2->buf_y1; | ||||||
|  |    | ||||||
|  | #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT | ||||||
|  |   u8g2_apply_clip_window(u8g2); | ||||||
|  | #endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_update_dimension_r1(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2_update_dimension_common(u8g2); | ||||||
|  |    | ||||||
|  |   u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_width; | ||||||
|  |   u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_height; | ||||||
|  |    | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_update_page_win_r1(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2->user_x0 = u8g2->buf_y0; | ||||||
|  |   u8g2->user_x1 = u8g2->buf_y1; | ||||||
|  |    | ||||||
|  |   u8g2->user_y0 = 0; | ||||||
|  |   u8g2->user_y1 = u8g2->height;	/* pixel_buf_width replaced with height (which is the real pixel width) */ | ||||||
|  |    | ||||||
|  | #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT | ||||||
|  |   u8g2_apply_clip_window(u8g2); | ||||||
|  | #endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_update_dimension_r2(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2_update_dimension_common(u8g2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_update_page_win_r2(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2->user_x0 = 0; | ||||||
|  |   u8g2->user_x1 = u8g2->width;	/* pixel_buf_width replaced with width */ | ||||||
|  |    | ||||||
|  |   /* there are ases where the height is not a multiple of 8. */ | ||||||
|  |   /* in such a case u8g2->buf_y1 might be heigher than u8g2->height */ | ||||||
|  |   u8g2->user_y0 = 0; | ||||||
|  |   if ( u8g2->height >= u8g2->buf_y1 ) | ||||||
|  |     u8g2->user_y0 = u8g2->height - u8g2->buf_y1; | ||||||
|  |   u8g2->user_y1 = u8g2->height - u8g2->buf_y0; | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT | ||||||
|  |   u8g2_apply_clip_window(u8g2); | ||||||
|  | #endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_update_dimension_r3(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   u8g2_update_dimension_common(u8g2); | ||||||
|  |    | ||||||
|  |   u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_width; | ||||||
|  |   u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_height; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_update_page_win_r3(u8g2_t *u8g2) | ||||||
|  | { | ||||||
|  |   /* there are ases where the height is not a multiple of 8. */ | ||||||
|  |   /* in such a case u8g2->buf_y1 might be heigher than u8g2->width */ | ||||||
|  |   u8g2->user_x0 = 0; | ||||||
|  |   if ( u8g2->width >= u8g2->buf_y1 ) | ||||||
|  |     u8g2->user_x0 = u8g2->width - u8g2->buf_y1; | ||||||
|  |   u8g2->user_x1 = u8g2->width - u8g2->buf_y0; | ||||||
|  |    | ||||||
|  |   u8g2->user_y0 = 0; | ||||||
|  |   u8g2->user_y1 = u8g2->height;	/* pixel_buf_width replaced with height (pixel_width) */ | ||||||
|  | 
 | ||||||
|  | #ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT | ||||||
|  |   u8g2_apply_clip_window(u8g2); | ||||||
|  | #endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | extern void u8g2_draw_hv_line_2dir(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8g2_draw_l90_r0(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  | #ifdef __unix | ||||||
|  |   assert( dir <= 1 ); | ||||||
|  | #endif | ||||||
|  |   u8g2_draw_hv_line_2dir(u8g2, x, y, len, dir); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_draw_l90_mirrorr_r0(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t xx; | ||||||
|  |   xx = u8g2->width; | ||||||
|  |   xx -= x; | ||||||
|  |   if ( (dir & 1) == 0 ) | ||||||
|  |   { | ||||||
|  |     xx -= len; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     xx--; | ||||||
|  |   } | ||||||
|  |   u8g2_draw_hv_line_2dir(u8g2, xx, y, len, dir); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* dir = 0 or 1 */ | ||||||
|  | void u8g2_draw_l90_r1(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t xx, yy; | ||||||
|  | 
 | ||||||
|  | #ifdef __unix | ||||||
|  |   assert( dir <= 1 ); | ||||||
|  | #endif | ||||||
|  |    | ||||||
|  |   yy = x; | ||||||
|  |    | ||||||
|  |   xx = u8g2->height; | ||||||
|  |   xx -= y; | ||||||
|  |   xx--; | ||||||
|  |    | ||||||
|  |   dir ++; | ||||||
|  |   if ( dir == 2 ) | ||||||
|  |   { | ||||||
|  |     xx -= len; | ||||||
|  |     xx++; | ||||||
|  |     dir = 0; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_draw_l90_r2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t xx, yy; | ||||||
|  | 
 | ||||||
|  |   /*
 | ||||||
|  |   yy = u8g2->height; | ||||||
|  |   yy -= y; | ||||||
|  |   yy--; | ||||||
|  |    | ||||||
|  |   xx = u8g2->width; | ||||||
|  |   xx -= x; | ||||||
|  |   xx--; | ||||||
|  |    | ||||||
|  |   if ( dir == 0 ) | ||||||
|  |   { | ||||||
|  |     xx -= len; | ||||||
|  |     xx++; | ||||||
|  |   } | ||||||
|  |   else if ( dir == 1 ) | ||||||
|  |   { | ||||||
|  |     yy -= len; | ||||||
|  |     yy++; | ||||||
|  |   } | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  |   yy = u8g2->height; | ||||||
|  |   yy -= y; | ||||||
|  |    | ||||||
|  |   xx = u8g2->width; | ||||||
|  |   xx -= x; | ||||||
|  |    | ||||||
|  |   if ( dir == 0 ) | ||||||
|  |   { | ||||||
|  |     yy--; | ||||||
|  |     xx -= len; | ||||||
|  |   } | ||||||
|  |   else if ( dir == 1 ) | ||||||
|  |   { | ||||||
|  |     xx--; | ||||||
|  |     yy -= len; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8g2_draw_l90_r3(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir) | ||||||
|  | { | ||||||
|  |   u8g2_uint_t xx, yy; | ||||||
|  | 
 | ||||||
|  |   xx = y; | ||||||
|  |    | ||||||
|  |   yy = u8g2->width; | ||||||
|  |   yy -= x; | ||||||
|  |    | ||||||
|  |   if ( dir == 0 ) | ||||||
|  |   { | ||||||
|  |     yy--; | ||||||
|  |     yy -= len; | ||||||
|  |     yy++; | ||||||
|  |     dir = 1; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     yy--; | ||||||
|  |     dir = 0; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*============================================*/ | ||||||
|  | const u8g2_cb_t u8g2_cb_r0 = { u8g2_update_dimension_r0, u8g2_update_page_win_r0, u8g2_draw_l90_r0 }; | ||||||
|  | const u8g2_cb_t u8g2_cb_r1 = { u8g2_update_dimension_r1, u8g2_update_page_win_r1, u8g2_draw_l90_r1 }; | ||||||
|  | const u8g2_cb_t u8g2_cb_r2 = { u8g2_update_dimension_r2, u8g2_update_page_win_r2, u8g2_draw_l90_r2 }; | ||||||
|  | const u8g2_cb_t u8g2_cb_r3 = { u8g2_update_dimension_r3, u8g2_update_page_win_r3, u8g2_draw_l90_r3 }; | ||||||
|  |    | ||||||
|  | const u8g2_cb_t u8g2_cb_mirror = { u8g2_update_dimension_r0, u8g2_update_page_win_r0, u8g2_draw_l90_mirrorr_r0 }; | ||||||
|  |    | ||||||
|  | /*============================================*/ | ||||||
|  | /* setup for the null device */ | ||||||
|  | 
 | ||||||
|  | /* setup for the null (empty) device */ | ||||||
|  | void u8g2_Setup_null(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) | ||||||
|  | { | ||||||
|  |   static uint8_t buf[8]; | ||||||
|  |   u8g2_SetupDisplay(u8g2, u8x8_d_null_cb, u8x8_cad_empty, byte_cb, gpio_and_delay_cb); | ||||||
|  |   u8g2_SetupBuffer(u8g2, buf, 1, u8g2_ll_hvline_vertical_top_lsb, rotation); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |    | ||||||
							
								
								
									
										1198
									
								
								lib/u8g2/u8x8.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1198
									
								
								lib/u8g2/u8x8.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										493
									
								
								lib/u8g2/u8x8_8x8.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										493
									
								
								lib/u8g2/u8x8_8x8.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,493 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8x8_8x8.c | ||||||
|  |    | ||||||
|  |   font procedures, directly interfaces display procedures | ||||||
|  |    | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.     | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8x8.h" | ||||||
|  | 
 | ||||||
|  | #if defined(ESP8266) | ||||||
|  | uint8_t u8x8_pgm_read_esp(const uint8_t * addr)  | ||||||
|  | { | ||||||
|  |     uint32_t bytes; | ||||||
|  |     bytes = *(uint32_t*)((uint32_t)addr & ~3); | ||||||
|  |     return ((uint8_t*)&bytes)[(uint32_t)addr & 3]; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8x8_SetFont(u8x8_t *u8x8, const uint8_t *font_8x8) | ||||||
|  | { | ||||||
|  |   u8x8->font = font_8x8; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  Args: | ||||||
|  |    u8x8: ptr to u8x8 structure | ||||||
|  |    encoding: glyph for which the data is requested (must be between 0 and 255) | ||||||
|  |    buf: pointer to 8 bytes | ||||||
|  | */ | ||||||
|  | static void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset) U8X8_NOINLINE; | ||||||
|  | static void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset)  | ||||||
|  | { | ||||||
|  |   uint8_t first, last, tiles, i; | ||||||
|  |   uint16_t offset; | ||||||
|  |   first = u8x8_pgm_read(u8x8->font+0); | ||||||
|  |   last = u8x8_pgm_read(u8x8->font+1); | ||||||
|  |   tiles = u8x8_pgm_read(u8x8->font+2);		/* new 2019 format */ | ||||||
|  |   tiles *= u8x8_pgm_read(u8x8->font+3);	/* new 2019 format */ | ||||||
|  |    | ||||||
|  |   /* get the glyph bitmap from the font */ | ||||||
|  |   if ( first <= encoding && encoding <= last ) | ||||||
|  |   { | ||||||
|  |     offset = encoding; | ||||||
|  |     offset -= first; | ||||||
|  |     offset *= tiles;		/* new 2019 format */ | ||||||
|  |     offset += tile_offset;	/* new 2019 format */ | ||||||
|  |     offset *= 8; | ||||||
|  |     offset +=4;			/* changed from 2 to 4, new 2019 format */ | ||||||
|  |     for( i = 0; i < 8; i++ ) | ||||||
|  |     { | ||||||
|  |       buf[i] = u8x8_pgm_read(u8x8->font+offset); | ||||||
|  |       offset++; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     for( i = 0; i < 8; i++ ) | ||||||
|  |     { | ||||||
|  |       buf[i] = 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   /* invert the bitmap if required */ | ||||||
|  |   if ( u8x8->is_font_inverse_mode ) | ||||||
|  |   { | ||||||
|  |     for( i = 0; i < 8; i++ ) | ||||||
|  |     { | ||||||
|  |       buf[i] ^= 255; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_DrawGlyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding) | ||||||
|  | { | ||||||
|  |   uint8_t th = u8x8_pgm_read(u8x8->font+2);		/* new 2019 format */ | ||||||
|  |   uint8_t tv = u8x8_pgm_read(u8x8->font+3);	/* new 2019 format */ | ||||||
|  |   uint8_t xx, tile; | ||||||
|  |   uint8_t buf[8]; | ||||||
|  |   th += x; | ||||||
|  |   tv += y; | ||||||
|  |   tile = 0; | ||||||
|  |   do | ||||||
|  |   { | ||||||
|  |     xx = x; | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |       u8x8_get_glyph_data(u8x8, encoding, buf, tile); | ||||||
|  |       u8x8_DrawTile(u8x8, xx, y, 1, buf); | ||||||
|  |       tile++; | ||||||
|  |       xx++; | ||||||
|  |     } while( xx < th ); | ||||||
|  |     y++; | ||||||
|  |   } while( y < tv ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Source: http://graphics.stanford.edu/~seander/bithacks.html
 | ||||||
|  | 	Section: Interleave bits by Binary Magic Numbers  | ||||||
|  |    Original codes is here: | ||||||
|  | 		static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; | ||||||
|  | 		static const unsigned int S[] = {1, 2, 4, 8}; | ||||||
|  | 
 | ||||||
|  | 		unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x
 | ||||||
|  | 		unsigned int y; // are in the even positions and bits from y in the odd;
 | ||||||
|  | 		unsigned int z; // z gets the resulting 32-bit Morton Number.  
 | ||||||
|  | 				// x and y must initially be less than 65536.
 | ||||||
|  | 
 | ||||||
|  | 		x = (x | (x << S[3])) & B[3]; | ||||||
|  | 		x = (x | (x << S[2])) & B[2]; | ||||||
|  | 		x = (x | (x << S[1])) & B[1]; | ||||||
|  | 		x = (x | (x << S[0])) & B[0]; | ||||||
|  | 
 | ||||||
|  | 		y = (y | (y << S[3])) & B[3]; | ||||||
|  | 		y = (y | (y << S[2])) & B[2]; | ||||||
|  | 		y = (y | (y << S[1])) & B[1]; | ||||||
|  | 		y = (y | (y << S[0])) & B[0]; | ||||||
|  | 
 | ||||||
|  | 		z = x | (y << 1); | ||||||
|  | */ | ||||||
|  | uint16_t u8x8_upscale_byte(uint8_t x)  | ||||||
|  | { | ||||||
|  | 	uint16_t y = x; | ||||||
|  | 	y |= (y << 4);		// x = (x | (x << S[2])) & B[2];
 | ||||||
|  | 	y &= 0x0f0f; | ||||||
|  | 	y |= (y << 2);		// x = (x | (x << S[1])) & B[1];
 | ||||||
|  | 	y &= 0x3333; | ||||||
|  | 	y |= (y << 1);		// x = (x | (x << S[0])) & B[0];
 | ||||||
|  | 	y &= 0x5555; | ||||||
|  |    | ||||||
|  | 	y |= (y << 1);		// z = x | (y << 1);
 | ||||||
|  | 	return y; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void u8x8_upscale_buf(uint8_t *src, uint8_t *dest) U8X8_NOINLINE; | ||||||
|  | static void u8x8_upscale_buf(uint8_t *src, uint8_t *dest) | ||||||
|  | { | ||||||
|  |   uint8_t i = 4;   | ||||||
|  |   do  | ||||||
|  |   { | ||||||
|  |     *dest++ = *src; | ||||||
|  |     *dest++ = *src++; | ||||||
|  |     i--; | ||||||
|  |   } while( i > 0 ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void u8x8_draw_2x2_subglyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding, uint8_t tile) | ||||||
|  | { | ||||||
|  |   uint8_t i; | ||||||
|  |   uint16_t t; | ||||||
|  |   uint8_t buf[8]; | ||||||
|  |   uint8_t buf1[8]; | ||||||
|  |   uint8_t buf2[8]; | ||||||
|  |   u8x8_get_glyph_data(u8x8, encoding, buf, tile); | ||||||
|  |   for( i = 0; i < 8; i ++ ) | ||||||
|  |   { | ||||||
|  |       t = u8x8_upscale_byte(buf[i]); | ||||||
|  |       buf1[i] = t >> 8; | ||||||
|  |       buf2[i] = t & 255; | ||||||
|  |   } | ||||||
|  |   u8x8_upscale_buf(buf2, buf); | ||||||
|  |   u8x8_DrawTile(u8x8, x, y, 1, buf); | ||||||
|  |    | ||||||
|  |   u8x8_upscale_buf(buf2+4, buf); | ||||||
|  |   u8x8_DrawTile(u8x8, x+1, y, 1, buf); | ||||||
|  |    | ||||||
|  |   u8x8_upscale_buf(buf1, buf); | ||||||
|  |   u8x8_DrawTile(u8x8, x, y+1, 1, buf); | ||||||
|  |    | ||||||
|  |   u8x8_upscale_buf(buf1+4, buf); | ||||||
|  |   u8x8_DrawTile(u8x8, x+1, y+1, 1, buf);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8x8_Draw2x2Glyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding) | ||||||
|  | { | ||||||
|  |   uint8_t th = u8x8_pgm_read(u8x8->font+2);		/* new 2019 format */ | ||||||
|  |   uint8_t tv = u8x8_pgm_read(u8x8->font+3);	/* new 2019 format */ | ||||||
|  |   uint8_t xx, tile; | ||||||
|  |   th *= 2; | ||||||
|  |   th += x; | ||||||
|  |   tv *= 2; | ||||||
|  |   tv += y; | ||||||
|  |   tile = 0; | ||||||
|  |   do | ||||||
|  |   { | ||||||
|  |     xx = x; | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |       u8x8_draw_2x2_subglyph(u8x8, xx, y, encoding, tile); | ||||||
|  |       tile++; | ||||||
|  |       xx+=2; | ||||||
|  |     } while( xx < th ); | ||||||
|  |     y+=2; | ||||||
|  |   } while( y < tv );   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* https://github.com/olikraus/u8g2/issues/474 */ | ||||||
|  | static void u8x8_draw_1x2_subglyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding, uint8_t tile) | ||||||
|  | { | ||||||
|  |   uint8_t i; | ||||||
|  |   uint16_t t; | ||||||
|  |   uint8_t buf[8]; | ||||||
|  |   uint8_t buf1[8]; | ||||||
|  |   uint8_t buf2[8]; | ||||||
|  |   u8x8_get_glyph_data(u8x8, encoding, buf, tile); | ||||||
|  |   for( i = 0; i < 8; i ++ ) | ||||||
|  |   { | ||||||
|  |       t = u8x8_upscale_byte(buf[i]); | ||||||
|  |       buf1[i] = t >> 8; | ||||||
|  |       buf2[i] = t & 255; | ||||||
|  |   } | ||||||
|  |   u8x8_DrawTile(u8x8, x,   y, 1, buf2); | ||||||
|  |   u8x8_DrawTile(u8x8, x, y+1, 1, buf1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_Draw1x2Glyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding) | ||||||
|  | { | ||||||
|  |   uint8_t th = u8x8_pgm_read(u8x8->font+2);		/* new 2019 format */ | ||||||
|  |   uint8_t tv = u8x8_pgm_read(u8x8->font+3);	/* new 2019 format */ | ||||||
|  |   uint8_t xx, tile; | ||||||
|  |   th += x; | ||||||
|  |   tv *= 2; | ||||||
|  |   tv += y; | ||||||
|  |   tile = 0; | ||||||
|  |   do | ||||||
|  |   { | ||||||
|  |     xx = x; | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |       u8x8_draw_1x2_subglyph(u8x8, xx, y, encoding, tile); | ||||||
|  |       tile++; | ||||||
|  |       xx++; | ||||||
|  |     } while( xx < th ); | ||||||
|  |     y+=2; | ||||||
|  |   } while( y < tv );   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | source: https://en.wikipedia.org/wiki/UTF-8
 | ||||||
|  | Bits	from 		to			bytes	Byte 1 		Byte 2 		Byte 3 		Byte 4 		Byte 5 		Byte 6 | ||||||
|  |   7 	U+0000 		U+007F 		1 		0xxxxxxx | ||||||
|  | 11 	U+0080 		U+07FF 		2 		110xxxxx 	10xxxxxx | ||||||
|  | 16 	U+0800 		U+FFFF 		3 		1110xxxx 	10xxxxxx 	10xxxxxx | ||||||
|  | 21 	U+10000 	U+1FFFFF 	4 		11110xxx 	10xxxxxx 	10xxxxxx 	10xxxxxx | ||||||
|  | 26 	U+200000 	U+3FFFFFF 	5 		111110xx 	10xxxxxx 	10xxxxxx 	10xxxxxx 	10xxxxxx | ||||||
|  | 31 	U+4000000 	U+7FFFFFFF 	6 		1111110x 	10xxxxxx 	10xxxxxx 	10xxxxxx 	10xxxxxx 	10xxxxxx   | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /* reset the internal state machine */ | ||||||
|  | void u8x8_utf8_init(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   u8x8->utf8_state = 0;	/* also reset during u8x8_SetupDefaults() */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint16_t u8x8_ascii_next(U8X8_UNUSED u8x8_t *u8x8, uint8_t b) | ||||||
|  | { | ||||||
|  |   if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */ | ||||||
|  |     return 0x0ffff;	/* end of string detected*/ | ||||||
|  |   return b; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   pass a byte from an utf8 encoded string to the utf8 decoder state machine | ||||||
|  |   returns  | ||||||
|  |     0x0fffe: no glyph, just continue | ||||||
|  |     0x0ffff: end of string | ||||||
|  |     anything else: The decoded encoding | ||||||
|  | */ | ||||||
|  | uint16_t u8x8_utf8_next(u8x8_t *u8x8, uint8_t b) | ||||||
|  | { | ||||||
|  |   if ( b == 0 || b == '\n' )	/* '\n' terminates the string to support the string list procedures */ | ||||||
|  |     return 0x0ffff;	/* end of string detected, pending UTF8 is discarded */ | ||||||
|  |   if ( u8x8->utf8_state == 0 ) | ||||||
|  |   { | ||||||
|  |     if ( b >= 0xfc )	/* 6 byte sequence */ | ||||||
|  |     { | ||||||
|  |       u8x8->utf8_state = 5; | ||||||
|  |       b &= 1; | ||||||
|  |     } | ||||||
|  |     else if ( b >= 0xf8 ) | ||||||
|  |     { | ||||||
|  |       u8x8->utf8_state = 4; | ||||||
|  |       b &= 3; | ||||||
|  |     } | ||||||
|  |     else if ( b >= 0xf0 ) | ||||||
|  |     { | ||||||
|  |       u8x8->utf8_state = 3; | ||||||
|  |       b &= 7;       | ||||||
|  |     } | ||||||
|  |     else if ( b >= 0xe0 ) | ||||||
|  |     { | ||||||
|  |       u8x8->utf8_state = 2; | ||||||
|  |       b &= 15; | ||||||
|  |     } | ||||||
|  |     else if ( b >= 0xc0 ) | ||||||
|  |     { | ||||||
|  |       u8x8->utf8_state = 1; | ||||||
|  |       b &= 0x01f; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       /* do nothing, just use the value as encoding */ | ||||||
|  |       return b; | ||||||
|  |     } | ||||||
|  |     u8x8->encoding = b; | ||||||
|  |     return 0x0fffe; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     u8x8->utf8_state--; | ||||||
|  |     /* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */ | ||||||
|  |     u8x8->encoding<<=6; | ||||||
|  |     b &= 0x03f; | ||||||
|  |     u8x8->encoding |= b; | ||||||
|  |     if ( u8x8->utf8_state != 0 ) | ||||||
|  |       return 0x0fffe;	/* nothing to do yet */ | ||||||
|  |   } | ||||||
|  |   return u8x8->encoding; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE; | ||||||
|  | static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | { | ||||||
|  |   uint16_t e; | ||||||
|  |   uint8_t cnt = 0; | ||||||
|  |   uint8_t th = u8x8_pgm_read(u8x8->font+2);		/* new 2019 format */ | ||||||
|  | 
 | ||||||
|  |   u8x8_utf8_init(u8x8); | ||||||
|  |   for(;;) | ||||||
|  |   { | ||||||
|  |     e = u8x8->next_cb(u8x8, (uint8_t)*s); | ||||||
|  |     if ( e == 0x0ffff ) | ||||||
|  |       break; | ||||||
|  |     s++; | ||||||
|  |     if ( e != 0x0fffe ) | ||||||
|  |     { | ||||||
|  |       u8x8_DrawGlyph(u8x8, x, y, e); | ||||||
|  |       x+=th; | ||||||
|  |       cnt++; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return cnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_DrawString(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | { | ||||||
|  |   u8x8->next_cb = u8x8_ascii_next; | ||||||
|  |   return u8x8_draw_string(u8x8, x, y, s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_DrawUTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | { | ||||||
|  |   u8x8->next_cb = u8x8_utf8_next; | ||||||
|  |   return u8x8_draw_string(u8x8, x, y, s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static uint8_t u8x8_draw_2x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE; | ||||||
|  | static uint8_t u8x8_draw_2x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | { | ||||||
|  |   uint16_t e; | ||||||
|  |   uint8_t cnt = 0; | ||||||
|  |   uint8_t th = u8x8_pgm_read(u8x8->font+2);	/* new 2019 format */ | ||||||
|  |    | ||||||
|  |   th <<= 1; | ||||||
|  |    | ||||||
|  |   u8x8_utf8_init(u8x8); | ||||||
|  |   for(;;) | ||||||
|  |   { | ||||||
|  |     e = u8x8->next_cb(u8x8, (uint8_t)*s); | ||||||
|  |     if ( e == 0x0ffff ) | ||||||
|  |       break; | ||||||
|  |     s++; | ||||||
|  |     if ( e != 0x0fffe ) | ||||||
|  |     { | ||||||
|  |       u8x8_Draw2x2Glyph(u8x8, x, y, e); | ||||||
|  |       x+=th; | ||||||
|  |       cnt++; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return cnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_Draw2x2String(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | { | ||||||
|  |   u8x8->next_cb = u8x8_ascii_next; | ||||||
|  |   return u8x8_draw_2x2_string(u8x8, x, y, s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_Draw2x2UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | { | ||||||
|  |   u8x8->next_cb = u8x8_utf8_next; | ||||||
|  |   return u8x8_draw_2x2_string(u8x8, x, y, s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static uint8_t u8x8_draw_1x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE; | ||||||
|  | static uint8_t u8x8_draw_1x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | {   | ||||||
|  |   uint16_t e; | ||||||
|  |   uint8_t cnt = 0; | ||||||
|  |   uint8_t th = u8x8_pgm_read(u8x8->font+2);	/* new 2019 format */ | ||||||
|  |   u8x8_utf8_init(u8x8); | ||||||
|  |   for(;;) | ||||||
|  |   { | ||||||
|  |     e = u8x8->next_cb(u8x8, (uint8_t)*s); | ||||||
|  |     if ( e == 0x0ffff ) | ||||||
|  |       break; | ||||||
|  |     s++; | ||||||
|  |     if ( e != 0x0fffe ) | ||||||
|  |     { | ||||||
|  |       u8x8_Draw1x2Glyph(u8x8, x, y, e); | ||||||
|  |       x+=th; | ||||||
|  |       cnt++; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return cnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_Draw1x2String(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | { | ||||||
|  |   u8x8->next_cb = u8x8_ascii_next; | ||||||
|  |   return u8x8_draw_1x2_string(u8x8, x, y, s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_Draw1x2UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) | ||||||
|  | { | ||||||
|  |   u8x8->next_cb = u8x8_utf8_next; | ||||||
|  |   return u8x8_draw_1x2_string(u8x8, x, y, s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_GetUTF8Len(u8x8_t *u8x8, const char *s) | ||||||
|  | { | ||||||
|  |   uint16_t e; | ||||||
|  |   uint8_t cnt = 0; | ||||||
|  |   u8x8_utf8_init(u8x8); | ||||||
|  |   for(;;) | ||||||
|  |   { | ||||||
|  |     e = u8x8_utf8_next(u8x8, *s); | ||||||
|  |     if ( e == 0x0ffff ) | ||||||
|  |       break; | ||||||
|  |     s++; | ||||||
|  |     if ( e != 0x0fffe ) | ||||||
|  |       cnt++; | ||||||
|  |   } | ||||||
|  |   return cnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										666
									
								
								lib/u8g2/u8x8_byte.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										666
									
								
								lib/u8g2/u8x8_byte.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,666 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8x8_byte.c  | ||||||
|  |    | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  |    | ||||||
|  |    | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8x8.h" | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_SetDC(u8x8_t *u8x8, uint8_t dc) | ||||||
|  | { | ||||||
|  |   return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SET_DC, dc, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_SendBytes(u8x8_t *u8x8, uint8_t cnt, uint8_t *data) | ||||||
|  | { | ||||||
|  |   return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SEND, cnt, (void *)data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_SendByte(u8x8_t *u8x8, uint8_t byte) | ||||||
|  | { | ||||||
|  |   return u8x8_byte_SendBytes(u8x8, 1, &byte); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_StartTransfer(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_START_TRANSFER, 0, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_EndTransfer(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_END_TRANSFER, 0, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*=========================================*/ | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_empty(U8X8_UNUSED u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr) | ||||||
|  | { | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       break;	/* do nothing */ | ||||||
|  |   } | ||||||
|  |   return 1;	/* always succeed */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*=========================================*/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Uses: | ||||||
|  |     u8x8->display_info->sda_setup_time_ns | ||||||
|  |     u8x8->display_info->sck_pulse_width_ns | ||||||
|  |     u8x8->display_info->spi_mode | ||||||
|  |     u8x8->display_info->chip_disable_level | ||||||
|  |     u8x8->display_info->chip_enable_level | ||||||
|  |     u8x8->display_info->post_chip_enable_wait_ns | ||||||
|  |     u8x8->display_info->pre_chip_disable_wait_ns | ||||||
|  |   Calls to GPIO and DELAY: | ||||||
|  |     U8X8_MSG_DELAY_NANO | ||||||
|  |     U8X8_MSG_GPIO_DC | ||||||
|  |     U8X8_MSG_GPIO_CS | ||||||
|  |     U8X8_MSG_GPIO_CLOCK | ||||||
|  |     U8X8_MSG_GPIO_DATA | ||||||
|  |   Handles: | ||||||
|  |     U8X8_MSG_BYTE_INIT | ||||||
|  |     U8X8_MSG_BYTE_SEND | ||||||
|  |     U8X8_MSG_BYTE_SET_DC | ||||||
|  |     U8X8_MSG_BYTE_START_TRANSFER | ||||||
|  |     U8X8_MSG_BYTE_END_TRANSFER | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t i, b; | ||||||
|  |   uint8_t *data; | ||||||
|  |   uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8); | ||||||
|  |   uint8_t not_takeover_edge = 1 - takeover_edge; | ||||||
|  |   | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |       data = (uint8_t *)arg_ptr; | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	b = *data; | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  | 	for( i = 0; i < 8; i++ ) | ||||||
|  | 	{ | ||||||
|  | 	  if ( b & 128 ) | ||||||
|  | 	    u8x8_gpio_SetSPIData(u8x8, 1); | ||||||
|  | 	  else | ||||||
|  | 	    u8x8_gpio_SetSPIData(u8x8, 0); | ||||||
|  | 	  b <<= 1; | ||||||
|  | 	   | ||||||
|  | 	  u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge); | ||||||
|  | 	  u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns); | ||||||
|  | 	  u8x8_gpio_SetSPIClock(u8x8, takeover_edge); | ||||||
|  | 	  u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns); | ||||||
|  | 	}     | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |        | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |       /* disable chipselect */ | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); | ||||||
|  |       /* no wait required here */ | ||||||
|  |        | ||||||
|  |       /* for SPI: setup correct level of the clock signal */ | ||||||
|  |       u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8)); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |       u8x8_gpio_SetDC(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);   | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL); | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*=========================================*/ | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_8bit_6800mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t i, b; | ||||||
|  |   uint8_t *data; | ||||||
|  |   | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |       data = (uint8_t *)arg_ptr; | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	b = *data; | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  | 	for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ ) | ||||||
|  | 	{ | ||||||
|  | 	  u8x8_gpio_call(u8x8, i, b&1); | ||||||
|  | 	  b >>= 1; | ||||||
|  | 	}     | ||||||
|  | 	 | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns); | ||||||
|  | 	u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1); | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); | ||||||
|  | 	u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0); | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |        | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |       /* disable chipselect */ | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);     | ||||||
|  |       /* ensure that the enable signal is high */ | ||||||
|  |       u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |       u8x8_gpio_SetDC(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);   | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL); | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t i, b; | ||||||
|  |   uint8_t *data; | ||||||
|  |   | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |       data = (uint8_t *)arg_ptr; | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	b = *data; | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  | 	for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ ) | ||||||
|  | 	{ | ||||||
|  | 	  u8x8_gpio_call(u8x8, i, b&1); | ||||||
|  | 	  b >>= 1; | ||||||
|  | 	}     | ||||||
|  | 	 | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns); | ||||||
|  | 	u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0); | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); | ||||||
|  | 	u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1); | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |        | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |       /* disable chipselect */ | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);     | ||||||
|  |       /* ensure that the enable signal is high */ | ||||||
|  |       u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |       u8x8_gpio_SetDC(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);   | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL); | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*=========================================*/ | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t i; | ||||||
|  |   uint8_t *data; | ||||||
|  |   uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8); | ||||||
|  |   uint8_t not_takeover_edge = 1 - takeover_edge; | ||||||
|  |   uint16_t b; | ||||||
|  |   static uint8_t last_dc; | ||||||
|  |   | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |       data = (uint8_t *)arg_ptr; | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	b = *data; | ||||||
|  | 	if ( last_dc != 0 ) | ||||||
|  | 	  b |= 256; | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  | 	for( i = 0; i < 9; i++ ) | ||||||
|  | 	{ | ||||||
|  | 	  if ( b & 256 ) | ||||||
|  | 	    u8x8_gpio_SetSPIData(u8x8, 1); | ||||||
|  | 	  else | ||||||
|  | 	    u8x8_gpio_SetSPIData(u8x8, 0); | ||||||
|  | 	  b <<= 1; | ||||||
|  | 	   | ||||||
|  | 	  u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge); | ||||||
|  | 	  u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns); | ||||||
|  | 	  u8x8_gpio_SetSPIClock(u8x8, takeover_edge); | ||||||
|  | 	  u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns); | ||||||
|  | 	}     | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |        | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |       /* disable chipselect */ | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); | ||||||
|  |       /* no wait required here */ | ||||||
|  |        | ||||||
|  |       /* for SPI: setup correct level of the clock signal */ | ||||||
|  |       u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8)); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |       last_dc = arg_int; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);   | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL); | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*=========================================*/ | ||||||
|  | 
 | ||||||
|  | void u8x8_byte_set_ks0108_cs(u8x8_t *u8x8, uint8_t arg) | ||||||
|  | { | ||||||
|  |   u8x8_gpio_SetCS(u8x8, arg&1); | ||||||
|  |   arg = arg >> 1; | ||||||
|  |   u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS1, arg&1); | ||||||
|  |   arg = arg >> 1; | ||||||
|  |   u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS2, arg&1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 6800 mode */ | ||||||
|  | uint8_t u8x8_byte_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t i, b; | ||||||
|  |   uint8_t *data; | ||||||
|  |   | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |       data = (uint8_t *)arg_ptr; | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	b = *data; | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  | 	for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ ) | ||||||
|  | 	{ | ||||||
|  | 	  u8x8_gpio_call(u8x8, i, b&1); | ||||||
|  | 	  b >>= 1; | ||||||
|  | 	}     | ||||||
|  | 	 | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns); | ||||||
|  | 	u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1); | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); | ||||||
|  | 	u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0); | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |        | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |       /* disable chipselect */ | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);     | ||||||
|  |       /* ensure that the enable signal is low */ | ||||||
|  |       u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |       u8x8_gpio_SetDC(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |       /* expects 3 bits in arg_int for the chip select lines */  | ||||||
|  |       u8x8_byte_set_ks0108_cs(u8x8, arg_int); | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL); | ||||||
|  |       u8x8_byte_set_ks0108_cs(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* sed1520 or sbn1661 
 | ||||||
|  |   U8X8_MSG_GPIO_E --> E1 | ||||||
|  |   U8X8_MSG_GPIO_CS --> E2 | ||||||
|  | */ | ||||||
|  | uint8_t u8x8_byte_sed1520(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t i, b; | ||||||
|  |   uint8_t *data; | ||||||
|  |   static uint8_t enable_pin; | ||||||
|  |   | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |       data = (uint8_t *)arg_ptr; | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	b = *data; | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  | 	for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ ) | ||||||
|  | 	{ | ||||||
|  | 	  u8x8_gpio_call(u8x8, i, b&1); | ||||||
|  | 	  b >>= 1; | ||||||
|  | 	}     | ||||||
|  | 	 | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns); | ||||||
|  | 	u8x8_gpio_call(u8x8, enable_pin, 1); | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 200);		/* KS0108 requires 450 ns, use 200 here */ | ||||||
|  | 	u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);  /* expect 250 here */ | ||||||
|  | 	u8x8_gpio_call(u8x8, enable_pin, 0); | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |        | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |       /* disable chipselect */ | ||||||
|  |       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);     | ||||||
|  |       /* ensure that the enable signals are low */ | ||||||
|  |       u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0); | ||||||
|  |       u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS, 0); | ||||||
|  |       enable_pin = U8X8_MSG_GPIO_E; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |       u8x8_gpio_SetDC(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |       /* cs lines are not supported for the SED1520/SBN1661 */ | ||||||
|  |       /* instead, this will select the E1 or E2 line */  | ||||||
|  |       enable_pin = U8X8_MSG_GPIO_E; | ||||||
|  |       if ( arg_int != 0 ) | ||||||
|  | 	enable_pin = U8X8_MSG_GPIO_CS; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*=========================================*/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   software i2c, | ||||||
|  |   ignores ACK response (which is anyway not provided by some displays) | ||||||
|  |   also does not allow reading from the device | ||||||
|  | */ | ||||||
|  | static void i2c_delay(u8x8_t *u8x8) U8X8_NOINLINE; | ||||||
|  | static void i2c_delay(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_10MICRO, u8x8->display_info->i2c_bus_clock_100kHz);
 | ||||||
|  |   u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_I2C, u8x8->display_info->i2c_bus_clock_100kHz); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void i2c_init(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   u8x8_gpio_SetI2CClock(u8x8, 1); | ||||||
|  |   u8x8_gpio_SetI2CData(u8x8, 1); | ||||||
|  |    | ||||||
|  |   i2c_delay(u8x8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* actually, the scl line is not observed, so this procedure does not return a value */ | ||||||
|  | 
 | ||||||
|  | static void i2c_read_scl_and_delay(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   /* set as input (line will be high) */ | ||||||
|  |   u8x8_gpio_SetI2CClock(u8x8, 1); | ||||||
|  | 
 | ||||||
|  |   i2c_delay(u8x8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void i2c_clear_scl(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   u8x8_gpio_SetI2CClock(u8x8, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void i2c_read_sda(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   /* set as input (line will be high) */ | ||||||
|  |   u8x8_gpio_SetI2CData(u8x8, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void i2c_clear_sda(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   /* set open collector and drive low */ | ||||||
|  |   u8x8_gpio_SetI2CData(u8x8, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void i2c_start(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   if ( u8x8->i2c_started != 0 ) | ||||||
|  |   { | ||||||
|  |     /* if already started: do restart */ | ||||||
|  |     i2c_read_sda(u8x8);     /* SDA = 1 */ | ||||||
|  |     i2c_delay(u8x8); | ||||||
|  |     i2c_read_scl_and_delay(u8x8); | ||||||
|  |   } | ||||||
|  |   i2c_read_sda(u8x8); | ||||||
|  |   /* send the start condition, both lines go from 1 to 0 */ | ||||||
|  |   i2c_clear_sda(u8x8); | ||||||
|  |   i2c_delay(u8x8); | ||||||
|  |   i2c_clear_scl(u8x8); | ||||||
|  |   u8x8->i2c_started = 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void i2c_stop(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   /* set SDA to 0 */ | ||||||
|  |   i2c_clear_sda(u8x8);   | ||||||
|  |   i2c_delay(u8x8); | ||||||
|  |   | ||||||
|  |   /* now release all lines */ | ||||||
|  |   i2c_read_scl_and_delay(u8x8); | ||||||
|  |   | ||||||
|  |   /* set SDA to 1 */ | ||||||
|  |   i2c_read_sda(u8x8); | ||||||
|  |   i2c_delay(u8x8); | ||||||
|  |   u8x8->i2c_started = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void i2c_write_bit(u8x8_t *u8x8, uint8_t val) | ||||||
|  | { | ||||||
|  |   if (val) | ||||||
|  |     i2c_read_sda(u8x8); | ||||||
|  |   else | ||||||
|  |     i2c_clear_sda(u8x8); | ||||||
|  |   | ||||||
|  |   i2c_delay(u8x8); | ||||||
|  |   i2c_read_scl_and_delay(u8x8); | ||||||
|  |   i2c_clear_scl(u8x8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void i2c_read_bit(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   //uint8_t val;
 | ||||||
|  |   /* do not drive SDA */ | ||||||
|  |   i2c_read_sda(u8x8); | ||||||
|  |   i2c_delay(u8x8); | ||||||
|  |   i2c_read_scl_and_delay(u8x8); | ||||||
|  |   i2c_read_sda(u8x8); | ||||||
|  |   i2c_delay(u8x8); | ||||||
|  |   i2c_clear_scl(u8x8); | ||||||
|  |   //return val;
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void i2c_write_byte(u8x8_t *u8x8, uint8_t b) | ||||||
|  | { | ||||||
|  |   i2c_write_bit(u8x8, b & 128); | ||||||
|  |   i2c_write_bit(u8x8, b & 64); | ||||||
|  |   i2c_write_bit(u8x8, b & 32); | ||||||
|  |   i2c_write_bit(u8x8, b & 16); | ||||||
|  |   i2c_write_bit(u8x8, b & 8); | ||||||
|  |   i2c_write_bit(u8x8, b & 4); | ||||||
|  |   i2c_write_bit(u8x8, b & 2); | ||||||
|  |   i2c_write_bit(u8x8, b & 1); | ||||||
|  |      | ||||||
|  |   /* read ack from client */ | ||||||
|  |   /* 0: ack was given by client */ | ||||||
|  |   /* 1: nothing happend during ack cycle */   | ||||||
|  |   i2c_read_bit(u8x8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t *data; | ||||||
|  | 
 | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |       data = (uint8_t *)arg_ptr; | ||||||
|  |      | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	i2c_write_byte(u8x8, *data); | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       break; | ||||||
|  |        | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |       i2c_init(u8x8); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |       i2c_start(u8x8); | ||||||
|  |       i2c_write_byte(u8x8, u8x8_GetI2CAddress(u8x8)); | ||||||
|  |       //i2c_write_byte(u8x8, 0x078);
 | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       i2c_stop(u8x8); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*=========================================*/ | ||||||
|  | 
 | ||||||
|  | /* alternative i2c byte procedure */ | ||||||
|  | #ifdef ALTERNATIVE_I2C_BYTE_PROCEDURE | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void i2c_transfer(u8x8_t *u8x8, uint8_t adr, uint8_t cnt, uint8_t *data) | ||||||
|  | { | ||||||
|  |   uint8_t i; | ||||||
|  |   i2c_start(u8x8); | ||||||
|  |   i2c_write_byte(u8x8, adr); | ||||||
|  |   for( i = 0; i < cnt; i++ ) | ||||||
|  |     i2c_write_byte(u8x8, data[i]); | ||||||
|  |   i2c_stop(u8x8);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   static uint8_t buffer[32];		/* u8g2/u8x8 will never send more than 32 bytes */ | ||||||
|  |   static uint8_t buf_idx; | ||||||
|  |   uint8_t *data; | ||||||
|  |   | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_BYTE_SEND: | ||||||
|  |       data = (uint8_t *)arg_ptr;       | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	buffer[buf_idx++] = *data; | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  |       }       | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_INIT: | ||||||
|  |       i2c_init(u8x8);			/* init i2c communication */ | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |       /* ignored for i2c */ | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |       buf_idx = 0; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |       i2c_transfer(u8x8, u8x8_GetI2CAddress(u8x8), buf_idx, buffer); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										749
									
								
								lib/u8g2/u8x8_cad.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										749
									
								
								lib/u8g2/u8x8_cad.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,749 @@ | |||||||
|  | /*
 | ||||||
|  |    | ||||||
|  |   u8x8_cad.c | ||||||
|  |    | ||||||
|  |   "command arg data" interface to the graphics controller | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   The following sequence must be used for any data, which is set to the display: | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8) | ||||||
|  | 
 | ||||||
|  |   any of the following calls | ||||||
|  |     uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd) | ||||||
|  |     uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg) | ||||||
|  |     uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data) | ||||||
|  |    | ||||||
|  |   uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | /*
 | ||||||
|  | uint8_t u8x8_cad_template(u8x8_t *u8x8, uint8_t msg, uint16_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t i; | ||||||
|  |    | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       u8x8_mcd_byte_SetDC(mcd->next, 1); | ||||||
|  |       u8x8_mcd_byte_Send(mcd->next, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_mcd_byte_SetDC(mcd->next, 1); | ||||||
|  |       u8x8_mcd_byte_Send(mcd->next, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       u8x8_mcd_byte_SetDC(mcd->next, 0); | ||||||
|  |       for( i = 0; i < 8; i++ ) | ||||||
|  | 	u8x8_mcd_byte_Send(mcd->next, ((uint8_t *)arg_ptr)[i]); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_RESET: | ||||||
|  |       return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr); | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |       return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr); | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr); | ||||||
|  |     default: | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "u8x8.h" | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd) | ||||||
|  | { | ||||||
|  |   return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_CMD, cmd, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg) | ||||||
|  | { | ||||||
|  |   return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_cad_SendMultipleArg(u8x8_t *u8x8, uint8_t cnt, uint8_t arg) | ||||||
|  | { | ||||||
|  |   while( cnt > 0 ) | ||||||
|  |   { | ||||||
|  |     u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL); | ||||||
|  |     cnt--; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data) | ||||||
|  | { | ||||||
|  |   return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, cnt, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_cad_vsendf(u8x8_t * u8x8, const char *fmt, va_list va) | ||||||
|  | { | ||||||
|  |   uint8_t d; | ||||||
|  |   u8x8_cad_StartTransfer(u8x8); | ||||||
|  |   while( *fmt != '\0' ) | ||||||
|  |   { | ||||||
|  |     d = (uint8_t)va_arg(va, int); | ||||||
|  |     switch(*fmt) | ||||||
|  |     { | ||||||
|  |       case 'a':  u8x8_cad_SendArg(u8x8, d); break; | ||||||
|  |       case 'c':  u8x8_cad_SendCmd(u8x8, d); break; | ||||||
|  |       case 'd':  u8x8_cad_SendData(u8x8, 1, &d); break; | ||||||
|  |     } | ||||||
|  |     fmt++; | ||||||
|  |   } | ||||||
|  |   u8x8_cad_EndTransfer(u8x8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_SendF(u8x8_t * u8x8, const char *fmt, ...) | ||||||
|  | { | ||||||
|  |   va_list va; | ||||||
|  |   va_start(va, fmt); | ||||||
|  |   u8x8_cad_vsendf(u8x8, fmt, va); | ||||||
|  |   va_end(va); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   21 c		send command c | ||||||
|  |   22 a		send arg a | ||||||
|  |   23 d		send data d | ||||||
|  |   24			CS on | ||||||
|  |   25			CS off | ||||||
|  |   254 milli	delay by milliseconds | ||||||
|  |   255		end of sequence | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | void u8x8_cad_SendSequence(u8x8_t *u8x8, uint8_t const *data) | ||||||
|  | { | ||||||
|  |   uint8_t cmd; | ||||||
|  |   uint8_t v; | ||||||
|  | 
 | ||||||
|  |   for(;;) | ||||||
|  |   { | ||||||
|  |     cmd = *data; | ||||||
|  |     data++; | ||||||
|  |     switch( cmd ) | ||||||
|  |     { | ||||||
|  |       case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  | 	  v = *data; | ||||||
|  | 	  u8x8->cad_cb(u8x8, cmd, v, NULL); | ||||||
|  | 	  data++; | ||||||
|  | 	  break; | ||||||
|  |       case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  | 	  v = *data; | ||||||
|  | 	  u8x8_cad_SendData(u8x8, 1, &v); | ||||||
|  | 	  data++; | ||||||
|  | 	  break; | ||||||
|  |       case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |       case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  | 	  u8x8->cad_cb(u8x8, cmd, 0, NULL); | ||||||
|  | 	  break; | ||||||
|  |       case 0x0fe: | ||||||
|  | 	  v = *data; | ||||||
|  | 	  u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, v);	     | ||||||
|  | 	  data++; | ||||||
|  | 	  break; | ||||||
|  |       default: | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_cad_empty(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   convert to bytes by using  | ||||||
|  |     dc = 1 for commands and args and | ||||||
|  |     dc = 0 for data | ||||||
|  | */ | ||||||
|  | uint8_t u8x8_cad_110(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 1); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 1); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 0); | ||||||
|  |       //u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
 | ||||||
|  |       //break;
 | ||||||
|  |       /* fall through */ | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   convert to bytes by using  | ||||||
|  |     dc = 1 for commands and args and | ||||||
|  |     dc = 0 for data | ||||||
|  |     t6963 | ||||||
|  | */ | ||||||
|  | uint8_t u8x8_cad_100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 1); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 0); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 0); | ||||||
|  |       //u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
 | ||||||
|  |       //break;
 | ||||||
|  |       /* fall through */ | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   convert to bytes by using  | ||||||
|  |     dc = 0 for commands and args and | ||||||
|  |     dc = 1 for data | ||||||
|  | */ | ||||||
|  | uint8_t u8x8_cad_001(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 0); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 0); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 1); | ||||||
|  |       //u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
 | ||||||
|  |       //break;
 | ||||||
|  |       /* fall through */ | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   convert to bytes by using  | ||||||
|  |     dc = 0 for commands  | ||||||
|  |     dc = 1 for args and data | ||||||
|  | */ | ||||||
|  | uint8_t u8x8_cad_011(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 0); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 1); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       u8x8_byte_SetDC(u8x8, 1); | ||||||
|  |       //u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
 | ||||||
|  |       //break;
 | ||||||
|  |       /* fall through */ | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* cad procedure for the ST7920 in SPI mode */ | ||||||
|  | /* u8x8_byte_SetDC is not used */ | ||||||
|  | uint8_t u8x8_cad_st7920_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t *data; | ||||||
|  |   uint8_t b; | ||||||
|  |   uint8_t i; | ||||||
|  |   static uint8_t buf[16]; | ||||||
|  |   uint8_t *ptr; | ||||||
|  |    | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       u8x8_byte_SendByte(u8x8, 0x0f8); | ||||||
|  |       u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int & 0x0f0); | ||||||
|  |       u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int << 4); | ||||||
|  |       u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_SendByte(u8x8, 0x0f8); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int & 0x0f0); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int << 4); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |      | ||||||
|  |       u8x8_byte_SendByte(u8x8, 0x0fa); | ||||||
|  |       u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1); | ||||||
|  | 
 | ||||||
|  |       /* this loop should be optimized: multiple bytes should be sent */ | ||||||
|  |       /* u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr); */ | ||||||
|  |       data = (uint8_t *)arg_ptr; | ||||||
|  |      | ||||||
|  |       /* the following loop increases speed by 20% */ | ||||||
|  |       while( arg_int >= 8 ) | ||||||
|  |       { | ||||||
|  | 	i = 8; | ||||||
|  | 	ptr = buf; | ||||||
|  | 	do | ||||||
|  | 	{ | ||||||
|  | 	  b = *data++; | ||||||
|  | 	  *ptr++= b & 0x0f0; | ||||||
|  | 	  b <<= 4; | ||||||
|  | 	  *ptr++= b; | ||||||
|  | 	  i--; | ||||||
|  | 	} while( i > 0 ); | ||||||
|  | 	arg_int -= 8; | ||||||
|  | 	u8x8_byte_SendBytes(u8x8, 16, buf);  | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |      | ||||||
|  |       while( arg_int > 0 ) | ||||||
|  |       { | ||||||
|  | 	b = *data; | ||||||
|  | 	u8x8_byte_SendByte(u8x8, b & 0x0f0); | ||||||
|  | 	u8x8_byte_SendByte(u8x8, b << 4); | ||||||
|  | 	data++; | ||||||
|  | 	arg_int--; | ||||||
|  |       } | ||||||
|  |       u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* cad procedure for the SSD13xx family in I2C mode */ | ||||||
|  | /* this procedure is also used by the ST7588 */ | ||||||
|  | /* u8x8_byte_SetDC is not used */ | ||||||
|  | /* U8X8_MSG_BYTE_START_TRANSFER starts i2c transfer, U8X8_MSG_BYTE_END_TRANSFER stops transfer */ | ||||||
|  | /* After transfer start, a full byte indicates command or data mode */ | ||||||
|  | 
 | ||||||
|  | static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE; | ||||||
|  | static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |     u8x8_byte_StartTransfer(u8x8);     | ||||||
|  |     u8x8_byte_SendByte(u8x8, 0x040); | ||||||
|  |     u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, arg_ptr); | ||||||
|  |     u8x8_byte_EndTransfer(u8x8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* classic version: will put a start/stop condition around each command and arg */ | ||||||
|  | uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t *p; | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       /* 7 Nov 2016: Can this be improved?  */ | ||||||
|  |       //u8x8_byte_SetDC(u8x8, 0);
 | ||||||
|  |       u8x8_byte_StartTransfer(u8x8); | ||||||
|  |       //u8x8_byte_SendByte(u8x8, u8x8_GetI2CAddress(u8x8));
 | ||||||
|  |       u8x8_byte_SendByte(u8x8, 0x000); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       u8x8_byte_EndTransfer(u8x8);       | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       //u8x8_byte_SetDC(u8x8, 1);
 | ||||||
|  |      | ||||||
|  |       /* the FeatherWing OLED with the 32u4 transfer of long byte */ | ||||||
|  |       /* streams was not possible. This is broken down to */ | ||||||
|  |       /* smaller streams, 32 seems to be the limit... */ | ||||||
|  |       /* I guess this is related to the size of the Wire buffers in Arduino */ | ||||||
|  |       /* Unfortunately, this can not be handled in the byte level drivers, */ | ||||||
|  |       /* so this is done here. Even further, only 24 bytes will be sent, */ | ||||||
|  |       /* because there will be another byte (DC) required during the transfer */ | ||||||
|  |       p = arg_ptr; | ||||||
|  |        while( arg_int > 24 ) | ||||||
|  |       { | ||||||
|  | 	u8x8_i2c_data_transfer(u8x8, 24, p); | ||||||
|  | 	arg_int-=24; | ||||||
|  | 	p+=24; | ||||||
|  |       } | ||||||
|  |       u8x8_i2c_data_transfer(u8x8, arg_int, p); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |       /* apply default i2c adr if required so that the start transfer msg can use this */ | ||||||
|  |       if ( u8x8->i2c_address == 255 ) | ||||||
|  | 	u8x8->i2c_address = 0x078; | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       /* cad transfer commands are ignored */ | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* fast version with reduced data start/stops, issue 735 */ | ||||||
|  | uint8_t u8x8_cad_ssd13xx_fast_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   static uint8_t in_transfer = 0; | ||||||
|  |   uint8_t *p; | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       /* improved version, takeover from ld7032 */ | ||||||
|  |       /* assumes, that the args of a command is not longer than 31 bytes */ | ||||||
|  |       /* speed improvement is about 4% compared to the classic version */ | ||||||
|  |       if ( in_transfer != 0 ) | ||||||
|  | 	 u8x8_byte_EndTransfer(u8x8);  | ||||||
|  |        | ||||||
|  |       u8x8_byte_StartTransfer(u8x8); | ||||||
|  |       u8x8_byte_SendByte(u8x8, 0x000);	/* cmd byte for ssd13xx controller */ | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       in_transfer = 1; | ||||||
|  |       /* lightning version: can replace the improved version from above */ | ||||||
|  |       /* the drawback of the lightning version is this: The complete init sequence */ | ||||||
|  |       /* must fit into the 32 byte Arduino Wire buffer, which might not always be the case */ | ||||||
|  |       /* speed improvement is about 6% compared to the classic version */ | ||||||
|  |       // if ( in_transfer == 0 )
 | ||||||
|  | 	// {
 | ||||||
|  | 	//   u8x8_byte_StartTransfer(u8x8);
 | ||||||
|  | 	//   u8x8_byte_SendByte(u8x8, 0x000);	/* cmd byte for ssd13xx controller */
 | ||||||
|  | 	//   in_transfer = 1;
 | ||||||
|  | 	// }
 | ||||||
|  | 	//u8x8_byte_SendByte(u8x8, arg_int);
 | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break;       | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       if ( in_transfer != 0 ) | ||||||
|  | 	u8x8_byte_EndTransfer(u8x8);  | ||||||
|  |        | ||||||
|  |      | ||||||
|  |       /* the FeatherWing OLED with the 32u4 transfer of long byte */ | ||||||
|  |       /* streams was not possible. This is broken down to */ | ||||||
|  |       /* smaller streams, 32 seems to be the limit... */ | ||||||
|  |       /* I guess this is related to the size of the Wire buffers in Arduino */ | ||||||
|  |       /* Unfortunately, this can not be handled in the byte level drivers, */ | ||||||
|  |       /* so this is done here. Even further, only 24 bytes will be sent, */ | ||||||
|  |       /* because there will be another byte (DC) required during the transfer */ | ||||||
|  |       p = arg_ptr; | ||||||
|  |        while( arg_int > 24 ) | ||||||
|  |       { | ||||||
|  | 	u8x8_i2c_data_transfer(u8x8, 24, p); | ||||||
|  | 	arg_int-=24; | ||||||
|  | 	p+=24; | ||||||
|  |       } | ||||||
|  |       u8x8_i2c_data_transfer(u8x8, arg_int, p); | ||||||
|  |       in_transfer = 0; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |       /* apply default i2c adr if required so that the start transfer msg can use this */ | ||||||
|  |       if ( u8x8->i2c_address == 255 ) | ||||||
|  | 	u8x8->i2c_address = 0x078; | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |       in_transfer = 0; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       if ( in_transfer != 0 ) | ||||||
|  | 	u8x8_byte_EndTransfer(u8x8);  | ||||||
|  |       in_transfer = 0; | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* the st75256 i2c driver is a copy of the ssd13xx driver, but with arg=1 */ | ||||||
|  | /* modified from cad001 (ssd13xx) to cad011 */ | ||||||
|  | uint8_t u8x8_cad_st75256_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   uint8_t *p; | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       u8x8_byte_StartTransfer(u8x8); | ||||||
|  |       u8x8_byte_SendByte(u8x8, 0x000); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       u8x8_byte_EndTransfer(u8x8);       | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_StartTransfer(u8x8); | ||||||
|  |       u8x8_byte_SendByte(u8x8, 0x040); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       u8x8_byte_EndTransfer(u8x8); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       /* see ssd13xx driver */ | ||||||
|  |       p = arg_ptr; | ||||||
|  |        while( arg_int > 24 ) | ||||||
|  |       { | ||||||
|  | 	u8x8_i2c_data_transfer(u8x8, 24, p); | ||||||
|  | 	arg_int-=24; | ||||||
|  | 	p+=24; | ||||||
|  |       } | ||||||
|  |       u8x8_i2c_data_transfer(u8x8, arg_int, p); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |       /* apply default i2c adr if required so that the start transfer msg can use this */ | ||||||
|  |       if ( u8x8->i2c_address == 255 ) | ||||||
|  | 	u8x8->i2c_address = 0x078;	/* ST75256, often this is 0x07e */ | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       /* cad transfer commands are ignored */ | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* cad i2c procedure for the ld7032 controller */ | ||||||
|  | /* Issue https://github.com/olikraus/u8g2/issues/865 mentiones, that I2C does not work */ | ||||||
|  | /* Workaround is to remove the while loop (or increase the value in the condition) */ | ||||||
|  | uint8_t u8x8_cad_ld7032_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   static uint8_t in_transfer = 0; | ||||||
|  |   uint8_t *p; | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |       if ( in_transfer != 0 ) | ||||||
|  | 	u8x8_byte_EndTransfer(u8x8);  | ||||||
|  |       u8x8_byte_StartTransfer(u8x8); | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       in_transfer = 1; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       //u8x8_byte_SetDC(u8x8, 1);
 | ||||||
|  |      | ||||||
|  |       /* the FeatherWing OLED with the 32u4 transfer of long byte */ | ||||||
|  |       /* streams was not possible. This is broken down to */ | ||||||
|  |       /* smaller streams, 32 seems to be the limit... */ | ||||||
|  |       /* I guess this is related to the size of the Wire buffers in Arduino */ | ||||||
|  |       /* Unfortunately, this can not be handled in the byte level drivers, */ | ||||||
|  |       /* so this is done here. Even further, only 24 bytes will be sent, */ | ||||||
|  |       /* because there will be another byte (DC) required during the transfer */ | ||||||
|  |       p = arg_ptr; | ||||||
|  |        while( arg_int > 24 ) | ||||||
|  |       { | ||||||
|  | 	u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p); | ||||||
|  | 	arg_int-=24; | ||||||
|  | 	p+=24; | ||||||
|  | 	u8x8_byte_EndTransfer(u8x8);  | ||||||
|  | 	u8x8_byte_StartTransfer(u8x8); | ||||||
|  | 	u8x8_byte_SendByte(u8x8, 0x08);	/* data write for LD7032 */ | ||||||
|  |       } | ||||||
|  |       u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |       /* apply default i2c adr if required so that the start transfer msg can use this */ | ||||||
|  |       if ( u8x8->i2c_address == 255 ) | ||||||
|  | 	u8x8->i2c_address = 0x060; | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |       in_transfer = 0; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       if ( in_transfer != 0 ) | ||||||
|  | 	u8x8_byte_EndTransfer(u8x8);  | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* cad procedure for the UC16xx family in I2C mode */ | ||||||
|  | /* u8x8_byte_SetDC is not used */ | ||||||
|  | /* DC bit is encoded into the adr byte */ | ||||||
|  | uint8_t u8x8_cad_uc16xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||||||
|  | { | ||||||
|  |   static uint8_t in_transfer = 0;	 | ||||||
|  |   static uint8_t is_data = 0; | ||||||
|  |   uint8_t *p; | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_CAD_SEND_CMD: | ||||||
|  |     case U8X8_MSG_CAD_SEND_ARG: | ||||||
|  |       if ( in_transfer != 0 ) | ||||||
|  |       { | ||||||
|  | 	if ( is_data != 0 ) | ||||||
|  | 	{ | ||||||
|  | 	  /* transfer mode is active, but data transfer */ | ||||||
|  | 	  u8x8_byte_EndTransfer(u8x8);  | ||||||
|  | 	  /* clear the lowest two bits of the adr */ | ||||||
|  | 	  u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc ); | ||||||
|  | 	  u8x8_byte_StartTransfer(u8x8);  | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  | 	/* clear the lowest two bits of the adr */ | ||||||
|  | 	u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc ); | ||||||
|  | 	u8x8_byte_StartTransfer(u8x8); | ||||||
|  |       } | ||||||
|  |       u8x8_byte_SendByte(u8x8, arg_int); | ||||||
|  |       in_transfer = 1; | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_SEND_DATA: | ||||||
|  |       if ( in_transfer != 0 ) | ||||||
|  |       { | ||||||
|  | 	if ( is_data == 0 ) | ||||||
|  | 	{ | ||||||
|  | 	  /* transfer mode is active, but data transfer */ | ||||||
|  | 	  u8x8_byte_EndTransfer(u8x8);  | ||||||
|  | 	  /* clear the lowest two bits of the adr */ | ||||||
|  | 	  u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 ); | ||||||
|  | 	  u8x8_byte_StartTransfer(u8x8);  | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  | 	/* clear the lowest two bits of the adr */ | ||||||
|  | 	u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 ); | ||||||
|  | 	u8x8_byte_StartTransfer(u8x8); | ||||||
|  |       } | ||||||
|  |       in_transfer = 1; | ||||||
|  |        | ||||||
|  |       p = arg_ptr; | ||||||
|  |       while( arg_int > 24 ) | ||||||
|  |       { | ||||||
|  | 	u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p); | ||||||
|  | 	arg_int-=24; | ||||||
|  | 	p+=24; | ||||||
|  | 	u8x8_byte_EndTransfer(u8x8);  | ||||||
|  | 	u8x8_byte_StartTransfer(u8x8); | ||||||
|  |       } | ||||||
|  |       u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p); | ||||||
|  |        | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_INIT: | ||||||
|  |       /* apply default i2c adr if required so that the start transfer msg can use this */ | ||||||
|  |       if ( u8x8->i2c_address == 255 ) | ||||||
|  | 	u8x8->i2c_address = 0x070; | ||||||
|  |       return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr); | ||||||
|  |     case U8X8_MSG_CAD_START_TRANSFER: | ||||||
|  |       in_transfer = 0;     | ||||||
|  |       /* actual start is delayed, because we do not whether this is data or cmd transfer */ | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_CAD_END_TRANSFER: | ||||||
|  |       if ( in_transfer != 0 ) | ||||||
|  | 	u8x8_byte_EndTransfer(u8x8); | ||||||
|  |       in_transfer = 0; | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
							
								
								
									
										1242
									
								
								lib/u8g2/u8x8_d_st7565.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1242
									
								
								lib/u8g2/u8x8_d_st7565.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										165
									
								
								lib/u8g2/u8x8_display.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								lib/u8g2/u8x8_display.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,165 @@ | |||||||
|  | /*
 | ||||||
|  |    | ||||||
|  |   u8x8_display.c | ||||||
|  |    | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   Abstraction layer for the graphics controller. | ||||||
|  |   Main goal is the placement of a 8x8 pixel block (tile) on the display. | ||||||
|  |    | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include "u8x8.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*==========================================*/ | ||||||
|  | /* internal library function */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   this is a helper function for the U8X8_MSG_DISPLAY_SETUP_MEMORY function. | ||||||
|  |   It can be called within the display callback function to carry out the usual standard tasks. | ||||||
|  |    | ||||||
|  | */ | ||||||
|  | void u8x8_d_helper_display_setup_memory(u8x8_t *u8x8, const u8x8_display_info_t *display_info) | ||||||
|  | { | ||||||
|  |       /* 1) set display info struct */ | ||||||
|  |       u8x8->display_info = display_info; | ||||||
|  |       u8x8->x_offset = u8x8->display_info->default_x_offset; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   this is a helper function for the U8X8_MSG_DISPLAY_INIT function. | ||||||
|  |   It can be called within the display callback function to carry out the usual standard tasks. | ||||||
|  |    | ||||||
|  | */ | ||||||
|  | void u8x8_d_helper_display_init(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |       /* 2) apply port directions to the GPIO lines and apply default values for the IO lines*/ | ||||||
|  |       u8x8_gpio_Init(u8x8); | ||||||
|  |       u8x8_cad_Init(u8x8); | ||||||
|  | 
 | ||||||
|  |       /* 3) do reset */ | ||||||
|  |       u8x8_gpio_SetReset(u8x8, 1); | ||||||
|  |       u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms); | ||||||
|  |       u8x8_gpio_SetReset(u8x8, 0); | ||||||
|  |       u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms); | ||||||
|  |       u8x8_gpio_SetReset(u8x8, 1); | ||||||
|  |       u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->post_reset_wait_ms); | ||||||
|  | }     | ||||||
|  | 
 | ||||||
|  | /*==========================================*/ | ||||||
|  | /* official functions */ | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_DrawTile(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr) | ||||||
|  | { | ||||||
|  |   u8x8_tile_t tile; | ||||||
|  |   tile.x_pos = x; | ||||||
|  |   tile.y_pos = y; | ||||||
|  |   tile.cnt = cnt; | ||||||
|  |   tile.tile_ptr = tile_ptr; | ||||||
|  |   return u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, 1, (void *)&tile); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* should be implemented as macro */ | ||||||
|  | void u8x8_SetupMemory(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SETUP_MEMORY, 0, NULL);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_InitDisplay(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable) | ||||||
|  | { | ||||||
|  |   u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_POWER_SAVE, is_enable, NULL);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode) | ||||||
|  | { | ||||||
|  |   u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, mode, NULL);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value) | ||||||
|  | { | ||||||
|  |   u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_CONTRAST, value, NULL);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_RefreshDisplay(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_REFRESH, 0, NULL);   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf) | ||||||
|  | { | ||||||
|  |   u8x8_tile_t tile; | ||||||
|  |   uint8_t h; | ||||||
|  | 
 | ||||||
|  |   tile.x_pos = 0; | ||||||
|  |   tile.cnt = 1; | ||||||
|  |   tile.tile_ptr = (uint8_t *)buf;		/* tile_ptr should be const, but isn't */ | ||||||
|  |    | ||||||
|  |   h = u8x8->display_info->tile_height; | ||||||
|  |   tile.y_pos = 0; | ||||||
|  |   do | ||||||
|  |   { | ||||||
|  |     u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile); | ||||||
|  |     tile.y_pos++; | ||||||
|  |   } while( tile.y_pos < h ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_ClearDisplay(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||||||
|  |   u8x8_ClearDisplayWithTile(u8x8, buf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_FillDisplay(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |   uint8_t buf[8] = { 255, 255, 255, 255, 255, 255, 255, 255 }; | ||||||
|  |   u8x8_ClearDisplayWithTile(u8x8, buf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void u8x8_ClearLine(u8x8_t *u8x8, uint8_t line) | ||||||
|  | { | ||||||
|  |   uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||||||
|  |   u8x8_tile_t tile; | ||||||
|  |   if ( line < u8x8->display_info->tile_height ) | ||||||
|  |   { | ||||||
|  |     tile.x_pos = 0; | ||||||
|  |     tile.y_pos = line; | ||||||
|  |     tile.cnt = 1; | ||||||
|  |     tile.tile_ptr = (uint8_t *)buf;		/* tile_ptr should be const, but isn't */ | ||||||
|  |     u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile); | ||||||
|  |   }   | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								lib/u8g2/u8x8_gpio.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								lib/u8g2/u8x8_gpio.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8x8_gpio.c | ||||||
|  |    | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include "u8x8.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void u8x8_gpio_call(u8x8_t *u8x8, uint8_t msg, uint8_t arg) | ||||||
|  | { | ||||||
|  |   u8x8->gpio_and_delay_cb(u8x8, msg, arg, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | void u8x8_gpio_Delay(u8x8_t *u8x8, uint8_t msg, uint8_t dly) | ||||||
|  | { | ||||||
|  |   u8x8->gpio_and_delay_cb(u8x8, msg, dly, NULL); | ||||||
|  | } | ||||||
|  | */ | ||||||
							
								
								
									
										147
									
								
								lib/u8g2/u8x8_setup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								lib/u8g2/u8x8_setup.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,147 @@ | |||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  |   u8x8_setup.c | ||||||
|  | 
 | ||||||
|  |   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 | ||||||
|  | 
 | ||||||
|  |   Copyright (c) 2016, olikraus@gmail.com | ||||||
|  |   All rights reserved. | ||||||
|  | 
 | ||||||
|  |   Redistribution and use in source and binary forms, with or without modification,  | ||||||
|  |   are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |   * Redistributions of source code must retain the above copyright notice, this list  | ||||||
|  |     of conditions and the following disclaimer. | ||||||
|  |      | ||||||
|  |   * 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. | ||||||
|  | 
 | ||||||
|  |   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.   | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include "u8x8.h" | ||||||
|  | 
 | ||||||
|  | /* universal dummy callback, which will be default for all callbacks */ | ||||||
|  | uint8_t u8x8_dummy_cb(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr) | ||||||
|  | { | ||||||
|  |   /* the dummy callback will not handle any message and will fail for all messages */ | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static const u8x8_display_info_t u8x8_null_display_info = | ||||||
|  | { | ||||||
|  |   /* chip_enable_level = */ 0, | ||||||
|  |   /* chip_disable_level = */ 1, | ||||||
|  |    | ||||||
|  |   /* post_chip_enable_wait_ns = */ 0, | ||||||
|  |   /* pre_chip_disable_wait_ns = */ 0, | ||||||
|  |   /* reset_pulse_width_ms = */ 0,  | ||||||
|  |   /* post_reset_wait_ms = */ 0,  | ||||||
|  |   /* sda_setup_time_ns = */ 0,		 | ||||||
|  |   /* sck_pulse_width_ns = */ 0,	/* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */ | ||||||
|  |   /* sck_clock_hz = */ 4000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */ | ||||||
|  |   /* spi_mode = */ 0,		/* active high, rising edge */ | ||||||
|  |   /* i2c_bus_clock_100kHz = */ 4, | ||||||
|  |   /* data_setup_time_ns = */ 0, | ||||||
|  |   /* write_pulse_width_ns = */ 0, | ||||||
|  |   /* tile_width = */ 1,		/* 8x8 */ | ||||||
|  |   /* tile_hight = */ 1, | ||||||
|  |   /* default_x_offset = */ 0, | ||||||
|  |   /* flipmode_x_offset = */ 0, | ||||||
|  |   /* pixel_width = */ 8, | ||||||
|  |   /* pixel_height = */ 8 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* a special null device */ | ||||||
|  | uint8_t u8x8_d_null_cb(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr) | ||||||
|  | { | ||||||
|  |   switch(msg) | ||||||
|  |   { | ||||||
|  |     case U8X8_MSG_DISPLAY_SETUP_MEMORY: | ||||||
|  |       u8x8_d_helper_display_setup_memory(u8x8, &u8x8_null_display_info); | ||||||
|  |       break; | ||||||
|  |     case U8X8_MSG_DISPLAY_INIT: | ||||||
|  |       u8x8_d_helper_display_init(u8x8); | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |   /* the null device callback will succeed for all messages */ | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Description: | ||||||
|  |     Setup u8x8 | ||||||
|  |   Args: | ||||||
|  |     u8x8	An empty u8x8 structure | ||||||
|  | */ | ||||||
|  | void u8x8_SetupDefaults(u8x8_t *u8x8) | ||||||
|  | { | ||||||
|  |     u8x8->display_info = NULL; | ||||||
|  |     u8x8->display_cb = u8x8_dummy_cb; | ||||||
|  |     u8x8->cad_cb = u8x8_dummy_cb; | ||||||
|  |     u8x8->byte_cb = u8x8_dummy_cb; | ||||||
|  |     u8x8->gpio_and_delay_cb = u8x8_dummy_cb; | ||||||
|  |     u8x8->is_font_inverse_mode = 0; | ||||||
|  |     //u8x8->device_address = 0;
 | ||||||
|  |     u8x8->utf8_state = 0;		/* also reset by u8x8_utf8_init */ | ||||||
|  |     u8x8->bus_clock = 0;		/* issue 769 */ | ||||||
|  |     u8x8->i2c_address = 255; | ||||||
|  |     u8x8->debounce_default_pin_state = 255;	/* assume all low active buttons */ | ||||||
|  |    | ||||||
|  | #ifdef U8X8_USE_PINS  | ||||||
|  |   { | ||||||
|  |     uint8_t i; | ||||||
|  |     for( i = 0; i < U8X8_PIN_CNT; i++ ) | ||||||
|  |       u8x8->pins[i] = U8X8_PIN_NONE; | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Description: | ||||||
|  |     Setup u8x8 and assign the callback function. The dummy  | ||||||
|  |     callback "u8x8_dummy_cb" can be used, if no callback is required. | ||||||
|  |     This setup will not communicate with the display itself. | ||||||
|  |     Use u8x8_InitDisplay() to send the startup code to the Display. | ||||||
|  |   Args: | ||||||
|  |     u8x8				An empty u8x8 structure | ||||||
|  |     display_cb			Display/controller specific callback function | ||||||
|  |     cad_cb				Display controller specific communication callback function | ||||||
|  |     byte_cb			Display controller/communication specific callback funtion | ||||||
|  |     gpio_and_delay_cb	Environment specific callback function | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | void u8x8_Setup(u8x8_t *u8x8, u8x8_msg_cb display_cb, u8x8_msg_cb cad_cb, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) | ||||||
|  | { | ||||||
|  |   /* setup defaults and reset pins to U8X8_PIN_NONE */ | ||||||
|  |   u8x8_SetupDefaults(u8x8); | ||||||
|  | 
 | ||||||
|  |   /* setup specific callbacks */ | ||||||
|  |   u8x8->display_cb = display_cb; | ||||||
|  |   u8x8->cad_cb = cad_cb; | ||||||
|  |   u8x8->byte_cb = byte_cb; | ||||||
|  |   u8x8->gpio_and_delay_cb = gpio_and_delay_cb; | ||||||
|  | 
 | ||||||
|  |   /* setup display info */ | ||||||
|  |   u8x8_SetupMemory(u8x8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										106
									
								
								lib/u8g2_vendor/u8g2_vendor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								lib/u8g2_vendor/u8g2_vendor.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | |||||||
|  | #include "u8g2_support.h" | ||||||
|  | #include "main.h" | ||||||
|  | #include "cmsis_os.h" | ||||||
|  | #include "gpio.h" | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | extern SPI_HandleTypeDef hspi1; | ||||||
|  | 
 | ||||||
|  | // #define DEBUG 1
 | ||||||
|  | 
 | ||||||
|  | uint8_t u8g2_gpio_and_delay_stm32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { | ||||||
|  |     switch(msg){ | ||||||
|  |         //Initialize SPI peripheral
 | ||||||
|  |         case U8X8_MSG_GPIO_AND_DELAY_INIT: | ||||||
|  |             /* HAL initialization contains all what we need so we can skip this part. */ | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         //Function which implements a delay, arg_int contains the amount of ms
 | ||||||
|  |         case U8X8_MSG_DELAY_MILLI: | ||||||
|  |             osDelay(arg_int); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         //Function which delays 10us
 | ||||||
|  |         case U8X8_MSG_DELAY_10MICRO: | ||||||
|  |             delay_us(10); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         //Function which delays 100ns
 | ||||||
|  |         case U8X8_MSG_DELAY_100NANO: | ||||||
|  |             asm("nop"); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         //Function to define the logic level of the RESET line
 | ||||||
|  |         case U8X8_MSG_GPIO_RESET: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 printf("[u8g2] rst %d\n", arg_int); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_RST_GPIO_Port, DISPLAY_RST_Pin, arg_int ? GPIO_PIN_SET : GPIO_PIN_RESET); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         default: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 printf("[u8g2] unknown io %d\n", msg); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             return 0; //A message was received which is not implemented, return 0 to indicate an error
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 1; // command processed successfully.
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t u8x8_hw_spi_stm32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr){ | ||||||
|  |     switch (msg) { | ||||||
|  |         case U8X8_MSG_BYTE_SEND: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 printf("[u8g2] send %d bytes %02X\n", arg_int, ((uint8_t*)arg_ptr)[0]); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             HAL_SPI_Transmit(&hspi1, (uint8_t *)arg_ptr, arg_int, 10000); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case U8X8_MSG_BYTE_SET_DC: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 printf("[u8g2] dc %d\n", arg_int); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_DI_GPIO_Port, DISPLAY_DI_Pin, arg_int ? GPIO_PIN_SET : GPIO_PIN_RESET); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case U8X8_MSG_BYTE_INIT: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 printf("[u8g2] init\n"); | ||||||
|  |             #endif | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_RESET); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case U8X8_MSG_BYTE_START_TRANSFER: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 printf("[u8g2] start\n"); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_RESET); | ||||||
|  |             asm("nop"); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case U8X8_MSG_BYTE_END_TRANSFER: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 printf("[u8g2] end\n"); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             asm("nop"); | ||||||
|  |             HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_SET); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         default: | ||||||
|  |             #ifdef DEBUG | ||||||
|  |                 printf("[u8g2] unknown xfer %d\n", msg); | ||||||
|  |             #endif | ||||||
|  | 
 | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								lib/u8g2_vendor/u8g2_vendor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								lib/u8g2_vendor/u8g2_vendor.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | #include "u8g2/u8g2.h" | ||||||
|  | 
 | ||||||
|  | uint8_t u8g2_gpio_and_delay_stm32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); | ||||||
|  | uint8_t u8x8_hw_spi_stm32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); | ||||||
							
								
								
									
										589
									
								
								lib/ui/ui.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										589
									
								
								lib/ui/ui.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,589 @@ | |||||||
|  | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | extern "C" { | ||||||
|  |     #include "main.h" | ||||||
|  |     #include "cmsis_os.h" | ||||||
|  |     #include "u8g2_support.h" | ||||||
|  |     #include "u8g2/u8g2.h" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #include "ui.h" | ||||||
|  | #include "events.h" | ||||||
|  | 
 | ||||||
|  | // function draw basic layout -- single bmp
 | ||||||
|  | void draw_bitmap(const char* bitmap, u8g2_t* u8g2, ScreenArea area) { | ||||||
|  |     if(bitmap == NULL) { | ||||||
|  |         printf("[basic layout] no content\n"); | ||||||
|  |         u8g2_SetFont(u8g2, u8g2_font_6x10_mf); | ||||||
|  |         u8g2_SetDrawColor(u8g2, 1); | ||||||
|  |         u8g2_SetFontMode(u8g2, 1); | ||||||
|  |         u8g2_DrawStr(u8g2, 2, 12, "no content"); | ||||||
|  |     } else { | ||||||
|  |         u8g2_SetDrawColor(u8g2, 1); | ||||||
|  |         u8g2_DrawXBM(u8g2, 0, 0, area.x + area.width, area.y + area.height, (unsigned char*)bitmap); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void draw_text(const char* text, u8g2_t* u8g2, ScreenArea area) { | ||||||
|  |     // TODO proper cleanup statusbar
 | ||||||
|  |     u8g2_SetDrawColor(u8g2, 0); | ||||||
|  |     u8g2_DrawBox(u8g2, 0, 0, area.x + area.width, area.y + area.height); | ||||||
|  | 
 | ||||||
|  |     Block text_block = Block { | ||||||
|  |         width: area.width, | ||||||
|  |         height: area.height, | ||||||
|  |         margin_left: 0, | ||||||
|  |         margin_top: 0, | ||||||
|  |         padding_left: 3, | ||||||
|  |         padding_top: 7, | ||||||
|  |         background: 0, | ||||||
|  |         color: 1, | ||||||
|  |         font: (uint8_t*)u8g2_font_6x10_mf, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     draw_block(u8g2, text, text_block, area.x, area.y); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // draw layout and switch between ui item by button and timer
 | ||||||
|  | void LayoutComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) { | ||||||
|  |     switch(event->type) { | ||||||
|  |         // get button event
 | ||||||
|  |         case EventTypeButton: | ||||||
|  |             if(event->value.button.state) { | ||||||
|  |                 for(size_t i = 0; i < this->actions_size; i++) { | ||||||
|  |                     FlipperComponent* next = NULL; | ||||||
|  | 
 | ||||||
|  |                     switch(this->actions[i].action) { | ||||||
|  |                         case LayoutActionUp: | ||||||
|  |                             if(event->value.button.id == ButtonsUp) { | ||||||
|  |                                 next = this->actions[i].item; | ||||||
|  |                             } | ||||||
|  |                         break; | ||||||
|  |                         case LayoutActionDown: | ||||||
|  |                             if(event->value.button.id == ButtonsDown) { | ||||||
|  |                                 next = this->actions[i].item; | ||||||
|  |                             } | ||||||
|  |                         break; | ||||||
|  |                         case LayoutActionLeft: | ||||||
|  |                             if(event->value.button.id == ButtonsLeft) { | ||||||
|  |                                 next = this->actions[i].item; | ||||||
|  |                             } | ||||||
|  |                         break; | ||||||
|  |                         case LayoutActionRight: | ||||||
|  |                             if(event->value.button.id == ButtonsRight) { | ||||||
|  |                                 next = this->actions[i].item; | ||||||
|  |                             } | ||||||
|  |                         break; | ||||||
|  |                         case LayoutActionOk: | ||||||
|  |                             if(event->value.button.id == ButtonsOk) { | ||||||
|  |                                 next = this->actions[i].item; | ||||||
|  |                             } | ||||||
|  |                         break; | ||||||
|  |                         case LayoutActionBack: | ||||||
|  |                             if(event->value.button.id == ButtonsBack) { | ||||||
|  |                                 next = this->actions[i].item; | ||||||
|  |                             } | ||||||
|  |                         break; | ||||||
|  | 
 | ||||||
|  |                         // stub action
 | ||||||
|  |                         case LayoutActionUsbDisconnect: | ||||||
|  |                             if(event->value.button.id == ButtonsLeft) { | ||||||
|  |                                 next = this->actions[i].item; | ||||||
|  |                             } | ||||||
|  |                         break; | ||||||
|  | 
 | ||||||
|  |                         case LayoutActionUsbConnect: | ||||||
|  |                             if(event->value.button.id == ButtonsRight) { | ||||||
|  |                                 next = this->actions[i].item; | ||||||
|  |                             } | ||||||
|  |                         break; | ||||||
|  | 
 | ||||||
|  |                         default: break; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if(next) { | ||||||
|  |                         printf("[layout view] go to next item\n"); | ||||||
|  |                         Event send_event; | ||||||
|  |                         send_event.type = EventTypeUiNext; | ||||||
|  |                         next->handle( | ||||||
|  |                             &send_event, | ||||||
|  |                             store, | ||||||
|  |                             u8g2, | ||||||
|  |                             area | ||||||
|  |                         ); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case EventTypeUsb: { | ||||||
|  |             printf("get usb event\n"); | ||||||
|  |              | ||||||
|  |             FlipperComponent* next = NULL; | ||||||
|  | 
 | ||||||
|  |             if(event->value.usb == UsbEventConnect) { | ||||||
|  |                 for(size_t i = 0; i < this->actions_size; i++) { | ||||||
|  |                     if(this->actions[i].action == LayoutActionUsbConnect) { | ||||||
|  |                         next = this->actions[i].item; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(event->value.usb == UsbEventDisconnect) { | ||||||
|  |                 for(size_t i = 0; i < this->actions_size; i++) { | ||||||
|  |                     if(this->actions[i].action == LayoutActionUsbDisconnect) { | ||||||
|  |                         next = this->actions[i].item; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(next) { | ||||||
|  |                 printf("[layout view] go to next item\n"); | ||||||
|  |                 Event send_event; | ||||||
|  |                 send_event.type = EventTypeUiNext; | ||||||
|  |                 next->handle( | ||||||
|  |                     &send_event, | ||||||
|  |                     store, | ||||||
|  |                     u8g2, | ||||||
|  |                     area | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } break; | ||||||
|  | 
 | ||||||
|  |         // start component from prev
 | ||||||
|  |         case EventTypeUiNext: | ||||||
|  |             printf("[layout view] start component %lX\n", (uint32_t)this); | ||||||
|  | 
 | ||||||
|  |             if(this->timeout > 0) { | ||||||
|  |                 // TODO start timer
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // set current item to self
 | ||||||
|  |             store->current_component = this; | ||||||
|  | 
 | ||||||
|  |             this->wait_time = 0; | ||||||
|  | 
 | ||||||
|  |             // render layout
 | ||||||
|  |             this->dirty = true; | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case EventTypeTick: | ||||||
|  |             this->wait_time += event->value.tick_delta; | ||||||
|  | 
 | ||||||
|  |             if(this->wait_time > this->timeout) { | ||||||
|  |                 for(size_t i = 0; i < this->actions_size; i++) { | ||||||
|  |                     if(this->actions[i].action == LayoutActionTimeout || | ||||||
|  |                         this->actions[i].action == LayoutActionEndOfCycle | ||||||
|  |                     ) { | ||||||
|  |                         if(this->actions[i].item != NULL) { | ||||||
|  |                             printf("[layout view] go to next item\n"); | ||||||
|  |                             Event send_event; | ||||||
|  |                             send_event.type = EventTypeUiNext; | ||||||
|  |                             this->actions[i].item->handle( | ||||||
|  |                                 &send_event, | ||||||
|  |                                 store, | ||||||
|  |                                 u8g2, | ||||||
|  |                                 area | ||||||
|  |                             ); | ||||||
|  | 
 | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(this->dirty) { | ||||||
|  |                 this->draw_fn(this->data, u8g2, area); | ||||||
|  | 
 | ||||||
|  |                 store->dirty_screen = true; | ||||||
|  | 
 | ||||||
|  |                 this->dirty = false; | ||||||
|  |             } | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         default: break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void BlinkerComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) { | ||||||
|  |     switch(event->type) { | ||||||
|  |         // get button event
 | ||||||
|  |         case EventTypeButton: | ||||||
|  |             if(event->value.button.state && event->value.button.id == ButtonsBack) { | ||||||
|  |                 if(this->prev && this->prev != this) { | ||||||
|  |                     printf("[blinker view] go back\n"); | ||||||
|  | 
 | ||||||
|  |                     Event send_event; | ||||||
|  |                     send_event.type = EventTypeUiNext; | ||||||
|  |                     this->prev->handle( | ||||||
|  |                         &send_event, | ||||||
|  |                         store, | ||||||
|  |                         u8g2, | ||||||
|  |                         area | ||||||
|  |                     ); | ||||||
|  | 
 | ||||||
|  |                     this->prev = NULL; | ||||||
|  | 
 | ||||||
|  |                     store->led = ColorBlack; | ||||||
|  |                     this->wait_time = 0; | ||||||
|  |                     this->is_on = true; | ||||||
|  |                     this->active = false; | ||||||
|  |                 } else { | ||||||
|  |                     printf("[blinker view] no back/loop\n"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(event->value.button.state && event->value.button.id != ButtonsBack) { | ||||||
|  |                 this->active = false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(!event->value.button.state && event->value.button.id != ButtonsBack) { | ||||||
|  |                 this->active = true; | ||||||
|  |             } | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         // start component from prev
 | ||||||
|  |         case EventTypeUiNext: | ||||||
|  |             printf("[blinker view] start component %lX\n", (uint32_t)this); | ||||||
|  | 
 | ||||||
|  |             if(this->prev == NULL) { | ||||||
|  |                 this->prev = store->current_component; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // set current item to self
 | ||||||
|  |             store->current_component = this; | ||||||
|  | 
 | ||||||
|  |             this->dirty = true; | ||||||
|  |             this->wait_time = 0; | ||||||
|  |             this->is_on = true; | ||||||
|  |             this->active = false; | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case EventTypeTick: | ||||||
|  |             if(this->active) { | ||||||
|  |                 this->wait_time += event->value.tick_delta; | ||||||
|  | 
 | ||||||
|  |                 if(this->is_on) { | ||||||
|  |                     if(this->wait_time > this->config.on_time) { | ||||||
|  |                         this->wait_time = 0; | ||||||
|  |                         this->is_on = false; | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     if(this->wait_time > this->config.off_time) { | ||||||
|  |                         this->wait_time = 0; | ||||||
|  |                         this->is_on = true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 store->led = this->is_on ? this->config.on_color : this->config.off_color; | ||||||
|  |             } else { | ||||||
|  |                 store->led = ColorBlack; | ||||||
|  |                 this->wait_time = 0; | ||||||
|  |                 this->is_on = true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(this->dirty) { | ||||||
|  |                 this->draw_fn(this->data, u8g2, area); | ||||||
|  | 
 | ||||||
|  |                 store->dirty_screen = true; | ||||||
|  | 
 | ||||||
|  |                 this->dirty = false; | ||||||
|  |             } | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         default: break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | void BlinkerComponentOnBtn::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) { | ||||||
|  |     switch(event->type) { | ||||||
|  |         // get button event
 | ||||||
|  |         case EventTypeButton: | ||||||
|  |             if(event->value.button.state && event->value.button.id == ButtonsBack) { | ||||||
|  |                 if(this->prev && this->prev != this) { | ||||||
|  |                     printf("[blinker view] go back\n"); | ||||||
|  | 
 | ||||||
|  |                     Event send_event; | ||||||
|  |                     send_event.type = EventTypeUiNext; | ||||||
|  |                     this->prev->handle( | ||||||
|  |                         &send_event, | ||||||
|  |                         store, | ||||||
|  |                         u8g2, | ||||||
|  |                         area | ||||||
|  |                     ); | ||||||
|  | 
 | ||||||
|  |                     this->prev = NULL; | ||||||
|  | 
 | ||||||
|  |                     store->led = ColorBlack; | ||||||
|  |                     this->wait_time = 0; | ||||||
|  |                     this->is_on = true; | ||||||
|  |                     this->active = false; | ||||||
|  |                 } else { | ||||||
|  |                     printf("[blinker view] no back/loop\n"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(event->value.button.state && event->value.button.id != ButtonsBack) { | ||||||
|  |                 this->active = true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(!event->value.button.state && event->value.button.id != ButtonsBack) { | ||||||
|  |                 this->active = false; | ||||||
|  |             } | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         // start component from prev
 | ||||||
|  |         case EventTypeUiNext: | ||||||
|  |             printf("[blinker view] start component %lX\n", (uint32_t)this); | ||||||
|  | 
 | ||||||
|  |             if(this->prev == NULL) { | ||||||
|  |                 this->prev = store->current_component; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // set current item to self
 | ||||||
|  |             store->current_component = this; | ||||||
|  | 
 | ||||||
|  |             this->dirty = true; | ||||||
|  |             this->wait_time = 0; | ||||||
|  |             this->is_on = true; | ||||||
|  |             this->active = false; | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case EventTypeTick: | ||||||
|  |             if(this->active) { | ||||||
|  |                 this->wait_time += event->value.tick_delta; | ||||||
|  | 
 | ||||||
|  |                 if(this->is_on) { | ||||||
|  |                     if(this->wait_time > this->config.on_time) { | ||||||
|  |                         this->wait_time = 0; | ||||||
|  |                         this->is_on = false; | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     if(this->wait_time > this->config.off_time) { | ||||||
|  |                         this->wait_time = 0; | ||||||
|  |                         this->is_on = true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 store->led = this->is_on ? this->config.on_color : this->config.off_color; | ||||||
|  |             } else { | ||||||
|  |                 store->led = ColorBlack; | ||||||
|  |                 this->wait_time = 0; | ||||||
|  |                 this->is_on = true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(this->dirty) { | ||||||
|  |                 this->draw_fn(this->data, u8g2, area); | ||||||
|  | 
 | ||||||
|  |                 store->dirty_screen = true; | ||||||
|  | 
 | ||||||
|  |                 this->dirty = false; | ||||||
|  |             } | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         default: break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define MENU_DRAW_LINES 4 | ||||||
|  | 
 | ||||||
|  | Point draw_block(u8g2_t* u8g2, const char* text, Block layout, uint8_t x, uint8_t y) { | ||||||
|  |     u8g2_SetDrawColor(u8g2, layout.background); | ||||||
|  |     u8g2_DrawBox(u8g2, | ||||||
|  |         x + layout.margin_left, | ||||||
|  |         y + layout.margin_top, | ||||||
|  |         layout.width, layout.height | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     u8g2_SetDrawColor(u8g2, layout.color); | ||||||
|  |     u8g2_SetFont(u8g2, layout.font); | ||||||
|  |     if(text != NULL) { | ||||||
|  |         u8g2_DrawStr(u8g2, | ||||||
|  |             x + layout.margin_left + layout.padding_left, | ||||||
|  |             y + layout.margin_top + layout.padding_top, | ||||||
|  |             text | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return { | ||||||
|  |         x: x + layout.margin_left + layout.width, | ||||||
|  |         y: y + layout.margin_top + layout.height | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void draw_menu(MenuCtx* ctx, u8g2_t* u8g2, ScreenArea area) { | ||||||
|  |     // u8g2_ClearBuffer(u8g2);
 | ||||||
|  |     // clear area
 | ||||||
|  |     u8g2_SetDrawColor(u8g2, 0); | ||||||
|  |     u8g2_DrawBox(u8g2, area.x, area.y, area.width, area.height); | ||||||
|  | 
 | ||||||
|  |     u8g2_SetFontMode(u8g2, 1); | ||||||
|  | 
 | ||||||
|  |     uint8_t list_start = ctx->current - ctx->cursor; | ||||||
|  |     uint8_t list_size = ctx->size > MENU_DRAW_LINES ? MENU_DRAW_LINES : ctx->size; | ||||||
|  | 
 | ||||||
|  |     // draw header
 | ||||||
|  |     /*
 | ||||||
|  |     Point next = draw_block(u8g2, (const char*)data->name, Block { | ||||||
|  |         width: 128, | ||||||
|  |         height: 14, | ||||||
|  |         margin_left: 0, | ||||||
|  |         margin_top: 0, | ||||||
|  |         padding_left: 4, | ||||||
|  |         padding_top: 13, | ||||||
|  |         background: 1, | ||||||
|  |         color: 0, | ||||||
|  |         font: (uint8_t*)u8g2_font_helvB14_tf, | ||||||
|  |     }, area.x, area.y); | ||||||
|  |     */ | ||||||
|  | 
 | ||||||
|  |     Point next = {area.x, area.y}; | ||||||
|  | 
 | ||||||
|  |     for(size_t i = 0; i < list_size; i++) { | ||||||
|  |         next = draw_block(u8g2, (const char*)ctx->list[list_start + i].name, Block { | ||||||
|  |             width: 128, | ||||||
|  |             height: 15, | ||||||
|  |             margin_left: 0, | ||||||
|  |             margin_top: i == 0 ? 2 : 0, | ||||||
|  |             padding_left: 2, | ||||||
|  |             padding_top: 12, | ||||||
|  |             background: i == ctx->cursor ? 1 : 0, | ||||||
|  |             color: i == ctx->cursor ? 0 : 1, | ||||||
|  |             font: (uint8_t*)u8g2_font_7x14_tf, | ||||||
|  |         }, area.x, next.y); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // u8g2_font_7x14_tf
 | ||||||
|  |     // u8g2_font_profont12_tf smallerbut cute
 | ||||||
|  |     // u8g2_font_samim_12_t_all орочий
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void MenuCtx::handle(MenuEvent event) { | ||||||
|  |     uint8_t menu_size = this->size > MENU_DRAW_LINES ? MENU_DRAW_LINES : this->size; | ||||||
|  | 
 | ||||||
|  |     switch(event) { | ||||||
|  |         case MenuEventDown: { | ||||||
|  |             if(this->current < (this->size - 1)) { | ||||||
|  |                 this->current++; | ||||||
|  | 
 | ||||||
|  |                 if(this->cursor < menu_size - 2 || this->current == this->size - 1) { | ||||||
|  |                     this->cursor++; | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 this->current = 0; | ||||||
|  |                 this->cursor = 0; | ||||||
|  |             } | ||||||
|  |         } break; | ||||||
|  | 
 | ||||||
|  |         case MenuEventUp: { | ||||||
|  |             if(this->current > 0) { | ||||||
|  |                 this->current--; | ||||||
|  | 
 | ||||||
|  |                 if(this->cursor > 1 || this->current == 0) { | ||||||
|  |                     this->cursor--; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } else { | ||||||
|  |                 this->current = this->size - 1; | ||||||
|  |                 this->cursor = menu_size - 1; | ||||||
|  |             } | ||||||
|  |         } break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void MenuCtx::reset() { | ||||||
|  |     this->current = 0; | ||||||
|  |     this->cursor = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // draw numenu and handle navigation
 | ||||||
|  | void MenuComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) { | ||||||
|  |     switch(event->type) { | ||||||
|  |         // get button event
 | ||||||
|  |         case EventTypeButton: { | ||||||
|  |             if(event->value.button.id == ButtonsOk && event->value.button.state) { | ||||||
|  |                 if(this->ctx.current < this->ctx.size) { | ||||||
|  |                     FlipperComponent* next_item = (FlipperComponent*)this->ctx.list[this->ctx.current].item; | ||||||
|  | 
 | ||||||
|  |                     if(next_item) { | ||||||
|  |                         store->is_fullscreen = false; | ||||||
|  | 
 | ||||||
|  |                         printf("[layout view] go to %d item\n", this->ctx.current); | ||||||
|  |                         Event send_event; | ||||||
|  |                         send_event.type = EventTypeUiNext; | ||||||
|  | 
 | ||||||
|  |                         next_item->handle( | ||||||
|  |                             &send_event, | ||||||
|  |                             store, | ||||||
|  |                             u8g2, | ||||||
|  |                             area | ||||||
|  |                         ); | ||||||
|  |                     } else { | ||||||
|  |                         printf("[menu view] no item at %d\n", this->ctx.current); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(event->value.button.id == ButtonsDown && event->value.button.state) { | ||||||
|  |                 this->ctx.handle(MenuEventDown); | ||||||
|  |                 this->dirty = true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(event->value.button.id == ButtonsUp && event->value.button.state) { | ||||||
|  |                 this->ctx.handle(MenuEventUp); | ||||||
|  |                 this->dirty = true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // go back item
 | ||||||
|  |             if(event->value.button.id == ButtonsBack && event->value.button.state) { | ||||||
|  |                 if(this->prev && this->prev != this) { | ||||||
|  |                     store->is_fullscreen = false; | ||||||
|  | 
 | ||||||
|  |                     printf("[menu view] go back\n"); | ||||||
|  | 
 | ||||||
|  |                     this->ctx.reset(); | ||||||
|  | 
 | ||||||
|  |                     Event send_event; | ||||||
|  |                     send_event.type = EventTypeUiNext; | ||||||
|  |                     this->prev->handle( | ||||||
|  |                         &send_event, | ||||||
|  |                         store, | ||||||
|  |                         u8g2, | ||||||
|  |                         area | ||||||
|  |                     ); | ||||||
|  | 
 | ||||||
|  |                     this->prev = NULL; | ||||||
|  |                 } else { | ||||||
|  |                     printf("[menu view] no back/loop\n"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } break; | ||||||
|  | 
 | ||||||
|  |         // start component from prev
 | ||||||
|  |         case EventTypeUiNext: | ||||||
|  |             printf("[menu view] start component %lX (size %d)\n", (uint32_t)this, this->ctx.size); | ||||||
|  | 
 | ||||||
|  |             // set prev item
 | ||||||
|  |             if(this->prev == NULL) { | ||||||
|  |                 printf("[menu view] set prev element to %lX\n", (uint32_t)store->current_component); | ||||||
|  |                 this->prev = store->current_component; | ||||||
|  |             } | ||||||
|  |             // set current item to self
 | ||||||
|  |             store->current_component = this; | ||||||
|  | 
 | ||||||
|  |             store->is_fullscreen = true; | ||||||
|  | 
 | ||||||
|  |             // render menu
 | ||||||
|  |             this->dirty = true; | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         case EventTypeTick: | ||||||
|  |             if(this->dirty) { | ||||||
|  |                 draw_menu(&this->ctx, u8g2, area); | ||||||
|  |                 store->dirty_screen = true; | ||||||
|  |                 this->dirty = false; | ||||||
|  |             } | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |         default: break; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										218
									
								
								lib/ui/ui.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								lib/ui/ui.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,218 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | extern "C" { | ||||||
|  |     #include "main.h" | ||||||
|  |     #include "cmsis_os.h" | ||||||
|  |     #include "u8g2_support.h" | ||||||
|  |     #include "u8g2/u8g2.h" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #include "events.h" | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     void* item; | ||||||
|  |     const char* name; | ||||||
|  | } MenuItem; | ||||||
|  | 
 | ||||||
|  | #include "vendor.h" | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     LayoutActionUp, | ||||||
|  |     LayoutActionDown, | ||||||
|  |     LayoutActionLeft, | ||||||
|  |     LayoutActionRight, | ||||||
|  |     LayoutActionOk, | ||||||
|  |     LayoutActionBack, | ||||||
|  |     LayoutActionTimeout, | ||||||
|  |     LayoutActionUsbConnect, | ||||||
|  |     LayoutActionUsbDisconnect, | ||||||
|  |     LayoutActionEndOfCycle | ||||||
|  | } LayoutAction; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     FlipperComponent* item; | ||||||
|  |     LayoutAction action; | ||||||
|  | } ActionItem; | ||||||
|  | 
 | ||||||
|  | void draw_text(const char* text, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | void draw_bitmap(const char* bitmap, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | 
 | ||||||
|  | class LayoutComponent: FlipperComponent { | ||||||
|  | public: | ||||||
|  |     LayoutComponent(void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area), ActionItem* actions, size_t actions_size, uint32_t timeout, const char* data) { | ||||||
|  |         this->data = data; | ||||||
|  |         this->actions = actions; | ||||||
|  |         this->actions_size = actions_size; | ||||||
|  |         this->timeout = timeout; | ||||||
|  |         this->draw_fn = draw_fn; | ||||||
|  | 
 | ||||||
|  |         this->dirty = true; | ||||||
|  | 
 | ||||||
|  |         this->wait_time = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     const char* data; | ||||||
|  |     ActionItem* actions; | ||||||
|  |     size_t actions_size; | ||||||
|  |     uint32_t timeout; | ||||||
|  | 
 | ||||||
|  |     void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | 
 | ||||||
|  |     uint32_t wait_time; | ||||||
|  | 
 | ||||||
|  |     bool dirty; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint32_t on_time; | ||||||
|  |     Color on_color; | ||||||
|  |     uint32_t off_time; | ||||||
|  |     Color off_color; | ||||||
|  | } BlinkerComponentConfig; | ||||||
|  | 
 | ||||||
|  | class BlinkerComponent: FlipperComponent { | ||||||
|  | public: | ||||||
|  |     BlinkerComponent( | ||||||
|  |         void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area), | ||||||
|  |         BlinkerComponentConfig config, | ||||||
|  |         const char* data | ||||||
|  |     ) { | ||||||
|  |         this->data = data; | ||||||
|  |         this->draw_fn = draw_fn; | ||||||
|  |         this->config = config; | ||||||
|  | 
 | ||||||
|  |         this->dirty = true; | ||||||
|  | 
 | ||||||
|  |         this->wait_time = 0; | ||||||
|  |         this->is_on = true; | ||||||
|  |         this->active = false; | ||||||
|  |         this->prev = NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     const char* data; | ||||||
|  |     BlinkerComponentConfig config; | ||||||
|  | 
 | ||||||
|  |     void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | 
 | ||||||
|  |     uint32_t wait_time; | ||||||
|  | 
 | ||||||
|  |     bool is_on; | ||||||
|  |     bool active; | ||||||
|  | 
 | ||||||
|  |     bool dirty; | ||||||
|  |     FlipperComponent* prev; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint32_t on_time; | ||||||
|  |     Color on_color; | ||||||
|  |     uint32_t off_time; | ||||||
|  |     Color off_color; | ||||||
|  | } BlinkerComponentOnBtnConfig; | ||||||
|  | 
 | ||||||
|  | class BlinkerComponentOnBtn: FlipperComponent { | ||||||
|  | public: | ||||||
|  |     BlinkerComponentOnBtn( | ||||||
|  |         void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area), | ||||||
|  |         BlinkerComponentOnBtnConfig config, | ||||||
|  |         const char* data | ||||||
|  |     ) { | ||||||
|  |         this->data = data; | ||||||
|  |         this->draw_fn = draw_fn; | ||||||
|  |         this->config = config; | ||||||
|  | 
 | ||||||
|  |         this->dirty = true; | ||||||
|  | 
 | ||||||
|  |         this->wait_time = 0; | ||||||
|  |         this->is_on = true; | ||||||
|  |         this->active = false; | ||||||
|  |         this->prev = NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     const char* data; | ||||||
|  |     BlinkerComponentOnBtnConfig config; | ||||||
|  | 
 | ||||||
|  |     void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | 
 | ||||||
|  |     uint32_t wait_time; | ||||||
|  | 
 | ||||||
|  |     bool is_on; | ||||||
|  |     bool active; | ||||||
|  | 
 | ||||||
|  |     bool dirty; | ||||||
|  |     FlipperComponent* prev; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     MenuEventUp, | ||||||
|  |     MenuEventDown | ||||||
|  | } MenuEvent; | ||||||
|  | 
 | ||||||
|  | class MenuCtx { | ||||||
|  | public: | ||||||
|  |     size_t size; | ||||||
|  |     size_t current; | ||||||
|  |     uint8_t cursor; | ||||||
|  |     MenuItem* list; | ||||||
|  | 
 | ||||||
|  |     void handle(MenuEvent event); | ||||||
|  |     void reset(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void draw_menu(MenuCtx* ctx, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | 
 | ||||||
|  | class MenuComponent: FlipperComponent { | ||||||
|  | public: | ||||||
|  |     MenuComponent(MenuItem* list, size_t size, const char* name) { | ||||||
|  |         this->ctx.size = size; | ||||||
|  |         this->ctx.current = 0; | ||||||
|  |         this->ctx.cursor = 0; | ||||||
|  | 
 | ||||||
|  |         this->ctx.list = list; | ||||||
|  |          | ||||||
|  |         this->name = name; | ||||||
|  |         this->prev = NULL; | ||||||
|  | 
 | ||||||
|  |         this->dirty = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     const char* name; | ||||||
|  |     FlipperComponent* prev; | ||||||
|  |     MenuCtx ctx; | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  |     bool dirty; | ||||||
|  | 
 | ||||||
|  |     virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t x; | ||||||
|  |     uint8_t y; | ||||||
|  | } Point; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t width; | ||||||
|  |     uint8_t height; | ||||||
|  |     uint8_t margin_left; | ||||||
|  |     uint8_t margin_top; | ||||||
|  |     uint8_t padding_left; | ||||||
|  |     uint8_t padding_top; | ||||||
|  |     uint8_t background; | ||||||
|  |     uint8_t color; | ||||||
|  |     uint8_t* font; | ||||||
|  | } Block; | ||||||
|  | 
 | ||||||
|  | Point draw_block(u8g2_t* u8g2, const char* text, Block layout, uint8_t x, uint8_t y); | ||||||
| @ -116,8 +116,35 @@ C_SOURCES += ../core/tty_uart.c | |||||||
| C_SOURCES += ../core/furi.c | C_SOURCES += ../core/furi.c | ||||||
| C_SOURCES += ../core/furi_ac.c | C_SOURCES += ../core/furi_ac.c | ||||||
| 
 | 
 | ||||||
|  | C_SOURCES += ../lib/u8g2/u8x8_d_st7565.c \
 | ||||||
|  | ../lib/u8g2/u8g2_d_setup.c \ | ||||||
|  | ../lib/u8g2/u8g2_intersection.c \ | ||||||
|  | ../lib/u8g2/u8g2_setup.c \ | ||||||
|  | ../lib/u8g2/u8g2_d_memory.c \ | ||||||
|  | ../lib/u8g2/u8x8_cad.c \ | ||||||
|  | ../lib/u8g2/u8x8_byte.c \ | ||||||
|  | ../lib/u8g2/u8x8_gpio.c \ | ||||||
|  | ../lib/u8g2/u8x8_display.c \ | ||||||
|  | ../lib/u8g2/u8x8_setup.c \ | ||||||
|  | ../lib/u8g2/u8g2_hvline.c \ | ||||||
|  | ../lib/u8g2/u8g2_ll_hvline.c \ | ||||||
|  | ../lib/u8g2/u8g2_circle.c \ | ||||||
|  | ../lib/u8g2/u8g2_box.c \ | ||||||
|  | ../lib/u8g2/u8g2_buffer.c \ | ||||||
|  | ../lib/u8g2/u8g2_font.c \ | ||||||
|  | ../lib/u8g2/u8g2_fonts.c \ | ||||||
|  | ../lib/u8g2/u8x8_8x8.c \ | ||||||
|  | ../lib/u8g2/u8g2_bitmap.c | ||||||
|  | 
 | ||||||
| # System applications
 | # System applications
 | ||||||
| 
 | 
 | ||||||
|  | C_SOURCES += ../applications/display-u8g2/display-u8g2.c | ||||||
|  | 
 | ||||||
|  | # Examples
 | ||||||
|  | 
 | ||||||
|  | # TODO example without condition
 | ||||||
|  | C_SOURCES += ../applications/examples/u8g2_example.c | ||||||
|  | 
 | ||||||
| ifeq ($(TEST), 1) | ifeq ($(TEST), 1) | ||||||
| C_SOURCES += ../applications/tests/furiac_test.c | C_SOURCES += ../applications/tests/furiac_test.c | ||||||
| C_SOURCES += ../applications/tests/furi_record_test.c | C_SOURCES += ../applications/tests/furi_record_test.c | ||||||
| @ -215,6 +242,7 @@ AS_INCLUDES =  \ | |||||||
| C_INCLUDES =  \
 | C_INCLUDES =  \
 | ||||||
| -IInc \ | -IInc \ | ||||||
| -I../applications \ | -I../applications \ | ||||||
|  | -I../lib \ | ||||||
| -I../core \ | -I../core \ | ||||||
| -IDrivers/STM32L4xx_HAL_Driver/Inc \ | -IDrivers/STM32L4xx_HAL_Driver/Inc \ | ||||||
| -IDrivers/STM32L4xx_HAL_Driver/Inc/Legacy \ | -IDrivers/STM32L4xx_HAL_Driver/Inc/Legacy \ | ||||||
|  | |||||||
							
								
								
									
										865
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_armcc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										865
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_armcc.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,865 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_armcc.h | ||||||
|  |  * @brief    CMSIS compiler ARMCC (Arm Compiler 5) header file | ||||||
|  |  * @version  V5.0.4 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_ARMCC_H | ||||||
|  | #define __CMSIS_ARMCC_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) | ||||||
|  |   #error "Please use Arm Compiler Toolchain V4.0.677 or later!" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* CMSIS compiler control architecture macros */ | ||||||
|  | #if ((defined (__TARGET_ARCH_6_M  ) && (__TARGET_ARCH_6_M   == 1)) || \ | ||||||
|  |      (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M  == 1))   ) | ||||||
|  |   #define __ARM_ARCH_6M__           1 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M  == 1)) | ||||||
|  |   #define __ARM_ARCH_7M__           1 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) | ||||||
|  |   #define __ARM_ARCH_7EM__          1 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |   /* __ARM_ARCH_8M_BASE__  not applicable */ | ||||||
|  |   /* __ARM_ARCH_8M_MAIN__  not applicable */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* CMSIS compiler specific defines */ | ||||||
|  | #ifndef   __ASM | ||||||
|  |   #define __ASM                                  __asm | ||||||
|  | #endif | ||||||
|  | #ifndef   __INLINE | ||||||
|  |   #define __INLINE                               __inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __STATIC_INLINE | ||||||
|  |   #define __STATIC_INLINE                        static __inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __STATIC_FORCEINLINE                  | ||||||
|  |   #define __STATIC_FORCEINLINE                   static __forceinline | ||||||
|  | #endif            | ||||||
|  | #ifndef   __NO_RETURN | ||||||
|  |   #define __NO_RETURN                            __declspec(noreturn) | ||||||
|  | #endif | ||||||
|  | #ifndef   __USED | ||||||
|  |   #define __USED                                 __attribute__((used)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __WEAK | ||||||
|  |   #define __WEAK                                 __attribute__((weak)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED | ||||||
|  |   #define __PACKED                               __attribute__((packed)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED_STRUCT | ||||||
|  |   #define __PACKED_STRUCT                        __packed struct | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED_UNION | ||||||
|  |   #define __PACKED_UNION                         __packed union | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32        /* deprecated */ | ||||||
|  |   #define __UNALIGNED_UINT32(x)                  (*((__packed uint32_t *)(x))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT16_WRITE | ||||||
|  |   #define __UNALIGNED_UINT16_WRITE(addr, val)    ((*((__packed uint16_t *)(addr))) = (val)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT16_READ | ||||||
|  |   #define __UNALIGNED_UINT16_READ(addr)          (*((const __packed uint16_t *)(addr))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32_WRITE | ||||||
|  |   #define __UNALIGNED_UINT32_WRITE(addr, val)    ((*((__packed uint32_t *)(addr))) = (val)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32_READ | ||||||
|  |   #define __UNALIGNED_UINT32_READ(addr)          (*((const __packed uint32_t *)(addr))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __ALIGNED | ||||||
|  |   #define __ALIGNED(x)                           __attribute__((aligned(x))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __RESTRICT | ||||||
|  |   #define __RESTRICT                             __restrict | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ###########################  Core Function Access  ########################### */ | ||||||
|  | /** \ingroup  CMSIS_Core_FunctionInterface
 | ||||||
|  |     \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Enable IRQ Interrupts | ||||||
|  |   \details Enables IRQ interrupts by clearing the I-bit in the CPSR. | ||||||
|  |            Can only be executed in Privileged modes. | ||||||
|  |  */ | ||||||
|  | /* intrinsic void __enable_irq();     */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Disable IRQ Interrupts | ||||||
|  |   \details Disables IRQ interrupts by setting the I-bit in the CPSR. | ||||||
|  |            Can only be executed in Privileged modes. | ||||||
|  |  */ | ||||||
|  | /* intrinsic void __disable_irq();    */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Control Register | ||||||
|  |   \details Returns the content of the Control Register. | ||||||
|  |   \return               Control Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_CONTROL(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regControl         __ASM("control"); | ||||||
|  |   return(__regControl); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Control Register | ||||||
|  |   \details Writes the given value to the Control Register. | ||||||
|  |   \param [in]    control  Control Register value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_CONTROL(uint32_t control) | ||||||
|  | { | ||||||
|  |   register uint32_t __regControl         __ASM("control"); | ||||||
|  |   __regControl = control; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get IPSR Register | ||||||
|  |   \details Returns the content of the IPSR Register. | ||||||
|  |   \return               IPSR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_IPSR(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regIPSR          __ASM("ipsr"); | ||||||
|  |   return(__regIPSR); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get APSR Register | ||||||
|  |   \details Returns the content of the APSR Register. | ||||||
|  |   \return               APSR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_APSR(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regAPSR          __ASM("apsr"); | ||||||
|  |   return(__regAPSR); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get xPSR Register | ||||||
|  |   \details Returns the content of the xPSR Register. | ||||||
|  |   \return               xPSR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_xPSR(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regXPSR          __ASM("xpsr"); | ||||||
|  |   return(__regXPSR); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Process Stack Pointer | ||||||
|  |   \details Returns the current value of the Process Stack Pointer (PSP). | ||||||
|  |   \return               PSP Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_PSP(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regProcessStackPointer  __ASM("psp"); | ||||||
|  |   return(__regProcessStackPointer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Process Stack Pointer | ||||||
|  |   \details Assigns the given value to the Process Stack Pointer (PSP). | ||||||
|  |   \param [in]    topOfProcStack  Process Stack Pointer value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) | ||||||
|  | { | ||||||
|  |   register uint32_t __regProcessStackPointer  __ASM("psp"); | ||||||
|  |   __regProcessStackPointer = topOfProcStack; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Main Stack Pointer | ||||||
|  |   \details Returns the current value of the Main Stack Pointer (MSP). | ||||||
|  |   \return               MSP Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_MSP(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regMainStackPointer     __ASM("msp"); | ||||||
|  |   return(__regMainStackPointer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Main Stack Pointer | ||||||
|  |   \details Assigns the given value to the Main Stack Pointer (MSP). | ||||||
|  |   \param [in]    topOfMainStack  Main Stack Pointer value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) | ||||||
|  | { | ||||||
|  |   register uint32_t __regMainStackPointer     __ASM("msp"); | ||||||
|  |   __regMainStackPointer = topOfMainStack; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Priority Mask | ||||||
|  |   \details Returns the current state of the priority mask bit from the Priority Mask Register. | ||||||
|  |   \return               Priority Mask value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_PRIMASK(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regPriMask         __ASM("primask"); | ||||||
|  |   return(__regPriMask); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Priority Mask | ||||||
|  |   \details Assigns the given value to the Priority Mask Register. | ||||||
|  |   \param [in]    priMask  Priority Mask | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) | ||||||
|  | { | ||||||
|  |   register uint32_t __regPriMask         __ASM("primask"); | ||||||
|  |   __regPriMask = (priMask); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \ | ||||||
|  |      (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Enable FIQ | ||||||
|  |   \details Enables FIQ interrupts by clearing the F-bit in the CPSR. | ||||||
|  |            Can only be executed in Privileged modes. | ||||||
|  |  */ | ||||||
|  | #define __enable_fault_irq                __enable_fiq | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Disable FIQ | ||||||
|  |   \details Disables FIQ interrupts by setting the F-bit in the CPSR. | ||||||
|  |            Can only be executed in Privileged modes. | ||||||
|  |  */ | ||||||
|  | #define __disable_fault_irq               __disable_fiq | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Base Priority | ||||||
|  |   \details Returns the current value of the Base Priority register. | ||||||
|  |   \return               Base Priority register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t  __get_BASEPRI(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regBasePri         __ASM("basepri"); | ||||||
|  |   return(__regBasePri); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Base Priority | ||||||
|  |   \details Assigns the given value to the Base Priority register. | ||||||
|  |   \param [in]    basePri  Base Priority value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_BASEPRI(uint32_t basePri) | ||||||
|  | { | ||||||
|  |   register uint32_t __regBasePri         __ASM("basepri"); | ||||||
|  |   __regBasePri = (basePri & 0xFFU); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Base Priority with condition | ||||||
|  |   \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, | ||||||
|  |            or the new value increases the BASEPRI priority level. | ||||||
|  |   \param [in]    basePri  Base Priority value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) | ||||||
|  | { | ||||||
|  |   register uint32_t __regBasePriMax      __ASM("basepri_max"); | ||||||
|  |   __regBasePriMax = (basePri & 0xFFU); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Fault Mask | ||||||
|  |   \details Returns the current value of the Fault Mask register. | ||||||
|  |   \return               Fault Mask register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_FAULTMASK(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regFaultMask       __ASM("faultmask"); | ||||||
|  |   return(__regFaultMask); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Fault Mask | ||||||
|  |   \details Assigns the given value to the Fault Mask register. | ||||||
|  |   \param [in]    faultMask  Fault Mask value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) | ||||||
|  | { | ||||||
|  |   register uint32_t __regFaultMask       __ASM("faultmask"); | ||||||
|  |   __regFaultMask = (faultMask & (uint32_t)1U); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \ | ||||||
|  |            (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get FPSCR | ||||||
|  |   \details Returns the current value of the Floating Point Status/Control register. | ||||||
|  |   \return               Floating Point Status/Control register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_FPSCR(void) | ||||||
|  | { | ||||||
|  | #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |      (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     ) | ||||||
|  |   register uint32_t __regfpscr         __ASM("fpscr"); | ||||||
|  |   return(__regfpscr); | ||||||
|  | #else | ||||||
|  |    return(0U); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set FPSCR | ||||||
|  |   \details Assigns the given value to the Floating Point Status/Control register. | ||||||
|  |   \param [in]    fpscr  Floating Point Status/Control value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) | ||||||
|  | { | ||||||
|  | #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |      (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     ) | ||||||
|  |   register uint32_t __regfpscr         __ASM("fpscr"); | ||||||
|  |   __regfpscr = (fpscr); | ||||||
|  | #else | ||||||
|  |   (void)fpscr; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*@} end of CMSIS_Core_RegAccFunctions */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ##########################  Core Instruction Access  ######################### */ | ||||||
|  | /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
 | ||||||
|  |   Access to dedicated instructions | ||||||
|  |   @{ | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   No Operation | ||||||
|  |   \details No Operation does nothing. This instruction can be used for code alignment purposes. | ||||||
|  |  */ | ||||||
|  | #define __NOP                             __nop | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Wait For Interrupt | ||||||
|  |   \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. | ||||||
|  |  */ | ||||||
|  | #define __WFI                             __wfi | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Wait For Event | ||||||
|  |   \details Wait For Event is a hint instruction that permits the processor to enter | ||||||
|  |            a low-power state until one of a number of events occurs. | ||||||
|  |  */ | ||||||
|  | #define __WFE                             __wfe | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Send Event | ||||||
|  |   \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. | ||||||
|  |  */ | ||||||
|  | #define __SEV                             __sev | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Instruction Synchronization Barrier | ||||||
|  |   \details Instruction Synchronization Barrier flushes the pipeline in the processor, | ||||||
|  |            so that all instructions following the ISB are fetched from cache or memory, | ||||||
|  |            after the instruction has been completed. | ||||||
|  |  */ | ||||||
|  | #define __ISB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __isb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Data Synchronization Barrier | ||||||
|  |   \details Acts as a special kind of Data Memory Barrier. | ||||||
|  |            It completes when all explicit memory accesses before this instruction complete. | ||||||
|  |  */ | ||||||
|  | #define __DSB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __dsb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Data Memory Barrier | ||||||
|  |   \details Ensures the apparent order of the explicit memory operations before | ||||||
|  |            and after the instruction, without ensuring their completion. | ||||||
|  |  */ | ||||||
|  | #define __DMB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __dmb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  |                    | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (32 bit) | ||||||
|  |   \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #define __REV                             __rev | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (16 bit) | ||||||
|  |   \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #ifndef __NO_EMBEDDED_ASM | ||||||
|  | __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) | ||||||
|  | { | ||||||
|  |   rev16 r0, r0 | ||||||
|  |   bx lr | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (16 bit) | ||||||
|  |   \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #ifndef __NO_EMBEDDED_ASM | ||||||
|  | __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) | ||||||
|  | { | ||||||
|  |   revsh r0, r0 | ||||||
|  |   bx lr | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Rotate Right in unsigned value (32 bit) | ||||||
|  |   \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. | ||||||
|  |   \param [in]    op1  Value to rotate | ||||||
|  |   \param [in]    op2  Number of Bits to rotate | ||||||
|  |   \return               Rotated value | ||||||
|  |  */ | ||||||
|  | #define __ROR                             __ror | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Breakpoint | ||||||
|  |   \details Causes the processor to enter Debug state. | ||||||
|  |            Debug tools can use this to investigate system state when the instruction at a particular address is reached. | ||||||
|  |   \param [in]    value  is ignored by the processor. | ||||||
|  |                  If required, a debugger can use it to store additional information about the breakpoint. | ||||||
|  |  */ | ||||||
|  | #define __BKPT(value)                       __breakpoint(value) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse bit order of value | ||||||
|  |   \details Reverses the bit order of the given value. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \ | ||||||
|  |      (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) | ||||||
|  |   #define __RBIT                          __rbit | ||||||
|  | #else | ||||||
|  | __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ | ||||||
|  | 
 | ||||||
|  |   result = value;                      /* r will be reversed bits of v; first get LSB of v */ | ||||||
|  |   for (value >>= 1U; value != 0U; value >>= 1U) | ||||||
|  |   { | ||||||
|  |     result <<= 1U; | ||||||
|  |     result |= value & 1U; | ||||||
|  |     s--; | ||||||
|  |   } | ||||||
|  |   result <<= s;                        /* shift when v's highest bits are zero */ | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Count leading zeros | ||||||
|  |   \details Counts the number of leading zeros of a data value. | ||||||
|  |   \param [in]  value  Value to count the leading zeros | ||||||
|  |   \return             number of leading zeros in value | ||||||
|  |  */ | ||||||
|  | #define __CLZ                             __clz | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \ | ||||||
|  |      (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (8 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 8 bit value. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return             value of type uint8_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __LDREXB(ptr)                                                        ((uint8_t ) __ldrex(ptr)) | ||||||
|  | #else | ||||||
|  |   #define __LDREXB(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr))  _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (16 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 16 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint16_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __LDREXH(ptr)                                                        ((uint16_t) __ldrex(ptr)) | ||||||
|  | #else | ||||||
|  |   #define __LDREXH(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr))  _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (32 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 32 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint32_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __LDREXW(ptr)                                                        ((uint32_t ) __ldrex(ptr)) | ||||||
|  | #else | ||||||
|  |   #define __LDREXW(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr))  _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (8 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 8 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __STREXB(value, ptr)                                                 __strex(value, ptr) | ||||||
|  | #else | ||||||
|  |   #define __STREXB(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (16 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 16 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __STREXH(value, ptr)                                                 __strex(value, ptr) | ||||||
|  | #else | ||||||
|  |   #define __STREXH(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (32 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 32 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __STREXW(value, ptr)                                                 __strex(value, ptr) | ||||||
|  | #else | ||||||
|  |   #define __STREXW(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Remove the exclusive lock | ||||||
|  |   \details Removes the exclusive lock which is created by LDREX. | ||||||
|  |  */ | ||||||
|  | #define __CLREX                           __clrex | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Signed Saturate | ||||||
|  |   \details Saturates a signed value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (1..32) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | #define __SSAT                            __ssat | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Unsigned Saturate | ||||||
|  |   \details Saturates an unsigned value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (0..31) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | #define __USAT                            __usat | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Rotate Right with Extend (32 bit) | ||||||
|  |   \details Moves each bit of a bitstring right by one bit. | ||||||
|  |            The carry input is shifted in at the left end of the bitstring. | ||||||
|  |   \param [in]    value  Value to rotate | ||||||
|  |   \return               Rotated value | ||||||
|  |  */ | ||||||
|  | #ifndef __NO_EMBEDDED_ASM | ||||||
|  | __attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) | ||||||
|  | { | ||||||
|  |   rrx r0, r0 | ||||||
|  |   bx lr | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDRT Unprivileged (8 bit) | ||||||
|  |   \details Executes a Unprivileged LDRT instruction for 8 bit value. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return             value of type uint8_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #define __LDRBT(ptr)                      ((uint8_t )  __ldrt(ptr)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDRT Unprivileged (16 bit) | ||||||
|  |   \details Executes a Unprivileged LDRT instruction for 16 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint16_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #define __LDRHT(ptr)                      ((uint16_t)  __ldrt(ptr)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDRT Unprivileged (32 bit) | ||||||
|  |   \details Executes a Unprivileged LDRT instruction for 32 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint32_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #define __LDRT(ptr)                       ((uint32_t ) __ldrt(ptr)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STRT Unprivileged (8 bit) | ||||||
|  |   \details Executes a Unprivileged STRT instruction for 8 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |  */ | ||||||
|  | #define __STRBT(value, ptr)               __strt(value, ptr) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STRT Unprivileged (16 bit) | ||||||
|  |   \details Executes a Unprivileged STRT instruction for 16 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |  */ | ||||||
|  | #define __STRHT(value, ptr)               __strt(value, ptr) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STRT Unprivileged (32 bit) | ||||||
|  |   \details Executes a Unprivileged STRT instruction for 32 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |  */ | ||||||
|  | #define __STRT(value, ptr)                __strt(value, ptr) | ||||||
|  | 
 | ||||||
|  | #else  /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \ | ||||||
|  |            (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Signed Saturate | ||||||
|  |   \details Saturates a signed value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (1..32) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | __attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) | ||||||
|  | { | ||||||
|  |   if ((sat >= 1U) && (sat <= 32U)) | ||||||
|  |   { | ||||||
|  |     const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); | ||||||
|  |     const int32_t min = -1 - max ; | ||||||
|  |     if (val > max) | ||||||
|  |     { | ||||||
|  |       return max; | ||||||
|  |     } | ||||||
|  |     else if (val < min) | ||||||
|  |     { | ||||||
|  |       return min; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return val; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Unsigned Saturate | ||||||
|  |   \details Saturates an unsigned value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (0..31) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) | ||||||
|  | { | ||||||
|  |   if (sat <= 31U) | ||||||
|  |   { | ||||||
|  |     const uint32_t max = ((1U << sat) - 1U); | ||||||
|  |     if (val > (int32_t)max) | ||||||
|  |     { | ||||||
|  |       return max; | ||||||
|  |     } | ||||||
|  |     else if (val < 0) | ||||||
|  |     { | ||||||
|  |       return 0U; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return (uint32_t)val; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \ | ||||||
|  |            (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) */ | ||||||
|  | 
 | ||||||
|  | /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ###################  Compiler specific Intrinsics  ########################### */ | ||||||
|  | /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
 | ||||||
|  |   Access to dedicated SIMD instructions | ||||||
|  |   @{ | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) | ||||||
|  | 
 | ||||||
|  | #define __SADD8                           __sadd8 | ||||||
|  | #define __QADD8                           __qadd8 | ||||||
|  | #define __SHADD8                          __shadd8 | ||||||
|  | #define __UADD8                           __uadd8 | ||||||
|  | #define __UQADD8                          __uqadd8 | ||||||
|  | #define __UHADD8                          __uhadd8 | ||||||
|  | #define __SSUB8                           __ssub8 | ||||||
|  | #define __QSUB8                           __qsub8 | ||||||
|  | #define __SHSUB8                          __shsub8 | ||||||
|  | #define __USUB8                           __usub8 | ||||||
|  | #define __UQSUB8                          __uqsub8 | ||||||
|  | #define __UHSUB8                          __uhsub8 | ||||||
|  | #define __SADD16                          __sadd16 | ||||||
|  | #define __QADD16                          __qadd16 | ||||||
|  | #define __SHADD16                         __shadd16 | ||||||
|  | #define __UADD16                          __uadd16 | ||||||
|  | #define __UQADD16                         __uqadd16 | ||||||
|  | #define __UHADD16                         __uhadd16 | ||||||
|  | #define __SSUB16                          __ssub16 | ||||||
|  | #define __QSUB16                          __qsub16 | ||||||
|  | #define __SHSUB16                         __shsub16 | ||||||
|  | #define __USUB16                          __usub16 | ||||||
|  | #define __UQSUB16                         __uqsub16 | ||||||
|  | #define __UHSUB16                         __uhsub16 | ||||||
|  | #define __SASX                            __sasx | ||||||
|  | #define __QASX                            __qasx | ||||||
|  | #define __SHASX                           __shasx | ||||||
|  | #define __UASX                            __uasx | ||||||
|  | #define __UQASX                           __uqasx | ||||||
|  | #define __UHASX                           __uhasx | ||||||
|  | #define __SSAX                            __ssax | ||||||
|  | #define __QSAX                            __qsax | ||||||
|  | #define __SHSAX                           __shsax | ||||||
|  | #define __USAX                            __usax | ||||||
|  | #define __UQSAX                           __uqsax | ||||||
|  | #define __UHSAX                           __uhsax | ||||||
|  | #define __USAD8                           __usad8 | ||||||
|  | #define __USADA8                          __usada8 | ||||||
|  | #define __SSAT16                          __ssat16 | ||||||
|  | #define __USAT16                          __usat16 | ||||||
|  | #define __UXTB16                          __uxtb16 | ||||||
|  | #define __UXTAB16                         __uxtab16 | ||||||
|  | #define __SXTB16                          __sxtb16 | ||||||
|  | #define __SXTAB16                         __sxtab16 | ||||||
|  | #define __SMUAD                           __smuad | ||||||
|  | #define __SMUADX                          __smuadx | ||||||
|  | #define __SMLAD                           __smlad | ||||||
|  | #define __SMLADX                          __smladx | ||||||
|  | #define __SMLALD                          __smlald | ||||||
|  | #define __SMLALDX                         __smlaldx | ||||||
|  | #define __SMUSD                           __smusd | ||||||
|  | #define __SMUSDX                          __smusdx | ||||||
|  | #define __SMLSD                           __smlsd | ||||||
|  | #define __SMLSDX                          __smlsdx | ||||||
|  | #define __SMLSLD                          __smlsld | ||||||
|  | #define __SMLSLDX                         __smlsldx | ||||||
|  | #define __SEL                             __sel | ||||||
|  | #define __QADD                            __qadd | ||||||
|  | #define __QSUB                            __qsub | ||||||
|  | 
 | ||||||
|  | #define __PKHBT(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0x0000FFFFUL) |  \ | ||||||
|  |                                            ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)  ) | ||||||
|  | 
 | ||||||
|  | #define __PKHTB(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0xFFFF0000UL) |  \ | ||||||
|  |                                            ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)  ) | ||||||
|  | 
 | ||||||
|  | #define __SMMLA(ARG1,ARG2,ARG3)          ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ | ||||||
|  |                                                       ((int64_t)(ARG3) << 32U)     ) >> 32U)) | ||||||
|  | 
 | ||||||
|  | #endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) */ | ||||||
|  | /*@} end of group CMSIS_SIMD_intrinsics */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_ARMCC_H */ | ||||||
							
								
								
									
										1869
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_armclang.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1869
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_armclang.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										266
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_compiler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_compiler.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,266 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_compiler.h | ||||||
|  |  * @brief    CMSIS compiler generic header file | ||||||
|  |  * @version  V5.0.4 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_COMPILER_H | ||||||
|  | #define __CMSIS_COMPILER_H | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Arm Compiler 4/5 | ||||||
|  |  */ | ||||||
|  | #if   defined ( __CC_ARM ) | ||||||
|  |   #include "cmsis_armcc.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Arm Compiler 6 (armclang) | ||||||
|  |  */ | ||||||
|  | #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) | ||||||
|  |   #include "cmsis_armclang.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * GNU Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __GNUC__ ) | ||||||
|  |   #include "cmsis_gcc.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * IAR Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __ICCARM__ ) | ||||||
|  |   #include <cmsis_iccarm.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * TI Arm Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __TI_ARM__ ) | ||||||
|  |   #include <cmsis_ccs.h> | ||||||
|  | 
 | ||||||
|  |   #ifndef   __ASM | ||||||
|  |     #define __ASM                                  __asm | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __INLINE | ||||||
|  |     #define __INLINE                               inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_INLINE | ||||||
|  |     #define __STATIC_INLINE                        static inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_FORCEINLINE | ||||||
|  |     #define __STATIC_FORCEINLINE                   __STATIC_INLINE | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __NO_RETURN | ||||||
|  |     #define __NO_RETURN                            __attribute__((noreturn)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __USED | ||||||
|  |     #define __USED                                 __attribute__((used)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __WEAK | ||||||
|  |     #define __WEAK                                 __attribute__((weak)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED | ||||||
|  |     #define __PACKED                               __attribute__((packed)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED_STRUCT | ||||||
|  |     #define __PACKED_STRUCT                        struct __attribute__((packed)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED_UNION | ||||||
|  |     #define __PACKED_UNION                         union __attribute__((packed)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32        /* deprecated */ | ||||||
|  |     struct __attribute__((packed)) T_UINT32 { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT16_WRITE | ||||||
|  |     __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT16_READ | ||||||
|  |     __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32_WRITE | ||||||
|  |     __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32_READ | ||||||
|  |     __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __ALIGNED | ||||||
|  |     #define __ALIGNED(x)                           __attribute__((aligned(x))) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __RESTRICT | ||||||
|  |     #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. | ||||||
|  |     #define __RESTRICT | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * TASKING Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __TASKING__ ) | ||||||
|  |   /*
 | ||||||
|  |    * The CMSIS functions have been implemented as intrinsics in the compiler. | ||||||
|  |    * Please use "carm -?i" to get an up to date list of all intrinsics, | ||||||
|  |    * Including the CMSIS ones. | ||||||
|  |    */ | ||||||
|  | 
 | ||||||
|  |   #ifndef   __ASM | ||||||
|  |     #define __ASM                                  __asm | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __INLINE | ||||||
|  |     #define __INLINE                               inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_INLINE | ||||||
|  |     #define __STATIC_INLINE                        static inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_FORCEINLINE | ||||||
|  |     #define __STATIC_FORCEINLINE                   __STATIC_INLINE | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __NO_RETURN | ||||||
|  |     #define __NO_RETURN                            __attribute__((noreturn)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __USED | ||||||
|  |     #define __USED                                 __attribute__((used)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __WEAK | ||||||
|  |     #define __WEAK                                 __attribute__((weak)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED | ||||||
|  |     #define __PACKED                               __packed__ | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED_STRUCT | ||||||
|  |     #define __PACKED_STRUCT                        struct __packed__ | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED_UNION | ||||||
|  |     #define __PACKED_UNION                         union __packed__ | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32        /* deprecated */ | ||||||
|  |     struct __packed__ T_UINT32 { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT16_WRITE | ||||||
|  |     __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT16_READ | ||||||
|  |     __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32_WRITE | ||||||
|  |     __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32_READ | ||||||
|  |     __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __ALIGNED | ||||||
|  |     #define __ALIGNED(x)              __align(x) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __RESTRICT | ||||||
|  |     #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. | ||||||
|  |     #define __RESTRICT | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * COSMIC Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __CSMC__ ) | ||||||
|  |    #include <cmsis_csm.h> | ||||||
|  | 
 | ||||||
|  |  #ifndef   __ASM | ||||||
|  |     #define __ASM                                  _asm | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __INLINE | ||||||
|  |     #define __INLINE                               inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_INLINE | ||||||
|  |     #define __STATIC_INLINE                        static inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_FORCEINLINE | ||||||
|  |     #define __STATIC_FORCEINLINE                   __STATIC_INLINE | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __NO_RETURN | ||||||
|  |     // NO RETURN is automatically detected hence no warning here
 | ||||||
|  |     #define __NO_RETURN | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __USED | ||||||
|  |     #warning No compiler specific solution for __USED. __USED is ignored. | ||||||
|  |     #define __USED | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __WEAK | ||||||
|  |     #define __WEAK                                 __weak | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED | ||||||
|  |     #define __PACKED                               @packed | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED_STRUCT | ||||||
|  |     #define __PACKED_STRUCT                        @packed struct | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED_UNION | ||||||
|  |     #define __PACKED_UNION                         @packed union | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32        /* deprecated */ | ||||||
|  |     @packed struct T_UINT32 { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT16_WRITE | ||||||
|  |     __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT16_READ | ||||||
|  |     __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32_WRITE | ||||||
|  |     __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32_READ | ||||||
|  |     __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __ALIGNED | ||||||
|  |     #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. | ||||||
|  |     #define __ALIGNED(x) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __RESTRICT | ||||||
|  |     #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. | ||||||
|  |     #define __RESTRICT | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  |   #error Unknown compiler. | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_COMPILER_H */ | ||||||
|  | 
 | ||||||
							
								
								
									
										2085
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_gcc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2085
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_gcc.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										935
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_iccarm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										935
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_iccarm.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,935 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_iccarm.h | ||||||
|  |  * @brief    CMSIS compiler ICCARM (IAR Compiler for Arm) header file | ||||||
|  |  * @version  V5.0.7 | ||||||
|  |  * @date     19. June 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | //------------------------------------------------------------------------------
 | ||||||
|  | //
 | ||||||
|  | // Copyright (c) 2017-2018 IAR Systems
 | ||||||
|  | //
 | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License")
 | ||||||
|  | // you may not use this file except in compliance with the License.
 | ||||||
|  | // You may obtain a copy of the License at
 | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  | //
 | ||||||
|  | // Unless required by applicable law or agreed to in writing, software
 | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||||
|  | // See the License for the specific language governing permissions and
 | ||||||
|  | // limitations under the License.
 | ||||||
|  | //
 | ||||||
|  | //------------------------------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_ICCARM_H__ | ||||||
|  | #define __CMSIS_ICCARM_H__ | ||||||
|  | 
 | ||||||
|  | #ifndef __ICCARM__ | ||||||
|  |   #error This file should only be compiled by ICCARM | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #pragma system_include | ||||||
|  | 
 | ||||||
|  | #define __IAR_FT _Pragma("inline=forced") __intrinsic | ||||||
|  | 
 | ||||||
|  | #if (__VER__ >= 8000000) | ||||||
|  |   #define __ICCARM_V8 1 | ||||||
|  | #else | ||||||
|  |   #define __ICCARM_V8 0 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __ALIGNED | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __ALIGNED(x) __attribute__((aligned(x))) | ||||||
|  |   #elif (__VER__ >= 7080000) | ||||||
|  |     /* Needs IAR language extensions */ | ||||||
|  |     #define __ALIGNED(x) __attribute__((aligned(x))) | ||||||
|  |   #else | ||||||
|  |     #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. | ||||||
|  |     #define __ALIGNED(x) | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define compiler macros for CPU architecture, used in CMSIS 5.
 | ||||||
|  |  */ | ||||||
|  | #if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ | ||||||
|  | /* Macros already defined */ | ||||||
|  | #else | ||||||
|  |   #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) | ||||||
|  |     #define __ARM_ARCH_8M_MAIN__ 1 | ||||||
|  |   #elif defined(__ARM8M_BASELINE__) | ||||||
|  |     #define __ARM_ARCH_8M_BASE__ 1 | ||||||
|  |   #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' | ||||||
|  |     #if __ARM_ARCH == 6 | ||||||
|  |       #define __ARM_ARCH_6M__ 1 | ||||||
|  |     #elif __ARM_ARCH == 7 | ||||||
|  |       #if __ARM_FEATURE_DSP | ||||||
|  |         #define __ARM_ARCH_7EM__ 1 | ||||||
|  |       #else | ||||||
|  |         #define __ARM_ARCH_7M__ 1 | ||||||
|  |       #endif | ||||||
|  |     #endif /* __ARM_ARCH */ | ||||||
|  |   #endif /* __ARM_ARCH_PROFILE == 'M' */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* Alternativ core deduction for older ICCARM's */ | ||||||
|  | #if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ | ||||||
|  |     !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) | ||||||
|  |   #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) | ||||||
|  |     #define __ARM_ARCH_6M__ 1 | ||||||
|  |   #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) | ||||||
|  |     #define __ARM_ARCH_7M__ 1 | ||||||
|  |   #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) | ||||||
|  |     #define __ARM_ARCH_7EM__  1 | ||||||
|  |   #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) | ||||||
|  |     #define __ARM_ARCH_8M_BASE__ 1 | ||||||
|  |   #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) | ||||||
|  |     #define __ARM_ARCH_8M_MAIN__ 1 | ||||||
|  |   #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) | ||||||
|  |     #define __ARM_ARCH_8M_MAIN__ 1 | ||||||
|  |   #else | ||||||
|  |     #error "Unknown target." | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 | ||||||
|  |   #define __IAR_M0_FAMILY  1 | ||||||
|  | #elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 | ||||||
|  |   #define __IAR_M0_FAMILY  1 | ||||||
|  | #else | ||||||
|  |   #define __IAR_M0_FAMILY  0 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __ASM | ||||||
|  |   #define __ASM __asm | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __INLINE | ||||||
|  |   #define __INLINE inline | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __NO_RETURN | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __NO_RETURN __attribute__((__noreturn__)) | ||||||
|  |   #else | ||||||
|  |     #define __NO_RETURN _Pragma("object_attribute=__noreturn") | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __PACKED | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __PACKED __attribute__((packed, aligned(1))) | ||||||
|  |   #else | ||||||
|  |     /* Needs IAR language extensions */ | ||||||
|  |     #define __PACKED __packed | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __PACKED_STRUCT | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) | ||||||
|  |   #else | ||||||
|  |     /* Needs IAR language extensions */ | ||||||
|  |     #define __PACKED_STRUCT __packed struct | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __PACKED_UNION | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __PACKED_UNION union __attribute__((packed, aligned(1))) | ||||||
|  |   #else | ||||||
|  |     /* Needs IAR language extensions */ | ||||||
|  |     #define __PACKED_UNION __packed union | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __RESTRICT | ||||||
|  |   #define __RESTRICT            __restrict | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __STATIC_INLINE | ||||||
|  |   #define __STATIC_INLINE       static inline | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __FORCEINLINE | ||||||
|  |   #define __FORCEINLINE         _Pragma("inline=forced") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __STATIC_FORCEINLINE | ||||||
|  |   #define __STATIC_FORCEINLINE  __FORCEINLINE __STATIC_INLINE | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT16_READ | ||||||
|  | #pragma language=save | ||||||
|  | #pragma language=extended | ||||||
|  | __IAR_FT uint16_t __iar_uint16_read(void const *ptr) | ||||||
|  | { | ||||||
|  |   return *(__packed uint16_t*)(ptr); | ||||||
|  | } | ||||||
|  | #pragma language=restore | ||||||
|  | #define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT16_WRITE | ||||||
|  | #pragma language=save | ||||||
|  | #pragma language=extended | ||||||
|  | __IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) | ||||||
|  | { | ||||||
|  |   *(__packed uint16_t*)(ptr) = val;; | ||||||
|  | } | ||||||
|  | #pragma language=restore | ||||||
|  | #define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT32_READ | ||||||
|  | #pragma language=save | ||||||
|  | #pragma language=extended | ||||||
|  | __IAR_FT uint32_t __iar_uint32_read(void const *ptr) | ||||||
|  | { | ||||||
|  |   return *(__packed uint32_t*)(ptr); | ||||||
|  | } | ||||||
|  | #pragma language=restore | ||||||
|  | #define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT32_WRITE | ||||||
|  | #pragma language=save | ||||||
|  | #pragma language=extended | ||||||
|  | __IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) | ||||||
|  | { | ||||||
|  |   *(__packed uint32_t*)(ptr) = val;; | ||||||
|  | } | ||||||
|  | #pragma language=restore | ||||||
|  | #define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT32   /* deprecated */ | ||||||
|  | #pragma language=save | ||||||
|  | #pragma language=extended | ||||||
|  | __packed struct  __iar_u32 { uint32_t v; }; | ||||||
|  | #pragma language=restore | ||||||
|  | #define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __USED | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __USED __attribute__((used)) | ||||||
|  |   #else | ||||||
|  |     #define __USED _Pragma("__root") | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __WEAK | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __WEAK __attribute__((weak)) | ||||||
|  |   #else | ||||||
|  |     #define __WEAK _Pragma("__weak") | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __ICCARM_INTRINSICS_VERSION__ | ||||||
|  |   #define __ICCARM_INTRINSICS_VERSION__  0 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if __ICCARM_INTRINSICS_VERSION__ == 2 | ||||||
|  | 
 | ||||||
|  |   #if defined(__CLZ) | ||||||
|  |     #undef __CLZ | ||||||
|  |   #endif | ||||||
|  |   #if defined(__REVSH) | ||||||
|  |     #undef __REVSH | ||||||
|  |   #endif | ||||||
|  |   #if defined(__RBIT) | ||||||
|  |     #undef __RBIT | ||||||
|  |   #endif | ||||||
|  |   #if defined(__SSAT) | ||||||
|  |     #undef __SSAT | ||||||
|  |   #endif | ||||||
|  |   #if defined(__USAT) | ||||||
|  |     #undef __USAT | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #include "iccarm_builtin.h" | ||||||
|  | 
 | ||||||
|  |   #define __disable_fault_irq __iar_builtin_disable_fiq | ||||||
|  |   #define __disable_irq       __iar_builtin_disable_interrupt | ||||||
|  |   #define __enable_fault_irq  __iar_builtin_enable_fiq | ||||||
|  |   #define __enable_irq        __iar_builtin_enable_interrupt | ||||||
|  |   #define __arm_rsr           __iar_builtin_rsr | ||||||
|  |   #define __arm_wsr           __iar_builtin_wsr | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   #define __get_APSR()                (__arm_rsr("APSR")) | ||||||
|  |   #define __get_BASEPRI()             (__arm_rsr("BASEPRI")) | ||||||
|  |   #define __get_CONTROL()             (__arm_rsr("CONTROL")) | ||||||
|  |   #define __get_FAULTMASK()           (__arm_rsr("FAULTMASK")) | ||||||
|  | 
 | ||||||
|  |   #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |        (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     ) | ||||||
|  |     #define __get_FPSCR()             (__arm_rsr("FPSCR")) | ||||||
|  |     #define __set_FPSCR(VALUE)        (__arm_wsr("FPSCR", (VALUE))) | ||||||
|  |   #else | ||||||
|  |     #define __get_FPSCR()             ( 0 ) | ||||||
|  |     #define __set_FPSCR(VALUE)        ((void)VALUE) | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #define __get_IPSR()                (__arm_rsr("IPSR")) | ||||||
|  |   #define __get_MSP()                 (__arm_rsr("MSP")) | ||||||
|  |   #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |        (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | ||||||
|  |     // without main extensions, the non-secure MSPLIM is RAZ/WI
 | ||||||
|  |     #define __get_MSPLIM()            (0U) | ||||||
|  |   #else | ||||||
|  |     #define __get_MSPLIM()            (__arm_rsr("MSPLIM")) | ||||||
|  |   #endif | ||||||
|  |   #define __get_PRIMASK()             (__arm_rsr("PRIMASK")) | ||||||
|  |   #define __get_PSP()                 (__arm_rsr("PSP")) | ||||||
|  | 
 | ||||||
|  |   #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |        (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | ||||||
|  |     // without main extensions, the non-secure PSPLIM is RAZ/WI
 | ||||||
|  |     #define __get_PSPLIM()            (0U) | ||||||
|  |   #else | ||||||
|  |     #define __get_PSPLIM()            (__arm_rsr("PSPLIM")) | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #define __get_xPSR()                (__arm_rsr("xPSR")) | ||||||
|  | 
 | ||||||
|  |   #define __set_BASEPRI(VALUE)        (__arm_wsr("BASEPRI", (VALUE))) | ||||||
|  |   #define __set_BASEPRI_MAX(VALUE)    (__arm_wsr("BASEPRI_MAX", (VALUE))) | ||||||
|  |   #define __set_CONTROL(VALUE)        (__arm_wsr("CONTROL", (VALUE))) | ||||||
|  |   #define __set_FAULTMASK(VALUE)      (__arm_wsr("FAULTMASK", (VALUE))) | ||||||
|  |   #define __set_MSP(VALUE)            (__arm_wsr("MSP", (VALUE))) | ||||||
|  | 
 | ||||||
|  |   #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |        (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | ||||||
|  |     // without main extensions, the non-secure MSPLIM is RAZ/WI
 | ||||||
|  |     #define __set_MSPLIM(VALUE)       ((void)(VALUE)) | ||||||
|  |   #else | ||||||
|  |     #define __set_MSPLIM(VALUE)       (__arm_wsr("MSPLIM", (VALUE))) | ||||||
|  |   #endif | ||||||
|  |   #define __set_PRIMASK(VALUE)        (__arm_wsr("PRIMASK", (VALUE))) | ||||||
|  |   #define __set_PSP(VALUE)            (__arm_wsr("PSP", (VALUE))) | ||||||
|  |   #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |        (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | ||||||
|  |     // without main extensions, the non-secure PSPLIM is RAZ/WI
 | ||||||
|  |     #define __set_PSPLIM(VALUE)       ((void)(VALUE)) | ||||||
|  |   #else | ||||||
|  |     #define __set_PSPLIM(VALUE)       (__arm_wsr("PSPLIM", (VALUE))) | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #define __TZ_get_CONTROL_NS()       (__arm_rsr("CONTROL_NS")) | ||||||
|  |   #define __TZ_set_CONTROL_NS(VALUE)  (__arm_wsr("CONTROL_NS", (VALUE))) | ||||||
|  |   #define __TZ_get_PSP_NS()           (__arm_rsr("PSP_NS")) | ||||||
|  |   #define __TZ_set_PSP_NS(VALUE)      (__arm_wsr("PSP_NS", (VALUE))) | ||||||
|  |   #define __TZ_get_MSP_NS()           (__arm_rsr("MSP_NS")) | ||||||
|  |   #define __TZ_set_MSP_NS(VALUE)      (__arm_wsr("MSP_NS", (VALUE))) | ||||||
|  |   #define __TZ_get_SP_NS()            (__arm_rsr("SP_NS")) | ||||||
|  |   #define __TZ_set_SP_NS(VALUE)       (__arm_wsr("SP_NS", (VALUE))) | ||||||
|  |   #define __TZ_get_PRIMASK_NS()       (__arm_rsr("PRIMASK_NS")) | ||||||
|  |   #define __TZ_set_PRIMASK_NS(VALUE)  (__arm_wsr("PRIMASK_NS", (VALUE))) | ||||||
|  |   #define __TZ_get_BASEPRI_NS()       (__arm_rsr("BASEPRI_NS")) | ||||||
|  |   #define __TZ_set_BASEPRI_NS(VALUE)  (__arm_wsr("BASEPRI_NS", (VALUE))) | ||||||
|  |   #define __TZ_get_FAULTMASK_NS()     (__arm_rsr("FAULTMASK_NS")) | ||||||
|  |   #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) | ||||||
|  | 
 | ||||||
|  |   #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |        (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | ||||||
|  |     // without main extensions, the non-secure PSPLIM is RAZ/WI
 | ||||||
|  |     #define __TZ_get_PSPLIM_NS()      (0U) | ||||||
|  |     #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) | ||||||
|  |   #else | ||||||
|  |     #define __TZ_get_PSPLIM_NS()      (__arm_rsr("PSPLIM_NS")) | ||||||
|  |     #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #define __TZ_get_MSPLIM_NS()        (__arm_rsr("MSPLIM_NS")) | ||||||
|  |   #define __TZ_set_MSPLIM_NS(VALUE)   (__arm_wsr("MSPLIM_NS", (VALUE))) | ||||||
|  | 
 | ||||||
|  |   #define __NOP     __iar_builtin_no_operation | ||||||
|  | 
 | ||||||
|  |   #define __CLZ     __iar_builtin_CLZ | ||||||
|  |   #define __CLREX   __iar_builtin_CLREX | ||||||
|  | 
 | ||||||
|  |   #define __DMB     __iar_builtin_DMB | ||||||
|  |   #define __DSB     __iar_builtin_DSB | ||||||
|  |   #define __ISB     __iar_builtin_ISB | ||||||
|  | 
 | ||||||
|  |   #define __LDREXB  __iar_builtin_LDREXB | ||||||
|  |   #define __LDREXH  __iar_builtin_LDREXH | ||||||
|  |   #define __LDREXW  __iar_builtin_LDREX | ||||||
|  | 
 | ||||||
|  |   #define __RBIT    __iar_builtin_RBIT | ||||||
|  |   #define __REV     __iar_builtin_REV | ||||||
|  |   #define __REV16   __iar_builtin_REV16 | ||||||
|  | 
 | ||||||
|  |   __IAR_FT int16_t __REVSH(int16_t val) | ||||||
|  |   { | ||||||
|  |     return (int16_t) __iar_builtin_REVSH(val); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #define __ROR     __iar_builtin_ROR | ||||||
|  |   #define __RRX     __iar_builtin_RRX | ||||||
|  | 
 | ||||||
|  |   #define __SEV     __iar_builtin_SEV | ||||||
|  | 
 | ||||||
|  |   #if !__IAR_M0_FAMILY | ||||||
|  |     #define __SSAT    __iar_builtin_SSAT | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #define __STREXB  __iar_builtin_STREXB | ||||||
|  |   #define __STREXH  __iar_builtin_STREXH | ||||||
|  |   #define __STREXW  __iar_builtin_STREX | ||||||
|  | 
 | ||||||
|  |   #if !__IAR_M0_FAMILY | ||||||
|  |     #define __USAT    __iar_builtin_USAT | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #define __WFE     __iar_builtin_WFE | ||||||
|  |   #define __WFI     __iar_builtin_WFI | ||||||
|  | 
 | ||||||
|  |   #if __ARM_MEDIA__ | ||||||
|  |     #define __SADD8   __iar_builtin_SADD8 | ||||||
|  |     #define __QADD8   __iar_builtin_QADD8 | ||||||
|  |     #define __SHADD8  __iar_builtin_SHADD8 | ||||||
|  |     #define __UADD8   __iar_builtin_UADD8 | ||||||
|  |     #define __UQADD8  __iar_builtin_UQADD8 | ||||||
|  |     #define __UHADD8  __iar_builtin_UHADD8 | ||||||
|  |     #define __SSUB8   __iar_builtin_SSUB8 | ||||||
|  |     #define __QSUB8   __iar_builtin_QSUB8 | ||||||
|  |     #define __SHSUB8  __iar_builtin_SHSUB8 | ||||||
|  |     #define __USUB8   __iar_builtin_USUB8 | ||||||
|  |     #define __UQSUB8  __iar_builtin_UQSUB8 | ||||||
|  |     #define __UHSUB8  __iar_builtin_UHSUB8 | ||||||
|  |     #define __SADD16  __iar_builtin_SADD16 | ||||||
|  |     #define __QADD16  __iar_builtin_QADD16 | ||||||
|  |     #define __SHADD16 __iar_builtin_SHADD16 | ||||||
|  |     #define __UADD16  __iar_builtin_UADD16 | ||||||
|  |     #define __UQADD16 __iar_builtin_UQADD16 | ||||||
|  |     #define __UHADD16 __iar_builtin_UHADD16 | ||||||
|  |     #define __SSUB16  __iar_builtin_SSUB16 | ||||||
|  |     #define __QSUB16  __iar_builtin_QSUB16 | ||||||
|  |     #define __SHSUB16 __iar_builtin_SHSUB16 | ||||||
|  |     #define __USUB16  __iar_builtin_USUB16 | ||||||
|  |     #define __UQSUB16 __iar_builtin_UQSUB16 | ||||||
|  |     #define __UHSUB16 __iar_builtin_UHSUB16 | ||||||
|  |     #define __SASX    __iar_builtin_SASX | ||||||
|  |     #define __QASX    __iar_builtin_QASX | ||||||
|  |     #define __SHASX   __iar_builtin_SHASX | ||||||
|  |     #define __UASX    __iar_builtin_UASX | ||||||
|  |     #define __UQASX   __iar_builtin_UQASX | ||||||
|  |     #define __UHASX   __iar_builtin_UHASX | ||||||
|  |     #define __SSAX    __iar_builtin_SSAX | ||||||
|  |     #define __QSAX    __iar_builtin_QSAX | ||||||
|  |     #define __SHSAX   __iar_builtin_SHSAX | ||||||
|  |     #define __USAX    __iar_builtin_USAX | ||||||
|  |     #define __UQSAX   __iar_builtin_UQSAX | ||||||
|  |     #define __UHSAX   __iar_builtin_UHSAX | ||||||
|  |     #define __USAD8   __iar_builtin_USAD8 | ||||||
|  |     #define __USADA8  __iar_builtin_USADA8 | ||||||
|  |     #define __SSAT16  __iar_builtin_SSAT16 | ||||||
|  |     #define __USAT16  __iar_builtin_USAT16 | ||||||
|  |     #define __UXTB16  __iar_builtin_UXTB16 | ||||||
|  |     #define __UXTAB16 __iar_builtin_UXTAB16 | ||||||
|  |     #define __SXTB16  __iar_builtin_SXTB16 | ||||||
|  |     #define __SXTAB16 __iar_builtin_SXTAB16 | ||||||
|  |     #define __SMUAD   __iar_builtin_SMUAD | ||||||
|  |     #define __SMUADX  __iar_builtin_SMUADX | ||||||
|  |     #define __SMMLA   __iar_builtin_SMMLA | ||||||
|  |     #define __SMLAD   __iar_builtin_SMLAD | ||||||
|  |     #define __SMLADX  __iar_builtin_SMLADX | ||||||
|  |     #define __SMLALD  __iar_builtin_SMLALD | ||||||
|  |     #define __SMLALDX __iar_builtin_SMLALDX | ||||||
|  |     #define __SMUSD   __iar_builtin_SMUSD | ||||||
|  |     #define __SMUSDX  __iar_builtin_SMUSDX | ||||||
|  |     #define __SMLSD   __iar_builtin_SMLSD | ||||||
|  |     #define __SMLSDX  __iar_builtin_SMLSDX | ||||||
|  |     #define __SMLSLD  __iar_builtin_SMLSLD | ||||||
|  |     #define __SMLSLDX __iar_builtin_SMLSLDX | ||||||
|  |     #define __SEL     __iar_builtin_SEL | ||||||
|  |     #define __QADD    __iar_builtin_QADD | ||||||
|  |     #define __QSUB    __iar_builtin_QSUB | ||||||
|  |     #define __PKHBT   __iar_builtin_PKHBT | ||||||
|  |     #define __PKHTB   __iar_builtin_PKHTB | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ | ||||||
|  | 
 | ||||||
|  |   #if __IAR_M0_FAMILY | ||||||
|  |    /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ | ||||||
|  |     #define __CLZ  __cmsis_iar_clz_not_active | ||||||
|  |     #define __SSAT __cmsis_iar_ssat_not_active | ||||||
|  |     #define __USAT __cmsis_iar_usat_not_active | ||||||
|  |     #define __RBIT __cmsis_iar_rbit_not_active | ||||||
|  |     #define __get_APSR  __cmsis_iar_get_APSR_not_active | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |          (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     )) | ||||||
|  |     #define __get_FPSCR __cmsis_iar_get_FPSR_not_active | ||||||
|  |     #define __set_FPSCR __cmsis_iar_set_FPSR_not_active | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #ifdef __INTRINSICS_INCLUDED | ||||||
|  |   #error intrinsics.h is already included previously! | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #include <intrinsics.h> | ||||||
|  | 
 | ||||||
|  |   #if __IAR_M0_FAMILY | ||||||
|  |    /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ | ||||||
|  |     #undef __CLZ | ||||||
|  |     #undef __SSAT | ||||||
|  |     #undef __USAT | ||||||
|  |     #undef __RBIT | ||||||
|  |     #undef __get_APSR | ||||||
|  | 
 | ||||||
|  |     __STATIC_INLINE uint8_t __CLZ(uint32_t data) | ||||||
|  |     { | ||||||
|  |       if (data == 0U) { return 32U; } | ||||||
|  | 
 | ||||||
|  |       uint32_t count = 0U; | ||||||
|  |       uint32_t mask = 0x80000000U; | ||||||
|  | 
 | ||||||
|  |       while ((data & mask) == 0U) | ||||||
|  |       { | ||||||
|  |         count += 1U; | ||||||
|  |         mask = mask >> 1U; | ||||||
|  |       } | ||||||
|  |       return count; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __STATIC_INLINE uint32_t __RBIT(uint32_t v) | ||||||
|  |     { | ||||||
|  |       uint8_t sc = 31U; | ||||||
|  |       uint32_t r = v; | ||||||
|  |       for (v >>= 1U; v; v >>= 1U) | ||||||
|  |       { | ||||||
|  |         r <<= 1U; | ||||||
|  |         r |= v & 1U; | ||||||
|  |         sc--; | ||||||
|  |       } | ||||||
|  |       return (r << sc); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __STATIC_INLINE  uint32_t __get_APSR(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm("MRS      %0,APSR" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |          (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     )) | ||||||
|  |     #undef __get_FPSCR | ||||||
|  |     #undef __set_FPSCR | ||||||
|  |     #define __get_FPSCR()       (0) | ||||||
|  |     #define __set_FPSCR(VALUE)  ((void)VALUE) | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #pragma diag_suppress=Pe940 | ||||||
|  |   #pragma diag_suppress=Pe177 | ||||||
|  | 
 | ||||||
|  |   #define __enable_irq    __enable_interrupt | ||||||
|  |   #define __disable_irq   __disable_interrupt | ||||||
|  |   #define __NOP           __no_operation | ||||||
|  | 
 | ||||||
|  |   #define __get_xPSR      __get_PSR | ||||||
|  | 
 | ||||||
|  |   #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) | ||||||
|  |     { | ||||||
|  |       return __LDREX((unsigned long *)ptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) | ||||||
|  |     { | ||||||
|  |       return __STREX(value, (unsigned long *)ptr); | ||||||
|  |     } | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ | ||||||
|  |   #if (__CORTEX_M >= 0x03) | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t __RRX(uint32_t value) | ||||||
|  |     { | ||||||
|  |       uint32_t result; | ||||||
|  |       __ASM("RRX      %0, %1" : "=r"(result) : "r" (value) : "cc"); | ||||||
|  |       return(result); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void __set_BASEPRI_MAX(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      BASEPRI_MAX,%0"::"r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     #define __enable_fault_irq  __enable_fiq | ||||||
|  |     #define __disable_fault_irq __disable_fiq | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   #endif /* (__CORTEX_M >= 0x03) */ | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) | ||||||
|  |   { | ||||||
|  |     return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ | ||||||
|  |        (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    ) | ||||||
|  | 
 | ||||||
|  |    __IAR_FT uint32_t __get_MSPLIM(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |     #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |          (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3))) | ||||||
|  |       // without main extensions, the non-secure MSPLIM is RAZ/WI
 | ||||||
|  |       res = 0U; | ||||||
|  |     #else | ||||||
|  |       __asm volatile("MRS      %0,MSPLIM" : "=r" (res)); | ||||||
|  |     #endif | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __set_MSPLIM(uint32_t value) | ||||||
|  |     { | ||||||
|  |     #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |          (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3))) | ||||||
|  |       // without main extensions, the non-secure MSPLIM is RAZ/WI
 | ||||||
|  |       (void)value; | ||||||
|  |     #else | ||||||
|  |       __asm volatile("MSR      MSPLIM,%0" :: "r" (value)); | ||||||
|  |     #endif | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t __get_PSPLIM(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |     #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |          (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3))) | ||||||
|  |       // without main extensions, the non-secure PSPLIM is RAZ/WI
 | ||||||
|  |       res = 0U; | ||||||
|  |     #else | ||||||
|  |       __asm volatile("MRS      %0,PSPLIM" : "=r" (res)); | ||||||
|  |     #endif | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __set_PSPLIM(uint32_t value) | ||||||
|  |     { | ||||||
|  |     #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |          (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3))) | ||||||
|  |       // without main extensions, the non-secure PSPLIM is RAZ/WI
 | ||||||
|  |       (void)value; | ||||||
|  |     #else | ||||||
|  |       __asm volatile("MSR      PSPLIM,%0" :: "r" (value)); | ||||||
|  |     #endif | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm volatile("MRS      %0,CONTROL_NS" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __TZ_set_CONTROL_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      CONTROL_NS,%0" :: "r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t   __TZ_get_PSP_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm volatile("MRS      %0,PSP_NS" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __TZ_set_PSP_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      PSP_NS,%0" :: "r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t   __TZ_get_MSP_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm volatile("MRS      %0,MSP_NS" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __TZ_set_MSP_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      MSP_NS,%0" :: "r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t   __TZ_get_SP_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm volatile("MRS      %0,SP_NS" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  |     __IAR_FT void   __TZ_set_SP_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      SP_NS,%0" :: "r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t   __TZ_get_PRIMASK_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm volatile("MRS      %0,PRIMASK_NS" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __TZ_set_PRIMASK_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      PRIMASK_NS,%0" :: "r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t   __TZ_get_BASEPRI_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm volatile("MRS      %0,BASEPRI_NS" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __TZ_set_BASEPRI_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      BASEPRI_NS,%0" :: "r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t   __TZ_get_FAULTMASK_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm volatile("MRS      %0,FAULTMASK_NS" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __TZ_set_FAULTMASK_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      FAULTMASK_NS,%0" :: "r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t   __TZ_get_PSPLIM_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |     #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |          (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3))) | ||||||
|  |       // without main extensions, the non-secure PSPLIM is RAZ/WI
 | ||||||
|  |       res = 0U; | ||||||
|  |     #else | ||||||
|  |       __asm volatile("MRS      %0,PSPLIM_NS" : "=r" (res)); | ||||||
|  |     #endif | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __TZ_set_PSPLIM_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |     #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | ||||||
|  |          (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3))) | ||||||
|  |       // without main extensions, the non-secure PSPLIM is RAZ/WI
 | ||||||
|  |       (void)value; | ||||||
|  |     #else | ||||||
|  |       __asm volatile("MSR      PSPLIM_NS,%0" :: "r" (value)); | ||||||
|  |     #endif | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT uint32_t   __TZ_get_MSPLIM_NS(void) | ||||||
|  |     { | ||||||
|  |       uint32_t res; | ||||||
|  |       __asm volatile("MRS      %0,MSPLIM_NS" : "=r" (res)); | ||||||
|  |       return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     __IAR_FT void   __TZ_set_MSPLIM_NS(uint32_t value) | ||||||
|  |     { | ||||||
|  |       __asm volatile("MSR      MSPLIM_NS,%0" :: "r" (value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ | ||||||
|  | 
 | ||||||
|  | #endif   /* __ICCARM_INTRINSICS_VERSION__ == 2 */ | ||||||
|  | 
 | ||||||
|  | #define __BKPT(value)    __asm volatile ("BKPT     %0" : : "i"(value)) | ||||||
|  | 
 | ||||||
|  | #if __IAR_M0_FAMILY | ||||||
|  |   __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) | ||||||
|  |   { | ||||||
|  |     if ((sat >= 1U) && (sat <= 32U)) | ||||||
|  |     { | ||||||
|  |       const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); | ||||||
|  |       const int32_t min = -1 - max ; | ||||||
|  |       if (val > max) | ||||||
|  |       { | ||||||
|  |         return max; | ||||||
|  |       } | ||||||
|  |       else if (val < min) | ||||||
|  |       { | ||||||
|  |         return min; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return val; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) | ||||||
|  |   { | ||||||
|  |     if (sat <= 31U) | ||||||
|  |     { | ||||||
|  |       const uint32_t max = ((1U << sat) - 1U); | ||||||
|  |       if (val > (int32_t)max) | ||||||
|  |       { | ||||||
|  |         return max; | ||||||
|  |       } | ||||||
|  |       else if (val < 0) | ||||||
|  |       { | ||||||
|  |         return 0U; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return (uint32_t)val; | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if (__CORTEX_M >= 0x03)   /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); | ||||||
|  |     return ((uint8_t)res); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); | ||||||
|  |     return ((uint16_t)res); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); | ||||||
|  |     return res; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) | ||||||
|  |   { | ||||||
|  |     __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) | ||||||
|  |   { | ||||||
|  |     __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) | ||||||
|  |   { | ||||||
|  |     __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | #endif /* (__CORTEX_M >= 0x03) */ | ||||||
|  | 
 | ||||||
|  | #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ | ||||||
|  |      (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | ||||||
|  |     return ((uint8_t)res); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | ||||||
|  |     return ((uint16_t)res); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | ||||||
|  |     return res; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) | ||||||
|  |   { | ||||||
|  |     __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) | ||||||
|  |   { | ||||||
|  |     __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) | ||||||
|  |   { | ||||||
|  |     __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | ||||||
|  |     return ((uint8_t)res); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | ||||||
|  |     return ((uint16_t)res); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | ||||||
|  |     return res; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); | ||||||
|  |     return res; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); | ||||||
|  |     return res; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) | ||||||
|  |   { | ||||||
|  |     uint32_t res; | ||||||
|  |     __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); | ||||||
|  |     return res; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ | ||||||
|  | 
 | ||||||
|  | #undef __IAR_FT | ||||||
|  | #undef __IAR_M0_FAMILY | ||||||
|  | #undef __ICCARM_V8 | ||||||
|  | 
 | ||||||
|  | #pragma diag_default=Pe940 | ||||||
|  | #pragma diag_default=Pe177 | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_ICCARM_H__ */ | ||||||
							
								
								
									
										39
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_version.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								target_f2/Drivers/CMSIS/Core/Include/cmsis_version.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_version.h | ||||||
|  |  * @brief    CMSIS Core(M) Version definitions | ||||||
|  |  * @version  V5.0.2 | ||||||
|  |  * @date     19. April 2017 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2017 ARM Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if   defined ( __ICCARM__ ) | ||||||
|  |   #pragma system_include         /* treat file as system include file for MISRA check */ | ||||||
|  | #elif defined (__clang__) | ||||||
|  |   #pragma clang system_header   /* treat file as system include file */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_VERSION_H | ||||||
|  | #define __CMSIS_VERSION_H | ||||||
|  | 
 | ||||||
|  | /*  CMSIS Version definitions */ | ||||||
|  | #define __CM_CMSIS_VERSION_MAIN  ( 5U)                                      /*!< [31:16] CMSIS Core(M) main version */ | ||||||
|  | #define __CM_CMSIS_VERSION_SUB   ( 1U)                                      /*!< [15:0]  CMSIS Core(M) sub version */ | ||||||
|  | #define __CM_CMSIS_VERSION       ((__CM_CMSIS_VERSION_MAIN << 16U) | \ | ||||||
|  |                                    __CM_CMSIS_VERSION_SUB           )       /*!< CMSIS Core(M) version number */ | ||||||
|  | #endif | ||||||
							
								
								
									
										1918
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_armv8mbl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1918
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_armv8mbl.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2927
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_armv8mml.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2927
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_armv8mml.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										949
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm0.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										949
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm0.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,949 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     core_cm0.h | ||||||
|  |  * @brief    CMSIS Cortex-M0 Core Peripheral Access Layer Header File | ||||||
|  |  * @version  V5.0.5 | ||||||
|  |  * @date     28. May 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if   defined ( __ICCARM__ ) | ||||||
|  |   #pragma system_include         /* treat file as system include file for MISRA check */ | ||||||
|  | #elif defined (__clang__) | ||||||
|  |   #pragma clang system_header   /* treat file as system include file */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __CORE_CM0_H_GENERIC | ||||||
|  | #define __CORE_CM0_H_GENERIC | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions | ||||||
|  |   CMSIS violates the following MISRA-C:2004 rules: | ||||||
|  | 
 | ||||||
|  |    \li Required Rule 8.5, object/function definition in header file.<br> | ||||||
|  |      Function definitions in header files are used to allow 'inlining'. | ||||||
|  | 
 | ||||||
|  |    \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br> | ||||||
|  |      Unions are used for effective representation of core registers. | ||||||
|  | 
 | ||||||
|  |    \li Advisory Rule 19.7, Function-like macro defined.<br> | ||||||
|  |      Function-like macros are used to allow more efficient code. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  *                 CMSIS definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /**
 | ||||||
|  |   \ingroup Cortex_M0 | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "cmsis_version.h" | ||||||
|  |   | ||||||
|  | /*  CMSIS CM0 definitions */ | ||||||
|  | #define __CM0_CMSIS_VERSION_MAIN  (__CM_CMSIS_VERSION_MAIN)              /*!< \deprecated [31:16] CMSIS HAL main version */ | ||||||
|  | #define __CM0_CMSIS_VERSION_SUB   (__CM_CMSIS_VERSION_SUB)               /*!< \deprecated [15:0]  CMSIS HAL sub version */ | ||||||
|  | #define __CM0_CMSIS_VERSION       ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ | ||||||
|  |                                     __CM0_CMSIS_VERSION_SUB           )  /*!< \deprecated CMSIS HAL version number */ | ||||||
|  | 
 | ||||||
|  | #define __CORTEX_M                (0U)                                   /*!< Cortex-M Core */ | ||||||
|  | 
 | ||||||
|  | /** __FPU_USED indicates whether an FPU is used or not.
 | ||||||
|  |     This core does not support an FPU at all | ||||||
|  | */ | ||||||
|  | #define __FPU_USED       0U | ||||||
|  | 
 | ||||||
|  | #if defined ( __CC_ARM ) | ||||||
|  |   #if defined __TARGET_FPU_VFP | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) | ||||||
|  |   #if defined __ARM_PCS_VFP | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __GNUC__ ) | ||||||
|  |   #if defined (__VFP_FP__) && !defined(__SOFTFP__) | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __ICCARM__ ) | ||||||
|  |   #if defined __ARMVFP__ | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __TI_ARM__ ) | ||||||
|  |   #if defined __TI_VFP_SUPPORT__ | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __TASKING__ ) | ||||||
|  |   #if defined __FPU_VFP__ | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __CSMC__ ) | ||||||
|  |   #if ( __CSMC__ & 0x400U) | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "cmsis_compiler.h"               /* CMSIS compiler specific defines */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* __CORE_CM0_H_GENERIC */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_GENERIC | ||||||
|  | 
 | ||||||
|  | #ifndef __CORE_CM0_H_DEPENDANT | ||||||
|  | #define __CORE_CM0_H_DEPENDANT | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* check device defines and use defaults */ | ||||||
|  | #if defined __CHECK_DEVICE_DEFINES | ||||||
|  |   #ifndef __CM0_REV | ||||||
|  |     #define __CM0_REV               0x0000U | ||||||
|  |     #warning "__CM0_REV not defined in device header file; using default!" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #ifndef __NVIC_PRIO_BITS | ||||||
|  |     #define __NVIC_PRIO_BITS          2U | ||||||
|  |     #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #ifndef __Vendor_SysTickConfig | ||||||
|  |     #define __Vendor_SysTickConfig    0U | ||||||
|  |     #warning "__Vendor_SysTickConfig not defined in device header file; using default!" | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* IO definitions (access restrictions to peripheral registers) */ | ||||||
|  | /**
 | ||||||
|  |     \defgroup CMSIS_glob_defs CMSIS Global Defines | ||||||
|  | 
 | ||||||
|  |     <strong>IO Type Qualifiers</strong> are used | ||||||
|  |     \li to specify the access to peripheral variables. | ||||||
|  |     \li for automatic generation of peripheral register debug information. | ||||||
|  | */ | ||||||
|  | #ifdef __cplusplus | ||||||
|  |   #define   __I     volatile             /*!< Defines 'read only' permissions */ | ||||||
|  | #else | ||||||
|  |   #define   __I     volatile const       /*!< Defines 'read only' permissions */ | ||||||
|  | #endif | ||||||
|  | #define     __O     volatile             /*!< Defines 'write only' permissions */ | ||||||
|  | #define     __IO    volatile             /*!< Defines 'read / write' permissions */ | ||||||
|  | 
 | ||||||
|  | /* following defines should be used for structure members */ | ||||||
|  | #define     __IM     volatile const      /*! Defines 'read only' structure member permissions */ | ||||||
|  | #define     __OM     volatile            /*! Defines 'write only' structure member permissions */ | ||||||
|  | #define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group Cortex_M0 */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  *                 Register Abstraction | ||||||
|  |   Core Register contain: | ||||||
|  |   - Core Register | ||||||
|  |   - Core NVIC Register | ||||||
|  |   - Core SCB Register | ||||||
|  |   - Core SysTick Register | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /**
 | ||||||
|  |   \defgroup CMSIS_core_register Defines and Type Definitions | ||||||
|  |   \brief Type definitions and defines for Cortex-M processor based devices. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup    CMSIS_core_register | ||||||
|  |   \defgroup   CMSIS_CORE  Status and Control Registers | ||||||
|  |   \brief      Core Register type definitions. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Union type to access the Application Program Status Register (APSR). | ||||||
|  |  */ | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   struct | ||||||
|  |   { | ||||||
|  |     uint32_t _reserved0:28;              /*!< bit:  0..27  Reserved */ | ||||||
|  |     uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */ | ||||||
|  |     uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */ | ||||||
|  |     uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */ | ||||||
|  |     uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */ | ||||||
|  |   } b;                                   /*!< Structure used for bit  access */ | ||||||
|  |   uint32_t w;                            /*!< Type      used for word access */ | ||||||
|  | } APSR_Type; | ||||||
|  | 
 | ||||||
|  | /* APSR Register Definitions */ | ||||||
|  | #define APSR_N_Pos                         31U                                            /*!< APSR: N Position */ | ||||||
|  | #define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */ | ||||||
|  | 
 | ||||||
|  | #define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */ | ||||||
|  | #define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */ | ||||||
|  | 
 | ||||||
|  | #define APSR_C_Pos                         29U                                            /*!< APSR: C Position */ | ||||||
|  | #define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */ | ||||||
|  | 
 | ||||||
|  | #define APSR_V_Pos                         28U                                            /*!< APSR: V Position */ | ||||||
|  | #define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Union type to access the Interrupt Program Status Register (IPSR). | ||||||
|  |  */ | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   struct | ||||||
|  |   { | ||||||
|  |     uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */ | ||||||
|  |     uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */ | ||||||
|  |   } b;                                   /*!< Structure used for bit  access */ | ||||||
|  |   uint32_t w;                            /*!< Type      used for word access */ | ||||||
|  | } IPSR_Type; | ||||||
|  | 
 | ||||||
|  | /* IPSR Register Definitions */ | ||||||
|  | #define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */ | ||||||
|  | #define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Union type to access the Special-Purpose Program Status Registers (xPSR). | ||||||
|  |  */ | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   struct | ||||||
|  |   { | ||||||
|  |     uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */ | ||||||
|  |     uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */ | ||||||
|  |     uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */ | ||||||
|  |     uint32_t _reserved1:3;               /*!< bit: 25..27  Reserved */ | ||||||
|  |     uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */ | ||||||
|  |     uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */ | ||||||
|  |     uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */ | ||||||
|  |     uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */ | ||||||
|  |   } b;                                   /*!< Structure used for bit  access */ | ||||||
|  |   uint32_t w;                            /*!< Type      used for word access */ | ||||||
|  | } xPSR_Type; | ||||||
|  | 
 | ||||||
|  | /* xPSR Register Definitions */ | ||||||
|  | #define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */ | ||||||
|  | #define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */ | ||||||
|  | #define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */ | ||||||
|  | #define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */ | ||||||
|  | #define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */ | ||||||
|  | #define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */ | ||||||
|  | #define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Union type to access the Control Registers (CONTROL). | ||||||
|  |  */ | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   struct | ||||||
|  |   { | ||||||
|  |     uint32_t _reserved0:1;               /*!< bit:      0  Reserved */ | ||||||
|  |     uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */ | ||||||
|  |     uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */ | ||||||
|  |   } b;                                   /*!< Structure used for bit  access */ | ||||||
|  |   uint32_t w;                            /*!< Type      used for word access */ | ||||||
|  | } CONTROL_Type; | ||||||
|  | 
 | ||||||
|  | /* CONTROL Register Definitions */ | ||||||
|  | #define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */ | ||||||
|  | #define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_CORE */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup    CMSIS_core_register | ||||||
|  |   \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC) | ||||||
|  |   \brief      Type definitions for the NVIC Registers | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC). | ||||||
|  |  */ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   __IOM uint32_t ISER[1U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */ | ||||||
|  |         uint32_t RESERVED0[31U]; | ||||||
|  |   __IOM uint32_t ICER[1U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */ | ||||||
|  |         uint32_t RSERVED1[31U]; | ||||||
|  |   __IOM uint32_t ISPR[1U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */ | ||||||
|  |         uint32_t RESERVED2[31U]; | ||||||
|  |   __IOM uint32_t ICPR[1U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */ | ||||||
|  |         uint32_t RESERVED3[31U]; | ||||||
|  |         uint32_t RESERVED4[64U]; | ||||||
|  |   __IOM uint32_t IP[8U];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register */ | ||||||
|  | }  NVIC_Type; | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_NVIC */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_core_register | ||||||
|  |   \defgroup CMSIS_SCB     System Control Block (SCB) | ||||||
|  |   \brief    Type definitions for the System Control Block Registers | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Structure type to access the System Control Block (SCB). | ||||||
|  |  */ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */ | ||||||
|  |   __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */ | ||||||
|  |         uint32_t RESERVED0; | ||||||
|  |   __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */ | ||||||
|  |   __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */ | ||||||
|  |   __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */ | ||||||
|  |         uint32_t RESERVED1; | ||||||
|  |   __IOM uint32_t SHP[2U];                /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */ | ||||||
|  |   __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */ | ||||||
|  | } SCB_Type; | ||||||
|  | 
 | ||||||
|  | /* SCB CPUID Register Definitions */ | ||||||
|  | #define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */ | ||||||
|  | #define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */ | ||||||
|  | #define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */ | ||||||
|  | #define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */ | ||||||
|  | #define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */ | ||||||
|  | #define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB Interrupt Control State Register Definitions */ | ||||||
|  | #define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */ | ||||||
|  | #define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */ | ||||||
|  | #define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */ | ||||||
|  | #define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */ | ||||||
|  | #define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */ | ||||||
|  | #define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */ | ||||||
|  | #define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */ | ||||||
|  | #define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */ | ||||||
|  | #define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */ | ||||||
|  | #define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB Application Interrupt and Reset Control Register Definitions */ | ||||||
|  | #define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */ | ||||||
|  | #define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */ | ||||||
|  | #define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */ | ||||||
|  | #define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */ | ||||||
|  | #define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */ | ||||||
|  | #define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB System Control Register Definitions */ | ||||||
|  | #define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */ | ||||||
|  | #define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */ | ||||||
|  | #define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */ | ||||||
|  | #define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB Configuration Control Register Definitions */ | ||||||
|  | #define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */ | ||||||
|  | #define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */ | ||||||
|  | #define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB System Handler Control and State Register Definitions */ | ||||||
|  | #define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */ | ||||||
|  | #define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_SCB */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_core_register | ||||||
|  |   \defgroup CMSIS_SysTick     System Tick Timer (SysTick) | ||||||
|  |   \brief    Type definitions for the System Timer Registers. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Structure type to access the System Timer (SysTick). | ||||||
|  |  */ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */ | ||||||
|  |   __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */ | ||||||
|  |   __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */ | ||||||
|  |   __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */ | ||||||
|  | } SysTick_Type; | ||||||
|  | 
 | ||||||
|  | /* SysTick Control / Status Register Definitions */ | ||||||
|  | #define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */ | ||||||
|  | #define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */ | ||||||
|  | #define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */ | ||||||
|  | #define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */ | ||||||
|  | #define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */ | ||||||
|  | 
 | ||||||
|  | /* SysTick Reload Register Definitions */ | ||||||
|  | #define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */ | ||||||
|  | #define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */ | ||||||
|  | 
 | ||||||
|  | /* SysTick Current Register Definitions */ | ||||||
|  | #define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */ | ||||||
|  | #define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */ | ||||||
|  | 
 | ||||||
|  | /* SysTick Calibration Register Definitions */ | ||||||
|  | #define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */ | ||||||
|  | #define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */ | ||||||
|  | #define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */ | ||||||
|  | #define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_SysTick */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_core_register | ||||||
|  |   \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug) | ||||||
|  |   \brief    Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. | ||||||
|  |             Therefore they are not covered by the Cortex-M0 header file. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | /*@} end of group CMSIS_CoreDebug */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup    CMSIS_core_register | ||||||
|  |   \defgroup   CMSIS_core_bitfield     Core register bit field macros | ||||||
|  |   \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk). | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Mask and shift a bit field value for use in a register bit range. | ||||||
|  |   \param[in] field  Name of the register bit field. | ||||||
|  |   \param[in] value  Value of the bit field. This parameter is interpreted as an uint32_t type. | ||||||
|  |   \return           Masked and shifted value. | ||||||
|  | */ | ||||||
|  | #define _VAL2FLD(field, value)    (((uint32_t)(value) << field ## _Pos) & field ## _Msk) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief     Mask and shift a register value to extract a bit filed value. | ||||||
|  |   \param[in] field  Name of the register bit field. | ||||||
|  |   \param[in] value  Value of register. This parameter is interpreted as an uint32_t type. | ||||||
|  |   \return           Masked and shifted bit field value. | ||||||
|  | */ | ||||||
|  | #define _FLD2VAL(field, value)    (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_core_bitfield */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup    CMSIS_core_register | ||||||
|  |   \defgroup   CMSIS_core_base     Core Definitions | ||||||
|  |   \brief      Definitions for base addresses, unions, and structures. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* Memory mapping of Core Hardware */ | ||||||
|  | #define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */ | ||||||
|  | #define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */ | ||||||
|  | #define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */ | ||||||
|  | #define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */ | ||||||
|  | 
 | ||||||
|  | #define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */ | ||||||
|  | #define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */ | ||||||
|  | #define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*@} */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  *                Hardware Abstraction Layer | ||||||
|  |   Core Function Interface contains: | ||||||
|  |   - Core NVIC Functions | ||||||
|  |   - Core SysTick Functions | ||||||
|  |   - Core Register Access Functions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /**
 | ||||||
|  |   \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ##########################   NVIC functions  #################################### */ | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_Core_FunctionInterface | ||||||
|  |   \defgroup CMSIS_Core_NVICFunctions NVIC Functions | ||||||
|  |   \brief    Functions that manage interrupts and exceptions via the NVIC. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifdef CMSIS_NVIC_VIRTUAL | ||||||
|  |   #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE | ||||||
|  |     #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" | ||||||
|  |   #endif | ||||||
|  |   #include CMSIS_NVIC_VIRTUAL_HEADER_FILE | ||||||
|  | #else | ||||||
|  |   #define NVIC_SetPriorityGrouping    __NVIC_SetPriorityGrouping | ||||||
|  |   #define NVIC_GetPriorityGrouping    __NVIC_GetPriorityGrouping | ||||||
|  |   #define NVIC_EnableIRQ              __NVIC_EnableIRQ | ||||||
|  |   #define NVIC_GetEnableIRQ           __NVIC_GetEnableIRQ | ||||||
|  |   #define NVIC_DisableIRQ             __NVIC_DisableIRQ | ||||||
|  |   #define NVIC_GetPendingIRQ          __NVIC_GetPendingIRQ | ||||||
|  |   #define NVIC_SetPendingIRQ          __NVIC_SetPendingIRQ | ||||||
|  |   #define NVIC_ClearPendingIRQ        __NVIC_ClearPendingIRQ | ||||||
|  | /*#define NVIC_GetActive              __NVIC_GetActive             not available for Cortex-M0 */ | ||||||
|  |   #define NVIC_SetPriority            __NVIC_SetPriority | ||||||
|  |   #define NVIC_GetPriority            __NVIC_GetPriority | ||||||
|  |   #define NVIC_SystemReset            __NVIC_SystemReset | ||||||
|  | #endif /* CMSIS_NVIC_VIRTUAL */ | ||||||
|  | 
 | ||||||
|  | #ifdef CMSIS_VECTAB_VIRTUAL | ||||||
|  |   #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE | ||||||
|  |     #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" | ||||||
|  |   #endif | ||||||
|  |   #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE | ||||||
|  | #else | ||||||
|  |   #define NVIC_SetVector              __NVIC_SetVector | ||||||
|  |   #define NVIC_GetVector              __NVIC_GetVector | ||||||
|  | #endif  /* (CMSIS_VECTAB_VIRTUAL) */ | ||||||
|  | 
 | ||||||
|  | #define NVIC_USER_IRQ_OFFSET          16 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* The following EXC_RETURN values are saved the LR on exception entry */ | ||||||
|  | #define EXC_RETURN_HANDLER         (0xFFFFFFF1UL)     /* return to Handler mode, uses MSP after return                               */ | ||||||
|  | #define EXC_RETURN_THREAD_MSP      (0xFFFFFFF9UL)     /* return to Thread mode, uses MSP after return                                */ | ||||||
|  | #define EXC_RETURN_THREAD_PSP      (0xFFFFFFFDUL)     /* return to Thread mode, uses PSP after return                                */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Interrupt Priorities are WORD accessible only under Armv6-M                  */ | ||||||
|  | /* The following MACROS handle generation of the register offset and byte masks */ | ||||||
|  | #define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL) | ||||||
|  | #define _SHP_IDX(IRQn)           ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >>    2UL)      ) | ||||||
|  | #define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      ) | ||||||
|  | 
 | ||||||
|  | #define __NVIC_SetPriorityGrouping(X) (void)(X) | ||||||
|  | #define __NVIC_GetPriorityGrouping()  (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Enable Interrupt | ||||||
|  |   \details Enables a device specific interrupt in the NVIC interrupt controller. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Interrupt Enable status | ||||||
|  |   \details Returns a device specific interrupt enable status from the NVIC interrupt controller. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \return             0  Interrupt is not enabled. | ||||||
|  |   \return             1  Interrupt is enabled. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     return(0U); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Disable Interrupt | ||||||
|  |   \details Disables a device specific interrupt in the NVIC interrupt controller. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | ||||||
|  |     __DSB(); | ||||||
|  |     __ISB(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Pending Interrupt | ||||||
|  |   \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \return             0  Interrupt status is not pending. | ||||||
|  |   \return             1  Interrupt status is pending. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     return(0U); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Pending Interrupt | ||||||
|  |   \details Sets the pending bit of a device specific interrupt in the NVIC pending register. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Clear Pending Interrupt | ||||||
|  |   \details Clears the pending bit of a device specific interrupt in the NVIC pending register. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Interrupt Priority | ||||||
|  |   \details Sets the priority of a device specific interrupt or a processor exception. | ||||||
|  |            The interrupt number can be positive to specify a device specific interrupt, | ||||||
|  |            or negative to specify a processor exception. | ||||||
|  |   \param [in]      IRQn  Interrupt number. | ||||||
|  |   \param [in]  priority  Priority to set. | ||||||
|  |   \note    The priority cannot be set for every processor exception. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) | | ||||||
|  |        (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | | ||||||
|  |        (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Interrupt Priority | ||||||
|  |   \details Reads the priority of a device specific interrupt or a processor exception. | ||||||
|  |            The interrupt number can be positive to specify a device specific interrupt, | ||||||
|  |            or negative to specify a processor exception. | ||||||
|  |   \param [in]   IRQn  Interrupt number. | ||||||
|  |   \return             Interrupt Priority. | ||||||
|  |                       Value is aligned automatically to the implemented priority bits of the microcontroller. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Encode Priority | ||||||
|  |   \details Encodes the priority for an interrupt with the given priority group, | ||||||
|  |            preemptive priority value, and subpriority value. | ||||||
|  |            In case of a conflict between priority grouping and available | ||||||
|  |            priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. | ||||||
|  |   \param [in]     PriorityGroup  Used priority group. | ||||||
|  |   \param [in]   PreemptPriority  Preemptive priority value (starting from 0). | ||||||
|  |   \param [in]       SubPriority  Subpriority value (starting from 0). | ||||||
|  |   \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) | ||||||
|  | { | ||||||
|  |   uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */ | ||||||
|  |   uint32_t PreemptPriorityBits; | ||||||
|  |   uint32_t SubPriorityBits; | ||||||
|  | 
 | ||||||
|  |   PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); | ||||||
|  |   SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |            ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | | ||||||
|  |            ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL))) | ||||||
|  |          ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Decode Priority | ||||||
|  |   \details Decodes an interrupt priority value with a given priority group to | ||||||
|  |            preemptive priority value and subpriority value. | ||||||
|  |            In case of a conflict between priority grouping and available | ||||||
|  |            priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. | ||||||
|  |   \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). | ||||||
|  |   \param [in]     PriorityGroup  Used priority group. | ||||||
|  |   \param [out] pPreemptPriority  Preemptive priority value (starting from 0). | ||||||
|  |   \param [out]     pSubPriority  Subpriority value (starting from 0). | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) | ||||||
|  | { | ||||||
|  |   uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */ | ||||||
|  |   uint32_t PreemptPriorityBits; | ||||||
|  |   uint32_t SubPriorityBits; | ||||||
|  | 
 | ||||||
|  |   PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); | ||||||
|  |   SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); | ||||||
|  | 
 | ||||||
|  |   *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); | ||||||
|  |   *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Interrupt Vector | ||||||
|  |   \details Sets an interrupt vector in SRAM based interrupt vector table. | ||||||
|  |            The interrupt number can be positive to specify a device specific interrupt, | ||||||
|  |            or negative to specify a processor exception. | ||||||
|  |            Address 0 must be mapped to SRAM. | ||||||
|  |   \param [in]   IRQn      Interrupt number | ||||||
|  |   \param [in]   vector    Address of interrupt handler function | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) | ||||||
|  | { | ||||||
|  |   uint32_t *vectors = (uint32_t *)0x0U; | ||||||
|  |   vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Interrupt Vector | ||||||
|  |   \details Reads an interrupt vector from interrupt vector table. | ||||||
|  |            The interrupt number can be positive to specify a device specific interrupt, | ||||||
|  |            or negative to specify a processor exception. | ||||||
|  |   \param [in]   IRQn      Interrupt number. | ||||||
|  |   \return                 Address of interrupt handler function | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   uint32_t *vectors = (uint32_t *)0x0U; | ||||||
|  |   return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   System Reset | ||||||
|  |   \details Initiates a system reset request to reset the MCU. | ||||||
|  |  */ | ||||||
|  | __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) | ||||||
|  | { | ||||||
|  |   __DSB();                                                          /* Ensure all outstanding memory accesses included
 | ||||||
|  |                                                                        buffered write are completed before reset */ | ||||||
|  |   SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | | ||||||
|  |                  SCB_AIRCR_SYSRESETREQ_Msk); | ||||||
|  |   __DSB();                                                          /* Ensure completion of memory access */ | ||||||
|  | 
 | ||||||
|  |   for(;;)                                                           /* wait until reset */ | ||||||
|  |   { | ||||||
|  |     __NOP(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*@} end of CMSIS_Core_NVICFunctions */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ##########################  FPU functions  #################################### */ | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_Core_FunctionInterface | ||||||
|  |   \defgroup CMSIS_Core_FpuFunctions FPU Functions | ||||||
|  |   \brief    Function that provides FPU type. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   get FPU type | ||||||
|  |   \details returns the FPU type | ||||||
|  |   \returns | ||||||
|  |    - \b  0: No FPU | ||||||
|  |    - \b  1: Single precision FPU | ||||||
|  |    - \b  2: Double + Single precision FPU | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t SCB_GetFPUType(void) | ||||||
|  | { | ||||||
|  |     return 0U;           /* No FPU */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*@} end of CMSIS_Core_FpuFunctions */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ##################################    SysTick function  ############################################ */ | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_Core_FunctionInterface | ||||||
|  |   \defgroup CMSIS_Core_SysTickFunctions SysTick Functions | ||||||
|  |   \brief    Functions that configure the System. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   System Tick Configuration | ||||||
|  |   \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. | ||||||
|  |            Counter is in free running mode to generate periodic interrupts. | ||||||
|  |   \param [in]  ticks  Number of ticks between two interrupts. | ||||||
|  |   \return          0  Function succeeded. | ||||||
|  |   \return          1  Function failed. | ||||||
|  |   \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the | ||||||
|  |            function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> | ||||||
|  |            must contain a vendor-specific implementation of this function. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) | ||||||
|  | { | ||||||
|  |   if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) | ||||||
|  |   { | ||||||
|  |     return (1UL);                                                   /* Reload value impossible */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */ | ||||||
|  |   NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ | ||||||
|  |   SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */ | ||||||
|  |   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | | ||||||
|  |                    SysTick_CTRL_TICKINT_Msk   | | ||||||
|  |                    SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */ | ||||||
|  |   return (0UL);                                                     /* Function successful */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*@} end of CMSIS_Core_SysTickFunctions */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* __CORE_CM0_H_DEPENDANT */ | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_GENERIC */ | ||||||
							
								
								
									
										1083
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm0plus.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1083
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm0plus.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										976
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm1.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										976
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm1.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,976 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     core_cm1.h | ||||||
|  |  * @brief    CMSIS Cortex-M1 Core Peripheral Access Layer Header File | ||||||
|  |  * @version  V1.0.0 | ||||||
|  |  * @date     23. July 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if   defined ( __ICCARM__ ) | ||||||
|  |   #pragma system_include         /* treat file as system include file for MISRA check */ | ||||||
|  | #elif defined (__clang__) | ||||||
|  |   #pragma clang system_header   /* treat file as system include file */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __CORE_CM1_H_GENERIC | ||||||
|  | #define __CORE_CM1_H_GENERIC | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions | ||||||
|  |   CMSIS violates the following MISRA-C:2004 rules: | ||||||
|  | 
 | ||||||
|  |    \li Required Rule 8.5, object/function definition in header file.<br> | ||||||
|  |      Function definitions in header files are used to allow 'inlining'. | ||||||
|  | 
 | ||||||
|  |    \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br> | ||||||
|  |      Unions are used for effective representation of core registers. | ||||||
|  | 
 | ||||||
|  |    \li Advisory Rule 19.7, Function-like macro defined.<br> | ||||||
|  |      Function-like macros are used to allow more efficient code. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  *                 CMSIS definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /**
 | ||||||
|  |   \ingroup Cortex_M1 | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "cmsis_version.h" | ||||||
|  |   | ||||||
|  | /*  CMSIS CM1 definitions */ | ||||||
|  | #define __CM1_CMSIS_VERSION_MAIN  (__CM_CMSIS_VERSION_MAIN)              /*!< \deprecated [31:16] CMSIS HAL main version */ | ||||||
|  | #define __CM1_CMSIS_VERSION_SUB   (__CM_CMSIS_VERSION_SUB)               /*!< \deprecated [15:0]  CMSIS HAL sub version */ | ||||||
|  | #define __CM1_CMSIS_VERSION       ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ | ||||||
|  |                                     __CM1_CMSIS_VERSION_SUB           )  /*!< \deprecated CMSIS HAL version number */ | ||||||
|  | 
 | ||||||
|  | #define __CORTEX_M                (1U)                                   /*!< Cortex-M Core */ | ||||||
|  | 
 | ||||||
|  | /** __FPU_USED indicates whether an FPU is used or not.
 | ||||||
|  |     This core does not support an FPU at all | ||||||
|  | */ | ||||||
|  | #define __FPU_USED       0U | ||||||
|  | 
 | ||||||
|  | #if defined ( __CC_ARM ) | ||||||
|  |   #if defined __TARGET_FPU_VFP | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) | ||||||
|  |   #if defined __ARM_PCS_VFP | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __GNUC__ ) | ||||||
|  |   #if defined (__VFP_FP__) && !defined(__SOFTFP__) | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __ICCARM__ ) | ||||||
|  |   #if defined __ARMVFP__ | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __TI_ARM__ ) | ||||||
|  |   #if defined __TI_VFP_SUPPORT__ | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __TASKING__ ) | ||||||
|  |   #if defined __FPU_VFP__ | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #elif defined ( __CSMC__ ) | ||||||
|  |   #if ( __CSMC__ & 0x400U) | ||||||
|  |     #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "cmsis_compiler.h"               /* CMSIS compiler specific defines */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* __CORE_CM1_H_GENERIC */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_GENERIC | ||||||
|  | 
 | ||||||
|  | #ifndef __CORE_CM1_H_DEPENDANT | ||||||
|  | #define __CORE_CM1_H_DEPENDANT | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* check device defines and use defaults */ | ||||||
|  | #if defined __CHECK_DEVICE_DEFINES | ||||||
|  |   #ifndef __CM1_REV | ||||||
|  |     #define __CM1_REV               0x0100U | ||||||
|  |     #warning "__CM1_REV not defined in device header file; using default!" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #ifndef __NVIC_PRIO_BITS | ||||||
|  |     #define __NVIC_PRIO_BITS          2U | ||||||
|  |     #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #ifndef __Vendor_SysTickConfig | ||||||
|  |     #define __Vendor_SysTickConfig    0U | ||||||
|  |     #warning "__Vendor_SysTickConfig not defined in device header file; using default!" | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* IO definitions (access restrictions to peripheral registers) */ | ||||||
|  | /**
 | ||||||
|  |     \defgroup CMSIS_glob_defs CMSIS Global Defines | ||||||
|  | 
 | ||||||
|  |     <strong>IO Type Qualifiers</strong> are used | ||||||
|  |     \li to specify the access to peripheral variables. | ||||||
|  |     \li for automatic generation of peripheral register debug information. | ||||||
|  | */ | ||||||
|  | #ifdef __cplusplus | ||||||
|  |   #define   __I     volatile             /*!< Defines 'read only' permissions */ | ||||||
|  | #else | ||||||
|  |   #define   __I     volatile const       /*!< Defines 'read only' permissions */ | ||||||
|  | #endif | ||||||
|  | #define     __O     volatile             /*!< Defines 'write only' permissions */ | ||||||
|  | #define     __IO    volatile             /*!< Defines 'read / write' permissions */ | ||||||
|  | 
 | ||||||
|  | /* following defines should be used for structure members */ | ||||||
|  | #define     __IM     volatile const      /*! Defines 'read only' structure member permissions */ | ||||||
|  | #define     __OM     volatile            /*! Defines 'write only' structure member permissions */ | ||||||
|  | #define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group Cortex_M1 */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  *                 Register Abstraction | ||||||
|  |   Core Register contain: | ||||||
|  |   - Core Register | ||||||
|  |   - Core NVIC Register | ||||||
|  |   - Core SCB Register | ||||||
|  |   - Core SysTick Register | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /**
 | ||||||
|  |   \defgroup CMSIS_core_register Defines and Type Definitions | ||||||
|  |   \brief Type definitions and defines for Cortex-M processor based devices. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup    CMSIS_core_register | ||||||
|  |   \defgroup   CMSIS_CORE  Status and Control Registers | ||||||
|  |   \brief      Core Register type definitions. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Union type to access the Application Program Status Register (APSR). | ||||||
|  |  */ | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   struct | ||||||
|  |   { | ||||||
|  |     uint32_t _reserved0:28;              /*!< bit:  0..27  Reserved */ | ||||||
|  |     uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */ | ||||||
|  |     uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */ | ||||||
|  |     uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */ | ||||||
|  |     uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */ | ||||||
|  |   } b;                                   /*!< Structure used for bit  access */ | ||||||
|  |   uint32_t w;                            /*!< Type      used for word access */ | ||||||
|  | } APSR_Type; | ||||||
|  | 
 | ||||||
|  | /* APSR Register Definitions */ | ||||||
|  | #define APSR_N_Pos                         31U                                            /*!< APSR: N Position */ | ||||||
|  | #define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */ | ||||||
|  | 
 | ||||||
|  | #define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */ | ||||||
|  | #define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */ | ||||||
|  | 
 | ||||||
|  | #define APSR_C_Pos                         29U                                            /*!< APSR: C Position */ | ||||||
|  | #define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */ | ||||||
|  | 
 | ||||||
|  | #define APSR_V_Pos                         28U                                            /*!< APSR: V Position */ | ||||||
|  | #define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Union type to access the Interrupt Program Status Register (IPSR). | ||||||
|  |  */ | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   struct | ||||||
|  |   { | ||||||
|  |     uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */ | ||||||
|  |     uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */ | ||||||
|  |   } b;                                   /*!< Structure used for bit  access */ | ||||||
|  |   uint32_t w;                            /*!< Type      used for word access */ | ||||||
|  | } IPSR_Type; | ||||||
|  | 
 | ||||||
|  | /* IPSR Register Definitions */ | ||||||
|  | #define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */ | ||||||
|  | #define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Union type to access the Special-Purpose Program Status Registers (xPSR). | ||||||
|  |  */ | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   struct | ||||||
|  |   { | ||||||
|  |     uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */ | ||||||
|  |     uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */ | ||||||
|  |     uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */ | ||||||
|  |     uint32_t _reserved1:3;               /*!< bit: 25..27  Reserved */ | ||||||
|  |     uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */ | ||||||
|  |     uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */ | ||||||
|  |     uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */ | ||||||
|  |     uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */ | ||||||
|  |   } b;                                   /*!< Structure used for bit  access */ | ||||||
|  |   uint32_t w;                            /*!< Type      used for word access */ | ||||||
|  | } xPSR_Type; | ||||||
|  | 
 | ||||||
|  | /* xPSR Register Definitions */ | ||||||
|  | #define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */ | ||||||
|  | #define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */ | ||||||
|  | #define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */ | ||||||
|  | #define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */ | ||||||
|  | #define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */ | ||||||
|  | #define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */ | ||||||
|  | 
 | ||||||
|  | #define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */ | ||||||
|  | #define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Union type to access the Control Registers (CONTROL). | ||||||
|  |  */ | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   struct | ||||||
|  |   { | ||||||
|  |     uint32_t _reserved0:1;               /*!< bit:      0  Reserved */ | ||||||
|  |     uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */ | ||||||
|  |     uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */ | ||||||
|  |   } b;                                   /*!< Structure used for bit  access */ | ||||||
|  |   uint32_t w;                            /*!< Type      used for word access */ | ||||||
|  | } CONTROL_Type; | ||||||
|  | 
 | ||||||
|  | /* CONTROL Register Definitions */ | ||||||
|  | #define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */ | ||||||
|  | #define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_CORE */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup    CMSIS_core_register | ||||||
|  |   \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC) | ||||||
|  |   \brief      Type definitions for the NVIC Registers | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC). | ||||||
|  |  */ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   __IOM uint32_t ISER[1U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */ | ||||||
|  |         uint32_t RESERVED0[31U]; | ||||||
|  |   __IOM uint32_t ICER[1U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */ | ||||||
|  |         uint32_t RSERVED1[31U]; | ||||||
|  |   __IOM uint32_t ISPR[1U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */ | ||||||
|  |         uint32_t RESERVED2[31U]; | ||||||
|  |   __IOM uint32_t ICPR[1U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */ | ||||||
|  |         uint32_t RESERVED3[31U]; | ||||||
|  |         uint32_t RESERVED4[64U]; | ||||||
|  |   __IOM uint32_t IP[8U];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register */ | ||||||
|  | }  NVIC_Type; | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_NVIC */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_core_register | ||||||
|  |   \defgroup CMSIS_SCB     System Control Block (SCB) | ||||||
|  |   \brief    Type definitions for the System Control Block Registers | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Structure type to access the System Control Block (SCB). | ||||||
|  |  */ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */ | ||||||
|  |   __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */ | ||||||
|  |         uint32_t RESERVED0; | ||||||
|  |   __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */ | ||||||
|  |   __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */ | ||||||
|  |   __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */ | ||||||
|  |         uint32_t RESERVED1; | ||||||
|  |   __IOM uint32_t SHP[2U];                /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */ | ||||||
|  |   __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */ | ||||||
|  | } SCB_Type; | ||||||
|  | 
 | ||||||
|  | /* SCB CPUID Register Definitions */ | ||||||
|  | #define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */ | ||||||
|  | #define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */ | ||||||
|  | #define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */ | ||||||
|  | #define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */ | ||||||
|  | #define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */ | ||||||
|  | #define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB Interrupt Control State Register Definitions */ | ||||||
|  | #define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */ | ||||||
|  | #define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */ | ||||||
|  | #define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */ | ||||||
|  | #define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */ | ||||||
|  | #define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */ | ||||||
|  | #define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */ | ||||||
|  | #define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */ | ||||||
|  | #define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */ | ||||||
|  | #define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */ | ||||||
|  | #define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB Application Interrupt and Reset Control Register Definitions */ | ||||||
|  | #define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */ | ||||||
|  | #define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */ | ||||||
|  | #define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */ | ||||||
|  | #define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */ | ||||||
|  | #define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */ | ||||||
|  | #define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB System Control Register Definitions */ | ||||||
|  | #define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */ | ||||||
|  | #define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */ | ||||||
|  | #define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */ | ||||||
|  | #define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB Configuration Control Register Definitions */ | ||||||
|  | #define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */ | ||||||
|  | #define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */ | ||||||
|  | #define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */ | ||||||
|  | 
 | ||||||
|  | /* SCB System Handler Control and State Register Definitions */ | ||||||
|  | #define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */ | ||||||
|  | #define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_SCB */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_core_register | ||||||
|  |   \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) | ||||||
|  |   \brief    Type definitions for the System Control and ID Register not in the SCB | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Structure type to access the System Control and ID Register not in the SCB. | ||||||
|  |  */ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |         uint32_t RESERVED0[2U]; | ||||||
|  |   __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */ | ||||||
|  | } SCnSCB_Type; | ||||||
|  | 
 | ||||||
|  | /* Auxiliary Control Register Definitions */ | ||||||
|  | #define SCnSCB_ACTLR_ITCMUAEN_Pos            4U                                        /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ | ||||||
|  | #define SCnSCB_ACTLR_ITCMUAEN_Msk           (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos)         /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ | ||||||
|  | 
 | ||||||
|  | #define SCnSCB_ACTLR_ITCMLAEN_Pos            3U                                        /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ | ||||||
|  | #define SCnSCB_ACTLR_ITCMLAEN_Msk           (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos)         /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_SCnotSCB */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_core_register | ||||||
|  |   \defgroup CMSIS_SysTick     System Tick Timer (SysTick) | ||||||
|  |   \brief    Type definitions for the System Timer Registers. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief  Structure type to access the System Timer (SysTick). | ||||||
|  |  */ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */ | ||||||
|  |   __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */ | ||||||
|  |   __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */ | ||||||
|  |   __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */ | ||||||
|  | } SysTick_Type; | ||||||
|  | 
 | ||||||
|  | /* SysTick Control / Status Register Definitions */ | ||||||
|  | #define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */ | ||||||
|  | #define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */ | ||||||
|  | #define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */ | ||||||
|  | #define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */ | ||||||
|  | #define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */ | ||||||
|  | 
 | ||||||
|  | /* SysTick Reload Register Definitions */ | ||||||
|  | #define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */ | ||||||
|  | #define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */ | ||||||
|  | 
 | ||||||
|  | /* SysTick Current Register Definitions */ | ||||||
|  | #define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */ | ||||||
|  | #define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */ | ||||||
|  | 
 | ||||||
|  | /* SysTick Calibration Register Definitions */ | ||||||
|  | #define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */ | ||||||
|  | #define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */ | ||||||
|  | #define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */ | ||||||
|  | 
 | ||||||
|  | #define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */ | ||||||
|  | #define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */ | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_SysTick */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_core_register | ||||||
|  |   \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug) | ||||||
|  |   \brief    Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. | ||||||
|  |             Therefore they are not covered by the Cortex-M1 header file. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | /*@} end of group CMSIS_CoreDebug */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup    CMSIS_core_register | ||||||
|  |   \defgroup   CMSIS_core_bitfield     Core register bit field macros | ||||||
|  |   \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk). | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Mask and shift a bit field value for use in a register bit range. | ||||||
|  |   \param[in] field  Name of the register bit field. | ||||||
|  |   \param[in] value  Value of the bit field. This parameter is interpreted as an uint32_t type. | ||||||
|  |   \return           Masked and shifted value. | ||||||
|  | */ | ||||||
|  | #define _VAL2FLD(field, value)    (((uint32_t)(value) << field ## _Pos) & field ## _Msk) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief     Mask and shift a register value to extract a bit filed value. | ||||||
|  |   \param[in] field  Name of the register bit field. | ||||||
|  |   \param[in] value  Value of register. This parameter is interpreted as an uint32_t type. | ||||||
|  |   \return           Masked and shifted bit field value. | ||||||
|  | */ | ||||||
|  | #define _FLD2VAL(field, value)    (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) | ||||||
|  | 
 | ||||||
|  | /*@} end of group CMSIS_core_bitfield */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \ingroup    CMSIS_core_register | ||||||
|  |   \defgroup   CMSIS_core_base     Core Definitions | ||||||
|  |   \brief      Definitions for base addresses, unions, and structures. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* Memory mapping of Core Hardware */ | ||||||
|  | #define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */ | ||||||
|  | #define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */ | ||||||
|  | #define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */ | ||||||
|  | #define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */ | ||||||
|  | 
 | ||||||
|  | #define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */ | ||||||
|  | #define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */ | ||||||
|  | #define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */ | ||||||
|  | #define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*@} */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  *                Hardware Abstraction Layer | ||||||
|  |   Core Function Interface contains: | ||||||
|  |   - Core NVIC Functions | ||||||
|  |   - Core SysTick Functions | ||||||
|  |   - Core Register Access Functions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /**
 | ||||||
|  |   \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ##########################   NVIC functions  #################################### */ | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_Core_FunctionInterface | ||||||
|  |   \defgroup CMSIS_Core_NVICFunctions NVIC Functions | ||||||
|  |   \brief    Functions that manage interrupts and exceptions via the NVIC. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifdef CMSIS_NVIC_VIRTUAL | ||||||
|  |   #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE | ||||||
|  |     #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" | ||||||
|  |   #endif | ||||||
|  |   #include CMSIS_NVIC_VIRTUAL_HEADER_FILE | ||||||
|  | #else | ||||||
|  |   #define NVIC_SetPriorityGrouping    __NVIC_SetPriorityGrouping | ||||||
|  |   #define NVIC_GetPriorityGrouping    __NVIC_GetPriorityGrouping | ||||||
|  |   #define NVIC_EnableIRQ              __NVIC_EnableIRQ | ||||||
|  |   #define NVIC_GetEnableIRQ           __NVIC_GetEnableIRQ | ||||||
|  |   #define NVIC_DisableIRQ             __NVIC_DisableIRQ | ||||||
|  |   #define NVIC_GetPendingIRQ          __NVIC_GetPendingIRQ | ||||||
|  |   #define NVIC_SetPendingIRQ          __NVIC_SetPendingIRQ | ||||||
|  |   #define NVIC_ClearPendingIRQ        __NVIC_ClearPendingIRQ | ||||||
|  | /*#define NVIC_GetActive              __NVIC_GetActive             not available for Cortex-M1 */ | ||||||
|  |   #define NVIC_SetPriority            __NVIC_SetPriority | ||||||
|  |   #define NVIC_GetPriority            __NVIC_GetPriority | ||||||
|  |   #define NVIC_SystemReset            __NVIC_SystemReset | ||||||
|  | #endif /* CMSIS_NVIC_VIRTUAL */ | ||||||
|  | 
 | ||||||
|  | #ifdef CMSIS_VECTAB_VIRTUAL | ||||||
|  |   #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE | ||||||
|  |     #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" | ||||||
|  |   #endif | ||||||
|  |   #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE | ||||||
|  | #else | ||||||
|  |   #define NVIC_SetVector              __NVIC_SetVector | ||||||
|  |   #define NVIC_GetVector              __NVIC_GetVector | ||||||
|  | #endif  /* (CMSIS_VECTAB_VIRTUAL) */ | ||||||
|  | 
 | ||||||
|  | #define NVIC_USER_IRQ_OFFSET          16 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* The following EXC_RETURN values are saved the LR on exception entry */ | ||||||
|  | #define EXC_RETURN_HANDLER         (0xFFFFFFF1UL)     /* return to Handler mode, uses MSP after return                               */ | ||||||
|  | #define EXC_RETURN_THREAD_MSP      (0xFFFFFFF9UL)     /* return to Thread mode, uses MSP after return                                */ | ||||||
|  | #define EXC_RETURN_THREAD_PSP      (0xFFFFFFFDUL)     /* return to Thread mode, uses PSP after return                                */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Interrupt Priorities are WORD accessible only under Armv6-M                  */ | ||||||
|  | /* The following MACROS handle generation of the register offset and byte masks */ | ||||||
|  | #define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL) | ||||||
|  | #define _SHP_IDX(IRQn)           ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >>    2UL)      ) | ||||||
|  | #define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      ) | ||||||
|  | 
 | ||||||
|  | #define __NVIC_SetPriorityGrouping(X) (void)(X) | ||||||
|  | #define __NVIC_GetPriorityGrouping()  (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Enable Interrupt | ||||||
|  |   \details Enables a device specific interrupt in the NVIC interrupt controller. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Interrupt Enable status | ||||||
|  |   \details Returns a device specific interrupt enable status from the NVIC interrupt controller. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \return             0  Interrupt is not enabled. | ||||||
|  |   \return             1  Interrupt is enabled. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     return(0U); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Disable Interrupt | ||||||
|  |   \details Disables a device specific interrupt in the NVIC interrupt controller. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | ||||||
|  |     __DSB(); | ||||||
|  |     __ISB(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Pending Interrupt | ||||||
|  |   \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \return             0  Interrupt status is not pending. | ||||||
|  |   \return             1  Interrupt status is pending. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     return(0U); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Pending Interrupt | ||||||
|  |   \details Sets the pending bit of a device specific interrupt in the NVIC pending register. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Clear Pending Interrupt | ||||||
|  |   \details Clears the pending bit of a device specific interrupt in the NVIC pending register. | ||||||
|  |   \param [in]      IRQn  Device specific interrupt number. | ||||||
|  |   \note    IRQn must not be negative. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Interrupt Priority | ||||||
|  |   \details Sets the priority of a device specific interrupt or a processor exception. | ||||||
|  |            The interrupt number can be positive to specify a device specific interrupt, | ||||||
|  |            or negative to specify a processor exception. | ||||||
|  |   \param [in]      IRQn  Interrupt number. | ||||||
|  |   \param [in]  priority  Priority to set. | ||||||
|  |   \note    The priority cannot be set for every processor exception. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) | ||||||
|  | { | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) | | ||||||
|  |        (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | | ||||||
|  |        (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Interrupt Priority | ||||||
|  |   \details Reads the priority of a device specific interrupt or a processor exception. | ||||||
|  |            The interrupt number can be positive to specify a device specific interrupt, | ||||||
|  |            or negative to specify a processor exception. | ||||||
|  |   \param [in]   IRQn  Interrupt number. | ||||||
|  |   \return             Interrupt Priority. | ||||||
|  |                       Value is aligned automatically to the implemented priority bits of the microcontroller. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |   if ((int32_t)(IRQn) >= 0) | ||||||
|  |   { | ||||||
|  |     return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Encode Priority | ||||||
|  |   \details Encodes the priority for an interrupt with the given priority group, | ||||||
|  |            preemptive priority value, and subpriority value. | ||||||
|  |            In case of a conflict between priority grouping and available | ||||||
|  |            priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. | ||||||
|  |   \param [in]     PriorityGroup  Used priority group. | ||||||
|  |   \param [in]   PreemptPriority  Preemptive priority value (starting from 0). | ||||||
|  |   \param [in]       SubPriority  Subpriority value (starting from 0). | ||||||
|  |   \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) | ||||||
|  | { | ||||||
|  |   uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */ | ||||||
|  |   uint32_t PreemptPriorityBits; | ||||||
|  |   uint32_t SubPriorityBits; | ||||||
|  | 
 | ||||||
|  |   PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); | ||||||
|  |   SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |            ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | | ||||||
|  |            ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL))) | ||||||
|  |          ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Decode Priority | ||||||
|  |   \details Decodes an interrupt priority value with a given priority group to | ||||||
|  |            preemptive priority value and subpriority value. | ||||||
|  |            In case of a conflict between priority grouping and available | ||||||
|  |            priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. | ||||||
|  |   \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). | ||||||
|  |   \param [in]     PriorityGroup  Used priority group. | ||||||
|  |   \param [out] pPreemptPriority  Preemptive priority value (starting from 0). | ||||||
|  |   \param [out]     pSubPriority  Subpriority value (starting from 0). | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) | ||||||
|  | { | ||||||
|  |   uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */ | ||||||
|  |   uint32_t PreemptPriorityBits; | ||||||
|  |   uint32_t SubPriorityBits; | ||||||
|  | 
 | ||||||
|  |   PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); | ||||||
|  |   SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); | ||||||
|  | 
 | ||||||
|  |   *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); | ||||||
|  |   *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set Interrupt Vector | ||||||
|  |   \details Sets an interrupt vector in SRAM based interrupt vector table. | ||||||
|  |            The interrupt number can be positive to specify a device specific interrupt, | ||||||
|  |            or negative to specify a processor exception. | ||||||
|  |            Address 0 must be mapped to SRAM. | ||||||
|  |   \param [in]   IRQn      Interrupt number | ||||||
|  |   \param [in]   vector    Address of interrupt handler function | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) | ||||||
|  | { | ||||||
|  |   uint32_t *vectors = (uint32_t *)0x0U; | ||||||
|  |   vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get Interrupt Vector | ||||||
|  |   \details Reads an interrupt vector from interrupt vector table. | ||||||
|  |            The interrupt number can be positive to specify a device specific interrupt, | ||||||
|  |            or negative to specify a processor exception. | ||||||
|  |   \param [in]   IRQn      Interrupt number. | ||||||
|  |   \return                 Address of interrupt handler function | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) | ||||||
|  | { | ||||||
|  |   uint32_t *vectors = (uint32_t *)0x0U; | ||||||
|  |   return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   System Reset | ||||||
|  |   \details Initiates a system reset request to reset the MCU. | ||||||
|  |  */ | ||||||
|  | __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) | ||||||
|  | { | ||||||
|  |   __DSB();                                                          /* Ensure all outstanding memory accesses included
 | ||||||
|  |                                                                        buffered write are completed before reset */ | ||||||
|  |   SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | | ||||||
|  |                  SCB_AIRCR_SYSRESETREQ_Msk); | ||||||
|  |   __DSB();                                                          /* Ensure completion of memory access */ | ||||||
|  | 
 | ||||||
|  |   for(;;)                                                           /* wait until reset */ | ||||||
|  |   { | ||||||
|  |     __NOP(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*@} end of CMSIS_Core_NVICFunctions */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ##########################  FPU functions  #################################### */ | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_Core_FunctionInterface | ||||||
|  |   \defgroup CMSIS_Core_FpuFunctions FPU Functions | ||||||
|  |   \brief    Function that provides FPU type. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   get FPU type | ||||||
|  |   \details returns the FPU type | ||||||
|  |   \returns | ||||||
|  |    - \b  0: No FPU | ||||||
|  |    - \b  1: Single precision FPU | ||||||
|  |    - \b  2: Double + Single precision FPU | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t SCB_GetFPUType(void) | ||||||
|  | { | ||||||
|  |     return 0U;           /* No FPU */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*@} end of CMSIS_Core_FpuFunctions */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ##################################    SysTick function  ############################################ */ | ||||||
|  | /**
 | ||||||
|  |   \ingroup  CMSIS_Core_FunctionInterface | ||||||
|  |   \defgroup CMSIS_Core_SysTickFunctions SysTick Functions | ||||||
|  |   \brief    Functions that configure the System. | ||||||
|  |   @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   System Tick Configuration | ||||||
|  |   \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. | ||||||
|  |            Counter is in free running mode to generate periodic interrupts. | ||||||
|  |   \param [in]  ticks  Number of ticks between two interrupts. | ||||||
|  |   \return          0  Function succeeded. | ||||||
|  |   \return          1  Function failed. | ||||||
|  |   \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the | ||||||
|  |            function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> | ||||||
|  |            must contain a vendor-specific implementation of this function. | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) | ||||||
|  | { | ||||||
|  |   if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) | ||||||
|  |   { | ||||||
|  |     return (1UL);                                                   /* Reload value impossible */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */ | ||||||
|  |   NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ | ||||||
|  |   SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */ | ||||||
|  |   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | | ||||||
|  |                    SysTick_CTRL_TICKINT_Msk   | | ||||||
|  |                    SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */ | ||||||
|  |   return (0UL);                                                     /* Function successful */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*@} end of CMSIS_Core_SysTickFunctions */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* __CORE_CM1_H_DEPENDANT */ | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_GENERIC */ | ||||||
							
								
								
									
										1993
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm23.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1993
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm23.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1941
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm3.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1941
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm3.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										3002
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm33.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3002
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm33.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2129
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm4.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2129
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm4.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2671
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm7.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2671
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_cm7.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1022
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_sc000.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1022
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_sc000.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1915
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_sc300.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1915
									
								
								target_f2/Drivers/CMSIS/Core/Include/core_sc300.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										270
									
								
								target_f2/Drivers/CMSIS/Core/Include/mpu_armv7.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								target_f2/Drivers/CMSIS/Core/Include/mpu_armv7.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,270 @@ | |||||||
|  | /******************************************************************************
 | ||||||
|  |  * @file     mpu_armv7.h | ||||||
|  |  * @brief    CMSIS MPU API for Armv7-M MPU | ||||||
|  |  * @version  V5.0.4 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2017-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  |   | ||||||
|  | #if   defined ( __ICCARM__ ) | ||||||
|  |   #pragma system_include         /* treat file as system include file for MISRA check */ | ||||||
|  | #elif defined (__clang__) | ||||||
|  |   #pragma clang system_header    /* treat file as system include file */ | ||||||
|  | #endif | ||||||
|  |   | ||||||
|  | #ifndef ARM_MPU_ARMV7_H | ||||||
|  | #define ARM_MPU_ARMV7_H | ||||||
|  | 
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_32B      ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_64B      ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_128B     ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_256B     ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_512B     ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_1KB      ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_2KB      ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_4KB      ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_8KB      ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_16KB     ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_32KB     ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_64KB     ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_128KB    ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_256KB    ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_512KB    ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_1MB      ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_2MB      ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_4MB      ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_8MB      ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_16MB     ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_32MB     ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_64MB     ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_128MB    ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_256MB    ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_512MB    ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_1GB      ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_2GB      ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes
 | ||||||
|  | #define ARM_MPU_REGION_SIZE_4GB      ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes
 | ||||||
|  | 
 | ||||||
|  | #define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access
 | ||||||
|  | #define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only
 | ||||||
|  | #define ARM_MPU_AP_URO  2U ///!< MPU Access Permission unprivileged access read-only
 | ||||||
|  | #define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access
 | ||||||
|  | #define ARM_MPU_AP_PRO  5U ///!< MPU Access Permission privileged access read-only
 | ||||||
|  | #define ARM_MPU_AP_RO   6U ///!< MPU Access Permission read-only access
 | ||||||
|  | 
 | ||||||
|  | /** MPU Region Base Address Register Value
 | ||||||
|  | * | ||||||
|  | * \param Region The region to be configured, number 0 to 15. | ||||||
|  | * \param BaseAddress The base address for the region. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_RBAR(Region, BaseAddress) \ | ||||||
|  |   (((BaseAddress) & MPU_RBAR_ADDR_Msk) |  \ | ||||||
|  |    ((Region) & MPU_RBAR_REGION_Msk)    |  \ | ||||||
|  |    (MPU_RBAR_VALID_Msk)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Memory Access Attributes | ||||||
|  | *  | ||||||
|  | * \param TypeExtField      Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. | ||||||
|  | * \param IsShareable       Region is shareable between multiple bus masters. | ||||||
|  | * \param IsCacheable       Region is cacheable, i.e. its value may be kept in cache. | ||||||
|  | * \param IsBufferable      Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. | ||||||
|  | */   | ||||||
|  | #define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable)   \ | ||||||
|  |   ((((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk)                 | \ | ||||||
|  |    (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk)                      | \ | ||||||
|  |    (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk)                      | \ | ||||||
|  |    (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Region Attribute and Size Register Value | ||||||
|  | *  | ||||||
|  | * \param DisableExec       Instruction access disable bit, 1= disable instruction fetches. | ||||||
|  | * \param AccessPermission  Data access permissions, allows you to configure read/write access for User and Privileged mode. | ||||||
|  | * \param AccessAttributes  Memory access attribution, see \ref ARM_MPU_ACCESS_. | ||||||
|  | * \param SubRegionDisable  Sub-region disable field. | ||||||
|  | * \param Size              Region size of the region to be configured, for example 4K, 8K. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size)      \ | ||||||
|  |   ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk)                                          | \ | ||||||
|  |    (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)                                      | \ | ||||||
|  |    (((AccessAttributes) ) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | ||||||
|  |    | ||||||
|  | /**
 | ||||||
|  | * MPU Region Attribute and Size Register Value | ||||||
|  | *  | ||||||
|  | * \param DisableExec       Instruction access disable bit, 1= disable instruction fetches. | ||||||
|  | * \param AccessPermission  Data access permissions, allows you to configure read/write access for User and Privileged mode. | ||||||
|  | * \param TypeExtField      Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. | ||||||
|  | * \param IsShareable       Region is shareable between multiple bus masters. | ||||||
|  | * \param IsCacheable       Region is cacheable, i.e. its value may be kept in cache. | ||||||
|  | * \param IsBufferable      Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. | ||||||
|  | * \param SubRegionDisable  Sub-region disable field. | ||||||
|  | * \param Size              Region size of the region to be configured, for example 4K, 8K. | ||||||
|  | */                          | ||||||
|  | #define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ | ||||||
|  |   ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Memory Access Attribute for strongly ordered memory. | ||||||
|  | *  - TEX: 000b | ||||||
|  | *  - Shareable | ||||||
|  | *  - Non-cacheable | ||||||
|  | *  - Non-bufferable | ||||||
|  | */  | ||||||
|  | #define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Memory Access Attribute for device memory. | ||||||
|  | *  - TEX: 000b (if non-shareable) or 010b (if shareable) | ||||||
|  | *  - Shareable or non-shareable | ||||||
|  | *  - Non-cacheable | ||||||
|  | *  - Bufferable (if shareable) or non-bufferable (if non-shareable) | ||||||
|  | * | ||||||
|  | * \param IsShareable Configures the device memory as shareable or non-shareable. | ||||||
|  | */  | ||||||
|  | #define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Memory Access Attribute for normal memory. | ||||||
|  | *  - TEX: 1BBb (reflecting outer cacheability rules) | ||||||
|  | *  - Shareable or non-shareable | ||||||
|  | *  - Cacheable or non-cacheable (reflecting inner cacheability rules) | ||||||
|  | *  - Bufferable or non-bufferable (reflecting inner cacheability rules) | ||||||
|  | * | ||||||
|  | * \param OuterCp Configures the outer cache policy. | ||||||
|  | * \param InnerCp Configures the inner cache policy. | ||||||
|  | * \param IsShareable Configures the memory as shareable or non-shareable. | ||||||
|  | */  | ||||||
|  | #define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Memory Access Attribute non-cacheable policy. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_CACHEP_NOCACHE 0U | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Memory Access Attribute write-back, write and read allocate policy. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_CACHEP_WB_WRA 1U | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Memory Access Attribute write-through, no write allocate policy. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_CACHEP_WT_NWA 2U | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * MPU Memory Access Attribute write-back, no write allocate policy. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_CACHEP_WB_NWA 3U | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * Struct for a single MPU Region | ||||||
|  | */ | ||||||
|  | typedef struct { | ||||||
|  |   uint32_t RBAR; //!< The region base address register value (RBAR)
 | ||||||
|  |   uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
 | ||||||
|  | } ARM_MPU_Region_t; | ||||||
|  |      | ||||||
|  | /** Enable the MPU.
 | ||||||
|  | * \param MPU_Control Default access permissions for unconfigured regions. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) | ||||||
|  | { | ||||||
|  |   __DSB(); | ||||||
|  |   __ISB(); | ||||||
|  |   MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; | ||||||
|  | #ifdef SCB_SHCSR_MEMFAULTENA_Msk | ||||||
|  |   SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Disable the MPU.
 | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Disable(void) | ||||||
|  | { | ||||||
|  |   __DSB(); | ||||||
|  |   __ISB(); | ||||||
|  | #ifdef SCB_SHCSR_MEMFAULTENA_Msk | ||||||
|  |   SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; | ||||||
|  | #endif | ||||||
|  |   MPU->CTRL  &= ~MPU_CTRL_ENABLE_Msk; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Clear and disable the given MPU region.
 | ||||||
|  | * \param rnr Region number to be cleared. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) | ||||||
|  | { | ||||||
|  |   MPU->RNR = rnr; | ||||||
|  |   MPU->RASR = 0U; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Configure an MPU region.
 | ||||||
|  | * \param rbar Value for RBAR register. | ||||||
|  | * \param rsar Value for RSAR register. | ||||||
|  | */    | ||||||
|  | __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) | ||||||
|  | { | ||||||
|  |   MPU->RBAR = rbar; | ||||||
|  |   MPU->RASR = rasr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Configure the given MPU region.
 | ||||||
|  | * \param rnr Region number to be configured. | ||||||
|  | * \param rbar Value for RBAR register. | ||||||
|  | * \param rsar Value for RSAR register. | ||||||
|  | */    | ||||||
|  | __STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) | ||||||
|  | { | ||||||
|  |   MPU->RNR = rnr; | ||||||
|  |   MPU->RBAR = rbar; | ||||||
|  |   MPU->RASR = rasr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Memcopy with strictly ordered memory access, e.g. for register targets.
 | ||||||
|  | * \param dst Destination data is copied to. | ||||||
|  | * \param src Source data is copied from. | ||||||
|  | * \param len Amount of data words to be copied. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) | ||||||
|  | { | ||||||
|  |   uint32_t i; | ||||||
|  |   for (i = 0U; i < len; ++i)  | ||||||
|  |   { | ||||||
|  |     dst[i] = src[i]; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Load the given number of MPU regions from a table.
 | ||||||
|  | * \param table Pointer to the MPU configuration table. | ||||||
|  | * \param cnt Amount of regions to be configured. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)  | ||||||
|  | { | ||||||
|  |   const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; | ||||||
|  |   while (cnt > MPU_TYPE_RALIASES) { | ||||||
|  |     orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); | ||||||
|  |     table += MPU_TYPE_RALIASES; | ||||||
|  |     cnt -= MPU_TYPE_RALIASES; | ||||||
|  |   } | ||||||
|  |   orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										333
									
								
								target_f2/Drivers/CMSIS/Core/Include/mpu_armv8.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										333
									
								
								target_f2/Drivers/CMSIS/Core/Include/mpu_armv8.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,333 @@ | |||||||
|  | /******************************************************************************
 | ||||||
|  |  * @file     mpu_armv8.h | ||||||
|  |  * @brief    CMSIS MPU API for Armv8-M MPU | ||||||
|  |  * @version  V5.0.4 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2017-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if   defined ( __ICCARM__ ) | ||||||
|  |   #pragma system_include         /* treat file as system include file for MISRA check */ | ||||||
|  | #elif defined (__clang__) | ||||||
|  |   #pragma clang system_header    /* treat file as system include file */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef ARM_MPU_ARMV8_H | ||||||
|  | #define ARM_MPU_ARMV8_H | ||||||
|  | 
 | ||||||
|  | /** \brief Attribute for device memory (outer only) */ | ||||||
|  | #define ARM_MPU_ATTR_DEVICE                           ( 0U ) | ||||||
|  | 
 | ||||||
|  | /** \brief Attribute for non-cacheable, normal memory */ | ||||||
|  | #define ARM_MPU_ATTR_NON_CACHEABLE                    ( 4U ) | ||||||
|  | 
 | ||||||
|  | /** \brief Attribute for normal memory (outer and inner)
 | ||||||
|  | * \param NT Non-Transient: Set to 1 for non-transient data. | ||||||
|  | * \param WB Write-Back: Set to 1 to use write-back update policy. | ||||||
|  | * \param RA Read Allocation: Set to 1 to use cache allocation on read miss. | ||||||
|  | * \param WA Write Allocation: Set to 1 to use cache allocation on write miss. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ | ||||||
|  |   (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) | ||||||
|  | 
 | ||||||
|  | /** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ | ||||||
|  | #define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) | ||||||
|  | 
 | ||||||
|  | /** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ | ||||||
|  | #define ARM_MPU_ATTR_DEVICE_nGnRE  (1U) | ||||||
|  | 
 | ||||||
|  | /** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ | ||||||
|  | #define ARM_MPU_ATTR_DEVICE_nGRE   (2U) | ||||||
|  | 
 | ||||||
|  | /** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ | ||||||
|  | #define ARM_MPU_ATTR_DEVICE_GRE    (3U) | ||||||
|  | 
 | ||||||
|  | /** \brief Memory Attribute
 | ||||||
|  | * \param O Outer memory attributes | ||||||
|  | * \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) | ||||||
|  | 
 | ||||||
|  | /** \brief Normal memory non-shareable  */ | ||||||
|  | #define ARM_MPU_SH_NON   (0U) | ||||||
|  | 
 | ||||||
|  | /** \brief Normal memory outer shareable  */ | ||||||
|  | #define ARM_MPU_SH_OUTER (2U) | ||||||
|  | 
 | ||||||
|  | /** \brief Normal memory inner shareable  */ | ||||||
|  | #define ARM_MPU_SH_INNER (3U) | ||||||
|  | 
 | ||||||
|  | /** \brief Memory access permissions
 | ||||||
|  | * \param RO Read-Only: Set to 1 for read-only memory. | ||||||
|  | * \param NP Non-Privileged: Set to 1 for non-privileged memory. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) | ||||||
|  | 
 | ||||||
|  | /** \brief Region Base Address Register value
 | ||||||
|  | * \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. | ||||||
|  | * \param SH Defines the Shareability domain for this memory region. | ||||||
|  | * \param RO Read-Only: Set to 1 for a read-only memory region. | ||||||
|  | * \param NP Non-Privileged: Set to 1 for a non-privileged memory region. | ||||||
|  | * \oaram XN eXecute Never: Set to 1 for a non-executable memory region. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ | ||||||
|  |   ((BASE & MPU_RBAR_BASE_Msk) | \ | ||||||
|  |   ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ | ||||||
|  |   ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ | ||||||
|  |   ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) | ||||||
|  | 
 | ||||||
|  | /** \brief Region Limit Address Register value
 | ||||||
|  | * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. | ||||||
|  | * \param IDX The attribute index to be associated with this memory region. | ||||||
|  | */ | ||||||
|  | #define ARM_MPU_RLAR(LIMIT, IDX) \ | ||||||
|  |   ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ | ||||||
|  |   ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ | ||||||
|  |   (MPU_RLAR_EN_Msk)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * Struct for a single MPU Region | ||||||
|  | */ | ||||||
|  | typedef struct { | ||||||
|  |   uint32_t RBAR;                   /*!< Region Base Address Register value */ | ||||||
|  |   uint32_t RLAR;                   /*!< Region Limit Address Register value */ | ||||||
|  | } ARM_MPU_Region_t; | ||||||
|  |      | ||||||
|  | /** Enable the MPU.
 | ||||||
|  | * \param MPU_Control Default access permissions for unconfigured regions. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) | ||||||
|  | { | ||||||
|  |   __DSB(); | ||||||
|  |   __ISB(); | ||||||
|  |   MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; | ||||||
|  | #ifdef SCB_SHCSR_MEMFAULTENA_Msk | ||||||
|  |   SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Disable the MPU.
 | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Disable(void) | ||||||
|  | { | ||||||
|  |   __DSB(); | ||||||
|  |   __ISB(); | ||||||
|  | #ifdef SCB_SHCSR_MEMFAULTENA_Msk | ||||||
|  |   SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; | ||||||
|  | #endif | ||||||
|  |   MPU->CTRL  &= ~MPU_CTRL_ENABLE_Msk; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef MPU_NS | ||||||
|  | /** Enable the Non-secure MPU.
 | ||||||
|  | * \param MPU_Control Default access permissions for unconfigured regions. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) | ||||||
|  | { | ||||||
|  |   __DSB(); | ||||||
|  |   __ISB(); | ||||||
|  |   MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; | ||||||
|  | #ifdef SCB_SHCSR_MEMFAULTENA_Msk | ||||||
|  |   SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Disable the Non-secure MPU.
 | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Disable_NS(void) | ||||||
|  | { | ||||||
|  |   __DSB(); | ||||||
|  |   __ISB(); | ||||||
|  | #ifdef SCB_SHCSR_MEMFAULTENA_Msk | ||||||
|  |   SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; | ||||||
|  | #endif | ||||||
|  |   MPU_NS->CTRL  &= ~MPU_CTRL_ENABLE_Msk; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /** Set the memory attribute encoding to the given MPU.
 | ||||||
|  | * \param mpu Pointer to the MPU to be configured. | ||||||
|  | * \param idx The attribute index to be set [0-7] | ||||||
|  | * \param attr The attribute value to be set. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) | ||||||
|  | { | ||||||
|  |   const uint8_t reg = idx / 4U; | ||||||
|  |   const uint32_t pos = ((idx % 4U) * 8U); | ||||||
|  |   const uint32_t mask = 0xFFU << pos; | ||||||
|  |    | ||||||
|  |   if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { | ||||||
|  |     return; // invalid index
 | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Set the memory attribute encoding.
 | ||||||
|  | * \param idx The attribute index to be set [0-7] | ||||||
|  | * \param attr The attribute value to be set. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) | ||||||
|  | { | ||||||
|  |   ARM_MPU_SetMemAttrEx(MPU, idx, attr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef MPU_NS | ||||||
|  | /** Set the memory attribute encoding to the Non-secure MPU.
 | ||||||
|  | * \param idx The attribute index to be set [0-7] | ||||||
|  | * \param attr The attribute value to be set. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) | ||||||
|  | { | ||||||
|  |   ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /** Clear and disable the given MPU region of the given MPU.
 | ||||||
|  | * \param mpu Pointer to MPU to be used. | ||||||
|  | * \param rnr Region number to be cleared. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) | ||||||
|  | { | ||||||
|  |   mpu->RNR = rnr; | ||||||
|  |   mpu->RLAR = 0U; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Clear and disable the given MPU region.
 | ||||||
|  | * \param rnr Region number to be cleared. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) | ||||||
|  | { | ||||||
|  |   ARM_MPU_ClrRegionEx(MPU, rnr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef MPU_NS | ||||||
|  | /** Clear and disable the given Non-secure MPU region.
 | ||||||
|  | * \param rnr Region number to be cleared. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) | ||||||
|  | {   | ||||||
|  |   ARM_MPU_ClrRegionEx(MPU_NS, rnr); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /** Configure the given MPU region of the given MPU.
 | ||||||
|  | * \param mpu Pointer to MPU to be used. | ||||||
|  | * \param rnr Region number to be configured. | ||||||
|  | * \param rbar Value for RBAR register. | ||||||
|  | * \param rlar Value for RLAR register. | ||||||
|  | */    | ||||||
|  | __STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) | ||||||
|  | { | ||||||
|  |   mpu->RNR = rnr; | ||||||
|  |   mpu->RBAR = rbar; | ||||||
|  |   mpu->RLAR = rlar; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Configure the given MPU region.
 | ||||||
|  | * \param rnr Region number to be configured. | ||||||
|  | * \param rbar Value for RBAR register. | ||||||
|  | * \param rlar Value for RLAR register. | ||||||
|  | */    | ||||||
|  | __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) | ||||||
|  | { | ||||||
|  |   ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef MPU_NS | ||||||
|  | /** Configure the given Non-secure MPU region.
 | ||||||
|  | * \param rnr Region number to be configured. | ||||||
|  | * \param rbar Value for RBAR register. | ||||||
|  | * \param rlar Value for RLAR register. | ||||||
|  | */    | ||||||
|  | __STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) | ||||||
|  | { | ||||||
|  |   ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);   | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /** Memcopy with strictly ordered memory access, e.g. for register targets.
 | ||||||
|  | * \param dst Destination data is copied to. | ||||||
|  | * \param src Source data is copied from. | ||||||
|  | * \param len Amount of data words to be copied. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) | ||||||
|  | { | ||||||
|  |   uint32_t i; | ||||||
|  |   for (i = 0U; i < len; ++i)  | ||||||
|  |   { | ||||||
|  |     dst[i] = src[i]; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Load the given number of MPU regions from a table to the given MPU.
 | ||||||
|  | * \param mpu Pointer to the MPU registers to be used. | ||||||
|  | * \param rnr First region number to be configured. | ||||||
|  | * \param table Pointer to the MPU configuration table. | ||||||
|  | * \param cnt Amount of regions to be configured. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)  | ||||||
|  | { | ||||||
|  |   const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; | ||||||
|  |   if (cnt == 1U) { | ||||||
|  |     mpu->RNR = rnr; | ||||||
|  |     orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); | ||||||
|  |   } else { | ||||||
|  |     uint32_t rnrBase   = rnr & ~(MPU_TYPE_RALIASES-1U); | ||||||
|  |     uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; | ||||||
|  |      | ||||||
|  |     mpu->RNR = rnrBase; | ||||||
|  |     while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { | ||||||
|  |       uint32_t c = MPU_TYPE_RALIASES - rnrOffset; | ||||||
|  |       orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); | ||||||
|  |       table += c; | ||||||
|  |       cnt -= c; | ||||||
|  |       rnrOffset = 0U; | ||||||
|  |       rnrBase += MPU_TYPE_RALIASES; | ||||||
|  |       mpu->RNR = rnrBase; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Load the given number of MPU regions from a table.
 | ||||||
|  | * \param rnr First region number to be configured. | ||||||
|  | * \param table Pointer to the MPU configuration table. | ||||||
|  | * \param cnt Amount of regions to be configured. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)  | ||||||
|  | { | ||||||
|  |   ARM_MPU_LoadEx(MPU, rnr, table, cnt); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef MPU_NS | ||||||
|  | /** Load the given number of MPU regions from a table to the Non-secure MPU.
 | ||||||
|  | * \param rnr First region number to be configured. | ||||||
|  | * \param table Pointer to the MPU configuration table. | ||||||
|  | * \param cnt Amount of regions to be configured. | ||||||
|  | */ | ||||||
|  | __STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)  | ||||||
|  | { | ||||||
|  |   ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
							
								
								
									
										70
									
								
								target_f2/Drivers/CMSIS/Core/Include/tz_context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								target_f2/Drivers/CMSIS/Core/Include/tz_context.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | /******************************************************************************
 | ||||||
|  |  * @file     tz_context.h | ||||||
|  |  * @brief    Context Management for Armv8-M TrustZone | ||||||
|  |  * @version  V1.0.1 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2017-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if   defined ( __ICCARM__ ) | ||||||
|  |   #pragma system_include         /* treat file as system include file for MISRA check */ | ||||||
|  | #elif defined (__clang__) | ||||||
|  |   #pragma clang system_header   /* treat file as system include file */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef TZ_CONTEXT_H | ||||||
|  | #define TZ_CONTEXT_H | ||||||
|  |   | ||||||
|  | #include <stdint.h> | ||||||
|  |   | ||||||
|  | #ifndef TZ_MODULEID_T | ||||||
|  | #define TZ_MODULEID_T | ||||||
|  | /// \details Data type that identifies secure software modules called by a process.
 | ||||||
|  | typedef uint32_t TZ_ModuleId_t; | ||||||
|  | #endif | ||||||
|  |   | ||||||
|  | /// \details TZ Memory ID identifies an allocated memory slot.
 | ||||||
|  | typedef uint32_t TZ_MemoryId_t; | ||||||
|  |    | ||||||
|  | /// Initialize secure context memory system
 | ||||||
|  | /// \return execution status (1: success, 0: error)
 | ||||||
|  | uint32_t TZ_InitContextSystem_S (void); | ||||||
|  |   | ||||||
|  | /// Allocate context memory for calling secure software modules in TrustZone
 | ||||||
|  | /// \param[in]  module   identifies software modules called from non-secure mode
 | ||||||
|  | /// \return value != 0 id TrustZone memory slot identifier
 | ||||||
|  | /// \return value 0    no memory available or internal error
 | ||||||
|  | TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); | ||||||
|  |   | ||||||
|  | /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
 | ||||||
|  | /// \param[in]  id  TrustZone memory slot identifier
 | ||||||
|  | /// \return execution status (1: success, 0: error)
 | ||||||
|  | uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); | ||||||
|  |   | ||||||
|  | /// Load secure context (called on RTOS thread context switch)
 | ||||||
|  | /// \param[in]  id  TrustZone memory slot identifier
 | ||||||
|  | /// \return execution status (1: success, 0: error)
 | ||||||
|  | uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); | ||||||
|  |   | ||||||
|  | /// Store secure context (called on RTOS thread context switch)
 | ||||||
|  | /// \param[in]  id  TrustZone memory slot identifier
 | ||||||
|  | /// \return execution status (1: success, 0: error)
 | ||||||
|  | uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); | ||||||
|  |   | ||||||
|  | #endif  // TZ_CONTEXT_H
 | ||||||
							
								
								
									
										58
									
								
								target_f2/Drivers/CMSIS/Core/Template/ARMv8-M/main_s.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								target_f2/Drivers/CMSIS/Core/Template/ARMv8-M/main_s.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | /******************************************************************************
 | ||||||
|  |  * @file     main_s.c | ||||||
|  |  * @brief    Code template for secure main function | ||||||
|  |  * @version  V1.1.1 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2013-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* Use CMSE intrinsics */ | ||||||
|  | #include <arm_cmse.h> | ||||||
|  |   | ||||||
|  | #include "RTE_Components.h" | ||||||
|  | #include CMSIS_device_header | ||||||
|  |   | ||||||
|  | /* TZ_START_NS: Start address of non-secure application */ | ||||||
|  | #ifndef TZ_START_NS | ||||||
|  | #define TZ_START_NS (0x200000U) | ||||||
|  | #endif | ||||||
|  |   | ||||||
|  | /* typedef for non-secure callback functions */ | ||||||
|  | typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call)); | ||||||
|  |   | ||||||
|  | /* Secure main() */ | ||||||
|  | int main(void) { | ||||||
|  |   funcptr_void NonSecure_ResetHandler; | ||||||
|  |   | ||||||
|  |   /* Add user setup code for secure part here*/ | ||||||
|  |   | ||||||
|  |   /* Set non-secure main stack (MSP_NS) */ | ||||||
|  |   __TZ_set_MSP_NS(*((uint32_t *)(TZ_START_NS))); | ||||||
|  |   | ||||||
|  |   /* Get non-secure reset handler */ | ||||||
|  |   NonSecure_ResetHandler = (funcptr_void)(*((uint32_t *)((TZ_START_NS) + 4U))); | ||||||
|  |   | ||||||
|  |   /* Start non-secure state software application */ | ||||||
|  |   NonSecure_ResetHandler(); | ||||||
|  |   | ||||||
|  |   /* Non-secure software does not return, this code is not executed */ | ||||||
|  |   while (1) { | ||||||
|  |     __NOP(); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										200
									
								
								target_f2/Drivers/CMSIS/Core/Template/ARMv8-M/tz_context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								target_f2/Drivers/CMSIS/Core/Template/ARMv8-M/tz_context.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,200 @@ | |||||||
|  | /******************************************************************************
 | ||||||
|  |  * @file     tz_context.c | ||||||
|  |  * @brief    Context Management for Armv8-M TrustZone - Sample implementation | ||||||
|  |  * @version  V1.1.1 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2016-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "RTE_Components.h" | ||||||
|  | #include CMSIS_device_header | ||||||
|  | #include "tz_context.h" | ||||||
|  | 
 | ||||||
|  | /// Number of process slots (threads may call secure library code)
 | ||||||
|  | #ifndef TZ_PROCESS_STACK_SLOTS | ||||||
|  | #define TZ_PROCESS_STACK_SLOTS     8U | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /// Stack size of the secure library code
 | ||||||
|  | #ifndef TZ_PROCESS_STACK_SIZE | ||||||
|  | #define TZ_PROCESS_STACK_SIZE      256U | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |   uint32_t sp_top;      // stack space top
 | ||||||
|  |   uint32_t sp_limit;    // stack space limit
 | ||||||
|  |   uint32_t sp;          // current stack pointer
 | ||||||
|  | } stack_info_t; | ||||||
|  | 
 | ||||||
|  | static stack_info_t ProcessStackInfo  [TZ_PROCESS_STACK_SLOTS]; | ||||||
|  | static uint64_t     ProcessStackMemory[TZ_PROCESS_STACK_SLOTS][TZ_PROCESS_STACK_SIZE/8U]; | ||||||
|  | static uint32_t     ProcessStackFreeSlot = 0xFFFFFFFFU; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Initialize secure context memory system
 | ||||||
|  | /// \return execution status (1: success, 0: error)
 | ||||||
|  | __attribute__((cmse_nonsecure_entry)) | ||||||
|  | uint32_t TZ_InitContextSystem_S (void) { | ||||||
|  |   uint32_t n; | ||||||
|  | 
 | ||||||
|  |   if (__get_IPSR() == 0U) { | ||||||
|  |     return 0U;  // Thread Mode
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   for (n = 0U; n < TZ_PROCESS_STACK_SLOTS; n++) { | ||||||
|  |     ProcessStackInfo[n].sp = 0U; | ||||||
|  |     ProcessStackInfo[n].sp_limit = (uint32_t)&ProcessStackMemory[n]; | ||||||
|  |     ProcessStackInfo[n].sp_top   = (uint32_t)&ProcessStackMemory[n] + TZ_PROCESS_STACK_SIZE; | ||||||
|  |     *((uint32_t *)ProcessStackMemory[n]) = n + 1U; | ||||||
|  |   } | ||||||
|  |   *((uint32_t *)ProcessStackMemory[--n]) = 0xFFFFFFFFU; | ||||||
|  | 
 | ||||||
|  |   ProcessStackFreeSlot = 0U; | ||||||
|  | 
 | ||||||
|  |   // Default process stack pointer and stack limit
 | ||||||
|  |   __set_PSPLIM((uint32_t)ProcessStackMemory); | ||||||
|  |   __set_PSP   ((uint32_t)ProcessStackMemory); | ||||||
|  | 
 | ||||||
|  |   // Privileged Thread Mode using PSP
 | ||||||
|  |   __set_CONTROL(0x02U); | ||||||
|  | 
 | ||||||
|  |   return 1U;    // Success
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Allocate context memory for calling secure software modules in TrustZone
 | ||||||
|  | /// \param[in]  module   identifies software modules called from non-secure mode
 | ||||||
|  | /// \return value != 0 id TrustZone memory slot identifier
 | ||||||
|  | /// \return value 0    no memory available or internal error
 | ||||||
|  | __attribute__((cmse_nonsecure_entry)) | ||||||
|  | TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module) { | ||||||
|  |   uint32_t slot; | ||||||
|  | 
 | ||||||
|  |   (void)module; // Ignore (fixed Stack size)
 | ||||||
|  | 
 | ||||||
|  |   if (__get_IPSR() == 0U) { | ||||||
|  |     return 0U;  // Thread Mode
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (ProcessStackFreeSlot == 0xFFFFFFFFU) { | ||||||
|  |     return 0U;  // No slot available
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   slot = ProcessStackFreeSlot; | ||||||
|  |   ProcessStackFreeSlot = *((uint32_t *)ProcessStackMemory[slot]); | ||||||
|  | 
 | ||||||
|  |   ProcessStackInfo[slot].sp = ProcessStackInfo[slot].sp_top; | ||||||
|  | 
 | ||||||
|  |   return (slot + 1U); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
 | ||||||
|  | /// \param[in]  id  TrustZone memory slot identifier
 | ||||||
|  | /// \return execution status (1: success, 0: error)
 | ||||||
|  | __attribute__((cmse_nonsecure_entry)) | ||||||
|  | uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id) { | ||||||
|  |   uint32_t slot; | ||||||
|  | 
 | ||||||
|  |   if (__get_IPSR() == 0U) { | ||||||
|  |     return 0U;  // Thread Mode
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { | ||||||
|  |     return 0U;  // Invalid ID
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   slot = id - 1U; | ||||||
|  | 
 | ||||||
|  |   if (ProcessStackInfo[slot].sp == 0U) { | ||||||
|  |     return 0U;  // Inactive slot
 | ||||||
|  |   } | ||||||
|  |   ProcessStackInfo[slot].sp = 0U; | ||||||
|  | 
 | ||||||
|  |   *((uint32_t *)ProcessStackMemory[slot]) = ProcessStackFreeSlot; | ||||||
|  |   ProcessStackFreeSlot = slot; | ||||||
|  | 
 | ||||||
|  |   return 1U;    // Success
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Load secure context (called on RTOS thread context switch)
 | ||||||
|  | /// \param[in]  id  TrustZone memory slot identifier
 | ||||||
|  | /// \return execution status (1: success, 0: error)
 | ||||||
|  | __attribute__((cmse_nonsecure_entry)) | ||||||
|  | uint32_t TZ_LoadContext_S (TZ_MemoryId_t id) { | ||||||
|  |   uint32_t slot; | ||||||
|  | 
 | ||||||
|  |   if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { | ||||||
|  |     return 0U;  // Thread Mode or using Main Stack for threads
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { | ||||||
|  |     return 0U;  // Invalid ID
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   slot = id - 1U; | ||||||
|  | 
 | ||||||
|  |   if (ProcessStackInfo[slot].sp == 0U) { | ||||||
|  |     return 0U;  // Inactive slot
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Setup process stack pointer and stack limit
 | ||||||
|  |   __set_PSPLIM(ProcessStackInfo[slot].sp_limit); | ||||||
|  |   __set_PSP   (ProcessStackInfo[slot].sp); | ||||||
|  | 
 | ||||||
|  |   return 1U;    // Success
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Store secure context (called on RTOS thread context switch)
 | ||||||
|  | /// \param[in]  id  TrustZone memory slot identifier
 | ||||||
|  | /// \return execution status (1: success, 0: error)
 | ||||||
|  | __attribute__((cmse_nonsecure_entry)) | ||||||
|  | uint32_t TZ_StoreContext_S (TZ_MemoryId_t id) { | ||||||
|  |   uint32_t slot; | ||||||
|  |   uint32_t sp; | ||||||
|  | 
 | ||||||
|  |   if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { | ||||||
|  |     return 0U;  // Thread Mode or using Main Stack for threads
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { | ||||||
|  |     return 0U;  // Invalid ID
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   slot = id - 1U; | ||||||
|  | 
 | ||||||
|  |   if (ProcessStackInfo[slot].sp == 0U) { | ||||||
|  |     return 0U;  // Inactive slot
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   sp = __get_PSP(); | ||||||
|  |   if ((sp < ProcessStackInfo[slot].sp_limit) || | ||||||
|  |       (sp > ProcessStackInfo[slot].sp_top)) { | ||||||
|  |     return 0U;  // SP out of range
 | ||||||
|  |   } | ||||||
|  |   ProcessStackInfo[slot].sp = sp; | ||||||
|  | 
 | ||||||
|  |   // Default process stack pointer and stack limit
 | ||||||
|  |   __set_PSPLIM((uint32_t)ProcessStackMemory); | ||||||
|  |   __set_PSP   ((uint32_t)ProcessStackMemory); | ||||||
|  | 
 | ||||||
|  |   return 1U;    // Success
 | ||||||
|  | } | ||||||
							
								
								
									
										544
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_armcc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										544
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_armcc.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,544 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_armcc.h | ||||||
|  |  * @brief    CMSIS compiler specific macros, functions, instructions | ||||||
|  |  * @version  V1.0.2 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_ARMCC_H | ||||||
|  | #define __CMSIS_ARMCC_H | ||||||
|  | 
 | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) | ||||||
|  |   #error "Please use Arm Compiler Toolchain V4.0.677 or later!" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* CMSIS compiler control architecture macros */ | ||||||
|  | #if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A  == 1)) | ||||||
|  |   #define __ARM_ARCH_7A__           1 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* CMSIS compiler specific defines */ | ||||||
|  | #ifndef   __ASM | ||||||
|  |   #define __ASM                                  __asm | ||||||
|  | #endif | ||||||
|  | #ifndef   __INLINE | ||||||
|  |   #define __INLINE                               __inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __FORCEINLINE | ||||||
|  |   #define __FORCEINLINE                          __forceinline | ||||||
|  | #endif | ||||||
|  | #ifndef   __STATIC_INLINE | ||||||
|  |   #define __STATIC_INLINE                        static __inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __STATIC_FORCEINLINE | ||||||
|  |   #define __STATIC_FORCEINLINE                   static __forceinline | ||||||
|  | #endif | ||||||
|  | #ifndef   __NO_RETURN | ||||||
|  |   #define __NO_RETURN                            __declspec(noreturn) | ||||||
|  | #endif | ||||||
|  | #ifndef   CMSIS_DEPRECATED | ||||||
|  |   #define CMSIS_DEPRECATED                       __attribute__((deprecated)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __USED | ||||||
|  |   #define __USED                                 __attribute__((used)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __WEAK | ||||||
|  |   #define __WEAK                                 __attribute__((weak)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED | ||||||
|  |   #define __PACKED                               __attribute__((packed)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED_STRUCT | ||||||
|  |   #define __PACKED_STRUCT                        __packed struct | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT16_WRITE | ||||||
|  |   #define __UNALIGNED_UINT16_WRITE(addr, val)    ((*((__packed uint16_t *)(addr))) = (val)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT16_READ | ||||||
|  |   #define __UNALIGNED_UINT16_READ(addr)          (*((const __packed uint16_t *)(addr))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32_WRITE | ||||||
|  |   #define __UNALIGNED_UINT32_WRITE(addr, val)    ((*((__packed uint32_t *)(addr))) = (val)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32_READ | ||||||
|  |   #define __UNALIGNED_UINT32_READ(addr)          (*((const __packed uint32_t *)(addr))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __ALIGNED | ||||||
|  |   #define __ALIGNED(x)                           __attribute__((aligned(x))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED | ||||||
|  |   #define __PACKED                               __attribute__((packed)) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ##########################  Core Instruction Access  ######################### */ | ||||||
|  | /**
 | ||||||
|  |   \brief   No Operation | ||||||
|  |  */ | ||||||
|  | #define __NOP                             __nop | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Wait For Interrupt | ||||||
|  |  */ | ||||||
|  | #define __WFI                             __wfi | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Wait For Event | ||||||
|  |  */ | ||||||
|  | #define __WFE                             __wfe | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Send Event | ||||||
|  |  */ | ||||||
|  | #define __SEV                             __sev | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Instruction Synchronization Barrier | ||||||
|  |  */ | ||||||
|  | #define __ISB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __isb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Data Synchronization Barrier | ||||||
|  |  */ | ||||||
|  | #define __DSB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __dsb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Data Memory Barrier | ||||||
|  |  */ | ||||||
|  | #define __DMB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __dmb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (32 bit) | ||||||
|  |   \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #define __REV                             __rev | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (16 bit) | ||||||
|  |   \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #ifndef __NO_EMBEDDED_ASM | ||||||
|  | __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) | ||||||
|  | { | ||||||
|  |   rev16 r0, r0 | ||||||
|  |   bx lr | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (16 bit) | ||||||
|  |   \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #ifndef __NO_EMBEDDED_ASM | ||||||
|  | __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) | ||||||
|  | { | ||||||
|  |   revsh r0, r0 | ||||||
|  |   bx lr | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Rotate Right in unsigned value (32 bit) | ||||||
|  |   \param [in]    op1  Value to rotate | ||||||
|  |   \param [in]    op2  Number of Bits to rotate | ||||||
|  |   \return               Rotated value | ||||||
|  |  */ | ||||||
|  | #define __ROR                             __ror | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Breakpoint | ||||||
|  |   \param [in]    value  is ignored by the processor. | ||||||
|  |                  If required, a debugger can use it to store additional information about the breakpoint. | ||||||
|  |  */ | ||||||
|  | #define __BKPT(value)                     __breakpoint(value) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse bit order of value | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #define __RBIT                            __rbit | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Count leading zeros | ||||||
|  |   \param [in]  value  Value to count the leading zeros | ||||||
|  |   \return             number of leading zeros in value | ||||||
|  |  */ | ||||||
|  | #define __CLZ                             __clz | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (8 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 8 bit value. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return             value of type uint8_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __LDREXB(ptr)                                                        ((uint8_t ) __ldrex(ptr)) | ||||||
|  | #else | ||||||
|  |   #define __LDREXB(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr))  _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (16 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 16 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint16_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __LDREXH(ptr)                                                        ((uint16_t) __ldrex(ptr)) | ||||||
|  | #else | ||||||
|  |   #define __LDREXH(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr))  _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (32 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 32 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint32_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __LDREXW(ptr)                                                        ((uint32_t ) __ldrex(ptr)) | ||||||
|  | #else | ||||||
|  |   #define __LDREXW(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr))  _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (8 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 8 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __STREXB(value, ptr)                                                 __strex(value, ptr) | ||||||
|  | #else | ||||||
|  |   #define __STREXB(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (16 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 16 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __STREXH(value, ptr)                                                 __strex(value, ptr) | ||||||
|  | #else | ||||||
|  |   #define __STREXH(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (32 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 32 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | ||||||
|  |   #define __STREXW(value, ptr)                                                 __strex(value, ptr) | ||||||
|  | #else | ||||||
|  |   #define __STREXW(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Remove the exclusive lock | ||||||
|  |   \details Removes the exclusive lock which is created by LDREX. | ||||||
|  |  */ | ||||||
|  | #define __CLREX                           __clrex | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Signed Saturate | ||||||
|  |   \details Saturates a signed value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (1..32) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | #define __SSAT                            __ssat | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Unsigned Saturate | ||||||
|  |   \details Saturates an unsigned value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (0..31) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | #define __USAT                            __usat | ||||||
|  | 
 | ||||||
|  | /* ###########################  Core Function Access  ########################### */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get FPSCR (Floating Point Status/Control) | ||||||
|  |   \return               Floating Point Status/Control register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_FPSCR(void) | ||||||
|  | { | ||||||
|  | #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |      (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     ) | ||||||
|  |   register uint32_t __regfpscr         __ASM("fpscr"); | ||||||
|  |   return(__regfpscr); | ||||||
|  | #else | ||||||
|  |    return(0U); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set FPSCR (Floating Point Status/Control) | ||||||
|  |   \param [in]    fpscr  Floating Point Status/Control value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) | ||||||
|  | { | ||||||
|  | #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |      (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     ) | ||||||
|  |   register uint32_t __regfpscr         __ASM("fpscr"); | ||||||
|  |   __regfpscr = (fpscr); | ||||||
|  | #else | ||||||
|  |   (void)fpscr; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CPSR (Current Program Status Register)
 | ||||||
|  |     \return               CPSR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_CPSR(void) | ||||||
|  | { | ||||||
|  |   register uint32_t __regCPSR          __ASM("cpsr"); | ||||||
|  |   return(__regCPSR); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CPSR (Current Program Status Register)
 | ||||||
|  |     \param [in]    cpsr  CPSR value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_CPSR(uint32_t cpsr) | ||||||
|  | { | ||||||
|  |   register uint32_t __regCPSR          __ASM("cpsr"); | ||||||
|  |   __regCPSR = cpsr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get Mode
 | ||||||
|  |     \return                Processor Mode | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_mode(void) | ||||||
|  | { | ||||||
|  |   return (__get_CPSR() & 0x1FU); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set Mode
 | ||||||
|  |     \param [in]    mode  Mode value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE __ASM void __set_mode(uint32_t mode) | ||||||
|  | { | ||||||
|  |   MOV  r1, lr | ||||||
|  |   MSR  CPSR_C, r0 | ||||||
|  |   BX   r1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get Stack Pointer
 | ||||||
|  |     \return Stack Pointer | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE __ASM uint32_t __get_SP(void) | ||||||
|  | { | ||||||
|  |   MOV  r0, sp | ||||||
|  |   BX   lr | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set Stack Pointer
 | ||||||
|  |     \param [in]    stack  Stack Pointer value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE __ASM void __set_SP(uint32_t stack) | ||||||
|  | { | ||||||
|  |   MOV  sp, r0 | ||||||
|  |   BX   lr | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /** \brief  Get USR/SYS Stack Pointer
 | ||||||
|  |     \return USR/SYSStack Pointer | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE __ASM uint32_t __get_SP_usr(void) | ||||||
|  | { | ||||||
|  |   ARM | ||||||
|  |   PRESERVE8 | ||||||
|  | 
 | ||||||
|  |   MRS     R1, CPSR | ||||||
|  |   CPS     #0x1F       ;no effect in USR mode | ||||||
|  |   MOV     R0, SP | ||||||
|  |   MSR     CPSR_c, R1  ;no effect in USR mode | ||||||
|  |   ISB | ||||||
|  |   BX      LR | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set USR/SYS Stack Pointer
 | ||||||
|  |     \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack) | ||||||
|  | { | ||||||
|  |   ARM | ||||||
|  |   PRESERVE8 | ||||||
|  | 
 | ||||||
|  |   MRS     R1, CPSR | ||||||
|  |   CPS     #0x1F       ;no effect in USR mode | ||||||
|  |   MOV     SP, R0 | ||||||
|  |   MSR     CPSR_c, R1  ;no effect in USR mode | ||||||
|  |   ISB | ||||||
|  |   BX      LR | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get FPEXC (Floating Point Exception Control Register)
 | ||||||
|  |     \return               Floating Point Exception Control Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE uint32_t __get_FPEXC(void) | ||||||
|  | { | ||||||
|  | #if (__FPU_PRESENT == 1) | ||||||
|  |   register uint32_t __regfpexc         __ASM("fpexc"); | ||||||
|  |   return(__regfpexc); | ||||||
|  | #else | ||||||
|  |   return(0); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set FPEXC (Floating Point Exception Control Register)
 | ||||||
|  |     \param [in]    fpexc  Floating Point Exception Control value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __set_FPEXC(uint32_t fpexc) | ||||||
|  | { | ||||||
|  | #if (__FPU_PRESENT == 1) | ||||||
|  |   register uint32_t __regfpexc         __ASM("fpexc"); | ||||||
|  |   __regfpexc = (fpexc); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Include common core functions to access Coprocessor 15 registers | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); (Rt) = tmp; } while(0) | ||||||
|  | #define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = (Rt); } while(0) | ||||||
|  | #define __get_CP64(cp, op1, Rt, CRm) \ | ||||||
|  |   do { \ | ||||||
|  |     uint32_t ltmp, htmp; \ | ||||||
|  |     __ASM volatile("MRRC p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \ | ||||||
|  |     (Rt) = ((((uint64_t)htmp) << 32U) | ((uint64_t)ltmp)); \ | ||||||
|  |   } while(0) | ||||||
|  | 
 | ||||||
|  | #define __set_CP64(cp, op1, Rt, CRm) \ | ||||||
|  |   do { \ | ||||||
|  |     const uint64_t tmp = (Rt); \ | ||||||
|  |     const uint32_t ltmp = (uint32_t)(tmp); \ | ||||||
|  |     const uint32_t htmp = (uint32_t)(tmp >> 32U); \ | ||||||
|  |     __ASM volatile("MCRR p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \ | ||||||
|  |   } while(0) | ||||||
|  | 
 | ||||||
|  | #include "cmsis_cp15.h" | ||||||
|  | 
 | ||||||
|  | /** \brief  Enable Floating Point Unit
 | ||||||
|  | 
 | ||||||
|  |   Critical section, called from undef handler, so systick is disabled | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE __ASM void __FPU_Enable(void) | ||||||
|  | { | ||||||
|  |         ARM | ||||||
|  | 
 | ||||||
|  |         //Permit access to VFP/NEON, registers by modifying CPACR
 | ||||||
|  |         MRC     p15,0,R1,c1,c0,2 | ||||||
|  |         ORR     R1,R1,#0x00F00000 | ||||||
|  |         MCR     p15,0,R1,c1,c0,2 | ||||||
|  | 
 | ||||||
|  |         //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
 | ||||||
|  |         ISB | ||||||
|  | 
 | ||||||
|  |         //Enable VFP/NEON
 | ||||||
|  |         VMRS    R1,FPEXC | ||||||
|  |         ORR     R1,R1,#0x40000000 | ||||||
|  |         VMSR    FPEXC,R1 | ||||||
|  | 
 | ||||||
|  |         //Initialise VFP/NEON registers to 0
 | ||||||
|  |         MOV     R2,#0 | ||||||
|  | 
 | ||||||
|  |         //Initialise D16 registers to 0
 | ||||||
|  |         VMOV    D0, R2,R2 | ||||||
|  |         VMOV    D1, R2,R2 | ||||||
|  |         VMOV    D2, R2,R2 | ||||||
|  |         VMOV    D3, R2,R2 | ||||||
|  |         VMOV    D4, R2,R2 | ||||||
|  |         VMOV    D5, R2,R2 | ||||||
|  |         VMOV    D6, R2,R2 | ||||||
|  |         VMOV    D7, R2,R2 | ||||||
|  |         VMOV    D8, R2,R2 | ||||||
|  |         VMOV    D9, R2,R2 | ||||||
|  |         VMOV    D10,R2,R2 | ||||||
|  |         VMOV    D11,R2,R2 | ||||||
|  |         VMOV    D12,R2,R2 | ||||||
|  |         VMOV    D13,R2,R2 | ||||||
|  |         VMOV    D14,R2,R2 | ||||||
|  |         VMOV    D15,R2,R2 | ||||||
|  | 
 | ||||||
|  |   IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 | ||||||
|  |         //Initialise D32 registers to 0
 | ||||||
|  |         VMOV    D16,R2,R2 | ||||||
|  |         VMOV    D17,R2,R2 | ||||||
|  |         VMOV    D18,R2,R2 | ||||||
|  |         VMOV    D19,R2,R2 | ||||||
|  |         VMOV    D20,R2,R2 | ||||||
|  |         VMOV    D21,R2,R2 | ||||||
|  |         VMOV    D22,R2,R2 | ||||||
|  |         VMOV    D23,R2,R2 | ||||||
|  |         VMOV    D24,R2,R2 | ||||||
|  |         VMOV    D25,R2,R2 | ||||||
|  |         VMOV    D26,R2,R2 | ||||||
|  |         VMOV    D27,R2,R2 | ||||||
|  |         VMOV    D28,R2,R2 | ||||||
|  |         VMOV    D29,R2,R2 | ||||||
|  |         VMOV    D30,R2,R2 | ||||||
|  |         VMOV    D31,R2,R2 | ||||||
|  |   ENDIF | ||||||
|  | 
 | ||||||
|  |         //Initialise FPSCR to a known state
 | ||||||
|  |         VMRS    R2,FPSCR | ||||||
|  |         LDR     R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
 | ||||||
|  |         AND     R2,R2,R3 | ||||||
|  |         VMSR    FPSCR,R2 | ||||||
|  | 
 | ||||||
|  |         BX      LR | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_ARMCC_H */ | ||||||
							
								
								
									
										503
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_armclang.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										503
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_armclang.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,503 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_armclang.h | ||||||
|  |  * @brief    CMSIS compiler specific macros, functions, instructions | ||||||
|  |  * @version  V1.0.2 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_ARMCLANG_H | ||||||
|  | #define __CMSIS_ARMCLANG_H | ||||||
|  | 
 | ||||||
|  | #pragma clang system_header   /* treat file as system include file */ | ||||||
|  | 
 | ||||||
|  | #ifndef __ARM_COMPAT_H | ||||||
|  | #include <arm_compat.h>    /* Compatibility header for Arm Compiler 5 intrinsics */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* CMSIS compiler specific defines */ | ||||||
|  | #ifndef   __ASM | ||||||
|  |   #define __ASM                                  __asm | ||||||
|  | #endif | ||||||
|  | #ifndef   __INLINE | ||||||
|  |   #define __INLINE                               __inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __FORCEINLINE | ||||||
|  |   #define __FORCEINLINE                          __attribute__((always_inline)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __STATIC_INLINE | ||||||
|  |   #define __STATIC_INLINE                        static __inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __STATIC_FORCEINLINE | ||||||
|  |   #define __STATIC_FORCEINLINE                   __attribute__((always_inline)) static __inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __NO_RETURN | ||||||
|  |   #define __NO_RETURN                            __attribute__((__noreturn__)) | ||||||
|  | #endif | ||||||
|  | #ifndef   CMSIS_DEPRECATED | ||||||
|  |   #define CMSIS_DEPRECATED                       __attribute__((deprecated)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __USED | ||||||
|  |   #define __USED                                 __attribute__((used)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __WEAK | ||||||
|  |   #define __WEAK                                 __attribute__((weak)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED | ||||||
|  |   #define __PACKED                               __attribute__((packed, aligned(1))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED_STRUCT | ||||||
|  |   #define __PACKED_STRUCT                        struct __attribute__((packed, aligned(1))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT16_WRITE | ||||||
|  |   #pragma clang diagnostic push | ||||||
|  |   #pragma clang diagnostic ignored "-Wpacked" | ||||||
|  | /*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ | ||||||
|  |   __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; | ||||||
|  |   #pragma clang diagnostic pop | ||||||
|  |   #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT16_READ | ||||||
|  |   #pragma clang diagnostic push | ||||||
|  |   #pragma clang diagnostic ignored "-Wpacked" | ||||||
|  | /*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ | ||||||
|  |   __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; | ||||||
|  |   #pragma clang diagnostic pop | ||||||
|  |   #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32_WRITE | ||||||
|  |   #pragma clang diagnostic push | ||||||
|  |   #pragma clang diagnostic ignored "-Wpacked" | ||||||
|  | /*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ | ||||||
|  |   __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; | ||||||
|  |   #pragma clang diagnostic pop | ||||||
|  |   #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32_READ | ||||||
|  |   #pragma clang diagnostic push | ||||||
|  |   #pragma clang diagnostic ignored "-Wpacked" | ||||||
|  |   __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; | ||||||
|  |   #pragma clang diagnostic pop | ||||||
|  |   #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v) | ||||||
|  | #endif | ||||||
|  | #ifndef   __ALIGNED | ||||||
|  |   #define __ALIGNED(x)                           __attribute__((aligned(x))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED | ||||||
|  |   #define __PACKED                               __attribute__((packed)) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ##########################  Core Instruction Access  ######################### */ | ||||||
|  | /**
 | ||||||
|  |   \brief   No Operation | ||||||
|  |  */ | ||||||
|  | #define __NOP                             __builtin_arm_nop | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Wait For Interrupt | ||||||
|  |  */ | ||||||
|  | #define __WFI                             __builtin_arm_wfi | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Wait For Event | ||||||
|  |  */ | ||||||
|  | #define __WFE                             __builtin_arm_wfe | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Send Event | ||||||
|  |  */ | ||||||
|  | #define __SEV                             __builtin_arm_sev | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Instruction Synchronization Barrier | ||||||
|  |  */ | ||||||
|  | #define __ISB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __builtin_arm_isb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Data Synchronization Barrier | ||||||
|  |  */ | ||||||
|  | #define __DSB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __builtin_arm_dsb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Data Memory Barrier | ||||||
|  |  */ | ||||||
|  | #define __DMB() do {\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                    __builtin_arm_dmb(0xF);\ | ||||||
|  |                    __schedule_barrier();\ | ||||||
|  |                 } while (0U) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (32 bit) | ||||||
|  |   \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #define __REV(value)   __builtin_bswap32(value) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (16 bit) | ||||||
|  |   \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #define __REV16(value) __ROR(__REV(value), 16) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (16 bit) | ||||||
|  |   \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #define __REVSH(value) (int16_t)__builtin_bswap16(value) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Rotate Right in unsigned value (32 bit) | ||||||
|  |   \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. | ||||||
|  |   \param [in]    op1  Value to rotate | ||||||
|  |   \param [in]    op2  Number of Bits to rotate | ||||||
|  |   \return               Rotated value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) | ||||||
|  | { | ||||||
|  |   op2 %= 32U; | ||||||
|  |   if (op2 == 0U) | ||||||
|  |   { | ||||||
|  |     return op1; | ||||||
|  |   } | ||||||
|  |   return (op1 >> op2) | (op1 << (32U - op2)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Breakpoint | ||||||
|  |   \param [in]    value  is ignored by the processor. | ||||||
|  |                  If required, a debugger can use it to store additional information about the breakpoint. | ||||||
|  |  */ | ||||||
|  | #define __BKPT(value)   __ASM volatile ("bkpt "#value) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse bit order of value | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #define __RBIT          __builtin_arm_rbit | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Count leading zeros | ||||||
|  |   \param [in]  value  Value to count the leading zeros | ||||||
|  |   \return             number of leading zeros in value | ||||||
|  |  */ | ||||||
|  | #define __CLZ           (uint8_t)__builtin_clz | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (8 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 8 bit value. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return             value of type uint8_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #define __LDREXB        (uint8_t)__builtin_arm_ldrex | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (16 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 16 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint16_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #define __LDREXH        (uint16_t)__builtin_arm_ldrex | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (32 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 32 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint32_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | #define __LDREXW        (uint32_t)__builtin_arm_ldrex | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (8 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 8 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #define __STREXB        (uint32_t)__builtin_arm_strex | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (16 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 16 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #define __STREXH        (uint32_t)__builtin_arm_strex | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (32 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 32 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | #define __STREXW        (uint32_t)__builtin_arm_strex | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Remove the exclusive lock | ||||||
|  |   \details Removes the exclusive lock which is created by LDREX. | ||||||
|  |  */ | ||||||
|  | #define __CLREX             __builtin_arm_clrex | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Signed Saturate | ||||||
|  |   \details Saturates a signed value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (1..32) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | #define __SSAT             __builtin_arm_ssat | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Unsigned Saturate | ||||||
|  |   \details Saturates an unsigned value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (0..31) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | #define __USAT             __builtin_arm_usat | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ###########################  Core Function Access  ########################### */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get FPSCR | ||||||
|  |   \details Returns the current value of the Floating Point Status/Control register. | ||||||
|  |   \return               Floating Point Status/Control register value | ||||||
|  |  */ | ||||||
|  | #define __get_FPSCR      __builtin_arm_get_fpscr | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set FPSCR | ||||||
|  |   \details Assigns the given value to the Floating Point Status/Control register. | ||||||
|  |   \param [in]    fpscr  Floating Point Status/Control value to set | ||||||
|  |  */ | ||||||
|  | #define __set_FPSCR      __builtin_arm_set_fpscr | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CPSR Register
 | ||||||
|  |     \return               CPSR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CPSR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile("MRS %0, cpsr" : "=r" (result) ); | ||||||
|  |   return(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CPSR Register
 | ||||||
|  |     \param [in]    cpsr  CPSR value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) | ||||||
|  | { | ||||||
|  | __ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get Mode
 | ||||||
|  |     \return                Processor Mode | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_mode(void) | ||||||
|  | { | ||||||
|  | 	return (__get_CPSR() & 0x1FU); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set Mode
 | ||||||
|  |     \param [in]    mode  Mode value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_mode(uint32_t mode) | ||||||
|  | { | ||||||
|  |   __ASM volatile("MSR  cpsr_c, %0" : : "r" (mode) : "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get Stack Pointer
 | ||||||
|  |     \return Stack Pointer value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_SP() | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile("MOV  %0, sp" : "=r" (result) : : "memory"); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set Stack Pointer
 | ||||||
|  |     \param [in]    stack  Stack Pointer value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_SP(uint32_t stack) | ||||||
|  | { | ||||||
|  |   __ASM volatile("MOV  sp, %0" : : "r" (stack) : "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get USR/SYS Stack Pointer
 | ||||||
|  |     \return USR/SYS Stack Pointer value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_SP_usr() | ||||||
|  | { | ||||||
|  |   uint32_t cpsr; | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile( | ||||||
|  |     "MRS     %0, cpsr   \n" | ||||||
|  |     "CPS     #0x1F      \n" // no effect in USR mode
 | ||||||
|  |     "MOV     %1, sp     \n" | ||||||
|  |     "MSR     cpsr_c, %2 \n" // no effect in USR mode
 | ||||||
|  |     "ISB" :  "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory" | ||||||
|  |    ); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set USR/SYS Stack Pointer
 | ||||||
|  |     \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) | ||||||
|  | { | ||||||
|  |   uint32_t cpsr; | ||||||
|  |   __ASM volatile( | ||||||
|  |     "MRS     %0, cpsr   \n" | ||||||
|  |     "CPS     #0x1F      \n" // no effect in USR mode
 | ||||||
|  |     "MOV     sp, %1     \n" | ||||||
|  |     "MSR     cpsr_c, %2 \n" // no effect in USR mode
 | ||||||
|  |     "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory" | ||||||
|  |    ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get FPEXC
 | ||||||
|  |     \return               Floating Point Exception Control register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_FPEXC(void) | ||||||
|  | { | ||||||
|  | #if (__FPU_PRESENT == 1) | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); | ||||||
|  |   return(result); | ||||||
|  | #else | ||||||
|  |   return(0); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set FPEXC
 | ||||||
|  |     \param [in]    fpexc  Floating Point Exception Control value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) | ||||||
|  | { | ||||||
|  | #if (__FPU_PRESENT == 1) | ||||||
|  |   __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Include common core functions to access Coprocessor 15 registers | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) | ||||||
|  | #define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) | ||||||
|  | #define __get_CP64(cp, op1, Rt, CRm)         __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : "=r" (Rt) : : "memory" ) | ||||||
|  | #define __set_CP64(cp, op1, Rt, CRm)         __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : : "r" (Rt) : "memory" ) | ||||||
|  | 
 | ||||||
|  | #include "cmsis_cp15.h" | ||||||
|  | 
 | ||||||
|  | /** \brief  Enable Floating Point Unit
 | ||||||
|  | 
 | ||||||
|  |   Critical section, called from undef handler, so systick is disabled | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __FPU_Enable(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile( | ||||||
|  |     //Permit access to VFP/NEON, registers by modifying CPACR
 | ||||||
|  |     "        MRC     p15,0,R1,c1,c0,2  \n" | ||||||
|  |     "        ORR     R1,R1,#0x00F00000 \n" | ||||||
|  |     "        MCR     p15,0,R1,c1,c0,2  \n" | ||||||
|  | 
 | ||||||
|  |     //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
 | ||||||
|  |     "        ISB                       \n" | ||||||
|  | 
 | ||||||
|  |     //Enable VFP/NEON
 | ||||||
|  |     "        VMRS    R1,FPEXC          \n" | ||||||
|  |     "        ORR     R1,R1,#0x40000000 \n" | ||||||
|  |     "        VMSR    FPEXC,R1          \n" | ||||||
|  | 
 | ||||||
|  |     //Initialise VFP/NEON registers to 0
 | ||||||
|  |     "        MOV     R2,#0             \n" | ||||||
|  | 
 | ||||||
|  |     //Initialise D16 registers to 0
 | ||||||
|  |     "        VMOV    D0, R2,R2         \n" | ||||||
|  |     "        VMOV    D1, R2,R2         \n" | ||||||
|  |     "        VMOV    D2, R2,R2         \n" | ||||||
|  |     "        VMOV    D3, R2,R2         \n" | ||||||
|  |     "        VMOV    D4, R2,R2         \n" | ||||||
|  |     "        VMOV    D5, R2,R2         \n" | ||||||
|  |     "        VMOV    D6, R2,R2         \n" | ||||||
|  |     "        VMOV    D7, R2,R2         \n" | ||||||
|  |     "        VMOV    D8, R2,R2         \n" | ||||||
|  |     "        VMOV    D9, R2,R2         \n" | ||||||
|  |     "        VMOV    D10,R2,R2         \n" | ||||||
|  |     "        VMOV    D11,R2,R2         \n" | ||||||
|  |     "        VMOV    D12,R2,R2         \n" | ||||||
|  |     "        VMOV    D13,R2,R2         \n" | ||||||
|  |     "        VMOV    D14,R2,R2         \n" | ||||||
|  |     "        VMOV    D15,R2,R2         \n" | ||||||
|  | 
 | ||||||
|  | #if __ARM_NEON == 1 | ||||||
|  |     //Initialise D32 registers to 0
 | ||||||
|  |     "        VMOV    D16,R2,R2         \n" | ||||||
|  |     "        VMOV    D17,R2,R2         \n" | ||||||
|  |     "        VMOV    D18,R2,R2         \n" | ||||||
|  |     "        VMOV    D19,R2,R2         \n" | ||||||
|  |     "        VMOV    D20,R2,R2         \n" | ||||||
|  |     "        VMOV    D21,R2,R2         \n" | ||||||
|  |     "        VMOV    D22,R2,R2         \n" | ||||||
|  |     "        VMOV    D23,R2,R2         \n" | ||||||
|  |     "        VMOV    D24,R2,R2         \n" | ||||||
|  |     "        VMOV    D25,R2,R2         \n" | ||||||
|  |     "        VMOV    D26,R2,R2         \n" | ||||||
|  |     "        VMOV    D27,R2,R2         \n" | ||||||
|  |     "        VMOV    D28,R2,R2         \n" | ||||||
|  |     "        VMOV    D29,R2,R2         \n" | ||||||
|  |     "        VMOV    D30,R2,R2         \n" | ||||||
|  |     "        VMOV    D31,R2,R2         \n" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     //Initialise FPSCR to a known state
 | ||||||
|  |     "        VMRS    R2,FPSCR          \n" | ||||||
|  |     "        LDR     R3,=0x00086060    \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
 | ||||||
|  |     "        AND     R2,R2,R3          \n" | ||||||
|  |     "        VMSR    FPSCR,R2            " | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_ARMCLANG_H */ | ||||||
							
								
								
									
										201
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_compiler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_compiler.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,201 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_compiler.h | ||||||
|  |  * @brief    CMSIS compiler specific macros, functions, instructions | ||||||
|  |  * @version  V1.0.2 | ||||||
|  |  * @date     10. January 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_COMPILER_H | ||||||
|  | #define __CMSIS_COMPILER_H | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Arm Compiler 4/5 | ||||||
|  |  */ | ||||||
|  | #if   defined ( __CC_ARM ) | ||||||
|  |   #include "cmsis_armcc.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Arm Compiler 6 (armclang) | ||||||
|  |  */ | ||||||
|  | #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) | ||||||
|  |   #include "cmsis_armclang.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * GNU Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __GNUC__ ) | ||||||
|  |   #include "cmsis_gcc.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * IAR Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __ICCARM__ ) | ||||||
|  |   #include "cmsis_iccarm.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * TI Arm Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __TI_ARM__ ) | ||||||
|  |   #include <cmsis_ccs.h> | ||||||
|  | 
 | ||||||
|  |   #ifndef   __ASM | ||||||
|  |     #define __ASM                     __asm | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __INLINE | ||||||
|  |     #define __INLINE                  inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_INLINE | ||||||
|  |     #define __STATIC_INLINE           static inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_INLINE | ||||||
|  |     #define __STATIC_INLINE           static inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_FORCEINLINE | ||||||
|  |     #define __STATIC_FORCEINLINE      __STATIC_INLINE | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __NO_RETURN | ||||||
|  |     #define __NO_RETURN               __attribute__((noreturn)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   CMSIS_DEPRECATED | ||||||
|  |     #define CMSIS_DEPRECATED          __attribute__((deprecated)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __USED | ||||||
|  |     #define __USED                    __attribute__((used)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __WEAK | ||||||
|  |     #define __WEAK                    __attribute__((weak)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32 | ||||||
|  |     struct __attribute__((packed)) T_UINT32 { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32(x)     (((struct T_UINT32 *)(x))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __ALIGNED | ||||||
|  |     #define __ALIGNED(x)              __attribute__((aligned(x))) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED | ||||||
|  |     #define __PACKED                  __attribute__((packed)) | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * TASKING Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __TASKING__ ) | ||||||
|  |   /*
 | ||||||
|  |    * The CMSIS functions have been implemented as intrinsics in the compiler. | ||||||
|  |    * Please use "carm -?i" to get an up to date list of all intrinsics, | ||||||
|  |    * Including the CMSIS ones. | ||||||
|  |    */ | ||||||
|  | 
 | ||||||
|  |   #ifndef   __ASM | ||||||
|  |     #define __ASM                     __asm | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __INLINE | ||||||
|  |     #define __INLINE                  inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_INLINE | ||||||
|  |     #define __STATIC_INLINE           static inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_FORCEINLINE | ||||||
|  |     #define __STATIC_FORCEINLINE      __STATIC_INLINE | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __NO_RETURN | ||||||
|  |     #define __NO_RETURN               __attribute__((noreturn)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   CMSIS_DEPRECATED | ||||||
|  |     #define CMSIS_DEPRECATED          __attribute__((deprecated)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __USED | ||||||
|  |     #define __USED                    __attribute__((used)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __WEAK | ||||||
|  |     #define __WEAK                    __attribute__((weak)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32 | ||||||
|  |     struct __packed__ T_UINT32 { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32(x)     (((struct T_UINT32 *)(x))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __ALIGNED | ||||||
|  |     #define __ALIGNED(x)              __align(x) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED | ||||||
|  |     #define __PACKED                  __packed__ | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * COSMIC Compiler | ||||||
|  |  */ | ||||||
|  | #elif defined ( __CSMC__ ) | ||||||
|  |    #include <cmsis_csm.h> | ||||||
|  | 
 | ||||||
|  |  #ifndef   __ASM | ||||||
|  |     #define __ASM                     _asm | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __INLINE | ||||||
|  |     #define __INLINE                  inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_INLINE | ||||||
|  |     #define __STATIC_INLINE           static inline | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __STATIC_FORCEINLINE | ||||||
|  |     #define __STATIC_FORCEINLINE      __STATIC_INLINE | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __NO_RETURN | ||||||
|  |     // NO RETURN is automatically detected hence no warning here
 | ||||||
|  |     #define __NO_RETURN | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __USED | ||||||
|  |     #warning No compiler specific solution for __USED. __USED is ignored. | ||||||
|  |     #define __USED | ||||||
|  |   #endif | ||||||
|  |   #ifndef   CMSIS_DEPRECATED | ||||||
|  |     #warning No compiler specific solution for CMSIS_DEPRECATED. CMSIS_DEPRECATED is ignored. | ||||||
|  |     #define CMSIS_DEPRECATED | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __WEAK | ||||||
|  |     #define __WEAK                    __weak | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __UNALIGNED_UINT32 | ||||||
|  |     @packed struct T_UINT32 { uint32_t v; }; | ||||||
|  |     #define __UNALIGNED_UINT32(x)     (((struct T_UINT32 *)(x))->v) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __ALIGNED | ||||||
|  |     #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. | ||||||
|  |     #define __ALIGNED(x) | ||||||
|  |   #endif | ||||||
|  |   #ifndef   __PACKED | ||||||
|  |     #define __PACKED                  @packed | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  |   #error Unknown compiler. | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_COMPILER_H */ | ||||||
|  | 
 | ||||||
							
								
								
									
										514
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_cp15.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										514
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_cp15.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,514 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_cp15.h | ||||||
|  |  * @brief    CMSIS compiler specific macros, functions, instructions | ||||||
|  |  * @version  V1.0.1 | ||||||
|  |  * @date     07. Sep 2017 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2017 ARM Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if   defined ( __ICCARM__ ) | ||||||
|  |   #pragma system_include         /* treat file as system include file for MISRA check */ | ||||||
|  | #elif defined (__clang__) | ||||||
|  |   #pragma clang system_header   /* treat file as system include file */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_CP15_H | ||||||
|  | #define __CMSIS_CP15_H | ||||||
|  | 
 | ||||||
|  | /** \brief  Get ACTLR
 | ||||||
|  |     \return               Auxiliary Control register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_ACTLR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 1, 0, 1); | ||||||
|  |   return(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set ACTLR
 | ||||||
|  |     \param [in]    actlr  Auxiliary Control value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, actlr, 1, 0, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CPACR
 | ||||||
|  |     \return               Coprocessor Access Control register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CPACR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 1, 0, 2); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CPACR
 | ||||||
|  |     \param [in]    cpacr  Coprocessor Access Control value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, cpacr, 1, 0, 2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get DFSR
 | ||||||
|  |     \return               Data Fault Status Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_DFSR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 5, 0, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set DFSR
 | ||||||
|  |     \param [in]    dfsr  Data Fault Status value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, dfsr, 5, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get IFSR
 | ||||||
|  |     \return               Instruction Fault Status Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_IFSR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 5, 0, 1); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set IFSR
 | ||||||
|  |     \param [in]    ifsr  Instruction Fault Status value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, ifsr, 5, 0, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get ISR
 | ||||||
|  |     \return               Interrupt Status Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_ISR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 12, 1, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CBAR
 | ||||||
|  |     \return               Configuration Base Address register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CBAR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 4, result, 15, 0, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get TTBR0
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the Translation Table Base Register 0. | ||||||
|  | 
 | ||||||
|  |     \return               Translation Table Base Register 0 value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_TTBR0(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 2, 0, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set TTBR0
 | ||||||
|  | 
 | ||||||
|  |     This function assigns the given value to the Translation Table Base Register 0. | ||||||
|  | 
 | ||||||
|  |     \param [in]    ttbr0  Translation Table Base Register 0 value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_TTBR0(uint32_t ttbr0) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, ttbr0, 2, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get DACR
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the Domain Access Control Register. | ||||||
|  | 
 | ||||||
|  |     \return               Domain Access Control Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_DACR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 3, 0, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set DACR
 | ||||||
|  | 
 | ||||||
|  |     This function assigns the given value to the Domain Access Control Register. | ||||||
|  | 
 | ||||||
|  |     \param [in]    dacr   Domain Access Control Register value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_DACR(uint32_t dacr) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, dacr, 3, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set SCTLR
 | ||||||
|  | 
 | ||||||
|  |     This function assigns the given value to the System Control Register. | ||||||
|  | 
 | ||||||
|  |     \param [in]    sctlr  System Control Register value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, sctlr, 1, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get SCTLR
 | ||||||
|  |     \return               System Control Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_SCTLR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 1, 0, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set ACTRL
 | ||||||
|  |     \param [in]    actrl  Auxiliary Control Register value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, actrl, 1, 0, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get ACTRL
 | ||||||
|  |     \return               Auxiliary Control Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_ACTRL(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 1, 0, 1); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get MPIDR
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the Multiprocessor Affinity Register. | ||||||
|  | 
 | ||||||
|  |     \return               Multiprocessor Affinity Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_MPIDR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 0, 0, 5); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get VBAR
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the Vector Base Address Register. | ||||||
|  | 
 | ||||||
|  |     \return               Vector Base Address Register | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_VBAR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 12, 0, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set VBAR
 | ||||||
|  | 
 | ||||||
|  |     This function assigns the given value to the Vector Base Address Register. | ||||||
|  | 
 | ||||||
|  |     \param [in]    vbar  Vector Base Address Register value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, vbar, 12, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get MVBAR
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the Monitor Vector Base Address Register. | ||||||
|  | 
 | ||||||
|  |     \return               Monitor Vector Base Address Register | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_MVBAR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 12, 0, 1); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set MVBAR
 | ||||||
|  | 
 | ||||||
|  |     This function assigns the given value to the Monitor Vector Base Address Register. | ||||||
|  | 
 | ||||||
|  |     \param [in]    mvbar  Monitor Vector Base Address Register value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_MVBAR(uint32_t mvbar) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, mvbar, 12, 0, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \ | ||||||
|  |     defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \ | ||||||
|  |     defined(DOXYGEN) | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CNTFRQ
 | ||||||
|  | 
 | ||||||
|  |   This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ). | ||||||
|  | 
 | ||||||
|  |   \param [in]    value  CNTFRQ Register value to set | ||||||
|  | */ | ||||||
|  | __STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 14, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CNTFRQ
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ). | ||||||
|  | 
 | ||||||
|  |     \return               CNTFRQ Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 14, 0 , 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CNTP_TVAL
 | ||||||
|  | 
 | ||||||
|  |   This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). | ||||||
|  | 
 | ||||||
|  |   \param [in]    value  CNTP_TVAL Register value to set | ||||||
|  | */ | ||||||
|  | __STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 14, 2, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CNTP_TVAL
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). | ||||||
|  | 
 | ||||||
|  |     \return               CNTP_TVAL Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 14, 2, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CNTPCT
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT). | ||||||
|  | 
 | ||||||
|  |     \return               CNTPCT Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint64_t __get_CNTPCT(void) | ||||||
|  | { | ||||||
|  |   uint64_t result; | ||||||
|  |   __get_CP64(15, 0, result, 14); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CNTP_CVAL
 | ||||||
|  | 
 | ||||||
|  |   This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). | ||||||
|  | 
 | ||||||
|  |   \param [in]    value  CNTP_CVAL Register value to set | ||||||
|  | */ | ||||||
|  | __STATIC_FORCEINLINE void __set_CNTP_CVAL(uint64_t value) | ||||||
|  | { | ||||||
|  |   __set_CP64(15, 2, value, 14); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CNTP_CVAL
 | ||||||
|  | 
 | ||||||
|  |     This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). | ||||||
|  | 
 | ||||||
|  |     \return               CNTP_CVAL Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint64_t __get_CNTP_CVAL(void) | ||||||
|  | { | ||||||
|  |   uint64_t result; | ||||||
|  |   __get_CP64(15, 2, result, 14); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CNTP_CTL
 | ||||||
|  | 
 | ||||||
|  |   This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). | ||||||
|  | 
 | ||||||
|  |   \param [in]    value  CNTP_CTL Register value to set | ||||||
|  | */ | ||||||
|  | __STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 14, 2, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CNTP_CTL register
 | ||||||
|  |     \return               CNTP_CTL Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __get_CP(15, 0, result, 14, 2, 1); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /** \brief  Set TLBIALL
 | ||||||
|  | 
 | ||||||
|  |   TLB Invalidate All | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_TLBIALL(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 8, 7, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set BPIALL.
 | ||||||
|  | 
 | ||||||
|  |   Branch Predictor Invalidate All | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_BPIALL(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 7, 5, 6); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set ICIALLU
 | ||||||
|  | 
 | ||||||
|  |   Instruction Cache Invalidate All | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 7, 5, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set DCCMVAC
 | ||||||
|  | 
 | ||||||
|  |   Data cache clean | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 7, 10, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set DCIMVAC
 | ||||||
|  | 
 | ||||||
|  |   Data cache invalidate | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 7, 6, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set DCCIMVAC
 | ||||||
|  | 
 | ||||||
|  |   Data cache clean and invalidate | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CP(15, 0, value, 7, 14, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CSSELR
 | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_CSSELR(uint32_t value) | ||||||
|  | { | ||||||
|  | //  __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory");
 | ||||||
|  |   __set_CP(15, 2, value, 0, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CSSELR
 | ||||||
|  |     \return CSSELR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CSSELR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  | //  __ASM volatile("MRC p15, 2, %0, c0, c0, 0" : "=r"(result) : : "memory");
 | ||||||
|  |   __get_CP(15, 2, result, 0, 0, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CCSIDR
 | ||||||
|  |     \deprecated CCSIDR itself is read-only. Use __set_CSSELR to select cache level instead. | ||||||
|  |  */ | ||||||
|  | CMSIS_DEPRECATED | ||||||
|  | __STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value) | ||||||
|  | { | ||||||
|  |   __set_CSSELR(value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CCSIDR
 | ||||||
|  |     \return CCSIDR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CCSIDR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  | //  __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory");
 | ||||||
|  |   __get_CP(15, 1, result, 0, 0, 0); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CLIDR
 | ||||||
|  |     \return CLIDR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CLIDR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  | //  __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory");
 | ||||||
|  |   __get_CP(15, 1, result, 0, 0, 1); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set DCISW
 | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_DCISW(uint32_t value) | ||||||
|  | { | ||||||
|  | //  __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(value) : "memory")
 | ||||||
|  |   __set_CP(15, 0, value, 7, 6, 2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set DCCSW
 | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_DCCSW(uint32_t value) | ||||||
|  | { | ||||||
|  | //  __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(value) : "memory")
 | ||||||
|  |   __set_CP(15, 0, value, 7, 10, 2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set DCCISW
 | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_DCCISW(uint32_t value) | ||||||
|  | { | ||||||
|  | //  __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(value) : "memory")
 | ||||||
|  |   __set_CP(15, 0, value, 7, 14, 2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										679
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_gcc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										679
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_gcc.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,679 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_gcc.h | ||||||
|  |  * @brief    CMSIS compiler specific macros, functions, instructions | ||||||
|  |  * @version  V1.0.2 | ||||||
|  |  * @date     09. April 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_GCC_H | ||||||
|  | #define __CMSIS_GCC_H | ||||||
|  | 
 | ||||||
|  | /* ignore some GCC warnings */ | ||||||
|  | #pragma GCC diagnostic push | ||||||
|  | #pragma GCC diagnostic ignored "-Wsign-conversion" | ||||||
|  | #pragma GCC diagnostic ignored "-Wconversion" | ||||||
|  | #pragma GCC diagnostic ignored "-Wunused-parameter" | ||||||
|  | 
 | ||||||
|  | /* Fallback for __has_builtin */ | ||||||
|  | #ifndef __has_builtin | ||||||
|  |   #define __has_builtin(x) (0) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* CMSIS compiler specific defines */ | ||||||
|  | #ifndef   __ASM | ||||||
|  |   #define __ASM                                  asm | ||||||
|  | #endif | ||||||
|  | #ifndef   __INLINE | ||||||
|  |   #define __INLINE                               inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __FORCEINLINE | ||||||
|  |   #define __FORCEINLINE                          __attribute__((always_inline)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __STATIC_INLINE | ||||||
|  |   #define __STATIC_INLINE                        static inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __STATIC_FORCEINLINE | ||||||
|  |   #define __STATIC_FORCEINLINE                   __attribute__((always_inline)) static inline | ||||||
|  | #endif | ||||||
|  | #ifndef   __NO_RETURN | ||||||
|  |   #define __NO_RETURN                            __attribute__((__noreturn__)) | ||||||
|  | #endif | ||||||
|  | #ifndef   CMSIS_DEPRECATED | ||||||
|  |  #define  CMSIS_DEPRECATED                       __attribute__((deprecated)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __USED | ||||||
|  |   #define __USED                                 __attribute__((used)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __WEAK | ||||||
|  |   #define __WEAK                                 __attribute__((weak)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED | ||||||
|  |   #define __PACKED                               __attribute__((packed, aligned(1))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __PACKED_STRUCT | ||||||
|  |   #define __PACKED_STRUCT                        struct __attribute__((packed, aligned(1))) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT16_WRITE | ||||||
|  |   #pragma GCC diagnostic push | ||||||
|  |   #pragma GCC diagnostic ignored "-Wpacked" | ||||||
|  | /*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ | ||||||
|  |   __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; | ||||||
|  |   #pragma GCC diagnostic pop | ||||||
|  |   #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT16_READ | ||||||
|  |   #pragma GCC diagnostic push | ||||||
|  |   #pragma GCC diagnostic ignored "-Wpacked" | ||||||
|  | /*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ | ||||||
|  |   __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; | ||||||
|  |   #pragma GCC diagnostic pop | ||||||
|  |   #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32_WRITE | ||||||
|  |   #pragma GCC diagnostic push | ||||||
|  |   #pragma GCC diagnostic ignored "-Wpacked" | ||||||
|  | /*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ | ||||||
|  |   __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; | ||||||
|  |   #pragma GCC diagnostic pop | ||||||
|  |   #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) | ||||||
|  | #endif | ||||||
|  | #ifndef   __UNALIGNED_UINT32_READ | ||||||
|  |   #pragma GCC diagnostic push | ||||||
|  |   #pragma GCC diagnostic ignored "-Wpacked" | ||||||
|  |   __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; | ||||||
|  |   #pragma GCC diagnostic pop | ||||||
|  |   #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v) | ||||||
|  | #endif | ||||||
|  | #ifndef   __ALIGNED | ||||||
|  |   #define __ALIGNED(x)                           __attribute__((aligned(x))) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ##########################  Core Instruction Access  ######################### */ | ||||||
|  | /**
 | ||||||
|  |   \brief   No Operation | ||||||
|  |  */ | ||||||
|  | #define __NOP()                             __ASM volatile ("nop") | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Wait For Interrupt | ||||||
|  |  */ | ||||||
|  | #define __WFI()                             __ASM volatile ("wfi") | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Wait For Event | ||||||
|  |  */ | ||||||
|  | #define __WFE()                             __ASM volatile ("wfe") | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Send Event | ||||||
|  |  */ | ||||||
|  | #define __SEV()                             __ASM volatile ("sev") | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Instruction Synchronization Barrier | ||||||
|  |   \details Instruction Synchronization Barrier flushes the pipeline in the processor, | ||||||
|  |            so that all instructions following the ISB are fetched from cache or memory, | ||||||
|  |            after the instruction has been completed. | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  void __ISB(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile ("isb 0xF":::"memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Data Synchronization Barrier | ||||||
|  |   \details Acts as a special kind of Data Memory Barrier. | ||||||
|  |            It completes when all explicit memory accesses before this instruction complete. | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  void __DSB(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile ("dsb 0xF":::"memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Data Memory Barrier | ||||||
|  |   \details Ensures the apparent order of the explicit memory operations before | ||||||
|  |            and after the instruction, without ensuring their completion. | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  void __DMB(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile ("dmb 0xF":::"memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (32 bit) | ||||||
|  |   \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint32_t __REV(uint32_t value) | ||||||
|  | { | ||||||
|  | #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) | ||||||
|  |   return __builtin_bswap32(value); | ||||||
|  | #else | ||||||
|  |   uint32_t result; | ||||||
|  | 
 | ||||||
|  |   __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); | ||||||
|  |   return result; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (16 bit) | ||||||
|  |   \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | #ifndef __NO_EMBEDDED_ASM | ||||||
|  | __attribute__((section(".rev16_text"))) __STATIC_INLINE uint32_t __REV16(uint32_t value) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile("rev16 %0, %1" : "=r" (result) : "r" (value)); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse byte order (16 bit) | ||||||
|  |   \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  int16_t __REVSH(int16_t value) | ||||||
|  | { | ||||||
|  | #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) | ||||||
|  |   return (int16_t)__builtin_bswap16(value); | ||||||
|  | #else | ||||||
|  |   int16_t result; | ||||||
|  | 
 | ||||||
|  |   __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); | ||||||
|  |   return result; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Rotate Right in unsigned value (32 bit) | ||||||
|  |   \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. | ||||||
|  |   \param [in]    op1  Value to rotate | ||||||
|  |   \param [in]    op2  Number of Bits to rotate | ||||||
|  |   \return               Rotated value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint32_t __ROR(uint32_t op1, uint32_t op2) | ||||||
|  | { | ||||||
|  |   op2 %= 32U; | ||||||
|  |   if (op2 == 0U) { | ||||||
|  |     return op1; | ||||||
|  |   } | ||||||
|  |   return (op1 >> op2) | (op1 << (32U - op2)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Breakpoint | ||||||
|  |   \param [in]    value  is ignored by the processor. | ||||||
|  |                  If required, a debugger can use it to store additional information about the breakpoint. | ||||||
|  |  */ | ||||||
|  | #define __BKPT(value)                       __ASM volatile ("bkpt "#value) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Reverse bit order of value | ||||||
|  |   \details Reverses the bit order of the given value. | ||||||
|  |   \param [in]    value  Value to reverse | ||||||
|  |   \return               Reversed value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint32_t __RBIT(uint32_t value) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  | 
 | ||||||
|  | #if ((defined (__ARM_ARCH_7M__      ) && (__ARM_ARCH_7M__      == 1)) || \ | ||||||
|  |      (defined (__ARM_ARCH_7EM__     ) && (__ARM_ARCH_7EM__     == 1)) || \ | ||||||
|  |      (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))    ) | ||||||
|  |    __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); | ||||||
|  | #else | ||||||
|  |   int32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ | ||||||
|  | 
 | ||||||
|  |   result = value;                      /* r will be reversed bits of v; first get LSB of v */ | ||||||
|  |   for (value >>= 1U; value; value >>= 1U) | ||||||
|  |   { | ||||||
|  |     result <<= 1U; | ||||||
|  |     result |= value & 1U; | ||||||
|  |     s--; | ||||||
|  |   } | ||||||
|  |   result <<= s;                        /* shift when v's highest bits are zero */ | ||||||
|  | #endif | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Count leading zeros | ||||||
|  |   \param [in]  value  Value to count the leading zeros | ||||||
|  |   \return             number of leading zeros in value | ||||||
|  |  */ | ||||||
|  | #define __CLZ                             (uint8_t)__builtin_clz | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (8 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 8 bit value. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return             value of type uint8_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint8_t __LDREXB(volatile uint8_t *addr) | ||||||
|  | { | ||||||
|  |     uint32_t result; | ||||||
|  | 
 | ||||||
|  | #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) | ||||||
|  |    __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); | ||||||
|  | #else | ||||||
|  |     /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
 | ||||||
|  |        accepted by assembler. So has to use following less efficient pattern. | ||||||
|  |     */ | ||||||
|  |    __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); | ||||||
|  | #endif | ||||||
|  |    return ((uint8_t) result);    /* Add explicit type cast here */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (16 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 16 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint16_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint16_t __LDREXH(volatile uint16_t *addr) | ||||||
|  | { | ||||||
|  |     uint32_t result; | ||||||
|  | 
 | ||||||
|  | #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) | ||||||
|  |    __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); | ||||||
|  | #else | ||||||
|  |     /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
 | ||||||
|  |        accepted by assembler. So has to use following less efficient pattern. | ||||||
|  |     */ | ||||||
|  |    __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); | ||||||
|  | #endif | ||||||
|  |    return ((uint16_t) result);    /* Add explicit type cast here */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   LDR Exclusive (32 bit) | ||||||
|  |   \details Executes a exclusive LDR instruction for 32 bit values. | ||||||
|  |   \param [in]    ptr  Pointer to data | ||||||
|  |   \return        value of type uint32_t at (*ptr) | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint32_t __LDREXW(volatile uint32_t *addr) | ||||||
|  | { | ||||||
|  |     uint32_t result; | ||||||
|  | 
 | ||||||
|  |    __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); | ||||||
|  |    return(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (8 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 8 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) | ||||||
|  | { | ||||||
|  |    uint32_t result; | ||||||
|  | 
 | ||||||
|  |    __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); | ||||||
|  |    return(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (16 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 16 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) | ||||||
|  | { | ||||||
|  |    uint32_t result; | ||||||
|  | 
 | ||||||
|  |    __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); | ||||||
|  |    return(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   STR Exclusive (32 bit) | ||||||
|  |   \details Executes a exclusive STR instruction for 32 bit values. | ||||||
|  |   \param [in]  value  Value to store | ||||||
|  |   \param [in]    ptr  Pointer to location | ||||||
|  |   \return          0  Function succeeded | ||||||
|  |   \return          1  Function failed | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) | ||||||
|  | { | ||||||
|  |    uint32_t result; | ||||||
|  | 
 | ||||||
|  |    __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); | ||||||
|  |    return(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Remove the exclusive lock | ||||||
|  |   \details Removes the exclusive lock which is created by LDREX. | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  void __CLREX(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile ("clrex" ::: "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Signed Saturate | ||||||
|  |   \details Saturates a signed value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (1..32) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | #define __SSAT(ARG1,ARG2) \ | ||||||
|  | __extension__ \ | ||||||
|  | ({                          \ | ||||||
|  |   int32_t __RES, __ARG1 = (ARG1); \ | ||||||
|  |   __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \ | ||||||
|  |   __RES; \ | ||||||
|  |  }) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Unsigned Saturate | ||||||
|  |   \details Saturates an unsigned value. | ||||||
|  |   \param [in]  value  Value to be saturated | ||||||
|  |   \param [in]    sat  Bit position to saturate to (0..31) | ||||||
|  |   \return             Saturated value | ||||||
|  |  */ | ||||||
|  | #define __USAT(ARG1,ARG2) \ | ||||||
|  | __extension__ \ | ||||||
|  | ({                          \ | ||||||
|  |   uint32_t __RES, __ARG1 = (ARG1); \ | ||||||
|  |   __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \ | ||||||
|  |   __RES; \ | ||||||
|  |  }) | ||||||
|  | 
 | ||||||
|  | /* ###########################  Core Function Access  ########################### */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Enable IRQ Interrupts | ||||||
|  |   \details Enables IRQ interrupts by clearing the I-bit in the CPSR. | ||||||
|  |            Can only be executed in Privileged modes. | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __enable_irq(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile ("cpsie i" : : : "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Disable IRQ Interrupts | ||||||
|  |   \details Disables IRQ interrupts by setting the I-bit in the CPSR. | ||||||
|  |   Can only be executed in Privileged modes. | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE  void __disable_irq(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile ("cpsid i" : : : "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Get FPSCR | ||||||
|  |   \details Returns the current value of the Floating Point Status/Control register. | ||||||
|  |   \return Floating Point Status/Control register value | ||||||
|  | */ | ||||||
|  | __STATIC_FORCEINLINE  uint32_t __get_FPSCR(void) | ||||||
|  | { | ||||||
|  |   #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |        (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     ) | ||||||
|  |   #if __has_builtin(__builtin_arm_get_fpscr)  | ||||||
|  |   // Re-enable using built-in when GCC has been fixed
 | ||||||
|  |   // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
 | ||||||
|  |     /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ | ||||||
|  |     return __builtin_arm_get_fpscr(); | ||||||
|  |   #else | ||||||
|  |     uint32_t result; | ||||||
|  | 
 | ||||||
|  |     __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); | ||||||
|  |     return(result); | ||||||
|  |   #endif | ||||||
|  |   #else | ||||||
|  |     return(0U); | ||||||
|  |   #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   \brief   Set FPSCR | ||||||
|  |   \details Assigns the given value to the Floating Point Status/Control register. | ||||||
|  |   \param [in] fpscr  Floating Point Status/Control value to set | ||||||
|  | */ | ||||||
|  | __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) | ||||||
|  | { | ||||||
|  |   #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||||
|  |        (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     ) | ||||||
|  |   #if __has_builtin(__builtin_arm_set_fpscr) | ||||||
|  |   // Re-enable using built-in when GCC has been fixed
 | ||||||
|  |   // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
 | ||||||
|  |     /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ | ||||||
|  |     __builtin_arm_set_fpscr(fpscr); | ||||||
|  |   #else | ||||||
|  |     __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); | ||||||
|  |   #endif | ||||||
|  |   #else | ||||||
|  |     (void)fpscr; | ||||||
|  |   #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get CPSR Register
 | ||||||
|  |     \return               CPSR Register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_CPSR(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile("MRS %0, cpsr" : "=r" (result) ); | ||||||
|  |   return(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set CPSR Register
 | ||||||
|  |     \param [in]    cpsr  CPSR value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) | ||||||
|  | { | ||||||
|  | __ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get Mode
 | ||||||
|  |     \return                Processor Mode | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_mode(void) | ||||||
|  | { | ||||||
|  |     return (__get_CPSR() & 0x1FU); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set Mode
 | ||||||
|  |     \param [in]    mode  Mode value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_mode(uint32_t mode) | ||||||
|  | { | ||||||
|  |   __ASM volatile("MSR  cpsr_c, %0" : : "r" (mode) : "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get Stack Pointer
 | ||||||
|  |     \return Stack Pointer value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_SP(void) | ||||||
|  | { | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile("MOV  %0, sp" : "=r" (result) : : "memory"); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set Stack Pointer
 | ||||||
|  |     \param [in]    stack  Stack Pointer value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_SP(uint32_t stack) | ||||||
|  | { | ||||||
|  |   __ASM volatile("MOV  sp, %0" : : "r" (stack) : "memory"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get USR/SYS Stack Pointer
 | ||||||
|  |     \return USR/SYS Stack Pointer value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_SP_usr(void) | ||||||
|  | { | ||||||
|  |   uint32_t cpsr = __get_CPSR(); | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile( | ||||||
|  |     "CPS     #0x1F  \n" | ||||||
|  |     "MOV     %0, sp   " : "=r"(result) : : "memory" | ||||||
|  |    ); | ||||||
|  |   __set_CPSR(cpsr); | ||||||
|  |   __ISB(); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set USR/SYS Stack Pointer
 | ||||||
|  |     \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) | ||||||
|  | { | ||||||
|  |   uint32_t cpsr = __get_CPSR(); | ||||||
|  |   __ASM volatile( | ||||||
|  |     "CPS     #0x1F  \n" | ||||||
|  |     "MOV     sp, %0   " : : "r" (topOfProcStack) : "memory" | ||||||
|  |    ); | ||||||
|  |   __set_CPSR(cpsr); | ||||||
|  |   __ISB(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Get FPEXC
 | ||||||
|  |     \return               Floating Point Exception Control register value | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE uint32_t __get_FPEXC(void) | ||||||
|  | { | ||||||
|  | #if (__FPU_PRESENT == 1) | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile("VMRS %0, fpexc" : "=r" (result) ); | ||||||
|  |   return(result); | ||||||
|  | #else | ||||||
|  |   return(0); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** \brief  Set FPEXC
 | ||||||
|  |     \param [in]    fpexc  Floating Point Exception Control value to set | ||||||
|  |  */ | ||||||
|  | __STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) | ||||||
|  | { | ||||||
|  | #if (__FPU_PRESENT == 1) | ||||||
|  |   __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Include common core functions to access Coprocessor 15 registers | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) | ||||||
|  | #define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) | ||||||
|  | #define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : "=r" (Rt) : : "memory" ) | ||||||
|  | #define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : : "r" (Rt) : "memory" ) | ||||||
|  | 
 | ||||||
|  | #include "cmsis_cp15.h" | ||||||
|  | 
 | ||||||
|  | /** \brief  Enable Floating Point Unit
 | ||||||
|  | 
 | ||||||
|  |   Critical section, called from undef handler, so systick is disabled | ||||||
|  |  */ | ||||||
|  | __STATIC_INLINE void __FPU_Enable(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile( | ||||||
|  |     //Permit access to VFP/NEON, registers by modifying CPACR
 | ||||||
|  |     "        MRC     p15,0,R1,c1,c0,2  \n" | ||||||
|  |     "        ORR     R1,R1,#0x00F00000 \n" | ||||||
|  |     "        MCR     p15,0,R1,c1,c0,2  \n" | ||||||
|  | 
 | ||||||
|  |     //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
 | ||||||
|  |     "        ISB                       \n" | ||||||
|  | 
 | ||||||
|  |     //Enable VFP/NEON
 | ||||||
|  |     "        VMRS    R1,FPEXC          \n" | ||||||
|  |     "        ORR     R1,R1,#0x40000000 \n" | ||||||
|  |     "        VMSR    FPEXC,R1          \n" | ||||||
|  | 
 | ||||||
|  |     //Initialise VFP/NEON registers to 0
 | ||||||
|  |     "        MOV     R2,#0             \n" | ||||||
|  | 
 | ||||||
|  |     //Initialise D16 registers to 0
 | ||||||
|  |     "        VMOV    D0, R2,R2         \n" | ||||||
|  |     "        VMOV    D1, R2,R2         \n" | ||||||
|  |     "        VMOV    D2, R2,R2         \n" | ||||||
|  |     "        VMOV    D3, R2,R2         \n" | ||||||
|  |     "        VMOV    D4, R2,R2         \n" | ||||||
|  |     "        VMOV    D5, R2,R2         \n" | ||||||
|  |     "        VMOV    D6, R2,R2         \n" | ||||||
|  |     "        VMOV    D7, R2,R2         \n" | ||||||
|  |     "        VMOV    D8, R2,R2         \n" | ||||||
|  |     "        VMOV    D9, R2,R2         \n" | ||||||
|  |     "        VMOV    D10,R2,R2         \n" | ||||||
|  |     "        VMOV    D11,R2,R2         \n" | ||||||
|  |     "        VMOV    D12,R2,R2         \n" | ||||||
|  |     "        VMOV    D13,R2,R2         \n" | ||||||
|  |     "        VMOV    D14,R2,R2         \n" | ||||||
|  |     "        VMOV    D15,R2,R2         \n" | ||||||
|  | 
 | ||||||
|  | #if (defined(__ARM_NEON) && (__ARM_NEON == 1)) | ||||||
|  |     //Initialise D32 registers to 0
 | ||||||
|  |     "        VMOV    D16,R2,R2         \n" | ||||||
|  |     "        VMOV    D17,R2,R2         \n" | ||||||
|  |     "        VMOV    D18,R2,R2         \n" | ||||||
|  |     "        VMOV    D19,R2,R2         \n" | ||||||
|  |     "        VMOV    D20,R2,R2         \n" | ||||||
|  |     "        VMOV    D21,R2,R2         \n" | ||||||
|  |     "        VMOV    D22,R2,R2         \n" | ||||||
|  |     "        VMOV    D23,R2,R2         \n" | ||||||
|  |     "        VMOV    D24,R2,R2         \n" | ||||||
|  |     "        VMOV    D25,R2,R2         \n" | ||||||
|  |     "        VMOV    D26,R2,R2         \n" | ||||||
|  |     "        VMOV    D27,R2,R2         \n" | ||||||
|  |     "        VMOV    D28,R2,R2         \n" | ||||||
|  |     "        VMOV    D29,R2,R2         \n" | ||||||
|  |     "        VMOV    D30,R2,R2         \n" | ||||||
|  |     "        VMOV    D31,R2,R2         \n" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     //Initialise FPSCR to a known state
 | ||||||
|  |     "        VMRS    R2,FPSCR          \n" | ||||||
|  |     "        LDR     R3,=0x00086060    \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
 | ||||||
|  |     "        AND     R2,R2,R3          \n" | ||||||
|  |     "        VMSR    FPSCR,R2            " | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #pragma GCC diagnostic pop | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_GCC_H */ | ||||||
							
								
								
									
										559
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										559
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,559 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     cmsis_iccarm.h | ||||||
|  |  * @brief    CMSIS compiler ICCARM (IAR Compiler for Arm) header file | ||||||
|  |  * @version  V5.0.6 | ||||||
|  |  * @date     02. March 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | //------------------------------------------------------------------------------
 | ||||||
|  | //
 | ||||||
|  | // Copyright (c) 2017-2018 IAR Systems
 | ||||||
|  | //
 | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License")
 | ||||||
|  | // you may not use this file except in compliance with the License.
 | ||||||
|  | // You may obtain a copy of the License at
 | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  | //
 | ||||||
|  | // Unless required by applicable law or agreed to in writing, software
 | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||||
|  | // See the License for the specific language governing permissions and
 | ||||||
|  | // limitations under the License.
 | ||||||
|  | //
 | ||||||
|  | //------------------------------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __CMSIS_ICCARM_H__ | ||||||
|  | #define __CMSIS_ICCARM_H__ | ||||||
|  | 
 | ||||||
|  | #ifndef __ICCARM__ | ||||||
|  |   #error This file should only be compiled by ICCARM | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #pragma system_include | ||||||
|  | 
 | ||||||
|  | #define __IAR_FT _Pragma("inline=forced") __intrinsic | ||||||
|  | 
 | ||||||
|  | #if (__VER__ >= 8000000) | ||||||
|  |   #define __ICCARM_V8 1 | ||||||
|  | #else | ||||||
|  |   #define __ICCARM_V8 0 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #pragma language=extended | ||||||
|  | 
 | ||||||
|  | #ifndef __ALIGNED | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __ALIGNED(x) __attribute__((aligned(x))) | ||||||
|  |   #elif (__VER__ >= 7080000) | ||||||
|  |     /* Needs IAR language extensions */ | ||||||
|  |     #define __ALIGNED(x) __attribute__((aligned(x))) | ||||||
|  |   #else | ||||||
|  |     #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. | ||||||
|  |     #define __ALIGNED(x) | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define compiler macros for CPU architecture, used in CMSIS 5.
 | ||||||
|  |  */ | ||||||
|  | #if __ARM_ARCH_7A__ | ||||||
|  | /* Macro already defined */ | ||||||
|  | #else | ||||||
|  |   #if defined(__ARM7A__) | ||||||
|  |     #define __ARM_ARCH_7A__ 1 | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __ASM | ||||||
|  |   #define __ASM __asm | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __INLINE | ||||||
|  |   #define __INLINE inline | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __NO_RETURN | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __NO_RETURN __attribute__((__noreturn__)) | ||||||
|  |   #else | ||||||
|  |     #define __NO_RETURN _Pragma("object_attribute=__noreturn") | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __PACKED | ||||||
|  |   /* Needs IAR language extensions */ | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __PACKED __attribute__((packed, aligned(1))) | ||||||
|  |   #else | ||||||
|  |     #define __PACKED __packed | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __PACKED_STRUCT | ||||||
|  |   /* Needs IAR language extensions */ | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) | ||||||
|  |   #else | ||||||
|  |     #define __PACKED_STRUCT __packed struct | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __PACKED_UNION | ||||||
|  |   /* Needs IAR language extensions */ | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __PACKED_UNION union __attribute__((packed, aligned(1))) | ||||||
|  |   #else | ||||||
|  |     #define __PACKED_UNION __packed union | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __RESTRICT | ||||||
|  |   #define __RESTRICT            __restrict | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __STATIC_INLINE | ||||||
|  |   #define __STATIC_INLINE       static inline | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __FORCEINLINE | ||||||
|  |   #define __FORCEINLINE         _Pragma("inline=forced") | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __STATIC_FORCEINLINE | ||||||
|  |   #define __STATIC_FORCEINLINE  __FORCEINLINE __STATIC_INLINE | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   CMSIS_DEPRECATED | ||||||
|  |   #define CMSIS_DEPRECATED      __attribute__((deprecated)) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT16_READ | ||||||
|  |   #pragma language=save | ||||||
|  |   #pragma language=extended | ||||||
|  |   __IAR_FT uint16_t __iar_uint16_read(void const *ptr) | ||||||
|  |   { | ||||||
|  |     return *(__packed uint16_t*)(ptr); | ||||||
|  |   } | ||||||
|  |   #pragma language=restore | ||||||
|  |   #define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT16_WRITE | ||||||
|  |   #pragma language=save | ||||||
|  |   #pragma language=extended | ||||||
|  |   __IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) | ||||||
|  |   { | ||||||
|  |     *(__packed uint16_t*)(ptr) = val;; | ||||||
|  |   } | ||||||
|  |   #pragma language=restore | ||||||
|  |   #define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT32_READ | ||||||
|  |   #pragma language=save | ||||||
|  |   #pragma language=extended | ||||||
|  |   __IAR_FT uint32_t __iar_uint32_read(void const *ptr) | ||||||
|  |   { | ||||||
|  |     return *(__packed uint32_t*)(ptr); | ||||||
|  |   } | ||||||
|  |   #pragma language=restore | ||||||
|  |   #define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef __UNALIGNED_UINT32_WRITE | ||||||
|  |   #pragma language=save | ||||||
|  |   #pragma language=extended | ||||||
|  |   __IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) | ||||||
|  |   { | ||||||
|  |     *(__packed uint32_t*)(ptr) = val;; | ||||||
|  |   } | ||||||
|  |   #pragma language=restore | ||||||
|  |   #define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if 0 | ||||||
|  | #ifndef __UNALIGNED_UINT32   /* deprecated */ | ||||||
|  |   #pragma language=save | ||||||
|  |   #pragma language=extended | ||||||
|  |   __packed struct  __iar_u32 { uint32_t v; }; | ||||||
|  |   #pragma language=restore | ||||||
|  |   #define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __USED | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __USED __attribute__((used)) | ||||||
|  |   #else | ||||||
|  |     #define __USED _Pragma("__root") | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef   __WEAK | ||||||
|  |   #if __ICCARM_V8 | ||||||
|  |     #define __WEAK __attribute__((weak)) | ||||||
|  |   #else | ||||||
|  |     #define __WEAK _Pragma("__weak") | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __ICCARM_INTRINSICS_VERSION__ | ||||||
|  |   #define __ICCARM_INTRINSICS_VERSION__  0 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if __ICCARM_INTRINSICS_VERSION__ == 2 | ||||||
|  | 
 | ||||||
|  |   #if defined(__CLZ) | ||||||
|  |     #undef __CLZ | ||||||
|  |   #endif | ||||||
|  |   #if defined(__REVSH) | ||||||
|  |     #undef __REVSH | ||||||
|  |   #endif | ||||||
|  |   #if defined(__RBIT) | ||||||
|  |     #undef __RBIT | ||||||
|  |   #endif | ||||||
|  |   #if defined(__SSAT) | ||||||
|  |     #undef __SSAT | ||||||
|  |   #endif | ||||||
|  |   #if defined(__USAT) | ||||||
|  |     #undef __USAT | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #include "iccarm_builtin.h" | ||||||
|  | 
 | ||||||
|  |   #define __enable_irq        __iar_builtin_enable_interrupt | ||||||
|  |   #define __disable_irq       __iar_builtin_disable_interrupt | ||||||
|  |   #define __enable_fault_irq    __iar_builtin_enable_fiq | ||||||
|  |   #define __disable_fault_irq   __iar_builtin_disable_fiq | ||||||
|  |   #define __arm_rsr           __iar_builtin_rsr | ||||||
|  |   #define __arm_wsr           __iar_builtin_wsr | ||||||
|  | 
 | ||||||
|  |   #if __FPU_PRESENT | ||||||
|  |     #define __get_FPSCR()             (__arm_rsr("FPSCR")) | ||||||
|  |   #else | ||||||
|  |     #define __get_FPSCR()             ( 0 ) | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #define __set_FPSCR(VALUE)          (__arm_wsr("FPSCR", VALUE)) | ||||||
|  | 
 | ||||||
|  |   #define __get_CPSR()                (__arm_rsr("CPSR")) | ||||||
|  |   #define __get_mode()                (__get_CPSR() & 0x1FU) | ||||||
|  | 
 | ||||||
|  |   #define __set_CPSR(VALUE)           (__arm_wsr("CPSR", (VALUE))) | ||||||
|  |   #define __set_mode(VALUE)           (__arm_wsr("CPSR_c", (VALUE))) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   #define __get_FPEXC()       (__arm_rsr("FPEXC")) | ||||||
|  |   #define __set_FPEXC(VALUE)    (__arm_wsr("FPEXC", VALUE)) | ||||||
|  | 
 | ||||||
|  |   #define __get_CP(cp, op1, RT, CRn, CRm, op2) \ | ||||||
|  |     ((RT) = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2)) | ||||||
|  | 
 | ||||||
|  |   #define __set_CP(cp, op1, RT, CRn, CRm, op2) \ | ||||||
|  |     (__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, (RT))) | ||||||
|  | 
 | ||||||
|  |   #define __get_CP64(cp, op1, Rt, CRm) \ | ||||||
|  |     __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : "=r" (Rt) : : "memory" ) | ||||||
|  | 
 | ||||||
|  |   #define __set_CP64(cp, op1, Rt, CRm) \ | ||||||
|  |     __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : : "r" (Rt) : "memory" ) | ||||||
|  | 
 | ||||||
|  |   #include "cmsis_cp15.h" | ||||||
|  | 
 | ||||||
|  |   #define __NOP     __iar_builtin_no_operation | ||||||
|  | 
 | ||||||
|  |   #define __CLZ     __iar_builtin_CLZ | ||||||
|  |   #define __CLREX   __iar_builtin_CLREX | ||||||
|  | 
 | ||||||
|  |   #define __DMB     __iar_builtin_DMB | ||||||
|  |   #define __DSB     __iar_builtin_DSB | ||||||
|  |   #define __ISB     __iar_builtin_ISB | ||||||
|  | 
 | ||||||
|  |   #define __LDREXB  __iar_builtin_LDREXB | ||||||
|  |   #define __LDREXH  __iar_builtin_LDREXH | ||||||
|  |   #define __LDREXW  __iar_builtin_LDREX | ||||||
|  | 
 | ||||||
|  |   #define __RBIT    __iar_builtin_RBIT | ||||||
|  |   #define __REV     __iar_builtin_REV | ||||||
|  |   #define __REV16   __iar_builtin_REV16 | ||||||
|  | 
 | ||||||
|  |   __IAR_FT int16_t __REVSH(int16_t val) | ||||||
|  |   { | ||||||
|  |     return (int16_t) __iar_builtin_REVSH(val); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #define __ROR     __iar_builtin_ROR | ||||||
|  |   #define __RRX     __iar_builtin_RRX | ||||||
|  | 
 | ||||||
|  |   #define __SEV     __iar_builtin_SEV | ||||||
|  | 
 | ||||||
|  |   #define __SSAT    __iar_builtin_SSAT | ||||||
|  | 
 | ||||||
|  |   #define __STREXB  __iar_builtin_STREXB | ||||||
|  |   #define __STREXH  __iar_builtin_STREXH | ||||||
|  |   #define __STREXW  __iar_builtin_STREX | ||||||
|  | 
 | ||||||
|  |   #define __USAT    __iar_builtin_USAT | ||||||
|  | 
 | ||||||
|  |   #define __WFE     __iar_builtin_WFE | ||||||
|  |   #define __WFI     __iar_builtin_WFI | ||||||
|  | 
 | ||||||
|  |   #define __SADD8   __iar_builtin_SADD8 | ||||||
|  |   #define __QADD8   __iar_builtin_QADD8 | ||||||
|  |   #define __SHADD8  __iar_builtin_SHADD8 | ||||||
|  |   #define __UADD8   __iar_builtin_UADD8 | ||||||
|  |   #define __UQADD8  __iar_builtin_UQADD8 | ||||||
|  |   #define __UHADD8  __iar_builtin_UHADD8 | ||||||
|  |   #define __SSUB8   __iar_builtin_SSUB8 | ||||||
|  |   #define __QSUB8   __iar_builtin_QSUB8 | ||||||
|  |   #define __SHSUB8  __iar_builtin_SHSUB8 | ||||||
|  |   #define __USUB8   __iar_builtin_USUB8 | ||||||
|  |   #define __UQSUB8  __iar_builtin_UQSUB8 | ||||||
|  |   #define __UHSUB8  __iar_builtin_UHSUB8 | ||||||
|  |   #define __SADD16  __iar_builtin_SADD16 | ||||||
|  |   #define __QADD16  __iar_builtin_QADD16 | ||||||
|  |   #define __SHADD16 __iar_builtin_SHADD16 | ||||||
|  |   #define __UADD16  __iar_builtin_UADD16 | ||||||
|  |   #define __UQADD16 __iar_builtin_UQADD16 | ||||||
|  |   #define __UHADD16 __iar_builtin_UHADD16 | ||||||
|  |   #define __SSUB16  __iar_builtin_SSUB16 | ||||||
|  |   #define __QSUB16  __iar_builtin_QSUB16 | ||||||
|  |   #define __SHSUB16 __iar_builtin_SHSUB16 | ||||||
|  |   #define __USUB16  __iar_builtin_USUB16 | ||||||
|  |   #define __UQSUB16 __iar_builtin_UQSUB16 | ||||||
|  |   #define __UHSUB16 __iar_builtin_UHSUB16 | ||||||
|  |   #define __SASX    __iar_builtin_SASX | ||||||
|  |   #define __QASX    __iar_builtin_QASX | ||||||
|  |   #define __SHASX   __iar_builtin_SHASX | ||||||
|  |   #define __UASX    __iar_builtin_UASX | ||||||
|  |   #define __UQASX   __iar_builtin_UQASX | ||||||
|  |   #define __UHASX   __iar_builtin_UHASX | ||||||
|  |   #define __SSAX    __iar_builtin_SSAX | ||||||
|  |   #define __QSAX    __iar_builtin_QSAX | ||||||
|  |   #define __SHSAX   __iar_builtin_SHSAX | ||||||
|  |   #define __USAX    __iar_builtin_USAX | ||||||
|  |   #define __UQSAX   __iar_builtin_UQSAX | ||||||
|  |   #define __UHSAX   __iar_builtin_UHSAX | ||||||
|  |   #define __USAD8   __iar_builtin_USAD8 | ||||||
|  |   #define __USADA8  __iar_builtin_USADA8 | ||||||
|  |   #define __SSAT16  __iar_builtin_SSAT16 | ||||||
|  |   #define __USAT16  __iar_builtin_USAT16 | ||||||
|  |   #define __UXTB16  __iar_builtin_UXTB16 | ||||||
|  |   #define __UXTAB16 __iar_builtin_UXTAB16 | ||||||
|  |   #define __SXTB16  __iar_builtin_SXTB16 | ||||||
|  |   #define __SXTAB16 __iar_builtin_SXTAB16 | ||||||
|  |   #define __SMUAD   __iar_builtin_SMUAD | ||||||
|  |   #define __SMUADX  __iar_builtin_SMUADX | ||||||
|  |   #define __SMMLA   __iar_builtin_SMMLA | ||||||
|  |   #define __SMLAD   __iar_builtin_SMLAD | ||||||
|  |   #define __SMLADX  __iar_builtin_SMLADX | ||||||
|  |   #define __SMLALD  __iar_builtin_SMLALD | ||||||
|  |   #define __SMLALDX __iar_builtin_SMLALDX | ||||||
|  |   #define __SMUSD   __iar_builtin_SMUSD | ||||||
|  |   #define __SMUSDX  __iar_builtin_SMUSDX | ||||||
|  |   #define __SMLSD   __iar_builtin_SMLSD | ||||||
|  |   #define __SMLSDX  __iar_builtin_SMLSDX | ||||||
|  |   #define __SMLSLD  __iar_builtin_SMLSLD | ||||||
|  |   #define __SMLSLDX __iar_builtin_SMLSLDX | ||||||
|  |   #define __SEL     __iar_builtin_SEL | ||||||
|  |   #define __QADD    __iar_builtin_QADD | ||||||
|  |   #define __QSUB    __iar_builtin_QSUB | ||||||
|  |   #define __PKHBT   __iar_builtin_PKHBT | ||||||
|  |   #define __PKHTB   __iar_builtin_PKHTB | ||||||
|  | 
 | ||||||
|  | #else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ | ||||||
|  | 
 | ||||||
|  |   #if !__FPU_PRESENT | ||||||
|  |   #define __get_FPSCR __cmsis_iar_get_FPSR_not_active | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #ifdef __INTRINSICS_INCLUDED | ||||||
|  |   #error intrinsics.h is already included previously! | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #include <intrinsics.h> | ||||||
|  | 
 | ||||||
|  |   #if !__FPU_PRESENT | ||||||
|  |   #define __get_FPSCR() (0) | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   #pragma diag_suppress=Pe940 | ||||||
|  |   #pragma diag_suppress=Pe177 | ||||||
|  | 
 | ||||||
|  |   #define __enable_irq        __enable_interrupt | ||||||
|  |   #define __disable_irq       __disable_interrupt | ||||||
|  |   #define __enable_fault_irq    __enable_fiq | ||||||
|  |   #define __disable_fault_irq   __disable_fiq | ||||||
|  |   #define __NOP               __no_operation | ||||||
|  | 
 | ||||||
|  |   #define __get_xPSR          __get_PSR | ||||||
|  | 
 | ||||||
|  |   __IAR_FT void __set_mode(uint32_t mode) | ||||||
|  |   { | ||||||
|  |     __ASM volatile("MSR  cpsr_c, %0" : : "r" (mode) : "memory"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) | ||||||
|  |   { | ||||||
|  |     return __LDREX((unsigned long *)ptr); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) | ||||||
|  |   { | ||||||
|  |     return __STREX(value, (unsigned long *)ptr); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __RRX(uint32_t value) | ||||||
|  |   { | ||||||
|  |     uint32_t result; | ||||||
|  |     __ASM("RRX      %0, %1" : "=r"(result) : "r" (value) : "cc"); | ||||||
|  |     return(result); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) | ||||||
|  |   { | ||||||
|  |     return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT uint32_t __get_FPEXC(void) | ||||||
|  |   { | ||||||
|  |   #if (__FPU_PRESENT == 1) | ||||||
|  |     uint32_t result; | ||||||
|  |     __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); | ||||||
|  |     return(result); | ||||||
|  |   #else | ||||||
|  |     return(0); | ||||||
|  |   #endif | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   __IAR_FT void __set_FPEXC(uint32_t fpexc) | ||||||
|  |   { | ||||||
|  |   #if (__FPU_PRESENT == 1) | ||||||
|  |     __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); | ||||||
|  |   #endif | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   #define __get_CP(cp, op1, Rt, CRn, CRm, op2) \ | ||||||
|  |     __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) | ||||||
|  |   #define __set_CP(cp, op1, Rt, CRn, CRm, op2) \ | ||||||
|  |     __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) | ||||||
|  |   #define __get_CP64(cp, op1, Rt, CRm) \ | ||||||
|  |     __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : "=r" (Rt) : : "memory" ) | ||||||
|  |   #define __set_CP64(cp, op1, Rt, CRm) \ | ||||||
|  |     __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : : "r" (Rt) : "memory" ) | ||||||
|  | 
 | ||||||
|  |   #include "cmsis_cp15.h" | ||||||
|  | 
 | ||||||
|  | #endif   /* __ICCARM_INTRINSICS_VERSION__ == 2 */ | ||||||
|  | 
 | ||||||
|  | #define __BKPT(value)    __asm volatile ("BKPT     %0" : : "i"(value)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | __IAR_FT uint32_t __get_SP_usr(void) | ||||||
|  | { | ||||||
|  |   uint32_t cpsr; | ||||||
|  |   uint32_t result; | ||||||
|  |   __ASM volatile( | ||||||
|  |     "MRS     %0, cpsr   \n" | ||||||
|  |     "CPS     #0x1F      \n" // no effect in USR mode
 | ||||||
|  |     "MOV     %1, sp     \n" | ||||||
|  |     "MSR     cpsr_c, %2 \n" // no effect in USR mode
 | ||||||
|  |     "ISB" :  "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory" | ||||||
|  |    ); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __IAR_FT void __set_SP_usr(uint32_t topOfProcStack) | ||||||
|  | { | ||||||
|  |   uint32_t cpsr; | ||||||
|  |   __ASM volatile( | ||||||
|  |     "MRS     %0, cpsr   \n" | ||||||
|  |     "CPS     #0x1F      \n" // no effect in USR mode
 | ||||||
|  |     "MOV     sp, %1     \n" | ||||||
|  |     "MSR     cpsr_c, %2 \n" // no effect in USR mode
 | ||||||
|  |     "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory" | ||||||
|  |    ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define __get_mode()                (__get_CPSR() & 0x1FU) | ||||||
|  | 
 | ||||||
|  | __STATIC_INLINE | ||||||
|  | void __FPU_Enable(void) | ||||||
|  | { | ||||||
|  |   __ASM volatile( | ||||||
|  |     //Permit access to VFP/NEON, registers by modifying CPACR
 | ||||||
|  |     "        MRC     p15,0,R1,c1,c0,2  \n" | ||||||
|  |     "        ORR     R1,R1,#0x00F00000 \n" | ||||||
|  |     "        MCR     p15,0,R1,c1,c0,2  \n" | ||||||
|  | 
 | ||||||
|  |     //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
 | ||||||
|  |     "        ISB                       \n" | ||||||
|  | 
 | ||||||
|  |     //Enable VFP/NEON
 | ||||||
|  |     "        VMRS    R1,FPEXC          \n" | ||||||
|  |     "        ORR     R1,R1,#0x40000000 \n" | ||||||
|  |     "        VMSR    FPEXC,R1          \n" | ||||||
|  | 
 | ||||||
|  |     //Initialise VFP/NEON registers to 0
 | ||||||
|  |     "        MOV     R2,#0             \n" | ||||||
|  | 
 | ||||||
|  |     //Initialise D16 registers to 0
 | ||||||
|  |     "        VMOV    D0, R2,R2         \n" | ||||||
|  |     "        VMOV    D1, R2,R2         \n" | ||||||
|  |     "        VMOV    D2, R2,R2         \n" | ||||||
|  |     "        VMOV    D3, R2,R2         \n" | ||||||
|  |     "        VMOV    D4, R2,R2         \n" | ||||||
|  |     "        VMOV    D5, R2,R2         \n" | ||||||
|  |     "        VMOV    D6, R2,R2         \n" | ||||||
|  |     "        VMOV    D7, R2,R2         \n" | ||||||
|  |     "        VMOV    D8, R2,R2         \n" | ||||||
|  |     "        VMOV    D9, R2,R2         \n" | ||||||
|  |     "        VMOV    D10,R2,R2         \n" | ||||||
|  |     "        VMOV    D11,R2,R2         \n" | ||||||
|  |     "        VMOV    D12,R2,R2         \n" | ||||||
|  |     "        VMOV    D13,R2,R2         \n" | ||||||
|  |     "        VMOV    D14,R2,R2         \n" | ||||||
|  |     "        VMOV    D15,R2,R2         \n" | ||||||
|  | 
 | ||||||
|  | #ifdef __ARM_ADVANCED_SIMD__ | ||||||
|  |     //Initialise D32 registers to 0
 | ||||||
|  |     "        VMOV    D16,R2,R2         \n" | ||||||
|  |     "        VMOV    D17,R2,R2         \n" | ||||||
|  |     "        VMOV    D18,R2,R2         \n" | ||||||
|  |     "        VMOV    D19,R2,R2         \n" | ||||||
|  |     "        VMOV    D20,R2,R2         \n" | ||||||
|  |     "        VMOV    D21,R2,R2         \n" | ||||||
|  |     "        VMOV    D22,R2,R2         \n" | ||||||
|  |     "        VMOV    D23,R2,R2         \n" | ||||||
|  |     "        VMOV    D24,R2,R2         \n" | ||||||
|  |     "        VMOV    D25,R2,R2         \n" | ||||||
|  |     "        VMOV    D26,R2,R2         \n" | ||||||
|  |     "        VMOV    D27,R2,R2         \n" | ||||||
|  |     "        VMOV    D28,R2,R2         \n" | ||||||
|  |     "        VMOV    D29,R2,R2         \n" | ||||||
|  |     "        VMOV    D30,R2,R2         \n" | ||||||
|  |     "        VMOV    D31,R2,R2         \n" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     //Initialise FPSCR to a known state
 | ||||||
|  |     "        VMRS    R2,FPSCR          \n" | ||||||
|  |     "        MOV32   R3,#0x00086060    \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
 | ||||||
|  |     "        AND     R2,R2,R3          \n" | ||||||
|  |     "        VMSR    FPSCR,R2          \n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #undef __IAR_FT | ||||||
|  | #undef __ICCARM_V8 | ||||||
|  | 
 | ||||||
|  | #pragma diag_default=Pe940 | ||||||
|  | #pragma diag_default=Pe177 | ||||||
|  | 
 | ||||||
|  | #endif /* __CMSIS_ICCARM_H__ */ | ||||||
							
								
								
									
										2614
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/core_ca.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2614
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/core_ca.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										186
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/irq_ctrl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								target_f2/Drivers/CMSIS/Core_A/Include/irq_ctrl.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,186 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     irq_ctrl.h | ||||||
|  |  * @brief    Interrupt Controller API header file | ||||||
|  |  * @version  V1.0.0 | ||||||
|  |  * @date     23. June 2017 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2017 ARM Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if   defined ( __ICCARM__ ) | ||||||
|  |   #pragma system_include         /* treat file as system include file for MISRA check */ | ||||||
|  | #elif defined (__clang__) | ||||||
|  |   #pragma clang system_header   /* treat file as system include file */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef IRQ_CTRL_H_ | ||||||
|  | #define IRQ_CTRL_H_ | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | #ifndef IRQHANDLER_T | ||||||
|  | #define IRQHANDLER_T | ||||||
|  | /// Interrupt handler data type
 | ||||||
|  | typedef void (*IRQHandler_t) (void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef IRQN_ID_T | ||||||
|  | #define IRQN_ID_T | ||||||
|  | /// Interrupt ID number data type
 | ||||||
|  | typedef int32_t IRQn_ID_t; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* Interrupt mode bit-masks */ | ||||||
|  | #define IRQ_MODE_TRIG_Pos           (0U) | ||||||
|  | #define IRQ_MODE_TRIG_Msk           (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) | ||||||
|  | #define IRQ_MODE_TRIG_LEVEL         (0x00UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: level triggered interrupt
 | ||||||
|  | #define IRQ_MODE_TRIG_LEVEL_LOW     (0x01UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: low level triggered interrupt
 | ||||||
|  | #define IRQ_MODE_TRIG_LEVEL_HIGH    (0x02UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: high level triggered interrupt
 | ||||||
|  | #define IRQ_MODE_TRIG_EDGE          (0x04UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: edge triggered interrupt
 | ||||||
|  | #define IRQ_MODE_TRIG_EDGE_RISING   (0x05UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising edge triggered interrupt
 | ||||||
|  | #define IRQ_MODE_TRIG_EDGE_FALLING  (0x06UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: falling edge triggered interrupt
 | ||||||
|  | #define IRQ_MODE_TRIG_EDGE_BOTH     (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising and falling edge triggered interrupt
 | ||||||
|  | 
 | ||||||
|  | #define IRQ_MODE_TYPE_Pos           (3U) | ||||||
|  | #define IRQ_MODE_TYPE_Msk           (0x01UL << IRQ_MODE_TYPE_Pos) | ||||||
|  | #define IRQ_MODE_TYPE_IRQ           (0x00UL << IRQ_MODE_TYPE_Pos)     ///< Type: interrupt source triggers CPU IRQ line
 | ||||||
|  | #define IRQ_MODE_TYPE_FIQ           (0x01UL << IRQ_MODE_TYPE_Pos)     ///< Type: interrupt source triggers CPU FIQ line
 | ||||||
|  | 
 | ||||||
|  | #define IRQ_MODE_DOMAIN_Pos         (4U) | ||||||
|  | #define IRQ_MODE_DOMAIN_Msk         (0x01UL << IRQ_MODE_DOMAIN_Pos) | ||||||
|  | #define IRQ_MODE_DOMAIN_NONSECURE   (0x00UL << IRQ_MODE_DOMAIN_Pos)   ///< Domain: interrupt is targeting non-secure domain
 | ||||||
|  | #define IRQ_MODE_DOMAIN_SECURE      (0x01UL << IRQ_MODE_DOMAIN_Pos)   ///< Domain: interrupt is targeting secure domain
 | ||||||
|  | 
 | ||||||
|  | #define IRQ_MODE_CPU_Pos            (5U) | ||||||
|  | #define IRQ_MODE_CPU_Msk            (0xFFUL << IRQ_MODE_CPU_Pos) | ||||||
|  | #define IRQ_MODE_CPU_ALL            (0x00UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets all CPUs
 | ||||||
|  | #define IRQ_MODE_CPU_0              (0x01UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets CPU 0
 | ||||||
|  | #define IRQ_MODE_CPU_1              (0x02UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets CPU 1
 | ||||||
|  | #define IRQ_MODE_CPU_2              (0x04UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets CPU 2
 | ||||||
|  | #define IRQ_MODE_CPU_3              (0x08UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets CPU 3
 | ||||||
|  | #define IRQ_MODE_CPU_4              (0x10UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets CPU 4
 | ||||||
|  | #define IRQ_MODE_CPU_5              (0x20UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets CPU 5
 | ||||||
|  | #define IRQ_MODE_CPU_6              (0x40UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets CPU 6
 | ||||||
|  | #define IRQ_MODE_CPU_7              (0x80UL << IRQ_MODE_CPU_Pos)      ///< CPU: interrupt targets CPU 7
 | ||||||
|  | 
 | ||||||
|  | #define IRQ_MODE_ERROR              (0x80000000UL)                    ///< Bit indicating mode value error
 | ||||||
|  | 
 | ||||||
|  | /* Interrupt priority bit-masks */ | ||||||
|  | #define IRQ_PRIORITY_Msk            (0x0000FFFFUL)                    ///< Interrupt priority value bit-mask
 | ||||||
|  | #define IRQ_PRIORITY_ERROR          (0x80000000UL)                    ///< Bit indicating priority value error
 | ||||||
|  | 
 | ||||||
|  | /// Initialize interrupt controller.
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_Initialize (void); | ||||||
|  | 
 | ||||||
|  | /// Register interrupt handler.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \param[in]     handler       interrupt handler function address
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler); | ||||||
|  | 
 | ||||||
|  | /// Get the registered interrupt handler.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return registered interrupt handler function address.
 | ||||||
|  | IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Enable interrupt.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_Enable (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Disable interrupt.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_Disable (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Get interrupt enable state.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return 0 - interrupt is disabled, 1 - interrupt is enabled.
 | ||||||
|  | uint32_t IRQ_GetEnableState (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Configure interrupt request mode.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \param[in]     mode          mode configuration
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode); | ||||||
|  | 
 | ||||||
|  | /// Get interrupt mode configuration.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return current interrupt mode configuration with optional IRQ_MODE_ERROR bit set.
 | ||||||
|  | uint32_t IRQ_GetMode (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Get ID number of current interrupt request (IRQ).
 | ||||||
|  | /// \return interrupt ID number.
 | ||||||
|  | IRQn_ID_t IRQ_GetActiveIRQ (void); | ||||||
|  | 
 | ||||||
|  | /// Get ID number of current fast interrupt request (FIQ).
 | ||||||
|  | /// \return interrupt ID number.
 | ||||||
|  | IRQn_ID_t IRQ_GetActiveFIQ (void); | ||||||
|  | 
 | ||||||
|  | /// Signal end of interrupt processing.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Set interrupt pending flag.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_SetPending (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Get interrupt pending flag.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return 0 - interrupt is not pending, 1 - interrupt is pending.
 | ||||||
|  | uint32_t IRQ_GetPending (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Clear interrupt pending flag.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_ClearPending (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Set interrupt priority value.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \param[in]     priority      interrupt priority value
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority); | ||||||
|  | 
 | ||||||
|  | /// Get interrupt priority.
 | ||||||
|  | /// \param[in]     irqn          interrupt ID number
 | ||||||
|  | /// \return current interrupt priority value with optional IRQ_PRIORITY_ERROR bit set.
 | ||||||
|  | uint32_t IRQ_GetPriority (IRQn_ID_t irqn); | ||||||
|  | 
 | ||||||
|  | /// Set priority masking threshold.
 | ||||||
|  | /// \param[in]     priority      priority masking threshold value
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_SetPriorityMask (uint32_t priority); | ||||||
|  | 
 | ||||||
|  | /// Get priority masking threshold
 | ||||||
|  | /// \return current priority masking threshold value with optional IRQ_PRIORITY_ERROR bit set.
 | ||||||
|  | uint32_t IRQ_GetPriorityMask (void); | ||||||
|  | 
 | ||||||
|  | /// Set priority grouping field split point
 | ||||||
|  | /// \param[in]     bits          number of MSB bits included in the group priority field comparison
 | ||||||
|  | /// \return 0 on success, -1 on error.
 | ||||||
|  | int32_t IRQ_SetPriorityGroupBits (uint32_t bits); | ||||||
|  | 
 | ||||||
|  | /// Get priority grouping field split point
 | ||||||
|  | /// \return current number of MSB bits included in the group priority field comparison with
 | ||||||
|  | ///         optional IRQ_PRIORITY_ERROR bit set.
 | ||||||
|  | uint32_t IRQ_GetPriorityGroupBits (void); | ||||||
|  | 
 | ||||||
|  | #endif  // IRQ_CTRL_H_
 | ||||||
							
								
								
									
										410
									
								
								target_f2/Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										410
									
								
								target_f2/Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,410 @@ | |||||||
|  | /**************************************************************************//**
 | ||||||
|  |  * @file     irq_ctrl_gic.c | ||||||
|  |  * @brief    Interrupt controller handling implementation for GIC | ||||||
|  |  * @version  V1.0.1 | ||||||
|  |  * @date     9. April 2018 | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2017 ARM Limited. All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||||||
|  |  * not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <stddef.h> | ||||||
|  | 
 | ||||||
|  | #include "RTE_Components.h" | ||||||
|  | #include CMSIS_device_header | ||||||
|  | 
 | ||||||
|  | #include "irq_ctrl.h" | ||||||
|  | 
 | ||||||
|  | #if defined(__GIC_PRESENT) && (__GIC_PRESENT == 1U) | ||||||
|  | 
 | ||||||
|  | /// Number of implemented interrupt lines
 | ||||||
|  | #ifndef IRQ_GIC_LINE_COUNT | ||||||
|  | #define IRQ_GIC_LINE_COUNT      (1020U) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U }; | ||||||
|  | static uint32_t     IRQ_ID0; | ||||||
|  | 
 | ||||||
|  | /// Initialize interrupt controller.
 | ||||||
|  | __WEAK int32_t IRQ_Initialize (void) { | ||||||
|  |   uint32_t i; | ||||||
|  | 
 | ||||||
|  |   for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) { | ||||||
|  |     IRQTable[i] = (IRQHandler_t)NULL; | ||||||
|  |   } | ||||||
|  |   GIC_Enable(); | ||||||
|  |   return (0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Register interrupt handler.
 | ||||||
|  | __WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) { | ||||||
|  |   int32_t status; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     IRQTable[irqn] = handler; | ||||||
|  |     status =  0; | ||||||
|  |   } else { | ||||||
|  |     status = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Get the registered interrupt handler.
 | ||||||
|  | __WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) { | ||||||
|  |   IRQHandler_t h; | ||||||
|  | 
 | ||||||
|  |   // Ignore CPUID field (software generated interrupts)
 | ||||||
|  |   irqn &= 0x3FFU; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     h = IRQTable[irqn]; | ||||||
|  |   } else { | ||||||
|  |     h = (IRQHandler_t)0; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (h); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Enable interrupt.
 | ||||||
|  | __WEAK int32_t IRQ_Enable (IRQn_ID_t irqn) { | ||||||
|  |   int32_t status; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     GIC_EnableIRQ ((IRQn_Type)irqn); | ||||||
|  |     status = 0; | ||||||
|  |   } else { | ||||||
|  |     status = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Disable interrupt.
 | ||||||
|  | __WEAK int32_t IRQ_Disable (IRQn_ID_t irqn) { | ||||||
|  |   int32_t status; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     GIC_DisableIRQ ((IRQn_Type)irqn); | ||||||
|  |     status = 0; | ||||||
|  |   } else { | ||||||
|  |     status = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Get interrupt enable state.
 | ||||||
|  | __WEAK uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) { | ||||||
|  |   uint32_t enable; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     enable = GIC_GetEnableIRQ((IRQn_Type)irqn); | ||||||
|  |   } else { | ||||||
|  |     enable = 0U; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (enable); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Configure interrupt request mode.
 | ||||||
|  | __WEAK int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) { | ||||||
|  |   uint32_t val; | ||||||
|  |   uint8_t cfg; | ||||||
|  |   uint8_t secure; | ||||||
|  |   uint8_t cpu; | ||||||
|  |   int32_t status = 0; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     // Check triggering mode
 | ||||||
|  |     val = (mode & IRQ_MODE_TRIG_Msk); | ||||||
|  | 
 | ||||||
|  |     if (val == IRQ_MODE_TRIG_LEVEL) { | ||||||
|  |       cfg = 0x00U; | ||||||
|  |     } else if (val == IRQ_MODE_TRIG_EDGE) { | ||||||
|  |       cfg = 0x02U; | ||||||
|  |     } else { | ||||||
|  |       cfg = 0x00U; | ||||||
|  |       status = -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Check interrupt type
 | ||||||
|  |     val = mode & IRQ_MODE_TYPE_Msk; | ||||||
|  | 
 | ||||||
|  |     if (val != IRQ_MODE_TYPE_IRQ) { | ||||||
|  |       status = -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Check interrupt domain
 | ||||||
|  |     val = mode & IRQ_MODE_DOMAIN_Msk; | ||||||
|  | 
 | ||||||
|  |     if (val == IRQ_MODE_DOMAIN_NONSECURE) { | ||||||
|  |       secure = 0U; | ||||||
|  |     } else { | ||||||
|  |       // Check security extensions support
 | ||||||
|  |       val = GIC_DistributorInfo() & (1UL << 10U); | ||||||
|  | 
 | ||||||
|  |       if (val != 0U) { | ||||||
|  |         // Security extensions are supported
 | ||||||
|  |         secure = 1U; | ||||||
|  |       } else { | ||||||
|  |         secure = 0U; | ||||||
|  |         status = -1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Check interrupt CPU targets
 | ||||||
|  |     val = mode & IRQ_MODE_CPU_Msk; | ||||||
|  | 
 | ||||||
|  |     if (val == IRQ_MODE_CPU_ALL) { | ||||||
|  |       cpu = 0xFFU; | ||||||
|  |     } else { | ||||||
|  |       cpu = val >> IRQ_MODE_CPU_Pos; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Apply configuration if no mode error
 | ||||||
|  |     if (status == 0) { | ||||||
|  |       GIC_SetConfiguration((IRQn_Type)irqn, cfg); | ||||||
|  |       GIC_SetTarget       ((IRQn_Type)irqn, cpu); | ||||||
|  | 
 | ||||||
|  |       if (secure != 0U) { | ||||||
|  |         GIC_SetGroup ((IRQn_Type)irqn, secure); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Get interrupt mode configuration.
 | ||||||
|  | __WEAK uint32_t IRQ_GetMode (IRQn_ID_t irqn) { | ||||||
|  |   uint32_t mode; | ||||||
|  |   uint32_t val; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     mode = IRQ_MODE_TYPE_IRQ; | ||||||
|  | 
 | ||||||
|  |     // Get trigger mode
 | ||||||
|  |     val = GIC_GetConfiguration((IRQn_Type)irqn); | ||||||
|  | 
 | ||||||
|  |     if ((val & 2U) != 0U) { | ||||||
|  |       // Corresponding interrupt is edge triggered
 | ||||||
|  |       mode |= IRQ_MODE_TRIG_EDGE; | ||||||
|  |     } else { | ||||||
|  |       // Corresponding interrupt is level triggered
 | ||||||
|  |       mode |= IRQ_MODE_TRIG_LEVEL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Get interrupt CPU targets
 | ||||||
|  |     mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos; | ||||||
|  | 
 | ||||||
|  |   } else { | ||||||
|  |     mode = IRQ_MODE_ERROR; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (mode); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Get ID number of current interrupt request (IRQ).
 | ||||||
|  | __WEAK IRQn_ID_t IRQ_GetActiveIRQ (void) { | ||||||
|  |   IRQn_ID_t irqn; | ||||||
|  |   uint32_t prio; | ||||||
|  | 
 | ||||||
|  |   /* Dummy read to avoid GIC 390 errata 801120 */ | ||||||
|  |   GIC_GetHighPendingIRQ(); | ||||||
|  | 
 | ||||||
|  |   irqn = GIC_AcknowledgePending(); | ||||||
|  | 
 | ||||||
|  |   __DSB(); | ||||||
|  | 
 | ||||||
|  |   /* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014)  */ | ||||||
|  |   /* The following workaround code is for a single-core system.  It would be       */ | ||||||
|  |   /* different in a multi-core system.                                             */ | ||||||
|  |   /* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */ | ||||||
|  |   /* so unlock it, otherwise service the interrupt as normal.                      */ | ||||||
|  |   /* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2  */ | ||||||
|  |   /* so will not occur here.                                                       */ | ||||||
|  | 
 | ||||||
|  |   if ((irqn == 0) || (irqn >= 0x3FE)) { | ||||||
|  |     /* Unlock the CPU interface with a dummy write to Interrupt Priority Register */ | ||||||
|  |     prio = GIC_GetPriority((IRQn_Type)0); | ||||||
|  |     GIC_SetPriority ((IRQn_Type)0, prio); | ||||||
|  | 
 | ||||||
|  |     __DSB(); | ||||||
|  | 
 | ||||||
|  |     if ((irqn == 0U) && ((GIC_GetIRQStatus ((IRQn_Type)irqn) & 1U) != 0U) && (IRQ_ID0 == 0U)) { | ||||||
|  |       /* If the ID is 0, is active and has not been seen before */ | ||||||
|  |       IRQ_ID0 = 1U; | ||||||
|  |     } | ||||||
|  |     /* End of Workaround GIC 390 errata 733075 */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (irqn); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Get ID number of current fast interrupt request (FIQ).
 | ||||||
|  | __WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) { | ||||||
|  |   return ((IRQn_ID_t)-1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Signal end of interrupt processing.
 | ||||||
|  | __WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) { | ||||||
|  |   int32_t status; | ||||||
|  |   IRQn_Type irq = (IRQn_Type)irqn; | ||||||
|  | 
 | ||||||
|  |   irqn &= 0x3FFU; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     GIC_EndInterrupt (irq); | ||||||
|  | 
 | ||||||
|  |     if (irqn == 0) { | ||||||
|  |       IRQ_ID0 = 0U; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     status = 0; | ||||||
|  |   } else { | ||||||
|  |     status = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Set interrupt pending flag.
 | ||||||
|  | __WEAK int32_t IRQ_SetPending (IRQn_ID_t irqn) { | ||||||
|  |   int32_t status; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     GIC_SetPendingIRQ ((IRQn_Type)irqn); | ||||||
|  |     status = 0; | ||||||
|  |   } else { | ||||||
|  |     status = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Get interrupt pending flag.
 | ||||||
|  | __WEAK uint32_t IRQ_GetPending (IRQn_ID_t irqn) { | ||||||
|  |   uint32_t pending; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     pending = GIC_GetPendingIRQ ((IRQn_Type)irqn); | ||||||
|  |   } else { | ||||||
|  |     pending = 0U; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (pending & 1U); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Clear interrupt pending flag.
 | ||||||
|  | __WEAK int32_t IRQ_ClearPending (IRQn_ID_t irqn) { | ||||||
|  |   int32_t status; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     GIC_ClearPendingIRQ ((IRQn_Type)irqn); | ||||||
|  |     status = 0; | ||||||
|  |   } else { | ||||||
|  |     status = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Set interrupt priority value.
 | ||||||
|  | __WEAK int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) { | ||||||
|  |   int32_t status; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     GIC_SetPriority ((IRQn_Type)irqn, priority); | ||||||
|  |     status = 0; | ||||||
|  |   } else { | ||||||
|  |     status = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Get interrupt priority.
 | ||||||
|  | __WEAK uint32_t IRQ_GetPriority (IRQn_ID_t irqn) { | ||||||
|  |   uint32_t priority; | ||||||
|  | 
 | ||||||
|  |   if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { | ||||||
|  |     priority = GIC_GetPriority ((IRQn_Type)irqn); | ||||||
|  |   } else { | ||||||
|  |     priority = IRQ_PRIORITY_ERROR; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (priority); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Set priority masking threshold.
 | ||||||
|  | __WEAK int32_t IRQ_SetPriorityMask (uint32_t priority) { | ||||||
|  |   GIC_SetInterfacePriorityMask (priority); | ||||||
|  |   return (0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Get priority masking threshold
 | ||||||
|  | __WEAK uint32_t IRQ_GetPriorityMask (void) { | ||||||
|  |   return GIC_GetInterfacePriorityMask(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Set priority grouping field split point
 | ||||||
|  | __WEAK int32_t IRQ_SetPriorityGroupBits (uint32_t bits) { | ||||||
|  |   int32_t status; | ||||||
|  | 
 | ||||||
|  |   if (bits == IRQ_PRIORITY_Msk) { | ||||||
|  |     bits = 7U; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (bits < 8U) { | ||||||
|  |     GIC_SetBinaryPoint (7U - bits); | ||||||
|  |     status = 0; | ||||||
|  |   } else { | ||||||
|  |     status = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Get priority grouping field split point
 | ||||||
|  | __WEAK uint32_t IRQ_GetPriorityGroupBits (void) { | ||||||
|  |   uint32_t bp; | ||||||
|  | 
 | ||||||
|  |   bp = GIC_GetBinaryPoint() & 0x07U; | ||||||
|  | 
 | ||||||
|  |   return (7U - bp); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -0,0 +1,220 @@ | |||||||
|  | #ifndef _ARR_DESC_H_ | ||||||
|  | #define _ARR_DESC_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <string.h>             /* memset() */ | ||||||
|  | #include "../util/util.h"       /* CONCAT() */ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Type Definitions */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Array-descriptor struct. | ||||||
|  |  */ | ||||||
|  | typedef struct ARR_DESC_struct | ||||||
|  | { | ||||||
|  |     void *  data_ptr;                /* Pointer to the array contents. */ | ||||||
|  |     int32_t element_count;           /* Number of current elements. */ | ||||||
|  |     int32_t element_size;            /* Size of current elements in bytes. */ | ||||||
|  |     int32_t underlying_size;         /* Size of underlying array in bytes. */ | ||||||
|  | } ARR_DESC_t; | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Prefix of the array variable's name when creating an array and an array | ||||||
|  |  *  descriptor at the same time. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_ARR_PREFIX ARR_DESC_ARR_ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the array variable's name when creating an array and an array | ||||||
|  |  *  descriptor at the same time. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_ARR_NAME(name)                 \ | ||||||
|  |     CONCAT(ARR_DESC_ARR_PREFIX, name) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define an #ARR_DESC_t by itself. | ||||||
|  |  * | ||||||
|  |  *  @note The user must supply an array to store the data used by the | ||||||
|  |  *  #ARR_DESC_t. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_INTERNAL_DEFINE(name, data_ptr,                \ | ||||||
|  |                                  element_count, element_size)   \ | ||||||
|  |     ARR_DESC_t name = {                                         \ | ||||||
|  |         data_ptr,                                               \ | ||||||
|  |         element_count,                                          \ | ||||||
|  |         element_size,                                           \ | ||||||
|  |         element_count * element_size                            \ | ||||||
|  |     }                                                           \ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define both an array and an #ARR_DESC_t that describes it. | ||||||
|  |  * | ||||||
|  |  *  @note Use the #CURLY() macro for the content field; it provides the curly | ||||||
|  |  *  braces necessary for an array initialization. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_DEFINE(type, name, element_count, content)             \ | ||||||
|  |     type ARR_DESC_ARR_NAME(name)[element_count] = content;              \ | ||||||
|  |     ARR_DESC_INTERNAL_DEFINE(name,                                      \ | ||||||
|  |                              &ARR_DESC_ARR_NAME(name),                  \ | ||||||
|  |                              element_count,                             \ | ||||||
|  |                              sizeof(type)) /* Note the lacking semicolon */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Create a #ARR_DESC_t which refers to a subset of the data in another. | ||||||
|  |  * | ||||||
|  |  *  The new #ARR_DESC_t shares the same underlying array as the aliased | ||||||
|  |  *  #ARR_DESC_t, but only describes a subset of the originals values. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_DEFINE_SUBSET(name, original, element_cnt)         \ | ||||||
|  |     ARR_DESC_INTERNAL_DEFINE(name,                                  \ | ||||||
|  |                              &ARR_DESC_ARR_NAME(original),          \ | ||||||
|  |                              element_cnt,                           \ | ||||||
|  |                              sizeof(ARR_DESC_ARR_NAME(original)[0]) \ | ||||||
|  |         ) /* Note the lacking semicolon */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Creat an #ARR_DESC_t which points to the data in an existing array. | ||||||
|  |  * | ||||||
|  |  *  @param start_idx Offset in array_ptr of first element. | ||||||
|  |  *  @param element_cnt Number of elements to include in the #ARR_DESC_t. | ||||||
|  |  * | ||||||
|  |  *  @example | ||||||
|  |  * | ||||||
|  |  *  float my_floats[4] = {0.0f, 1.0f, 2.0f, 3.0f}; | ||||||
|  |  * | ||||||
|  |  *  ARR_DESC_DEFINE_USING_ARR(my_arr_desc, my_floats, 1, 3); | ||||||
|  |  * | ||||||
|  |  *  printf("Element 0: %f\n", ARR_DESC_ELT(float, 0, &my_arr_desc)); | ||||||
|  |  *  printf("Element 1: %f\n", ARR_DESC_ELT(float, 1, &my_arr_desc)); | ||||||
|  |  * | ||||||
|  |  *  Outputs: | ||||||
|  |  * | ||||||
|  |  *  Element 0: 1.000000 | ||||||
|  |  *  Element 1: 2.000000 | ||||||
|  |  * | ||||||
|  |  *  @warning There are no checks in place to catch invalid start indices; This | ||||||
|  |  *  is left to the user. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_DEFINE_USING_ARR(type, name, array_ptr, start_idx, element_cnt) \ | ||||||
|  |     ARR_DESC_INTERNAL_DEFINE(                                           \ | ||||||
|  |         name,                                                           \ | ||||||
|  |         (type *) (array_ptr + start_idx),                               \ | ||||||
|  |         element_cnt,                                                    \ | ||||||
|  |         sizeof(type)                                                    \ | ||||||
|  |         ) /* Note the lacking semicolon*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Declare an #ARR_DESC_t object. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_DECLARE(name)                              \ | ||||||
|  |     extern ARR_DESC_t name /* Note the lacking semicolon */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the number of bytes stored in the #ARR_DESC_t. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_BYTES(arr_desc_ptr)                                \ | ||||||
|  |     ((arr_desc_ptr)->element_count * (arr_desc_ptr)->element_size) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Set the contents of #ARR_DESC_t to value. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_MEMSET(arr_desc_ptr, value, bytes)     \ | ||||||
|  |     do                                                  \ | ||||||
|  |     {                                                   \ | ||||||
|  |         memset((arr_desc_ptr)->data_ptr,                \ | ||||||
|  |                value,                                   \ | ||||||
|  |                BOUND(0,                                 \ | ||||||
|  |                      (arr_desc_ptr)->underlying_size,   \ | ||||||
|  |                      bytes)                             \ | ||||||
|  |             );                                          \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Perform a memcpy of 'bytes' bytes from the source #ARR_DESC_t to the | ||||||
|  |  *  destination #ARR_DESC_t. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_MEMCPY(arr_desc_dest_ptr, arr_desc_src_ptr, bytes) \ | ||||||
|  |     do                                                              \ | ||||||
|  |     {                                                               \ | ||||||
|  |         memcpy((arr_desc_dest_ptr)->data_ptr,                       \ | ||||||
|  |                (arr_desc_src_ptr)->data_ptr,                        \ | ||||||
|  |                BOUND(0,                                             \ | ||||||
|  |                      (arr_desc_dest_ptr)->underlying_size,          \ | ||||||
|  |                      bytes));                                       \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to true if the source #ARR_DESC_t contents will fit into the | ||||||
|  |  *  destination #ARR_DESC_t and false otherwise. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_COPYABLE(arr_desc_dest_ptr, arr_desc_src_ptr)  \ | ||||||
|  |       (ARR_DESC_BYTES(arr_desc_src_ptr) <=                      \ | ||||||
|  |        (arr_desc_dest_ptr)->underlying_size) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Copy all the data from the source #ARR_DESC_t to the destination | ||||||
|  |  *  #ARR_DESC_t. | ||||||
|  |  * | ||||||
|  |  *  @note If the destination #ARR_DESC_t is too small to fit the source data the | ||||||
|  |  *  copy is aborted and nothing happens. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_COPY(arr_desc_dest_ptr, arr_desc_src_ptr)      \ | ||||||
|  |     do                                                          \ | ||||||
|  |     {                                                           \ | ||||||
|  |         if (ARR_DESC_COPYABLE(arr_desc_dest_ptr,                 \ | ||||||
|  |                              arr_desc_src_ptr))                 \ | ||||||
|  |         {                                                       \ | ||||||
|  |             ARR_DESC_MEMCPY(arr_desc_dest_ptr,                  \ | ||||||
|  |                             arr_desc_src_ptr,                   \ | ||||||
|  |                             ARR_DESC_BYTES(arr_desc_src_ptr));  \ | ||||||
|  |             /* Update the properties*/                          \ | ||||||
|  |             (arr_desc_dest_ptr)->element_count =                \ | ||||||
|  |                 (arr_desc_src_ptr)->element_count;              \ | ||||||
|  |             (arr_desc_dest_ptr)->element_size =                 \ | ||||||
|  |                 (arr_desc_src_ptr)->element_size;               \ | ||||||
|  |         }                                                       \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare the data in two #ARR_DESC_t structs for the specified number of | ||||||
|  |  *  bytes. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_MEMCMP(arr_desc_ptr_a, arr_desc_ptr_b, bytes)  \ | ||||||
|  |         memcmp((arr_desc_ptr_a)->data_ptr,                      \ | ||||||
|  |             (arr_desc_ptr_b)->data_ptr,                         \ | ||||||
|  |                bytes) /* Note the lacking semicolon */          \ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Zero out the contents of the #ARR_DESC_t. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_ZERO(arr_desc_ptr)             \ | ||||||
|  |         ARR_DESC_MEMSET(arr_desc_ptr,           \ | ||||||
|  |                         0,                      \ | ||||||
|  |                         (arr_desc_ptr)->underlying_size) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the data address in #ARR_DESC_t at offset. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_DATA_ADDR(type, arr_desc_ptr, offset)  \ | ||||||
|  |         ((void*)(((type *)                              \ | ||||||
|  |                   ((arr_desc_ptr)->data_ptr))           \ | ||||||
|  |                  + offset)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the element in #ARR_DESC_t with type at idx. | ||||||
|  |  */ | ||||||
|  | #define ARR_DESC_ELT(type, idx, arr_desc_ptr)           \ | ||||||
|  |         (*((type *) ARR_DESC_DATA_ADDR(type,            \ | ||||||
|  |                                        arr_desc_ptr,    \ | ||||||
|  |                                        idx))) | ||||||
|  | 
 | ||||||
|  | #endif /* _ARR_DESC_H_ */ | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | #ifndef _JTEST_H_ | ||||||
|  | #define _JTEST_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "jtest_fw.h" | ||||||
|  | #include "jtest_test.h" | ||||||
|  | #include "jtest_test_define.h" | ||||||
|  | #include "jtest_test_call.h" | ||||||
|  | #include "jtest_group.h" | ||||||
|  | #include "jtest_group_define.h" | ||||||
|  | #include "jtest_group_call.h" | ||||||
|  | #include "jtest_cycle.h" | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_H_ */ | ||||||
| @ -0,0 +1,65 @@ | |||||||
|  | #ifndef _JTEST_CYCLE_H_ | ||||||
|  | #define _JTEST_CYCLE_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "jtest_fw.h"           /* JTEST_DUMP_STRF() */ | ||||||
|  | #include "jtest_systick.h" | ||||||
|  | #include "jtest_util.h"         /* STR() */ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Declare Module Variables */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | extern const char * JTEST_CYCLE_STRF; | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Wrap the function call, fn_call, to count execution cycles and display the | ||||||
|  |  *  results. | ||||||
|  |  */ | ||||||
|  | /* skipp function name + param
 | ||||||
|  | #define JTEST_COUNT_CYCLES(fn_call)                     \ | ||||||
|  |     do                                                  \ | ||||||
|  |     {                                                   \ | ||||||
|  |         uint32_t __jtest_cycle_end_count;               \ | ||||||
|  |                                                         \ | ||||||
|  |         JTEST_SYSTICK_RESET(SysTick);                   \ | ||||||
|  |         JTEST_SYSTICK_START(SysTick);                   \ | ||||||
|  |                                                         \ | ||||||
|  |         fn_call;                                        \ | ||||||
|  |                                                         \ | ||||||
|  |         __jtest_cycle_end_count =                       \ | ||||||
|  |             JTEST_SYSTICK_VALUE(SysTick);               \ | ||||||
|  |                                                         \ | ||||||
|  | 		JTEST_SYSTICK_RESET(SysTick);                   \ | ||||||
|  |         JTEST_DUMP_STRF(JTEST_CYCLE_STRF,               \ | ||||||
|  |                         STR(fn_call),                   \ | ||||||
|  |                         (JTEST_SYSTICK_INITIAL_VALUE -  \ | ||||||
|  |                          __jtest_cycle_end_count));     \ | ||||||
|  |     } while (0) | ||||||
|  | */ | ||||||
|  | #define JTEST_COUNT_CYCLES(fn_call)                     \ | ||||||
|  |     do                                                  \ | ||||||
|  |     {                                                   \ | ||||||
|  |         uint32_t __jtest_cycle_end_count;               \ | ||||||
|  |                                                         \ | ||||||
|  |         JTEST_SYSTICK_RESET(SysTick);                   \ | ||||||
|  |         JTEST_SYSTICK_START(SysTick);                   \ | ||||||
|  |                                                         \ | ||||||
|  |         fn_call;                                        \ | ||||||
|  |                                                         \ | ||||||
|  |         __jtest_cycle_end_count =                       \ | ||||||
|  |             JTEST_SYSTICK_VALUE(SysTick);               \ | ||||||
|  |                                                         \ | ||||||
|  | 		JTEST_SYSTICK_RESET(SysTick);                   \ | ||||||
|  |         JTEST_DUMP_STRF(JTEST_CYCLE_STRF,               \ | ||||||
|  |                         (JTEST_SYSTICK_INITIAL_VALUE -  \ | ||||||
|  |                          __jtest_cycle_end_count));     \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_CYCLE_H_ */ | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | #ifndef _JTEST_DEFINE_H_ | ||||||
|  | #define _JTEST_DEFINE_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Makes a symbol for use as a struct name. Names made this way have two parts; | ||||||
|  |  *  the first parts is a prefix common to all structs of that class. The second | ||||||
|  |  *  is a specifier which differs for each instance of that struct type. | ||||||
|  |  */ | ||||||
|  | #define JTEST_STRUCT_NAME(prefix, specifier)    \ | ||||||
|  |     CONCAT(prefix, specifier) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define a struct with type with a name generated by #JTEST_STRUCT_NAME(). | ||||||
|  |  */ | ||||||
|  | #define JTEST_DEFINE_STRUCT(type, struct_name)    \ | ||||||
|  |     type struct_name | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Declare a struct with type with a name generated by #JTEST_STRUCT_NAME(). | ||||||
|  |  */ | ||||||
|  | #define JTEST_DECLARE_STRUCT(struct_definition) \ | ||||||
|  |     extern struct_definition | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define and initialize a struct (created with JTEST_DEFINE_STRUCT()) and | ||||||
|  |  *  initialize it with init_values. | ||||||
|  |  */ | ||||||
|  | #define JTEST_INIT_STRUCT(struct_definition, init_values)       \ | ||||||
|  |     struct_definition = {                                       \ | ||||||
|  |         init_values                                             \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_DEFINE_H_ */ | ||||||
| @ -0,0 +1,253 @@ | |||||||
|  | #ifndef _JTEST_FW_H_ | ||||||
|  | #define _JTEST_FW_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include <stdint.h>             /* int32_t */ | ||||||
|  | #include <string.h>             /* strcpy() */ | ||||||
|  | #include <stdio.h>              /* sprintf() */ | ||||||
|  | #include "jtest_pf.h"           /* Extend JTEST_FW_t with Pass/Fail data */ | ||||||
|  | #include "jtest_group.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Type Definitions */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  A struct used to interface with the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | typedef struct JTEST_FW_struct | ||||||
|  | { | ||||||
|  |     /* Action Triggers: The Keil debugger monitors these values for changes.  In
 | ||||||
|  |      * response to a change, the debugger executes code on the host. */ | ||||||
|  |     volatile int32_t test_start; | ||||||
|  |     volatile int32_t test_end; | ||||||
|  |     volatile int32_t group_start; | ||||||
|  |     volatile int32_t group_end; | ||||||
|  |     volatile int32_t dump_str; | ||||||
|  |     volatile int32_t dump_data; | ||||||
|  |     volatile int32_t exit_fw; | ||||||
|  | 
 | ||||||
|  |     JTEST_GROUP_t * current_group_ptr; | ||||||
|  | 
 | ||||||
|  |     /* Buffers: The C-code cannot send strings and data directly to the
 | ||||||
|  |      * debugging framework. Instead, the debugger can be told to read 128 byte | ||||||
|  |      * (by default) chunks of memory.  Data received in this manner requires | ||||||
|  |      * post-processing to be legible.*/ | ||||||
|  |     char * str_buffer; | ||||||
|  |     char * data_buffer; | ||||||
|  | 
 | ||||||
|  |     /* Pass/Fail Data */ | ||||||
|  |     JTEST_PF_MEMBERS; | ||||||
|  | 
 | ||||||
|  | } JTEST_FW_t; | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Default name for the JTEST_FW struct. | ||||||
|  |  * | ||||||
|  |  *  Define your own if you want the variable containing the #JTEST_FW_t to have | ||||||
|  |  *  a different name. | ||||||
|  |  */ | ||||||
|  | #ifndef JTEST_FW | ||||||
|  | #define JTEST_FW JTEST_FW | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Default name for the JTEST_FW_STR_BUFFER. | ||||||
|  |  * | ||||||
|  |  *  Define your own if you want the variable containing the char buffer to have | ||||||
|  |  *  a different name. | ||||||
|  |  */ | ||||||
|  | #ifndef JTEST_FW_STR_BUFFER | ||||||
|  | #define JTEST_FW_STR_BUFFER JTEST_FW_STR_BUFFER | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Size of the #JTEST_FW_t, output string-buffer. | ||||||
|  |  * | ||||||
|  |  *  If you change this value, make sure the "dump_str_fn" and "dump_data_fn" | ||||||
|  |  *  functions in jtest_fns.ini uses the same size. If you aren't sure, read the | ||||||
|  |  *  documentation Keil Debugger Command 'DISPLAY'. | ||||||
|  |  */ | ||||||
|  | #define JTEST_BUF_SIZE 256 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  The maximum number of bytes output at once using #JTEST_DUMP_STRF(). | ||||||
|  |  */ | ||||||
|  | #define JTEST_STR_MAX_OUTPUT_SIZE 128 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  The maximum number of block transimissions needed to send a string from a | ||||||
|  |  *  buffer with JTEST_BUF_SIZE. | ||||||
|  |  */ | ||||||
|  | #define JTEST_STR_MAX_OUTPUT_SEGMENTS           \ | ||||||
|  |     (JTEST_BUF_SIZE / JTEST_STR_MAX_OUTPUT_SIZE) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Initialize the JTEST framework. | ||||||
|  |  */ | ||||||
|  | #define JTEST_INIT()                                                    \ | ||||||
|  |     do                                                                  \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         JTEST_FW.str_buffer = JTEST_FW_STR_BUFFER;                      \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /* Debugger Action-triggering Macros */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dispatch macro to trigger various actions in the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TRIGGER_ACTION(action_name)       \ | ||||||
|  |     do                                          \ | ||||||
|  |     {                                           \ | ||||||
|  |         action_name();                          \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Trigger the "Test Start" action in the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_ACT_TEST_START()                  \ | ||||||
|  |     JTEST_TRIGGER_ACTION(test_start) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Trigger the "Test End" action in the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_ACT_TEST_END()                    \ | ||||||
|  |     JTEST_TRIGGER_ACTION(test_end) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Trigger the "Group Start" action in the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_ACT_GROUP_START()                 \ | ||||||
|  |     JTEST_TRIGGER_ACTION(group_start) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Trigger the "Group End" action in the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_ACT_GROUP_END()                   \ | ||||||
|  |     JTEST_TRIGGER_ACTION(group_end) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Fill the buffer named buf_name with value and dump it to the Keil debugger | ||||||
|  |  *  using action. | ||||||
|  |  */ | ||||||
|  | #define JTEST_ACT_DUMP(action, buf_name, value) \ | ||||||
|  |     do                                          \ | ||||||
|  |     {                                           \ | ||||||
|  |         JTEST_CLEAR_BUFFER(buf_name);           \ | ||||||
|  |         strcpy(JTEST_FW.buf_name, (value));     \ | ||||||
|  |         JTEST_TRIGGER_ACTION(action);           \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Trigger the "Exit Framework" action in the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_ACT_EXIT_FW()                     \ | ||||||
|  |     do                                          \ | ||||||
|  |     {                                           \ | ||||||
|  |         JTEST_TRIGGER_ACTION(exit_fw);          \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Buffer Manipulation Macros */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Clear the JTEST_FW buffer with name buf_name. | ||||||
|  |  */ | ||||||
|  | #define JTEST_CLEAR_BUFFER(buf_name)                    \ | ||||||
|  |     do                                                  \ | ||||||
|  |     {                                                   \ | ||||||
|  |         memset(JTEST_FW.buf_name, 0, JTEST_BUF_SIZE);   \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Clear the memory needed for the JTEST_FW's string buffer. | ||||||
|  |  */ | ||||||
|  | #define JTEST_CLEAR_STR_BUFFER()                \ | ||||||
|  |         JTEST_CLEAR_BUFFER(str_buffer) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Clear the memory needed for the JTEST_FW's data buffer. | ||||||
|  |  */ | ||||||
|  | #define JTEST_CLEAR_DATA_BUFFER()               \ | ||||||
|  |         JTEST_CLEAR_BUFFER(data_buffer) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dump the given string to the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_DUMP_STR(string)                          \ | ||||||
|  |         JTEST_ACT_DUMP(dump_str, str_buffer, string) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dump a formatted string to the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_DUMP_STRF(format_str, ... )                               \ | ||||||
|  |     do                                                                  \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         JTEST_CLEAR_STR_BUFFER();                                       \ | ||||||
|  |         sprintf(JTEST_FW.str_buffer,format_str, __VA_ARGS__);           \ | ||||||
|  |         jtest_dump_str_segments();                                      \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /* Pass/Fail Macros */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Increment the number of passed tests in #JTEST_FW. | ||||||
|  |  */ | ||||||
|  | #define JTEST_FW_INC_PASSED(amount)             \ | ||||||
|  |         JTEST_PF_INC_PASSED(&JTEST_FW, amount) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Increment the number of passed tests in #JTEST_FW. | ||||||
|  |  */ | ||||||
|  | #define JTEST_FW_INC_FAILED(amount)             \ | ||||||
|  |         JTEST_PF_INC_FAILED(&JTEST_FW, amount) | ||||||
|  | 
 | ||||||
|  | /* Manipulating the Current Group */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the current_group_ptr in #JTEST_FW. | ||||||
|  |  */ | ||||||
|  | #define JTEST_CURRENT_GROUP_PTR()               \ | ||||||
|  |     (JTEST_FW.current_group_ptr) | ||||||
|  | 
 | ||||||
|  | #define JTEST_SET_CURRENT_GROUP(group_ptr)      \ | ||||||
|  |     do                                          \ | ||||||
|  |     {                                           \ | ||||||
|  |         JTEST_CURRENT_GROUP_PTR() = group_ptr;  \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Declare Global Variables */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | extern char JTEST_FW_STR_BUFFER[JTEST_BUF_SIZE]; | ||||||
|  | extern volatile JTEST_FW_t JTEST_FW; | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Function Prototypes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | void jtest_dump_str_segments(void); | ||||||
|  | 
 | ||||||
|  | void test_start  (void); | ||||||
|  | void test_end    (void); | ||||||
|  | void group_start (void); | ||||||
|  | void group_end   (void); | ||||||
|  | void dump_str    (void); | ||||||
|  | void dump_data   (void); | ||||||
|  | void exit_fw     (void); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_FW_H_ */ | ||||||
| @ -0,0 +1,66 @@ | |||||||
|  | #ifndef _JTEST_GROUP_H_ | ||||||
|  | #define _JTEST_GROUP_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "jtest_pf.h" | ||||||
|  | #include "jtest_util.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Type Definitions */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  A struct which represents a group of #JTEST_TEST_t structs. This struct is | ||||||
|  |  *  used to run the group of tests, and report on their outcomes. | ||||||
|  |  */ | ||||||
|  | typedef struct JTEST_GROUP_struct | ||||||
|  | { | ||||||
|  |     void (* group_fn_ptr) (void); /**< Pointer to the test group */ | ||||||
|  |     char * name_str;              /**< Name of the group */ | ||||||
|  |      | ||||||
|  |     /* Extend the #JTEST_GROUP_t with Pass/Fail information.*/ | ||||||
|  |     JTEST_PF_MEMBERS; | ||||||
|  | } JTEST_GROUP_t; | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Set the name of JTEST_GROUP_t. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_SET_NAME(group_ptr, name)     \ | ||||||
|  |     JTEST_SET_STRUCT_ATTRIBUTE(group_ptr, name_str, name) | ||||||
|  | 
 | ||||||
|  | #define JTEST_GROUP_SET_FN(group_ptr, fn_ptr)     \ | ||||||
|  |     JTEST_SET_STRUCT_ATTRIBUTE(group_ptr, group_fn_ptr, fn_ptr) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Increment the number of tests passed in the JTEST_GROUP_t pointed to by | ||||||
|  |  *  group_ptr. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_INC_PASSED(group_ptr, amount) \ | ||||||
|  |     JTEST_PF_INC_PASSED(group_ptr, amount) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Increment the number of tests failed in the JTEST_GROUP_t pointed to by | ||||||
|  |  *  group_ptr. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_INC_FAILED(group_ptr, amount) \ | ||||||
|  |     JTEST_PF_INC_FAILED(group_ptr, amount) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Reset the pass/fail information of the #JTEST_GROUP_t pointed to by | ||||||
|  |  *  group_ptr. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_RESET_PF(group_ptr)         \ | ||||||
|  |     do                                          \ | ||||||
|  |     {                                           \ | ||||||
|  |         JTEST_PF_RESET_PASSED(group_ptr);       \ | ||||||
|  |         JTEST_PF_RESET_FAILED(group_ptr);       \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_GROUP_H_ */ | ||||||
| @ -0,0 +1,126 @@ | |||||||
|  | #ifndef _JTEST_GROUP_CALL_H_ | ||||||
|  | #define _JTEST_GROUP_CALL_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "jtest_fw.h" | ||||||
|  | #include <inttypes.h> | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Execute the test in the #JTEST_GROUP_t struct associated witht he identifier | ||||||
|  |  *  group_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_RUN(group_fn)                                   \ | ||||||
|  |     do                                                              \ | ||||||
|  |     {                                                               \ | ||||||
|  |         JTEST_DUMP_STR("Group Name:\n");                            \ | ||||||
|  |         JTEST_DUMP_STR(JTEST_GROUP_STRUCT_NAME(group_fn).name_str); \ | ||||||
|  |         JTEST_GROUP_STRUCT_NAME(group_fn).group_fn_ptr();           \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Update the enclosing #JTEST_GROUP_t's pass/fail information using the | ||||||
|  |  *  current #JTEST_GROUP_t's. | ||||||
|  |  * | ||||||
|  |  *  @param group_ptr Pointer to the current #JTEST_GROUP_t. | ||||||
|  |  *  @param parent_ptr Pointer to the enclosing #JTEST_GROUP_t. | ||||||
|  |  * | ||||||
|  |  *  @warning Only run this if the current #JTEST_GROUP_t is being called within | ||||||
|  |  *  the context of another #JTEST_GROUP_t. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_UPDATE_PARENT_GROUP_PF(group_ptr, parent_group_ptr) \ | ||||||
|  |     do                                                                  \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         JTEST_GROUP_INC_PASSED(parent_group_ptr,                        \ | ||||||
|  |                                (group_ptr)->passed);                    \ | ||||||
|  |         JTEST_GROUP_INC_FAILED(parent_group_ptr,                        \ | ||||||
|  |                                (group_ptr)->failed);                    \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Update the #JTEST_FW's pass/fail information using the current | ||||||
|  |  *  #JTEST_GROUP_t's. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_UPDATE_FW_PF(group_ptr)                     \ | ||||||
|  |     do                                                          \ | ||||||
|  |     {                                                           \ | ||||||
|  |         JTEST_FW_INC_PASSED((group_ptr)->passed);               \ | ||||||
|  |         JTEST_FW_INC_FAILED((group_ptr)->failed);               \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Update the enclosing context with the current #JTEST_GROUP_t's pass/fail | ||||||
|  |  *  information. If this group isn't in an enclosing group, it updates the | ||||||
|  |  *  #JTEST_FW's pass/fail info by default. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_UPDATE_PARENT_GROUP_OR_FW_PF(group_ptr,         \ | ||||||
|  |                                                  parent_group_ptr)  \ | ||||||
|  |     do                                                              \ | ||||||
|  |     {                                                               \ | ||||||
|  |         /* Update the pass fail counts in the parent group */       \ | ||||||
|  |         if (parent_group_ptr /* Null implies Top*/)                 \ | ||||||
|  |         {                                                           \ | ||||||
|  |             JTEST_GROUP_UPDATE_PARENT_GROUP_PF(                     \ | ||||||
|  |                 group_ptr,                                          \ | ||||||
|  |                 parent_group_ptr);                                  \ | ||||||
|  |         } else {                                                    \ | ||||||
|  |             JTEST_GROUP_UPDATE_FW_PF(                               \ | ||||||
|  |                 group_ptr);                                         \ | ||||||
|  |         }                                                           \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dump the results of running the #JTEST_GROUP_t to the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_DUMP_RESULTS(group_ptr)                             \ | ||||||
|  |         do                                                              \ | ||||||
|  |         {                                                               \ | ||||||
|  |             JTEST_DUMP_STRF(                                            \ | ||||||
|  |                 "Tests Run: %" PRIu32 "\n"                              \ | ||||||
|  |                 "----------\n"                                          \ | ||||||
|  |                 "   Passed: %" PRIu32 "\n"                              \ | ||||||
|  |                 "   Failed: %" PRIu32 "\n",                             \ | ||||||
|  |                 (group_ptr)->passed + (group_ptr)->failed,              \ | ||||||
|  |                 (group_ptr)->passed,                                    \ | ||||||
|  |                 (group_ptr)->failed);                                   \ | ||||||
|  |         } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Call the #JTEST_GROUP_t associated with the identifier group_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_CALL(group_fn)                                      \ | ||||||
|  |         do                                                              \ | ||||||
|  |         {   /* Save the current group from JTEST_FW_t before swapping */ \ | ||||||
|  |             /* it to this group (in order to restore it later )*/       \ | ||||||
|  |             JTEST_GROUP_t * __jtest_temp_group_ptr =                    \ | ||||||
|  |                 JTEST_CURRENT_GROUP_PTR();                              \ | ||||||
|  |             JTEST_SET_CURRENT_GROUP(&JTEST_GROUP_STRUCT_NAME(group_fn)); \ | ||||||
|  |                                                                         \ | ||||||
|  |             /* Reset this group's pass/fail count. Each group */        \ | ||||||
|  |             /* should only remember counts for its last execution. */   \ | ||||||
|  |             JTEST_GROUP_RESET_PF(JTEST_CURRENT_GROUP_PTR());            \ | ||||||
|  |                                                                         \ | ||||||
|  |             /* Run the current group */                                 \ | ||||||
|  |             JTEST_ACT_GROUP_START();                                    \ | ||||||
|  |             JTEST_GROUP_RUN(group_fn);                                  \ | ||||||
|  |             JTEST_ACT_GROUP_END();                                      \ | ||||||
|  |                                                                         \ | ||||||
|  |             /* Update the pass fail counts in the parent group (or FW) */ \ | ||||||
|  |             JTEST_GROUP_UPDATE_PARENT_GROUP_OR_FW_PF(                   \ | ||||||
|  |                 JTEST_CURRENT_GROUP_PTR(),                              \ | ||||||
|  |                 __jtest_temp_group_ptr);                                \ | ||||||
|  |                                                                         \ | ||||||
|  |             JTEST_GROUP_DUMP_RESULTS(JTEST_CURRENT_GROUP_PTR());        \ | ||||||
|  |                                                                         \ | ||||||
|  |             /* Restore the previously current group */                  \ | ||||||
|  |             JTEST_SET_CURRENT_GROUP(__jtest_temp_group_ptr);            \ | ||||||
|  |         } while (0) | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_GROUP_CALL_H_ */ | ||||||
| @ -0,0 +1,87 @@ | |||||||
|  | #ifndef _JTEST_GROUP_DEFINE_H_ | ||||||
|  | #define _JTEST_GROUP_DEFINE_H_ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "jtest_util.h" | ||||||
|  | #include "jtest_define.h" | ||||||
|  | #include "jtest_group.h" | ||||||
|  | 
 | ||||||
|  | /* For defining macros with optional arguments */ | ||||||
|  | #include "opt_arg/opt_arg.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Prefix for all #JTEST_GROUP_t structs. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_STRUCT_NAME_PREFIX G_JTEST_GROUP_STRUCT_ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define test template used by #JTEST_GROUP_t tests. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_FN_TEMPLATE(group_fn)    \ | ||||||
|  |     void group_fn(void) | ||||||
|  | 
 | ||||||
|  | #define JTEST_GROUP_FN_PROTOTYPE JTEST_GROUP_FN_TEMPLATE /**< Alias for | ||||||
|  |                                                             #JTEST_GROUP_FN_TEMPLATE. */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the name of the #JTEST_GROUP_t struct associated with group_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_STRUCT_NAME(group_fn)    \ | ||||||
|  |     JTEST_STRUCT_NAME(JTEST_GROUP_STRUCT_NAME_PREFIX, group_fn) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define a #JTEST_GROUP_t struct based on the given group_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_DEFINE_STRUCT(group_fn)  \ | ||||||
|  |     JTEST_DEFINE_STRUCT(JTEST_GROUP_t,       \ | ||||||
|  |                         JTEST_GROUP_STRUCT_NAME(group_fn)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Declare a #JTEST_GROUP_t struct based on the given group_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_DECLARE_STRUCT(group_fn) \ | ||||||
|  |     JTEST_DECLARE_STRUCT(JTEST_GROUP_DEFINE_STRUCT(group_fn)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Contents needed to initialize a JTEST_GROUP_t struct. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_STRUCT_INIT(group_fn)    \ | ||||||
|  |     group_fn,                                \ | ||||||
|  |         STR_NL(group_fn),                       \ | ||||||
|  |         JTEST_PF_MEMBER_INIT | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Initialize the contents of a #JTEST_GROUP_t struct. | ||||||
|  |  */ | ||||||
|  | #define JTEST_GROUP_INIT(group_fn)           \ | ||||||
|  |     JTEST_GROUP_DEFINE_STRUCT(group_fn) = {  \ | ||||||
|  |         JTEST_GROUP_STRUCT_INIT(group_fn)    \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | /* Test Definition Macro */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define a #JTEST_GROUP_t object and a test function. | ||||||
|  |  */ | ||||||
|  | #define JTEST_DEFINE_GROUP(group_fn)         \ | ||||||
|  |     JTEST_GROUP_FN_PROTOTYPE(group_fn);      \ | ||||||
|  |     JTEST_GROUP_INIT(group_fn);              \ | ||||||
|  |     JTEST_GROUP_FN_PROTOTYPE(group_fn) /* Notice the lacking semicolon */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Declare a #JTEST_GROUP_t object and a test function prototype. | ||||||
|  |  */ | ||||||
|  | #define JTEST_DECLARE_GROUP(group_fn)        \ | ||||||
|  |     JTEST_GROUP_FN_PROTOTYPE(group_fn);      \ | ||||||
|  |     JTEST_GROUP_DECLARE_STRUCT(group_fn) /* Note the lacking semicolon */ | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_GROUP_DEFINE_H_ */ | ||||||
| @ -0,0 +1,85 @@ | |||||||
|  | #ifndef _JTEST_PF_H_ | ||||||
|  | #define _JTEST_PF_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Purpose */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* jtest_pf.h Contains macros useful for capturing pass/fail data. */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Members that can be added to other structs to extend them pass/fail data and | ||||||
|  |  * corresponding functionality. | ||||||
|  |  */ | ||||||
|  | #define JTEST_PF_MEMBERS                            \ | ||||||
|  |     uint32_t passed;                                \ | ||||||
|  |     uint32_t failed /* Note the lacking semicolon*/ \ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Used for initializing JTEST_PF_MEMBERS in a struct declaration. | ||||||
|  |  */ | ||||||
|  | #define JTEST_PF_MEMBER_INIT                    \ | ||||||
|  |     0,                                          \ | ||||||
|  |     0 | ||||||
|  | 
 | ||||||
|  | /* Member-Incrementing Macros */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dispatch macro for incrementing #JTEST_PF_MEMBERS. | ||||||
|  |  * | ||||||
|  |  *  @param xxx Values: 'passed', 'failed' | ||||||
|  |  */ | ||||||
|  | #define JTEST_PF_INC_XXX(xxx, struct_pf_ptr, amount)    \ | ||||||
|  |     do                                                  \ | ||||||
|  |     {                                                   \ | ||||||
|  |         ((struct_pf_ptr)->xxx) += (amount);             \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of the #JTEST_PF_INC_XXX macro to increment the passed | ||||||
|  |  *  member. | ||||||
|  |  */ | ||||||
|  | #define JTEST_PF_INC_PASSED(struct_pf_ptr, amount)  \ | ||||||
|  |     JTEST_PF_INC_XXX(passed, struct_pf_ptr, amount) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of the #JTEST_PF_INC_XXX macro to increment the failed | ||||||
|  |  *  member. | ||||||
|  |  */ | ||||||
|  | #define JTEST_PF_INC_FAILED(struct_pf_ptr, amount)  \ | ||||||
|  |     JTEST_PF_INC_XXX(failed, struct_pf_ptr, amount) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Member-Resetting Macros */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dispatch macro for setting #JTEST_PF_MEMBERS to zero. | ||||||
|  |  * | ||||||
|  |  *  @param xxx Values: 'passed', 'failed' | ||||||
|  |  */ | ||||||
|  | #define JTEST_PF_RESET_XXX(xxx, struct_pf_ptr)  \ | ||||||
|  |     do                                          \ | ||||||
|  |     {                                           \ | ||||||
|  |         ((struct_pf_ptr)->xxx) = UINT32_C(0);   \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of #JTEST_PF_RESET_XXX for the 'passed' member. | ||||||
|  |  */ | ||||||
|  | #define JTEST_PF_RESET_PASSED(struct_pf_ptr)    \ | ||||||
|  |     JTEST_PF_RESET_XXX(passed, struct_pf_ptr) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of #JTEST_PF_RESET_XXX for the 'failed' member. | ||||||
|  |  */ | ||||||
|  | #define JTEST_PF_RESET_FAILED(struct_pf_ptr)    \ | ||||||
|  |     JTEST_PF_RESET_XXX(failed, struct_pf_ptr) | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_PF_H_ */ | ||||||
| @ -0,0 +1,93 @@ | |||||||
|  | #ifndef _JTEST_SYSTICK_H_ | ||||||
|  | #define _JTEST_SYSTICK_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* Get access to the SysTick structure. */ | ||||||
|  | #if   defined ARMCM0 | ||||||
|  |   #include "ARMCM0.h" | ||||||
|  | #elif defined ARMCM0P | ||||||
|  |   #include "ARMCM0plus.h" | ||||||
|  | #elif defined ARMCM3 | ||||||
|  |   #include "ARMCM3.h" | ||||||
|  | #elif defined ARMCM4 | ||||||
|  |   #include "ARMCM4.h" | ||||||
|  | #elif defined ARMCM4_FP | ||||||
|  |   #include "ARMCM4_FP.h" | ||||||
|  | #elif defined ARMCM7 | ||||||
|  |   #include "ARMCM7.h"  | ||||||
|  | #elif defined ARMCM7_SP | ||||||
|  |   #include "ARMCM7_SP.h" | ||||||
|  | #elif defined ARMCM7_DP | ||||||
|  |   #include "ARMCM7_DP.h" | ||||||
|  | #elif defined ARMSC000 | ||||||
|  |   #include "ARMSC000.h" | ||||||
|  | #elif defined ARMSC300 | ||||||
|  |   #include "ARMSC300.h" | ||||||
|  | #elif defined ARMv8MBL | ||||||
|  |   #include "ARMv8MBL.h" | ||||||
|  | #elif defined ARMv8MML | ||||||
|  |   #include "ARMv8MML.h" | ||||||
|  | #elif defined ARMv8MML_DSP | ||||||
|  |   #include "ARMv8MML_DSP.h" | ||||||
|  | #elif defined ARMv8MML_SP | ||||||
|  |   #include "ARMv8MML_SP.h" | ||||||
|  | #elif defined ARMv8MML_DSP_SP | ||||||
|  |   #include "ARMv8MML_DSP_SP.h" | ||||||
|  | #elif defined ARMv8MML_DP | ||||||
|  |   #include "ARMv8MML_DP.h" | ||||||
|  | #elif defined ARMv8MML_DSP_DP | ||||||
|  |   #include "ARMv8MML_DSP_DP.h" | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  |   #warning "no appropriate header file found!" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Initial value for the SysTick module. | ||||||
|  |  * | ||||||
|  |  *  @note This is also the maximum value, important as SysTick is a decrementing | ||||||
|  |  *  counter. | ||||||
|  |  */ | ||||||
|  | #define JTEST_SYSTICK_INITIAL_VALUE 0xFFFFFF | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Reset the SysTick, decrementing timer to it's maximum value and disable it. | ||||||
|  |  * | ||||||
|  |  *  This macro should leave the SysTick timer in a state that's ready for cycle | ||||||
|  |  *  counting. | ||||||
|  |  */ | ||||||
|  | #define JTEST_SYSTICK_RESET(systick_ptr)                    \ | ||||||
|  |     do                                                      \ | ||||||
|  |     {                                                       \ | ||||||
|  |         (systick_ptr)->LOAD = JTEST_SYSTICK_INITIAL_VALUE;  \ | ||||||
|  |         (systick_ptr)->VAL = 1;                             \ | ||||||
|  |                                                             \ | ||||||
|  |         /* Disable the SysTick module. */                   \ | ||||||
|  |         (systick_ptr)->CTRL = UINT32_C(0x000000);           \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Start the SysTick timer, sourced by the processor clock. | ||||||
|  |  */ | ||||||
|  | #define JTEST_SYSTICK_START(systick_ptr)                    \ | ||||||
|  |     do                                                      \ | ||||||
|  |     {                                                       \ | ||||||
|  |         (systick_ptr)->CTRL =                               \ | ||||||
|  |             SysTick_CTRL_ENABLE_Msk |                       \ | ||||||
|  |             SysTick_CTRL_CLKSOURCE_Msk; /* Internal clk*/   \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the current value of the SysTick timer. | ||||||
|  |  */ | ||||||
|  | #define JTEST_SYSTICK_VALUE(systick_ptr)        \ | ||||||
|  |     ((systick_ptr)->VAL) | ||||||
|  |             | ||||||
|  | #endif /* _JTEST_SYSTICK_H_ */ | ||||||
| @ -0,0 +1,100 @@ | |||||||
|  | #ifndef _JTEST_TEST_H_ | ||||||
|  | #define _JTEST_TEST_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | #include "jtest_util.h" | ||||||
|  | #include "jtest_test_ret.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Type Definitions */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  A struct which represents a Test in the JTEST framework.  This struct is | ||||||
|  |  *  used to enable, run, and describe the test it represents. | ||||||
|  |  */ | ||||||
|  | typedef struct JTEST_TEST_struct | ||||||
|  | { | ||||||
|  |     JTEST_TEST_RET_t ( * test_fn_ptr)(void); /**< Pointer to the test function. */ | ||||||
|  |     char   * test_fn_str;                    /**< Name of the test function */ | ||||||
|  |     char   * fut_str;           /**< Name of the function under test. */ | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      *  Flags that govern how the #JTEST_TEST_t behaves. | ||||||
|  |      */ | ||||||
|  |     union { | ||||||
|  |         struct { | ||||||
|  |             unsigned enabled : 1; | ||||||
|  |             unsigned unused  : 7; | ||||||
|  |         } bits; | ||||||
|  |         uint8_t byte;           /* Access all flags at once. */ | ||||||
|  |     } flags; | ||||||
|  |      | ||||||
|  | } JTEST_TEST_t; | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Assign a test function to the #JTEST_TEST_t struct. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_SET_FN(jtest_test_ptr, fn_ptr)                   \ | ||||||
|  |     JTEST_SET_STRUCT_ATTRIBUTE(jtest_test_ptr, test_fn_ptr, fn_ptr) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specify a function under test (FUT) for the #JTEST_TEST_t struct. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_SET_FUT(jtest_test_ptr, str)                 \ | ||||||
|  |     JTEST_SET_STRUCT_ATTRIBUTE(jtest_test_ptr, fut_str, str) | ||||||
|  | 
 | ||||||
|  | /* Macros concerning JTEST_TEST_t flags */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #define JTEST_TEST_FLAG_SET 1 /**< Value of a set #JTEST_TEST_t flag. */ | ||||||
|  | #define JTEST_TEST_FLAG_CLR 0 /**< Value of a cleared #JTEST_TEST_t flag. */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the flag in #JTEST_TEST_t having flag_name. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_FLAG(jtest_test_ptr, flag_name)  \ | ||||||
|  |     ((jtest_test_ptr)->flags.bits.flag_name) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dispatch macro for setting and clearing #JTEST_TEST_t flags. | ||||||
|  |  * | ||||||
|  |  *  @param jtest_test_ptr Pointer to a #JTEST_TEST_t struct. | ||||||
|  |  *  @param flag_name      Name of the flag to set in #JTEST_TEST_t.flags.bits | ||||||
|  |  *  @param xxx            Vaid values: "SET" or "CLR" | ||||||
|  |  * | ||||||
|  |  *  @note This function depends on JTEST_TEST_FLAG_SET and JTEST_TEST_FLAG_CLR. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, xxx)                  \ | ||||||
|  |     do                                                                       \ | ||||||
|  |     {                                                                        \ | ||||||
|  |         JTEST_TEST_FLAG(jtest_test_ptr, flag_name) = JTEST_TEST_FLAG_##xxx ; \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specification of #JTEST_TEST_XXX_FLAG to set #JTEST_TEST_t flags. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_SET_FLAG(jtest_test_ptr, flag_name)                       \ | ||||||
|  |     JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, SET) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specification of #JTEST_TEST_XXX_FLAG to clear #JTEST_TEST_t flags. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_CLR_FLAG(jtest_test_ptr, flag_name)                       \ | ||||||
|  |     JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, CLR) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to true if the #JTEST_TEST_t is enabled. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_IS_ENABLED(jtest_test_ptr)                           \ | ||||||
|  |     (JTEST_TEST_FLAG(jtest_test_ptr, enabled) == JTEST_TEST_FLAG_SET) | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_TEST_H_ */ | ||||||
| @ -0,0 +1,121 @@ | |||||||
|  | #ifndef _JTEST_TEST_CALL_H_ | ||||||
|  | #define _JTEST_TEST_CALL_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | #include "jtest_test.h" | ||||||
|  | #include "jtest_test_define.h" | ||||||
|  | #include "jtest_fw.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Exectute the test in the #JTEST_TEST_t struct associated with the identifier | ||||||
|  |  *  test_fn and store the result in retval. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_RUN(retval, test_fn)                                 \ | ||||||
|  |     do                                                                  \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         JTEST_DUMP_STR("Test Name:\n");                                 \ | ||||||
|  |         JTEST_DUMP_STR(JTEST_TEST_STRUCT_NAME(test_fn).test_fn_str);    \ | ||||||
|  |         JTEST_DUMP_STR("Function Under Test:\n");                       \ | ||||||
|  |         JTEST_DUMP_STR(JTEST_TEST_STRUCT_NAME(test_fn).fut_str);        \ | ||||||
|  |         retval = JTEST_TEST_STRUCT_NAME(test_fn).test_fn_ptr();         \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Update the enclosing #JTEST_GROUP_t's pass/fail information based on | ||||||
|  |  *  test_retval. | ||||||
|  |  * | ||||||
|  |  *  @param test_retval A #JTEST_TEST_RET_enum for the current test. | ||||||
|  |  * | ||||||
|  |  *  @warning Only use if #JTEST_TEST_t is called in the context of a | ||||||
|  |  *  #JTEST_GROUP_t. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_UPDATE_PARENT_GROUP_PF(test_retval)              \ | ||||||
|  |     do                                                              \ | ||||||
|  |     {                                                               \ | ||||||
|  |         /* Update enclosing JTEST_GROUP_t with pass/fail info */    \ | ||||||
|  |         if (test_retval == JTEST_TEST_PASSED)                       \ | ||||||
|  |         {                                                           \ | ||||||
|  |             JTEST_GROUP_INC_PASSED(JTEST_CURRENT_GROUP_PTR(), 1);   \ | ||||||
|  |         } else {                                                    \ | ||||||
|  |             JTEST_GROUP_INC_FAILED(JTEST_CURRENT_GROUP_PTR(), 1);   \ | ||||||
|  |         }                                                           \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Update the #JTEST_FW with pass/fail information based on test_retval. | ||||||
|  |  * | ||||||
|  |  *  @param test_retval A #JTEST_TEST_RET_enum for the current test. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_UPDATE_FW_PF(test_retval)                        \ | ||||||
|  |     do                                                              \ | ||||||
|  |     {                                                               \ | ||||||
|  |         /* Update the JTEST_FW with pass/fail info */                \ | ||||||
|  |         if (test_retval == JTEST_TEST_PASSED)                       \ | ||||||
|  |         {                                                           \ | ||||||
|  |             JTEST_FW_INC_PASSED( 1);                                \ | ||||||
|  |         } else {                                                    \ | ||||||
|  |             JTEST_FW_INC_FAILED(1);                                 \ | ||||||
|  |         }                                                           \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Update the enclosing JTEST_GROUP_t's pass/fail information, or the | ||||||
|  |  *  #JTEST_FW's if this test has no enclosing #JTEST_GROUP_t. | ||||||
|  |  * | ||||||
|  |  *  @param test_retval A #JTEST_TEST_RET_enum for the current test. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_UPDATE_PARENT_GROUP_OR_FW_PF(test_retval)            \ | ||||||
|  |     do                                                                  \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         /* Update pass-fail information */                              \ | ||||||
|  |         if (JTEST_CURRENT_GROUP_PTR() /* Non-null */)                    \ | ||||||
|  |         {                                                               \ | ||||||
|  |             JTEST_TEST_UPDATE_PARENT_GROUP_PF(test_retval);             \ | ||||||
|  |         } else {                                                        \ | ||||||
|  |             JTEST_TEST_UPDATE_FW_PF(test_retval);                       \ | ||||||
|  |         }                                                               \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dump the results of the test to the Keil Debugger. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_DUMP_RESULTS(test_retval)        \ | ||||||
|  |         do                                          \ | ||||||
|  |         {                                           \ | ||||||
|  |             if (test_retval == JTEST_TEST_PASSED)   \ | ||||||
|  |             {                                       \ | ||||||
|  |                 JTEST_DUMP_STR("Test Passed\n");      \ | ||||||
|  |             } else {                                \ | ||||||
|  |                 JTEST_DUMP_STR("Test Failed\n");      \ | ||||||
|  |             }                                       \ | ||||||
|  |         } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Call the #JTEST_TEST_t assocaited with the identifier test_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_CALL(test_fn)                                        \ | ||||||
|  |     do                                                                  \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         if (JTEST_TEST_IS_ENABLED(&JTEST_TEST_STRUCT_NAME(test_fn)))    \ | ||||||
|  |         {                                                               \ | ||||||
|  |             /* Default to failure */                                    \ | ||||||
|  |             JTEST_TEST_RET_t __jtest_test_ret = JTEST_TEST_FAILED;      \ | ||||||
|  |                                                                         \ | ||||||
|  |             JTEST_ACT_TEST_START();                                     \ | ||||||
|  |             JTEST_TEST_RUN(__jtest_test_ret, test_fn);                  \ | ||||||
|  |                                                                         \ | ||||||
|  |             /* Update pass-fail information */                          \ | ||||||
|  |             JTEST_TEST_UPDATE_PARENT_GROUP_OR_FW_PF(__jtest_test_ret);  \ | ||||||
|  |                                                                         \ | ||||||
|  |             JTEST_TEST_DUMP_RESULTS(__jtest_test_ret);                  \ | ||||||
|  |             JTEST_ACT_TEST_END();                                       \ | ||||||
|  |         }                                                               \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_TEST_CALL_H_ */ | ||||||
| @ -0,0 +1,133 @@ | |||||||
|  | #ifndef _JTEST_TEST_DEFINE_H_ | ||||||
|  | #define _JTEST_TEST_DEFINE_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "jtest_util.h" | ||||||
|  | #include "jtest_define.h" | ||||||
|  | #include "jtest_test.h" | ||||||
|  | 
 | ||||||
|  | /* For defining macros with optional arguments */ | ||||||
|  | #include "opt_arg/opt_arg.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Prefix for all #JTEST_TEST_t structs. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_STRUCT_NAME_PREFIX G_JTEST_TEST_STRUCT_ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define test template used by #JTEST_TEST_t tests. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_FN_TEMPLATE(test_fn)                         \ | ||||||
|  |     JTEST_TEST_RET_t test_fn(void) | ||||||
|  | 
 | ||||||
|  | #define JTEST_TEST_FN_PROTOTYPE JTEST_TEST_FN_TEMPLATE /**< Alias for | ||||||
|  |                                                         * #JTEST_TEST_FN_TEMPLATE. */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Evaluate to the name of the #JTEST_TEST_t struct associated with test_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_STRUCT_NAME(test_fn)                         \ | ||||||
|  |     JTEST_STRUCT_NAME(JTEST_TEST_STRUCT_NAME_PREFIX, test_fn) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define a #JTEST_TEST_t struct based on the given test_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_DEFINE_STRUCT(test_fn)                   \ | ||||||
|  |     JTEST_DEFINE_STRUCT(JTEST_TEST_t,                       \ | ||||||
|  |                         JTEST_TEST_STRUCT_NAME(test_fn)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Declare a #JTEST_TEST_t struct based on the given test_fn. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_DECLARE_STRUCT(test_fn)      \ | ||||||
|  |     JTEST_DECLARE_STRUCT(JTEST_TEST_DEFINE_STRUCT(test_fn)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Contents needed to initialize a JTEST_TEST_t struct. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_STRUCT_INIT(test_fn, fut, enable)    \ | ||||||
|  |     test_fn,                                            \ | ||||||
|  |         STR_NL(test_fn),                                   \ | ||||||
|  |         STR_NL(fut),                                       \ | ||||||
|  |     {                                                   \ | ||||||
|  |         {                                               \ | ||||||
|  |             enable,                                     \ | ||||||
|  |                 0                                       \ | ||||||
|  |         }                                               \ | ||||||
|  |     }                                                   \ | ||||||
|  |          | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Initialize the contents of a #JTEST_TEST_t struct. | ||||||
|  |  */ | ||||||
|  | #define JTEST_TEST_INIT(test_fn, fut, enable)              \ | ||||||
|  |     JTEST_TEST_DEFINE_STRUCT(test_fn) = {                  \ | ||||||
|  |         JTEST_TEST_STRUCT_INIT(test_fn, fut, enable)       \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | /* Test Definition Macro */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Define a #JTEST_TEST_t object and a test function. | ||||||
|  |  */ | ||||||
|  | #define _JTEST_DEFINE_TEST(test_fn, fut, enable)           \ | ||||||
|  |     JTEST_TEST_FN_PROTOTYPE(test_fn);                      \ | ||||||
|  |     JTEST_TEST_INIT(test_fn, fut, enable);                 \ | ||||||
|  |     JTEST_TEST_FN_PROTOTYPE(test_fn) /* Notice the lacking semicolon */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Declare a #JTEST_TEST_t object and a test function prototype. | ||||||
|  |  */ | ||||||
|  | #define JTEST_DECLARE_TEST(test_fn)                                     \ | ||||||
|  |     JTEST_TEST_FN_PROTOTYPE(test_fn);                                   \ | ||||||
|  |     JTEST_TEST_DECLARE_STRUCT(test_fn) /* Note the lacking semicolon */ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros with optional arguments */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* Top-level Interface */ | ||||||
|  | #define JTEST_DEFINE_TEST(...)                             \ | ||||||
|  |     JTEST_DEFINE_TEST_(PP_NARG(__VA_ARGS__), ##__VA_ARGS__) | ||||||
|  | 
 | ||||||
|  | /* Dispatch Macro*/ | ||||||
|  | #define JTEST_DEFINE_TEST_(N, ...)                         \ | ||||||
|  |     SPLICE(JTEST_DEFINE_TEST_, N)(__VA_ARGS__) | ||||||
|  | 
 | ||||||
|  | /* Default Arguments */ | ||||||
|  | #define JTEST_DEFINE_TEST_DEFAULT_FUT /* Blank */ | ||||||
|  | #define JTEST_DEFINE_TEST_DEFAULT_ENABLE                   \ | ||||||
|  |     JTEST_TRUE                                 /* Tests enabled by
 | ||||||
|  |                                                 * default. */  | ||||||
|  | 
 | ||||||
|  | /* Dispatch Cases*/ | ||||||
|  | #define JTEST_DEFINE_TEST_1(_1)                            \ | ||||||
|  |     _JTEST_DEFINE_TEST(                                    \ | ||||||
|  |         _1,                                                \ | ||||||
|  |         JTEST_DEFINE_TEST_DEFAULT_FUT,                     \ | ||||||
|  |         JTEST_DEFINE_TEST_DEFAULT_ENABLE                   \ | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | #define JTEST_DEFINE_TEST_2(_1, _2)                        \ | ||||||
|  |     _JTEST_DEFINE_TEST(                                    \ | ||||||
|  |         _1,                                                \ | ||||||
|  |         _2,                                                \ | ||||||
|  |         JTEST_DEFINE_TEST_DEFAULT_ENABLE                   \ | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | #define JTEST_DEFINE_TEST_3(_1, _2, _3)                    \ | ||||||
|  |     _JTEST_DEFINE_TEST(                                    \ | ||||||
|  |         _1,                                                \ | ||||||
|  |         _2,                                                \ | ||||||
|  |         _3                                                 \ | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_TEST_DEFINE_H_ */ | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | #ifndef _JTEST_TEST_RET_H_ | ||||||
|  | #define _JTEST_TEST_RET_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Type Definitions */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Values a #JTEST_TEST_t can return. | ||||||
|  |  */ | ||||||
|  | typedef enum JTEST_TEST_RET_enum | ||||||
|  | { | ||||||
|  |     JTEST_TEST_PASSED, | ||||||
|  |     JTEST_TEST_FAILED | ||||||
|  | } JTEST_TEST_RET_t; | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_TEST_RET_H_ */ | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | #ifndef _JTEST_UTIL_H_ | ||||||
|  | #define _JTEST_UTIL_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "util/util.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* Define boolean values for the framework. */ | ||||||
|  | #define JTEST_TRUE  1           /**< Value used for TRUE in JTEST. */ | ||||||
|  | #define JTEST_FALSE 0           /**< Value used for FALSE in JTEST. */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Set the value of the attribute in the struct to by struct_ptr to value. | ||||||
|  |  */ | ||||||
|  | #define JTEST_SET_STRUCT_ATTRIBUTE(struct_ptr, attribute, value)    \ | ||||||
|  |     do                                                              \ | ||||||
|  |     {                                                               \ | ||||||
|  |         (struct_ptr)->attribute = (value);                          \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | #endif /* _JTEST_UTIL_H_ */ | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | #ifndef _OPT_ARG_H_ | ||||||
|  | #define _OPT_ARG_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "pp_narg.h" | ||||||
|  | #include "splice.h" | ||||||
|  | 
 | ||||||
|  | /* If you are Joseph Jaoudi, you have a snippet which expands into an
 | ||||||
|  |    example. If you are not Joseph, but possess his code, study the examples. If | ||||||
|  |    you have no examples, turn back contact Joseph. */ | ||||||
|  | 
 | ||||||
|  | #endif /* _OPT_ARG_H_ */ | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | #ifndef _PP_NARG_H_ | ||||||
|  | #define _PP_NARG_H_ | ||||||
|  | 
 | ||||||
|  | #define PP_NARG(...)                                      \ | ||||||
|  |     PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) | ||||||
|  | #define PP_NARG_(...)                                     \ | ||||||
|  |     PP_ARG_N(__VA_ARGS__) | ||||||
|  | #define PP_ARG_N(                                         \ | ||||||
|  |                  _1, _2, _3, _4, _5, _6, _7, _8, _9,_10,  \ | ||||||
|  |                  _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ | ||||||
|  |                  _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ | ||||||
|  |                  _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ | ||||||
|  |                  _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ | ||||||
|  |                  _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ | ||||||
|  |                  _61,_62,_63,N,...) N | ||||||
|  | #define PP_RSEQ_N()                                       \ | ||||||
|  |     63,62,61,60,                                          \ | ||||||
|  |         59,58,57,56,55,54,53,52,51,50,                    \ | ||||||
|  |         49,48,47,46,45,44,43,42,41,40,                    \ | ||||||
|  |         39,38,37,36,35,34,33,32,31,30,                    \ | ||||||
|  |         29,28,27,26,25,24,23,22,21,20,                    \ | ||||||
|  |         19,18,17,16,15,14,13,12,11,10,                    \ | ||||||
|  |         9,8,7,6,5,4,3,2,1,0 | ||||||
|  | 
 | ||||||
|  | #endif /* _PP_NARG_H_ */ | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | #ifndef _SPLICE_H_ | ||||||
|  | #define _SPLICE_H_ | ||||||
|  | 
 | ||||||
|  | #define SPLICE(a,b) SPLICE_1(a,b) | ||||||
|  | #define SPLICE_1(a,b) SPLICE_2(a,b) | ||||||
|  | #define SPLICE_2(a,b) a##b | ||||||
|  | 
 | ||||||
|  | #endif /* _SPLICE_H_ */ | ||||||
| @ -0,0 +1,52 @@ | |||||||
|  | #ifndef _UTIL_H_ | ||||||
|  | #define _UTIL_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Convert a symbol to a string and add a 'NewLine'. | ||||||
|  |  */ | ||||||
|  | #define STR_NL(x)  STR1_NL(x) | ||||||
|  | #define STR1_NL(x) (STR2_NL(x)"\n") | ||||||
|  | #define STR2_NL(x) #x | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Convert a symbol to a string. | ||||||
|  |  */ | ||||||
|  | #define STR(x)  STR1(x) | ||||||
|  | #define STR1(x) STR2(x) | ||||||
|  | #define STR2(x) #x | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Concatenate two symbols. | ||||||
|  |  */ | ||||||
|  | #define CONCAT(a, b)  CONCAT1(a, b) | ||||||
|  | #define CONCAT1(a, b) CONCAT2(a, b) | ||||||
|  | #define CONCAT2(a, b) a##b | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Place curly braces around a varaible number of macro arguments. | ||||||
|  |  */ | ||||||
|  | #define CURLY(...) {__VA_ARGS__} | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Place parenthesis around a variable number of macro arguments. | ||||||
|  |  */ | ||||||
|  | #define PAREN(...) (__VA_ARGS__) | ||||||
|  | 
 | ||||||
|  | /* Standard min/max macros. */ | ||||||
|  | #define MIN(x,y) (((x) < (y)) ? (x) : (y) ) | ||||||
|  | #define MAX(x,y) (((x) > (y)) ? (x) : (y) ) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Bound value using low and high limits. | ||||||
|  |  * | ||||||
|  |  *  Evaluate to a number in the range, endpoint inclusive. | ||||||
|  |  */ | ||||||
|  | #define BOUND(low, high, value)                 \ | ||||||
|  |     MAX(MIN(high, value), low) | ||||||
|  | 
 | ||||||
|  | #endif /* _UTIL_H_ */ | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | #include "../inc/jtest_cycle.h" | ||||||
|  | #include <inttypes.h> | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Define Module Variables */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* const char * JTEST_CYCLE_STRF = "Running: %s\nCycles: %" PRIu32 "\n"; */ | ||||||
|  | const char * JTEST_CYCLE_STRF = "Cycles: %" PRIu32 "\n"; /* function name + parameter string skipped */ | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | #include "jtest_fw.h" | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Dump the JTEST_FW.str_buffer the Keil framework in pieces. | ||||||
|  |  * | ||||||
|  |  *  The JTEST_FW.str_buffer contains more characters than the Keil framework can | ||||||
|  |  *  dump at once. This function dumps them in blocks. | ||||||
|  |  */ | ||||||
|  | void jtest_dump_str_segments(void) | ||||||
|  | { | ||||||
|  |     uint32_t seg_idx      = 0; | ||||||
|  |     uint32_t memmove_idx = 0; | ||||||
|  |     uint32_t seg_cnt  = | ||||||
|  |         (strlen(JTEST_FW.str_buffer) / JTEST_STR_MAX_OUTPUT_SIZE) + 1; | ||||||
|  | 
 | ||||||
|  |     for( seg_idx = 0; seg_idx < seg_cnt; ++seg_idx) | ||||||
|  |     { | ||||||
|  |         JTEST_TRIGGER_ACTION(dump_str); | ||||||
|  | 
 | ||||||
|  |         if (seg_idx < JTEST_STR_MAX_OUTPUT_SEGMENTS) | ||||||
|  |         { | ||||||
|  |             memmove_idx = 0; | ||||||
|  |             while (memmove_idx < (seg_cnt - seg_idx -1) ) | ||||||
|  |             { | ||||||
|  |                 memmove( | ||||||
|  |                     JTEST_FW.str_buffer+ | ||||||
|  |                     (memmove_idx* JTEST_STR_MAX_OUTPUT_SIZE), | ||||||
|  |                     JTEST_FW.str_buffer+ | ||||||
|  |                     ((memmove_idx+1)*JTEST_STR_MAX_OUTPUT_SIZE), | ||||||
|  |                     JTEST_BUF_SIZE); | ||||||
|  |                 ++memmove_idx; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return; | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | #include "../inc/jtest.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Define Global Variables */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | char JTEST_FW_STR_BUFFER[JTEST_BUF_SIZE] = {0}; | ||||||
|  | 
 | ||||||
|  | volatile JTEST_FW_t JTEST_FW = {0}; | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | 
 | ||||||
|  | #include "jtest_fw.h" | ||||||
|  | 
 | ||||||
|  | void test_start    (void) { | ||||||
|  | //  ;
 | ||||||
|  |   JTEST_FW.test_start++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void test_end      (void) { | ||||||
|  | //  ;
 | ||||||
|  |   JTEST_FW.test_end++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void group_start   (void) { | ||||||
|  | //  ;
 | ||||||
|  |   JTEST_FW.group_start++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void group_end     (void) { | ||||||
|  | //  ;
 | ||||||
|  |   JTEST_FW.group_end++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dump_str      (void) { | ||||||
|  | //  ;
 | ||||||
|  |   JTEST_FW.dump_str++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dump_data     (void) { | ||||||
|  | //  ;
 | ||||||
|  |   JTEST_FW.dump_data++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void exit_fw       (void) { | ||||||
|  | //  ;
 | ||||||
|  |   JTEST_FW.exit_fw++; | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | #ifndef _ALL_TESTS_H_ | ||||||
|  | #define _ALL_TESTS_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Declare Test Groups */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | JTEST_DECLARE_GROUP(all_tests); | ||||||
|  | 
 | ||||||
|  | #endif /* _ALL_TESTS_H_ */ | ||||||
| @ -0,0 +1,267 @@ | |||||||
|  | #ifndef _BASIC_MATH_TEMPLATES_H_ | ||||||
|  | #define _BASIC_MATH_TEMPLATES_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | #include "test_templates.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Group Specific Templates */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare the outputs used by basic math tests for the function under test and | ||||||
|  |  *  the reference function. | ||||||
|  |  */ | ||||||
|  | #define BASIC_MATH_COMPARE_INTERFACE(block_size, output_type)   \ | ||||||
|  |     TEST_ASSERT_BUFFERS_EQUAL(                                  \ | ||||||
|  |         basic_math_output_ref.data_ptr,                         \ | ||||||
|  |         basic_math_output_fut.data_ptr,                         \ | ||||||
|  |         block_size * sizeof(output_type)) | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Comparison SNR thresholds for the data types used in basic_math_tests. | ||||||
|  |  */ | ||||||
|  | #define BASIC_MATH_SNR_THRESHOLD_float32_t 120 | ||||||
|  | #define BASIC_MATH_SNR_THRESHOLD_q31_t 100 | ||||||
|  | #define BASIC_MATH_SNR_THRESHOLD_q15_t 75 | ||||||
|  | #define BASIC_MATH_SNR_THRESHOLD_q7_t 25 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare reference and fut outputs using SNR. | ||||||
|  |  * | ||||||
|  |  *  @note The outputs are converted to float32_t before comparison. | ||||||
|  |  */ | ||||||
|  | #define BASIC_MATH_SNR_COMPARE_INTERFACE(block_size, output_type)   \ | ||||||
|  |     do                                                              \ | ||||||
|  |     {                                                               \ | ||||||
|  |         TEST_CONVERT_AND_ASSERT_SNR(                                \ | ||||||
|  |             basic_math_output_f32_ref,                              \ | ||||||
|  |             basic_math_output_ref.data_ptr,                         \ | ||||||
|  |             basic_math_output_f32_fut,                              \ | ||||||
|  |             basic_math_output_fut.data_ptr,                         \ | ||||||
|  |             block_size,                                             \ | ||||||
|  |             output_type,                                            \ | ||||||
|  |             BASIC_MATH_SNR_THRESHOLD_##output_type                  \ | ||||||
|  |             );                                                      \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare reference and fut outputs using SNR. | ||||||
|  |  * | ||||||
|  |  *  @note The outputs are converted to float32_t before comparison. | ||||||
|  |  */ | ||||||
|  | #define BASIC_MATH_SNR_ELT1_COMPARE_INTERFACE(block_size, output_type)  \ | ||||||
|  |     do                                                                  \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         TEST_CONVERT_AND_ASSERT_SNR(                                    \ | ||||||
|  |             basic_math_output_f32_ref,                                  \ | ||||||
|  |             basic_math_output_ref.data_ptr,                             \ | ||||||
|  |             basic_math_output_f32_fut,                                  \ | ||||||
|  |             basic_math_output_fut.data_ptr,                             \ | ||||||
|  |             1,                                                          \ | ||||||
|  |             output_type,                                                \ | ||||||
|  |             BASIC_MATH_SNR_THRESHOLD_##output_type                      \ | ||||||
|  |             );                                                          \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Input Interfaces */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /*
 | ||||||
|  |  *  General: | ||||||
|  |  *  Input interfaces provide inputs to functions inside test templates.  They | ||||||
|  |  *  ONLY provide the inputs.  The output variables should be hard coded. | ||||||
|  |  * | ||||||
|  |  *  The input interfaces must have the following format: | ||||||
|  |  * | ||||||
|  |  *  ARM_xxx_INPUT_INTERFACE() or | ||||||
|  |  *  REF_xxx_INPUT_INTERFACE() | ||||||
|  |  * | ||||||
|  |  *  The xxx must be lowercase, and is intended to be the indentifying substring | ||||||
|  |  *  in the function's name.  Acceptable values are 'sub' or 'add' from the | ||||||
|  |  *  functions arm_add_q31. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define ARM_abs_INPUT_INTERFACE(input, block_size)              \ | ||||||
|  |     PAREN(input, basic_math_output_fut.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define REF_abs_INPUT_INTERFACE(input, block_size)              \ | ||||||
|  |     PAREN(input, basic_math_output_ref.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define ARM_add_INPUT_INTERFACE(input_a, input_b, block_size)           \ | ||||||
|  |     PAREN(input_a, input_b, basic_math_output_fut.data_ptr, block_size) \ | ||||||
|  | 
 | ||||||
|  | #define REF_add_INPUT_INTERFACE(input_a, input_b, block_size)           \ | ||||||
|  |     PAREN(input_a, input_b, basic_math_output_ref.data_ptr, block_size) \ | ||||||
|  | 
 | ||||||
|  | #define ARM_dot_prod_INPUT_INTERFACE(input_a, input_b, block_size)      \ | ||||||
|  |     PAREN(input_a, input_b, block_size, basic_math_output_fut.data_ptr) \ | ||||||
|  | 
 | ||||||
|  | #define REF_dot_prod_INPUT_INTERFACE(input_a, input_b, block_size)      \ | ||||||
|  |     PAREN(input_a, input_b, block_size, basic_math_output_ref.data_ptr) \ | ||||||
|  | 
 | ||||||
|  | #define ARM_mult_INPUT_INTERFACE(input_a, input_b, block_size)          \ | ||||||
|  |     PAREN(input_a, input_b, basic_math_output_fut.data_ptr, block_size) \ | ||||||
|  | 
 | ||||||
|  | #define REF_mult_INPUT_INTERFACE(input_a, input_b, block_size)          \ | ||||||
|  |     PAREN(input_a, input_b, basic_math_output_ref.data_ptr, block_size) \ | ||||||
|  | 
 | ||||||
|  | #define ARM_negate_INPUT_INTERFACE(input, block_size)           \ | ||||||
|  |     PAREN(input, basic_math_output_fut.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define REF_negate_INPUT_INTERFACE(input, block_size)           \ | ||||||
|  |     PAREN(input, basic_math_output_ref.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define ARM_offset_INPUT_INTERFACE(input, elt, block_size)          \ | ||||||
|  |     PAREN(input, elt, basic_math_output_fut.data_ptr, block_size)   \ | ||||||
|  | 
 | ||||||
|  | #define REF_offset_INPUT_INTERFACE(input, elt, block_size)          \ | ||||||
|  |     PAREN(input, elt, basic_math_output_ref.data_ptr, block_size)   \ | ||||||
|  | 
 | ||||||
|  | #define ARM_shift_INPUT_INTERFACE(input, elt, block_size)           \ | ||||||
|  |     PAREN(input, elt, basic_math_output_fut.data_ptr, block_size)   \ | ||||||
|  | 
 | ||||||
|  | #define REF_shift_INPUT_INTERFACE(input, elt, block_size)           \ | ||||||
|  |     PAREN(input, elt, basic_math_output_ref.data_ptr, block_size)   \ | ||||||
|  | 
 | ||||||
|  | #define ARM_scale_float_INPUT_INTERFACE(input, elt, block_size)     \ | ||||||
|  |     PAREN(input, elt, basic_math_output_fut.data_ptr, block_size)   \ | ||||||
|  | 
 | ||||||
|  | #define REF_scale_float_INPUT_INTERFACE(input, elt, block_size)     \ | ||||||
|  |     PAREN(input, elt, basic_math_output_ref.data_ptr, block_size)   \ | ||||||
|  | 
 | ||||||
|  | /* These two are for the fixed point functions */ | ||||||
|  | #define ARM_scale_INPUT_INTERFACE(input, elt1, elt2, block_size)        \ | ||||||
|  |     PAREN(input, elt1, elt2, basic_math_output_fut.data_ptr, block_size) \ | ||||||
|  | 
 | ||||||
|  | #define REF_scale_INPUT_INTERFACE(input, elt1, elt2, block_size)        \ | ||||||
|  |     PAREN(input, elt1, elt2, basic_math_output_ref.data_ptr, block_size) \ | ||||||
|  | 
 | ||||||
|  | #define ARM_sub_INPUT_INTERFACE(input_a, input_b, block_size)           \ | ||||||
|  |     PAREN(input_a, input_b, basic_math_output_fut.data_ptr, block_size) \ | ||||||
|  | 
 | ||||||
|  | #define REF_sub_INPUT_INTERFACE(input_a, input_b, block_size)           \ | ||||||
|  |     PAREN(input_a, input_b, basic_math_output_ref.data_ptr, block_size) \ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Test Templates */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of #TEST_TEMPLATE_BUF1_BLK() for basic math tests. | ||||||
|  |  * | ||||||
|  |  *  @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and | ||||||
|  |  *  REF_xxx_INPUT_INTERFACEs. | ||||||
|  |  */ | ||||||
|  | #define BASIC_MATH_DEFINE_TEST_TEMPLATE_BUF1_BLK(fn_name,       \ | ||||||
|  |                                                  suffix,        \ | ||||||
|  |                                                  input_type,    \ | ||||||
|  |                                                  output_type)   \ | ||||||
|  |     JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test,          \ | ||||||
|  |                       arm_##fn_name##_##suffix)                 \ | ||||||
|  |     {                                                           \ | ||||||
|  |         TEST_TEMPLATE_BUF1_BLK(                                 \ | ||||||
|  |             basic_math_f_all,                                   \ | ||||||
|  |             basic_math_block_sizes,                             \ | ||||||
|  |             input_type,                                         \ | ||||||
|  |             output_type,                                        \ | ||||||
|  |             arm_##fn_name##_##suffix,                           \ | ||||||
|  |             ARM_##fn_name##_INPUT_INTERFACE,                    \ | ||||||
|  |             ref_##fn_name##_##suffix,                           \ | ||||||
|  |             REF_##fn_name##_INPUT_INTERFACE,                    \ | ||||||
|  |             BASIC_MATH_COMPARE_INTERFACE);                      \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of #TEST_TEMPLATE_BUF2_BLK() for basic math tests. | ||||||
|  |  * | ||||||
|  |  *  @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and | ||||||
|  |  *  REF_xxx_INPUT_INTERFACEs. | ||||||
|  |  */ | ||||||
|  | #define BASIC_MATH_DEFINE_TEST_TEMPLATE_BUF2_BLK(fn_name,               \ | ||||||
|  |                                                  suffix,                \ | ||||||
|  |                                                  input_type,            \ | ||||||
|  |                                                  output_type,           \ | ||||||
|  |                                                  comparison_interface)  \ | ||||||
|  |     JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test,                  \ | ||||||
|  |                       arm_##fn_name##_##suffix)                         \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         TEST_TEMPLATE_BUF2_BLK(                                         \ | ||||||
|  |             basic_math_f_all,                                           \ | ||||||
|  |             basic_math_f_all,                                           \ | ||||||
|  |             basic_math_block_sizes,                                     \ | ||||||
|  |             input_type,                                                 \ | ||||||
|  |             output_type,                                                \ | ||||||
|  |             arm_##fn_name##_##suffix,                                   \ | ||||||
|  |             ARM_##fn_name##_INPUT_INTERFACE,                            \ | ||||||
|  |             ref_##fn_name##_##suffix,                                   \ | ||||||
|  |             REF_##fn_name##_INPUT_INTERFACE,                            \ | ||||||
|  |             comparison_interface);                                      \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of #TEST_TEMPLATE_BUF1_ELT1_BLK() for basic math tests. | ||||||
|  |  * | ||||||
|  |  *  @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and | ||||||
|  |  *  REF_xxx_INPUT_INTERFACEs. | ||||||
|  |  */ | ||||||
|  | #define BASIC_MATH_DEFINE_TEST_TEMPLATE_BUF1_ELT1_BLK(fn_name,      \ | ||||||
|  |                                                       suffix,       \ | ||||||
|  |                                                       input_type,   \ | ||||||
|  |                                                       elt_type,     \ | ||||||
|  |                                                       output_type)  \ | ||||||
|  |     JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test,              \ | ||||||
|  |                       arm_##fn_name##_##suffix)                     \ | ||||||
|  |     {                                                               \ | ||||||
|  |         TEST_TEMPLATE_BUF1_ELT1_BLK(                                \ | ||||||
|  |             basic_math_f_all,                                       \ | ||||||
|  |             basic_math_elts,                                        \ | ||||||
|  |             basic_math_block_sizes,                                 \ | ||||||
|  |             input_type,                                             \ | ||||||
|  |             elt_type,                                               \ | ||||||
|  |             output_type,                                            \ | ||||||
|  |             arm_##fn_name##_##suffix,                               \ | ||||||
|  |             ARM_##fn_name##_INPUT_INTERFACE,                        \ | ||||||
|  |             ref_##fn_name##_##suffix,                               \ | ||||||
|  |             REF_##fn_name##_INPUT_INTERFACE,                        \ | ||||||
|  |             BASIC_MATH_COMPARE_INTERFACE);                          \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of #TEST_TEMPLATE_BUF1_ELT2_BLK() for basic math tests. | ||||||
|  |  * | ||||||
|  |  *  @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and | ||||||
|  |  *  REF_xxx_INPUT_INTERFACEs. | ||||||
|  |  */ | ||||||
|  | #define BASIC_MATH_DEFINE_TEST_TEMPLATE_BUF1_ELT2_BLK(fn_name,      \ | ||||||
|  |                                                       suffix,       \ | ||||||
|  |                                                       input_type,   \ | ||||||
|  |                                                       elt1_type,    \ | ||||||
|  |                                                       elt2_type,    \ | ||||||
|  |                                                       output_type)  \ | ||||||
|  |     JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test,              \ | ||||||
|  |                       arm_##fn_name##_##suffix)                     \ | ||||||
|  |     {                                                               \ | ||||||
|  |         TEST_TEMPLATE_BUF1_ELT2_BLK(                                \ | ||||||
|  |             basic_math_f_all,                                       \ | ||||||
|  |             basic_math_elts,                                        \ | ||||||
|  |             basic_math_elts2,                                       \ | ||||||
|  |             basic_math_block_sizes,                                 \ | ||||||
|  |             input_type,                                             \ | ||||||
|  |             elt1_type,                                              \ | ||||||
|  |             elt2_type,                                              \ | ||||||
|  |             output_type,                                            \ | ||||||
|  |             arm_##fn_name##_##suffix,                               \ | ||||||
|  |             ARM_##fn_name##_INPUT_INTERFACE,                        \ | ||||||
|  |             ref_##fn_name##_##suffix,                               \ | ||||||
|  |             REF_##fn_name##_INPUT_INTERFACE,                        \ | ||||||
|  |             BASIC_MATH_COMPARE_INTERFACE);                          \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | #endif /* _BASIC_MATH_TEMPLATES_H_ */ | ||||||
| @ -0,0 +1,46 @@ | |||||||
|  | #ifndef ARM_BASIC_MATH_TEST_DATA_H | ||||||
|  | #define ARM_BASIC_MATH_TEST_DATA_H | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "arr_desc.h" | ||||||
|  | #include "arm_math.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | #define BASIC_MATH_MAX_INPUT_ELEMENTS 32 | ||||||
|  | #define BASIC_MATH_BIGGEST_INPUT_TYPE float32_t | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Declare Variables */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* Input/Output Buffers */ | ||||||
|  | ARR_DESC_DECLARE(basic_math_output_fut); | ||||||
|  | ARR_DESC_DECLARE(basic_math_output_ref); | ||||||
|  | 
 | ||||||
|  | extern BASIC_MATH_BIGGEST_INPUT_TYPE | ||||||
|  | basic_math_output_f32_ref[BASIC_MATH_MAX_INPUT_ELEMENTS]; | ||||||
|  | 
 | ||||||
|  | extern BASIC_MATH_BIGGEST_INPUT_TYPE | ||||||
|  | basic_math_output_f32_fut[BASIC_MATH_MAX_INPUT_ELEMENTS]; | ||||||
|  | 
 | ||||||
|  | /* Block Sizes*/ | ||||||
|  | ARR_DESC_DECLARE(basic_math_block_sizes); | ||||||
|  | 
 | ||||||
|  | /* Numbers */ | ||||||
|  | ARR_DESC_DECLARE(basic_math_elts); | ||||||
|  | ARR_DESC_DECLARE(basic_math_elts2); | ||||||
|  | ARR_DESC_DECLARE(basic_math_eltsf); | ||||||
|  | 
 | ||||||
|  | /* Float Inputs */ | ||||||
|  | ARR_DESC_DECLARE(basic_math_zeros); | ||||||
|  | ARR_DESC_DECLARE(basic_math_f_2); | ||||||
|  | ARR_DESC_DECLARE(basic_math_f_15); | ||||||
|  | ARR_DESC_DECLARE(basic_math_f_32); | ||||||
|  | ARR_DESC_DECLARE(basic_math_f_all); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | #ifndef _BASIC_MATH_TEST_GROUP_H_ | ||||||
|  | #define _BASIC_MATH_TEST_GROUP_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Declare Test Groups */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | JTEST_DECLARE_GROUP(basic_math_tests); | ||||||
|  | 
 | ||||||
|  | #endif /* _BASIC_MATH_TEST_GROUP_H_ */ | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | #ifndef _BASIC_MATH_TESTS_H_ | ||||||
|  | #define _BASIC_MATH_TESTS_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Test/Group Declarations */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | JTEST_DECLARE_GROUP(abs_tests); | ||||||
|  | JTEST_DECLARE_GROUP(add_tests); | ||||||
|  | JTEST_DECLARE_GROUP(dot_prod_tests); | ||||||
|  | JTEST_DECLARE_GROUP(mult_tests); | ||||||
|  | JTEST_DECLARE_GROUP(negate_tests); | ||||||
|  | JTEST_DECLARE_GROUP(offset_tests); | ||||||
|  | JTEST_DECLARE_GROUP(scale_tests); | ||||||
|  | JTEST_DECLARE_GROUP(shift_tests); | ||||||
|  | JTEST_DECLARE_GROUP(sub_tests); | ||||||
|  | 
 | ||||||
|  | #endif /* _BASIC_MATH_TESTS_H_ */ | ||||||
| @ -0,0 +1,222 @@ | |||||||
|  | #ifndef _COMPLEX_MATH_TEMPLATES_H_ | ||||||
|  | #define _COMPLEX_MATH_TEMPLATES_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | #include "test_templates.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Group Specific Templates */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare the real outputs from the function under test and the reference | ||||||
|  |  *  function. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_COMPARE_RE_INTERFACE(block_size, output_type)  \ | ||||||
|  |     TEST_ASSERT_BUFFERS_EQUAL(                                      \ | ||||||
|  |         complex_math_output_ref_a.data_ptr,                         \ | ||||||
|  |         complex_math_output_fut_a.data_ptr,                         \ | ||||||
|  |         block_size * sizeof(output_type)) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare the real and imaginary outputs from the function under test and the | ||||||
|  |  *  reference function. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_COMPARE_CMPLX_INTERFACE(block_size, output_type)   \ | ||||||
|  |     do                                                                  \ | ||||||
|  |     {                                                                   \ | ||||||
|  |         COMPLEX_MATH_COMPARE_RE_INTERFACE(block_size * 2, output_type); \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Comparison SNR thresholds for the data types used in complex_math_tests. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_SNR_THRESHOLD_float32_t 120 | ||||||
|  | #define COMPLEX_MATH_SNR_THRESHOLD_q31_t 100 | ||||||
|  | #define COMPLEX_MATH_SNR_THRESHOLD_q15_t 75 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare reference and fut outputs using SNR. | ||||||
|  |  * | ||||||
|  |  *  The output_suffix specifies which output buffers to use for the | ||||||
|  |  *  comparison. An output_suffix of 'a' expands to the following buffers: | ||||||
|  |  * | ||||||
|  |  *  - complex_math_output_f32_ref_a | ||||||
|  |  *  - complex_math_output_f32_fut_a | ||||||
|  |  *  - complex_math_output_ref_a | ||||||
|  |  *  - complex_math_output_fut_a | ||||||
|  |  * | ||||||
|  |  *  @note The outputs are converted to float32_t before comparison. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size,      \ | ||||||
|  |                                                output_type,     \ | ||||||
|  |                                                output_suffix)   \ | ||||||
|  |     do                                                          \ | ||||||
|  |     {                                                           \ | ||||||
|  |         TEST_CONVERT_AND_ASSERT_SNR(                            \ | ||||||
|  |             complex_math_output_f32_ref_##output_suffix,        \ | ||||||
|  |             complex_math_output_ref_##output_suffix.data_ptr,   \ | ||||||
|  |             complex_math_output_f32_fut_##output_suffix,        \ | ||||||
|  |             complex_math_output_fut_##output_suffix.data_ptr,   \ | ||||||
|  |             block_size,                                         \ | ||||||
|  |             output_type,                                        \ | ||||||
|  |             COMPLEX_MATH_SNR_THRESHOLD_##output_type            \ | ||||||
|  |             );                                                  \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specification of #COMPLEX_MATH_SNR_COMPARE_INTERFACE() for real outputs. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_SNR_COMPARE_RE_INTERFACE(block_size,       \ | ||||||
|  |                                                    output_type) \ | ||||||
|  |     COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size,          \ | ||||||
|  |                                            output_type,         \ | ||||||
|  |                                            a) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specification of #COMPLEX_MATH_SNR_COMPARE_INTERFACE() for complex outputs. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_SNR_COMPARE_CMPLX_INTERFACE(block_size,    \ | ||||||
|  |                                                  output_type)   \ | ||||||
|  |         COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size * 2,  \ | ||||||
|  |                                                output_type,     \ | ||||||
|  |                                                a) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare reference and fut split outputs using SNR. | ||||||
|  |  * | ||||||
|  |  *  'Split' refers to two separate output buffers; one for real and one for | ||||||
|  |  *  complex. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_SNR_COMPARE_SPLIT_INTERFACE(block_size,    \ | ||||||
|  |                                                  output_type)   \ | ||||||
|  |         do                                                      \ | ||||||
|  |         {                                                       \ | ||||||
|  |             COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size,  \ | ||||||
|  |                                                    output_type, \ | ||||||
|  |                                                    a);          \ | ||||||
|  |             COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size,  \ | ||||||
|  |                                                    output_type, \ | ||||||
|  |                                                    b);          \ | ||||||
|  |         } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Input Interfaces */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /*
 | ||||||
|  |  *  General: | ||||||
|  |  *  Input interfaces provide inputs to functions inside test templates.  They | ||||||
|  |  *  ONLY provide the inputs.  The output variables should be hard coded. | ||||||
|  |  * | ||||||
|  |  *  The input interfaces must have the following format: | ||||||
|  |  * | ||||||
|  |  *  ARM_xxx_INPUT_INTERFACE() or | ||||||
|  |  *  REF_xxx_INPUT_INTERFACE() | ||||||
|  |  * | ||||||
|  |  *  The xxx must be lowercase, and is intended to be the indentifying substring | ||||||
|  |  *  in the function's name.  Acceptable values are 'sub' or 'add' from the | ||||||
|  |  *  functions arm_add_q31. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define ARM_cmplx_conj_INPUT_INTERFACE(input, block_size)           \ | ||||||
|  |     PAREN(input, complex_math_output_fut_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define REF_cmplx_conj_INPUT_INTERFACE(input, block_size)           \ | ||||||
|  |     PAREN(input, complex_math_output_ref_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define ARM_cmplx_dot_prod_INPUT_INTERFACE(input_a, input_b, block_size) \ | ||||||
|  |     PAREN(input_a, input_b, block_size,                                 \ | ||||||
|  |           complex_math_output_fut_a.data_ptr,                          \ | ||||||
|  |           complex_math_output_fut_b.data_ptr) | ||||||
|  | 
 | ||||||
|  | #define REF_cmplx_dot_prod_INPUT_INTERFACE(input_a, input_b, block_size) \ | ||||||
|  |     PAREN(input_a, input_b, block_size,                                 \ | ||||||
|  |           complex_math_output_ref_a.data_ptr,                          \ | ||||||
|  |           complex_math_output_ref_b.data_ptr) | ||||||
|  | 
 | ||||||
|  | #define ARM_cmplx_mag_INPUT_INTERFACE(input, block_size)            \ | ||||||
|  |     PAREN(input, complex_math_output_fut_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define REF_cmplx_mag_INPUT_INTERFACE(input, block_size)            \ | ||||||
|  |     PAREN(input, complex_math_output_ref_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define ARM_cmplx_mag_squared_INPUT_INTERFACE(input, block_size)    \ | ||||||
|  |     PAREN(input, complex_math_output_fut_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define REF_cmplx_mag_squared_INPUT_INTERFACE(input, block_size)    \ | ||||||
|  |     PAREN(input, complex_math_output_ref_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define ARM_cmplx_mult_cmplx_INPUT_INTERFACE(input_a, input_b, block_size) \ | ||||||
|  |     PAREN(input_a, input_b, complex_math_output_fut_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define REF_cmplx_mult_cmplx_INPUT_INTERFACE(input_a, input_b, block_size) \ | ||||||
|  |     PAREN(input_a, input_b, complex_math_output_ref_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define ARM_cmplx_mult_real_INPUT_INTERFACE(input_a, input_b, block_size) \ | ||||||
|  |     PAREN(input_a, input_b, complex_math_output_fut_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | #define REF_cmplx_mult_real_INPUT_INTERFACE(input_a, input_b, block_size) \ | ||||||
|  |     PAREN(input_a, input_b, complex_math_output_ref_a.data_ptr, block_size) | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Test Templates */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of #TEST_TEMPLATE_BUF1_BLK() for complex math tests. | ||||||
|  |  * | ||||||
|  |  *  @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and | ||||||
|  |  *  REF_xxx_INPUT_INTERFACEs. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_DEFINE_TEST_TEMPLATE_BUF1_BLK(fn_name,         \ | ||||||
|  |                                                    suffix,          \ | ||||||
|  |                                                    input_type,      \ | ||||||
|  |                                                    output_type,     \ | ||||||
|  |                                                    comparison_interface) \ | ||||||
|  |     JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test,              \ | ||||||
|  |                       arm_##fn_name##_##suffix)                     \ | ||||||
|  |     {                                                               \ | ||||||
|  |         TEST_TEMPLATE_BUF1_BLK(                                     \ | ||||||
|  |             complex_math_f_all,                                     \ | ||||||
|  |             complex_math_block_sizes,                               \ | ||||||
|  |             input_type,                                             \ | ||||||
|  |             output_type,                                            \ | ||||||
|  |             arm_##fn_name##_##suffix,                               \ | ||||||
|  |             ARM_##fn_name##_INPUT_INTERFACE,                        \ | ||||||
|  |             ref_##fn_name##_##suffix,                               \ | ||||||
|  |             REF_##fn_name##_INPUT_INTERFACE,                        \ | ||||||
|  |             comparison_interface);                                  \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Specialization of #TEST_TEMPLATE_BUF2_BLK1() for complex math tests. | ||||||
|  |  * | ||||||
|  |  *  @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and | ||||||
|  |  *  REF_xxx_INPUT_INTERFACEs. | ||||||
|  |  */ | ||||||
|  | #define COMPLEX_MATH_DEFINE_TEST_TEMPLATE_BUF2_BLK(fn_name,         \ | ||||||
|  |                                                    suffix,          \ | ||||||
|  |                                                    input_type,      \ | ||||||
|  |                                                    output_type,     \ | ||||||
|  |                                                    comparison_interface) \ | ||||||
|  |     JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test,              \ | ||||||
|  |                       arm_##fn_name##_##suffix)                     \ | ||||||
|  |     {                                                               \ | ||||||
|  |         TEST_TEMPLATE_BUF2_BLK(                                     \ | ||||||
|  |             complex_math_f_all,                                     \ | ||||||
|  |             complex_math_f_all,                                     \ | ||||||
|  |             complex_math_block_sizes,                               \ | ||||||
|  |             input_type,                                             \ | ||||||
|  |             output_type,                                            \ | ||||||
|  |             arm_##fn_name##_##suffix,                               \ | ||||||
|  |             ARM_##fn_name##_INPUT_INTERFACE,                        \ | ||||||
|  |             ref_##fn_name##_##suffix,                               \ | ||||||
|  |             REF_##fn_name##_INPUT_INTERFACE,                        \ | ||||||
|  |             comparison_interface);                                  \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | #endif /* _COMPLEX_MATH_TEMPLATES_H_ */ | ||||||
| @ -0,0 +1,50 @@ | |||||||
|  | #ifndef _COMPLEX_MATH_TEST_DATA_H_ | ||||||
|  | #define _COMPLEX_MATH_TEST_DATA_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "arr_desc.h" | ||||||
|  | #include "arm_math.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | #define COMPLEX_MATH_MAX_INPUT_ELEMENTS 32 | ||||||
|  | #define COMPLEX_MATH_BIGGEST_INPUT_TYPE float32_t | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Decalare Variables */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* Input/Output Buffers */ | ||||||
|  | ARR_DESC_DECLARE(complex_math_output_fut_a); | ||||||
|  | ARR_DESC_DECLARE(complex_math_output_fut_b); | ||||||
|  | ARR_DESC_DECLARE(complex_math_output_ref_a); | ||||||
|  | ARR_DESC_DECLARE(complex_math_output_ref_b); | ||||||
|  | 
 | ||||||
|  | extern COMPLEX_MATH_BIGGEST_INPUT_TYPE | ||||||
|  | complex_math_output_f32_ref_a[COMPLEX_MATH_MAX_INPUT_ELEMENTS * 2]; | ||||||
|  | 
 | ||||||
|  | extern COMPLEX_MATH_BIGGEST_INPUT_TYPE | ||||||
|  | complex_math_output_f32_ref_b[COMPLEX_MATH_MAX_INPUT_ELEMENTS * 2]; | ||||||
|  | 
 | ||||||
|  | extern COMPLEX_MATH_BIGGEST_INPUT_TYPE | ||||||
|  | complex_math_output_f32_fut_a[COMPLEX_MATH_MAX_INPUT_ELEMENTS * 2]; | ||||||
|  | 
 | ||||||
|  | extern COMPLEX_MATH_BIGGEST_INPUT_TYPE | ||||||
|  | complex_math_output_f32_fut_b[COMPLEX_MATH_MAX_INPUT_ELEMENTS * 2]; | ||||||
|  | 
 | ||||||
|  | /* Block Sizes*/ | ||||||
|  | ARR_DESC_DECLARE(complex_math_block_sizes); | ||||||
|  | 
 | ||||||
|  | /* Float Inputs */ | ||||||
|  | ARR_DESC_DECLARE(complex_math_zeros); | ||||||
|  | ARR_DESC_DECLARE(complex_math_f_2); | ||||||
|  | ARR_DESC_DECLARE(complex_math_f_15); | ||||||
|  | ARR_DESC_DECLARE(complex_math_f_32); | ||||||
|  | ARR_DESC_DECLARE(complex_math_f_all); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* _COMPLEX_MATH_TEST_DATA_H_ */ | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | #ifndef _COMPLEX_MATH_TEST_GROUP_H_ | ||||||
|  | #define _COMPLEX_MATH_TEST_GROUP_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Declare Test Groups */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | JTEST_DECLARE_GROUP(complex_math_tests); | ||||||
|  | 
 | ||||||
|  | #endif /* _COMPLEX_MATH_TEST_GROUP_H_ */ | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | #ifndef _COMPLEX_MATH_TESTS_H_ | ||||||
|  | #define _COMPLEX_MATH_TESTS_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Test/Group Declarations */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | JTEST_DECLARE_GROUP(cmplx_conj_tests); | ||||||
|  | JTEST_DECLARE_GROUP(cmplx_dot_prod_tests); | ||||||
|  | JTEST_DECLARE_GROUP(cmplx_mag_tests); | ||||||
|  | JTEST_DECLARE_GROUP(cmplx_mag_squared_tests); | ||||||
|  | JTEST_DECLARE_GROUP(cmplx_mult_cmplx_tests); | ||||||
|  | JTEST_DECLARE_GROUP(cmplx_mult_real_tests); | ||||||
|  | 
 | ||||||
|  | #endif /* _COMPLEX_MATH_TESTS_H_ */ | ||||||
| @ -0,0 +1,46 @@ | |||||||
|  | #ifndef _CONTROLLER_TEMPLATES_H_ | ||||||
|  | #define _CONTROLLER_TEMPLATES_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "test_templates.h" | ||||||
|  | #include <string.h>             /* memcpy() */ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Group Specific Templates */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Comparison SNR thresholds for the data types used in transform_tests. | ||||||
|  |  */ | ||||||
|  | #define CONTROLLER_SNR_THRESHOLD_float32_t 110 | ||||||
|  | #define CONTROLLER_SNR_THRESHOLD_q31_t     100 | ||||||
|  | #define CONTROLLER_SNR_THRESHOLD_q15_t     45 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare the outputs from the function under test and the reference | ||||||
|  |  *  function using SNR. | ||||||
|  |  */ | ||||||
|  | #define CONTROLLER_SNR_COMPARE_INTERFACE(block_size,    \ | ||||||
|  |                                          output_type)   \ | ||||||
|  |     do                                                  \ | ||||||
|  |     {                                                   \ | ||||||
|  |         TEST_CONVERT_AND_ASSERT_SNR(                    \ | ||||||
|  |             controller_output_f32_ref,                  \ | ||||||
|  |             (output_type *) controller_output_ref,      \ | ||||||
|  |             controller_output_f32_fut,                  \ | ||||||
|  |             (output_type *) controller_output_fut,      \ | ||||||
|  |             block_size,                                 \ | ||||||
|  |             output_type,                                \ | ||||||
|  |             CONTROLLER_SNR_THRESHOLD_##output_type      \ | ||||||
|  |             );                                          \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* TEST Templates */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #endif /* _CONTROLLER_TEMPLATES_H_ */ | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | #ifndef _CONTROLLER_TEST_DATA_H_ | ||||||
|  | #define _CONTROLLER_TEST_DATA_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "arm_math.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #define CONTROLLER_MAX_LEN 1024 | ||||||
|  | #define CONTROLLER_MAX_COEFFS_LEN (12 * 3) | ||||||
|  | #define TRANFORM_BIGGEST_INPUT_TYPE float32_t | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Variable Declarations */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | extern float32_t controller_output_fut[CONTROLLER_MAX_LEN]; | ||||||
|  | extern float32_t controller_output_ref[CONTROLLER_MAX_LEN]; | ||||||
|  | extern float32_t controller_output_f32_fut[CONTROLLER_MAX_LEN]; | ||||||
|  | extern float32_t controller_output_f32_ref[CONTROLLER_MAX_LEN]; | ||||||
|  | extern const float32_t controller_f32_inputs[CONTROLLER_MAX_LEN]; | ||||||
|  | extern const q31_t controller_q31_inputs[CONTROLLER_MAX_LEN]; | ||||||
|  | extern const q15_t * controller_q15_inputs; | ||||||
|  | extern const float32_t controller_f32_coeffs[CONTROLLER_MAX_COEFFS_LEN]; | ||||||
|  | extern const q31_t controller_q31_coeffs[CONTROLLER_MAX_COEFFS_LEN]; | ||||||
|  | extern const q15_t controller_q15_coeffs[CONTROLLER_MAX_COEFFS_LEN]; | ||||||
|  | 
 | ||||||
|  | #endif /* _CONTROLLER_TEST_DATA_H_ */ | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | #ifndef _CONTROLLER_TEST_GROUP_H_ | ||||||
|  | #define _CONTROLLER_TEST_GROUP_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Declare Test Group */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | JTEST_DECLARE_GROUP(controller_tests); | ||||||
|  | 
 | ||||||
|  | #endif /* _CONTROLLER_TEST_GROUP_H_ */ | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | #ifndef _CONTROLLER_TESTS_H_ | ||||||
|  | #define _CONTROLLER_TESTS_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Test/Group Declarations */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | JTEST_DECLARE_GROUP(pid_reset_tests); | ||||||
|  | JTEST_DECLARE_GROUP(sin_cos_tests); | ||||||
|  | JTEST_DECLARE_GROUP(pid_tests); | ||||||
|  | 
 | ||||||
|  | #endif /* _CONTROLLER_TESTS_H_ */ | ||||||
| @ -0,0 +1,102 @@ | |||||||
|  | #ifndef _FAST_MATH_TEMPLATES_H_ | ||||||
|  | #define _FAST_MATH_TEMPLATES_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "test_templates.h" | ||||||
|  | #include <string.h>             /* memcpy() */ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Group Specific Templates */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Comparison SNR thresholds for the data types used in transform_tests. | ||||||
|  |  */ | ||||||
|  | #define FAST_MATH_SNR_THRESHOLD_float32_t 95 | ||||||
|  | #define FAST_MATH_SNR_THRESHOLD_q31_t     95 | ||||||
|  | #define FAST_MATH_SNR_THRESHOLD_q15_t     45 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  Compare the outputs from the function under test and the reference | ||||||
|  |  *  function using SNR. | ||||||
|  |  */ | ||||||
|  | #define FAST_MATH_SNR_COMPARE_INTERFACE(block_size,     \ | ||||||
|  |                                         output_type)    \ | ||||||
|  |     do                                                  \ | ||||||
|  |     {                                                   \ | ||||||
|  |         TEST_CONVERT_AND_ASSERT_SNR(                    \ | ||||||
|  |             fast_math_output_f32_ref,                   \ | ||||||
|  |             (output_type *) fast_math_output_ref,       \ | ||||||
|  |             fast_math_output_f32_fut,                   \ | ||||||
|  |             (output_type *) fast_math_output_fut,       \ | ||||||
|  |             block_size,                                 \ | ||||||
|  |             output_type,                                \ | ||||||
|  |             FAST_MATH_SNR_THRESHOLD_##output_type       \ | ||||||
|  |             );                                          \ | ||||||
|  |     } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* TEST Templates */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #define SQRT_TEST_TEMPLATE_ELT1(suffix)                             \ | ||||||
|  |                                                                     \ | ||||||
|  |     JTEST_DEFINE_TEST(arm_sqrt_##suffix##_test, arm_sqrt_##suffix)  \ | ||||||
|  |     {                                                               \ | ||||||
|  |         uint32_t i;                                                 \ | ||||||
|  |                                                                     \ | ||||||
|  |         JTEST_COUNT_CYCLES(                                         \ | ||||||
|  |             for(i=0;i<FAST_MATH_MAX_LEN;i++)                        \ | ||||||
|  |             {                                                       \ | ||||||
|  |                 arm_sqrt_##suffix(                                  \ | ||||||
|  |                     (suffix##_t)fast_math_##suffix##_inputs[i]      \ | ||||||
|  |                     ,(suffix##_t*)fast_math_output_fut + i);        \ | ||||||
|  |             });                                                     \ | ||||||
|  |                                                                     \ | ||||||
|  |         for(i=0;i<FAST_MATH_MAX_LEN;i++)                            \ | ||||||
|  |         {                                                           \ | ||||||
|  |             ref_sqrt_##suffix(                                      \ | ||||||
|  |                 (suffix##_t)fast_math_##suffix##_inputs[i]          \ | ||||||
|  |                 ,(suffix##_t*)fast_math_output_ref + i);            \ | ||||||
|  |         }                                                           \ | ||||||
|  |                                                                     \ | ||||||
|  |         FAST_MATH_SNR_COMPARE_INTERFACE(                            \ | ||||||
|  |             FAST_MATH_MAX_LEN,                                      \ | ||||||
|  |             suffix##_t);                                            \ | ||||||
|  |                                                                     \ | ||||||
|  |         return JTEST_TEST_PASSED;                                   \ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define SIN_COS_TEST_TEMPLATE_ELT1(suffix, type, func)                  \ | ||||||
|  |                                                                         \ | ||||||
|  |         JTEST_DEFINE_TEST(arm_##func##_##suffix##_test, arm_##func##_##suffix) \ | ||||||
|  |         {                                                               \ | ||||||
|  |             uint32_t i;                                                 \ | ||||||
|  |                                                                         \ | ||||||
|  |             JTEST_COUNT_CYCLES(                                         \ | ||||||
|  |                 for(i=0;i<FAST_MATH_MAX_LEN;i++)                        \ | ||||||
|  |                 {                                                       \ | ||||||
|  |                     *((type*)fast_math_output_fut + i) = arm_##func##_##suffix( \ | ||||||
|  |                         fast_math_##suffix##_inputs[i]);                \ | ||||||
|  |                 });                                                     \ | ||||||
|  |                                                                         \ | ||||||
|  |             JTEST_COUNT_CYCLES(                                         \ | ||||||
|  |                 for(i=0;i<FAST_MATH_MAX_LEN;i++)                        \ | ||||||
|  |                 {                                                       \ | ||||||
|  |                     *((type*)fast_math_output_ref + i) = ref_##func##_##suffix( \ | ||||||
|  |                         fast_math_##suffix##_inputs[i]);                \ | ||||||
|  |                 });                                                     \ | ||||||
|  |                                                                         \ | ||||||
|  |             FAST_MATH_SNR_COMPARE_INTERFACE(                            \ | ||||||
|  |                 FAST_MATH_MAX_LEN,                                      \ | ||||||
|  |                 type);                                                  \ | ||||||
|  |                                                                         \ | ||||||
|  |             return JTEST_TEST_PASSED;                                   \ | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | #endif /* _FAST_MATH_TEMPLATES_H_ */ | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | #ifndef _FAST_MATH_TEST_DATA_H_ | ||||||
|  | #define _FAST_MATH_TEST_DATA_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Includes */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include "arm_math.h" | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Macros and Defines */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #define FAST_MATH_MAX_LEN 1024 | ||||||
|  | #define TRANFORM_BIGGEST_INPUT_TYPE float32_t | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Variable Declarations */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | extern float32_t fast_math_output_fut[FAST_MATH_MAX_LEN]; | ||||||
|  | extern float32_t fast_math_output_ref[FAST_MATH_MAX_LEN]; | ||||||
|  | extern float32_t fast_math_output_f32_fut[FAST_MATH_MAX_LEN]; | ||||||
|  | extern float32_t fast_math_output_f32_ref[FAST_MATH_MAX_LEN]; | ||||||
|  | extern const float32_t fast_math_f32_inputs[FAST_MATH_MAX_LEN]; | ||||||
|  | extern const q31_t fast_math_q31_inputs[FAST_MATH_MAX_LEN]; | ||||||
|  | extern const q15_t * fast_math_q15_inputs; | ||||||
|  | 
 | ||||||
|  | #endif /* _FAST_MATH_TEST_DATA_H_ */ | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | #ifndef _FAST_MATH_TEST_GROUP_H_ | ||||||
|  | #define _FAST_MATH_TEST_GROUP_H_ | ||||||
|  | 
 | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | /* Declare Test Groups */ | ||||||
|  | /*--------------------------------------------------------------------------------*/ | ||||||
|  | JTEST_DECLARE_GROUP(fast_math_tests); | ||||||
|  | 
 | ||||||
|  | #endif /* _FAST_MATH_TEST_GROUP_H_ */ | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 coreglitch
						coreglitch