Nu-Link programmer (bottom) with LC Technology's WiFi Relay Board |
In Part 1, we encountered a 'Device ID' problem reading the N76E003AT20 CPU in the LC Technology WiFi Relay Board. The CPU appeared to be responding to the programmer's queries, so I checked the nuvoprog source code. In the file protocol/commands.go was the code to check for Device ID:
type DeviceID uint32
const (
// N76E003, Observed in trace
//
// Matches IAP registers:
// 0x00CCDDDD where
// CC = Company ID
// DDDD = Device ID
DeviceN76E003 = 0xDA3650
)
And since my relay board's N76E003 was returning 0xff3650, I changed it to
type DeviceID uint32
const (
// N76E003, Observed in trace
//
// Matches IAP registers:
// 0x00CCDDDD where
// CC = Company ID
// DDDD = Device ID
// DeviceN76E003 = 0xDA3650
DeviceN76E003 = 0xFF3650
)
Now remember to put your nuvoton directory into /root/go/ for the build only works for that directory listed in the environmant variable GOPATH:
# go env GOPATH
/root/go
# go build
And indeed there is a new nuvoprog (check the timestamp):
# ls -l
total 5224
drwxr-xr-x 2 root root 4096 Jul 6 17:15 cmd
drwxr-xr-x 2 root root 4096 Jul 6 17:15 ihex
-rw-r--r-- 1 root root 11358 Jul 6 17:15 LICENSE
-rw-r--r-- 1 root root 688 Jul 6 17:15 main.go
drwxr-xr-x 2 root root 4096 Jul 6 17:15 misc
-rwxr-xr-x 1 root root 5306088 Jul 7 15:46 nuvoprog
drwxr-xr-x 2 root root 4096 Jul 7 15:44 protocol
-rw-r--r-- 1 root root 2812 Jul 6 17:15 README.md
drwxr-xr-x 4 root root 4096 Jul 6 17:15 target
And now the programmer reads back properly:
# ./nuvoprog read -t n76e003 2relay_readback_good.ihx -v
.
.
.
2020/07/07 15:46:45 Performing reset {None (NuLink) Disconnect Ext Mode}
2020/07/07 15:46:45 > 0c10e2000000050000000400000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000
2020/07/07 15:46:45 < 0c04e2000000fffffffffffffffffffffffffffffffffffffffffffff
fffffffffff000046662915699c03b4c74319896b6b8896664ef446d10e91c0d10a904c
2020/07/07 15:46:45 OK
Now despite a working relay board the program file read back is actually blank:
# head 2relay_readback_good.ihx
:020000040003F7
:08000000FDFFFFFFFFFFFFFF02
:020000040000FA
:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:20004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:20006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:20008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:2000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:2000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
A check of the relay CPU configuration revealed the cause: it has been locked:
# ./nuvoprog config decode -t n76e003 -i 2relay_readback_good.ihx
{
"boot_select": "aprom",
"pwm_enabled_during_ocd": false,
"ocd_enabled": false,
"reset_pin_disabled": false,
"locked": true,
"ldrom_size": "0kb",
"bod_disabled": false,
"bod_voltage": "2v2",
"iap_enabled_in_brownout": false,
"bod_reset_disabled": false,
"wdt": "disabled"
}
For comparison, the config file of the Core Controller was:
{
"boot_select": "aprom",
"pwm_enabled_during_ocd": false,
"ocd_enabled": true,
"reset_pin_disabled": false,
"locked": false,
"ldrom_size": "0kb",
"bod_disabled": false,
"bod_voltage": "2v2",
"iap_enabled_in_brownout": false,
"bod_reset_disabled": false,
"wdt": "disabled"
}
The relay board CPU programming command returned no error once:
# ./nuvoprog program -t n76e003 -a blink.ihx -c @config.json -v
2020/07/07 15:57:01 Performing reset {Auto Disconnect 0x00000001}
2020/07/07 15:57:01 > 0c10e2000000000000000400000001000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000
2020/07/07 15:57:01 < 0c04e20000005036ff00f8ffffff57012d0100002000fffffffffffff
fffffffffff000046662915699c03b4c74319896b6b8896664ef446d10e91c0d10a904c
2020/07/07 15:57:01 OK
2020/07/07 15:57:01 Performing reset {None (NuLink) Disconnect Ext Mode}
2020/07/07 15:57:01 > 0d10e2000000050000000400000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000
2020/07/07 15:57:01 < 0d04e20000005036ff00f8ffffff57012d0100002000fffffffffffff
fffffffffff000046662915699c03b4c74319896b6b8896664ef446d10e91c0d10a904c
2020/07/07 15:57:01 OK
But a read-back confirmed that the device ID has changed back to da3650:
# ./nuvoprog read -t n76e003 2relay_readback_bad.ihx
Error: Unsupported device
Usage:
nuvoprog read [outfile.ihx] [flags]
Flags:
-h, --help help for read
Global Flags:
-t, --target string target device
-v, --verbose make verbose (enable debug logging)
Unsupported device
And the file is blank, so the 'program' action merely erased the existing relay program:
# head 2relay_readback_bad.ihx
:020000040003F7
:08000000FFFFFFFFFFFFFFFF00
:020000040000FA
:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:20004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:20006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:20008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:2000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:2000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
So now having unlocked the relay CPU for programming I now need to revert back to erincandescent's original code:
type DeviceID uint32
const (
// N76E003, Observed in trace
//
// Matches IAP registers:
// 0x00CCDDDD where
// CC = Company ID
// DDDD = Device ID
DeviceN76E003 = 0xDA3650
)
Whereupon the CPU behaves normally:
# /root/go/bin/nuvoprog program -t n76e003 -a blink.ihx -c @config.json
# /root/go/bin/nuvoprog read -t n76e003 2relay_readback_bad.ihx
And the new blink.c program took:
# head 2relay_readback_bad.ihx
:020000040003F7
:08000000EFFFFFFFFFFFFFFF10
:020000040000FA
:200000000200060200997581071200E8E58260030200037900E94400601B7A009000EC78E8
:200020000175A000E493F2A308B8000205A0D9F4DAF275A0FFE478FFF6D8FD7800E84400C0
:20004000600A790175A000E4F309D8FC7800E84400600C7900900001E4F0A3D8FCD9FA02B9
:200060000003AC82AD83AEF0FF538EF774FC55894401F589D28CEC4D4E4F601A758ACB75AC
:200080008CFA108D0280FB1CBCFF091DBDFF051EBEFF011F80E0C28C2275B10075B2007575
:2000A000B30075B40075AC0075AD007E007F00C2959002BCE4F5F0C007C006120062D2954E
:2000C0009002BCE4F5F0120062D006D0070EBE00010FC3EE940AEF6480948040D29003E849
Now having wiped the firmware in a perfectly good WiFi Relay board, I need working N76E003 firmware. I need not have worried, for this being the Internet, cometh the hour, cometh the man, necromant. There is even a pre-compiled executable, firmware.hex!
I tried programming firmware.hex, but it did not work. And looking at the source code, src/main.c was the reason; the CPU pin assignments are different for the dual relay board. The code read:
#define RELAY4 P01#define RELAY3 P04
#define RELAY2 P03
#define RELAY1 P05 #define RED P11
#define GREEN P00
#define BLUE P10 #define PWM_GREEN PWM3L
#define PWM_BLUE PWM2L
#define PWM_RED PWM1L #define BUTTON1 P15
#define BUTTON2 P12
And inside the main() loop are more hard code:
int main(){
uart_init(19200);
printf("\n\n\nHello world. I'm a hacky opensource firmware for LC-tech modules\n");
printf("Go check out my blog https://ncrmnt.org for more awesome stuff\n");
/* Relays */
P01_PushPull_Mode;
P03_PushPull_Mode;
P04_PushPull_Mode;
P05_PushPull_Mode; /* LEDS */
P10_PushPull_Mode;
P11_PushPull_Mode;
P00_PushPull_Mode; /* Buttons */
P12_Input_Mode;
P15_Input_Mode;
#define RELAY4 P15
#define RELAY3 P12
#define RELAY2 P15
#define RELAY1 P12
#define RED P01
#define GREEN P04
#define BLUE P03
#define PWM_GREEN PWM3L
#define PWM_BLUE PWM2L
#define PWM_RED PWM1L
#define BUTTON1 P00
#define BUTTON2 P10
int main()
{
uart_init(19200);
printf("\n\n\nHello world. I'm a hacky opensource firmware for LC-tech modules\n");
printf("Go check out my blog https://ncrmnt.org for more awesome stuff\n");
/* Relays */
P15_PushPull_Mode; /* Relay 4 */
P15_PushPull_Mode; /* Relay 2 */
P12_PushPull_Mode; /* Relay 3 */
P12_PushPull_Mode; /* Relay 1 */
/* LEDS */
P03_PushPull_Mode; /* Blue */
P01_PushPull_Mode; /* Red */
P04_PushPull_Mode; /* Green */
/* Buttons */
P10_Input_Mode;
P00_Input_Mode;
/* buttonz */
PWMPH = 0;
PWMPL = 255;
PWM_CLOCK_FSYS;
PWM_CLOCK_DIV_128;
PWM_EDGE_TYPE;
PWM1_P11_OUTPUT_ENABLE;
PWM2_P10_OUTPUT_ENABLE;
PWM3_P00_OUTPUT_ENABLE;
RED = 0;
GREEN = 0;
BLUE = 1;
RELAY1 = 0;
RELAY2 = 0;
RELAY3 = 0;
RELAY4 = 0;
To keep the changes to a minimum, I modified RELAY3 to be the same as RELAY1, and RELAY4 the same as RELAY2. Also the code defaulted to relays turned on at power-up, and I changed it to off.
Now not having the same IDE as nekromant, and not having the Makefile, I issued the build commands separately:
# sdcc -mmcs51 -c Delay.c -D FOSC_160000 -I../include
# sdcc -mmcs51 -o 2relays.ihx main.c Delay.rel Common.rel -D FOSC_160000 -I../include
# sdcc -mmcs51 -o 2relays.ihx main.c Delay.rel Common.rel -D FOSC_160000 -I../include
And lastly the programming command:
# /root/go/bin/nuvoprog program -t n76e003 -a ./necromant/lctech-relay-altfw-master/src/2relays.ihx -c @config.json
And the LC Tech WiFi dual relay board worked, just like that. You can pick up the 2-relay version of nekromant's code from my github repository. Life is good.
Happy Trails.
HEllo Cmheong's can you please tell how to do this in windows
ReplyDelete