DEVICE SX28, OSCHS3, TURBO, STACKX, OPTIONX IRC_CAL IRC_SLOW FREQ 50000000 'January 21st, 2006 'The incoming data is at 500kbps+, as the floppy drive data rate varies. 'bit cells are approximately 2us each, and obviously get shorter as data rate increases 'worst case variation here seems to be roughly 10% (shortest is something like 7.5 on an 8us group) 'possible receive data patterns are 10, 100, and 1000. 'idle condition is a ttl high 5v 'transition to 0v is a "1" data bit 'no transition in a bitcell following a 1 is considered a "0" data bit 'data is raw amiga MFM(does not follow standard MFM rules, beware) 'Logic of this program is as follows 'setup ports of the SX, initialize variables and pins as necessary 'prepare memory for writes 'enable interrupts where all the action happens 'this program starts with the first transition and ends by being stopped in the debugger 'if you send more than 32k total bytes, the FRAM rolls and overwrites old data. 'note idle condition does *not* store series of zero..... 'currently I need separate code to xfer this to the PC. 'framtousb.SXB transmits memory contents starting at 0, one byte at a time, via async 9600 baud to capture software 'ISR logic 'we detect an edge or a "timeout" by checking the value of RTCC when we enter the ISR 'RTCC will have a low value when its a falling edge pin-trigger 'if we see an edge store a 1 and note the fact that we've seen an edge 'if we see a timer rollover, and we've seen a recent edge, make sure its not more than three rolls, store a 0 'note isr doesn't use SENDFRAM or RECVFRAM routines, but instead stores one bit at a time 'we can see bit errors in the writing of memory regarding fram errata in a case where there is a delay 'between writing the 5th and 8th bit of a byte. A single bit error is no sweat, and those delays should only 'be seek conditions, in which case we will have finished the current track. 'DOUBLE CHECK WE AREN'T GETTING SCREWED HERE ' ------------------------------------------------------------------------- ' Variables ' ------------------------------------------------------------------------- 'These names are all from the fram perspective CS var RC.7 'chip select SO var RC.6 'serial output SI var RC.5 'serial input SCK var RC.4 'serial clock seenedge var bit 'seen an edge or are we idly? pending var byte 'swapped with wkpnd_b, RTCC or edge? validhigh var byte 'how many high bits have we seen in a row myrtcc var byte 'this is saved at the top of interrupt datatosend var byte gotdata var byte nsb var byte 'number of sent bits. decremented from 8 to indicate a byte received inloop var byte 'inloop and outloop are used to clear the entire fram prior to start outloop var byte WATCH seenedge,1,UDEC WATCH pending.0,1,UBIN WATCH validhigh,8,UDEC WATCH myrtcc,8,UDEC ' ------------------------------------------------------------------------- INTERRUPT NOCODE ' ------------------------------------------------------------------------- ASM SETB rb.1 'debug pin(inside interrupt) MOV myrtcc, RTCC 'preserve for comparison later CLR FSR ISR_Start: 'a rollover here rtcc would be zero, and myrtcc should be 4 'if this was an edge, myrtcc would be much higher like 230 etc CJA myrtcc,#5,@processedge 'if myrtcc > 5 then processedge 'i dunno if Im keeping this here, doublecheck this 'wkpnd_b = 0 'MODE $09 'MOV !RB, #0 JNB seenedge,@goback 'if seenedge = 0 then goback 'are we idle? inc validhigh jb validhigh.2,@goidle 'if validhigh = 4 then goidle 'the next 5 lines of code write a 0 to the fram CLRB SCK 'make sure clock is low to start with(should already be low, though) NOP CLRB SI 'put a zero on the port NOP SETB SCK 'raise clock notifying chip to read the data goback: CLRB rb.1 'for debugging MOV W, #156 '255-100 = 156 RETIW goidle: CLRB seenedge 'erase the edge we saw before CLR validhigh 'reset and start over CLRB RB.1 'for debugging MOV w,#188 '255-188=67 RETIW processedge: MODE $09 'clear pending edge MOV !RB,#0 'bean thinks this is troublesome. try removing with the understanding that the returnint values have to be 'modified to support this change. So far timing appears to not be an issue. CLR RTCC 'sync to the edge! SETB seenedge 'we've now seen an edge! CLR validhigh 'next five lines of code store a 1 in the fram CLRB SCK 'make sure clock is low to start with(should already be low, though) NOP SETB SI 'put a one on the port NOP SETB SCK 'raise clock notifying chip to read the data retfromedge: CLRB RB.1 'for debugging MOV W,#155 'WAS 188, 150 = 2.68, 160 =2.54, 170=2.26 perfect RETIW ENDASM SENDFRAM SUB 1 'sub definition for full byte writes RECVFRAM SUB 'sub definition for a full byte read PROGRAM start_point ' Program Code ' ------------------------------------------------------------------------- start_point: 'setup port b TRIS_B=%11111001 'direction bits rb.0 input, rb.1 & rb.2 output ST_B = %11111110 'schmitt trigger for our drive input WKPND_B = 0 'clear pending interrupts WKED_B = %11111111 'set falling edge trigger WKEN_B = %11111110 'enable drive input interrupts PLP_B = %11111110 'enable pullups LVL_B = %00000000 'enable CMOS for port b 'setup port c TRIS_C=%01001111 'bits 7, 5, 4 are output, 6 input PLP_C = %00000000 CS = 1 SCK = 0 seenedge = 0 pending = 0 validhigh = 0 'xmitbytes = 128 'this entire code segment until repeat: is designed to do a couple things '1. prepare the FRAM for writing by enabling writes '2. clear the entire contents of the FRAM since this is non-volatile 'this transmits the FRAM opcode dec 6, Set Write Enable Latch, aka WREN CS=0 SENDFRAM 6 CS = 1 pauseus 1 CS = 0 'This transmits FRAM opcode dec 2, Write Memory data, WRITE SENDFRAM 2 'send the two byte address, in this case, start at 0 SENDFRAM 0 SENDFRAM 0 for outloop = 0 to 127 for inloop = 0 to 255 SENDFRAM 0 next inloop next outloop ' turn on interrupts OPTION = $88 'main code segment really doesn't do anything, since it is interrupt driven, and everything happens in the ISR repeat: goto repeat brcode: 'BREAK goto goback SENDFRAM: datatosend = __PARAM1 'save incoming sub argument ASM MOV nsb, #8 loopz: CLRB SCK 'make sure clock is low to start with(should already be low, though) CLRB C RL datatosend 'left shift data onto the port, because chip's MSB MOVB SI, C 'put the carry onto the port DEC nsb 'decrement counter SETB SCK 'raise clock notifying chip to read the data JNZ loopz 'if nsb > 0 then loopz CLRB SCK 'drop final bit clock ENDASM RETURN RECVFRAM: ASM MOV nsb, #8 CLR gotdata loopzz: SETB SCK 'We are ready to get a bit, so give it us! NOP 'wait for Todv, ie bit to stabilize MOVB C, SO 'read the bit into carry RL gotdata 'bring the bit via carry into gotdata, leftshifting for MSB DEC nsb 'decrement byte counter CLRB SCK 'drop clock so we can raise for the next bit JNZ loopzz ENDASM RETURN