Avrdude unable to write - C232HM-DDHSL-0 Linux Mint - linux

I've been trying to program my ATmega644p using a C232HM-DDHSL-0 programmer which is based on the FT232H chip.
I've edited the .avrduderc in my home directory to include the following, which I've adapted from /etc/avrdude.conf:
programmer
id = "C232HM";
desc = "C232HM-MPSSE";
type = avrftdi;
usbvid = 0x0403;
# Note: This PID is reserved for generic H devices and
# should be programmed into the EEPROM
# usbpid = 0x8A48;
usbpid = 0x6014; // changed from 0x6010 after checking "lsusb"
usbdev = "A";
usbvendor = "";
usbproduct = "";
usbsn = "";
#ISP-signals // Modified according to datasheet
reset = 5;
sck = 2;
mosi = 3;
miso = 4;
;
I've been able to communicate with the MCU using avrdude using
sudo avrdude -c 2232HIO -p m644p -P /dev/ttyUSB0
where the output to terminal is:
Unknown type 6 (0x6) //Remainder pins - 1,2,7,8,9,10 not declared
Unknown type 6 (0x6)
Unknown type 6 (0x6)
Unknown type 6 (0x6)
Unknown type 6 (0x6)
Unknown type 6 (0x6)
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e960a
avrdude: safemode: Fuses OK
avrdude done. Thank you.
Ouput with -vvvv option enabled:
http://pastebin.com/z3K8RYJP
However when I try to flash a simple .hex file, it stalls while writing flash:
Unknown type 6 (0x6)
Unknown type 6 (0x6)
Unknown type 6 (0x6)
Unknown type 6 (0x6)
Unknown type 6 (0x6)
Unknown type 6 (0x6)
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e960a
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "int1.hex"
avrdude: input file int1.hex auto detected as Intel Hex
avrdude: writing flash (164 bytes):
Writing |
Output with the -vvvv option enabled:
http://pastebin.com/EmmuCsxN
I've also installed the D2XX drivers from FTDI and followed the steps as outlined in this guide, but to no avail: (see comment for links)
It seems that I'm unable to write to the MCU, so my first guess would be I've mis-configured the programmer. Any help would be much appreciated. Thanks!
EDIT: Just noticed that I was using the different command to communicate with the MCU :(
EDIT2: I fixed it using this config:
programmer
id = "C232HM";
desc = "C232HM-MPSSE";
type = avrftdi;
usbvid = 0x0403;
# Note: This PID is reserved for generic H devices and
# should be programmed into the EEPROM
# usbpid = 0x8A48;
usbpid = 0x6014;
usbdev = "A";
usbvendor = "";
usbproduct = "";
usbsn = "";
#ISP-signals
reset = 4;
sck = 1;
mosi = 2;
miso = 3;
;

Related

Linux Kernel DTSI File Cannot Compile from Yocto for BeagleBone

I am using the Texas Instruments official Yocto SDK to build a complete BSP for the Beaglebone X-15 ( TI AM5728 Processor ).
The entire SDK builds great for the MACHINE=am57xx-evm type from the SDK. Later SDKs include the MACHINE=beagle-x15, but I need this older version with Linux kernel 4.4.
The Linux kernel 4.4 in this SDK does have beagle-x15 device tree fragments included, but the machine configuration for the beagle x15 was not present, so I included the 1 conf file for the new machine from a later SDK.
The problem is that the Device Tree fails to compile - there is a syntax issue as shown in this traceback:
| Error: /home/user/tisdk/build/arago-tmp-external-linaro-toolchain/work-shared/beagle-x15/kernel-source/arch/arm/boot/dts/beagle-x15-cmem.dtsi:1.1-2 syntax error
| FATAL ERROR: Unable to parse input tree
| scripts/Makefile.lib:293: recipe for target 'arch/arm/boot/dts/am57xx-beagle-x15-revc.dtb' failed
| make[3]: *** [arch/arm/boot/dts/am57xx-beagle-x15-revc.dtb] Error 1
| arch/arm/Makefile:333: recipe for target 'am57xx-beagle-x15-revc.dtb' failed
| make[2]: *** [am57xx-beagle-x15-revc.dtb] Error 2
| Makefile:150: recipe for target 'sub-make' failed
| make[1]: *** [sub-make] Error 2
| Makefile:24: recipe for target '__sub-make' failed
| make: *** [__sub-make] Error 2
| WARNING: /home/user/tisdk/build/arago-tmp-external-linaro-toolchain/work/beagle_x15-linux-gnueabi/linux-ti-staging/4.4.41+gitAUTOINC+f9f6f0db2d-r7a.arago5.tisdk60/temp/run.do_compile.121513:1 exit 1 from 'exit 1'
| ERROR: oe_runmake failed
| ERROR: Function failed: do_compile (log file is located at /home/user/tisdk/build/arago-tmp-external-linaro-toolchain/work/beagle_x15-linux-gnueabi/linux-ti-staging/4.4.41+gitAUTOINC+f9f6f0db2d-r7a.arago5.tisdk60/temp/log.do_compile.121513)
Here is the entire DTSI file that fails to compile:
/ {
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
cmem_block_mem_0: cmem_block_mem#a0000000 {
reg = <0x0 0xa0000000 0x0 0x0c000000>;
no-map;
status = "okay";
};
cmem_block_mem_1_ocmc3: cmem_block_mem#40500000 {
reg = <0x0 0x40500000 0x0 0x100000>;
no-map;
status = "okay";
};
};
cmem {
compatible = "ti,cmem";
#address-cells = <1>;
#size-cells = <0>;
#pool-size-cells = <2>;
status = "okay";
cmem_block_0: cmem_block#0 {
reg = <0>;
memory-region = <&cmem_block_mem_0>;
cmem-buf-pools = <1 0x0 0x0c000000>;
};
cmem_block_1: cmem_block#1 {
reg = <1>;
memory-region = <&cmem_block_mem_1_ocmc3>;
};
};
};
Here is the beagle-x15.conf file:
##TYPE: Machine
##NAME: BeagleBoard X15
##DESCRIPTION: Machine configuration for the BeagleBoard X15
require conf/machine/include/dra7xx.inc
KERNEL_DEVICETREE = "am57xx-beagle-x15.dtb am57xx-beagle-x15-revb1.dtb am57xx-beagle-x15-revc.dtb"
MACHINE_GUI_CLASS = "bigscreen"
SERIAL_CONSOLE = "115200 ttyS2"
UBOOT_MACHINE = "am57xx_evm_config"
WKS_FILE = "sdimage-bootpart.wks"
IMAGE_BOOT_FILES = "MLO u-boot.img"
IMAGE_FSTYPES += "tar.xz wic.xz"
do_image_wic[depends] += "mtools-native:do_populate_sysroot dosfstools-native:do_populate_sysroot"
# UBI information. Note that this is board and kernel specific. Changes
# in your kernel port may require changes in these variables. For more
# details about this board please see
# http://processors.wiki.ti.com/index.php/UBIFS_Support
# do ubiattach /dev/ubi_ctrl -m 7 -O 2048
# From dmesg:
# UBI: smallest flash I/O unit: 2048
# UBI: logical eraseblock size: 126976 bytes
# from ubiattach stdout:
# UBI device number 0, total 1988 LEBs
MKUBIFS_ARGS = "-F -m 2048 -e 126976 -c 8192"
# do ubiattach /dev/ubi_ctrl -m 7 -O 2048
# from dmesg:
# UBI: smallest flash I/O unit: 2048
# UBI: physical eraseblock size: 131072 bytes (128 KiB)
# UBI: sub-page size: 512
# UBI: VID header offset: 2048 (aligned 2048)
UBINIZE_ARGS = "-m 2048 -p 128KiB -s 512 -O 2048"
How can I get this DTSI file to compile? Thanks.
UPDATE: It turns out the Ubuntu DTC compiler also fails ( Version 1.4 ):
dtc -O dtb -o /home/user/Desktop/test.dtb /home/user/tisdk/build/arago-tmp-external-linaro-toolchain/work-shared/beagle-x15/kernel-source/arch/arm/boot/dts/beagle-x15-cmem.dtsi
Error: /home/user/tisdk/build/arago-tmp-external-linaro-toolchain/work-shared/beagle-x15/kernel-source/arch/arm/boot/dts/beagle-x15-cmem.dtsi:1.1-2 syntax error
FATAL ERROR: Unable to parse input tree
dtc compiler by default treats the Device Tree version as 0 if no version is specified. Syntax for version 0 is different from version 1. So you need to add,
/dts-v1/;
as your fist line of device tree file.
Apart from this, usually you need to compile .dts file, not the .dtsi (which is include) directly. So you need to define according device tree file with .dts extension including .dtsi files.

How to set value of i2c PCA9570 gpio expander as early as possible during Linux boot?

I have written a working driver for the PCA9570. Its four outputs are set (and read back) via Linux's GPIO subsystem. e.g.
root#armbox:/sys/class/gpio# echo 508 > export
root#armbox:/sys/class/gpio# echo 509 > export
root#armbox:/sys/class/gpio# echo 510 > export
root#armbox:/sys/class/gpio# echo 511 > export
The problem is that the chip starts with its outputs high. https://www.nxp.com/docs/en/data-sheet/PCA9570.pdf section 8.1.
root#armbox:/sys/class/gpio# cat gpio508/value
1
root#armbox:/sys/class/gpio# cat gpio509/value
1
root#armbox:/sys/class/gpio# cat gpio510/value
1
root#armbox:/sys/class/gpio# cat gpio511/value
1
I can manually set them low from userspace, after boot. e.g.
root#armbox:/sys/class/gpio# echo 0 > gpio510/value
root#armbox:/sys/class/gpio# cat gpio510/value
0
How can I set the chip's outputs low as early as possible during the boot sequence?
I can hack my own driver to do this, during pca9570_probe(), but that feels very hacky. pca9570_probe() currently reads the values from the chip.
static int pca9570_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
...
ret = pca9570_readb(chip, &chip->reg);
if (ret)
goto out_failed;
return 0;
out_failed:
if (chip->client)
i2c_unregister_device(chip->client);
return -1;
}
Is there a correct way in Linux to specify GPIO values during boot, rather than hacking a driver?
P.S. The dts clause is:
pca9570: pca9570#48 {
compatible = "pca9570";
reg = <0x24>;
gpio-controller;
#gpio-cells = <4>;
};
You can use 'GPIO hogging' mechanism as described in DeviceTree gpio binding documentation. Quoting basic information:
GPIO hogging is a mechanism
providing automatic GPIO request and configuration as part of the
gpio-controller's driver probe function.
For example, we have this definition in our device tree for our gpio expander:
gpio_expander: tca6424a#22 {
compatible = "ti,tca6424";
reg = <0x22>;
[...] /* some other gpio expander configuration */
lcd-rst {
gpio-hog;
gpios = <7 GPIO_ACTIVE_LOW>;
output-low;
};
};
You don't need to extend your driver, it is part of the gpio subsystem.

Turn off power to a USB port

I'm looking for a way to turn power off (and back on) for a USB port. Solution can be in C, bash, etc. I'm using a BeagleBone running 32-bit Ubuntu 16.04 for armhf.
> uname -srvm
Linux 4.4.6-ti-r15 #1 SMP Tue Apr 5 12:32:22 UTC 2016 armv7l
I've tried many things discussed on StackOverflow and AskUbuntu, including:
#include <linux/usbdevice_fs.h>
int main(void)
{
int fd = open( "/dev/bus/usb/001/002", O_WRONLY );
if (fd < 0) return 1;
int rc = ioctl( fd, USBDEVFS_RESET, 0 );
if (rc < 0) return 2;
close( fd );
return 0;
}
The USB device I need to turn off (and eventually back on) is a Champtek FS310 barcode reader which shows up as a magnetic card strip reader when I run lsusb:
> lsusb
Bus 001 Device 002: ID 040b:6543 Weltrend Semiconductor Manhattan Magnetic Card Strip Reader
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
> lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 1: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
I've found that running these two commands results in the device turning off:
echo "1-1" > /sys/bus/usb/drivers/usb/unbind
echo "1-1" > /sys/bus/usb/drivers/usb/bind
Strangely enough, it only turns off during "bind", not "unbind". But once it turns off this way, the only way I've found to turn it back on is to reboot the computer, which is not a usable solution.
Indeed, that other question did have a technique that worked for what I was trying to do. Note this isn't a generic Linux answer, it will only work on BeagleBone Black and similar devices. (I tested on a BeagleBone Green.) Working backwards from the devmem2 example, this block of C++ code turns the USB power off, then back on:
const size_t page_size_in_bytes = getpagesize();
const size_t address_gpio3_13 = 0x47401c60; // see comment below
const size_t address_start = address_gpio3_13 / page_size_in_bytes * page_size_in_bytes;
const size_t address_offset = address_gpio3_13 - address_start;
int fd = open("/dev/mem", O_RDWR);
void *addr = mmap( 0, page_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address_start );
uint8_t *byte_ptr = reinterpret_cast<uint8_t*>(addr);
byte_ptr[address_offset] = 0x00; // turn off USB
std::this_thread::sleep_for( std::chrono::milliseconds(500) );
byte_ptr[address_offset] = 0x01; // turn on USB
munmap( addr, page_size_in_bytes );
close(fd);
(Error handling not included.)
The magic number 0x47401c60 really is a magic number. According to some posts, it looks like a NDA needs to be signed to get access to some of the USB-related documentation. In the ARM335X Technical Reference Manual, the only mention of the 0x47401Cxx address space is the following on page 156:
Block Name Start Address End Address
USB1 Core 0x4740_1C00 0x4740_1FFF

nrf24l01+ between arduino and raspberry Pi in NodeJS

I'm trying to retrieve my sensor data from my Raspberry Pi using nrf24l01+ network receiver.
I'm sending it from an Arduino nano board. Here is the setting of my Arduino:
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xcccccc3ccc 0xcccccc3c3c
RX_ADDR_P2-5 = 0x33 0xce 0x3e 0xe3
TX_ADDR = 0xcccccccc3c
RX_PW_P0-6 = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA = 0x3e
EN_RXADDR = 0x3f
RF_CH = 0x5a
RF_SETUP = 0x07
CONFIG = 0x0f
DYNPD/FEATURE = 0x3f 0x04
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
My Raspberry Pi is plugged with nrf24l01+ through GPIO. I made sure the connection is OK by using the C++ example given on https://github.com/TMRh20/RF24:
RF24 radio(RPI_BPLUS_GPIO_J8_15,RPI_BPLUS_GPIO_J8_24, BCM2835_SPI_SPEED_8MHZ);
The data is OK. Now i want to use a nodeJS program to get this data. I'm using this library: https://github.com/natevw/node-nrf
The code is very simple, but somehow is not working (console is silent):
var spiDev = "/dev/spidev0.0";
var cePin = 15; //RPI_BPLUS_GPIO_J8_15
var irqPin = null;
var channel = 0x5a; //90
var radio = require('nrf').connect(spiDev, cePin, irqPin);
radio
.channel(channel)
.dataRate('1Mbps')
.crcBytes(1)
// .autoRetransmit({count:15, delay:4000})
;
radio.begin(function () {
var rx = radio.openPipe('rx', 0xcccccccc3c);
rx.pipe(process.stdout);
});
I'm wondering what I'm doing wrong. Hardware is OK and the setting seems pretty good, what do you think?
Thanks
Usually to find out what is wrong with NRF you should start from basics:
Try simpler NRF configs to test if its working, especially with no CRC bytes etc.
Try it w/o dynamic payload and try fixed payload size on both ends.
Auto-acknowledge also can be an issue (note that when auto-ack is enabled, CRC can't be disabled as it is used to ensure transmission acknowledgement in this mode).
Ensure that CRC lengths match on both ends. In your example on Arduino you have CRC Length = 16 bits whether Raspberry configured with radio.crcBytes(1).
Don't rely on default values, always provide same full configuration on both ends.
These steps can considerably reduce time to locate the problem especially when using different libraries and platforms.

Retrieval of the error counters via TIOCGICOUNT returns always error (-1)

I have come across a show stopping problem when developing an interface application for a USB to RS422 converter module.
I need to retrieve the UART error counters for framing, overrun, parity and break errors. But the call to ioctl always returns -1 and the counter values from the retrieved struct are jumping to very big numbers.
The code i am using to retrieve the counters is the following:
struct serial_icounter_struct counters;
int ret = ioctl(portDescriptor, TIOCGICOUNT, &counters);
To set the portDescriptor i am using a similar code to:
int portDescriptor = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
struct termios new_port_settings;
//clear the new struct
memset(&new_port_settings, 0, sizeof(new_port_settings));
//set port settings
new_port_settings.c_cflag = B57600 | CS8 | CLOCAL | CREAD;
new_port_settings.c_oflag = 0;
new_port_settings.c_lflag = 0;
new_port_settings.c_cc[VMIN] = 0;
new_port_settings.c_cc[VTIME] = 0;
int error = tcsetattr(portDescriptor, TCSANOW, &new_port_settings)
Sometimes we also need to enable flow control or parity e.g.
new_port_settings.c_cflag = new_port_settings.c_cflag | CRTSCTS;
I have tried the code on a Ubuntu 11.10 32bit and on a SLES11 SP1 64bit, both with the FTDI_SIO kernel module.
Is anybody aware of any kind of issue regarding the usage of TIOCGICOUNT or am I doing something wrong?

Resources