/* Copyright (C) 2019 - 2021 Vega 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. */ #Registers #r0 = Scrap register for temporary values #r3 = Unused #r4 = Unused #r5 = Unused #r6 = Another LR backup #r7 = old MSR #r8 = current bit to send to SEEPROM #r9 = 1st arg of send_bits #r10 = Loop tracker for send_bits (instruction length minus 1) #r11 = GPIO #r12 = LR #Disable Interrupts; backup OG MSR in r7 seeprom_eral: mfmsr r7 rlwinm r0, r7, 0, 17, 15 mtmsr r0 #Backup first LR mflr r12 #Set GPIO Upper Bits lis r11, 0xCD80 #Unclock, Clear CS lwz r0, 0x00E0 (r11) sync rlwinm r0, r0, 0, 22, 19 #Clear CS and SK stw r0, 0x00E0 (r11) eieio bl wait #Turn on Chip Select lwz r0, 0x00E0 (r11) sync ori r0, r0, 0x0400 #CS high stw r0, 0x00E0 (r11) eieio bl wait ###EWEN### (Enable Write & Erase) #SB = 1 #OpCode = 00 #Address x16 = 11xxxxxx (x = don't care values) li r9, 0x4C0 #Send EWEN Command bl send_bits ###EWEN Sent### #ERAL #SB = 1 #OpCode = 00 #Address x16 = 10xxxxxx (x = don't care values) li r9, 0x480 #Clear CS, Turn it Back on, so we can do a new Command bl CS_low_high #Now send the bits bl send_bits #Before we can check the Ready/Busy status, we must clear CS, and turn it back on again! lol bl CS_low_high #Check Ready/Busy signal #0 = Busy #1 = Task completed check_busyready: lwz r0, 0x00E8 (r11) #GPIO_IN!!!!!!! sync andi. r0, r0, 0x2000 #DO bit beq- check_busyready ####EWDS#### #Ends erase&writing abilities, do this for safey #SB = 1 #OpCode = 00 #Address x16 = xxxxxxxx (x = don't care values) li r9, 0x400 #Yes CS does need to be brought low and high again..... ugh bl CS_low_high #Send bits bl send_bits #All done, do a final clear of CS and wait; SK already low at this point lwz r0, 0x00E0 (r11) sync rlwinm r0, r0, 0, 22, 20 stw r0, 0x00E0 (r11) eieio bl wait #Restore Interrupts (restore old MSR) mtmsr r7 #END Function end_function: mtlr r12 blr ###Send bits subroutine### #r9 = Only arg (the command) send_bits: mflr r6 #Set Loop Amount (instruction length minus 1) li r10, 10 #Bit Sending loop bit_loop: srw r8, r9, r10 #Will start shift by 10, then 9, then 8, etc etc. This will make first bit of Command to send first, and last bit sent last #Load GPIO lwz r0, 0x00E0 (r11) sync #Replace bit 19 of loaded GPIO with bit 31 of r8 rlwimi r0, r8, 12, 19, 19 #Hex mask of 0x00001000 #Send the bit! stw r0, 0x00E0 (r11) #DI now sent eieio bl wait #Clock and unclock lwz r0, 0x00E0 (r11) sync ori r0, r0, 0x0800 #SK; bit 20 high stw r0, 0x00E0 (r11) eieio bl wait lwz r0, 0x00E0 (r11) sync rlwinm r0, r0, 0, 21, 19 #Sk; bit 20 low stw r0, 0x00E0 (r11) eieio bl wait subic. r10, r10, 1 bge+ bit_loop mtlr r6 blr #All done, end subroutine #Clear and set CS subroutine CS_low_high: mflr r6 lwz r0, 0x00E0 (r11) sync rlwinm r0, r0, 0, 22, 20 #CS low stw r0, 0x00E0 (r11) eieio bl wait lwz r0, 0x00E0 (r11) sync ori r0, r0, 0x0400 #CS high stw r0, 0x00E0 (r11) eieio bl wait mtlr r6 blr #Wait subroutine wait: li r0, 0 #Reset Starlet Timer stw r0, 0x0010 (r11) wait_loop: lwz r0, 0x0010 (r11) cmplwi r0, 2 #Check if 2 'tick's (~1000 nanoseconds) has elapsed blt- wait_loop blr