AOSP Broadcastradio 1.0 types.hal - digital, signalStrength - android-source

i want to use this data type for notifying hd_digital_signal_exist and level of information to be imported
The question is in the description of this signalstrength - " Despite the name, this is not a signal strength.The purpose of this field is primarily informative." what does this mean?
/**
* Signal quality measured in 0% to 100% range.
*
* Despite the name, this is not a signal strength.
* The purpose of this field is primarily informative.
*/
uint32_t signalStrength;

Related

QSPI connection on STM32 microcontrollers with other peripherals instead of Flash memories

I will start a project which needs a QSPI protocol. The component I will use is a 16-bit ADC which supports QSPI with all combinations of clock phase and polarity. Unfortunately, I couldn't find a source on the internet that points to QSPI on STM32, which works with other components rather than Flash memories. Now, my question: Can I use STM32's QSPI protocol to communicate with other devices that support QSPI? Or is it just configured to be used for memories?
The ADC component I want to use is: ADS9224R (16-bit, 3MSPS)
Here is the image of the datasheet that illustrates this device supports the full QSPI protocol.
Many thanks
page 33 of the datasheet
The STM32 QSPI can work in several modes. The Memory Mapped mode is specifically designed for memories. The Indirect mode however can be used for any peripheral. In this mode you can specify the format of the commands that are exchanged: presence of an instruction, of an adress, of data, etc...
See register QUADSPI_CCR.
QUADSPI supports indirect mode, where for each data transaction you manually specify command, number of bytes in address part, number of data bytes, number of lines used for each part of the communication and so on. Don't know whether HAL supports all of that, it would probably be more efficient to work directly with QUADSPI registers - there are simply too many levers and controls you need to set up, and if the library is missing something, things may not work as you want, and QUADSPI is pretty unpleasant to debug. Luckily, after initial setup, you probably won't need to change very much in its settings.
In fact, some time ago, when I was learning QUADSPI, I wrote my own indirect read/write for QUADSPI flash. Purely a demo program for myself. With a bit of tweaking it shouldn't be hard to adapt it. From my personal experience, QUADSPI is a little hard at first, I spent a pair of weeks debugging it with logic analyzer until I got it to work. Or maybe it was due to my general inexperience.
Below you can find one of my functions, which can be used after initial setup of QUADSPI. Other communication functions are around the same length. You only need to set some settings in a few registers. Be careful with the order of your register manipulations - there is no "start communication" flag/bit/command. Communication starts automatically when you set some parameters in specific registers. This is explicitly stated in the reference manual, QUADSPI section, which was the only documentation I used to write my code. There is surprisingly limited information on QUADSPI available on the Internet, even less with registers.
Here is a piece from my basic example code on registers:
void QSPI_readMemoryBytesQuad(uint32_t address, uint32_t length, uint8_t destination[]) {
while (QUADSPI->SR & QUADSPI_SR_BUSY); //Make sure no operation is going on
QUADSPI->FCR = QUADSPI_FCR_CTOF | QUADSPI_FCR_CSMF | QUADSPI_FCR_CTCF | QUADSPI_FCR_CTEF; // clear all flags
QUADSPI->DLR = length - 1U; //Set number of bytes to read
QUADSPI->CR = (QUADSPI->CR & ~(QUADSPI_CR_FTHRES)) | (0x00 << QUADSPI_CR_FTHRES_Pos); //Set FIFO threshold to 1
/*
* Set communication configuration register
* Functional mode: Indirect read
* Data mode: 4 Lines
* Instruction mode: 4 Lines
* Address mode: 4 Lines
* Address size: 24 Bits
* Dummy cycles: 6 Cycles
* Instruction: Quad Output Fast Read
*
* Set 24-bit Address
*
*/
QUADSPI->CCR =
(QSPI_FMODE_INDIRECT_READ << QUADSPI_CCR_FMODE_Pos) |
(QIO_QUAD << QUADSPI_CCR_DMODE_Pos) |
(QIO_QUAD << QUADSPI_CCR_IMODE_Pos) |
(QIO_QUAD << QUADSPI_CCR_ADMODE_Pos) |
(QSPI_ADSIZE_24 << QUADSPI_CCR_ADSIZE_Pos) |
(0x06 << QUADSPI_CCR_DCYC_Pos) |
(MT25QL128ABA1EW9_COMMAND_QUAD_OUTPUT_FAST_READ << QUADSPI_CCR_INSTRUCTION_Pos);
QUADSPI->AR = (0xFFFFFF) & address;
/* ---------- Communication Starts Automatically ----------*/
while (QUADSPI->SR & QUADSPI_SR_BUSY) {
if (QUADSPI->SR & QUADSPI_SR_FTF) {
*destination = *((uint8_t*) &(QUADSPI->DR)); //Read a byte from data register, byte access
destination++;
}
}
QUADSPI->FCR = QUADSPI_FCR_CTOF | QUADSPI_FCR_CSMF | QUADSPI_FCR_CTCF | QUADSPI_FCR_CTEF; //Clear flags
}
It is a little crude, but it may be a good starting point for you, and it's well-tested and definitely works. You can find all my functions here (GitHub). Combine it with reading the QUADSPI section of the reference manual, and you should start to get a grasp of how to make it work.
Your job will be to determine what kind of commands and in what format you need to send to your QSPI slave device. That information is available in the device's datasheet. Make sure you send command and address and every other part on the correct number of QUADSPI lines. For example, sometimes you need to have command on 1 line and data on all 4, all in the same transaction. Make sure you set dummy cycles, if they are required for some operation. Pay special attention at how you read data that you receive via QUADSPI. You can read it in 32-bit words at once (if incoming data is a whole number of 32-bit words). In my case - in the function provided here - I read it by individual bytes, hence such a scary looking *destination = *((uint8_t*) &(QUADSPI->DR));, where I take an address of the data register, cast it to pointer to uint8_t and dereference it. Otherwise, if you read DR just as QUADSPI->DR, your MCU reads 32-bit word for every byte that arrives, and QUADSPI goes crazy and hangs and shows various errors and triggers FIFO threshold flags and stuff. Just be mindful of how you read that register.

STM32 HAL_I2C_Master_Transmit - Why we need to shift address?

after stumbling upon very strange thing I would like to find out if anyone could provide reasonable explanation.
I have SHT31 humidity sensor running on I2C and after trying to run it on STM32F2 it didn't work.
uint8_t __data[5]={0};
__data[0] = SHT31_SOFTRESET >> 8;
__data[1] = SHT31_SOFTRESET & 0xFF;
HAL_I2C_Master_Transmit(&hi2c3,((uint16_t)0x44)<<1,__data,2,1000);
I have opened the function and saw:
/**
* #brief Transmits in master mode an amount of data in blocking mode.
* #param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2C.
* #param DevAddress Target device address: The device 7 bits address value
* in datasheet must be shifted to the left before calling the interface
* #param pData Pointer to data buffer
* #param Size Amount of data to be sent
* #param Timeout Timeout duration
* #retval HAL status
*/
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
/* Init tickstart for timeout management*/
uint32_t tickstart = HAL_GetTick();
if (hi2c->State == HAL_I2C_STATE_READY)
....... and it goes ....
So I followed the comment and frustration from my scope (looking why my bits are not going on the wire) and did:
HAL_I2C_Master_Transmit(&hi2c3,((uint16_t)0x44)<<1,__data,2,1000);
Finally my bits are going out and device ACKs me back - voila it works!
But why?? What would be the reason behind putting burden on the programmer to shift the address?
Because the programmer should probably be made aware if he wants to read or write data to or from the I2C slave device.
In common I2C communication the first seven bits of the "address byte" contains the slave address, whereas the last bit is a read/write bit. 0 is write and 1 is read.
In your case, you want to write data to the device (to perform a soft reset) and therefore a simple left shift will do the trick.
It has never been agreed whether an I2C address is to be specified:
such that it needs to be shifted for transmission, or
such that it does not need to be shifted for transmission.
Therefore some device datasheets specify it in variant 1 and some in variant 2. Similarly, some I2C APIs take the address in variant 1 and some in variant 2.
If the device and the API use a different variant, it's the programmer's burden to shift the address.
It creates a lot of confusion and is quite annoying. I doubt it will every be clarified.
Sorry for the late reply, I just bumped my head against this myself. This should be considered a bug but ST refuses to acknowledge it as such. If you research the reference manual for the I2C section, the OAR1 register states that the address is stored in bits 7:1 for 7 bit mode. Bits 0, 8 and 9 are ignored. The HAL routine that sets the address should then shift the 7 LSB's so that bits 6:0 of your address get written to bits 7:1 of the OAR1 register. This doesn't happen. Essentially, because the code was released, it is now a "feature" and not a bug. Another way to look at it is that the address byte that you send to the HAL is left aligned. This is extremely irritating as it is not consistent for 7 and 10 bit addresses.

STM32F072RB does not receive/send data over SPI in slave mode

I am using the
STM32F072RB
uC to receive and transmit data over SPI2 in slave mode with the following configuration:
CR1 = 0x0078
CR2 = 0x0700
AFRH = 0x55353500
MODER = 0xa2a0556a
The register APB1ENR is also properly configured.
The current program just checks the RXNE flag, reads the received data from DR and sends a random value writing to DR.
The status register when I receive data has the following value:
SR = 0x1403
The master sends data properly and I checked the signals at the slave pins (clock phase and polarity are identical on both sides and the NSS signal is cleared before sending SCK and data over MOSI).
I even configured the pins as inputs and I know I could read any digital signal the master could send.
With the current configuration it seems the slave receives something because the RXNE is set when the master sends data but the read value is always 0x00.
I have tried different configurations (software/hardware NSS, different data sizes, etc.) but I always get 0x00.
Moreover, the random value I send after reading DR is not sent to the outputs.
This is my current function, which is called continuously:
unsigned char spi_rx_slave(unsigned char spiPort, unsigned char *receiveBuffer)
{
uint8_t temp;
static unsigned long sr;
if (!spi_isOpen(spiPort))
{
sendDebug("%s() Error: spiPort not in use!\r\n",__func__);
return false;
}
if (spiDescriptor[spiPort]->powerdown == true)
{
sendDebug("%s() Error: spiPort in powerdown!\r\n",__func__);
return false;
}
/* wait till spi is not busy anymore */
while((spiDescriptor[spiPort]->spiBase->SR) & SPI_SR_BSY)
{
sendDebug("SPI is busy(1)\r\n");
vTaskDelay(2);
}
sendDebug("CR1 = 0x%04x, ", spiDescriptor[spiPort]->spiBase->CR1);
sendDebug("CR2 = 0x%04x, ", spiDescriptor[spiPort]->spiBase->CR2);
sendDebug("AFRH address = 0x%08x, AFRH value = %08x, ", (unsigned long*)(GPIOB_BASE+0x24), *(unsigned long*)(GPIOB_BASE+0x24));
sendDebug("MODER address = 0x%08x, MODER value = %08x\r\n", (unsigned long*)(GPIOB_BASE), *(unsigned long*)(GPIOB_BASE));
sr = spiDescriptor[spiPort]->spiBase->SR;
while(sr & SPI_SR_RXNE)
{
/* get RX byte */
temp = *(uint8_t *)&(spiDescriptor[spiPort]->spiBase->DR);
spiDescriptor[spiPort]->spiBase->DR = 0x53;
sendDebug("-------->DR address = 0x%08x, data received: 0x%02x\r\n", &spiDescriptor[spiPort]->spiBase->DR, temp);
sendDebug("SR = 0x%04x\r\n", sr);
vTaskDelay(1);
sr = spiDescriptor[spiPort]->spiBase->SR;
}
while((spiDescriptor[spiPort]->spiBase->SR) & SPI_SR_BSY)
{
sendDebug("SPI is busy(2)\r\n");
vTaskDelay(2);
}
return true;
}
What am I doing wrong?
Is there anything I did not configure properly?
Thanks in advance.
Regards,
Javier
Edit:
I switched to software NSS and copied the register values from a STM32CubeMX example I found online. I cannot use those libraries for this project but I would like to have the same behaviour.
The new values are:
CR1 = 0x0278
which means
fPCLK/256 (the proper one for the communication speed),
SPI enabled and
SSM = 1 (software NSS).
CR2 = 0x1700
which means
8-bit data and
RXNE event is generated if the FIFO level is greater than or equal to 1/4 (8-bit).
AFRH = 0x55303500
MODER = 0xa8a1556a
which means
MISO, MOSI and SCK alternate function 5 (SPI2)
NSS is not configured because now it is in software mode (slave is always selected).
I am still getting the same results and the eval kit with those libraries works fine using SPI1 instead.
Therefore there must be another issue that has nothing to do with the register values.
Might there be any clock issue e.g. the pins need to get some clock?
Thanks!
The question points to a couple of mistakes which may explain why no receive has been observed:
GPIO configuration points to some wrong Alternate Functions / Modes:
The question didn't state it precisely, but I assume that
AFRH = 0x55303500
MODER = 0xa8a1556a
refers to GPIOB (otherwise, it wouldn't make sense with SPI2).
This corresponds to the following pin configuration (see the
Reference Manual,
sec. 8.4.1, 8.4.10 and the
Datasheet,
Table 16):
PB15 - Alternate Function - AF5 = [INVALID]
PB14 - Alternate Function - AF5 = [I2C2_SDA]
PB13 - Alternate Function - AF3 = [TSC_G6_IO3]
PB12 - GP Input (reset state)
PB11 - Alternate Function - AF3 = [TIM_CH4]
PB10 - Alternate Function - AF5 = [SPI2_SCK / I2S2_CK]
PB09 - GP Input (reset state)
PB08 - GP Output
PB07 - Alternate Function - (unknown which, see register AFRL)
PB06 - GP Output
PB05 - Alternate Function - (unknown which, see register AFRL)
PB04 - GP Output
PB03 - GP Output
PB02 - Alternate Function - (unknown which, see register AFRL)
PB01 - Alternate Function - (unknown which, see register AFRL)
PB00 - Alternate Function - (unknown which, see register AFRL)
This is obviously not what the software is required to do.
Solution: Make sure to configure PB15=>AF0, PB14=>AF0, either PB13=>AF0 or PB10=>AF0, depending on your hardware.
In order to avoid mistakes in doing so, you should follow the hint of #P__J__ and use speaking macros for constants assigned to MODER, AFRH etc.
Using the HAL library provided by ST is a truly controversial subject among SO users, but one should really consider to use at least a header like stm32f072xb.h with macros like GPIO_AFRH_AFSEL15.
If one represents all configuration register values as (bitwise) ORs of such macros, it is easier to re-check configuration against datasheets, and the famous
rubber duck
will directly know what an unhappy developer is talking about.
Other clock activations might be missing:
The question confirms that
The register APB1ENR is also properly configured.
This is correct (as long as bit 14 is set).
Additionally, GPIOB must be powered, i. e., bit 18 of RCC_AHBENR must be set.
See again the
Reference Manual,
sec. 6.4.8 and 6.4.6.
GPIO pins may be in wrong mode during debugging:
I even configured the pins as inputs and I know I could read any digital signal the master could send. With the current configuration it seems the slave receives something because the RXNE is set when the master sends data but the read value is always 0x00.
Please note that for every GPIO pin, a unique mode is selected through the MODER register. If this is set to "Input" (0b00), the Alternate Function is disconnected and won't work with external signals.

HM-10 Wont accept name and returning +NAME=?

Maybe someone had this problem.
"Send(AT)"
OK
"Send(AT+NAME?)"
+NAME=?
OK
"Send(AT+NAME1234)"
+NAME=1234
OK
"Send(AT+NAME?)"
+NAME=?
OK
Cant get this BLE HM-10 to remember name.
I was using FTDI and ch340, arduino monitor and realterm
Update!
After reset to defaults it started working Now i now its a genuine HM-10 and i have CC41-A
Command Description *
---------------------------------------------------------------- *
AT Check if the command terminal work normally *
AT+RESET Software reboot *
AT+VERSION Get firmware, bluetooth, HCI and LMP version *
AT+HELP List all the commands *
AT+NAME Get/Set local device name *
AT+PIN Get/Set pin code for pairing *
AT+PASS Get/Set pin code for pairing *
AT+BAUD Get/Set baud rate *
AT+LADDR Get local bluetooth address *
AT+ADDR Get local bluetooth address *
AT+DEFAULT Restore factory default *
AT+RENEW Restore factory default *
AT+STATE Get current state *
AT+PWRM Get/Set power on mode(low power) *
AT+POWE Get/Set RF transmit power *
AT+SLEEP Sleep mode *
AT+ROLE Get/Set current role. *
AT+PARI Get/Set UART parity bit. *
AT+STOP Get/Set UART stop bit. *
AT+START System start working. *
AT+IMME System wait for command when power on. *
AT+IBEA Switch iBeacon mode. *
AT+IBE0 Set iBeacon UUID 0. *
AT+IBE1 Set iBeacon UUID 1. *
AT+IBE2 Set iBeacon UUID 2. *
AT+IBE3 Set iBeacon UUID 3. *
AT+MARJ Set iBeacon MARJ . *
AT+MINO Set iBeacon MINO . *
AT+MEA Set iBeacon MEA . *
AT+NOTI Notify connection event . *
AT+UUID Get/Set system SERVER_UUID . *
AT+CHAR Get/Set system CHAR_UUID . *
-----------------------------------------------------------------*
Note: (M) = The command support slave mode only. *
For more information, please visit http://www.bolutek.com *
Copyright#2013 www.bolutek.com. All rights reserved. *
+VERSION=Firmware V3.0.6,Bluetooth V4.0 LE
Type to get value (Same is with other commands):
AT+NAME
Type to set value:
AT+NAMEnewName
You can try equal sign for set a value
AT+NAME=newName
edit for code prefix
try a shorter name. I had the same problem.some version do not accept long name

how to retrieve bus pointer from device tree

Question:
I'm trying to find a way to retrieve the dev object for an mdio_bus that has been added to the device tree. I'm sure I'm going to be rapidly applying my palm to my forehead when I get past this, but for the life of me, I can't find the answer anywhere. I've seen how to find objects on the bus itself using bus_find_device_by_name(), but I can't seem to find how to get the bus itself.
Background:
We are providing network access to our host using a Micrel KSZ8863 Ethernet switch attached to the MACB on an at919g20. Rather than using the fixed PHY option, I've spoofed MDIO address 0 to be a "fake" PHY representing the fixed MII link to the switch. I'm writing a driver for the switch to receive its interrupts and monitor the outward facing PHYs and control the link state of the "fake" PHY to the host. In order to configure the switch beyond basic MIIM configuration, you need to use SMI on the MDIO bus to access the full array of registers in the switch. Through further tweaking of the mii_read/write functions in the MACB, adding a header to the reg address, I believe I can use the MACB's MDIO/MII controller to do the right thing for SMI requests. Because the bus no longer gets addressed by PHY:REG, I need to be able to issue raw read/write commands straight to the bus from the switch driver. And that brings me back to my question: How do I request the dev object of the mdio_bus from the device tree by name?
Thanks,
Brian
After hunting around, fruitlessly, for a way to retrieve a device pointer to an mii_bus object, I ended up coming up with the following solution. I'm not sure its the best way to go about it, but it seems pretty clean. I basically ended up adding a helper function to mdio_bus.c that allows another driver to search for a bus by name using class_find_device(). I'm sure there is better way to do this, that doesn't involve adding onto the bus' driver, but it doesn't seem like the worst way either.
-Brian
Here are the functions I added to mdio_bus.c:
/**
* mdiobus_match_name - compares specified string to the device name
* #dev: device object to be examined
* #data: pointer to string to compare device name to
*
* Description: matching function used in call to class_find_device() to find
* a device with the specified name
*/
static int mdiobus_match_name( struct device * dev, void * data )
{
const char * name = data;
return sysfs_streq( name, dev_name( dev ) );
}
/**
* mdiobus_find_by_name - Convenience function for retrieving an mii_bus pointer
* by name
* #name: name of the bus being searched for
*/
struct mii_bus * mdiobus_find_by_name( char * name )
{
struct device * dev;
/* search devices registered for with the mdio_bus_class using the device
name as the matching criteria */
dev = class_find_device( &mdio_bus_class,
NULL,
(void *)name,
mdiobus_match_name );
/* return the mii_bus pointer or NULL if none was found */
return dev ? container_of( dev, struct mii_bus, dev ) : NULL;
}
EXPORT_SYMBOL( mdiobus_find_by_name );