/* NanoStack: MCU software and PC tools for IP-based wireless sensor networking. Copyright (C) 2006-2007 Sensinode Ltd. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Address: Sensinode Ltd. Teknologiantie 6 90570 Oulu, Finland E-mail: info@sensinode.com */ #include #include #ifdef PLATFORM_WINDOWS #include #endif #include FT_HANDLE curr_handle = 0; uint8_t curr_mode = 0; /* 0 = in, 1=out */ /* * This function checks if the CBUS2 ise set to SLEEP and modifies it if necessary. * The CBUS2 must be set to sleep in order the programming to succeed. */ int check_cbus2(FT_HANDLE fthandle) { FT_PROGRAM_DATA eeprom_data; char manufacturer_buf[32]; char manufacturer_id[16]; char description_buf[64]; char serialnumber_buf[16]; eeprom_data.Signature1 = 0x00000000; // This is a given value from the FT232R programming guide eeprom_data.Signature2 = 0xffffffff; // This is a given value from the FT232R programming guide eeprom_data.Version = 0x00000002; // This is a given value from the FT232R programming guide eeprom_data.Manufacturer = manufacturer_buf; eeprom_data.ManufacturerId = manufacturer_id; eeprom_data.Description = description_buf; eeprom_data.SerialNumber = serialnumber_buf; if(FT_EE_Read(fthandle, &eeprom_data) != FT_OK) { printf("FTDI EEPROM read failed.\n"); return(-1); } if(eeprom_data.Cbus2 != 0x05) { printf("Need to re-program the CBUS2 to 0x05\n"); eeprom_data.Cbus2 = 0x05; if(FT_EE_Program(fthandle, &eeprom_data) != FT_OK) { printf("FTDI EEPROM program error.\n"); return(-1); } else { printf("FTDI EEPROM program ok\n"); return(1); } } else { return(1); } return(1); } void prog_scan(void) { FT_STATUS ftStatus; FT_DEVICE_LIST_INFO_NODE *info; unsigned long n_devices = 0; uint8_t out; ftStatus = FT_CreateDeviceInfoList(&n_devices); if (ftStatus == FT_OK) { FT_DEVICE_LIST_INFO_NODE devices[n_devices]; ftStatus = FT_GetDeviceInfoList(devices,&n_devices); if (ftStatus == FT_OK) { for (out = 0; out < n_devices; out++) { printf("Dev %d:",n_devices - out -1); printf(" Type=0x%x",devices[n_devices - out -1].Type); printf(" SerialNumber=%s",devices[n_devices - out -1].SerialNumber); printf(" Description=%s\n",devices[n_devices - out -1].Description); } } else { printf("Failed to fetch device list.\n"); } } else { printf("Failed to fetch device list.\n"); } } FT_HANDLE prog_open(int iport) { FT_HANDLE ftHandle; FT_STATUS ftStatus; FT_DEVICE_LIST_INFO_NODE *info; unsigned long n_devices = 0; uint8_t out; if (curr_handle) return 0; ftStatus = FT_CreateDeviceInfoList(&n_devices); if (ftStatus == FT_OK) { FT_DEVICE_LIST_INFO_NODE devices[n_devices]; ftStatus = FT_GetDeviceInfoList(devices,&n_devices); if (ftStatus == FT_OK) { iport = n_devices - iport - 1; if (iport < 0) { printf("Invalid port id.\n"); for (out = 0; out < n_devices; out++) { printf("Dev %d:",n_devices - out -1); printf(" Type=0x%x",devices[n_devices - out -1].Type); printf(" SerialNumber=%s",devices[n_devices - out -1].SerialNumber); printf(" Description=%s\n",devices[n_devices - out -1].Description); } return 0; } } } ftStatus = FT_Open(iport, &ftHandle); if(ftStatus != FT_OK) { /* This can fail if the ftdi_sio driver is loaded use lsmod to check this and rmmod ftdi_sio to remove also rmmod usbserial */ printf("FT_Open(%d) failed\n", iport); return 0; } if(check_cbus2(ftHandle) < 0) { printf("Nano USB Programmer exiting...\n"); return(0); } FT_ResetDevice(ftHandle); FT_SetBaudRate(ftHandle, 115200); FT_SetUSBParameters(ftHandle, 64, 0); out = 0x04; ftStatus = FT_SetBitMode(ftHandle, out, 0x20); if (ftStatus == FT_OK) { ftStatus = FT_SetLatencyTimer(ftHandle, 2); } if (ftStatus == FT_OK) { DWORD bytes; out = 0xE0; ftStatus = FT_SetBitMode(ftHandle, out, 0x04); out = 0x80; FT_Write(ftHandle, &out, 1, &bytes); /*write reset high*/ FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ curr_mode = 1; } if (ftStatus != FT_OK) { printf("Failed to set CBUS2/bit bang mode.\n"); FT_ResetDevice(ftHandle); sleep(3); FT_Close(ftHandle); ftHandle = 0; } curr_handle = ftHandle; return ftHandle; } void prog_close(void) { FT_STATUS ftStatus; DWORD bytes; if (curr_handle) { FT_HANDLE ftHandle = curr_handle; uint8_t out = 0x00; FT_Write(ftHandle, &out, 1, &bytes); /*write reset low*/ FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ sleep(1); out = 0x80; FT_Write(ftHandle, &out, 1, &bytes); /*write reset high*/ FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ sleep(1); out = 0x00; ftStatus = FT_SetBitMode(ftHandle, out, 0x04); FT_ResetDevice(ftHandle); FT_Close(ftHandle); ftHandle = 0; curr_handle = ftHandle; } } int prog_write(uint8_t byte) { FT_STATUS ftStatus; uint8_t out[16]; uint8_t mask = 0x80; int i; DWORD bytes; if (curr_mode == 0) { out[0] = 0xE0; ftStatus = FT_SetBitMode(curr_handle, out[0], 0x04); /*Set DD as output*/ if (ftStatus != FT_OK) { printf("!WR"); fflush(stdout); return -1; } curr_mode = 1; } i = 0; while (mask) { out[i] = 0xC0; /*clock high, reset high*/ if (byte & mask) out[i] |= 0x20; i++; out[i] = 0x80; /*clock low, reset high*/ if (byte & mask) out[i] |= 0x20; i++; mask >>= 1; } ftStatus = FT_Write(curr_handle, out, 16, &bytes); /*write clock high and data bit*/ if (ftStatus != FT_OK) { printf("!W"); fflush(stdout); return -1; } if(FT_Read(curr_handle, out, 16, &bytes) != FT_OK) { printf("!R"); return(-1); } return 0; } int prog_read(uint8_t *byte) { FT_STATUS ftStatus; uint8_t rd; uint8_t mask = 0x80; DWORD bytes; uint8_t out[17]; uint8_t i=0; *byte = 0; if (curr_mode == 1) { out[0] = 0xC0; ftStatus = FT_SetBitMode(curr_handle, out[0], 0x04); /*Set DD as input*/ if (ftStatus != FT_OK) { printf("!RD"); fflush(stdout); return -1; } curr_mode = 0; } while (mask) { out[i] = 0xC0; /*clock high, reset high*/ if (*byte & mask) out[i] |= 0x20; i++; out[i] = 0x80; /*clock low, reset high*/ if (*byte & mask) out[i] |= 0x20; i++; mask >>= 1; } out[16] = out[15]; ftStatus = FT_Write(curr_handle, out, 17, &bytes); /*write clock high and data bit*/ if(FT_Read(curr_handle, out, 17, &bytes) != FT_OK) { printf("!R"); return(-1); } mask = 0x80; i = 1; while (mask) { if (out[i] & 0x20) *byte |= mask; mask >>= 1; i+=2; } return 0; } int prog_start(void) { FT_STATUS ftStatus; uint8_t wr; uint8_t mask = 0x80; DWORD bytes; uint8_t out[16] = { 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80 }; printf("prog_start()\n"); if (curr_mode == 0) { wr = 0xE0; ftStatus = FT_SetBitMode(curr_handle, wr, 0x04); /*Set DD as output*/ curr_mode = 1; } if(FT_Write(curr_handle, out, 7, &bytes) != FT_OK) { printf("!W\n"); return(-1); } if(FT_Read(curr_handle, out, 7, &bytes) != FT_OK) { printf("!R\n"); return(-1); } }