The Riotboard User Manual doesn’t state clearly which side of the GPIO expansion port is which, so I made a diagram explaining it a bit better:
Print it out and align it with the board, and your job will be easier.
Also available in PDF form.
The Riotboard User Manual doesn’t state clearly which side of the GPIO expansion port is which, so I made a diagram explaining it a bit better:
Print it out and align it with the board, and your job will be easier.
Also available in PDF form.
For all you U-Boot users out there, if you set bootdelay=0
on a Riotboard, you will have problems if you ever want to get back into the U-Boot configuration menu.
To erase or modify the U-Boot environment settings, you need to create an /etc/fw_env.config
that the U-Boot userspace tools can use.
tl;dr
This is what the fw_env.config
file should look like on a Riotboard (at least, when using a build of Freescale’s General Availability kernels):
# Device Env. Offset Env. Size Flash Sector Size /dev/mmcblk3 0x60000 0x2000 0x1000
The U-Boot environment is saved to /dev/mmcblk3
, which is tricky, because the partition table explicitly defines an unused area at the beginning of the eMMC storage device.
Once you’ve got the configuration file in place, running fw_printenv
should show something like:
# fw_printenv baudrate=115200 boot_a_script=load ${devtype} ${devnum}:${bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr} boot_extlinux=sysboot ${devtype} ${devnum}:${bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf boot_prefixes=/ /boot/ boot_script_dhcp=boot.scr.uimg boot_scripts=boot.scr.uimg boot.scr boot_targets=mmc0 mmc1 mmc2 usb0 pxe dhcp bootcmd=run distro_bootcmd bootcmd_dhcp=usb start; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi bootcmd_mmc0=setenv devnum 0; run mmc_boot bootcmd_mmc1=setenv devnum 1; run mmc_boot bootcmd_mmc2=setenv devnum 2; run mmc_boot bootcmd_pxe=usb start; dhcp; if pxe get; then pxe boot; fi bootcmd_usb0=setenv devnum 0; run usb_boot bootdelay=0 bootm_size=0x10000000 distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done ethact=FEC ethprime=FEC fdt_addr_r=0x13000000 fdtfile=imx6dl-riotboard.dtb kernel_addr_r=0x12000000 loadaddr=0x12000000 mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi pxefile_addr_r=0x13200000 ramdisk_addr_r=0x13300000 scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${bootpart} bootfstype; then rune scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: cone scriptaddr=0x13100000 stderr=serial stdin=serial stdout=serial usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi
You can now use the fw_setenv
command to reset the bootdelay
parameter.
Figuring Out The Right Configuration Parameters
If you’re using the U-Boot riotboard_defconfig
, you’ll see:
#define CONFIG_SYS_EXTRA_OPTIONS "IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s1g.cfg,MX6S,DDR_MB=1024,ENV_IS_IN_MMC"
If you then look at include/configs/embestmx6boards.h
, you’ll see the configuration used to store the environment:
/* Environment organization */ #define CONFIG_ENV_SIZE (8 * 1024) #if defined(CONFIG_ENV_IS_IN_MMC) /* RiOTboard */ #define CONFIG_FDTFILE "imx6dl-riotboard.dtb" #define CONFIG_SYS_FSL_USDHC_NUM 3 #define CONFIG_SYS_MMC_ENV_DEV 2 /* SDHC4 */ #define CONFIG_ENV_OFFSET (6 * 64 * 1024) #define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */ #elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) ... #endif
Kind of a pain in the ass that no one at embest thought it would be useful to document this information.
It’s not you, it’s the crappy counterfeit FTDI chip in your USB to serial adapter. That is what is keeping your esptool.py
or esptool-ck
flash download from working.
When I first started using the esp8266, I had some serious problems getting esptool.py
and esptool-ck
working, due to one model of super-flaky, cheap USB serial adapter not working.
This had me tearing my hair out for a few weeks, as I tried replacing everything besides the serial adapter, which I had assumed could not possibly be the culprit.
After all, USB-to-serial conversion is a solved problem, right?
Wrong.
This page is a collection of reviews of the serial adapters I’ve used, which specifically have support for the DTR / RTS signaling used to automatically reset the esp8266 and put the chip into UART firmware download mode.
Here are the adapters I’ve tried:
A – FTDI FT232RQ (4D Systems uUSB-PA5 Adapter, available here)
B – FTDI FT232RL (Chinese YP-05 counterfeit, from eBay)
C – FTDI FT232H (genuine C232HD-EDHSP-0 cable, available here)
D – Prolific PL2303HX (probably counterfeit, from eBay)
E – Silicon Labs CP2102 (black PCB, from eBay)
F – Silicon Labs CP2102 (red PCB, from eBay)
G – Silicon Labs CP2104 (blue PCB, from eBay)
H – WinChipHead CH340G (from eBay)
If there are any modules I’ve missed, or you think I should test, feel free to drop me a line with a link to where I can buy one. (Or you could send me one, I’d be happy.)
Also feel free to drop me any questions you might have about getting set up with the esp8266, I’ve got way more brain damage learning how to do this myself, so perhaps I could share some of it with you!
tl;dr
Buy either an adapter with a genuine FTDI chip, or one of the Silicon Labs CP2102 chips.
Test Results
Here are the results when testing the adapters at various baud rates with the following modules:
ESP-01 (4Mbit, 25Q41BT, blue PCB)
Adapter | 3M | 1.5M | 921.6 | 460.8 | 230.4 | 115.2 | Log |
---|---|---|---|---|---|---|---|
A | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
B | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |
C | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
D | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | link |
E | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
F | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
G | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
H | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | link |
ESP-01 (8Mbit, BergMicro 25Q80A, black PCB)
Adapter | 3M | 1.5M | 921.6 | 460.8 | 230.4 | 115.2 | Log |
---|---|---|---|---|---|---|---|
A | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
B | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |
C | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
D | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | link |
E | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
F | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
G | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
H | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | link |
ESP-12 (32Mbit, flash_id e0 / 4016, blue PCB)
Adapter | 3M | 1.5M | 921.6 | 460.8 | 230.4 | 115.2 | Log |
---|---|---|---|---|---|---|---|
A | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
B | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | link |
C | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
D | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | link |
E | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
F | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
G | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
H | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | link |
ESP-12E (32Mbit, flash_id e0 / 4016, black PCB)
Adapter | 3M | 1.5M | 921.6 | 460.8 | 230.4 | 115.2 | Log |
---|---|---|---|---|---|---|---|
A | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
B | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |
C | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
D | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | link |
E | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
F | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
G | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | link |
H | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | link |
Pin Voltages When Idle
Adapter | Vcc | DTR | RTS | TX | RX |
---|---|---|---|---|---|
A | 5.10 | 3.44 | 3.44 | 1.66 | 1.49 |
B | 5.10 | 0.00 | 3.53 | 3.53 | 0.00 |
C | 5.09 | 3.32 | 3.32 | 3.32 | 2.43 |
D | 5.11 | 3.46 | 3.46 | 3.46 | 2.14 |
E | 5.10 | 3.37 | 3.37 | 3.37 | 3.28 |
F | 5.09 | 3.37 | 3.37 | 3.37 | 3.53 |
G | 5.10 | 2.25 | 3.41 | 3.41 | 3.15 |
H | 5.11 | 3.70 | 3.70 | 3.70 | 3.63 |
Test Setup
Here are the perfboards I built to program the modules:
Version 0
Only works with the 4D Systems uUSB-PA5 Adapter. Two other programming circuits on board require manual reset/mode selection and do not work.
Version 1
Version 2
Improved upon Version 1, by making a common header layout for programming: 5V (red), GND (green), DTR (yellow), RTS (blue), TX (orange), RX (gray).
The trace wires are shorter and more uniform this way, and there’s less chance of screwing up the adaptation wiring. Also, the adapters all become interchangeable, which improves test consistency.
Test Script
I’ve created a test script to test each USB adapter, using a variety of baud rates. The code is on Github here.
FTDI FT232RQ (4D Systems uUSB-PA5 Adapter)
Works.
FTDI FT232RL (Chinese counterfeit)
Does not work.
Markings on the board call it a YP-05. You can get these for about 3 EUR on eBay, and they work reasonably well as plain USB serial adapters. But they always fail for me while programming the esp8266, with the following errors:
$ ./esptool.py write_flash 0x00000 x.bin Connecting... Erasing flash... Took 2.21s to erase flash block Writing at 0x00008000... (7 %) A fatal error occurred: Invalid head of packet
and:
esptool.py v1.0.2-dev Traceback (most recent call last): File "./esptool.py", line 1213, inmain() File "./esptool.py", line 1122, in main esp = ESPROM(args.port, initial_baud) File "./esptool.py", line 70, in __init__ self._port = serial.Serial(port) File "/usr/local/lib/python2.7/dist-packages/serial/serialutil.py", line 180, in __init__ self.open() File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 311, in open self._update_dtr_state() File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 605, in _update_dtr_state fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str) IOError: [Errno 5] Input/output error
The esptool programmer always stops flashing at some percentage point.
FTDI FT232H Cable (C232HD-EDHSP-0)
Works.
Prolific PL2303HX
Works, sometimes.
I honestly did not expect them to. Hilariously, these come shrink wrapped in plastic, because the USB plug support posts aren’t even soldered!
These are probably counterfeit chips, too, but who knows? Also, they don’t really work in Windows, after Prolific disabled support for counterfeit devices (though sometimes I wonder how they even know).
Thanks to Daniel for soldering the DTR and RTS wires onto the extremely thin SSOP pins. For great justice!
[30217.752502] usb 3-1.4: new full-speed USB device number 32 using ehci-pci [30217.845449] usb 3-1.4: New USB device found, idVendor=067b, idProduct=2303 [30217.845454] usb 3-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [30217.845457] usb 3-1.4: Product: USB-Serial Controller [30217.845459] usb 3-1.4: Manufacturer: Prolific Technology Inc. [30217.845884] pl2303 3-1.4:1.0: pl2303 converter detected [30217.847596] usb 3-1.4: pl2303 converter now attached to ttyUSB1
Bus 003 Device 032: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
$ ./esptool.py read_mac esptool.py v1.0.2-dev Connecting... MAC: 5c:cf:7f:07:8e:cd $ ./esptool.py chip_id esptool.py v1.0.2-dev Connecting... Chip ID: 0x00078ecd $ ./esptool.py flash_id esptool.py v1.0.2-dev Connecting... Manufacturer: e0 Device: 4016 $ ./esptool.py read_flash 0x0 0x80000 x.bin esptool.py v1.0.2-dev Connecting... Running Cesanta flasher stub... Reading 524288 @ 0x0... 524288 (100 %) Read 524288 bytes at 0x0 in 49.9 seconds (84.0 kbit/s)... $ ./esptool.py write_flash 0x0 x.bin esptool.py v1.0.2-dev Connecting... Running Cesanta flasher stub... Flash params set to 0x0000 Writing 524288 @ 0x0... 524288 (100 %) Wrote 524288 bytes at 0x0 in 46.1 seconds (90.9 kbit/s)... Leaving...
Silicon Labs CP2102 (black PCB)
Works.
Silicon Labs CP2102 (red PCB)
Works.
[ 7727.919777] usb 2-1: new full-speed USB device number 4 using xhci_hcd [ 7728.049611] usb 2-1: New USB device found, idVendor=10c4, idProduct=ea60 [ 7728.049616] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 7728.049619] usb 2-1: Product: CP2102 USB to UART Bridge Controller [ 7728.049621] usb 2-1: Manufacturer: Silicon Labs [ 7728.049623] usb 2-1: SerialNumber: 0001 [ 7729.078772] usbcore: registered new interface driver usbserial [ 7729.078985] usbcore: registered new interface driver usbserial_generic [ 7729.079148] usbserial: USB Serial support registered for generic [ 7729.083795] usbcore: registered new interface driver cp210x [ 7729.083830] usbserial: USB Serial support registered for cp210x [ 7729.083862] cp210x 2-1:1.0: cp210x converter detected [ 7729.084803] usb 2-1: cp210x converter now attached to ttyUSB0
Bus 002 Device 007: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge / myAVR mySmartUSB light
$ ./esptool.py read_flash 0x0 0x80000 x.bin esptool.py v1.0.2-dev Connecting... Running Cesanta flasher stub... Reading 524288 @ 0x0... 524288 (100 %) Read 524288 bytes at 0x0 in 60.8 seconds (69.0 kbit/s)... $ ./esptool.py write_flash 0x0 x.bin esptool.py v1.0.2-dev Connecting... Running Cesanta flasher stub... Flash params set to 0x0000 Writing 524288 @ 0x0... 524288 (100 %) Wrote 524288 bytes at 0x0 in 45.5 seconds (92.3 kbit/s)... Leaving...
Silicon Labs CP2104 (blue PCB)
Works!
After modifying the DTR line to bypass the capacitor as suggested by comments from 0xPIT, this adapter works as expected.
Doesn’t work.
Persistent errors on DTR line:
$ python esptool.py --port /dev/ttyUSB0 chip_id esptool.py v1.0.2-dev Connecting... Traceback (most recent call last): File "esptool.py", line 1214, inmain() File "esptool.py", line 1124, in main esp.connect() File "esptool.py", line 159, in connect self._port.setDTR(False) File "/usr/local/lib/python2.7/dist-packages/serial/serialutil.py", line 547, in setDTR self.dtr = value File "/usr/local/lib/python2.7/dist-packages/serial/serialutil.py", line 411, in dtr self._update_dtr_state() File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 607, in _update_dtr_state fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str) IOError: [Errno 5] Input/output error $ python esptool.py --port /dev/ttyUSB0 chip_id esptool.py v1.0.2-dev Connecting... A fatal error occurred: Failed to connect to ESP8266 $ python esptool.py --port /dev/ttyUSB0 flash_id esptool.py v1.0.2-dev Connecting... Traceback (most recent call last): File "esptool.py", line 1214, in main() File "esptool.py", line 1124, in main esp.connect() File "esptool.py", line 159, in connect self._port.setDTR(False) File "/usr/local/lib/python2.7/dist-packages/serial/serialutil.py", line 547, in setDTR self.dtr = value File "/usr/local/lib/python2.7/dist-packages/serial/serialutil.py", line 411, in dtr self._update_dtr_state() File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 607, in _update_dtr_state fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str) IOError: [Errno 5] Input/output error
[12903.595812] usb 2-1: new full-speed USB device number 12 using xhci_hcd [12903.725411] usb 2-1: New USB device found, idVendor=10c4, idProduct=ea60 [12903.725416] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [12903.725418] usb 2-1: Product: CP2104 USB to UART Bridge Controller [12903.725420] usb 2-1: Manufacturer: Silicon Labs [12903.725422] usb 2-1: SerialNumber: 0100ACEA [12903.726485] cp210x 2-1:1.0: cp210x converter detected [12903.727140] usb 2-1: cp210x converter now attached to ttyUSB0
Bus 002 Device 012: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge / myAVR mySmartUSB light
WinChipHead CH340G
Works!
These things are so ridiculously cheap. They’re normally covered in a shrink-wrap plastic tube, which is because the two USB support pins aren’t even soldered!
These are more work, you have to wire the DTR / RTS lines on the SOP package.
[11337.449533] usb 2-1: new full-speed USB device number 6 using xhci_hcd [11337.578783] usb 2-1: New USB device found, idVendor=1a86, idProduct=7523 [11337.578788] usb 2-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0 [11337.578790] usb 2-1: Product: USB2.0-Serial [11338.602146] usbcore: registered new interface driver ch341 [11338.602511] usbserial: USB Serial support registered for ch341-uart [11338.602547] ch341 2-1:1.0: ch341-uart converter detected [11338.604752] usb 2-1: ch341-uart converter now attached to ttyUSB0
Bus 002 Device 006: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
$ ./esptool.py read_flash 0x0 0x80000 x.bin esptool.py v1.0.2-dev Connecting... Running Cesanta flasher stub... Reading 524288 @ 0x0... 524288 (100 %) Read 524288 bytes at 0x0 in 50.8 seconds (82.5 kbit/s)... $ ./esptool.py write_flash 0x0 x.bin esptool.py v1.0.2-dev Connecting... Running Cesanta flasher stub... Flash params set to 0x0000 Writing 524288 @ 0x0... 524288 (100 %) Wrote 524288 bytes at 0x0 in 45.5 seconds (92.3 kbit/s)... Leaving...
For posterity for me (verbatim from here, thanks to the original poster):
- Change #AutoEnable=false to AutoEnable=true in the /etc/bluetooth/main.conf (notice new line is un-commented)
- Unpair the headset
- Restart the bluetooth service sudo /etc/init.d/bluetooth restart
- Pair your headset again and connect it
- Go to sound settings. From the output device tab you should now see the headset listed along with other output device like internal speakers
- Choose it as the sound output device.
Still scratching my head as to why this stuff still doesn’t work out of the box in 2016, even though all the pieces are there to make it work. Linux could be so much easier.
It’s probably no secret that I hate using Eclipse. It’s always been a slow, memory-hungry, nigh-untamable beast. It’s always made my computers feel inadequate, even if they’re perfectly fine for everything else.
After playing around a bit with NetBeans for an embedded systems project using the Nordic Semiconductor nRF5-series chips, I like Eclipse even less.
NetBeans has a great parser for existing Makefile-based projects.
All I had to do was:
Create a new GCC toolchain in NetBeans:
The awesome thing is that as soon as you hit Apply, NetBeans scans the folders around your new toolchain and figures out automatically where the right include
folders are:
Create a new project using existing Makefile:
You may get a failure right after the project is imported, NetBeans will attempt to make
the Makefile
once, in order to automatically detect all of the -D
defines, -I
include folders, and -L
library folders.
cd '/Users/max/Downloads/nRF5/examples/peripheral/blinky/pca10036/blank/armgcc' /usr/bin/make -f Makefile rm -rf _build echo Makefile Makefile mkdir _build Compiling file: system_nrf52.c make: /usr/local/gcc-arm-none-eabi-4_9-2015q1/bin/arm-none-eabi-gcc: No such file or directory make: *** [_build/system_nrf52.o] Error 1 BUILD FAILED (exit value 2, total time: 61ms)
The problem is an incorrect gcc compiler version, which comes from included Makefile settings in the nRF52 SDK.
Open up components/toolchain/gcc/Makefile.posix
in the SDK, and change the GNU_INSTALL_ROOT
and GNU_VERSION
defines to reflect the real version of the GNU tools that you downloaded.
In my case, these are:
GNU_INSTALL_ROOT := /Users/max/Downloads/gcc-arm-none-eabi-5_2-2015q4 GNU_VERSION := 5.2.1
Now delete and re-create the NetBeans project, and it will automatically run the Makefile and create references to the source files used:
cd '/Users/max/Downloads/nRF5/examples/peripheral/blinky/pca10036/blank/armgcc' /usr/bin/make -f Makefile clean rm -rf _build CLEAN SUCCESSFUL (total time: 112ms) cd '/Users/max/Downloads/nRF5/examples/peripheral/blinky/pca10036/blank/armgcc' /usr/bin/make -f Makefile rm -rf _build echo Makefile Makefile mkdir _build Compiling file: system_nrf52.c Compiling file: main.c Compiling file: nrf_delay.c Compiling file: gcc_startup_nrf52.s Linking target: nrf52832_xxaa.out Preparing: nrf52832_xxaa.bin Preparing: nrf52832_xxaa.hex text data bss dec hex filename 2464 108 28 2600 a28 _build/nrf52832_xxaa.out BUILD SUCCESSFUL (total time: 1s)
Done! You should see a complete project in the projects window (if not, try deleting the project and re-creating it):
Now Autocomplete and Jump to Source work!
I must’ve spent a day and a ton of googling to figure out this same level of functionality using Eclipse, and even then the autocomplete would usually glitch. Never mind the hard disk thrashing that Eclipse always seemed to give my systems.
Kudos to the NetBeans team for making my day easier!