User Tools

Site Tools


project:usb:code:goodlink

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

project:usb:code:goodlink [2007/04/27 00:21] (current)
Line 1: Line 1:
 +====== GoodLink(TM) code ======
 +Below is the code I needed to get the PDIUSBD12's GoodLink(TM) indicator to come on. Naturally this code runs on the PIC16F877 of my project, which is wired up as described on in the ''#define''s as well as the [[project:usb]] page.
 +
 +Below is a screenshot of HyperTerminal interacting with the system running this code. For more information on the PIC <--> PC setup, see [[:project:tools#terminals_dumb_terminal_hyperterminal|Tools]].
 +
 +{{ project:hyperterminal_goodlink_code.gif }}
 +
 +This code assumes you are using either a dumb-terminal or equivalent (I was using HyperTerminal) to view the results of ''printf'' and to satisfy ''getch()'' statements.
 +
 +This code was made for MPLAB v7.0, with the CCS add-in.
 +
 +  * {{project:usb:code:goodlink.hex|Download compiled HEX firmware}}
 +  * {{project:usb:code:goodlink_mod.hex|Download slightly modified compiled HEX firmware}} --- All getch() statements were removed, so you don't need to have RS232 working to use this
 +
 +<code c>
 +#include <16f877.h>
 +#include <ctype.h>
 +
 +//--------------------------------------------------------
 +// Setup PIC and CCS compiler
 +#fuses XT, PUT, NOWDT, NOPROTECT
 +#use delay(clock = 4000000)
 +
 +#use rs232(baud = 9600, xmit = PIN_C6, rcv = PIN_C7)
 +// By using C6 and C7, we will make use of the 877's hardware USART abilities
 +
 +#use standard_io(b)
 +#byte port_d = 8
 +
 +//--------------------------------------------------------
 +// Definitions
 +#define ON 1
 +#define OFF 0
 +
 +#define D12_A0 PIN_B6
 +#define D12_WR_N PIN_B2
 +#define D12_RD_N PIN_B1
 +#define D12_RESET_N PIN_B5
 +#define D12_SUSPEND PIN_B4
 +#define D12_INT_N PIN_B0
 +
 +#define D12_DATA 0
 +#define D12_COMMAND 1
 +
 +#define LED_N PIN_B7
 +
 +//--------------------------------------------------------
 +// Global Variable Declarations
 +
 +
 +//--------------------------------------------------------
 +// Function prototypes
 +void D12Write(short, int);
 +void D12Read(unsigned char, int);
 +void D12InterruptHandler();
 +
 +//--------------------------------------------------------
 +// Entry point
 +void main(void){
 + short debug = OFF;
 +
 + output_low(LED_N); // Turn on the yellow LED
 +
 + while(debug)
 + {
 + printf("Hello World!\r\n");
 + delay_ms(1000);
 + output_toggle(LED_N); // Yellow LED
 + }
 +
 + //---------------------------------
 +
 + printf(""); // Clear screen (ANSI escape sequence)
 + printf("Putting pins into known state and resetting D12\r\n");
 + set_tris_b(0x01); //PIN_B1 (D12's INT) is input, the rest are output.
 + set_tris_d(0x00); //All output
 + port_d = 0xFF; //Set bus high, useful for checking the ribbon has not come loose
 +
 + output_high(D12_RD_N);
 + output_high(D12_WR_N);
 +
 + output_low(D12_RESET_N); // Reset PDIUSBD12
 + output_low(D12_A0); // Indicates bus is for data
 + output_low(D12_SUSPEND); // (? Not sure how this is meant to work in practice)
 +
 + disable_interrupts(GLOBAL); // Stop interrupts from interrupting us while we setup ;)
 +
 + ext_int_edge(H_TO_L); // Set up when to trigger
 + enable_interrupts(INT_EXT); // Enable external interrupts (connected to the D12's INT_N)
 + clear_interrupt(INT_EXT); // Remove pending interrupts
 + enable_interrupts(GLOBAL); // Globally enable interrupts
 +
 + printf("=================================================\r\n");
 + printf("Ready. Press any key to proceed.\r\n");
 +
 +
 + //---------------------------------
 +
 + getch(); // Wait for keypress
 + output_high(D12_RESET_N); // Bring D12 out of reset (start it up!)
 + delay_ms(1);
 +
 + //if(input(D12_INT_N)==0)
 + // D12InterruptHandler();
 +
 + printf("CMD:  Set Address/Enable\r\n");
 + D12Write(D12_COMMAND, 0xD0);
 +
 + printf("\tDATA: 0x80 (Enable, no address)\r\n");
 + D12Write(D12_DATA, 0x80);
 +
 + printf("CMD:  Set endpoint enable\r\n");
 + D12Write(D12_COMMAND, 0xD8);
 + printf("\tDATA: 0x01 (Enabled)\r\n");
 + D12Write(D12_DATA, 0x01);
 +
 + printf("CMD:  Set Mode\r\n");
 + D12Write(D12_COMMAND, 0xF3);
 + printf("\tDATA: No Lazy Clock, Clock Running, ");
 + printf("Interrupts=1, SoftConnect=1\r\n");
 + D12Write(D12_DATA, 0x1E);
 + printf("\tDATA: Start of Frame interrupt disabled, ");
 + printf("Set-to-one not set, ");
 + printf("\r\n\t\tClock Division Factor = 1011b\r\n");
 + D12Write(D12_DATA, 0x0B);
 +
 + printf("End of Program\r\n");
 +}
 +
 +//--------------------------------------------------------
 +// Used for passing commands or data to the PDIUSBD12
 +void D12Write(short type, int data)
 +{
 + switch(type)
 + {
 + case D12_DATA:
 + case D12_COMMAND:
 + set_tris_d(0x00); // Set bus to output mode
 + output_high(D12_RD_N); // Ensure we don't conflict with RD_N
 +
 + if(type == D12_COMMAND)
 + output_high(D12_A0);
 + else
 + output_low(D12_A0);
 +
 + port_d = data; // Setup bus
 + delay_ms(1); // Settling time
 + output_low(D12_WR_N);
 + output_high(D12_WR_N);
 +
 + if(type == D12_COMMAND)
 + output_low(D12_A0);
 + break;
 + default:
 + printf("Error in D12Write(), unknown type: 0x%x!\r\n", type);
 + printf("Expecting one of:\r\n\t 0x%x\r\n\t0x%x\r\n", D12_COMMAND, D12_DATA);
 + }
 +}
 +
 +//--------------------------------------------------------
 +// Used for reading data from the PDIUSBD12
 +void D12Read(unsigned char* buffer, int reads)
 +{
 + int i;
 +
 + set_tris_d(0xFF); // Set bus to intput mode
 + for(i = 0; i<reads; i++)
 + {
 + output_low(D12_RD_N);
 + buffer[i] = port_d; // Latch in the bus
 + output_high(D12_RD_N);
 + }
 +}
 +
 +//--------------------------------------------------------
 +// FIXME: Probably want to save some registers when handling
 +//        this interrupt, as it takes quite a long time.
 +#INT_EXT
 +void D12InterruptHandler()
 +{
 + unsigned char buffer[2];
 + int i;
 +
 + // The first "" is an bell control-character, the second an escape
 + //  makes text red and bold,  makes it normal and white
 + printf("\r\n\r\nInterrupt!\r\n");
 + printf("CMD:  Read Interrupt Register\r\n");
 + D12Write(D12_COMMAND, 0xF4);
 + D12Read(buffer, 2);
 + printf("Interrupt register bytes were 0x%x and 0x%x.\r\n\r\n", buffer[0], buffer[1]);
 + getch();
 +
 + for(i=0; i<6; i++)
 + {
 + printf("CMD:  Read Last Transaction Status Register (0x%x)\r\n", 0x40 + i);
 +
 + D12Write(D12_COMMAND, 0x40 + i);
 + D12Read(buffer, 1);
 +
 + printf("\tStatus: 0x%x.\r\n", buffer[0]);
 + }
 + printf("Press a key to resume\r\n\r\n");
 + getch();
 +}
 +</code>
  
project/usb/code/goodlink.txt · Last modified: 2007/04/27 00:21 (external edit)