Ejemplo n.º 1
0
int sector_print( void* buf, size_t sector, size_t chunks )
{
	uint8_t* start = (uint8_t*)buf + sector * USB_DFU_TRANSFER_SIZE;
	uint8_t* end = (uint8_t*)buf + (sector + 1) * USB_DFU_TRANSFER_SIZE;
	uint8_t* pos = start;

	// Verify if sector erased
	FTFL.fccob.read_1s_section.fcmd = FTFL_FCMD_READ_1s_SECTION;
	FTFL.fccob.read_1s_section.addr = (uintptr_t)start;
	FTFL.fccob.read_1s_section.margin = FTFL_MARGIN_NORMAL;
	FTFL.fccob.read_1s_section.num_words = 250; // 2000 kB / 64 bits
	int retval = ftfl_submit_cmd();

#ifdef FLASH_DEBUG
	print( NL );
	print("Block ");
	printHex( sector );
	print(" ");
	printHex( (size_t)start );
	print(" -> ");
	printHex( (size_t)end );
	print(" Erased: ");
	printHex( retval );
	print( NL );
#endif

	// Display sector
	for ( size_t line = 0; pos < end - 24; line++ )
	{
		// Each Line
		printHex_op( (size_t)pos, 4 );
		print(": ");

		// Each 2 byte chunk
		for ( size_t chunk = 0; chunk < chunks; chunk++ )
		{
			// Print out the two bytes (second one first)
			printHex_op( *(pos + 1), 2 );
			printHex_op( *pos, 2 );
			print(" ");
			pos += 2;
		}

		print( NL );
	}

	return retval;
}
Ejemplo n.º 2
0
// Detect short or open circuit in Matrix
// Only works with IS31FL3733
void LED_shortOpenDetect()
{
#if ISSI_Chip_31FL3733_define == 1 || ISSI_Chip_31FL3736_define == 1
	// Pause ISSI processing
	LED_pause = 1;

	for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
	{
		uint8_t addr = LED_ChannelMapping[ ch ].addr;
		uint8_t bus = LED_ChannelMapping[ ch ].bus;

		// Set Global Current Control (needed for accurate reading)
		LED_writeReg( bus, addr, 0x01, 0x01, ISSI_ConfigPage );

		// Enable master sync for the first chip and disable software shutdown
		// Also enable OSD (Open/Short Detect)
		if ( ch == 0 )
		{
			LED_writeReg( bus, addr, 0x00, 0x45, ISSI_ConfigPage );
		}
		// Slave sync for the rest and disable software shutdown
		// Also enable OSD (Open/Short Detect)
		else
		{
			LED_writeReg( bus, addr, 0x00, 0x85, ISSI_ConfigPage );
		}

		// Wait for 3.3 ms before reading the value
		// Needs at least 3.264 ms to query the information
		delay_us(3300);

		// Read registers
		info_msg("Bus: ");
		printHex( bus );
		print(" Addr: ");
		printHex( addr );
		print(" - 0x18 -> 0x2F + 0x30 -> 0x47");
		print(NL);

		// Validate open detection
		// TODO
		for ( uint8_t reg = 0x18; reg < 0x30; reg++ )
		{
			uint8_t val = LED_readReg( bus, addr, reg, ISSI_LEDControlPage );
			printHex_op( val, 2 );
			print(" ");
		}
		print(NL);

		// Validate short detection
		// TODO
		for ( uint8_t reg = 0x30; reg < 0x48; reg++ )
		{
			uint8_t val = LED_readReg( bus, addr, reg, ISSI_LEDControlPage );
			printHex_op( val, 2 );
			print(" ");
		}
		print(NL);
	}

	// We have to adjust various settings in order to get the correct reading
	// Reset ISSI configuration
	LED_reset();
#endif
}
Ejemplo n.º 3
0
// send the contents of keyboard_keys and keyboard_modifier_keys
void usb_keyboard_send()
{
	uint32_t wait_count = 0;
	usb_packet_t *tx_packet;

	// Wait till ready
	while ( 1 )
	{
		if ( !usb_configuration )
		{
			erro_print("USB not configured...");
			return;
		}

		if ( USBKeys_Protocol == 0 ) // Boot Mode
		{
			if ( usb_tx_packet_count( NKRO_KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT )
			{
				tx_packet = usb_malloc();
				if ( tx_packet )
					break;
			}
		}
		else if ( USBKeys_Protocol == 1 ) // NKRO Mode
		{
			if ( usb_tx_packet_count( KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT )
			{
				tx_packet = usb_malloc();
				if ( tx_packet )
					break;
			}
		}

		if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout )
		{
			transmit_previous_timeout = 1;
			warn_print("USB Transmit Timeout...");
			return;
		}
		yield();
	}

	// Pointer to USB tx packet buffer
	uint8_t *tx_buf = tx_packet->buf;

	switch ( USBKeys_Protocol )
	{
	// Send boot keyboard interrupt packet(s)
	case 0:
		// USB Boot Mode debug output
		if ( Output_DebugMode )
		{
			dbug_msg("Boot USB: ");
			printHex_op( USBKeys_Modifiers, 2 );
			print(" ");
			printHex( 0 );
			print(" ");
			printHex_op( USBKeys_Keys[0], 2 );
			printHex_op( USBKeys_Keys[1], 2 );
			printHex_op( USBKeys_Keys[2], 2 );
			printHex_op( USBKeys_Keys[3], 2 );
			printHex_op( USBKeys_Keys[4], 2 );
			printHex_op( USBKeys_Keys[5], 2 );
			print( NL );
		}

		// Boot Mode
		*tx_buf++ = USBKeys_Modifiers;
		*tx_buf++ = 0;
		memcpy( tx_buf, USBKeys_Keys, USB_BOOT_MAX_KEYS );
		tx_packet->len = 8;

		// Send USB Packet
		usb_tx( KEYBOARD_ENDPOINT, tx_packet );
		USBKeys_Changed = USBKeyChangeState_None;
		break;

	// Send NKRO keyboard interrupts packet(s)
	case 1:
		if ( Output_DebugMode )
		{
			dbug_msg("NKRO USB: ");
		}

		// Check system control keys
		if ( USBKeys_Changed & USBKeyChangeState_System )
		{
			if ( Output_DebugMode )
			{
				print("SysCtrl[");
				printHex_op( USBKeys_SysCtrl, 2 );
				print( "] " NL );
			}

			*tx_buf++ = 0x02; // ID
			*tx_buf   = USBKeys_SysCtrl;
			tx_packet->len = 2;

			// Send USB Packet
			usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
			USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
		}

		// Check consumer control keys
		if ( USBKeys_Changed & USBKeyChangeState_Consumer )
		{
			if ( Output_DebugMode )
			{
				print("ConsCtrl[");
				printHex_op( USBKeys_ConsCtrl, 2 );
				print( "] " NL );
			}

			*tx_buf++ = 0x03; // ID
			*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
			*tx_buf   = (uint8_t)(USBKeys_ConsCtrl >> 8);
			tx_packet->len = 3;

			// Send USB Packet
			usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
			USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
		}

		// Standard HID Keyboard
		if ( USBKeys_Changed )
		{
			// USB NKRO Debug output
			if ( Output_DebugMode )
			{
				printHex_op( USBKeys_Modifiers, 2 );
				print(" ");
				for ( uint8_t c = 0; c < 6; c++ )
					printHex_op( USBKeys_Keys[ c ], 2 );
				print(" ");
				for ( uint8_t c = 6; c < 20; c++ )
					printHex_op( USBKeys_Keys[ c ], 2 );
				print(" ");
				printHex_op( USBKeys_Keys[20], 2 );
				print(" ");
				for ( uint8_t c = 21; c < 27; c++ )
					printHex_op( USBKeys_Keys[ c ], 2 );
				print( NL );
			}

			tx_packet->len = 0;

			// Modifiers
			*tx_buf++ = 0x01; // ID
			*tx_buf++ = USBKeys_Modifiers;
			tx_packet->len += 2;

			// 4-49 (first 6 bytes)
			memcpy( tx_buf, USBKeys_Keys, 6 );
			tx_buf += 6;
			tx_packet->len += 6;

			// 51-155 (Middle 14 bytes)
			memcpy( tx_buf, USBKeys_Keys + 6, 14 );
			tx_buf += 14;
			tx_packet->len += 14;

			// 157-164 (Next byte)
			memcpy( tx_buf, USBKeys_Keys + 20, 1 );
			tx_buf += 1;
			tx_packet->len += 1;

			// 176-221 (last 6 bytes)
			memcpy( tx_buf, USBKeys_Keys + 21, 6 );
			tx_packet->len += 6;

			// Send USB Packet
			usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
			USBKeys_Changed = USBKeyChangeState_None; // Mark sent
		}

		break;
	}

	return;
}
Ejemplo n.º 4
0
// Single strobe matrix scan
// Only goes through a single strobe
// This module keeps track of the next strobe to scan
uint8_t Matrix_single_scan()
{
	// Start latency measurement
	Latency_start_time( matrixLatencyResource );


	// Read systick for event scheduling
	uint32_t currentTime = systick_millis_count;

	// Current strobe
	uint8_t strobe = matrixCurrentStrobe;

	// XXX (HaaTa)
	// Before strobing drain each sense line
	// This helps with faulty pull-up resistors (particularily with SAM4S)
	for ( uint8_t sense = 0; sense < Matrix_rowsNum; sense++ )
	{
		GPIO_Ctrl( Matrix_rows[ sense ], GPIO_Type_DriveSetup, Matrix_type );
#if ScanCodeMatrixInvert_define == 2 // GPIO_Config_Pulldown
		GPIO_Ctrl( Matrix_rows[ sense ], GPIO_Type_DriveLow, Matrix_type );
#elif ScanCodeMatrixInvert_define == 1 // GPIO_Config_Pullup
		GPIO_Ctrl( Matrix_rows[ sense ], GPIO_Type_DriveHigh, Matrix_type );
#endif
		GPIO_Ctrl( Matrix_rows[ sense ], GPIO_Type_ReadSetup, Matrix_type );
	}

	// Strobe Pin
	GPIO_Ctrl( Matrix_cols[ strobe ], GPIO_Type_DriveHigh, Matrix_type );

	// Used to allow the strobe signal to propagate, generally not required
	if ( strobeDelayTime > 0 )
	{
		delay_us( strobeDelayTime );
	}

	// Scan each of the sense pins
	for ( uint8_t sense = 0; sense < Matrix_rowsNum; sense++ )
	{
		// Key position
		uint16_t key = Matrix_colsNum * sense + strobe;
#if ScanCodeRemapping_define == 1
		uint16_t key_disp = matrixScanCodeRemappingMatrix[key];
#else
		uint16_t key_disp = key + 1; // 1-indexed for reporting purposes
#endif

		// Check bounds, before attempting to scan
		// 1-indexed as ScanCode 0 is not used
		if ( key_disp > MaxScanCode_KLL || key_disp == 0 )
		{
			continue;
		}
		volatile KeyState *state = &Matrix_scanArray[ key ];

		// Signal Detected
		// Increment count and right shift opposing count
		// This means there is a maximum of scan 13 cycles on a perfect off to on transition
		//  (coming from a steady state 0xFFFF off scans)
		// Somewhat longer with switch bounciness
		// The advantage of this is that the count is ongoing and never needs to be reset
		// State still needs to be kept track of to deal with what to send to the Macro module
		// Compared against the default state value (ScanCodeMatrixInvert_define), usually 0
		if ( GPIO_Ctrl( Matrix_rows[ sense ], GPIO_Type_Read, Matrix_type ) != ScanCodeMatrixInvert_define )
		{
			// Only update if not going to wrap around
			if ( state->activeCount < DebounceDivThreshold ) state->activeCount += 1;
			state->inactiveCount >>= 1;
		}
		// Signal Not Detected
		else
		{
			// Only update if not going to wrap around
			if ( state->inactiveCount < DebounceDivThreshold ) state->inactiveCount += 1;
			state->activeCount >>= 1;
		}

		// Check for state change
		// But only if:
		// 1) Enough time has passed since last state change
		// 2) Either active or inactive count is over the debounce threshold

		// Update previous state
		state->prevState = state->curState;

		// Determine time since last decision
		uint32_t lastTransition = currentTime - state->prevDecisionTime;

		// Attempt state transition
		switch ( state->prevState )
		{
		case KeyState_Press:
		case KeyState_Hold:
			if ( state->activeCount > state->inactiveCount )
			{
				state->curState = KeyState_Hold;
			}
			else
			{
				// If not enough time has passed since Hold
				// Keep previous state
				if ( lastTransition < debounceExpiryTime )
				{
					state->curState = state->prevState;
					Macro_keyState( key_disp, state->curState );
					continue;
				}

				state->curState = KeyState_Release;
			}
			break;

		case KeyState_Release:
		case KeyState_Off:
			if ( state->activeCount > state->inactiveCount )
			{
				// If not enough time has passed since Hold
				// Keep previous state
				if ( lastTransition < debounceExpiryTime )
				{
					state->curState = state->prevState;
					Macro_keyState( key_disp, state->curState );
					continue;
				}

				state->curState = KeyState_Press;
			}
			else
			{
				state->curState = KeyState_Off;
			}
			break;

		case KeyState_Invalid:
		default:
			erro_msg("Matrix scan bug!! Report me! - ");
			printHex( state->prevState );
			print(" Col: ");
			printHex( strobe );
			print(" Row: ");
			printHex( sense );
			print(" Key: ");
			printHex( key_disp );
			print( NL );
			break;
		}

		// Update decision time
		state->prevDecisionTime = currentTime;

		// Send keystate to macro module
		Macro_keyState( key_disp, state->curState );

		// Check for activity and inactivity
		if ( state->curState != KeyState_Off )
		{
			matrixStateActiveCount++;
		}
		switch ( state->curState )
		{
		case KeyState_Press:
			matrixStatePressCount++;
			break;

		case KeyState_Release:
			matrixStateReleaseCount++;
			break;

		default:
			break;
		}

		// Matrix Debug, only if there is a state change
		if ( matrixDebugMode && state->curState != state->prevState )
		{
			// Basic debug output
			if ( matrixDebugMode == 1 && state->curState == KeyState_Press )
			{
				printInt16( key_disp );
				print(":");
				printHex( key_disp );
				print(" ");
			}
			// State transition debug output
			else if ( matrixDebugMode == 2 )
			{
				printInt16( key_disp );
				Matrix_keyPositionDebug( state->curState );
				print(" ");
			}
			else if ( matrixDebugMode == 3 )
			{
				print("\033[1m");
				printInt16( key_disp );
				print("\033[0m");
				print(":");
				Matrix_keyPositionDebug( Matrix_scanArray[ key ].prevState );
				Matrix_keyPositionDebug( Matrix_scanArray[ key ].curState );
				print(" 0x");
				printHex_op( state->activeCount, 2 );
				print(" 0x");
				printHex_op( state->inactiveCount, 2 );
				print(" ");
				printInt32( lastTransition );
				print( NL );
			}

		}
	}