forked from microtherion/ScratchMonkey
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSMoXPROG.cpp
137 lines (125 loc) · 3.92 KB
/
SMoXPROG.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// -*- mode: c++; tab-width: 4; indent-tabs-mode: nil -*-
//
// ScratchMonkey 0.1 - STK500v2 compatible programmer for Arduino
//
// File: SMoXPROG.cpp - XPROG for TPI and PDI
//
// This part of ScratchMonkey is written by Hisashi Ito <info at mewpro.cc> (c) 2015
// in order to support HVprog2, an STK500 clone open hardware that you can buy or make.
// http://mewpro.cc/2016/01/20/how-to-use-hvprog2/
//
// Derived from source codes of LUFA AVRISP mkII clone, avrdude, USBasp
// and ATtiny4_5_9_10_20_40Programmer.ino
// The same license as main part applies.
#include "SMoCommand.h"
#include "SMoGeneral.h"
#include "SMoXPROG.h"
#include "SMoTPI.h"
#include "SMoPDI.h"
struct SMoXPROG::param_t SMoXPROG::XPRGParam;
static uint8_t SelectedProtocol = XPRG_MODE_TPI;
static uint16_t
SetParam()
{
uint8_t param = XPRG_Body[1];
switch (param) {
case XPRG_PARAM_NVMBASE: // PDI only
SMoXPROG::XPRGParam.NVMBase = (uint32_t)XPRG_Body[2] << 24 | (uint32_t)XPRG_Body[3] << 16 | XPRG_Body[4] << 8 | XPRG_Body[5];
break;
case XPRG_PARAM_EEPPAGESIZE: // PDI only
SMoXPROG::XPRGParam.EEPageSize = XPRG_Body[2] << 8 | XPRG_Body[3];
break;
case XPRG_PARAM_NVMCMD_REG: // TPI only
SMoXPROG::XPRGParam.NVMCMD = XPRG_Body[2];
break;
case XPRG_PARAM_NVMCSR_REG: // TPI only
SMoXPROG::XPRGParam.NVMCSR = XPRG_Body[2];
break;
case XPRG_PARAM_FLASHPAGESIZE: // PDI only (Atmel Studio 5.1 or later)
SMoXPROG::XPRGParam.FlashPageSize = XPRG_Body[2] << 8 | XPRG_Body[3];
break;
default:
// not implemented
break;
}
XPRG_Body[1] = XPRG_ERR_OK;
return 2;
}
void
SMoXPROG::XPROG()
{
uint8_t XPROGCommand = XPRG_Body[0];
uint16_t answerlen;
switch (SelectedProtocol) {
case XPRG_MODE_TPI:
switch (XPROGCommand) {
case XPRG_CMD_ENTER_PROGMODE:
answerlen = SMoTPI::EnterProgmode();
break;
case XPRG_CMD_LEAVE_PROGMODE:
answerlen = SMoTPI::LeaveProgmode();
break;
case XPRG_CMD_ERASE:
answerlen = SMoTPI::Erase();
break;
case XPRG_CMD_WRITE_MEM:
answerlen = SMoTPI::WriteMem();
break;
case XPRG_CMD_READ_MEM:
answerlen = SMoTPI::ReadMem();
break;
case XPRG_CMD_CRC:
answerlen = SMoTPI::CRC();
break;
case XPRG_CMD_SET_PARAM:
answerlen = SetParam();
break;
default:
SMoCommand::SendResponse(STATUS_CMD_FAILED);
return;
}
break;
case XPRG_MODE_PDI:
switch (XPROGCommand) {
case XPRG_CMD_ENTER_PROGMODE:
SMoGeneral::gVoltage = 33; // report 3.3V from now on if queried
SMoXPROG::XPRGParam.FlashPageSize = 0; // assume the old method
answerlen = SMoPDI::EnterProgmode();
break;
case XPRG_CMD_LEAVE_PROGMODE:
SMoGeneral::gVoltage = 50; // report 5.0V from now on if queried
answerlen = SMoPDI::LeaveProgmode();
break;
case XPRG_CMD_ERASE:
answerlen = SMoPDI::Erase();
break;
case XPRG_CMD_WRITE_MEM:
answerlen = SMoPDI::WriteMem();
break;
case XPRG_CMD_READ_MEM:
answerlen = SMoPDI::ReadMem();
break;
case XPRG_CMD_CRC:
answerlen = SMoPDI::CRC();
break;
case XPRG_CMD_SET_PARAM:
answerlen = SetParam();
break;
default:
SMoCommand::SendResponse(STATUS_CMD_FAILED);
return;
}
break;
default:
SMoCommand::SendResponse(STATUS_CMD_FAILED);
return;
}
SMoCommand::SendResponse(XPROGCommand, answerlen+1);
}
void
SMoXPROG::XPROG_SetMode()
{
int8_t mode = XPRG_Body[0];
SelectedProtocol = mode;
SMoCommand::SendResponse();
}