Просмотр исходного кода

Revert "upd fm radio" due to broken UI

This reverts commit 835091e98810897213b3086651b3c1204e1a325a.
MX 2 лет назад
Родитель
Сommit
0efd06ad1b

+ 64 - 69
non_catalog_apps/fm_radio_controller/TEA5767/TEA5767.c

@@ -42,19 +42,21 @@ bool tea5767_is_device_ready() {
 }
 
 bool tea5767_read_registers(uint8_t* buffer) {
-    if(buffer == NULL) return false;
+    if (buffer == NULL) return false;
     bool result = acquire_i2c();
-    if(result) {result =furi_hal_i2c_rx(&furi_hal_i2c_handle_external, TEA5767_ADR, buffer, 5, TIMEOUT_MS);}
+    if(result) {
+        result = furi_hal_i2c_rx(&furi_hal_i2c_handle_external, TEA5767_ADR, buffer, 5, TIMEOUT_MS);
+    }
     release_i2c();
     return result;
 }
 
 bool tea5767_write_registers(uint8_t* buffer) {
     bool result = false;
-    if(buffer == NULL) return false; // Added NULL check
-    furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
-    result = furi_hal_i2c_tx(&furi_hal_i2c_handle_external, TEA5767_ADR, buffer, 5, TIMEOUT_MS);
-    furi_hal_i2c_release(&furi_hal_i2c_handle_external);
+    if (buffer == NULL) return false;  // Added NULL check
+        furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
+        result = furi_hal_i2c_tx(&furi_hal_i2c_handle_external, TEA5767_ADR, buffer, 5, TIMEOUT_MS);
+        furi_hal_i2c_release(&furi_hal_i2c_handle_external);
     return result;
 }
 
@@ -98,30 +100,28 @@ bool tea5767_set_stereo(uint8_t* buffer, bool stereo) {
 }
 
 bool tea5767_seek(uint8_t* buffer, bool seek_up) {
-    bool result = false;    
-    if(buffer == NULL) {return false;}
-    
-    buffer[REG_1] |= REG_1_SM; // Set the Search Mode (SM) bit to initiate seek    
-    if(seek_up) {buffer[REG_3] |= REG_3_SUD;} // Set Search Up (SUD) bit    
-    else {buffer[REG_3] &= ~REG_3_SUD; } // Set Search Down (SUD) bit       
+    bool result = false;
+    if (buffer == NULL) {return false;} 
+    buffer[REG_1] |= REG_1_SM;    // Set the Search Mode (SM) bit to initiate seek
+    if(seek_up) {    
+        buffer[REG_3] |= REG_3_SUD;  // Set Search Up (SUD) bit
+    } else {
+        buffer[REG_3] &= ~REG_3_SUD;  // Set Search Down (SUD) bit 
+    }
     buffer[REG_3] |= (REG_3_SSL | 0x60); // Set the Search Stop Level (SSL) to high for better tuning accuracy,  set bit 7 for RSSI 7
-    buffer[REG_3] &= ~REG_3_MS; // Set stereo mode (clearing the Mono bit)
-    //buffer[REG_3] |= REG_4_SNC; // Set the Stereo Noise Cancelling (SNC) bit to 1 to reduce noise in stereo reception
-    buffer[REG_4] &= ~REG_4_STBY; // Clear the Standby bit in register 4 to exit standby mode
-    buffer[REG_4] &= ~REG_4_BL; // Limit FM band 87.5 - 108 MHz.        
-    buffer[REG_5] |= REG_5_PLLREF;  // Set the PLLREF bit to 1 to enable the 6.5 MHz reference frequency for the PLL
-    buffer[REG_5] |= REG_5_DTC;     // Set the De-emphasis Time Constant (DTC) bit to 1 for 75 µs
-    
+    buffer[REG_3] &= ~REG_3_MS;  // Set stereo mode (clearing the Mono bit)   
+    buffer[REG_4] &= ~REG_4_BL;   // Limit FM band 87.5 - 108 MHz.        
+    buffer[REG_5] |= REG_5_PLLREF;
     // Write the updated register values to the TEA5767
     result = tea5767_write_registers(buffer);
-    return result;
+    return result;    
 }
 
 bool tea5767_get_frequency(uint8_t* buffer, int* value) {
     bool result = false;
     uint16_t frequency;
-    if(buffer == NULL || value == NULL) return false; //NULL check
-    if(tea5767_read_registers(buffer)) {
+    if (buffer == NULL || value == NULL) return false;  //NULL check
+    if (tea5767_read_registers(buffer)) {
         frequency = ((buffer[REG_1] & REG_1_PLL) << 8) | buffer[1];
         *value = (frequency * QUARTZ / 4 - FILTER) / 10000;
         result = true;
@@ -131,30 +131,24 @@ bool tea5767_get_frequency(uint8_t* buffer, int* value) {
 
 bool tea5767_set_frequency(uint8_t* buffer, int value) {
     bool result = false;
-    if(buffer == NULL) {return false;}
+    if (buffer == NULL) {return false;}
     uint16_t frequency = 4 * (value * 10000 + FILTER) / QUARTZ;
-
-    buffer[REG_1] = ((buffer[0] & ~REG_1_PLL) | ((frequency >> 8) & REG_1_PLL)); // Set the upper 8 bits of the PLL word
-    buffer[REG_2] = frequency & REG_2_PLL; // Set the lower 8 bits of the PLL word
-    buffer[REG_1] &= ~REG_1_MUTE; // Clear the Mute bit in register 1
-    buffer[REG_3] &= ~REG_3_MS;   // Set stereo mode (clearing the Mono bit)
-    //buffer[REG_3] |= REG_4_SNC; // Set the Stereo Noise Cancelling (SNC) bit to 1 to reduce noise in stereo reception
-    buffer[REG_4] &= ~REG_4_STBY; // Clear the Standby bit in register 4 to exit standby mode
-    buffer[REG_4] &= ~REG_4_BL;   // Limit FM band 87.5 - 108 MHz.
-    buffer[REG_5] |= REG_5_PLLREF;  // Set the PLLREF bit to 1 to enable the 6.5 MHz reference frequency for the PLL
-    buffer[REG_5] |= REG_5_DTC;     // Set the De-emphasis Time Constant (DTC) bit to 1 for 75 µs
-
+    buffer[REG_1] = ((buffer[0] & ~REG_1_PLL) | ((frequency >> 8) & REG_1_PLL));  // Set the upper 8 bits of the PLL word
+    buffer[REG_2] = frequency & REG_2_PLL;  // Set the lower 8 bits of the PLL word
+    buffer[REG_3] &= ~REG_3_MS;  // Set stereo mode (clearing the Mono bit)   
+    buffer[REG_5] |= REG_5_PLLREF;
     result = tea5767_write_registers(buffer);
     return result;
 }
 
 bool tea5767_get_radio_info(uint8_t* buffer, struct RADIO_INFO* info) {
     bool result = false;
-    int frequency_khz;
+    int frequency_khz; 
 
     // Error handling: Check if buffer and info are not NULL
-    if(buffer && info && tea5767_read_registers(buffer)) {
-        if(buffer[REG_3] & REG_3_MS) {
+    if (buffer && info && tea5767_read_registers(buffer)) {
+        
+        if (buffer[REG_3] & REG_3_MS) {
             info->stereo = true;
         } else {
             info->stereo = false;
@@ -163,41 +157,42 @@ bool tea5767_get_radio_info(uint8_t* buffer, struct RADIO_INFO* info) {
         info->signalLevel = buffer[REG_4] >> 4;
 
         // Determine signal quality based on signal level
-        if(info->signalLevel >= 0 && info->signalLevel <= 3) {
+        if (info->signalLevel >= 0 && info->signalLevel <= 3) {
             strncpy(info->signalQuality, "Poor", sizeof(info->signalQuality));
-        } else if(info->signalLevel >= 4 && info->signalLevel <= 7) {
+        } else if (info->signalLevel >= 4 && info->signalLevel <= 7) {
             strncpy(info->signalQuality, "Fair", sizeof(info->signalQuality));
-        } else if(info->signalLevel >= 8 && info->signalLevel <= 11) {
+        } else if (info->signalLevel >= 8 && info->signalLevel <= 11) {
             strncpy(info->signalQuality, "Good", sizeof(info->signalQuality));
-        } else if(info->signalLevel >= 12 && info->signalLevel <= 15) {
+        } else if (info->signalLevel >= 12 && info->signalLevel <= 15) {
             strncpy(info->signalQuality, "Excellent", sizeof(info->signalQuality));
         } else {
             strncpy(info->signalQuality, "Unknown", sizeof(info->signalQuality));
         }
 
         // Now get the frequency
-        if(tea5767_get_frequency(buffer, &frequency_khz)) {
-            info->frequency = frequency_khz / 100.0f; // Convert kHz to MHz
-            result = true; // Only return true if both read_registers and get_frequency succeeded
+        if (tea5767_get_frequency(buffer, &frequency_khz)) {
+            info->frequency = frequency_khz / 100.0f;  // Convert kHz to MHz
+            result = true;  // Only return true if both read_registers and get_frequency succeeded
         }
 
-        // Check if the radio is muted
-        if(buffer[REG_1] & REG_1_MUTE) {
+         // Check if the radio is muted
+        if (buffer[REG_1] & REG_1_MUTE) {
             info->muted = true;
         } else {
             info->muted = false;
         }
+
     }
     return result;
 }
 
-void tea5767_seekUp() {
+void tea5767_seekUp() {    
     //Get CUrrent Station
     double fm_frequency = tea5767_GetFreq();
     int targetFrequencyKHz = fm_frequency * 100;
-
+        
     uint8_t buffer[5];
-    if(tea5767_init(buffer)) {
+    if(tea5767_init(buffer)) { 
         tea5767_set_frequency(buffer, targetFrequencyKHz);
         // Start seeking upwards
         tea5767_seek(buffer, true);
@@ -205,12 +200,12 @@ void tea5767_seekUp() {
 }
 
 void tea5767_seekDown() {
-    //Get CUrrent Station
+        //Get CUrrent Station
     double fm_frequency = tea5767_GetFreq();
-    int targetFrequencyKHz = fm_frequency * 100;
-
+    int targetFrequencyKHz = fm_frequency * 100;     
+    
     uint8_t buffer[5];
-    if(tea5767_init(buffer)) {
+    if(tea5767_init(buffer)) {   
         tea5767_set_frequency(buffer, targetFrequencyKHz);
         // Start seeking upwards
         tea5767_seek(buffer, false);
@@ -230,34 +225,34 @@ void tea5767_ToggleMute() {
 
 void tea5767_MuteOn() {
     uint8_t buffer[5];
-    if(tea5767_read_registers(buffer)) { // Read the current state into the buffer
-        tea5767_set_mute(buffer, true); // Set the mute bit
+    if(tea5767_read_registers(buffer)) {  // Read the current state into the buffer
+        tea5767_set_mute(buffer, true);  // Set the mute bit
     }
 }
 
 void tea5767_MuteOff() {
     uint16_t frequency;
-    float value; // Changed to a float variable, not a pointer
+    float value;  // Changed to a float variable, not a pointer
     uint8_t buffer[5];
-    if(tea5767_read_registers(buffer)) { // Read the current state into the buffer
-        tea5767_set_mute(buffer, false); // Clear the mute bit
+    if (tea5767_read_registers(buffer)) {  // Read the current state into the buffer
+        tea5767_set_mute(buffer, false);  // Clear the mute bit
         frequency = ((buffer[0] & REG_1_PLL) << 8) | buffer[1];
-        value = (float)(frequency * QUARTZ / 4 - FILTER) / 10000; // Explicitly cast to float
-        tea5767_SetFreqMHz(value / 100.0); // Pass the float value, not the pointer
+        value = (float)(frequency * QUARTZ / 4 - FILTER) / 10000;  // Explicitly cast to float
+        tea5767_SetFreqMHz(value/ 100.0);  // Pass the float value, not the pointer
     }
 }
 
-void tea5767_SetFreqKHz(int freq_khz) {
+void tea5767_SetFreqKHz(int freq_khz) { 
     uint8_t buffer[5];
-    if(tea5767_init(buffer)) {
+    if (tea5767_init(buffer)) {
         tea5767_set_frequency(buffer, freq_khz);
     }
 }
 
-void tea5767_SetFreqMHz(float freq_mhz) {
+void tea5767_SetFreqMHz(float freq_mhz) { 
     uint8_t buffer[5];
-    if(tea5767_init(buffer)) {
-        int freq_khz = (int)(freq_mhz * 100.0); // Convert MHz to kHz
+    if (tea5767_init(buffer)) {
+        int freq_khz = (int)(freq_mhz * 100.0);  // Convert MHz to kHz
         tea5767_set_frequency(buffer, freq_khz);
     }
 }
@@ -266,13 +261,13 @@ float tea5767_GetFreq() {
     uint8_t buffer[5];
     int value;
     if(tea5767_get_frequency(buffer, &value)) {
-        return value / 100.0; // Convert to MHz
+        return value / 100.0;  // Convert to MHz
     }
-    return -1; // Error
+    return -1;  // Error
 }
 
-void tea5767_sleep(uint8_t* buffer) {
-    if(tea5767_read_registers(buffer)) {
+void tea5767_sleep(uint8_t *buffer) {
+    if(tea5767_read_registers(buffer)) {        
         buffer[REG_4] |= REG_4_STBY; // Set the Standby bit in register 4 to enter standby mode
         tea5767_write_registers(buffer);
     }

+ 40 - 35
non_catalog_apps/fm_radio_controller/TEA5767/TEA5767.h

@@ -16,6 +16,7 @@
 #ifndef TEA5767_H
 #define TEA5767_H
 
+
 #include <stdbool.h>
 #include <stdint.h>
 
@@ -28,52 +29,56 @@
 #define FILTER 225000 // Frequency of the filter in Hz
 
 // Define the registers
-#define REG_1 0x00 // Register 1 address
-#define REG_1_MUTE 0x80 // Mute: 1 to mute the audio output, 0 to unmute
-#define REG_1_SM 0x40 // Search Mode: 1 to activate search mode, 0 for normal mode
-#define REG_1_PLL 0x3F // PLL Setting: Sets the PLL value (6 bits)
-
-#define REG_2 0x01 // Register 2 address
-#define REG_2_PLL 0xFF // PLL Setting: Sets the PLL value (8 bits)
-
-#define REG_3 0x02 // Register 3 address
-#define REG_3_SUD 0x80 // Search Up/Down: 1 to search up, 0 to search down
-#define REG_3_SSL 0x60 // Search Stop Level: Sets the level at which the search stops (2 bits)
-#define REG_3_HLSI 0x10 // High/Low Side Injection: 1 for high side LO injection, 0 for low side LO injection
-#define REG_3_MS 0x08 // Mono to Stereo: 1 to force mono, 0 for stereo
-#define REG_3_MR 0x04 // Mute Right: 1 to mute the right audio channel and force mono, 0 to unmute
-#define REG_3_ML 0x02 // Mute Left: 1 to mute the left audio channel and force mono, 0 to unmute
-#define REG_3_SWP1 0x01 // Software programmable port 1: 1 for HIGH, 0 for LOW
-
-#define REG_4 0x03 // Register 4 address
-#define REG_4_SWP2 0x80 // Software programmable port 2: 1 for HIGH, 0 for LOW
-#define REG_4_STBY 0x40 // Standby: 1 to activate standby mode, 0 to deactivate
-#define REG_4_BL 0x20 // Band Limits: 1 for Japanese FM band, 0 for US/Europe FM band
-#define REG_4_XTAL 0x10 // Clock frequency: Sets the clock frequency (see Table 16)
-#define REG_4_SMUTE 0x08 // Soft Mute: 1 to activate soft mute, 0 to deactivate
-#define REG_4_HCC 0x04 // High Cut Control: 1 to activate high cut control, 0 to deactivate
-#define REG_4_SNC  0x02 // Stereo Noise Cancelling: 1 to activate stereo noise cancelling, 0 to deactivate
-#define REG_4_SI 0x01 // Search Indicator: 1 for ready flag output on pin SWPORT1, 0 for software programmable port 1
-
-#define REG_5 0x04 // Register 5 address
-#define REG_5_PLLREF 0x80 // PLL Ref: 1 to enable the 6.5 MHz reference frequency for the PLL, 0 to disable
-#define REG_5_DTC 0x40 // De-emphasis Time Constant: 1 for 75 µs, 0 for 50 µs
+#define REG_1 0x00  // Register 1 address
+#define REG_1_MUTE 0x80  // Mute: 1 to mute the audio output, 0 to unmute
+#define REG_1_SM 0x40  // Search Mode: 1 to activate search mode, 0 for normal mode
+#define REG_1_PLL 0x3F  // PLL Setting: Sets the PLL value (6 bits)
+
+#define REG_2 0x01  // Register 2 address
+#define REG_2_PLL 0xFF  // PLL Setting: Sets the PLL value (8 bits)
+
+#define REG_3 0x02  // Register 3 address
+#define REG_3_SUD 0x80  // Search Up/Down: 1 to search up, 0 to search down
+#define REG_3_SSL 0x60  // Search Stop Level: Sets the level at which the search stops (2 bits)
+#define REG_3_HLSI 0x10  // High/Low Side Injection: 1 for high side LO injection, 0 for low side LO injection
+#define REG_3_MS 0x08  // Mono to Stereo: 1 to force mono, 0 for stereo
+#define REG_3_MR 0x04  // Mute Right: 1 to mute the right audio channel and force mono, 0 to unmute
+#define REG_3_ML 0x02  // Mute Left: 1 to mute the left audio channel and force mono, 0 to unmute
+#define REG_3_SWP1 0x01  // Software programmable port 1: 1 for HIGH, 0 for LOW
+
+#define REG_4 0x03  // Register 4 address
+#define REG_4_SWP2 0x80  // Software programmable port 2: 1 for HIGH, 0 for LOW
+#define REG_4_STBY 0x40  // Standby: 1 to activate standby mode, 0 to deactivate
+#define REG_4_BL 0x20  // Band Limits: 1 for Japanese FM band, 0 for US/Europe FM band
+#define REG_4_XTAL 0x10  // Clock frequency: Sets the clock frequency (see Table 16)
+#define REG_4_SMUTE 0x08  // Soft Mute: 1 to activate soft mute, 0 to deactivate
+#define REG_4_HCC 0x04  // High Cut Control: 1 to activate high cut control, 0 to deactivate
+#define REG_4_SNC 0x02  // Stereo Noise Cancelling: 1 to activate stereo noise cancelling, 0 to deactivate
+#define REG_4_SI 0x01  // Search Indicator: 1 for ready flag output on pin SWPORT1, 0 for software programmable port 1
 
+#define REG_5 0x04  // Register 5 address
+#define REG_5_PLLREF 0x80  // PLL Ref: 1 to enable the 6.5 MHz reference frequency for the PLL, 0 to disable
+#define REG_5_DTC 0x40  // De-emphasis Time Constant: 1 for 75 µs, 0 for 50 µs
+
+// ----- local variables
+/// Band datatype.
 /// The BANDs TEA5767 can tune to.
 typedef enum {
-    RADIO_BAND_FM = 0x01, ///< FM band 87.5 - 108 MHz (USA, Europe) selected.
-    RADIO_BAND_FM_JAPAN = 0x02 ///< FM band 76 - 90 MHz (Japan) selected.
+    RADIO_BAND_FM = 0x01,       ///< FM band 87.5 - 108 MHz (USA, Europe) selected.
+    RADIO_BAND_FM_JAPAN = 0x02  ///< FM band 76 - 90 MHz (Japan) selected.
 } RADIO_BAND;
 
+
 /// A structure that contains information about the radio features from the chip.
 struct RADIO_INFO {
     float frequency; // Frequency in MHz
     int signalLevel; // Signal level
-    bool stereo; // Stereo or not
-    bool muted; // Muted or not
-    char signalQuality[10]; // Field for signal quality text
+    bool stereo;     // Stereo or not
+    bool muted;      // Muted or not
+    char signalQuality[10];  // Field for signal quality text
 };
 
+
 // Function prototypes
 bool tea5767_is_device_ready();
 bool tea5767_read_registers(uint8_t* buffer);

+ 55 - 88
non_catalog_apps/fm_radio_controller/TEA5767/examples.md

@@ -1,88 +1,55 @@
-## Example calls for TEA5767.c library<br>
-
-Device Initialization and Readiness<br>
-----------------------------------<br>
-uint8_t buffer[5];<br>
-bool is_ready = tea5767_is_device_ready();<br>
-
-Read/Write Registers<br>
---------------------<br>
-bool read_success = tea5767_read_registers(buffer);<br>
-bool write_success = tea5767_write_registers(buffer);<br>
-
-Initialize the Device<br>
----------------------<br>
-bool init_success = tea5767_init(buffer);<br>
-
-Set Mute<br>
---------<br>
-bool mute_success = tea5767_set_mute(buffer, true);  // To mute<br>
-bool unmute_success = tea5767_set_mute(buffer, false);  // To unmute<br>
-
-Set Stereo<br>
-----------<br>
-bool stereo_on = tea5767_set_stereo(buffer, true);  // Stereo ON<br>
-bool stereo_off = tea5767_set_stereo(buffer, false);  // Stereo OFF<br>
-
-Seek<br>
-----<br>
-bool seek_up_success = tea5767_seek(buffer, true);  // Seek up<br>
-bool seek_down_success = tea5767_seek(buffer, false);  // Seek down<br>
-
-Get/Set Frequency<br>
------------------<br>
-int frequency_khz;<br>
-bool get_freq_success = tea5767_get_frequency(buffer, &frequency_khz);<br>
-bool set_freq_success = tea5767_set_frequency(buffer, 101900);  // Set to 101.9 MHz<br>
-
-Get Radio Information<br>
----------------------<br>
-struct RADIO_INFO radio_info;<br>
-bool get_info_success = tea5767_get_radio_info(buffer, &radio_info);<br>
-
-Higher-Level Functions<br>
-----------------------<br>
-tea5767_seekUp();  // Seek to next station up<br>
-tea5767_seekDown();  // Seek to next station down<br>
-tea5767_ToggleMute();  // Toggle mute state<br>
-tea5767_MuteOn();  // Mute the device<br>
-tea5767_MuteOff();  // Unmute the device<br>
-tea5767_SetFreqKHz(101900);  // Set frequency to 101.9 MHz<br>
-tea5767_SetFreqMHz(101.9);  // Set frequency to 101.9 MHz<br>
-float current_freq = tea5767_GetFreq();  // Get current frequency in MHz<br>
-tea5767_sleep(buffer);  // Put the device to sleep<br>
-
-## i2C Registers for TEA5767:<br>
-// Define the registers<br>
-#define REG_1 0x00  // Register 1 address<br>
-#define REG_1_MUTE 0x80  // Mute: 1 to mute the audio output, 0 to unmute<br>
-#define REG_1_SM 0x40  // Search Mode: 1 to activate search mode, 0 for normal mode<br>
-#define REG_1_PLL 0x3F  // PLL Setting: Sets the PLL value (6 bits)<br>
-
-#define REG_2 0x01  // Register 2 address<br>
-#define REG_2_PLL 0xFF  // PLL Setting: Sets the PLL value (8 bits)<br>
-
-#define REG_3 0x02  // Register 3 address<br>
-#define REG_3_SUD 0x80  // Search Up/Down: 1 to search up, 0 to search down<br>
-#define REG_3_SSL 0x60  // Search Stop Level: Sets the level at which the search stops (2 bits)<br>
-#define REG_3_HLSI 0x10  // High/Low Side Injection: 1 for high side LO injection, 0 for low side LO injection<br>
-#define REG_3_MS 0x08  // Mono to Stereo: 1 to force mono, 0 for stereo<br>
-#define REG_3_MR 0x04  // Mute Right: 1 to mute the right audio channel and force mono, 0 to unmute<br>
-#define REG_3_ML 0x02  // Mute Left: 1 to mute the left audio channel and force mono, 0 to unmute<br>
-#define REG_3_SWP1 0x01  // Software programmable port 1: 1 for HIGH, 0 for LOW<br>
-
-#define REG_4 0x03  // Register 4 address<br>
-#define REG_4_SWP2 0x80  // Software programmable port 2: 1 for HIGH, 0 for LOW<br>
-#define REG_4_STBY 0x40  // Standby: 1 to activate standby mode, 0 to deactivate<br>
-#define REG_4_BL 0x20  // Band Limits: 1 for Japanese FM band, 0 for US/Europe FM band<br>
-#define REG_4_XTAL 0x10  // Clock frequency: Sets the clock frequency (see Table 16)<br>
-#define REG_4_SMUTE 0x08  // Soft Mute: 1 to activate soft mute, 0 to deactivate<br>
-#define REG_4_HCC 0x04  // High Cut Control: 1 to activate high cut control, 0 to deactivate<br>
-#define REG_4_SNC 0x02  // Stereo Noise Cancelling: 1 to activate stereo noise cancelling, 0 to deactivate<br>
-#define REG_4_SI 0x01  // Search Indicator: 1 for ready flag output on pin SWPORT1, 0 for software programmable port 1<br>
-
-#define REG_5 0x04  // Register 5 address<br>
-#define REG_5_PLLREF 0x80  // PLL Ref: 1 to enable the 6.5 MHz reference frequency for the PLL, 0 to disable<br>
-#define REG_5_DTC 0x40  // De-emphasis Time Constant: 1 for 75 µs, 0 for 50 µs<br>
-<br><br><br><br>
-## Created By: Coolshrimp - https://CoolshrimpModz.com<br>
+/**
+ * Example calls for TEA5767.c library
+ * 
+ * Device Initialization and Readiness
+ * ----------------------------------
+ * uint8_t buffer[5];
+ * bool is_ready = tea5767_is_device_ready();
+ * 
+ * Read/Write Registers
+ * --------------------
+ * bool read_success = tea5767_read_registers(buffer);
+ * bool write_success = tea5767_write_registers(buffer);
+ * 
+ * Initialize the Device
+ * ---------------------
+ * bool init_success = tea5767_init(buffer);
+ * 
+ * Set Mute
+ * --------
+ * bool mute_success = tea5767_set_mute(buffer, true);  // To mute
+ * bool unmute_success = tea5767_set_mute(buffer, false);  // To unmute
+ * 
+ * Set Stereo
+ * ----------
+ * bool stereo_on = tea5767_set_stereo(buffer, true);  // Stereo ON
+ * bool stereo_off = tea5767_set_stereo(buffer, false);  // Stereo OFF
+ * 
+ * Seek
+ * ----
+ * bool seek_up_success = tea5767_seek(buffer, true);  // Seek up
+ * bool seek_down_success = tea5767_seek(buffer, false);  // Seek down
+ * 
+ * Get/Set Frequency
+ * -----------------
+ * int frequency_khz;
+ * bool get_freq_success = tea5767_get_frequency(buffer, &frequency_khz);
+ * bool set_freq_success = tea5767_set_frequency(buffer, 101900);  // Set to 101.9 MHz
+ * 
+ * Get Radio Information
+ * ---------------------
+ * struct RADIO_INFO radio_info;
+ * bool get_info_success = tea5767_get_radio_info(buffer, &radio_info);
+ * 
+ * Higher-Level Functions
+ * ----------------------
+ * tea5767_seekUp();  // Seek to next station up
+ * tea5767_seekDown();  // Seek to next station down
+ * tea5767_ToggleMute();  // Toggle mute state
+ * tea5767_MuteOn();  // Mute the device
+ * tea5767_MuteOff();  // Unmute the device
+ * tea5767_SetFreqKHz(101900);  // Set frequency to 101.9 MHz
+ * tea5767_SetFreqMHz(101.9);  // Set frequency to 101.9 MHz
+ * float current_freq = tea5767_GetFreq();  // Get current frequency in MHz
+ * tea5767_sleep(buffer);  // Put the device to sleep
+ */

+ 3 - 3
non_catalog_apps/fm_radio_controller/application.fam

@@ -2,13 +2,13 @@ App(
     appid="fmradio_controller",
     name="[TEA5767] FM Radio",
     apptype=FlipperAppType.EXTERNAL,
-    entry_point="my_fm_radio",
+    entry_point="fmradio_controller_app",
     stack_size=1 * 1024,
     fap_category="GPIO",
     fap_icon="radio.png",
     fap_icon_assets="images",
     fap_author="coolshrimp",
-    fap_weburl="https://github.com/coolshrimp/flipperzero-firmware-wPlugins/tree/420/applications/external/FM_Radio",
-    fap_version="1.1",
+    fap_weburl="https://coolshrimp/flipperzero-firmware-wPlugins/",
+    fap_version="0.8",
     fap_description="FM Radio App",
 )

+ 183 - 212
non_catalog_apps/fm_radio_controller/radio.c

@@ -1,9 +1,11 @@
+
+
 /**
  *
  * @author Coolshrimp - CoolshrimpModz.com
  *
  * @brief FM Radio using the TEA5767 FM radio chip.
- * @version 1.1
+ * @version 0.8
  * @date 2023-09-29
  * 
  * @copyright GPLv3
@@ -21,105 +23,71 @@
 #include <gui/modules/variable_item_list.h>
 #include <notification/notification.h>
 #include <notification/notification_messages.h>
-#include <stdbool.h>  // for true/false
-#include <stdint.h>   // for uint8_t, size_t
-#include <stdio.h>    // for snprintf
-#include <math.h>     // for fabsf
+#include <string.h>
+#include <stdlib.h>
+
 #include "TEA5767/TEA5767.h"
-#include <gui/icon_i.h>
 #include "fmradio_controller_icons.h"
 
-// Define macros for easier management
+// Define a macro for enabling the backlight always on.
 #define BACKLIGHT_ALWAYS_ON
-#define TAG "FM_Radio"
 
-// Declare global variables
+#define TAG "FMRadio"
+
+// Define volume options and names
 uint8_t volume_values[] = {0, 1};
 char* volume_names[] = {"Un-Muted", "Muted"};
-bool current_volume = 1;  // Current volume state
-int* signal_strength;  // Signal strength (unused, consider removing or implementing)
+bool current_volume = 0;  // Muted or not
+char* current_vol = "Un-Muted";  // Current volume status as text. Changed type to char*
+int* signal_strength;
+int loopcount = 0;
+
 uint8_t tea5767_registers[5];
-uint32_t current_station_index = 0;  // Default to the first frequency
 
-// Station struct to hold frequency and station name
-struct Station {
-    float frequency;
-    char* name;
+// Define values for frequency selection
+float frequency_values[] = {
+    88.1, 88.9, 89.1, 90.3, 91.5, 91.7, 92.0, 92.5, 94.1, 95.9, 96.3, 96.9,
+    97.3, 98.1, 98.7, 99.1, 99.9, 100.7, 101.3, 103.9, 104.5, 105.1, 105.5, 106.5,
+    107.1, 102.7, 105.3
 };
 
-#define NUM_VOLUME_VALUES (sizeof(volume_values) / sizeof(volume_values[0]))
-#define NUM_STATIONS (sizeof(stations) / sizeof(stations[0]))
-
-// Array of Stations 
-struct Station stations[] = {
-    {88.1, "CIND Indie 88"},
-    {88.9, "CIRV Portuguese"},
-    {89.5, "CIUT FM"},
-    {90.3, "Ici Musique"},
-    {91.1, "JAZZ.FM91"},
-    {92.5, "KiSS Radio"},
-    {93.5, "93.5 Today"},
-    {94.1, "CBC Music"},
-    {95.9, "KX96"},
-    {96.3, "Classical 96.3"},
-    {97.3, "Boom 97.3"},
-    {98.1, "CHFI"},
-    {98.7, "Flow 98.7"},
-    {99.1, "CBC Radio 1"},
-    {99.9, "99.9 Toronto"},
-    {100.7, "CHIN 100.7"},
-    {101.3, "CMR Diversity"},
-    {101.3, "CMR Hindi Urdu"},
-    {101.3, "CMR Punjabi"},
-    {101.3, "CMR Tamil"},
-    {102.1, "102.1 Edge"},
-    {103.5, "Z103.5"},
-    {103.9, "Proud FM"},
-    {104.5, "CHUM"},
-    {105.5, "VIBE1055 FM"},
-    {106.5, "106.5 Elmnt"},
-    {107.1, "Q107"}
-};
+uint32_t current_frequency_index = 0;  // Default to the first frequency
 
-// Function prototypes for forward declarations
-void elements_button_top_left(Canvas* canvas, const char* str);
-void elements_button_top_right(Canvas* canvas, const char* str);
 //lib can only do bottom left/right
 void elements_button_top_left(Canvas* canvas, const char* str) {
-    const uint8_t button_height = 10; // Define the height of the button
-    const uint8_t vertical_offset = 2; // Define the vertical offset of the text
-    const uint8_t horizontal_offset = 2; // Define the horizontal offset of the text
-    const uint8_t string_width = canvas_string_width(canvas, str);
-    const Icon* icon = &I_ButtonUp;
-    const uint8_t icon_h_offset = 2;
-    const uint8_t icon_width_with_offset = icon->width + icon_h_offset;
-    const uint8_t icon_v_offset = icon->height + vertical_offset;
-    const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
+    const uint8_t button_height = 12;
+    const uint8_t vertical_offset = 3;
+    const uint8_t horizontal_offset = 3;
+
+    // You may need to declare or pass 'button_width' here.
+    const uint8_t string_width = canvas_string_width(canvas, str);    
+
+    // 'button_width' should be declared or passed here.
+    const uint8_t button_width = string_width + horizontal_offset * 2 + 3;
 
     const uint8_t x = 0;
     const uint8_t y = 0 + button_height;
 
-    canvas_draw_box(canvas, x, y - button_height, button_width, button_height); // Draw the button
-    canvas_draw_line(canvas, x + button_width + 0, y - button_height, x + button_width + 0, y - 1); // Draw the button border
-    canvas_draw_line(canvas, x + button_width + 1, y - button_height, x + button_width + 1, y - 2); // Draw the button border
-    canvas_draw_line(canvas, x + button_width + 2, y - button_height, x + button_width + 2, y - 3); // Draw the button border
+    canvas_draw_box(canvas, x, y - button_height, button_width, button_height);
+    canvas_draw_line(canvas, x + button_width + 0, y - button_height, x + button_width + 0, y - 1);
+    canvas_draw_line(canvas, x + button_width + 1, y - button_height, x + button_width + 1, y - 2);
+    canvas_draw_line(canvas, x + button_width + 2, y - button_height, x + button_width + 2, y - 3);
 
-    canvas_invert_color(canvas); // Invert the color of the text and icon
-    canvas_draw_icon(canvas, x + horizontal_offset, y - icon_v_offset, &I_ButtonUp); // Draw the icon
-    canvas_draw_str(canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str); // Draw the text
-    canvas_invert_color(canvas); // Invert the color of the text and icon
+    canvas_invert_color(canvas);
+    canvas_draw_str(
+        canvas, x + horizontal_offset + 3, y - vertical_offset, str);
+    canvas_invert_color(canvas);
 }
 
 void elements_button_top_right(Canvas* canvas, const char* str) {
-    const uint8_t button_height = 10;
-    const uint8_t vertical_offset = 2;
-    const uint8_t horizontal_offset = 2;
+    const uint8_t button_height = 12;
+    const uint8_t vertical_offset = 3;
+    const uint8_t horizontal_offset = 3;
+    // You may need to declare or pass 'button_width' here.
     const uint8_t string_width = canvas_string_width(canvas, str);
-    const Icon* icon = &I_ButtonDown;
-    const uint8_t icon_h_offset = 2;
-    const uint8_t icon_width_with_offset = icon->width + icon_h_offset;
-    const uint8_t icon_v_offset = icon->height + vertical_offset;
-    const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
+
+    // 'button_width' should be declared or passed here.
+    const uint8_t button_width = string_width + horizontal_offset * 2 + 3;
 
     const uint8_t x = canvas_width(canvas);
     const uint8_t y = 0 + button_height;
@@ -131,24 +99,22 @@ void elements_button_top_right(Canvas* canvas, const char* str) {
 
     canvas_invert_color(canvas);
     canvas_draw_str(canvas, x - button_width + horizontal_offset, y - vertical_offset, str);
-    canvas_draw_icon(
-        canvas, x - horizontal_offset - icon->width, y - icon_v_offset, &I_ButtonDown);
     canvas_invert_color(canvas);
 }
 
 // Enumerations for submenu and view indices
 typedef enum {
-    MyAppSubmenuIndexConfigure,
-    MyAppSubmenuIndexFlipTheWorld,
-    MyAppSubmenuIndexAbout,
-} MyAppSubmenuIndex;
+    FMRadioSubmenuIndexConfigure,
+    FMRadioSubmenuIndexFlipTheWorld,
+    FMRadioSubmenuIndexAbout,
+} FMRadioSubmenuIndex;
 
 typedef enum {
-    MyAppViewSubmenu,
-    MyAppViewConfigure,
-    MyAppViewFlipTheWorld,
-    MyAppViewAbout,
-} MyAppView;
+    FMRadioViewSubmenu,
+    FMRadioViewConfigure,
+    FMRadioViewFlipTheWorld,
+    FMRadioViewAbout,
+} FMRadioView;
 
 // Define a struct to hold the application's components
 typedef struct {
@@ -158,163 +124,167 @@ typedef struct {
     VariableItemList* variable_item_list_config;
     View* view_flip_the_world;
     Widget* widget_about;
-} MyApp;
+} FMRadio;
 
 // Define a model struct for your application
 typedef struct {
-    uint32_t current_station_index;
+    uint32_t frequency_index;
     uint8_t volume_index;
 } MyModel;
 
 // Callback for navigation events
 
-uint32_t my_app_navigation_exit_callback(void* context) {
+uint32_t fmradio_controller_navigation_exit_callback(void* context) {
     UNUSED(context);
-    uint8_t buffer[5]; // Create a buffer to hold the TEA5767 register values
-    tea5767_sleep(buffer); // Call the tea5767_sleep function, passing the buffer as an argument
+    uint8_t buffer[5];  // Create a buffer to hold the TEA5767 register values
+        tea5767_sleep(buffer);  // Call the tea5767_sleep function, passing the buffer as an argument
     return VIEW_NONE;
 }
 
 // Callback for navigating to the submenu
-uint32_t my_app_navigation_submenu_callback(void* context) {
+uint32_t fmradio_controller_navigation_submenu_callback(void* context) {
     UNUSED(context);
-    return MyAppViewSubmenu;
+    return FMRadioViewSubmenu;
 }
 
 // Callback for handling submenu selections
-void my_app_submenu_callback(void* context, uint32_t index) {
-    MyApp* app = (MyApp*)context;
+void fmradio_controller_submenu_callback(void* context, uint32_t index) {
+    FMRadio* app = (FMRadio*)context;
     switch(index) {
-    case MyAppSubmenuIndexConfigure:
-        view_dispatcher_switch_to_view(app->view_dispatcher, MyAppViewConfigure);
+    case FMRadioSubmenuIndexConfigure:
+        view_dispatcher_switch_to_view(app->view_dispatcher, FMRadioViewConfigure);
         break;
-    case MyAppSubmenuIndexFlipTheWorld:
-        view_dispatcher_switch_to_view(app->view_dispatcher, MyAppViewFlipTheWorld);
+    case FMRadioSubmenuIndexFlipTheWorld:
+        view_dispatcher_switch_to_view(app->view_dispatcher, FMRadioViewFlipTheWorld);
         break;
-    case MyAppSubmenuIndexAbout:
-        view_dispatcher_switch_to_view(app->view_dispatcher, MyAppViewAbout);
+    case FMRadioSubmenuIndexAbout:
+        view_dispatcher_switch_to_view(app->view_dispatcher, FMRadioViewAbout);
         break;
     default:
         break;
     }
 }
 
-bool my_app_view_input_callback(InputEvent* event, void* context) {
+bool fmradio_controller_view_input_callback(InputEvent* event, void* context) {
     UNUSED(context);
-    if(event->type == InputTypeShort && event->key == InputKeyLeft) {
+    if (event->type == InputTypeShort && event->key == InputKeyLeft) {
         tea5767_seekDown();
         current_volume = 0;
-        return true; // Event was handled
-    } else if(event->type == InputTypeShort && event->key == InputKeyRight) {
+        current_vol = "Un-Muted";
+        return true;  // Event was handled
+    } else if (event->type == InputTypeShort && event->key == InputKeyRight) {
         tea5767_seekUp();
         current_volume = 0;
-        return true; // Event was handled
-    } else if(event->type == InputTypeShort && event->key == InputKeyOk) {
-        if(current_volume == 0) { 
+        current_vol = "Un-Muted";
+        return true;  // Event was handled
+    } else if (event->type == InputTypeShort && event->key == InputKeyOk) {       
+        if (current_volume == 0) {  // Fixed: == instead of =
             tea5767_MuteOn();
             current_volume = 1;
+            current_vol = "Muted";
         } else {
             tea5767_MuteOff();
             current_volume = 0;
+            current_vol = "Un-Muted";
         }
-        return true; // Event was handled
-    } else if(event->type == InputTypeShort && event->key == InputKeyUp) {
-        // Increment the current station index and loop back if at the end
-        current_station_index = (current_station_index + 1) % NUM_STATIONS;
-        // Set the new frequency from the stations array
-        tea5767_SetFreqMHz(stations[current_station_index].frequency);
+        return true;  // Event was handled
+    } else if (event->type == InputTypeShort && event->key == InputKeyUp) {
+        // Increment the current frequency index and loop back if at the end
+        current_frequency_index = (current_frequency_index + 1) % (sizeof(frequency_values) / sizeof(frequency_values[0]));
+        // Set the new frequency
+        tea5767_SetFreqMHz(frequency_values[current_frequency_index]);
         current_volume = 0;
-        return true; // Event was handled
-    } else if(event->type == InputTypeShort && event->key == InputKeyDown) {
-        // Decrement the current station index and loop back if at the beginning
-        if(current_station_index == 0) {
-            current_station_index = NUM_STATIONS - 1;
+        current_vol = "Un-Muted";
+        return true;  // Event was handled
+    } else if (event->type == InputTypeShort && event->key == InputKeyDown) {
+        // Decrement the current frequency index and loop back if at the beginning
+        if (current_frequency_index == 0) {
+            current_frequency_index = (sizeof(frequency_values) / sizeof(frequency_values[0])) - 1;
         } else {
-            current_station_index--;
+            current_frequency_index--;
         }
-        // Set the new frequency from the stations array
-        tea5767_SetFreqMHz(stations[current_station_index].frequency);
+        // Set the new frequency
+        tea5767_SetFreqMHz(frequency_values[current_frequency_index]);
         current_volume = 0;
-        return true; // Event was handled
+        current_vol = "Un-Muted";
+        return true;  // Event was handled
     }
-    return false; // Event was not handled
+    
+    return false;  // Event was not handled
 }
 
 // Callback for handling frequency changes
-void my_app_frequency_change(VariableItem* item) {
-    MyApp* app = variable_item_get_context(item);
+void fmradio_controller_frequency_change(VariableItem* item) {
+    FMRadio* app = variable_item_get_context(item);
     uint8_t index = variable_item_get_current_value_index(item);
     MyModel* model = view_get_model(app->view_flip_the_world);
-    model->current_station_index = index;
+    model->frequency_index = index;
 
     // Display the selected frequency value as text
-    char frequency_display[16];
-    snprintf(frequency_display, sizeof(frequency_display), "%.1f MHz", (double)stations[(int)index].frequency);
+    char frequency_display[16];  // Adjust the buffer size as needed
+    snprintf(frequency_display, sizeof(frequency_display), "%.1f MHz", (double)frequency_values[index]);
     variable_item_set_current_value_text(item, frequency_display);
 }
 
 // Callback for handling volume changes
-void my_app_volume_change(VariableItem* item) {
-    MyApp* app = variable_item_get_context(item);
+void fmradio_controller_volume_change(VariableItem* item) {
+    FMRadio* app = variable_item_get_context(item);
     uint8_t index = variable_item_get_current_value_index(item);
-    variable_item_set_current_value_text(
-        item, volume_names[index]); // Display the selected volume as text
+    variable_item_set_current_value_text(item, volume_names[index]);  // Display the selected volume as text
     MyModel* model = view_get_model(app->view_flip_the_world);
     model->volume_index = index;
 }
 
-// Declare local buffers for text display
-char frequency_display[64];
-char station_display[256];
-char signal_display[64];
-char volume_display[32];
-
 // Callback for drawing the view
-void my_app_view_draw_callback(Canvas* canvas, void* model) {
-    (void)model;
+
+void fmradio_controller_view_draw_callback(Canvas* canvas, void* model) {
+    (void)model;  // Mark model as unused
+    
+    char frequency_display[64];    
+    char signal_display[64];
+    char volume_display[32]; 
     
+    // tea5767_get_radio_info() populates the info
+    struct RADIO_INFO info;
+    uint8_t buffer[5];
+
     // Draw strings on the canvas
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str(canvas, 33, 10, "FM Radio");
-    canvas_draw_icon(canvas,83, 0, &I_RadioSmall);
+    canvas_draw_str(canvas, 45, 10, "FM Radio");    
 
     // Draw button prompts
     canvas_set_font(canvas, FontSecondary);
-    elements_button_top_left(canvas, "Pre"); elements_button_top_right(canvas, "Pre");
-    elements_button_left(canvas, "Scan-"); elements_button_center(canvas, "Mute"); elements_button_right(canvas, "Scan+"); 
-
-    struct RADIO_INFO info; // Create a struct to hold the radio info       
-    uint8_t buffer[5]; // Create a buffer to hold the TEA5767 register values
-    if(tea5767_get_radio_info(buffer, &info)) {
+    elements_button_left(canvas, "Scan-");
+    elements_button_right(canvas, "Scan+");
+    elements_button_center(canvas, "Mute");
+    elements_button_top_left(canvas, " Pre");
+    elements_button_top_right(canvas, "Pre ");
+    
+    
+    if (tea5767_get_radio_info(buffer, &info)) { 
         snprintf(frequency_display, sizeof(frequency_display), "Frequency: %.1f MHz", (double)info.frequency);
-        float tolerance = 0.05f;
-        float diff = stations[current_station_index].frequency - info.frequency;        
-        if(fabsf(diff) < tolerance) {snprintf(station_display, sizeof(station_display), "%s", stations[current_station_index].name);} 
-        else {station_display[0] = '\0';}
-        snprintf(volume_display, sizeof(volume_display), "Status: %s %s", info.muted ? "Playing" : "Muted", info.stereo ? "(Mono)" : "(Stereo)");            
-        snprintf(signal_display, sizeof(signal_display), "Signal: %d (%s)", info.signalLevel, info.signalQuality);
+        canvas_draw_str(canvas, 10, 25, frequency_display);
+
+        snprintf(signal_display, sizeof(signal_display), "RSSI: %d (%s) %d", info.signalLevel, info.signalQuality, loopcount);
+        canvas_draw_str(canvas, 10, 45, signal_display); 
+
+        snprintf(volume_display, sizeof(volume_display), "Status: %s %s", info.muted ? "Playing" : "Muted", info.stereo ? "(Stereo)" : "(Mono)");
+        canvas_draw_str(canvas, 10, 35, volume_display);              
     } else {
-        // Display error message if TEA5767 is not detected
         snprintf(frequency_display, sizeof(frequency_display), "TEA5767 Not Detected");
-        snprintf(signal_display, sizeof(signal_display), "Pin 15 = SDA | Pin 16 = SLC");            
-        // Reset frequency_display and volume_display to blank
-        station_display[0] = '\0';
-        volume_display[0] = '\0';
+        canvas_draw_str(canvas, 10, 25, frequency_display); 
+
+        snprintf(signal_display, sizeof(signal_display), "Pin 15 = SDA | Pin 16 = SLC");
+        canvas_draw_str(canvas, 10, 45, signal_display); 
     }   
 
-    // Display the stored values on the 5th loop
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str(canvas, 10, 20, station_display);
-    canvas_set_font(canvas, FontSecondary);
-    canvas_draw_str(canvas, 10, 30, frequency_display);    
-    canvas_draw_str(canvas, 10, 40, volume_display);
-    canvas_draw_str(canvas, 10, 49, signal_display);
 }
 
 // Allocate memory for the application
-MyApp* my_app_alloc() {
-    MyApp* app = (MyApp*)malloc(sizeof(MyApp));
+FMRadio* fmradio_controller_alloc() {
+    FMRadio* app = (FMRadio*)malloc(sizeof(FMRadio));
+
     Gui* gui = furi_record_open(RECORD_GUI);
+
     // Initialize the view dispatcher
     app->view_dispatcher = view_dispatcher_alloc();
     view_dispatcher_enable_queue(app->view_dispatcher);
@@ -322,83 +292,84 @@ MyApp* my_app_alloc() {
 
     // Initialize the submenu
     app->submenu = submenu_alloc();
-    submenu_add_item(app->submenu, "Listen Now", MyAppSubmenuIndexFlipTheWorld, my_app_submenu_callback, app);    
-    //submenu_add_item(app->submenu, "Config", MyAppSubmenuIndexConfigure, my_app_submenu_callback, app);
-    submenu_add_item(app->submenu, "About", MyAppSubmenuIndexAbout, my_app_submenu_callback, app);
-    view_set_previous_callback(submenu_get_view(app->submenu), my_app_navigation_exit_callback);
-    view_dispatcher_add_view(app->view_dispatcher, MyAppViewSubmenu, submenu_get_view(app->submenu));
-    view_dispatcher_switch_to_view(app->view_dispatcher, MyAppViewSubmenu);
+    submenu_add_item(app->submenu,"Listen Now",FMRadioSubmenuIndexFlipTheWorld,fmradio_controller_submenu_callback,app);
+    //submenu_add_item(app->submenu, "Config", FMRadioSubmenuIndexConfigure, fmradio_controller_submenu_callback, app);
+    submenu_add_item(app->submenu, "About", FMRadioSubmenuIndexAbout, fmradio_controller_submenu_callback, app);
+    view_set_previous_callback(submenu_get_view(app->submenu), fmradio_controller_navigation_exit_callback);
+    view_dispatcher_add_view(app->view_dispatcher, FMRadioViewSubmenu, submenu_get_view(app->submenu));
+    view_dispatcher_switch_to_view(app->view_dispatcher, FMRadioViewSubmenu);
 
     // Initialize the variable item list for configuration
     app->variable_item_list_config = variable_item_list_alloc();
     variable_item_list_reset(app->variable_item_list_config);
 
     // Add frequency configuration
-    VariableItem* frequency_item = variable_item_list_add(app->variable_item_list_config, "Freq (MHz)",  NUM_STATIONS, my_app_frequency_change, app);    
-    
-    uint32_t current_station_index = 0;
-    variable_item_set_current_value_index(frequency_item, current_station_index);
+    VariableItem* frequency_item = variable_item_list_add(app->variable_item_list_config,"Freq (MHz)", COUNT_OF(frequency_values),fmradio_controller_frequency_change,app); 
+    uint32_t frequency_index = 0;
+    variable_item_set_current_value_index(frequency_item, frequency_index);
+
     // Add volume configuration
-    VariableItem* volume_item = variable_item_list_add(app->variable_item_list_config, "Volume", COUNT_OF(volume_values), my_app_volume_change, app);
+    VariableItem* volume_item = variable_item_list_add(app->variable_item_list_config,"Volume", COUNT_OF(volume_values),fmradio_controller_volume_change,app);
     uint8_t volume_index = 0;
     variable_item_set_current_value_index(volume_item, volume_index);
-    view_set_previous_callback(variable_item_list_get_view(app->variable_item_list_config),my_app_navigation_submenu_callback);
-    view_dispatcher_add_view(app->view_dispatcher, MyAppViewConfigure, variable_item_list_get_view(app->variable_item_list_config));
-    
+    view_set_previous_callback(variable_item_list_get_view(app->variable_item_list_config),fmradio_controller_navigation_submenu_callback);
+    view_dispatcher_add_view(app->view_dispatcher,FMRadioViewConfigure,variable_item_list_get_view(app->variable_item_list_config));
+
     // Initialize the view for flipping the world
     app->view_flip_the_world = view_alloc();
-    view_set_draw_callback(app->view_flip_the_world, my_app_view_draw_callback);
-    view_set_input_callback(app->view_flip_the_world, my_app_view_input_callback);
-    view_set_previous_callback(app->view_flip_the_world, my_app_navigation_submenu_callback);
+    view_set_draw_callback(app->view_flip_the_world, fmradio_controller_view_draw_callback);
+    view_set_input_callback(app->view_flip_the_world, fmradio_controller_view_input_callback);
+    view_set_previous_callback(app->view_flip_the_world, fmradio_controller_navigation_submenu_callback);
     view_allocate_model(app->view_flip_the_world, ViewModelTypeLockFree, sizeof(MyModel));
     MyModel* model = view_get_model(app->view_flip_the_world);
-    model->current_station_index = current_station_index;
+    model->frequency_index = frequency_index;
     model->volume_index = volume_index;
-    view_dispatcher_add_view(app->view_dispatcher, MyAppViewFlipTheWorld, app->view_flip_the_world);
-    
+
+    view_dispatcher_add_view(app->view_dispatcher, FMRadioViewFlipTheWorld, app->view_flip_the_world);
+
     // Initialize the widget for displaying information about the app
     app->widget_about = widget_alloc();
-    widget_add_text_scroll_element(app->widget_about, 0, 0, 128, 64,
-        "FM Radio (v1.1)\n"
-        "---\n"
-        "Created By Coolshrimp\n\n"
-        "Up = Preset Up\n"
-        "Down = Preset Down\n"
-        "Left = Seek Down\n"
-        "Right = Seek Up\n"
-        "OK = Toggle Mute");    
-
-    view_set_previous_callback(widget_get_view(app->widget_about), my_app_navigation_submenu_callback);
-    view_dispatcher_add_view(app->view_dispatcher, MyAppViewAbout, widget_get_view(app->widget_about));
+    widget_add_text_scroll_element(app->widget_about,0,0,128,64,"FM Radio. (v0.8)\n---\n Created By Coolshrimp\n\nUp = Preset Up\nDown = Preset Down\nLeft = Seek Down \nRight = Seek Up \n OK = Toggle Mute");
+    view_set_previous_callback(widget_get_view(app->widget_about), fmradio_controller_navigation_submenu_callback);
+    view_dispatcher_add_view(app->view_dispatcher, FMRadioViewAbout, widget_get_view(app->widget_about));
+
     app->notifications = furi_record_open(RECORD_NOTIFICATION);
+
 #ifdef BACKLIGHT_ALWAYS_ON
     notification_message(app->notifications, &sequence_display_backlight_enforce_on);
 #endif
+
     return app;
 }
+
 // Free memory used by the application
-void my_app_free(MyApp* app) {
+void fmradio_controller_free(FMRadio* app) {
 #ifdef BACKLIGHT_ALWAYS_ON
     notification_message(app->notifications, &sequence_display_backlight_enforce_auto);
 #endif
     furi_record_close(RECORD_NOTIFICATION);
-    view_dispatcher_remove_view(app->view_dispatcher, MyAppViewAbout);
+
+    view_dispatcher_remove_view(app->view_dispatcher, FMRadioViewAbout);
     widget_free(app->widget_about);
-    view_dispatcher_remove_view(app->view_dispatcher, MyAppViewFlipTheWorld);
+    view_dispatcher_remove_view(app->view_dispatcher, FMRadioViewFlipTheWorld);
     view_free(app->view_flip_the_world);
-    view_dispatcher_remove_view(app->view_dispatcher, MyAppViewConfigure);
+    view_dispatcher_remove_view(app->view_dispatcher, FMRadioViewConfigure);
     variable_item_list_free(app->variable_item_list_config);
-    view_dispatcher_remove_view(app->view_dispatcher, MyAppViewSubmenu);
+    view_dispatcher_remove_view(app->view_dispatcher, FMRadioViewSubmenu);
     submenu_free(app->submenu);
     view_dispatcher_free(app->view_dispatcher);
     furi_record_close(RECORD_GUI);
+
     free(app);
 }
+
 // Main function to start the application
-int32_t my_fm_radio(void* p) {
+int32_t fmradio_controller_app(void* p) {
     UNUSED(p);
-    MyApp* app = my_app_alloc();
+
+    FMRadio* app = fmradio_controller_alloc();
     view_dispatcher_run(app->view_dispatcher);
-    my_app_free(app);
+
+    fmradio_controller_free(app);
     return 0;
 }