/* * Turbo Programmer Utilities, turbo-prog-utils, www.bladox.com * * Copyright (C) 2004 BLADOX, s.r.o. * * 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, 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. */ #include <config.h> #include <tprog/tprog.h> #include <stdlib.h> #include <avr/interrupt.h> #include "turboadapter.h" #include "btldr.h" #define DEFAULT_BTLDR_CLK_DIV (2) #define DEFAULT_F (372) #define DEFAULT_D (1) #define DEFAULT_DIVIDER (DEFAULT_F/DEFAULT_D) u16 actualUbrr; #define BTLDR_TX_SM_STATE1 (1) #define BTLDR_TX_SM_STATE2 (2) u8 btldrUartTxStateMachine; #define BTLDR_UART_RX_FIFO_SIZE 8 u8 btldrUartRxFifo[BTLDR_UART_RX_FIFO_SIZE]; u8 btldrUartRxFifoNumOfChars; u8 btldrUartRxFifoTail; u8 btldrUartRxFifoHead; void init_vars () { btldrUartRxFifoHead = 0; btldrUartRxFifoTail = 0; btldrUartRxFifoNumOfChars = 0; actualUbrr = ((DEFAULT_BTLDR_CLK_DIV * DEFAULT_DIVIDER) / 8) - 1; btldrUartTxStateMachine = BTLDR_TX_SM_STATE1; } void init_btldrUart (void) { //set mode to double speed outb (BTLDR_UART_UCSRA, 0x02); // enable receive complete interrupt // disable transmit complete interrupt // enable receiver // disable transmitter because of RXD and TXD connected together // to not output log.1 to TXD and RXD // we enable transmitter before each char will be send outb (BTLDR_UART_UCSRB, 0x90); // asynchronous mode // 8 bit data, even parity, 1 stop bit outb (BTLDR_UART_UCSRC, 0x26); // set baud rate register to DEFAULT_DIVIDER outb (BTLDR_UART_UBRRH, (actualUbrr >> 8)); outb (BTLDR_UART_UBRRL, (actualUbrr & 0xFF)); } u8 btldrRxChars (void) { u8 tmpRxChars; cli (); tmpRxChars = btldrUartRxFifoNumOfChars; sei (); return tmpRxChars; } u8 btldrRxGetChar (void) { u8 tmpTail; cli (); if (btldrUartRxFifoNumOfChars > 0) { btldrUartRxFifoNumOfChars--; sei (); tmpTail = btldrUartRxFifoTail; if (btldrUartRxFifoTail < (BTLDR_UART_RX_FIFO_SIZE - 1)) btldrUartRxFifoTail++; else btldrUartRxFifoTail = 0; return btldrUartRxFifo[tmpTail]; } else { sei (); return 0; } } void btldrTxSendChar (u8 txValue) { u8 txValueTmp; u8 iTmp; u8 interrupts; //store global interrupt enable bit interrupts = (inb (SREG) & (1 << SREG_I)); //cli(); txValueTmp = txValue; if (btldrUartTxStateMachine == BTLDR_TX_SM_STATE1) { // execute delay before transmitting char //do delay interval delayMs (3); btldrUartTxStateMachine = BTLDR_TX_SM_STATE2; } // disable receive complete interrupt // disable receiver outb (BTLDR_UART_UCSRB, (inb (BTLDR_UART_UCSRB) & 0x6F)); //TXD1 pin to log.1 sbi (BTLDR_TXD_PORT, BTLDR_TXD_PORT_PIN); //TXD1 pin change direction to output only when transmitting char sbi (BTLDR_TXD_DDR, BTLDR_TXD_DDR_DD); // enable transmitter outb (BTLDR_UART_UCSRB, (inb (BTLDR_UART_UCSRB) | 0x08)); // send txValueTmp to UDR register sbi (BTLDR_UART_UCSRA, TXC); outb (BTLDR_UDR, txValueTmp); loop_until_bit_is_set (BTLDR_UART_UCSRA, TXC); sbi (BTLDR_UART_UCSRA, TXC); // disable transmitter outb (BTLDR_UART_UCSRB, (inb (BTLDR_UART_UCSRB) & 0xF7)); // set TXD1 pin to log.1 sbi (BTLDR_TXD_PORT, BTLDR_TXD_PORT_PIN); //TXD1 pin change direction to input to allow receiving cbi (BTLDR_TXD_DDR, BTLDR_TXD_DDR_DD); // clear TXC flag (write log.1 to it) sbi (BTLDR_UART_UCSRA, TXC); //restore global interrupt enable bit if (interrupts != 0) sei (); // enable receive complete interrupt // enable receiver outb (BTLDR_UART_UCSRB, (inb (BTLDR_UART_UCSRB) | 0x90)); } void init_turboadapter_btldr_port () { led_on (LED_TFM); //DEBUG_SS_MCU change direction to output sbi (DEBUG_SS_MCU_DDR, DEBUG_SS_MCU_DDR_DD); // RESETn pin stays output and set it to log.1 sbi (PROG_RESETn_PORT, PROG_RESETn_PORT_PIN); sbi (PROG_RESETn_DDR, PROG_RESETn_DDR_DD); //PROG_DEBUG_RESETn_ENABLE pin set it to log.0 //(in BTLDR mode RESETn is connected) ext_cbi (EXT_PROG_DEBUG_RESETn_ENABLE_PORT, EXT_PROG_DEBUG_RESETn_ENABLE_PORT_PIN); delayMs (200); // clear RXC flag (write log.1 to it) sbi (BTLDR_UART_UCSRA, RXC); // clear TXC flag (write log.1 to it) sbi (BTLDR_UART_UCSRA, TXC); // set baud rate to enhanced value from PTS outb (BTLDR_UART_UBRRH, (actualUbrr >> 8)); outb (BTLDR_UART_UBRRL, (actualUbrr & 0xFF)); //PROG_DEBUG_CLKA_ENABLE set it to log.1 //(in BTLDR_MODE CLKA is connected) ext_sbi (EXT_PROG_DEBUG_CLKA_ENABLE_PORT, EXT_PROG_DEBUG_CLKA_ENABLE_PORT_PIN); delayMs (10); //BTLDR_RX //let it set to input //set pin to log.1 sbi (BTLDR_RXD_PORT, BTLDR_RXD_PORT_PIN); cbi (BTLDR_RXD_DDR, BTLDR_RXD_DDR_DD); //BTLDR_TX //let it set to output //set pin to log.0 cbi (BTLDR_TXD_PORT, BTLDR_TXD_PORT_PIN); sbi (BTLDR_TXD_DDR, BTLDR_TXD_DDR_DD); //BTLDR_ENABLE //set pin to log.1 //(in BTLDR_MODE BTLDR_RX and BTLDR_TX are connected) ext_sbi (EXT_BTLDR_ENABLE_PORT, EXT_BTLDR_ENABLE_PORT_PIN); delayMs (10); //PROG_DEBUG_VCC_ENABLE set it to log.0 //(in BTLDR_MODE we must apply power after all unecessary signals were disconnected) ext_cbi (EXT_PROG_DEBUG_VCC_ENABLE_PORT, EXT_PROG_DEBUG_VCC_ENABLE_PORT_PIN); //EXTRA RESET------------------------------- delayMs (200); // RESETn pin stays output and set it to log.0 cbi (PROG_RESETn_PORT, PROG_RESETn_PORT_PIN); sbi (PROG_RESETn_DDR, PROG_RESETn_DDR_DD); //PROG_DEBUG_RESETn_ENABLE pin set it to log.1 //(in BTLDR mode RESETn is connected) ext_sbi (EXT_PROG_DEBUG_RESETn_ENABLE_PORT, EXT_PROG_DEBUG_RESETn_ENABLE_PORT_PIN); delayMs (100); // RESETn pin stays output and set it to log.1 sbi (PROG_RESETn_PORT, PROG_RESETn_PORT_PIN); sbi (PROG_RESETn_DDR, PROG_RESETn_DDR_DD); //PROG_DEBUG_RESETn_ENABLE pin set it to log.0 //(in BTLDR mode RESETn is disconnected) ext_cbi (EXT_PROG_DEBUG_RESETn_ENABLE_PORT, EXT_PROG_DEBUG_RESETn_ENABLE_PORT_PIN); //EXTRA RESET------------------------------- delayMs (500); //remove any char pending in btldf rx fifo while (btldrRxChars () != 0) btldrRxGetChar (); delayMs (10); //BTLDR_TX //let it set to input //set pin to log.1 sbi (BTLDR_TXD_PORT, BTLDR_TXD_PORT_PIN); cbi (BTLDR_TXD_DDR, BTLDR_TXD_DDR_DD); delayMs (10); } void btldr_uart_irq () { // next BTLDR char transmit will execute delay before transmitting char btldrUartTxStateMachine = BTLDR_TX_SM_STATE1; if (btldrUartRxFifoNumOfChars == BTLDR_UART_RX_FIFO_SIZE) { } else { btldrUartRxFifo[btldrUartRxFifoHead] = inb (BTLDR_UDR); btldrUartRxFifoNumOfChars++; if (btldrUartRxFifoHead < (BTLDR_UART_RX_FIFO_SIZE - 1)) btldrUartRxFifoHead++; else btldrUartRxFifoHead = 0; } } void btldr_flash_page (USB_Data * data, u8 * buf) { u16 i; led_on (LED_NO); btldrTxSendChar (UCMD_BTLDR_MODE_WRITE_PAGE_FLASH); btldrTxSendChar (data->buf[0]); btldrTxSendChar (data->buf[1]); for (i = 0; i < 256; i++) btldrTxSendChar (data->buf[2 + i]); while (btldrRxChars () == 0); buf[0] = btldrRxGetChar (); led_on (LED_TFM); usb_send (NO_ERROR, 1, buf); }
Copyright © 2004 BLADOX | Turbo Programmer version 2.0
|