mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-17 11:04:16 +00:00
Compare commits
10 Commits
v6.3.1.0-w
...
v6.3.1.1-w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02150bbb26 | ||
|
|
7d87a12d57 | ||
|
|
03eb736a62 | ||
|
|
cb6208939b | ||
|
|
8dce9107df | ||
|
|
61310bf1a3 | ||
|
|
e8d42fc993 | ||
|
|
a8916983a0 | ||
|
|
bc0245e41b | ||
|
|
fa608b5ddf |
@@ -180,6 +180,8 @@ libavrdude_a_SOURCES = \
|
||||
stk500v2_private.h \
|
||||
stk500generic.c \
|
||||
stk500generic.h \
|
||||
teensy.c \
|
||||
teensy.h \
|
||||
tpi.h \
|
||||
usbasp.c \
|
||||
usbasp.h \
|
||||
|
||||
@@ -898,6 +898,15 @@ programmer
|
||||
usbpid = 0x0753;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "teensy";
|
||||
desc = "Teensy Bootloader";
|
||||
type = "teensy";
|
||||
connection_type = usb;
|
||||
usbvid = 0x16C0;
|
||||
usbpid = 0x0478;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "butterfly";
|
||||
desc = "Atmel Butterfly Development Board";
|
||||
|
||||
@@ -92,6 +92,9 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -104,6 +107,9 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@@ -121,6 +127,9 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -138,6 +147,9 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="arduino.c" />
|
||||
@@ -182,6 +194,7 @@
|
||||
<ClCompile Include="stk500.c" />
|
||||
<ClCompile Include="stk500generic.c" />
|
||||
<ClCompile Include="stk500v2.c" />
|
||||
<ClCompile Include="teensy.c" />
|
||||
<ClCompile Include="term.c" />
|
||||
<ClCompile Include="update.c" />
|
||||
<ClCompile Include="usbasp.c" />
|
||||
@@ -231,7 +244,9 @@
|
||||
<ClInclude Include="msvc\IntegerHandleMap.h" />
|
||||
<ClInclude Include="msvc\pthread.h" />
|
||||
<ClInclude Include="msvc\ReaderWriterLock.h" />
|
||||
<ClInclude Include="msvc\resource.h" />
|
||||
<ClInclude Include="msvc\semaphore.h" />
|
||||
<ClInclude Include="msvc\version.h" />
|
||||
<ClInclude Include="my_ddk_hidsdi.h" />
|
||||
<ClInclude Include="par.h" />
|
||||
<ClInclude Include="pickit2.h" />
|
||||
@@ -244,6 +259,7 @@
|
||||
<ClInclude Include="stk500v2.h" />
|
||||
<ClInclude Include="stk500v2_private.h" />
|
||||
<ClInclude Include="stk500_private.h" />
|
||||
<ClInclude Include="teensy.h" />
|
||||
<ClInclude Include="term.h" />
|
||||
<ClInclude Include="tpi.h" />
|
||||
<ClInclude Include="usbasp.h" />
|
||||
@@ -273,6 +289,17 @@
|
||||
<Project>{22615ec5-9dbc-4538-9c01-2cd535b3810b}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="msvc\avrdude.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="msvc\res\resource.rc2">
|
||||
<FileType>Text</FileType>
|
||||
</None>
|
||||
<None Include="msvc\res\version.rc2">
|
||||
<FileType>Text</FileType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
@@ -12,10 +12,13 @@
|
||||
<Filter Include="3 Generated Files">
|
||||
<UniqueIdentifier>{be5ce6e6-223e-4d41-8915-29103d899c5a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="4 msvc">
|
||||
<Filter Include="4 Resource Files">
|
||||
<UniqueIdentifier>{a7668888-00c6-4911-9e47-7af645f31778}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="5 msvc">
|
||||
<UniqueIdentifier>{dbbd7498-e1e9-4d80-b91f-137dc5b988f1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="4 msvc\sys">
|
||||
<Filter Include="5 msvc\sys">
|
||||
<UniqueIdentifier>{1cc9d4fb-f03f-48cb-8af7-3e96681dc03b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
@@ -140,6 +143,9 @@
|
||||
<ClCompile Include="stk500v2.c">
|
||||
<Filter>1 Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="teensy.c">
|
||||
<Filter>1 Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="term.c">
|
||||
<Filter>1 Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -168,22 +174,22 @@
|
||||
<Filter>3 Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="msvc\getopt.c">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="msvc\gettimeofday.c">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="msvc\unistd.cpp">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="msvc\usb_com_helper.cpp">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="msvc\pthread.cpp">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="msvc\semaphore.cpp">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -301,6 +307,9 @@
|
||||
<ClInclude Include="stk500v2_private.h">
|
||||
<Filter>2 Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="teensy.h">
|
||||
<Filter>2 Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="term.h">
|
||||
<Filter>2 Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -326,34 +335,53 @@
|
||||
<Filter>3 Generated Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\getopt.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\unistd.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\sys\time.h">
|
||||
<Filter>4 msvc\sys</Filter>
|
||||
<Filter>5 msvc\sys</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\msvc_compat.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\usb_com_helper.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\usb_com_locator.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\pthread.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\semaphore.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\ReaderWriterLock.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\IntegerHandleMap.h">
|
||||
<Filter>4 msvc</Filter>
|
||||
<Filter>5 msvc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\resource.h">
|
||||
<Filter>2 Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msvc\version.h">
|
||||
<Filter>4 Resource Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="msvc\avrdude.rc">
|
||||
<Filter>4 Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="msvc\res\resource.rc2">
|
||||
<Filter>4 Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="msvc\res\version.rc2">
|
||||
<Filter>4 Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
52
external/libftdi1/src/ftdi.cpp
vendored
52
external/libftdi1/src/ftdi.cpp
vendored
@@ -46,6 +46,7 @@ static ftdi_chip_type MapChipType(ULONG type)
|
||||
return TYPE_AM;
|
||||
}
|
||||
}
|
||||
|
||||
static int SetError(struct ftdi_context* ftdi, int result, const char* error_str)
|
||||
{
|
||||
if (ftdi != nullptr)
|
||||
@@ -82,6 +83,42 @@ void ftdi_free(struct ftdi_context* ftdi)
|
||||
|
||||
int ftdi_set_interface(struct ftdi_context* ftdi, enum ftdi_interface interface)
|
||||
{
|
||||
if (ftdi == nullptr)
|
||||
{
|
||||
return SetError(ftdi, -2, "USB device unavailable");
|
||||
}
|
||||
|
||||
if (ftdi->usb_dev != nullptr)
|
||||
{
|
||||
if (ftdi->index != (interface != INTERFACE_ANY ? interface : INTERFACE_A))
|
||||
{
|
||||
return SetError(ftdi, -3, "Interface can not be changed on an already open device");
|
||||
}
|
||||
}
|
||||
|
||||
switch (interface)
|
||||
{
|
||||
case INTERFACE_ANY:
|
||||
case INTERFACE_A:
|
||||
ftdi->interface = 0;
|
||||
ftdi->index = INTERFACE_A;
|
||||
break;
|
||||
case INTERFACE_B:
|
||||
ftdi->interface = 1;
|
||||
ftdi->index = INTERFACE_B;
|
||||
break;
|
||||
case INTERFACE_C:
|
||||
ftdi->interface = 2;
|
||||
ftdi->index = INTERFACE_C;
|
||||
break;
|
||||
case INTERFACE_D:
|
||||
ftdi->interface = 3;
|
||||
ftdi->index = INTERFACE_D;
|
||||
break;
|
||||
default:
|
||||
return SetError(ftdi, -1, "Unknown interface");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -93,7 +130,7 @@ int ftdi_init(struct ftdi_context* ftdi)
|
||||
|
||||
void ftdi_deinit(struct ftdi_context* ftdi)
|
||||
{
|
||||
if (ftdi->usb_dev != nullptr)
|
||||
if (ftdi != nullptr && ftdi->usb_dev != nullptr)
|
||||
{
|
||||
std::unique_ptr<FtdiDevice> device(reinterpret_cast<FtdiDevice*>(ftdi->usb_dev));
|
||||
ftdi->usb_dev = nullptr;
|
||||
@@ -139,14 +176,21 @@ int ftdi_usb_open_desc_index(struct ftdi_context* ftdi, int vendor, int product,
|
||||
}
|
||||
|
||||
auto device = std::make_unique<FtdiDevice>();
|
||||
auto status = device->OpenBySerialNumber(info.SerialNumber);
|
||||
FT_STATUS status = device->OpenBySerialNumber(info.SerialNumber);
|
||||
if (status == FT_OK)
|
||||
{
|
||||
device->ResetDevice();
|
||||
device->Purge();
|
||||
device->SetBitMode(0, 0);
|
||||
device->SetTimeouts(5000, 5000);
|
||||
status = device->SetEventNotification(FT_EVENT_RXCHAR);
|
||||
}
|
||||
|
||||
if (status != FT_OK)
|
||||
{
|
||||
return SetError(ftdi, -3, "failed to open device");
|
||||
}
|
||||
|
||||
device->SetEventNotification(FT_EVENT_RXCHAR);
|
||||
|
||||
ftdi->type = MapChipType(info.Type);
|
||||
ftdi->usb_dev = reinterpret_cast<struct libusb_device_handle*>(device.release());
|
||||
return 0;
|
||||
|
||||
111
external/libftdi1/src/libwinftdi.h
vendored
111
external/libftdi1/src/libwinftdi.h
vendored
@@ -114,30 +114,36 @@ namespace LibWinFtdi
|
||||
if (m_module != nullptr)
|
||||
return S_FALSE;
|
||||
|
||||
m_module = LoadLibraryExW(L"ftd2xx.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (m_module == nullptr)
|
||||
HMODULE module = LoadLibraryExW(L"ftd2xx.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (module == nullptr)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
if (FAILED(hr = LoadImport("FT_CreateDeviceInfoList", &FT_CreateDeviceInfoList)) ||
|
||||
FAILED(hr = LoadImport("FT_GetDeviceInfoList", &FT_GetDeviceInfoList)) ||
|
||||
FAILED(hr = LoadImport("FT_OpenEx", &FT_OpenEx)) ||
|
||||
FAILED(hr = LoadImport("FT_Close", &FT_Close)) ||
|
||||
FAILED(hr = LoadImport("FT_Purge", &FT_Purge)) ||
|
||||
FAILED(hr = LoadImport("FT_SetTimeouts", &FT_SetTimeouts)) ||
|
||||
FAILED(hr = LoadImport("FT_SetBaudRate", &FT_SetBaudRate)) ||
|
||||
FAILED(hr = LoadImport("FT_SetBitMode", &FT_SetBitMode)) ||
|
||||
FAILED(hr = LoadImport("FT_SetLatencyTimer", &FT_SetLatencyTimer)) ||
|
||||
FAILED(hr = LoadImport("FT_GetQueueStatus", &FT_GetQueueStatus)) ||
|
||||
FAILED(hr = LoadImport("FT_SetEventNotification", &FT_SetEventNotification)) ||
|
||||
FAILED(hr = LoadImport("FT_Read", &FT_Read)) ||
|
||||
FAILED(hr = LoadImport("FT_Write", &FT_Write)))
|
||||
if (FAILED(hr = LoadImport(module, "FT_CreateDeviceInfoList", &FT_CreateDeviceInfoList)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_GetDeviceInfoList", &FT_GetDeviceInfoList)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_OpenEx", &FT_OpenEx)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_Close", &FT_Close)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_ResetDevice", &FT_ResetDevice)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_ResetPort", &FT_ResetPort)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_CyclePort", &FT_ResetPort)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_Purge", &FT_Purge)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_SetTimeouts", &FT_SetTimeouts)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_SetBaudRate", &FT_SetBaudRate)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_SetBitMode", &FT_SetBitMode)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_SetLatencyTimer", &FT_SetLatencyTimer)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_GetQueueStatus", &FT_GetQueueStatus)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_SetEventNotification", &FT_SetEventNotification)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_SetUSBParameters", &FT_SetUSBParameters)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_Read", &FT_Read)) ||
|
||||
FAILED(hr = LoadImport(module, "FT_Write", &FT_Write)))
|
||||
{
|
||||
FreeLibrary(module);
|
||||
return hr;
|
||||
}
|
||||
|
||||
m_module = module;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -154,11 +160,12 @@ namespace LibWinFtdi
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
HRESULT LoadImport(LPCSTR lpProcName, T** ptr)
|
||||
static HRESULT LoadImport(HMODULE module, LPCSTR lpProcName, T** ptr)
|
||||
{
|
||||
auto proc = GetProcAddress(m_module, lpProcName);
|
||||
auto proc = GetProcAddress(module, lpProcName);
|
||||
if (proc == nullptr)
|
||||
{
|
||||
*ptr = nullptr;
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
@@ -169,18 +176,22 @@ namespace LibWinFtdi
|
||||
private:
|
||||
HMODULE m_module = nullptr;
|
||||
|
||||
public:
|
||||
protected:
|
||||
FT_STATUS(WINAPI* FT_CreateDeviceInfoList)(LPDWORD lpdwNumDevs) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_GetDeviceInfoList)(DeviceInfo* pDest, LPDWORD lpdwNumDevs) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_OpenEx)(PVOID pArg1, DWORD Flags, FT_HANDLE* pHandle) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_Close)(FT_HANDLE ftHandle) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_Purge)(FT_HANDLE ftHandle, ULONG Mask) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetTimeouts)(FT_HANDLE ftHandle, ULONG ReadTimeout, ULONG WriteTimeout) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetBaudRate)(FT_HANDLE ftHandle, ULONG BaudRate) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_ResetDevice)(FT_HANDLE ftHandle) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_ResetPort)(FT_HANDLE ftHandle) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_CyclePort)(FT_HANDLE ftHandle) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_Purge)(FT_HANDLE ftHandle, DWORD dwMask) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetTimeouts)(FT_HANDLE ftHandle, DWORD dwReadTimeout, DWORD dwWriteTimeout) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetBaudRate)(FT_HANDLE ftHandle, DWORD dwBaudRate) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetBitMode)(FT_HANDLE ftHandle, UCHAR ucMask, UCHAR ucEnable) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetLatencyTimer)(FT_HANDLE ftHandle, UCHAR ucLatency) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetLatencyTimer)(FT_HANDLE ftHandle, UCHAR ucTimer) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_GetQueueStatus)(FT_HANDLE ftHandle, DWORD* dwRxBytes) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetEventNotification)(FT_HANDLE ftHandle, DWORD Mask, PVOID Param) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_SetUSBParameters)(FT_HANDLE ftHandle, DWORD dwInTransferSize, DWORD dwOutTransferSize) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_Read)(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesReturned) = nullptr;
|
||||
FT_STATUS(WINAPI* FT_Write)(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten) = nullptr;
|
||||
};
|
||||
@@ -278,34 +289,64 @@ namespace LibWinFtdi
|
||||
return FT_Close(m_handle);
|
||||
}
|
||||
|
||||
FT_STATUS Purge(ULONG Mask = FT_PURGE_RX | FT_PURGE_TX)
|
||||
FT_STATUS ResetDevice()
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
{
|
||||
return FT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return FT_Purge(m_handle, Mask);
|
||||
return FT_ResetDevice(m_handle);
|
||||
}
|
||||
|
||||
FT_STATUS SetTimeouts(ULONG ReadTimeout, ULONG WriteTimeout)
|
||||
FT_STATUS ResetPort()
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
{
|
||||
return FT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return FT_SetTimeouts(m_handle, ReadTimeout, WriteTimeout);
|
||||
return FT_ResetPort(m_handle);
|
||||
}
|
||||
|
||||
FT_STATUS SetBaudRate(ULONG BaudRate)
|
||||
FT_STATUS CyclePort()
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
{
|
||||
return FT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return FT_SetBaudRate(m_handle, BaudRate);
|
||||
return FT_CyclePort(m_handle);
|
||||
}
|
||||
|
||||
FT_STATUS Purge(DWORD dwMask = FT_PURGE_RX | FT_PURGE_TX)
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
{
|
||||
return FT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return FT_Purge(m_handle, dwMask);
|
||||
}
|
||||
|
||||
FT_STATUS SetTimeouts(DWORD dwReadTimeout, DWORD dwWriteTimeout)
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
{
|
||||
return FT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return FT_SetTimeouts(m_handle, dwReadTimeout, dwWriteTimeout);
|
||||
}
|
||||
|
||||
FT_STATUS SetBaudRate(DWORD dwBaudRate)
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
{
|
||||
return FT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return FT_SetBaudRate(m_handle, dwBaudRate);
|
||||
}
|
||||
|
||||
FT_STATUS SetBitMode(UCHAR ucMask, UCHAR ucEnable)
|
||||
@@ -318,14 +359,14 @@ namespace LibWinFtdi
|
||||
return FT_SetBitMode(m_handle, ucMask, ucEnable);
|
||||
}
|
||||
|
||||
FT_STATUS SetLatencyTimer(UCHAR ucLatency)
|
||||
FT_STATUS SetLatencyTimer(UCHAR ucTimer)
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
{
|
||||
return FT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return FT_SetLatencyTimer(m_handle, ucLatency);
|
||||
return FT_SetLatencyTimer(m_handle, ucTimer);
|
||||
}
|
||||
|
||||
FT_STATUS GetQueueStatus(DWORD* dwRxBytes)
|
||||
@@ -353,6 +394,16 @@ namespace LibWinFtdi
|
||||
return FT_SetEventNotification(m_handle, Mask, m_event);
|
||||
}
|
||||
|
||||
FT_STATUS SetUSBParameters(DWORD dwInTransferSize, DWORD dwOutTransferSize)
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
{
|
||||
return FT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return FT_SetUSBParameters(m_handle, dwInTransferSize, dwOutTransferSize);
|
||||
}
|
||||
|
||||
FT_STATUS Read(LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesReturned)
|
||||
{
|
||||
if (FAILED(Load()))
|
||||
|
||||
8
external/libusb/libusb.vcxproj
vendored
8
external/libusb/libusb.vcxproj
vendored
@@ -103,7 +103,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LOG_APPNAME="avrdude";WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
||||
<AdditionalIncludeDirectories>include</AdditionalIncludeDirectories>
|
||||
@@ -118,7 +118,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LOG_APPNAME="avrdude";WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
||||
@@ -134,7 +134,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LOG_APPNAME="avrdude";_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
||||
<AdditionalIncludeDirectories>include</AdditionalIncludeDirectories>
|
||||
@@ -149,7 +149,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LOG_APPNAME="avrdude";NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
||||
|
||||
1
external/libusb/src/windows.cpp
vendored
1
external/libusb/src/windows.cpp
vendored
@@ -140,7 +140,6 @@ int usb_os_find_devices(struct usb_bus* bus, struct usb_device** devices)
|
||||
if (FAILED(item->Open(driver)) ||
|
||||
FAILED(driver->GetDescriptor(USB_DT_DEVICE, 0, 0, &dev->descriptor, sizeof(dev->descriptor), nullptr, 5000)))
|
||||
{
|
||||
USBERR0("couldn't read device descriptor\n");
|
||||
free(dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
4
main.c
4
main.c
@@ -353,6 +353,10 @@ int main(int argc, char * argv [])
|
||||
char * homedir;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
_set_printf_count_output(1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set line buffering for file descriptors so we see stdout and stderr
|
||||
* properly interleaved.
|
||||
|
||||
@@ -562,9 +562,12 @@ static void micronucleus_powerdown(PROGRAMMER* pgm)
|
||||
pdata->write_last_page = false;
|
||||
|
||||
uint8_t* buffer = (unsigned char*)malloc(pdata->page_size);
|
||||
memset(buffer, 0xFF, pdata->page_size);
|
||||
micronucleus_write_page(pdata, pdata->bootloader_start - pdata->page_size, buffer, pdata->page_size);
|
||||
free(buffer);
|
||||
if (buffer != NULL)
|
||||
{
|
||||
memset(buffer, 0xFF, pdata->page_size);
|
||||
micronucleus_write_page(pdata, pdata->bootloader_start - pdata->page_size, buffer, pdata->page_size);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (pdata->start_program)
|
||||
@@ -644,6 +647,13 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
|
||||
}
|
||||
}
|
||||
|
||||
if (port != NULL && dev_name == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Invalid -P value: '%s'\n", progname, port);
|
||||
avrdude_message(MSG_INFO, "%sUse -P usb:bus:device\n", progbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Determine VID/PID
|
||||
int vid = pgm->usbvid ? pgm->usbvid : MICRONUCLEUS_VID;
|
||||
int pid = MICRONUCLEUS_PID;
|
||||
@@ -707,8 +717,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
|
||||
pdata->usb_handle = usb_open(device);
|
||||
if (pdata->usb_handle == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: WARNING: cannot open USB device: %s\n", progname, usb_strerror());
|
||||
continue;
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Failed to open USB device: %s\n", progname, usb_strerror());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,13 +739,6 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
|
||||
break;
|
||||
}
|
||||
|
||||
if (port != NULL && dev_name == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Invalid -P value: '%s'\n", progname, port);
|
||||
avrdude_message(MSG_INFO, "%sUse -P usb:bus:device\n", progbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!pdata->usb_handle)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Could not find device with Micronucleus bootloader (%04X:%04X)\n",
|
||||
@@ -821,6 +823,11 @@ static int micronucleus_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
|
||||
}
|
||||
|
||||
uint8_t* page_buffer = (uint8_t*)malloc(pdata->page_size);
|
||||
if (page_buffer == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: Failed to allocate memory\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Note: Page size reported by the bootloader may be smaller than device page size as configured in avrdude.conf.
|
||||
int result = 0;
|
||||
@@ -866,7 +873,7 @@ static int micronucleus_parseextparams(PROGRAMMER* pgm, LISTID xparams)
|
||||
}
|
||||
else
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: invalid extended parameter '%s'\n", progname, param);
|
||||
avrdude_message(MSG_INFO, "%s: Invalid extended parameter '%s'\n", progname, param);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -904,7 +911,7 @@ void micronucleus_initpgm(PROGRAMMER* pgm)
|
||||
// Give a proper error if we were not compiled with libusb
|
||||
static int micronucleus_nousb_open(struct programmer_t* pgm, char* name)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: error: no usb support. Please compile again with libusb installed.\n", progname);
|
||||
avrdude_message(MSG_INFO, "%s: error: No usb support. Please compile again with libusb installed.\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
BIN
msvc/avrdude.rc
Normal file
BIN
msvc/avrdude.rc
Normal file
Binary file not shown.
@@ -173,7 +173,7 @@
|
||||
#define PACKAGE_NAME "avrdude"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "avrdude 6.3.1.0-windows"
|
||||
#define PACKAGE_STRING "avrdude 6.3.1.1-windows"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "avrdude"
|
||||
@@ -182,7 +182,7 @@
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "6.3.1.0-windows"
|
||||
#define PACKAGE_VERSION "6.3.1.1-windows"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
@@ -191,7 +191,7 @@
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "6.3.1.0-windows"
|
||||
#define VERSION "6.3.1.1-windows"
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
|
||||
16244
msvc/generated/avrdude.conf
Normal file
16244
msvc/generated/avrdude.conf
Normal file
File diff suppressed because it is too large
Load Diff
16
msvc/res/resource.rc2
Normal file
16
msvc/res/resource.rc2
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// resource.rc2
|
||||
// Copyright (C) 2020 Marius Greuel. All rights reserved.
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#error this file is not editable by Microsoft Visual C++
|
||||
#endif //APSTUDIO_INVOKED
|
||||
|
||||
#pragma code_page(1252)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////// Version
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
#include "version.rc2"
|
||||
102
msvc/res/version.rc2
Normal file
102
msvc/res/version.rc2
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// Version.rc2
|
||||
// Copyright (C) 2020 Marius Greuel. All rights reserved.
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "..\version.h"
|
||||
|
||||
#define _STR(s) #s
|
||||
#define _VER_STR(a, b, c, d) _STR(a) "." _STR(b) "." _STR(c) "." _STR(d)
|
||||
|
||||
#ifndef VER_FILEVERSION
|
||||
#define VER_FILEVERSION VER_MAJOR,VER_MINOR,VER_BUILD,VER_REVISION
|
||||
#endif
|
||||
|
||||
#ifndef VER_FILEVERSION_STR
|
||||
#define VER_FILEVERSION_STR _VER_STR(VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION)
|
||||
#endif
|
||||
|
||||
#ifndef VER_PRODUCTVERSION
|
||||
#define VER_PRODUCTVERSION VER_FILEVERSION
|
||||
#endif
|
||||
|
||||
#ifndef VER_PRODUCTVERSION_STR
|
||||
#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
|
||||
#endif
|
||||
|
||||
#ifndef VER_COMPANYNAME_STR
|
||||
#define VER_COMPANYNAME_STR "Marius Greuel"
|
||||
#endif
|
||||
|
||||
#ifndef VER_FILEDESCRIPTION_STR
|
||||
#define VER_FILEDESCRIPTION_STR "AVRDUDE"
|
||||
#endif
|
||||
|
||||
#ifndef VER_PRODUCTNAME_STR
|
||||
#define VER_PRODUCTNAME_STR "AVRDUDE"
|
||||
#endif
|
||||
|
||||
#ifndef VER_INTERNALNAME_STR
|
||||
#define VER_INTERNALNAME_STR "avrdude.exe"
|
||||
#endif
|
||||
|
||||
#ifndef VER_LEGALCOPYRIGHT_STR
|
||||
#define VER_LEGALCOPYRIGHT_STR "\251 2020 The AVRDUDE authors."
|
||||
#endif
|
||||
|
||||
#ifndef VER_ORIGINALFILENAME_STR
|
||||
#define VER_ORIGINALFILENAME_STR VER_INTERNALNAME_STR
|
||||
#endif
|
||||
|
||||
#ifndef VER_FILETYPE
|
||||
#define VER_FILETYPE VFT_APP
|
||||
#define VER_FILESUBTYPE 0
|
||||
#endif
|
||||
|
||||
#ifdef RC_INVOKED
|
||||
|
||||
#ifdef DEBUG
|
||||
#define VER_DEBUG VS_FF_DEBUG
|
||||
#else
|
||||
#define VER_DEBUG 0
|
||||
#endif
|
||||
|
||||
#define VER_FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#define VER_FILEOS VOS__WINDOWS32
|
||||
#define VER_FILEFLAGS (VER_DEBUG)
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
FILEFLAGSMASK VER_FILEFLAGSMASK
|
||||
FILEFLAGS VER_FILEFLAGS
|
||||
FILEOS VER_FILEOS
|
||||
FILETYPE VER_FILETYPE
|
||||
FILESUBTYPE VER_FILESUBTYPE
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0" // LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP
|
||||
BEGIN
|
||||
#ifdef VER_COMMENTS_STR
|
||||
VALUE "Comments", VER_COMMENTS_STR
|
||||
#endif
|
||||
VALUE "CompanyName", VER_COMPANYNAME_STR
|
||||
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", VER_INTERNALNAME_STR
|
||||
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
|
||||
VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR
|
||||
VALUE "ProductName", VER_PRODUCTNAME_STR
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 1200 //LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP
|
||||
END
|
||||
END
|
||||
|
||||
#endif // RC_INVOKED
|
||||
BIN
msvc/resource.h
Normal file
BIN
msvc/resource.h
Normal file
Binary file not shown.
14
msvc/version.h
Normal file
14
msvc/version.h
Normal file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// version.h
|
||||
// Copyright (C) 2020 Marius Greuel. All rights reserved.
|
||||
//
|
||||
|
||||
#define PRD_MAJOR 6
|
||||
#define PRD_MINOR 3
|
||||
#define PRD_BUILD 1
|
||||
#define PRD_REVISION 0
|
||||
|
||||
#define VER_MAJOR PRD_MAJOR
|
||||
#define VER_MINOR PRD_MINOR
|
||||
#define VER_BUILD PRD_BUILD
|
||||
#define VER_REVISION PRD_REVISION
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "stk500.h"
|
||||
#include "stk500generic.h"
|
||||
#include "stk500v2.h"
|
||||
#include "teensy.h"
|
||||
#include "usbasp.h"
|
||||
#include "usbtiny.h"
|
||||
#include "wiring.h"
|
||||
@@ -94,6 +95,7 @@ const PROGRAMMER_TYPE programmers_types[] = {
|
||||
{"stk600", stk600_initpgm, stk600_desc},
|
||||
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc},
|
||||
{"stk600pp", stk600pp_initpgm, stk600pp_desc},
|
||||
{"teensy", teensy_initpgm, teensy_desc},
|
||||
{"usbasp", usbasp_initpgm, usbasp_desc},
|
||||
{"usbtiny", usbtiny_initpgm, usbtiny_desc},
|
||||
{"wiring", wiring_initpgm, wiring_desc},
|
||||
|
||||
58
readme.md
58
readme.md
@@ -10,6 +10,7 @@ Noteable changes include:
|
||||
|
||||
- Support Atmel AVR programmers out of the box
|
||||
- Support Micronucleus bootloader
|
||||
- Support Teensy HalfKay bootloader
|
||||
- Support COM port discovery via USB VID/PID
|
||||
- Support Arduino Leonardo bootloader auto-reset
|
||||
- Support WinUSB devices via custom libusb
|
||||
@@ -18,6 +19,12 @@ Noteable changes include:
|
||||
- Support Visual Studio
|
||||
- Miscellaneous bug-fixes and patches
|
||||
|
||||
## Download
|
||||
|
||||
To get the latest version of **AVRDUDE for Windows**, go to the [releases folder](https://github.com/mariusgreuel/avrdude/releases):
|
||||
|
||||
<https://github.com/mariusgreuel/avrdude/releases>
|
||||
|
||||
## Feature Details
|
||||
|
||||
### Support Atmel AVR programmers out of the box
|
||||
@@ -44,7 +51,27 @@ As it does not support reading, use the -V option to prevent AVRDUDE from verifi
|
||||
#### Example: Flashing a Micronucleus bootloader device
|
||||
|
||||
```bash
|
||||
AVRDUDE -c micronucleus -p t85 -x wait -V -U flash:w:main.hex:i
|
||||
avrdude -c micronucleus -p t85 -x wait -V -U flash:w:main.hex:i
|
||||
```
|
||||
|
||||
### Support Teensy HalfKay bootloader
|
||||
|
||||
This build adds support for the [Teensy HalfKay bootloader](https://www.pjrc.com/teensy/halfkay_protocol.html), so you do no longer need a the Teensy Loader tool when working with Teensy devices.
|
||||
|
||||
Since this bootloader is optimized for size, it implements writing to flash memory only.
|
||||
As it does not support reading, use the -V option to prevent AVRDUDE from verifing the flash memory. To have AVRDUDE wait for the device to be connected, use the extended option '-x wait'.
|
||||
|
||||
Supported devices are:
|
||||
|
||||
- Teensy 1.0 (AT90USB162)
|
||||
- Teensy 2.0 (ATmega32U4)
|
||||
- Teensy++ 1.0 (AT90USB646)
|
||||
- Teensy++ 2.0 (AT90USB1286)
|
||||
|
||||
#### Example: Flashing a Teensy 2.0 device
|
||||
|
||||
```bash
|
||||
avrdude -c teensy -p m32u4 -x wait -V -U flash:w:main.hex:i
|
||||
```
|
||||
|
||||
### Support COM port discovery via USB VID/PID
|
||||
@@ -157,13 +184,17 @@ Note: The folder `msvc\generated` includes pre-built files from the AVRDUDE conf
|
||||
|
||||
### Building AVRDUDE for Linux
|
||||
|
||||
Note that the AVRDUDE for Linux version does not contain all extra Windows features. The features that have been added to the stock version of AVRDUDE include:
|
||||
|
||||
- Support Micronucleus bootloader
|
||||
- Support Teensy HalfKay bootloader
|
||||
|
||||
#### Linux Prerequisites
|
||||
|
||||
In order to build AVRDUDE on Linux, you need the following packages:
|
||||
In order to build AVRDUDE on Linux, you need to install the following packages:
|
||||
|
||||
```bash
|
||||
sudo apt install make gcc automake libtool flex bison
|
||||
sudo apt install libelf-dev libusb-dev libftdi1-dev libhidapi-dev
|
||||
sudo apt install git make gcc automake libtool flex bison libelf-dev libusb-dev libftdi1-dev libhidapi-dev
|
||||
```
|
||||
|
||||
#### Linux Build Instructions
|
||||
@@ -178,6 +209,25 @@ cd avrdude
|
||||
make
|
||||
```
|
||||
|
||||
To install a local build of AVRDUDE on your system, run the following command:
|
||||
|
||||
```bash
|
||||
sudo make install
|
||||
```
|
||||
|
||||
#### Linux udev rules
|
||||
|
||||
If you intent to use either the Micronucleus or Teensy bootloader, you should edit the udev rules so that you can run AVRDUDE without root.
|
||||
|
||||
For instance, if you are on Ubuntu and you installed the avrdude package, you would edit `/lib/udev/rules.d/60-avrdude.rules` and add the following rules:
|
||||
|
||||
```bash
|
||||
# Micronucleus Bootloader
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="16d0", ATTR{idProduct}=="0753", TAG+="uaccess"
|
||||
# Teensy Bootloader
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="16c0", ATTR{idProduct}=="0478", TAG+="uaccess"
|
||||
```
|
||||
|
||||
## Troubleshooting Tips & Tricks
|
||||
|
||||
### Atmel DFU Device driver broken
|
||||
|
||||
616
teensy.c
Normal file
616
teensy.c
Normal file
@@ -0,0 +1,616 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2020 Marius Greuel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Notes:
|
||||
// This file adds support for the HalfKay bootloader,
|
||||
// so you do no longer need the Teensy loader utility.
|
||||
//
|
||||
// This HalfKay bootloader is used on various PJRC Teensy boards,
|
||||
// such as Teensy 2.0 (ATmega32U4), Teensy++ 2.0 (AT90USB1286),
|
||||
// and the respective clones.
|
||||
// By default, it bootloader uses the VID/PID 16C0:0478 (VOTI).
|
||||
//
|
||||
// As the Teensy bootloader is optimized for size, it implements
|
||||
// writing to flash memory only. Since it does not support reading,
|
||||
// use the -V option to prevent avrdude from verifing the flash memory.
|
||||
// To have avrdude wait for the device to be connected, use the
|
||||
// extended option '-x wait'.
|
||||
//
|
||||
// Example:
|
||||
// avrdude -c teensy -p m32u4 -x wait -V -U flash:w:main.hex:i
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "avrdude.h"
|
||||
#include "teensy.h"
|
||||
#include "usbdevs.h"
|
||||
|
||||
#if defined(HAVE_LIBHIDAPI)
|
||||
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define TEENSY_CONNECT_WAIT 100
|
||||
|
||||
#define PDATA(pgm) ((pdata_t*)(pgm->cookie))
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef struct pdata
|
||||
{
|
||||
hid_device* hid_handle;
|
||||
uint16_t hid_usage;
|
||||
// Extended parameters
|
||||
bool wait_until_device_present;
|
||||
// Bootloader info (from hid_usage)
|
||||
const char* board;
|
||||
uint32_t flash_size;
|
||||
uint16_t page_size;
|
||||
uint8_t sig_bytes[3];
|
||||
// State
|
||||
bool erase_flash;
|
||||
bool reboot;
|
||||
} pdata_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void delay_ms(uint32_t duration)
|
||||
{
|
||||
usleep(duration * 1000);
|
||||
}
|
||||
|
||||
static int teensy_get_bootloader_info(pdata_t* pdata, AVRPART* p)
|
||||
{
|
||||
switch (pdata->hid_usage)
|
||||
{
|
||||
case 0x19:
|
||||
pdata->board = "Teensy 1.0 (AT90USB162)";
|
||||
pdata->flash_size = 0x4000 - 0x200;
|
||||
pdata->page_size = 128;
|
||||
pdata->sig_bytes[0] = 0x1E;
|
||||
pdata->sig_bytes[1] = 0x94;
|
||||
pdata->sig_bytes[2] = 0x82;
|
||||
break;
|
||||
case 0x1A:
|
||||
pdata->board = "Teensy++ 1.0 (AT90USB646)";
|
||||
pdata->flash_size = 0x10000 - 0x400;
|
||||
pdata->page_size = 256;
|
||||
pdata->sig_bytes[0] = 0x1E;
|
||||
pdata->sig_bytes[1] = 0x96;
|
||||
pdata->sig_bytes[2] = 0x82;
|
||||
break;
|
||||
case 0x1B:
|
||||
pdata->board = "Teensy 2.0 (ATmega32U4)";
|
||||
pdata->flash_size = 0x8000 - 0x200;
|
||||
pdata->page_size = 128;
|
||||
pdata->sig_bytes[0] = 0x1E;
|
||||
pdata->sig_bytes[1] = 0x95;
|
||||
pdata->sig_bytes[2] = 0x87;
|
||||
break;
|
||||
case 0x1C:
|
||||
pdata->board = "Teensy++ 2.0 (AT90USB1286)";
|
||||
pdata->flash_size = 0x20000 - 0x400;
|
||||
pdata->page_size = 256;
|
||||
pdata->sig_bytes[0] = 0x1E;
|
||||
pdata->sig_bytes[1] = 0x97;
|
||||
pdata->sig_bytes[2] = 0x82;
|
||||
break;
|
||||
default:
|
||||
if (pdata->hid_usage == 0)
|
||||
{
|
||||
// On Linux, libhidapi does not seem to return the HID usage from the report descriptor.
|
||||
// We try to infer the board from the part information, until somebody fixes libhidapi.
|
||||
// To use this workaround, the -F option is required.
|
||||
avrdude_message(MSG_INFO, "%s: WARNING: Cannot detect board type (HID usage is 0)\n", progname);
|
||||
|
||||
AVRMEM* mem = avr_locate_mem(p, "flash");
|
||||
if (mem == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "No flash memory for part %s\n", p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdata->board = "Unknown Board";
|
||||
pdata->flash_size = mem->size - (mem->size < 0x10000 ? 0x200 : 0x400);
|
||||
pdata->page_size = mem->page_size;
|
||||
|
||||
// Pass an invalid signature to require -F option.
|
||||
pdata->sig_bytes[0] = 0x1E;
|
||||
pdata->sig_bytes[1] = 0x00;
|
||||
pdata->sig_bytes[2] = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Teensy board not supported (HID usage 0x%02X)\n",
|
||||
progname, pdata->hid_usage);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void teensy_dump_device_info(pdata_t* pdata)
|
||||
{
|
||||
avrdude_message(MSG_NOTICE, "%s: HID usage: 0x%02X\n", progname, pdata->hid_usage);
|
||||
avrdude_message(MSG_NOTICE, "%s: Board: %s\n", progname, pdata->board);
|
||||
avrdude_message(MSG_NOTICE, "%s: Available flash size: %u\n", progname, pdata->flash_size);
|
||||
avrdude_message(MSG_NOTICE, "%s: Page size: %u\n", progname, pdata->page_size);
|
||||
avrdude_message(MSG_NOTICE, "%s: Signature: 0x%02X%02X%02X\n", progname,
|
||||
pdata->sig_bytes[0], pdata->sig_bytes[1], pdata->sig_bytes[2]);
|
||||
}
|
||||
|
||||
static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* buffer, uint32_t size)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_write_page(address=0x%06X, size=%d)\n", progname, address, size);
|
||||
|
||||
if (size > pdata->page_size)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Invalid page size: %u\n", progname, pdata->page_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t report_size = 1 + 2 + (size_t)pdata->page_size;
|
||||
uint8_t* report = (uint8_t*)malloc(report_size);
|
||||
if (report == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Failed to allocate memory\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
report[0] = 0; // report number
|
||||
if (pdata->page_size <= 256 && pdata->flash_size < 0x10000)
|
||||
{
|
||||
report[1] = (uint8_t)(address >> 0);
|
||||
report[2] = (uint8_t)(address >> 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
report[1] = (uint8_t)(address >> 8);
|
||||
report[2] = (uint8_t)(address >> 16);
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
memcpy(report + 1 + 2, buffer, size);
|
||||
}
|
||||
|
||||
memset(report + 1 + 2 + size, 0xFF, report_size - (1 + 2 + size));
|
||||
|
||||
int result = hid_write(pdata->hid_handle, report, report_size);
|
||||
free(report);
|
||||
if (result < 0)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: WARNING: Failed to write page: %ls\n",
|
||||
progname, hid_error(pdata->hid_handle));
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teensy_erase_flash(pdata_t* pdata)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_erase_flash()\n", progname);
|
||||
|
||||
// Write a dummy page at address 0 to explicitly erase the flash.
|
||||
return teensy_write_page(pdata, 0, NULL, 0);
|
||||
}
|
||||
|
||||
static int teensy_reboot(pdata_t* pdata)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_reboot()\n", progname);
|
||||
|
||||
// Write a dummy page at address -1 to reboot the Teensy.
|
||||
return teensy_write_page(pdata, 0xFFFFFFFF, NULL, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void teensy_setup(PROGRAMMER* pgm)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_setup()\n", progname);
|
||||
|
||||
if ((pgm->cookie = malloc(sizeof(pdata_t))) == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Failed to allocate memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(pgm->cookie, 0, sizeof(pdata_t));
|
||||
}
|
||||
|
||||
static void teensy_teardown(PROGRAMMER* pgm)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_teardown()\n", progname);
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
static int teensy_initialize(PROGRAMMER* pgm, AVRPART* p)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_initialize()\n", progname);
|
||||
|
||||
pdata_t* pdata = PDATA(pgm);
|
||||
|
||||
int result = teensy_get_bootloader_info(pdata, p);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
teensy_dump_device_info(pdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void teensy_display(PROGRAMMER* pgm, const char* prefix)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_display()\n", progname);
|
||||
}
|
||||
|
||||
static void teensy_powerup(PROGRAMMER* pgm)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_powerup()\n", progname);
|
||||
}
|
||||
|
||||
static void teensy_powerdown(PROGRAMMER* pgm)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_powerdown()\n", progname);
|
||||
|
||||
pdata_t* pdata = PDATA(pgm);
|
||||
|
||||
if (pdata->erase_flash)
|
||||
{
|
||||
teensy_erase_flash(pdata);
|
||||
pdata->erase_flash = false;
|
||||
}
|
||||
|
||||
if (pdata->reboot)
|
||||
{
|
||||
teensy_reboot(pdata);
|
||||
pdata->reboot = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void teensy_enable(PROGRAMMER* pgm)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_enable()\n", progname);
|
||||
}
|
||||
|
||||
static void teensy_disable(PROGRAMMER* pgm)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_disable()\n", progname);
|
||||
}
|
||||
|
||||
static int teensy_program_enable(PROGRAMMER* pgm, AVRPART* p)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_program_enable()\n", progname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teensy_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_read_sig_bytes()\n", progname);
|
||||
|
||||
if (mem->size < 3)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: memory size too small for read_sig_bytes\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdata_t* pdata = PDATA(pgm);
|
||||
memcpy(mem->buf, pdata->sig_bytes, sizeof(pdata->sig_bytes));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teensy_chip_erase(PROGRAMMER* pgm, AVRPART* p)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_chip_erase()\n", progname);
|
||||
|
||||
pdata_t* pdata = PDATA(pgm);
|
||||
|
||||
// Schedule a chip erase, either at first write or on powerdown.
|
||||
pdata->erase_flash = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teensy_open(PROGRAMMER* pgm, char* port)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_open(\"%s\")\n", progname, port);
|
||||
|
||||
pdata_t* pdata = PDATA(pgm);
|
||||
char* bus_name = NULL;
|
||||
char* dev_name = NULL;
|
||||
|
||||
// if no -P was given or '-P usb' was given
|
||||
if (strcmp(port, "usb") == 0)
|
||||
{
|
||||
port = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate bus and device names from -P option
|
||||
if (strncmp(port, "usb", 3) == 0 && ':' == port[3])
|
||||
{
|
||||
bus_name = port + 4;
|
||||
dev_name = strchr(bus_name, ':');
|
||||
if (dev_name != NULL)
|
||||
{
|
||||
*dev_name = '\0';
|
||||
dev_name++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (port != NULL && dev_name == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Invalid -P value: '%s'\n", progname, port);
|
||||
avrdude_message(MSG_INFO, "%sUse -P usb:bus:device\n", progbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Determine VID/PID
|
||||
int vid = pgm->usbvid ? pgm->usbvid : TEENSY_VID;
|
||||
int pid = TEENSY_PID;
|
||||
|
||||
LNODEID usbpid = lfirst(pgm->usbpid);
|
||||
if (usbpid != NULL)
|
||||
{
|
||||
pid = *(int*)(ldata(usbpid));
|
||||
if (lnext(usbpid))
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: WARNING: using PID 0x%04x, ignoring remaining PIDs in list\n",
|
||||
progname, pid);
|
||||
}
|
||||
}
|
||||
|
||||
bool show_retry_message = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Search for device
|
||||
struct hid_device_info* devices = hid_enumerate(vid, pid);
|
||||
struct hid_device_info* device = devices;
|
||||
|
||||
while (device)
|
||||
{
|
||||
if (device->vendor_id == vid && device->product_id == pid)
|
||||
{
|
||||
pdata->hid_handle = hid_open_path(device->path);
|
||||
if (pdata->hid_handle == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Found HID device, but hid_open_path() failed.\n", progname);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata->hid_usage = device->usage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
device = device->next;
|
||||
}
|
||||
|
||||
hid_free_enumeration(devices);
|
||||
|
||||
if (pdata->hid_handle == NULL && pdata->wait_until_device_present)
|
||||
{
|
||||
if (show_retry_message)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: No device found, waiting for device...\n", progname);
|
||||
avrdude_message(MSG_INFO, "%s: Press CTRL-C to terminate.\n", progname);
|
||||
show_retry_message = false;
|
||||
}
|
||||
|
||||
delay_ms(TEENSY_CONNECT_WAIT);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pdata->hid_handle)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: Could not find device with Teensy bootloader (%04X:%04X)\n",
|
||||
progname, vid, pid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void teensy_close(PROGRAMMER* pgm)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_close()\n", progname);
|
||||
|
||||
pdata_t* pdata = PDATA(pgm);
|
||||
if (pdata->hid_handle != NULL)
|
||||
{
|
||||
hid_close(pdata->hid_handle);
|
||||
pdata->hid_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int teensy_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
|
||||
unsigned long addr, unsigned char* value)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_read_byte(desc=%s, addr=0x%0X)\n",
|
||||
progname, mem->desc, addr);
|
||||
|
||||
if (strcmp(mem->desc, "lfuse") == 0 ||
|
||||
strcmp(mem->desc, "hfuse") == 0 ||
|
||||
strcmp(mem->desc, "efuse") == 0 ||
|
||||
strcmp(mem->desc, "lock") == 0)
|
||||
{
|
||||
*value = 0xFF;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: Unsupported memory type: %s\n", progname, mem->desc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int teensy_write_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
|
||||
unsigned long addr, unsigned char value)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_write_byte(desc=%s, addr=0x%0X)\n",
|
||||
progname, mem->desc, addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int teensy_paged_load(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n",
|
||||
progname, page_size, addr, n_bytes);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int teensy_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n",
|
||||
progname, page_size, addr, n_bytes);
|
||||
|
||||
if (strcmp(mem->desc, "flash") == 0)
|
||||
{
|
||||
pdata_t* pdata = PDATA(pgm);
|
||||
|
||||
if (n_bytes > page_size)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: Buffer size (%u) exceeds page size (%u)\n", progname, n_bytes, page_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (addr + n_bytes > pdata->flash_size)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: Program size (%u) exceeds flash size (%u)\n", progname, addr + n_bytes, pdata->flash_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pdata->erase_flash)
|
||||
{
|
||||
// Writing page 0 will automatically erase the flash.
|
||||
// If mem does not contain a page at address 0, write a dummy page at address 0.
|
||||
if (addr != 0)
|
||||
{
|
||||
int result = teensy_erase_flash(pdata);
|
||||
if (result < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
pdata->erase_flash = false;
|
||||
}
|
||||
|
||||
int result = teensy_write_page(pdata, addr, mem->buf + addr, n_bytes);
|
||||
if (result < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Schedule a reboot.
|
||||
pdata->reboot = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: Unsupported memory type: %s\n", progname, mem->desc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int teensy_parseextparams(PROGRAMMER* pgm, LISTID xparams)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: teensy_parseextparams()\n", progname);
|
||||
|
||||
pdata_t* pdata = PDATA(pgm);
|
||||
for (LNODEID node = lfirst(xparams); node != NULL; node = lnext(node))
|
||||
{
|
||||
const char* param = ldata(node);
|
||||
|
||||
if (strcmp(param, "wait") == 0)
|
||||
{
|
||||
pdata->wait_until_device_present = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: Invalid extended parameter '%s'\n", progname, param);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void teensy_initpgm(PROGRAMMER* pgm)
|
||||
{
|
||||
strcpy(pgm->type, "teensy");
|
||||
|
||||
pgm->setup = teensy_setup;
|
||||
pgm->teardown = teensy_teardown;
|
||||
pgm->initialize = teensy_initialize;
|
||||
pgm->display = teensy_display;
|
||||
pgm->powerup = teensy_powerup;
|
||||
pgm->powerdown = teensy_powerdown;
|
||||
pgm->enable = teensy_enable;
|
||||
pgm->disable = teensy_disable;
|
||||
pgm->program_enable = teensy_program_enable;
|
||||
pgm->read_sig_bytes = teensy_read_sig_bytes;
|
||||
pgm->chip_erase = teensy_chip_erase;
|
||||
pgm->cmd = NULL;
|
||||
pgm->open = teensy_open;
|
||||
pgm->close = teensy_close;
|
||||
pgm->read_byte = teensy_read_byte;
|
||||
pgm->write_byte = teensy_write_byte;
|
||||
pgm->paged_load = teensy_paged_load;
|
||||
pgm->paged_write = teensy_paged_write;
|
||||
pgm->parseextparams = teensy_parseextparams;
|
||||
}
|
||||
|
||||
#else /* !HAVE_LIBHIDAPI */
|
||||
|
||||
// Give a proper error if we were not compiled with libhidapi
|
||||
static int teensy_nousb_open(struct programmer_t* pgm, char* name)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: error: No HID support. Please compile again with libhidapi installed.\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void teensy_initpgm(PROGRAMMER* pgm)
|
||||
{
|
||||
strcpy(pgm->type, "teensy");
|
||||
pgm->open = teensy_nousb_open;
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBHIDAPI */
|
||||
|
||||
const char teensy_desc[] = "Teensy Bootloader";
|
||||
35
teensy.h
Normal file
35
teensy.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2020 Marius Greuel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef teensy_h
|
||||
#define teensy_h
|
||||
|
||||
#include "libavrdude.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char teensy_desc[];
|
||||
void teensy_initpgm(PROGRAMMER* pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* teensy_h */
|
||||
Reference in New Issue
Block a user