From bee5e7f049a0599b336d7e78ca7b248d912f9b86 Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Wed, 17 Mar 2021 22:56:24 +0100 Subject: [PATCH] hardware divider eabi library --- inc/display.h | 13 ++++--- lib/armlib/c2_p.l | Bin 0 -> 2336 bytes lib/armlib/libattrs.map | 44 +++++++++++++++++++++ src/ST7735S.c | 20 +++++----- src/devices.c | 8 +--- src/display.c | 18 ++++++--- src/div.s | 79 ++++++++++++++++++++++++++++++++++++++ src/events.c | 4 +- src/init.c | 2 + src/main.c | 5 +-- src/screens.c | 2 +- src/screens/screen_main.c | 6 +-- 12 files changed, 162 insertions(+), 39 deletions(-) create mode 100644 lib/armlib/c2_p.l create mode 100644 lib/armlib/libattrs.map create mode 100644 src/div.s diff --git a/inc/display.h b/inc/display.h index b3dd3ce..508a0a6 100644 --- a/inc/display.h +++ b/inc/display.h @@ -30,14 +30,12 @@ typedef struct display void (*CLS)( void ); void (*SetBrightness)( uint32_t b ); void (*SetFont)( const font_t* ); - void (*Print)( const char*, const rect_t* ); + void (*Print)( const char*, const rect_t*, unsigned align ); } display_t; extern const display_t *display; - - extern const display_t ST7735S; extern DISPLAY_STATUS display_status; @@ -45,9 +43,12 @@ extern DISPLAY_STATUS display_status; extern uint16_t fgcolor; extern uint16_t bgcolor; -extern void SetDisplay( const display_t *d ); -extern void SetDisplayStatus( uint32_t status ); -extern DISPLAY_STATUS GetDisplayStatus( void ); + +extern void DMStartup(); +extern void DMSetStatus( DISPLAY_STATUS status ); +extern DISPLAY_STATUS DMGetStatus(); + extern void FormatNumber( char *str, uint32_t num, int nbdig, int nbdec, int exp ); + #endif /* __DISPLAY_H__ */ diff --git a/lib/armlib/c2_p.l b/lib/armlib/c2_p.l new file mode 100644 index 0000000000000000000000000000000000000000..05680d35d8ad2b95d3c279862a754a0d4a9c8d00 GIT binary patch literal 2336 zcmbtV&u`;Y5PnXY*6p_4wjji^E96}nX(hIH+#hMTYEjcP-G(OJQa1&OBG<8<){w-J z?L>=IEg->d4+tS~;KG3;e+4HbBqVP92^?981GnVz9Ui;Iy%J`u~N|P1|6>xuPMdDnnKWT zd7)C!jAi902wH239k%VLt$eubx+|-0KK~IrIjL{e_mAo)O)m_doVZ^9#P-hoi0}S7 z9~sMtM2S4n{3LkDz-L}dmatJW<14r%Wya1E*&;c{*cS=@Dv{qM^7}+?LuT1sj7Z$* z6h@Iier0UTFU`}K%fO9gUzOe<%8uV6k;#mXVwDC9ollN9mPxZxR(?yqEze4G(hQ=^ zXe`SCjG#RD5|l-*9OrE&T};nSVda=KmKn>+BXUk2mB(aR9+xNN8)K95^dJ>{F$PKt zF%d~B#8q$x-*}xQV%be_HNg-=^jivzu;-V*rZC;)7vQTzrz%Ooe3svGu;7Se9GK9L z9P?!H8Hyu|Hu*WR-{Dwd#|a*Y=a(BPJd6G3fhnJKzqyRWXdV9$3BCzA1*W@`oos}O z2*1!;>FOFbrJGdLo@JrBEtIk5dX3(hWj7k3*VhcT)$?0!F^)sO(TlxERgZRSR>ds# z7i+4i7T2l^3+e}JRl`tCXq9rgY^YBw@2hpQY#tZXr{>XKX>WS~R{(db>SObuSSqXK zt>UVBa9B21)pBvG(qCX&>^+H@>M}KE|FZ*=o}8cO*HIvS`^<`Z-EQbb(Z<7viv}j0 zZf~O$ggAD-mIrPE@1xtH+Fd8w(4(LkH@nJwpy@&5WBw!r%6z4?rq?4cjPxDqZ@t*< zZrib~R|Cgx>BX?EAK1<(k-p#S2XWAWtocqDSlc@Xx}hyt&%*x|^>$rSKQZdU%MP+$$ z@t$&>I#zsu;^5CSlkP#yUEP+APL88%Z%KEuZ;mJ#9LHXP14-!ylo4qft<1FOJc`5E zZZHid&AuuGra3{ojdu|)i9_^hn>&VHE2*MpXtzB!R8lBKZ1l29)2`RGa7UKHey15E z)q&9dBRzv3^$5M0MD!n^o)SbqGNRAHqR$8)fT^bi3EKrG#>FJ$-{4I!^&@pZ?MJUd z7cAC5WlI3`CI}L?7ADgBUBE!=X+PRa>}Nus1q=Ez<(Kv?!-4Nj!GN9tC|ny1+y<52 zO`((JCjffW1PL4ED;*zQQo$UZNpXt!sKk;Zp}_~>FG#8)5#J1S6+HOALIKSH{4r4Z qD9*hNBy=+T3BUE!givXJm?+(xRQwAz6P<+cBbh$eh2J+X@%tAy6LUoX literal 0 HcmV?d00001 diff --git a/lib/armlib/libattrs.map b/lib/armlib/libattrs.map new file mode 100644 index 0000000..c47d98b --- /dev/null +++ b/lib/armlib/libattrs.map @@ -0,0 +1,44 @@ +# libattrs.map +# +# This file defines the mapping from library names to the +# attributes assumed for that library by the linker. It is for +# internal use only. Modification by users is likely to produce +# unanticipated results. +# +# Copyright 2004 ARM Limited. All rights reserved. +# +# RCS $Revision$ +# Checkin $Date$ +# Revising $Author$ + +# Attributes in the library suffix. +*_4*.* $IEEE1$ARM_ISAv4 +*_t*.* $IEEE1$ARM_ISAv4$THUMB_ISAv1 +*_5*.* $IEEE1$ARM_ISAv5$THUMB_ISAv1 +*_w*.* $IEEE1$THUMB_ISAv4$D +*_p*.* $IEEE1$THM_ISAv3M +*_2*.* $IEEE1$THUMB_ISAv4$ARM_ISAv7 +*_8*.* $IEEE1$ARM_ISAv8$THUMB_ISAv5$DE$MPE$B$J$K +*_o*.* $IEEE1$A64_ISAv8 +*_*e*.* $IEEE1$RWPI +*_*f*.* $IEEE1$~SHL$FPIC +*_*s*.* $IEEE1$PE +*_*v*.* $IEEE1$VFPv1 +*_*m*.* $IEEE1$VFPi1$EXTD16$VFPS +*_*n*.* $IEEE1$ENUMINT +*_*u*.* $IEEE1$WCHAR32 +*_r*.* $IEEE1$A64_ISAv8$SIGN_RET_ADDR +*_a*.* $IEEE1$A64_ISAv8$SIGN_RET_ADDR$TAGGED_STACK + +# Sets of library prefixes which denote the same library set and +# vary the attributes. +fz_* $IEEE1$STANDARDLIB +g_* $IEEE1$STANDARDLIB$IEEEX fz +f_* $IEEE1$STANDARDLIB$IEEEF fz +fj_* $IEEE1$STANDARDLIB$IEEEJ fz +mf_* $IEEE1$MICROLIB fz + +c2_* $IEEE1$STANDARDLIB +c_* $IEEE1$STANDARDLIB +mc_* $IEEE1$MICROLIB c + diff --git a/src/ST7735S.c b/src/ST7735S.c index 68d7556..0ef3392 100644 --- a/src/ST7735S.c +++ b/src/ST7735S.c @@ -219,7 +219,7 @@ static void Close( void ) static void Sleep( void ) { send_cmd_byte( 0x10 ); - SetDisplayStatus( DISPLAY_SLEEPING ); + DMSetStatus( DISPLAY_SLEEPING ); } static void Wakeup( void ) @@ -227,7 +227,7 @@ static void Wakeup( void ) send_cmd_byte( 0x11 ); if ( display_status == DISPLAY_SLEEPING ) - TMCreateTask( 120, SetDisplayStatus, DISPLAY_ON, 0, 0, 0 ); + TMCreateTask( 120, (void(*)(uint32_t))DMSetStatus, DISPLAY_ON, 0, 0, 0 ); } static void Reset( void ) @@ -338,7 +338,7 @@ static int draw_char( const uint16_t c, int x, int y ) return cw; } -static void Print( const char *str, const rect_t *r ) +static void Print( const char *str, const rect_t *r, unsigned align ) { if ( !font ) return; @@ -363,12 +363,12 @@ void rainbow( void ) for ( int l = 0 ; l < 160 ; ++l ) { - g = HDIV_Div( 64 * l, 160 ); + g = 64 * l / 160; for ( int c = 0 ; c < 80 ; ++c ) { - r = HDIV_Div( 32 * c, 80 ); - b = HDIV_Div( 32 * ( c + l ), 240 ) ^ 0x1F; + r = 32 * c / 80; + b = ( 32 * ( c + l ) / 240 ) ^ 0x1F; uint32_t c = b << 11 | g << 5 | r; send_data_word( c ); @@ -385,7 +385,7 @@ void rainbow( void ) static uint8_t startup_task_id; -void startup_task( uint32_t step ) +static void startup_task( uint32_t step ) { switch ( step ) { @@ -407,19 +407,19 @@ void startup_task( uint32_t step ) case 3: Init(); TMDestroyTask( startup_task_id ); - SetDisplayStatus( DISPLAY_ON ); + DMSetStatus( DISPLAY_ON ); break; } } -void Startup( void ) +static void Startup( void ) { if ( startup_task_id ) { TMDestroyTask( startup_task_id ); } - SetDisplayStatus( DISPLAY_OFF ); + DMSetStatus( DISPLAY_OFF ); TMCreateTask( 0, startup_task, 0, 1, 120, &startup_task_id ); } diff --git a/src/devices.c b/src/devices.c index a079245..e8b2ee4 100644 --- a/src/devices.c +++ b/src/devices.c @@ -210,12 +210,6 @@ void ConfigureADC() } -void ConfigureHDIV() -{ - CLK_EnableModuleClock( HDIV_MODULE ); -} - - uint32_t ADCSample( uint32_t ch, int count ) { uint32_t sample; @@ -231,6 +225,6 @@ uint32_t ADCSample( uint32_t ch, int count ) sample += ADC_GET_CONVERSION_DATA( ADC, ch ); } - sample = HDIV_Div( sample, count ); + sample = sample / count; return sample; } diff --git a/src/display.c b/src/display.c index 165678e..b63676a 100644 --- a/src/display.c +++ b/src/display.c @@ -16,22 +16,28 @@ uint16_t bgcolor; //------------------------------------------------------------------------------ -// Inform the display manager of the display we'll use. +// Display startup. //------------------------------------------------------------------------------ -void SetDisplay( const display_t *d ) +// Initializes the display global variable and calls the startup process. +//------------------------------------------------------------------------------ +void DMStartup() { - display = d; + display = &ST7735S; + display->Startup(); } -void SetDisplayStatus( uint32_t status ) +//------------------------------------------------------------------------------ +// Display status change +//------------------------------------------------------------------------------ +void DMSetStatus( DISPLAY_STATUS status ) { display_status = status; EMSendEvent1P( EVENT_DISPLAY, EV_D_DISPLAY_STATUS, status ); } -DISPLAY_STATUS GetDisplayStatus( void ) +DISPLAY_STATUS DMGetStatus( void ) { return display_status; } @@ -60,7 +66,7 @@ void FormatNumber( char *str, uint32_t num, int nbdig, int nbdec, int exp ) while ( num ) { - num = HDIV_Div( num, 10 ); + num /= 10; uint16_t rem = HDIV->DIVREM; buf[idx++] = '0' + rem; } diff --git a/src/div.s b/src/div.s new file mode 100644 index 0000000..d8d817c --- /dev/null +++ b/src/div.s @@ -0,0 +1,79 @@ +; /***************************************************************************** +; * +; * Replacement for aeabi standard division functions +; * Using the NUC126 hardware divider +; * +; *****************************************************************************/ + + AREA |.text|, CODE, READONLY + +HDIV EQU 0x50014000 + + +; Signed division using the hardware divider. +; ~20 cycles + + ALIGN +__aeabi_idivmod PROC + ROUT + EXPORT __aeabi_idivmod + + LDR R2, = HDIV + STR R0, [ R2, #0 ] + STR R1, [ R2, #4 ] + LDR R0, [ R2, #8 ] + LDR R1, [ R2, #12 ] + BX LR + + ENDP + + ALIGN +__aeabi_idiv PROC + ROUT + EXPORT __aeabi_idiv + + LDR R2, = HDIV + STR R0, [ R2, #0 ] + STR R1, [ R2, #4 ] + LDR R0, [ R2, #8 ] + BX LR + + ENDP + + +; Unsigned divisions are just signed divisions, +; assuming that divisor and dividend never exceed 2^31-1. +; That's lazy but good enough. + +__aeabi_uidivmod EQU __aeabi_idivmod + EXPORT __aeabi_uidivmod + +__aeabi_uidiv EQU __aeabi_idiv + EXPORT __aeabi_uidiv + + +; Just in case + + IF {FALSE} + ALIGN +__aeabi_uidivmod PROC + ROUT + EXPORT __aeabi_uidivmod + + B __aeabi_idivmod + + ENDP + + ALIGN +__aeabi_uidiv PROC + ROUT + EXPORT __aeabi_uidiv + + B __aeabi_idiv + + ENDP + ENDIF + + ALIGN + + END diff --git a/src/events.c b/src/events.c index 99c95ec..e8d84f1 100644 --- a/src/events.c +++ b/src/events.c @@ -13,11 +13,11 @@ static uint8_t embuffer[ 20 * sizeof( Event_t ) ]; // For debugging pruposes static void PrintEvent( const Event_t *ev ) { - if ( GetDisplayStatus() != DISPLAY_ON ) return; + if ( DMGetStatus() != DISPLAY_ON ) return; rect_t r = { 11, 150, 79, 159 }; char buf[12]; snprintf( buf, sizeof( buf ), "%02X %02X %02X %02X", ev->type, ev->k, ev->p1, ev->p2 ); - display->Print( buf, &r ); + display->Print( buf, &r, 0 ); } diff --git a/src/init.c b/src/init.c index d3304f5..ec28da4 100644 --- a/src/init.c +++ b/src/init.c @@ -64,6 +64,8 @@ void SystemInit( void ) SYS_UnlockReg(); SYS_DISABLE_POR(); + CLK_EnableModuleClock( HDIV_MODULE ); + CLK_EnableXtalRC( CLK_PWRCTL_HIRCEN_Msk ); CLK_WaitClockReady( CLK_STATUS_HIRCSTB_Msk ); CLK_SetHCLK( CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1) ); diff --git a/src/main.c b/src/main.c index ddc6638..a7382d7 100644 --- a/src/main.c +++ b/src/main.c @@ -13,7 +13,6 @@ void StartupDevices( void ) ConfigureADC(); ConfigurePWM1(); ConfigureSPI0(); - ConfigureHDIV(); } @@ -71,9 +70,7 @@ int main( void ) EMStartup(); BMStartup(); SMStartup(); - - SetDisplay( &ST7735S ); - display->Startup(); + DMStartup(); while ( 1 ) { diff --git a/src/screens.c b/src/screens.c index 35182e5..3047762 100644 --- a/src/screens.c +++ b/src/screens.c @@ -139,7 +139,7 @@ void SMShowScreen( SCREENID sid ) //------------------------------------------------------------------------------ void SMRefresh( void ) { - if ( GetDisplayStatus() != DISPLAY_ON ) return; + if ( DMGetStatus() != DISPLAY_ON ) return; uint32_t t = GetSysTick(); diff --git a/src/screens/screen_main.c b/src/screens/screen_main.c index be52a45..cefbf0f 100644 --- a/src/screens/screen_main.c +++ b/src/screens/screen_main.c @@ -38,17 +38,17 @@ extern int ScrMainRefresh( void ) BMGetCells( &vbat1, &vbat2 ); FormatNumber( buf, vbat1, 4, 3, 3 ); - display->Print( buf, &r ); + display->Print( buf, &r, 0 ); FormatNumber( buf, vbat2, 4, 3, 3 ); r.left = 33; - display->Print( buf, &r ); + display->Print( buf, &r, 0 ); BATT_STATUS bs = BMGetStatus(); if ( bs != BATT_UNK ) { r.left = 66; - display->Print( bs == BATT_OK ? "OK" : "LO" , &r ); + display->Print( bs == BATT_OK ? "OK" : "LO" , &r, 0 ); } }