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\n[1;​31mInterrupt![0;​37m\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)