Skip to content

Commit

Permalink
Added support for Arduino IDE
Browse files Browse the repository at this point in the history
  • Loading branch information
wagiminator committed Apr 4, 2023
1 parent b272ce8 commit ff8967c
Show file tree
Hide file tree
Showing 37 changed files with 305 additions and 181 deletions.
51 changes: 37 additions & 14 deletions picoAVR_Programmer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,58 @@ The CH552G is a low-cost, enhanced E8051 core microcontroller compatible with th
![picoAVR_pic3.jpg](https://raw.githubusercontent.com/wagiminator/AVR-Programmer/master/picoAVR_Programmer/documentation/picoAVR_pic3.jpg)

# Compiling and Installing Firmware
## Installing Toolchain for CH55x
Install the [CH55x Software Development Kit for the SDCC compiler](https://github.com/Blinkinlabs/ch554_sdcc). Follow the instructions on the website. In order for the programming tool to work, Python3 must be installed on your system. To do this, follow these [instructions](https://www.pythontutorial.net/getting-started/install-python/). In addition [PyUSB](https://github.com/pyusb/pyusb) must be installed. On Linux (Debian-based), all of this can be done with the following commands:

```
sudo apt install build-essential sdcc python3 python3-pip
sudo pip install pyusb
```

## Installing Drivers for the CH55x Bootloader
## Preparing the CH55x Bootloader
### Installing Drivers for the CH55x Bootloader
On Linux you do not need to install a driver. However, by default Linux will not expose enough permission to upload your code with the USB bootloader. In order to fix this, open a terminal and run the following commands:

```
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="4348", ATTR{idProduct}=="55e0", MODE="666"' | sudo tee /etc/udev/rules.d/99-ch55x.rules
sudo service udev restart
```

On Windows you will need the [Zadig tool](https://zadig.akeo.ie/) to install the correct driver for the CH55x bootloader. Click "Options" and "List All Devices" to select the USB module, then install the libusb-win32 driver.
On Windows you will need the [Zadig tool](https://zadig.akeo.ie/) to install the correct driver. Click "Options" and "List All Devices" to select the USB module, then install the libusb-win32 driver. To do this, the board must be connected and the CH55x must be in bootloader mode.

## Entering CH55x Bootloader Mode
### Entering CH55x Bootloader Mode
A brand new chip starts automatically in bootloader mode as soon as it is connected to the PC via USB. Once firmware has been uploaded, the bootloader must be started manually for new uploads. To do this, the board must first be disconnected from the USB port and all voltage sources. Now press the BOOT button and keep it pressed while reconnecting the board to the USB port of your PC. The chip now starts again in bootloader mode, the BOOT button can be released and new firmware can be uploaded within the next couple of seconds.

## Compiling and Uploading Firmware
Open a terminal and navigate to the folder with the makefile. Run ```make flash``` to compile and upload the firmware. If you don't want to compile the firmware yourself, you can also upload the precompiled binary. To do this, just run ```python3 ./tools/chprog.py picoavr.bin```.
## Compiling and Uploading using the makefile
### Installing SDCC Toolchain for CH55x
Install the [SDCC Compiler](https://sdcc.sourceforge.net/). In order for the programming tool to work, Python3 must be installed on your system. To do this, follow these [instructions](https://www.pythontutorial.net/getting-started/install-python/). In addition [pyusb](https://github.com/pyusb/pyusb) must be installed. On Linux (Debian-based), all of this can be done with the following commands:

```
sudo apt install build-essential sdcc python3 python3-pip
sudo pip install pyusb
```

### Compiling and Uploading Firmware
- Open a terminal.
- Navigate to the folder with the makefile.
- Connect the board and make sure the CH55x ist in bootloader mode.
- Run ```make flash``` to compile and upload the firmware.
- If you don't want to compile the firmware yourself, you can also upload the precompiled binary. To do this, just run ```python3 ./tools/chprog.py picoavr.bin```.

## Compiling and Uploading using the Arduino IDE
### Installing the Arduino IDE and CH55xduino
Install the [Arduino IDE](https://www.arduino.cc/en/software) if you haven't already. Install the [CH55xduino](https://github.com/DeqingSun/ch55xduino) package by following the instructions on the website.

### Compiling and Uploading Firmware
- Copy the .ino and .c files as well as the /src folder together into one folder and name it picoavr.
- Open the .ino file in the Arduino IDE.
- Go to **Tools -> Board -> CH55x Boards** and select **CH552 Board**.
- Go to **Tools** and choose the following board options:
- **Clock Source:** 16 MHz (internal)
- **Upload Method:** USB
- **USB Settings:** USER CODE /w 266B USB RAM
- Connect the board and make sure the CH55x ist in bootloader mode.
- Click **Upload**.

## Installing Drivers for the picoAVR
On Linux you do not need to install a driver. Windows users may need to install the usbtiny driver (https://learn.adafruit.com/usbtinyisp) and a CDC driver using the [Zadig tool](https://zadig.akeo.ie/).

# Operating Instructions
- Select the programming voltage (3.3V or 5V) with the voltage selection switch.
- Plug the picoAVR into a USB port on your PC, it should be identified as a USBtinyISP with an additional CDC serial interface.
- Connect the picoAVR to the target board via the 6-pin ICSP connector or the 3-pin UPDI connector.
- Windows users may need to install a driver for USBtinyISP (https://learn.adafruit.com/usbtinyisp) and CDC (https://zadig.akeo.ie/).
- The picoAVR should work with any IDE or programming software that supports the USBtinyISP and/or SerialUPDI programmer.

# References, Links and Notes
Expand Down
6 changes: 3 additions & 3 deletions picoAVR_Programmer/software/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
# Input and Output File Names
SKETCH = picoavr.c
TARGET = picoavr
INCLUDE = include
INCLUDE = src

# Microcontroller Settings
FREQ_SYS = 16000000
XRAM_SIZE = 0x0300
XRAM_LOC = 0x0100
XRAM_SIZE = 0x0300
CODE_SIZE = 0x3800

# Toolchain
Expand All @@ -27,7 +27,7 @@ WCHISP ?= python3 tools/chprog.py
# Compiler Flags
CFLAGS = -mmcs51 --model-small --no-xinit-opt
CFLAGS += --xram-size $(XRAM_SIZE) --xram-loc $(XRAM_LOC) --code-size $(CODE_SIZE)
CFLAGS += -I$(INCLUDE) -DFREQ_SYS=$(FREQ_SYS)
CFLAGS += -I$(INCLUDE) -DF_CPU=$(FREQ_SYS)
CFILES = $(SKETCH) $(wildcard $(INCLUDE)/*.c)
RFILES = $(CFILES:.c=.rel)
CLEAN = rm -f *.ihx *.lk *.map *.mem *.lst *.rel *.rst *.sym *.asm *.adb
Expand Down
Binary file modified picoAVR_Programmer/software/picoavr.bin
Binary file not shown.
20 changes: 11 additions & 9 deletions picoAVR_Programmer/software/picoavr.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ===================================================================================
// Project: picoAVR ISP + UPDI Programmer based on CH551, CH552, CH554
// Version: v1.0
// Version: v1.1
// Year: 2023
// Author: Stefan Wagner
// Github: https://github.com/wagiminator
Expand All @@ -27,13 +27,15 @@
//
// Compilation Instructions:
// -------------------------
// - Chip: CH551, CH552 or CH554
// - Clock: 16 MHz internal
// - Adjust the firmware parameters in include/config.h if necessary.
// - Chip: CH551, CH552 or CH554
// - Clock: 16 MHz internal
// - Adjust the firmware parameters in src/config.h if necessary.
// - Make sure SDCC toolchain and Python3 with PyUSB is installed.
// - Press BOOT button on the board and keep it pressed while connecting it via USB
// with your PC.
// - Run 'make flash'.
// - Run 'make flash' immediatly afterwards.
// - To compile the firmware using the Arduino IDE, follow the instructions in the
// .ino file.
//
// Operating Instructions:
// -----------------------
Expand All @@ -52,9 +54,9 @@
// ===================================================================================

// Libraries
#include <system.h> // system functions
#include <delay.h> // delay functions
#include <usb_avr.h> // AVR ISP and UPDI functions
#include "src/system.h" // system functions
#include "src/delay.h" // delay functions
#include "src/usb_avr.h" // AVR ISP and UPDI functions

// Prototypes for used interrupts
void USB_interrupt(void);
Expand All @@ -71,7 +73,7 @@ void main(void) {

// Setup
CLK_config(); // configure system clock
DLY_ms(5); // wait for clock to settle
DLY_ms(10); // wait for clock to settle
AVR_init(); // init AVR ISP and UPDI
WDT_start(); // start watchdog

Expand Down
27 changes: 27 additions & 0 deletions picoAVR_Programmer/software/picoavr.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// ===================================================================================
// Arduino IDE Wrapper for ch55xduino
// ===================================================================================
//
// Compilation Instructions for the Arduino IDE:
// ---------------------------------------------
// - Make sure you have installed ch55xduino: https://github.com/DeqingSun/ch55xduino
// - Copy the .ino and .c files as well as the /src folder together into one folder
// and name it like the .ino file. Open the .ino file in the Arduino IDE. Go to
// "Tools -> Board -> CH55x Boards -> CH552 Board". Under "Tools" select the
// following board options:
// - Clock Source: 16 MHz (internal)
// - Upload Method: USB
// - USB Settings: USER CODE /w 266B USB RAM
// - Press BOOT button on the board and keep it pressed while connecting it via USB
// with your PC.
// - Click on "Upload" immediatly afterwards.
// - To compile the firmware using the makefile, follow the instructions in the
// .c file.

#ifndef USER_USB_RAM
#error "This firmware needs to be compiled with a USER USB setting"
#endif

unsigned char _sdcc_external_startup (void) __nonbanked {
return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ Header file for CH554 microcontrollers.
#ifndef __CH554_H__
#define __CH554_H__

#include <compiler.h>
#define SBIT(name, addr, bit) __sbit __at(addr+bit) name
#define SFR(name, addr) __sfr __at(addr) name
#define SFRX(name, addr) __xdata volatile unsigned char __at(addr) name
#define SFR16(name, addr) __sfr16 __at(((addr+1U)<<8) | addr) name
#define SFR16E(name, fulladdr) __sfr16 __at(fulladdr) name
#define SFR32(name, addr) __sfr32 __at(((addr+3UL)<<24) | ((addr+2UL)<<16) | ((addr+1UL)<<8) | addr) name
#define SFR32E(name, fulladdr) __sfr32 __at(fulladdr) name

/*----- SFR --------------------------------------------------------------*/
/* sbit are bit addressable, others are byte addressable */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// USB device descriptor
#define USB_VENDOR_ID 0x1781 // VID (private use only)
#define USB_PRODUCT_ID 0x0C9F // PID (private use only)
#define USB_DEVICE_VERSION 0x0104 // v1.04 (BCD-format)
#define USB_DEVICE_VERSION 0x0107 // v1.07 (BCD-format)

// USB configuration descriptor
#define USB_MAX_POWER_mA 500 // max power in mA (also to power target board)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,49 @@
// Delay in Units of us
// ===================================================================================
void DLY_us(uint16_t n) { // delay in us
#ifdef FREQ_SYS
#if FREQ_SYS <= 6000000
#ifdef F_CPU
#if F_CPU <= 6000000
n >>= 2;
#endif
#if FREQ_SYS <= 3000000
#if F_CPU <= 3000000
n >>= 2;
#endif
#if FREQ_SYS <= 750000
#if F_CPU <= 750000
n >>= 4;
#endif
#endif

while(n) { // total = 12~13 Fsys cycles, 1uS @Fsys=12MHz
SAFE_MOD++; // 2 Fsys cycles, for higher Fsys, add operation here
#ifdef FREQ_SYS
#if FREQ_SYS >= 14000000
#ifdef F_CPU
#if F_CPU >= 14000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 16000000
#if F_CPU >= 16000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 18000000
#if F_CPU >= 18000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 20000000
#if F_CPU >= 20000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 22000000
#if F_CPU >= 22000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 24000000
#if F_CPU >= 24000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 26000000
#if F_CPU >= 26000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 28000000
#if F_CPU >= 28000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 30000000
#if F_CPU >= 30000000
SAFE_MOD++;
#endif
#if FREQ_SYS >= 32000000
#if F_CPU >= 32000000
SAFE_MOD++;
#endif
#endif
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ===================================================================================
// Basic GPIO, PWM and ADC Functions for CH551, CH552 and CH554 * v1.3 *
// Basic GPIO, PWM and ADC Functions for CH551, CH552 and CH554 * v1.4 *
// ===================================================================================
//
// Pins must be defined as P10, P11, P12, etc. - e.g.:
Expand Down Expand Up @@ -227,12 +227,12 @@ SBIT(PP37, 0xB0, 7);
(0)))))

// ===================================================================================
// Set global PWM frequency (in Hertz, range: FREQ_SYS/65536 - FREQ_SYS/256)
// Set global PWM frequency (in Hertz, range: F_CPU/65536 - F_CPU/256)
// ===================================================================================
#define PWM_set_freq(FREQ) \
(((FREQ) >= FREQ_SYS / 256) ? (PWM_CK_SE = 0) : \
(((FREQ_SYS / 256 / (FREQ) - 1) > 255) ? (PWM_CK_SE = 255) : \
(PWM_CK_SE = (uint8_t)(FREQ_SYS / 256 / (FREQ) - 1)) \
(((FREQ) >= F_CPU / 256) ? (PWM_CK_SE = 0) : \
(((F_CPU / 256 / (FREQ) - 1) > 255) ? (PWM_CK_SE = 255) : \
(PWM_CK_SE = (uint8_t)(F_CPU / 256 / (FREQ) - 1)) \
))

// ===================================================================================
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// ===================================================================================
// Basic System Functions for CH551, CH552 and CH554 * v1.2 *
// Basic System Functions for CH551, CH552 and CH554 * v1.3 *
// ===================================================================================
//
// Functions available:
// --------------------
// CLK_config() set system clock frequency according to FREQ_SYS
// CLK_config() set system clock frequency according to F_CPU
// CLK_external() set external crystal as clock source
// CLK_internal() set internal oscillator as clock source
//
Expand Down Expand Up @@ -71,30 +71,30 @@ inline void CLK_config(void) {
SAFE_MOD = 0x55;
SAFE_MOD = 0xAA; // enter safe mode

#if FREQ_SYS == 32000000
#if F_CPU == 32000000
__asm__("orl _CLOCK_CFG, #0b00000111"); // 32MHz
#elif FREQ_SYS == 24000000
#elif F_CPU == 24000000
__asm__("anl _CLOCK_CFG, #0b11111000");
__asm__("orl _CLOCK_CFG, #0b00000110"); // 24MHz
#elif FREQ_SYS == 16000000
#elif F_CPU == 16000000
__asm__("anl _CLOCK_CFG, #0b11111000");
__asm__("orl _CLOCK_CFG, #0b00000101"); // 16MHz
#elif FREQ_SYS == 12000000
#elif F_CPU == 12000000
__asm__("anl _CLOCK_CFG, #0b11111000");
__asm__("orl _CLOCK_CFG, #0b00000100"); // 12MHz
#elif FREQ_SYS == 6000000
#elif F_CPU == 6000000
__asm__("anl _CLOCK_CFG, #0b11111000");
__asm__("orl _CLOCK_CFG, #0b00000011"); // 6MHz
#elif FREQ_SYS == 3000000
#elif F_CPU == 3000000
__asm__("anl _CLOCK_CFG, #0b11111000");
__asm__("orl _CLOCK_CFG, #0b00000010"); // 3MHz
#elif FREQ_SYS == 750000
#elif F_CPU == 750000
__asm__("anl _CLOCK_CFG, #0b11111000");
__asm__("orl _CLOCK_CFG, #0b00000001"); // 750kHz
#elif FREQ_SYS == 187500
#elif F_CPU == 187500
__asm__("anl _CLOCK_CFG, #0b11111000"); // 187.5kHz
#else
#warning FREQ_SYS invalid or not set
#warning F_CPU invalid or not set
#endif

SAFE_MOD = 0x00; // terminate safe mode
Expand All @@ -121,7 +121,7 @@ inline void CLK_inernal(void) {
// ===================================================================================
#define WDT_reset() WDOG_COUNT = 0
#define WDT_feed(value) WDOG_COUNT = value
#define WDT_set(time) WDOG_COUNT = (uint8_t)(256 - ((FREQ_SYS / 1000) * time / 65536))
#define WDT_set(time) WDOG_COUNT = (uint8_t)(256 - ((F_CPU / 1000) * time / 65536))

inline void WDT_start(void) {
WDOG_COUNT = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ===================================================================================
// SerialUPDI Functions for CH551, CH552 and CH554 * v1.0 *
// SerialUPDI Functions for CH551, CH552 and CH554 * v1.1 *
// ===================================================================================

#pragma once
Expand Down Expand Up @@ -61,7 +61,7 @@ inline void UPDI_break(void) {
// Set BAUD rate (currently limited to max 230400 BAUD)
// We don't need to be precise here as the AVR adapts with auto-baud.
inline void UPDI_setBAUD(uint32_t baud) {
if (baud >= 230400) TH1 = (uint8_t)(256 - (FREQ_SYS / 16 / 230400));
else if (baud <= FREQ_SYS / 16 / 256) TH1 = 0;
else TH1 = (uint8_t)(256 - (FREQ_SYS / 16 / baud));
if (baud >= 230400) TH1 = (uint8_t)(256 - (F_CPU / 16 / 230400));
else if (baud <= F_CPU / 16 / 256) TH1 = 0;
else TH1 = (uint8_t)(256 - (F_CPU / 16 / baud));
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,14 @@
#define USB_DEV_CLASS_COMM 0x02
#define USB_DEV_CLASS_HID 0x03
#define USB_DEV_CLASS_MONITOR 0x04
#define USB_DEV_CLASS_PHYSIC_IF 0x05
#define USB_DEV_CLASS_PHYSIC 0x05
#define USB_DEV_CLASS_POWER 0x06
#define USB_DEV_CLASS_PRINTER 0x07
#define USB_DEV_CLASS_STORAGE 0x08
#define USB_DEV_CLASS_HUB 0x09
#define USB_DEV_CLASS_DATA 0x0A
#define USB_DEV_CLASS_VEN_SPEC 0xFF
#define USB_DEV_CLASS_MISC 0xEF
#define USB_DEV_CLASS_VENDOR 0xFF
#endif

// USB endpoint type and attributes
Expand Down
Loading

0 comments on commit ff8967c

Please sign in to comment.