kopia lustrzana https://github.com/piotr022/UV_K5_playground
				
				
				
			fix for spectrum scanner, added possibility to switch center freq and peak printing
							rodzic
							
								
									fc0a057248
								
							
						
					
					
						commit
						94ce3e5059
					
				|  | @ -6,15 +6,14 @@ sbar with calibrated S steps | |||
| * flash with original quansheng update tool | ||||
| 
 | ||||
| Please, consider paying tribute to the two fallen Quashengs that were bricked during the development process. Their sacrifice played a crucial role in shaping this project. To show your appreciation and support for our ongoing work, you can make a [donation](https://paypal.me/sq9p). | ||||
| 
 | ||||
| ## src/spectrum  | ||||
|    | ||||
| It's still in beta. It prints a spectrum graph that covers +/- 1 MHz from the center frequency. Overall, it prints 2 MHz of the band. | ||||
| Spectrum scanner. It prints a spectrum graph that covers +/- 1 MHz from the center frequency. Prints center frequency, and frequency with highest amplitude. | ||||
| 
 | ||||
| * download mod [uv_k5_01_26_spectrum_2MHz_encoded.bin](https://github.com/piotr022/UV_K5_playground/releases/latest) | ||||
| * to enable spectum view press flash light button | ||||
| * (optional) turn down the volume | ||||
| * to disable, power off radio xD   | ||||
| * use *up* and *down* key to change center frequency | ||||
| * press PTT to disable spectrum view | ||||
| 
 | ||||
| ## src/rssi_printer  | ||||
|    | ||||
|  |  | |||
										
											Plik binarny nie jest wyświetlany.
										
									
								
							| Przed Szerokość: | Wysokość: | Rozmiar: 190 KiB Po Szerokość: | Wysokość: | Rozmiar: 53 KiB | 
|  | @ -4,6 +4,18 @@ namespace System | |||
|    using VoidFxPointer = void(*)(void); | ||||
|    static constexpr auto CortexM0VectorsCnt = 16+32; | ||||
| 
 | ||||
|    struct TCortexM0Stacking | ||||
|    { | ||||
|       unsigned int R0; | ||||
|       unsigned int R1; | ||||
|       unsigned int R2; | ||||
|       unsigned int R3; | ||||
|       unsigned int R12; | ||||
|       unsigned int LR; | ||||
|       unsigned int PC; | ||||
|       unsigned int xPSR; | ||||
|    }; | ||||
| 
 | ||||
|    struct TVectorTable | ||||
|    { | ||||
|       VoidFxPointer Vectors[CortexM0VectorsCnt]; | ||||
|  |  | |||
|  | @ -201,24 +201,71 @@ public: | |||
|       memset(U8NumBuff, 0, sizeof(U8NumBuff)); | ||||
| 
 | ||||
|       char *pString = U8NumBuff + u8Digts; | ||||
|       *pString = '\0';                     | ||||
|       *pString = '\0'; | ||||
| 
 | ||||
|       if (s32Number < 0) | ||||
|       { | ||||
|          U8NumBuff[0] = '-'; | ||||
|          s32Number = -s32Number;  | ||||
|          s32Number = -s32Number; | ||||
|       } | ||||
| 
 | ||||
|       while (u8Digts--) | ||||
|       { | ||||
|          *--pString = '0' + (s32Number % 10);  | ||||
|          s32Number /= 10;                      | ||||
|          *--pString = '0' + (s32Number % 10); | ||||
|          s32Number /= 10; | ||||
|       } | ||||
| 
 | ||||
|       Print(U8NumBuff); | ||||
|       return u8Digts * pCurrentFont->GetSizeX('0'); | ||||
|    } | ||||
| 
 | ||||
|    static constexpr int powersOfTen[9] = { | ||||
|        1,        // 10^0
 | ||||
|        10,       // 10^1
 | ||||
|        100,      // 10^2
 | ||||
|        1000,     // 10^3
 | ||||
|        10000,    // 10^4
 | ||||
|        100000,   // 10^5
 | ||||
|        1000000,  // 10^6
 | ||||
|        10000000, // 10^7
 | ||||
|        100000000 // 10^8
 | ||||
|    }; | ||||
|    void PrintFixedDigitsNumber2(int s32Number) | ||||
|    { | ||||
|       char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator
 | ||||
|       int startIdx = 0; | ||||
|       bool isNegative = false; | ||||
| 
 | ||||
|       if (s32Number < 0) | ||||
|       { | ||||
|          U8NumBuff[0] = '-'; | ||||
|          s32Number = -s32Number; | ||||
|          isNegative = true; | ||||
|       } | ||||
| 
 | ||||
|       for (int i = 8; i >= 2; --i) // assuming powersOfTen is an array of powers of 10
 | ||||
|       { | ||||
|          int digit = 0; | ||||
|          while (s32Number >= powersOfTen[i]) | ||||
|          { | ||||
|             s32Number -= powersOfTen[i]; | ||||
|             ++digit; | ||||
|          } | ||||
|          U8NumBuff[isNegative + (8 - i)] = '0' + digit; | ||||
| 
 | ||||
|          // We found the first non-zero digit
 | ||||
|          if (digit != 0 && startIdx == (isNegative ? 1 : 0)) | ||||
|             startIdx = isNegative + (8 - i); | ||||
|       } | ||||
| 
 | ||||
|       // If the number was 0, we write a single 0.
 | ||||
|       if (startIdx == (isNegative ? 1 : 0)) | ||||
|          U8NumBuff[isNegative] = '0'; | ||||
| 
 | ||||
|       // Print the string from the start index
 | ||||
|       Print(U8NumBuff + startIdx); | ||||
|    } | ||||
| 
 | ||||
| private: | ||||
|    const BitmapType &Bitmap; | ||||
|    mutable const IFont *pCurrentFont; | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ int main() | |||
| { | ||||
|    System::JumpToOrginalFw(); | ||||
|    return 0; | ||||
| }  | ||||
| } | ||||
| 
 | ||||
| void MultiIrq_Handler(unsigned int u32IrqSource) | ||||
| { | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ void MultiIrq_Handler(unsigned int u32IrqSource) | |||
|    } | ||||
| 
 | ||||
|    static unsigned int u32StupidCounter = 1; | ||||
|    if((!(u32StupidCounter++ % 15) && u32StupidCounter > 200)) // exit key
 | ||||
|    if((!(u32StupidCounter++ % 10) && u32StupidCounter > 200)) // exit key
 | ||||
|    { | ||||
|       CRssiPrinter::Handle(Fw, FwData); | ||||
|    } | ||||
|  |  | |||
|  | @ -154,6 +154,7 @@ public: | |||
|       Display.SetCoursor(3, 5 * 7 + 8); | ||||
|       Display.Print(C8SignalString); | ||||
| 
 | ||||
|       u8BlocksToFill = u8BlocksToFill > 13 ? 13 : u8BlocksToFill; | ||||
|       for (unsigned char i = 0; i < u8BlocksToFill; i++) | ||||
|       { | ||||
|          unsigned char u8BlockHeight = i + 1 > BlockSizeY ? BlockSizeY : i + 1; | ||||
|  | @ -161,11 +162,7 @@ public: | |||
|          Display.DrawRectangle(u8X, 24 + BlockSizeY - u8BlockHeight, BlockSizeX, | ||||
|                                u8BlockHeight, i < LinearBlocksCnt); | ||||
|       } | ||||
|       // Turn the proper pixel on, and the ones below it on as well
 | ||||
|       // The code to turn just the correct pixel on is: U8ScreenHistory[u8ChartPosition - ChartStartX] = (1 << u8PrintShift) & 0xFF;
 | ||||
|       // U8ScreenHistory[u8ChartPosition - ChartStartX] = ~(0xFF >> (7 - u8PrintShift));
 | ||||
| 
 | ||||
|       // memcpy(pDData, FwData.pSmallLeters, 256 * 2);
 | ||||
|       Fw.FlushFramebufferToScreen(); | ||||
|    } | ||||
| }; | ||||
|  | @ -19,6 +19,10 @@ int main() | |||
| 
 | ||||
| void MultiIrq_Handler(unsigned int u32IrqSource) | ||||
| { | ||||
|    unsigned int u32Dummy; | ||||
|    System::TCortexM0Stacking* pStackedRegs =  | ||||
|       (System::TCortexM0Stacking*)(((unsigned int*)&u32Dummy) + 1); | ||||
| 
 | ||||
|    static bool bFirstInit = false; | ||||
|    if(!bFirstInit) | ||||
|    { | ||||
|  | @ -27,8 +31,11 @@ void MultiIrq_Handler(unsigned int u32IrqSource) | |||
|       bFirstInit = true; | ||||
|    } | ||||
| 
 | ||||
|    bool bPreventWhileKeypadPolling = pStackedRegs->LR > (unsigned int)Fw.PollKeyboard &&  | ||||
|       pStackedRegs->PC < (unsigned int)Fw.PollKeyboard + 0x100; // i made a mistake and compared PC and LR, but this works fine xD
 | ||||
| 
 | ||||
|    static unsigned int u32StupidCounter = 1; | ||||
|    if(u32StupidCounter++ > 200) | ||||
|    if(u32StupidCounter++ > 200 && !bPreventWhileKeypadPolling) | ||||
|    { | ||||
|       Spectrum.Handle(); | ||||
|    } | ||||
|  |  | |||
|  | @ -28,18 +28,24 @@ public: | |||
|    static constexpr auto StepSizeFreq = 10'000; | ||||
|    static constexpr unsigned char EnableKey = 13; | ||||
|    static constexpr auto DrawingSize = TUV_K5Display::SizeX * 2; | ||||
|    static constexpr auto DrawingSizeY = 16; | ||||
|    static constexpr auto DrawingEndY = 32; | ||||
|    static constexpr auto DrawingSizeY = 16 + 4 * 8; | ||||
|    static constexpr auto DrawingEndY = 57; | ||||
|    static constexpr auto LabelsCnt = 6; | ||||
|    static constexpr auto PressDuration = 30; | ||||
|    CSpectrum() | ||||
|        : DisplayBuff(FwData.pDisplayBuffer), | ||||
|          FontSmallNr(FwData.pSmallDigs), | ||||
|          Display(DisplayBuff), | ||||
|          bDisplayCleared(true){}; | ||||
|          bDisplayCleared(true), | ||||
|          u8PressCnt(0), | ||||
|          bEnabled(0) | ||||
|    { | ||||
|       Display.SetFont(&FontSmallNr); | ||||
|    }; | ||||
| 
 | ||||
|    void Handle() | ||||
|    { | ||||
|       if ((GPIOA->DATA & ((1 << 0xA) | (1 << 0xB) | (1 << 0xC) | (1 << 0xD))) || !(GPIOC->DATA & 0b1)) | ||||
|       if (!(GPIOC->DATA & 0b1)) | ||||
|       { | ||||
|          return; | ||||
|       } | ||||
|  | @ -66,23 +72,53 @@ public: | |||
|       } | ||||
| 
 | ||||
|       bDisplayCleared = false; | ||||
|       if (u8LastBtnPressed == 11) // up
 | ||||
|       { | ||||
|          u32OldFreq += 100_KHz; | ||||
|       } | ||||
|       else if (u8LastBtnPressed == 12) // down
 | ||||
|       { | ||||
|          u32OldFreq -= 100_KHz; | ||||
|       } | ||||
| 
 | ||||
|       ClearDrawings(); | ||||
| 
 | ||||
|       unsigned int u32Peak; | ||||
|       unsigned char u8MaxRssi = 0; | ||||
|       unsigned char u8PeakPos; | ||||
|       for (unsigned char u8Pos = 0; u8Pos < DisplayBuff.SizeX; u8Pos++) | ||||
|       { | ||||
|          if (!(u8Pos % (DisplayBuff.SizeX / LabelsCnt))) | ||||
|          { | ||||
|             Display.DrawHLine(16, 18, u8Pos); | ||||
|             Display.DrawHLine(10, 15, u8Pos); | ||||
|          } | ||||
| 
 | ||||
|          auto const FreqOffset = u8Pos * ScanRange / (DisplayBuff.SizeX - 1); | ||||
|          auto const Rssi = GetRssi(u32OldFreq - (ScanRange / 2) + FreqOffset); | ||||
|          signed char u8Sub = ((Rssi * 120) >> 7) - 12; | ||||
|          auto const FreqOffset = (u8Pos * ScanRange) >> 7; | ||||
|          auto const Rssi = GetRssi(u32OldFreq - (ScanRange >> 1) + FreqOffset); | ||||
|          signed char u8Sub = ((Rssi * 200) >> 7) - 20; | ||||
|          u8Sub = (u8Sub > DrawingSizeY ? DrawingSizeY : u8Sub); | ||||
|          u8Sub = (u8Sub < 0 ? 0 : u8Sub); | ||||
|          Display.DrawHLine(DrawingEndY - u8Sub, DrawingEndY, u8Pos); | ||||
| 
 | ||||
|          if (Rssi > u8MaxRssi) | ||||
|          { | ||||
|             u8MaxRssi = Rssi; | ||||
|             u8PeakPos = u8Pos; | ||||
|             u32Peak = u32OldFreq - (ScanRange >> 1) + FreqOffset; | ||||
|          } | ||||
|       } | ||||
| 
 | ||||
|       // Display.DrawRectangle(0,0, 7, 7, 0);
 | ||||
|       memcpy(FwData.pDisplayBuffer + 8 * 2 + 10 * 6, FwData.pSmallLeters + 18 + 5, 7); | ||||
|       Display.SetCoursor(0, 0); | ||||
|       Display.PrintFixedDigitsNumber2(u32OldFreq); | ||||
| 
 | ||||
|       // Display.DrawRectangle(8*2 + 10*6,0, 7, 7, 0);
 | ||||
|       Display.SetCoursor(0, 8 * 2 + 10 * 7); | ||||
|       Display.PrintFixedDigitsNumber2(u32Peak); | ||||
| 
 | ||||
|       memcpy(FwData.pDisplayBuffer + 128 * 2 + u8PeakPos - 3, FwData.pSmallLeters + 18 + 5, 7); | ||||
| 
 | ||||
|       Fw.FlushFramebufferToScreen(); | ||||
|    } | ||||
| 
 | ||||
|  | @ -112,24 +148,43 @@ private: | |||
| 
 | ||||
|    bool FreeToDraw() | ||||
|    { | ||||
|       bool bLedKey = GPIOA->DATA & GPIO_PIN_3; // Fw.PollKeyboard(); keyboard polling causes many problems probably it disrupt main fw polling procedure
 | ||||
|       auto *pMenuCheckData = (unsigned char *)DisplayBuff.GetCoursorData( | ||||
|           DisplayBuff.GetCoursorPosition(1, 6 * 8 + 1)); | ||||
| 
 | ||||
|       unsigned char u8Keyboard = 0; | ||||
|       if (bLedKey) | ||||
|       bool bFlashlight = (GPIOC->DATA & GPIO_PIN_3); | ||||
|       if (bFlashlight) | ||||
|       { | ||||
|          u8Keyboard = Fw.PollKeyboard(); | ||||
|          bEnabled = true; | ||||
|          GPIOC->DATA &= ~GPIO_PIN_3; | ||||
|       } | ||||
| 
 | ||||
|       return bLedKey && *pMenuCheckData != 0xFF && u8Keyboard != EnableKey; | ||||
|       bool bPtt = !(GPIOC->DATA & GPIO_PIN_5); | ||||
|       if(bPtt) | ||||
|       { | ||||
|          bEnabled = false; | ||||
|       } | ||||
| 
 | ||||
|       if(bEnabled) | ||||
|       { | ||||
|          u8LastBtnPressed = Fw.PollKeyboard(); | ||||
|       } | ||||
| 
 | ||||
|          // u8LastBtnPressed = Fw.PollKeyboard();
 | ||||
|          // if (u8LastBtnPressed == EnableKey)
 | ||||
|          // {
 | ||||
|          //    u8PressCnt++;
 | ||||
|          // }
 | ||||
| 
 | ||||
|          // if (u8PressCnt > (bEnabled ? 3 : PressDuration))
 | ||||
|          // {
 | ||||
|          //    u8PressCnt = 0;
 | ||||
|          //    bEnabled = !bEnabled;
 | ||||
|          // }
 | ||||
|        | ||||
| 
 | ||||
|       return bEnabled; | ||||
|    } | ||||
| 
 | ||||
|    void ClearDrawings() | ||||
|    { | ||||
|       auto *p8Drw = (unsigned char *)DisplayBuff.GetCoursorData( | ||||
|           DisplayBuff.GetCoursorPosition(2, 0)); | ||||
|       memset(p8Drw, 0, DrawingSize); | ||||
|       memset(FwData.pDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY); | ||||
|    } | ||||
| 
 | ||||
|    TUV_K5Display DisplayBuff; | ||||
|  | @ -139,4 +194,7 @@ private: | |||
| 
 | ||||
|    unsigned int u32OldFreq; | ||||
|    unsigned short u16OldAfSettings; | ||||
|    unsigned char u8PressCnt; | ||||
|    bool bEnabled; | ||||
|    unsigned char u8LastBtnPressed; | ||||
| }; | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Piotr Lewandowski
						Piotr Lewandowski