⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmcfmt.c

📁 AVR MMC 开锁源码。Multi-Media Card Unlocker
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** MMC Unlocker *************************************************************
 *
 *	File Name  : mmcfmt.c
 *	Title      : Multi-Media Card Unlocker
 *  Description: Reset locked MMC cards (and wipes all data) allowing them
 *                to be used again
 *	Author     : Muhammad J. A. Galadima
 *	Created    : 2004 / 01 / 27
 *	Version    : 0.1
 *	Target MCU : STK500 (can be used w/any AVRs with enough pins for
                 the MMC card (4) plus any switches/LEDs you want)
 *	
 *	
 *	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.
 *
 *****************************************************************************/

#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>

#include <ctype.h>
#include <inttypes.h>
#include <string.h>


#define MMC_PORT	PORTC
#define MMC_PIN		PINC
#define MMC_DDR		DDRC
#define MMC_CS      PC0
#define MMC_MISO    PC2
#define MMC_MOSI    PC1
#define MMC_CLK     PC6

#define LED_PORT	PORTB
#define LED_PIN		PINB
#define LED_DDR		DDRB
#define SW_PORT		PORTA
#define SW_PIN		PINA
#define SW_DDR		DDRA
#define BAUDRATE	115200
#define BAUD_REG	((uint16_t)((F_CPU / (16.0 * (BAUDRATE))) + 0.5) - 1)	// if above .5 mark, round up; replace 16 with 8 for double
#define BAUD_H  	((uint8_t)(0xFF&(BAUD_REG>>8)))
#define BAUD_L		((uint8_t)(0xFF&BAUD_REG))

#define spi_response()	spi_byte(0xFF)					// read response
#define spi_busywait()	while(spi_byte(0xFF) == 0)		// wait for non-zero response to continue



uint8_t spi_cmd[5];	// 6 is CRC, which we won't be using here (or should be generated indide spi_command())
uint8_t reg_csd[16];
uint8_t reg_cid[16];
uint16_t block_len;
uint32_t block_cnt;


/*** SIG_UART_RECV ************************************************************
 *	interrupt on receive byte; for now just echo if any char received
 *****************************************************************************/
SIGNAL (SIG_UART_RECV) {
	uint8_t temp;
	temp = UDR;			// read
	LED_PORT = ~temp;	// show the current command on the LEDs
	if(temp=='\r' || temp == '\n') {
		printf_P(PSTR("\n\r"));
	}
	else
		UDR = temp;			// write	(just echo what the user types)
}

uint8_t uart_tx(uint8_t uart_tx) {
	while(!(UCSRA & _BV(UDRE)));		// wait for empty tx buffer
	UDR = uart_tx;						// put data in buffer, init send
	
	return 0;
}
// uint8_t uart_tx(uint8_t uart_tx)


uint8_t uart_rx(void) {
	while(!(UCSRA & _BV(RXC)));		// wait for full rx buffer
	return UDR;                   /* return the new c */
}
// uint8_t uart_rx(void)


/*** delay ********************************************************************
 *	rough delay; 65k loops, 4 instr each, +over head: 65536*4 = 262144, 
 *	round up tp 300000 clks (time: 300000/F_CPU seconds)
 *****************************************************************************/
void delay(void) {
	uint8_t i, j;
	for(i=0; i<255; i++) {
		for(j=0; j<255; j++) {
			asm volatile("nop"::);
			asm volatile("nop"::);
			asm volatile("nop"::);
			asm volatile("nop"::);
		}
	}
}
// void delay(void)

/*** show_resp ****************************************************************
 *	show value in response on LEDs and wait for keypress; for debugging only
 *****************************************************************************/
void show_resp(uint8_t retval) {
	LED_PORT = ~(retval);				// light leds 0-7 according to error,
										//	and show that system is waiting (led7)
	loop_until_bit_is_clear(SW_PIN, 0);	// wait for sw0 to be pressed
	delay();							// debounce delay
	loop_until_bit_is_set(SW_PIN, 0);	// wait for sw0 to be released
	delay();							// debounce delay
	LED_PORT = 0xFF;					// clear all leds
}
// void show_resp(uint8_t retval)

/*** spi_byte *****************************************************************
 *	Send one, receive one (happens simultaneously)
 *****************************************************************************/
uint8_t spi_byte(uint8_t spi_tx) {
	uint8_t i, spi_rx = 0;
	
	for(i=8; i>0; i--) {
	    i--;
		
		if( bit_is_set(spi_tx,i) )
		    MMC_PORT |= _BV(MMC_MOSI);  // set mosi pin
		else
		    MMC_PORT &= ~_BV(MMC_MOSI);  // clr mosi pin

		// read MISO
	    spi_rx <<= 1;		// x2, shift left to create space for next
		if( bit_is_set(MMC_PIN,MMC_MISO) )
			spi_rx++;

		MMC_PORT |= _BV(MMC_CLK);	// clk high
	    MMC_PORT &= ~_BV(MMC_CLK);	// clk low
 		
	    i++;
    }
	
	return spi_rx;
}
// uint8_t spi_byte(uint8_t spi_tx)


/*** spi_command **************************************************************
 *	Send contents of command structure, get (first) response byte
 *****************************************************************************/
uint8_t spi_command(void) {
	uint8_t retval, i;
	
	MMC_PORT &= ~_BV(MMC_CS);	// cs low (select, spi mode)
	
	spi_byte(0xFF);
	// send command struct
	spi_byte(spi_cmd[0] | 0x40);	// make 2 MSBs '01' (01xxxxxx, where x represents command bit)
	spi_byte(spi_cmd[4]);			// address
	spi_byte(spi_cmd[3]);			//    "
	spi_byte(spi_cmd[2]);			//    "
	spi_byte(spi_cmd[1]);			//    "
	spi_byte(0x95);					// CRC (from spec; calculate?)
//	spi_byte(0xFF);
	
	i=0;
	do {							// Flush Ncr (1-8 bytes) before response
		retval = spi_byte(0xff);
		i++;
	} while(i<8 && retval == 0xFF);
	
	return retval;	// return R1 response (or first byte of any other command)
}
// uint8_t spi_command(void)


/*** get_slice ****************************************************************
 *	get the requested portion of the given register
 *****************************************************************************/
uint16_t get_slice(uint8_t *ptr_reg, uint8_t start, uint8_t stop) {
	uint8_t upper, lower, lower_s, count, i;
	uint32_t rval=0;
	
	lower = stop / 8.0;
	upper = start / 8.0;
	
	// merge all used bytes into on large var
	count = upper - lower;
	for(i=0; i<=count; i++) {
		rval <<= 8;
		rval |= ptr_reg[upper-i];
	}
	
	// shift data down so it starts at zero
	lower_s = stop - (lower * 8);
	rval >>= lower_s;
	
	// clear upper bits (all bits before start)
	start -= stop;
	start++;
	//for(i=start; i<32; i++)
	for(i=start; i<16; i++)	// clear bits 15-start
		rval &= ~(1<<i);
	rval &= 0x0000FFFF;			// clear bits 31-16
	
	return (uint16_t)rval;
}
// uint16_t get_slice(uint8_t ptr_reg[], uint8_t start, uint8_t stop)

/*** get_regs *****************************************************************
 *	read the contents of the CSD + CID registers from the card
 *****************************************************************************/
void get_regs(void) {
	uint8_t i, c_size_mult, read_bl_len;
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -