Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:f5a073ecafa6, committed 2019-12-16
- Comitter:
- jlpadiolleau
- Date:
- Mon Dec 16 07:37:25 2019 +0000
- Commit message:
- Si4735 GEII TOURS
Changed in this revision
| Si4735.cpp | Show annotated file Show diff for this revision Revisions of this file |
| Si4735.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Si4735.cpp Mon Dec 16 07:37:25 2019 +0000
@@ -0,0 +1,397 @@
+//Modifié par VG: attention il faut diminuer la vitesse du bus SPI sur la UnoRev3 (sinon gros problème de lecture)
+//Voir ligne dans la méthode begin SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
+//j'ai ajouté 1<<SPR0 pour mettre l'horloge / 16 (Fmax du Si7435=2,5MHz !!!)
+
+
+/* Arduino Si4735 Library
+ * Written by Ryan Owens for SparkFun Electronics 5/17/11
+ * Altered by Wagner Sartori Junior 09/13/11
+ * Actively Being Developed by Jon Carrier
+ *
+ * This library is for use with the SparkFun Si4735 Shield
+ * Released under the 'Buy Me a Beer' license
+ * (If we ever meet, you buy me a beer)
+ *
+ * See the header file for better function documentation.
+ *
+ * See the example sketches to learn how to use the library in your code.
+*/
+
+/*
+
+SPCR
+| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+| SPIE | SPE | DORD | MSTR | CPOL | CPHA | SPR1 | SPR0 |
+
+SPIE - Enables the SPI interrupt when 1
+SPE - Enables the SPI when 1
+DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0
+MSTR - Sets the Arduino in master mode when 1, slave mode when 0
+CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0
+CPHA - Samples data on the falling edge of the data clock when 1, rising edge when 0
+SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz)
+
+*/
+#include "Si4735.h"
+
+
+//This is just a constructor.
+//Default values are assigned to various private variables
+Si4735::Si4735()
+{
+ //busspi = new SPI(D11,D12,D13);//mosi,miso,sck
+ SPISS = new DigitalOut(D10);
+ GPO2 = new DigitalInOut(D2);//D2
+ GPO1 = new DigitalInOut(D12);//D12
+ POWER_PIN = new DigitalOut(D8);//D8
+ RADIO_RESET_PIN = new DigitalOut(D9);//D9
+
+ _mode = FM;//FM par défaut
+ _locale = EU;//europe de l'ouest
+ _volume = 63;//volume à fond
+}
+
+void Si4735::begin(char mode)
+{
+ _mode = mode;//FM par défaut
+ //Etat RESET de l'ordinogramme
+ //On configure les broches en sorties, positionne GPO1 et GPO2 à 1 pendant le reset du Si4735
+ //pour se mettre en mode de communication SPI
+ GPO2->output();//On force pour l'instant GPO2 en sortie
+ GPO1->output();//On force pour l'instant GPO1 en sortie
+
+ //On active la séquence reset du Si4735
+ RADIO_RESET_PIN->write(0);
+ POWER_PIN->write(0);
+ //wait_ms(20);
+ //On met un niveau 1 sur les GPO (mode SPI)
+ GPO1->write(1);
+ GPO2->write(1);
+ wait_ms(20);
+ //On alimente le Si4735
+ POWER_PIN->write(1);
+ wait_ms(20);
+ //front montant sur la broche reset du Si4735
+ RADIO_RESET_PIN->write(1);
+ wait_ms(200);//attente pour la prise en compte du mode choisi
+
+ GPO1->input();//On remet GPO1 en entrée pour le bus SPI
+ //broche INT_PIN en entrée
+ GPO2->input();//On remet GPO2 en entrée
+ //SS au niveau haut
+ SPISS->write(1);
+ delete GPO1;//on détruit GPO1 pour laisser la broche D12 au bus SPI
+
+ wait(0.2);
+ //Configure le SPI, Maitre, 1MHz Mode 0 à priori pour le Si4735
+ //2,5 MHz max pour l'horloge bus SPI
+ busspi = new SPI(D11,D12,D13);//mosi,miso,sck
+ busspi->format(8,0);//8 bits de données et mode 0
+ busspi->frequency(1000000);//1 MHz
+ wait(0.2);
+
+ //Emission de la commande POWER_UP (0x01)
+ sprintf(command, "%c%c%c", 0x01, 0x50, 0x05);//Quartz 32768Hz externe validé et sortie GPO2, sortie analogique validé
+ sendCommand(command, 3);
+ wait_ms(200);//Pas vu dans la doc ???
+
+ //Configure GPO lines to maximize stability
+ sprintf(command, "%c%c", 0x80,0x06);//GPO1 et GPO2 en sortie, GPO3 en haute impédance
+ sendCommand(command, 2);
+ wait_ms(10);
+ sprintf(command, "%c%c", 0x81,0x04);//toutes les sorties à zéro sauf GPO1 (pourquoi MISO à 1 ?)
+ sendCommand(command, 2);
+ wait_ms(10);
+
+ //Configure le volume à la valeur courante
+ setVolume(_volume);
+
+ //son sur les sorties audio
+ unmute();
+
+ setLocale(EU);//désaccentuation Europe = 50µs (filtrage)
+ /*
+ //Enable RDS
+ setProperty(0x1500, 0x0001);//positionne RDSINT quand la pile FIFO a des données RDS
+ setProperty(0x1501, 0x0004);//Minimum 4 groupes RDS stocké dans la FIFO (A,B,C et D)
+ //setProperty(0x1502, 0xEF01);//Validation RDS et config de la gestion des erreurs sur chaque bloc
+ //Only store good blocks and ones that have been corrected
+ setProperty(0x1502, 0xAA01);
+ //Only store good blocks
+ //setProperty(0x1502, 0x0001);//Validation RDS et aucune erreur sur les blocs
+ */
+ seekThresholds(2,14);//on ajuste le seuil pour rechercher plus de stations SNR=2, RSSI=14
+}
+
+
+void Si4735::tuneFrequency(uint16_t frequency)
+{
+ //Split the desired frequency into two character for use in the
+ //set frequency command.
+ uint8_t highByte = frequency >> 8;
+ uint8_t lowByte = frequency & 0x00FF;
+
+ //set the new frequency. Mode FM uniquement
+ sprintf(command, "%c%c%c%c", 0x20, 0x00, highByte, lowByte);
+ sendCommand(command, 4);
+ wait_ms(100);
+}
+#if defined(USE_SI4735_REV)
+void Si4735::getREV(char*FW,char*CMP,char *REV)
+{
+ //FW = Firmware and it is a 2 character array
+ //CMP = Component Revision and it is a 2 character array
+ //REV = Chip Revision and it is a single character
+ char response [16]={0};
+ sprintf(command, "%c", 0x10);
+
+ //Send the command
+ sendCommand(command, 1);
+
+ //Now read the response
+ getResponse(response);
+
+ FW[0]=response[2];
+ FW[1]=response[3];
+ FW[2]='\0';
+ CMP[0]=response[6];
+ CMP[1]=response[7];
+ CMP[2]='\0';
+ *REV=response[8];
+}
+#endif //USE_SI4735_REV
+
+uint16_t Si4735::getFrequency()
+{
+ char response [16]={0};
+ uint16_t frequency=0;
+ uint8_t highByte=0;
+ uint8_t lowByte=0;
+
+ //The FM_TUNE_STATUS command
+ sprintf(command, "%c%c", 0x22, 0x00);
+ //Send the command
+ sendCommand(command, 2);
+
+ //Now read the response
+ getResponse(response);
+
+ lowByte=response[3];
+ highByte=response[2];
+
+ frequency = (highByte<<8)+lowByte;
+ return frequency;
+}
+
+void Si4735::seekUp(void)
+{
+ //Use the current mode selection to seek up.
+ sprintf(command, "%c%c", 0x21, 0x0C);
+ sendCommand(command, 2);
+ wait_ms(1);
+}
+
+void Si4735::seekDown(void)
+{
+ //Use the current mode selection to seek down.
+ sprintf(command, "%c%c", 0x21, 0x04);
+ sendCommand(command, 2);
+ wait_ms(1);
+}
+
+void Si4735::seekThresholds(uint8_t SNR, uint8_t RSSI)
+{
+ //Use the current mode selection to set the threshold properties.
+ if(SNR>127)SNR=127;
+ else if(SNR<1)SNR=0;
+ if(RSSI>127)RSSI=127;
+ else if(RSSI<1)RSSI=0;
+ setProperty(0x1403, (uint16_t)SNR);
+ setProperty(0x1404, (uint16_t)RSSI);
+}
+
+#if defined(USE_SI4735_RSQ)
+void Si4735::getRSQ(Metrics * RSQ)
+{
+ //This function gets the Received Signal Quality Information
+ char response [16]={0};
+
+ //The FM_RSQ_STATUS command
+ sprintf(command, "%c%c", 0x23, 0x00);
+ //Send the command
+ sendCommand(command, 2);
+
+ //Now read the response
+ getResponse(response);
+
+ //Pull the response data into their respecive fields
+ RSQ->RSSI=response[4];
+ RSQ->SNR=response[5];
+
+ RSQ->STBLEND=response[3]&63;
+ RSQ->MULT=response[6];
+ RSQ->FREQOFF=response[7];
+}
+#endif
+
+uint8_t Si4735::volumeUp(void)
+{
+ //63 est le volume maximum
+ if(_volume < 63)
+ {
+ _volume+=1;
+ //Set the volume to the current value.
+ setProperty(0x4000, (uint16_t)_volume);
+ }
+ return _volume;
+}
+
+uint8_t Si4735::volumeDown(void)
+{
+ //If we're not at the minimum volume yet, decrease the volume
+ if(_volume > 0){
+ _volume-=1;
+ //Set the volume to the current value.
+ setProperty(0x4000, (uint16_t)_volume);
+ }
+ return _volume;
+}
+
+uint8_t Si4735::setVolume(uint8_t value)
+{
+ if(value <= 63 && value > 0){
+ _volume=value;
+ //Set the volume to the current value.
+ setProperty(0x4000, (uint16_t)_volume);
+ }
+ return _volume;
+}
+
+uint8_t Si4735::getVolume(void)
+{
+ return _volume;
+}
+
+void Si4735::mute(void)
+{
+ setProperty(0x4001, 0x0003);//coupe le son sur les voies gauche et droite
+}
+
+void Si4735::unmute(void)
+{
+ setProperty(0x4001, 0x0000);//son L et R ok
+}
+
+char Si4735::getStatus(void)
+{
+ char response=0;
+ //SS au niveau bas
+ SPISS->write(0);
+ wait_ms(1);
+ spiTransfer(0xA0); //Commande de lecture sur GPO1 d'un octet (MISO du SPI)
+ wait_ms(1);
+ response = spiTransfer(0x00); //Lecture de la réponse
+ //SS au niveau haut, fin de lecture
+ SPISS->write(1);
+ return response;
+}
+
+void Si4735::getResponse(char *response)
+{
+ //char cmd=0xE0;
+ //SS au niveau bas
+ SPISS->write(0);
+ wait_ms(1);
+ busspi->write(0xE0);//Commande de lecture d'une série de 16 octets sur GPO1 (MISO)
+ //spiTransfer(0xE0); //Commande de lecture d'une série de 16 octets sur GPO1 (MISO)
+ //wait_ms(1);
+ //lecture de 16 octets - le premier est l'octet de contrôle, puis les 15 data
+ //busspi->write(&cmd,1,response,16);
+ for(int i=0; i<16; i++) *response++ = busspi->write(0x00); //Lecture des 16 octets
+ //SS au niveau haut, fin de lecture
+ SPISS->write(1);
+}
+
+void Si4735::end(void)
+{
+ sprintf(command, "%c", 0x11);//Commande POWER_DOWN
+ sendCommand(command, 1);
+ wait_ms(1);
+}
+
+void Si4735::setLocale(uint8_t locale)
+{
+ _locale=locale;
+ //Set the deemphasis to match the locale
+ switch(_locale)
+ {
+ case NA:
+ setProperty(0x1100, 0x0002);
+ break;
+ case EU:
+ setProperty(0x1100, 0x0001);
+ break;
+ default:
+ break;
+ }
+}
+
+uint8_t Si4735::getLocale(void)
+{
+ return _locale;
+}
+
+
+void Si4735::setMode(char mode)
+{
+ end();
+ begin(mode);
+}
+
+char Si4735::getMode(void)
+{
+ return _mode;
+}
+
+//Envoie la commande 0x12 pour positionner la valeur value du paramètre situé à l'adresse address
+void Si4735::setProperty(uint16_t address, uint16_t value)
+{
+ sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, (address>>8)&255, address&255, (value>>8)&255, value&255);
+ sendCommand(command, 6);
+ wait_ms(1);
+}
+
+//Envoie la commande 0x13 pour lire la valeur du paramètre situé à l'adresse address.
+uint16_t Si4735::getProperty(uint16_t address)
+{
+ char response [16]={0};
+ sprintf(command, "%c%c%c%c", 0x13, 0x00, (address>>8)&255, address&255);
+ sendCommand(command, 4);
+ getResponse(response);
+ return response[2]<<8 | response[3];
+}
+
+/*******************************************
+*
+* Private Functions
+*
+*******************************************/
+//Ecriture ou lecture sur le bus SPI !
+char Si4735::spiTransfer(char value)
+{
+ return busspi->write(value);//Emission d'un octet ou lecture
+}
+
+//Ecriture de données dans le Si4735
+//length=8 octets maximum
+void Si4735::sendCommand(char * command, int length)
+{
+ //SS au niveau bas
+ SPISS->write(0);
+ wait_ms(1);
+ spiTransfer(0x48); //Octet de contrôle à 0x48 pour signifier une écriture dans le Si4735 (puis envoie de 8 octets de data)
+ for(int i=0; i<length; i++)spiTransfer(command[i]);
+ for(int i=length; i<8; i++)spiTransfer(0x00); //on compléte avec des 0 si la data est < à 8 octets.
+ //Fin de la séquence par SS au niveau haut
+ SPISS->write(1);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Si4735.h Mon Dec 16 07:37:25 2019 +0000
@@ -0,0 +1,243 @@
+/* Arduino Si4735 Library
+ * Written by Ryan Owens for SparkFun Electronics 5/17/11
+ * Altered by Wagner Sartori Junior 09/13/11
+ * Actively Being Developed by Jon Carrier
+ *
+ * This library is for use with the SparkFun Si4735 Shield
+ * Released under the 'Buy Me a Beer' license
+ * (If we ever meet, you buy me a beer)
+ *
+ * See the example sketches to learn how to use the library in your code.
+*/
+
+//Modifié par VG pour fonctionner sous MBED
+//14 Decembre 2017
+#include "mbed.h"
+
+#ifndef __SI4735_H
+#define __SI4735_H
+
+
+//#include <string.h>
+//#include <stdio.h>
+#include <ctype.h> //toupper
+
+//Ajouter par VG pour redéfinir les constantes Arduino INPUT, OUTPUT, LOW et HIGH
+//#define INPUT 0
+//#define OUTPUT 1
+//#define LOW 0
+//#define HIGH 1
+
+
+#define READ_DELAY 10
+//Comment out these 'defines' to strip down the Si4735 library features.
+//This will help you save memory space at the cost of features.
+#define USE_SI4735_REV
+#define USE_SI4735_RDS
+#define USE_SI4735_CALLSIGN
+#define USE_SI4735_PTY
+#define USE_SI4735_RADIOTEXT
+#define USE_SI4735_DATE_TIME
+#define USE_SI4735_RSQ
+
+//List of possible modes for the Si4735 Radio
+#define AM 0
+#define FM 1
+#define SW 2
+#define LW 3
+
+//Define the Locale options
+#define NA 0
+#define EU 1
+
+#define ON true
+#define OFF false
+
+#define MAKEINT(msb, lsb) (((msb) << 8) | (lsb))
+
+struct Metrics {
+ uint8_t STBLEND;
+ uint8_t RSSI;
+ uint8_t SNR;
+ uint8_t MULT;
+ uint8_t FREQOFF;
+};
+
+
+class Si4735// : public SPIClass
+{
+ public:
+ //This is just a constructor.
+ Si4735();
+ /*
+ * Description:
+ * Initializes the Si4735, powers up the radio in the desired mode and limits the bandwidth appropriately.
+ * This function must be called before any other radio command.
+ * The bands are set as follows:
+ * FM - 87.5 - 107.9 MHz
+ * AM - 520 - 1710 kHz
+ * SW - 2300 - 23000 khz
+ * LW - 152 - 279 kHz
+ * Parameters:
+ * mode - The desired radio mode. Use AM(0), FM(1), SW(2) or LW(3).
+ */
+ void begin(char mode);
+
+ /*
+ * Description:
+ * Acquires certain revision parameters from the Si4735 chip
+ * Parameters:
+ * FW = Firmware and it is a 2 character array
+ * CMP = Component Revision and it is a 2 character array
+ * REV = Chip Revision and it is a single character
+ */
+ #if defined(USE_SI4735_REV)
+ void getREV(char*FW,char*CMP,char *REV);
+ #endif
+
+ /*
+ * Description:
+ * Used to to tune the radio to a desired frequency. The library uses the mode indicated in the
+ * begin() function to determine how to set the frequency.
+ * Parameters:
+ * frequency - The frequency to tune to, in kHz (or in 10kHz if using FM mode).
+ */
+ void tuneFrequency(uint16_t frequency);
+
+ //Gets the frequency of the currently tuned station
+ uint16_t getFrequency();
+
+
+ // Commands the radio to seek up to the next valid channel. If the top of the band is reached, the seek
+ // will continue from the bottom of the band.
+ void seekUp(void);
+
+ // Commands the radio to seek down to the next valid channel. If the bottom of the band is reached, the seek
+ // will continue from the top of the band.
+ void seekDown(void);
+
+ /*
+ * Description:
+ * Adjust the threshold levels of the seek function.
+ * FM Ranges:
+ * SNR=[0-127], FM_default=3 dB
+ * RSSI=[0-127], FM_default=20 dBuV
+ * AM Ranges:
+ * SNR=[0-63], AM_default=5 dB
+ * RSSI=[0-63], AM_default=19 dBuV
+ */
+ void seekThresholds(uint8_t SNR, uint8_t RSSI);
+
+ // Retreives the Received Signal Quality Parameters/Metrics.
+ #if defined(USE_SI4735_RSQ)
+ void getRSQ(Metrics * RSQ);
+ #endif
+
+ // Sets the volume. If of of the 0 - 63 range, no change will be made.
+ uint8_t setVolume(uint8_t value);
+
+ // Gets the current volume.
+ uint8_t getVolume(void);
+
+ // Increasese the volume by 1. If the maximum volume has been reached, no increase will take place.
+ uint8_t volumeUp(void);
+
+ // Decreases the volume by 1. If the minimum volume has been reached, no decrease will take place.
+ uint8_t volumeDown(void);
+
+
+ // Coupe la sortie audio
+ void mute(void);
+
+ // Disables the mute.
+ void unmute(void);
+
+ /*
+ * Description:
+ * Gets the current status of the radio. Learn more about the status in the Si4735 datasheet.
+ * Returns:
+ * The status of the radio.
+ */
+ char getStatus(void);
+
+ /*
+ * Description:
+ * Gets the long response (16 characters) from the radio. Learn more about the long response in the Si4735 datasheet.
+ * Parameters:
+ * response - A string for the response from the radio to be stored in.
+ */
+ void getResponse(char * response);
+
+ // Powers down the radio
+ void end(void);
+
+ // Sets the Locale. This determines what Lookup Table (LUT) to use for the pyt_LUT.
+ void setLocale(uint8_t locale);
+
+ // Gets the Locale.
+ uint8_t getLocale(void);
+
+ // Gets the Mode of the radio [AM,FM,SW,LW]
+ char getMode(void);
+
+ /*
+ * Description:
+ * Sets the Mode of the radio [AM,FM,SW,LW]. This also performs a powerdown operation.
+ * The user is responsible for reissuing the begin method after this method has been called.
+ */
+ void setMode(char mode);
+
+ // Sets a property value
+ void setProperty(uint16_t address, uint16_t value);
+
+ /*
+ * Description:
+ * Gets a property value.
+ * Returns:
+ * The value stored in address.
+ */
+ uint16_t getProperty(uint16_t address);
+
+ private:
+ SPI *busspi;//(DATAOUT, DATAIN, SPICLOCK); // mosi, miso, sclk
+ DigitalOut *SPISS;
+ DigitalInOut *GPO2;//D2
+ DigitalInOut *GPO1;//D12
+ DigitalOut *POWER_PIN;//D8
+ DigitalOut *RADIO_RESET_PIN;//D9
+
+
+ char _mode; //Contains the Current Radio mode [AM,FM,SW,LW]
+ char _volume; //Current Volume
+ uint16_t _frequency; //Current Frequency
+ uint8_t _locale; //Contains the locale [NA, EU]
+
+ /*
+ * Command string that holds the binary command string to be sent to the Si4735.
+ */
+ char command[9];
+
+ /*
+ * Description:
+ * Sends a binary command string to the Si4735.
+ * Parameters:
+ * command - Binary command to be sent to the radio.
+ * length - The number of characters in the command string (since it can't be null terminated!)
+ * TODO:
+ * Make the command wait for a valid CTS response from the radio before releasing control of the CPU.
+ */
+ void sendCommand(char * command, int length);
+
+ /*
+ * Description:
+ * Sends/Receives a character from the SPI bus.
+ * Parameters:
+ * value - The character to be sent to the SPI bus.
+ * Returns:
+ * The character read from the SPI bus during the transfer.
+ */
+ char spiTransfer(char value);
+
+};
+
+#endif