I can't get data by I2C bus in Android Things - raspberry-pi

I can't get data by I2C bus in Android Things on Raspberry Pi 3.
I connect Android Things on RPi and DS18B20(Temperature Sensor).
Connect to RPi
and run the I2C address scan App (https://github.com/dennisg/i2c-address-scanner), but can't find available address.
for (int address = 0; address < 256; address++) {
//auto-close the devices
try (final I2cDevice device = peripheralManagerService.openI2cDevice(BoardDefaults.getI2cBus(), address)) {
try {
device.readRegByte(TEST_REGISTER);
Log.i(TAG, String.format(Locale.US, "Trying: 0x%02X - SUCCESS", address));
} catch (final IOException e) {
Log.i(TAG, String.format(Locale.US, "Trying: 0x%02X - FAIL", address));
}
} catch (final IOException e) {
//in case the openI2cDevice(name, address) fails
}
}
How do I get data by I2C?

The linked test project appears to use the I2C protocol poorly in several ways.
First, it makes the assumption that there is only a single I2C bus on a particular board. Although that is true now, it may not scale to additional SOMs that support Android Things in the future.
Second, it assumes the register address to read from (0x00). This may have worked for whatever device the developer started with, but a large number of I2C peripherals may not respond to that address.
You should take a look at the datasheet for this device. After a cursory examination, it seems that there is no register corresponding to 0x00. Additionally, it has a custom read flow that would make it difficult to use the snippet above. The microcontroller getting these values on your sensor probably throws them away and returns no signal.
It may be useful to read through the datasheet again. It seems like the sensor is "one-wire" instead of I2C. While the two protocols may be similar, using the built in readByte method may make some assumptions in the data transmission that may not match the peripheral protocol exactly.

As Nick Felker wrote in his answer DS18B20 has 1-Wire interface and you can't connect it to Raspberry Pi with Android Things directly. You should use industrial (e.g DS2482-100) or custom MCU-based (like in that project) 1-Wire <-> I2C converter, or other (e.g. USB <-> 1-Wire, UART<-> 1-Wire) converters.

Related

STM32L4 USB not appearing on computer as device

I have a STM32 Nucleo-64 development board with STM32L476RG MCU on it.. I have made a small PCB that, among other things, brings the USB interface to a connector.
I have followed the steps shown here: https://www.youtube.com/watch?v=rLnQ3W8gmjY
When I run the code in debug mode (in STM32CubeIDE v1.10.1) the USB never appears on my computer. I have also probed the USB data +/- signals and see no activity.
When I step through the code, I can see that something is failing immediately in:
MX_USB_DEVICE_Init()
USBD_Init()
The code the that fails is:
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
USBD_DescriptorsTypeDef *pdesc, uint8_t id)
{
USBD_StatusTypeDef ret;
/* Check whether the USB Host handle is valid */
if (pdev == NULL)
{
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Device handle");
#endif
return USBD_FAIL;
}
The exact line above that fails is if (pdev == NULL)
One thing to note is that the CubeMX tool did NOT add a handler declaration:
USBD_HandleTypeDef hUsbDeviceFS;
...despite me configuring up the USB interface... I added my own line in main.c:
extern USBD_HandleTypeDef hUsbDeviceFS;
..thinking it may be declared elsewhere??
Can someone please help me figure out whats going on?
Thanks!
Followed a video example online, but its not working as expected. I was expecting to see the dev board appear as a USB device on my computer and spit out some text.

what is the the hardware fifo size of STM32f103CB and how to know whether the FIFO is empty or full?

As the title mentioned, I can't find relevant information in the datasheet.
I get some problem when using UART. I have two chips, the master chip transmits packages to RS485 Bus line, and the slave chip receives it then transmits the respond(UART1), at the same time, every second the timer will transmit debugging stuff to pc by TTL(UART2), they should be mutual independent, however the UART1 doesn't work when UART2 is working, and the data is still transmiting to RS485 bus from master chip, so some of the data will not received by slave chip when slave chip is using UART2, after a while whole system on slave chip get weird (the timer is still working), I guess it is the FIFO overflow. So I am asking for function or ways to know the fifo size remain.
Thanks.
As Codo comments, this chip has not FIFO with USARTs.
after a while whole system on slave chip get weird
So your problem is not caused by the lackness of FIFO.
Besides using DMA for transfering, you could also use interrupt preemption to receive while transfer.
uart2_rcv_isr() {
receive_from_uart2();
}
timer_isr() {
mark_flag_for_uart1_transfer();
}
main() {
if(flag_for_uart2) {
reply_with_uart2();
unflag_uart2_task();
}
if(flag_for_timing_task) {
transfer_with_uart1();
clear_timing_task_flag();
}
}

Can't receive from USB bulk endpoint despite Windows enumerates and libusb reads descriptor of STM32 custom device class

For a fast ADC sampling USB device, I am using the USB 2.0 High Speed capable STM32F733 with the embedded USB-HS PHY. In USBView, I can see that the device is enumerated, the libusb code opens the device and claims interface, but when I try to receive data with libusb_bulk_transfer, the operation times out (return code -12). Things I have tried: I have confirmed than when I request data with libusb_bulk_transfer, the device is interrupted. Note: I have DMA enabled in my class configuration C file and it is not clear to me how that is triggered. I have verified that the transfersize and packet count registers are being set correctly by the LL library function, and that when I request data from
Any tips on debugging such problems will be much appreciated - this board is my undergrad thesis due in under two months!
Desktop sequence:
libusb_get_device_list, libusb_get_device_descriptor, libusb_open, libusb_get_string_descriptor_ascii, libusb_free_device_list, libusb_bulk_transfer(devh, fat_EPIN_ADDR, inframe, fat_EPIN_SIZE, &gotBytes, 100). Where gotBytes is integer, and inframe is a large array.
Device firmware:
MX_USB_DEVICE_Init();
uint8_t txBuffer[10*fat_EPIN_SIZE];
while (1)
{
USBD_LL_Transmit(&hUsbDeviceHS, Custom_fat_EPIN_ADDR, txBuffer, Custom_fat_EPIN_SIZE);
HAL_Delay(1);
}
Custom_fat_EPIN_SIZE is 0x200 and the endpoint address is 0x81 (EP IN 1)
Installed driver for device is WinUSB (verified in Device Manger to be winusb.sys), and I am linking libusb-1.0 into my desktop program. You can find my source code at https://gitlab.com/tywonemi-school-stuff/silicon-radar-fun, the firmware is My SW/v1 and the desktop software is a Qt Creator project in My SW/Viewer, of note is usb.cpp. You can also compare with testing project/HIDTest, which is code that I tested with STM32F303 nucleo dev board where I was able to read an array through IN bulk endpoint with the Viewer application. However, F3 has the USB peripheral, while F7 has OTG_USB, and I am now attempting USB 2.0 compliant HS so there may be more protocol-based pitfalls. You can also find the output of the device descriptor etc from USBView in my SW/USBView_broken.txt
EDIT 1: I have found finally some concrete error in the STM32 behavior. The DMAADDR is set for EPIN 0x81, and never increments, despite the DMA being enabled. I have went through literally every occurrence of the word "DMA" in the USB_OTG periphery.
I thought it might be that my linker script makes my array be stored in DTCM or similar, and the OTG DMA can't access it, but the address of txBuffer is 0x2003EBEC which is in SRAM2. The AHB matrix in the reference manual clearly shows, that the USB OTG HS DMA is master for a bus that SRAM2 is a slave of. And DTCM is connected too. I will look for application notes for USB OTG HS DMA - it just seems to be refusing to copy data!
I have fixed my issue by disabling the DMA setting. I have re-read the relevant portions of the reference manual and still don't know how exactly the values propagate into the Tx FIFOs. It is possible that DMA-less operation will be a major bottleneck in my project, I might return to this later.

Reading/writing SPI devices

(I am really unsure of which tags to apply, so apologies in advance if I chose the wrong ones.)
I hope that this is not a too stupid question, but I'm really lost here.
A client lent me an Atmel SAMA5D2 Xplained board with Linux4SAM to play around with. I'm trying to interface the SPI interface on it, but I have no clue where to start.
To be clear, I've used similar boards (not this particular one) bare-metal. I've also used Linux for many years and wrote a few simple devices drivers some years ago. And still I'm lost.
dmesg | grep spi gives me the following output:
[ 1.840000] atmel_spi f8000000.spi: version: 0x311
[ 1.840000] atmel_spi f8000000.spi: Using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers
[ 1.850000] atmel_spi f8000000.spi: Using FIFO (16 data)
[ 1.860000] atmel_spi f8000000.spi: Atmel SPI Controller at 0xf8000000 (irq 32)
[ 1.860000] m25p80 spi32766.0: at25df321a (4096 Kbytes)
From this I infer that a driver is loaded and that it is configured to use DMA. Yet, looking in /dev/ there is nothing that looks like a SPI device (I was expecting to find something like /dev/spidev or /dev/spi32766.0 or similar.)
Does this mean that there is no actual device driver loaded? Do I have to write one in order to use the SPI?
If I look at the Makefile in the Linux4SAM source tree, I see around line 1171 that the kernel does not support loading of modules. Does this imply I have to recompile the kernel to include my new driver? This seems to be a silly approach; why providing a Linux distribution if I can't access the hardware with it?
What am I missing here?
(I feel rather stupid...)
EDIT To be clear: I want to access the external SPI interface that will be connected to some external device. I think the m25p80 is some internal Flash memory; I'm not interested to read/write there.
spidev is a standard Linux device driver which just exports a low level API to userspace via /dev interface
if you want to access specific SPI client(slave) you should write your driver
according to Linux SPI driver model:
static const struct of_device_id myspi_dt_ids[] = {
{ .compatible = "xxxx,yyyyy" },
{},
static struct spi_driver xxx_spi_driver = {
.driver = {
.name = "myspi",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(myspi_dt_ids),
},
.probe = myspi_probe,
.remove = myspi_remove,
e.g. define spi_driver struct, of_device_id struct, callbacks(hooks), and register it.
You should bind it to your DT node with compatible property string.
myspi#0 {
compatible = "xxxx,yyyyy";
spi-max-frequency = <5000000>;
reg = <0>;
};
second,
compatible = "linux,spidev";
Linux discourages using this compatible property because nodes should
describe real HW devices not userspace abstractions
#0andriy put me on the right track. I had to add a SPI resource to the Device Tree and flash the compile Device Tree Blob to the board. (Since I didn't know about Device Trees at all, this information is really hard to find...).
I now have a /dev/spidev32765.0. I added this to the device tree:
spi1: spi#fc000000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi1_default>;
status = "okay";
spidev#0 {
compatible = "linux,spidev";
spi-max-frequency = <83000000>;
reg = <0>;
};
};
pinctrl#fc038000 {
pinctrl_spi1_default: spi1_default {
pinmux = <PIN_PD25__SPI1_SPCK>,
<PIN_PD26__SPI1_MOSI>,
<PIN_PD27__SPI1_MISO>,
<PIN_PD28__SPI1_NPCS0>;
bias-disable;
};
};
Although I read that adding the spidev#0 is not really the right thing to do (I indeed see in dmesg output "spidev spi32765.0: buggy DT: spidev listed directly in DT").
Now, if I run spidev_test it still doesn't work (it times out), but I guess that's for another question.

Bluetooth low energy (BLE 112 ) Difference between BGAPI and BGScript

What is the Difference between BGAPI and BGScript ?
And if we write any code for BG profile than how can we burn it in BLE 112?
The BGAPI interface defines the protocol used to talk to the module over USB or serial link.
BGScript is something which runs on the module processor itself, when the USB or serial link is not used.
I have the dongle, BLED112, which is the same thing as BLE112 with a USB connector on it, and the code is "burned" to it using standard USB DFU interface.
The downloading of the code to BLE112 can be done using several methods:
(1) Bring out the DD, DC debug interface pins from your module and use the CC-Debugger (digikey part 296-30207-ND, $55). This works every time. If you have the DKBLE112 kit, the CC-Debugger fits on the 10-pin .050 connector in lower right corner. You can "burn" any firmware and any stack this way. Works awesome.
(2) Hope that the current firmware on the CC2540 has serial bootloader, and load the new firmware (hopefully also containing serial bootloader) using UART. TI has the tools, but it sure seems quite convoluted to me, and I did not try it.